mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 21:32:13 +03:00
macos: implement opacity for CGL and Metal
There's a few different knobs to turn, but this commit turns them and we're now able to respect opacity settings for both OpenGL/CGL and Metal renderers. closes: #141
This commit is contained in:
parent
2364b0a20e
commit
191b047126
@ -13,6 +13,9 @@ brief notes about them may accumulate here.
|
||||
* New: split/pane support!
|
||||
See [#157](https://github.com/wez/wezterm/issues/157) for
|
||||
overall status and additional information.
|
||||
* New: `window_background_opacity`, `window_background_image`
|
||||
and `window_background_tint` options to control using background
|
||||
images, transparent windows. [More info](https://github.com/wez/wezterm/commit/f2cbc182cdbf4463b5f80bee7cb651bb7e67024b)
|
||||
* The GUI layer now normalizes SHIFT state for keyboard processing.
|
||||
If a keypress is ASCII uppercase and SHIFT is held then the
|
||||
SHIFT modifier is removed from the set of active modifiers. This
|
||||
|
@ -2588,11 +2588,15 @@ impl TermWindow {
|
||||
pos: &PositionedPane,
|
||||
frame: &mut glium::Frame,
|
||||
) -> anyhow::Result<()> {
|
||||
let config = configuration();
|
||||
let palette = pos.pane.palette();
|
||||
|
||||
let background_color = palette.resolve_bg(wezterm_term::color::ColorAttribute::Default);
|
||||
let background_alpha = (config.window_background_opacity * 255.0) as u8;
|
||||
let background = rgbcolor_alpha_to_window_color(palette.background, background_alpha);
|
||||
|
||||
if pos.index == 0 {
|
||||
let (r, g, b, a) = background_color.to_tuple_rgba();
|
||||
let (r, g, b, a) = background.to_tuple_rgba();
|
||||
frame.clear_color_srgb(r, g, b, a);
|
||||
}
|
||||
|
||||
@ -2607,7 +2611,6 @@ impl TermWindow {
|
||||
let current_viewport = self.get_viewport(pos.pane.pane_id());
|
||||
let (stable_top, lines);
|
||||
let dims = term.get_dimensions();
|
||||
let config = configuration();
|
||||
|
||||
{
|
||||
let stable_range = match current_viewport {
|
||||
@ -2626,8 +2629,6 @@ impl TermWindow {
|
||||
|
||||
let cursor_border_color = rgbcolor_to_window_color(palette.cursor_border);
|
||||
let foreground = rgbcolor_to_window_color(palette.foreground);
|
||||
let background_alpha = (config.window_background_opacity * 255.0) as u8;
|
||||
let background = rgbcolor_alpha_to_window_color(palette.background, background_alpha);
|
||||
|
||||
if self.show_tab_bar && pos.index == 0 {
|
||||
let tab_dims = RenderableDimensions {
|
||||
|
@ -6,9 +6,9 @@ use crate::bitmaps::Image;
|
||||
use crate::connection::ConnectionOps;
|
||||
use crate::os::macos::bitmap::BitmapRef;
|
||||
use crate::{
|
||||
BitmapImage, Clipboard, Color, Connection, Dimensions, KeyCode, KeyEvent, Modifiers,
|
||||
MouseButtons, MouseCursor, MouseEvent, MouseEventKind, MousePress, Operator, PaintContext,
|
||||
Point, Rect, ScreenPoint, Size, WindowCallbacks, WindowOps, WindowOpsMut,
|
||||
is_egl_preferred, BitmapImage, Clipboard, Color, Connection, Dimensions, KeyCode, KeyEvent,
|
||||
Modifiers, MouseButtons, MouseCursor, MouseEvent, MouseEventKind, MousePress, Operator,
|
||||
PaintContext, Point, Rect, ScreenPoint, Size, WindowCallbacks, WindowOps, WindowOpsMut,
|
||||
};
|
||||
use anyhow::{anyhow, bail, ensure};
|
||||
use cocoa::appkit::{
|
||||
@ -131,17 +131,6 @@ mod opengl {
|
||||
/// The ANGLE EGL implementation wants a CALayer descendant passed
|
||||
/// as the EGLNativeWindowType.
|
||||
pub fn create(view: id) -> anyhow::Result<Self> {
|
||||
let layer: id;
|
||||
|
||||
// ANGLE wants a layer, so tell the view to create one.
|
||||
// Importantly, we must set its scale to 1.0 prior to initializing
|
||||
// EGL to prevent undesirable scaling.
|
||||
unsafe {
|
||||
let _: () = msg_send![view, setWantsLayer: YES];
|
||||
layer = msg_send![view, layer];
|
||||
let _: () = msg_send![layer, setContentsScale: 1.0f64];
|
||||
};
|
||||
|
||||
let behavior = if cfg!(debug_assertions) {
|
||||
glium::debug::DebugCallbackBehavior::DebugMessageOnError
|
||||
} else {
|
||||
@ -149,8 +138,38 @@ mod opengl {
|
||||
};
|
||||
|
||||
// Let's first try to initialize EGL...
|
||||
let (context, backend) = match crate::egl::GlState::create(None, layer as *const c_void)
|
||||
{
|
||||
let (context, backend) = match if is_egl_preferred() {
|
||||
// ANGLE wants a layer, so tell the view to create one.
|
||||
// Importantly, we must set its scale to 1.0 prior to initializing
|
||||
// EGL to prevent undesirable scaling.
|
||||
let layer: id;
|
||||
unsafe {
|
||||
let _: () = msg_send![view, setWantsLayer: YES];
|
||||
layer = msg_send![view, layer];
|
||||
let _: () = msg_send![layer, setContentsScale: 1.0f64];
|
||||
let _: () = msg_send![layer, setOpaque: NO];
|
||||
};
|
||||
let state = crate::egl::GlState::create(None, layer as *const c_void);
|
||||
|
||||
if state.is_ok() {
|
||||
// ANGLE will create a CAMetalLayer as a sublayer of our provided
|
||||
// layer. Even though CALayer defaults to !opaque, CAMetalLayer
|
||||
// defaults to opaque, so we need to find that layer and fix
|
||||
// the opacity so that our alpha values are respected.
|
||||
unsafe {
|
||||
let sublayers: id = msg_send![layer, sublayers];
|
||||
let layer_count = sublayers.count();
|
||||
for i in 0..layer_count {
|
||||
let layer = sublayers.objectAtIndex(i);
|
||||
let _: () = msg_send![layer, setOpaque: NO];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state
|
||||
} else {
|
||||
Err(anyhow!("prefers not to use EGL"))
|
||||
} {
|
||||
Ok(backend) => {
|
||||
let backend = Rc::new(backend);
|
||||
let context = unsafe {
|
||||
@ -220,7 +239,14 @@ mod opengl {
|
||||
)
|
||||
};
|
||||
ensure!(!gl_context.is_null(), "failed to create NSOpenGLContext");
|
||||
|
||||
unsafe {
|
||||
let opaque: cgl::GLint = 0;
|
||||
gl_context.setValues_forParameter_(
|
||||
&opaque,
|
||||
cocoa::appkit::NSOpenGLContextParameter::NSOpenGLCPSurfaceOpacity,
|
||||
);
|
||||
|
||||
gl_context.setView_(view);
|
||||
}
|
||||
|
||||
@ -378,6 +404,14 @@ impl Window {
|
||||
let _: () = msg_send![*window, setTabbingMode:2 /* NSWindowTabbingModeDisallowed */];
|
||||
|
||||
window.setReleasedWhenClosed_(NO);
|
||||
window.setOpaque_(NO);
|
||||
// window.setHasShadow_(NO);
|
||||
let ns_color: id = msg_send![Class::get("NSColor").unwrap(), alloc];
|
||||
window.setBackgroundColor_(cocoa::appkit::NSColor::clearColor(ns_color));
|
||||
|
||||
// We could set this, but it makes the entire window, including
|
||||
// its titlebar, opaque to this fixed degree.
|
||||
// window.setAlphaValue_(0.4);
|
||||
|
||||
// Window positioning: the first window opens up in the center of
|
||||
// the screen. Subsequent windows will be offset from the position
|
||||
@ -1045,7 +1079,7 @@ impl WindowView {
|
||||
// Tell the window/view/layer stuff that we only have a single opaque
|
||||
// thing in the window so that it can optimize rendering
|
||||
extern "C" fn is_opaque(_this: &Object, _sel: Sel) -> BOOL {
|
||||
YES
|
||||
NO
|
||||
}
|
||||
|
||||
// Don't use Cocoa native window tabbing
|
||||
@ -1483,6 +1517,7 @@ impl WindowView {
|
||||
sel!(isFlipped),
|
||||
Self::is_flipped as extern "C" fn(&Object, Sel) -> BOOL,
|
||||
);
|
||||
|
||||
cls.add_method(
|
||||
sel!(isOpaque),
|
||||
Self::is_opaque as extern "C" fn(&Object, Sel) -> BOOL,
|
||||
|
Loading…
Reference in New Issue
Block a user