From a90f783dc8eba1332bc80b0f5b2410e9418d9bb8 Mon Sep 17 00:00:00 2001 From: "Ngo Iok Ui (Wu Yu Wei)" Date: Fri, 29 Sep 2023 21:57:45 +0900 Subject: [PATCH] Fix transparency on macOS (#260) * Fix transparency on macOS Unlike other platforms, macOS add another opaque layer on CALayer. This makes the window opaque even if winit window is set to transparent. * Determine layer opaque based on NSWindow's opqaue --- surfman/src/platform/macos/cgl/connection.rs | 1 + surfman/src/platform/macos/system/connection.rs | 4 ++++ surfman/src/platform/macos/system/surface.rs | 13 +++++++++---- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/surfman/src/platform/macos/cgl/connection.rs b/surfman/src/platform/macos/cgl/connection.rs index ba19c519..420bce49 100644 --- a/surfman/src/platform/macos/cgl/connection.rs +++ b/surfman/src/platform/macos/cgl/connection.rs @@ -149,6 +149,7 @@ impl Connection { match raw_handle { AppKit(handle) => Ok(NativeWidget { view: NSView(unsafe { msg_send![handle.ns_view as id, retain] }), + opaque: unsafe { msg_send![handle.ns_window as id, isOpaque] }, }), _ => Err(Error::IncompatibleNativeWidget), } diff --git a/surfman/src/platform/macos/system/connection.rs b/surfman/src/platform/macos/system/connection.rs index a1271228..8e7c305f 100644 --- a/surfman/src/platform/macos/system/connection.rs +++ b/surfman/src/platform/macos/system/connection.rs @@ -146,12 +146,14 @@ impl Connection { window: &Window, ) -> Result { let ns_view = window.ns_view() as id; + let ns_window = window.ns_window() as id; if ns_view.is_null() { return Err(Error::IncompatibleNativeWidget); } unsafe { Ok(NativeWidget { view: NSView(msg_send![ns_view, retain]), + opaque: msg_send![ns_window as id, isOpaque], }) } } @@ -164,6 +166,7 @@ impl Connection { ) -> NativeWidget { NativeWidget { view: NSView(raw as id), + opaque: true, } } @@ -179,6 +182,7 @@ impl Connection { match raw_handle { AppKit(handle) => Ok(NativeWidget { view: NSView(unsafe { msg_send![handle.ns_view as id, retain] }), + opaque: unsafe { msg_send![handle.ns_window as id, isOpaque] }, }), _ => Err(Error::IncompatibleNativeWidget), } diff --git a/surfman/src/platform/macos/system/surface.rs b/surfman/src/platform/macos/system/surface.rs index 6b4997ee..ab44487a 100644 --- a/surfman/src/platform/macos/system/surface.rs +++ b/surfman/src/platform/macos/system/surface.rs @@ -78,6 +78,7 @@ pub(crate) struct ViewInfo { logical_size: NSSize, display_link: DisplayLink, next_vblank: Arc, + opaque: bool, } struct VblankCond { @@ -94,6 +95,8 @@ pub struct NSView(pub(crate) id); pub struct NativeWidget { /// The `NSView` object. pub view: NSView, + /// A bool value that indicates whether widget's NSWindow is opaque. + pub opaque: bool, } /// Represents the CPU view of the pixel data of this surface. @@ -204,12 +207,13 @@ impl Device { }]; let logical_size = logical_rect.size; + let opaque = native_widget.opaque; let layer = CALayer::new(); let layer_size = CGSize::new(logical_size.width as f64, logical_size.height as f64); layer.set_frame(&CGRect::new(&CG_ZERO_POINT, &layer_size)); layer.set_contents(front_surface.obj as id); - layer.set_opaque(true); - layer.set_contents_opaque(true); + layer.set_opaque(opaque); + layer.set_contents_opaque(opaque); superlayer.add_sublayer(&layer); let view = native_widget.view.clone(); @@ -223,6 +227,7 @@ impl Device { logical_size, display_link, next_vblank, + opaque, } } @@ -284,8 +289,8 @@ impl Device { view_info .layer .set_contents(view_info.front_surface.obj as id); - view_info.layer.set_opaque(true); - view_info.layer.set_contents_opaque(true); + view_info.layer.set_opaque(view_info.opaque); + view_info.layer.set_contents_opaque(view_info.opaque); surface.io_surface = self.create_io_surface(&size, surface.access); surface.size = size; }