@@ -18,12 +18,13 @@ use objc2::{
1818} ;
1919use objc2_app_kit:: {
2020 NSAppKitVersionNumber , NSAppKitVersionNumber10_12 , NSAppearance , NSAppearanceCustomization ,
21- NSAppearanceNameAqua , NSApplication , NSApplicationPresentationOptions , NSBackingStoreType ,
22- NSColor , NSDraggingDestination , NSDraggingInfo , NSRequestUserAttentionType , NSScreen ,
23- NSToolbar , NSView , NSViewFrameDidChangeNotification , NSWindow , NSWindowButton ,
24- NSWindowDelegate , NSWindowLevel , NSWindowOcclusionState , NSWindowOrderingMode ,
25- NSWindowSharingType , NSWindowStyleMask , NSWindowTabbingMode , NSWindowTitleVisibility ,
26- NSWindowToolbarStyle ,
21+ NSAppearanceNameAqua , NSApplication , NSApplicationPresentationOptions ,
22+ NSAutoresizingMaskOptions , NSBackingStoreType , NSColor , NSDraggingDestination , NSDraggingInfo ,
23+ NSRequestUserAttentionType , NSScreen , NSToolbar , NSView , NSViewFrameDidChangeNotification ,
24+ NSVisualEffectBlendingMode , NSVisualEffectMaterial , NSVisualEffectState , NSVisualEffectView ,
25+ NSWindow , NSWindowButton , NSWindowDelegate , NSWindowLevel , NSWindowOcclusionState ,
26+ NSWindowOrderingMode , NSWindowSharingType , NSWindowStyleMask , NSWindowTabbingMode ,
27+ NSWindowTitleVisibility , NSWindowToolbarStyle ,
2728} ;
2829#[ allow( deprecated) ]
2930use objc2_app_kit:: { NSFilenamesPboardType , NSWindowFullScreenButton } ;
@@ -55,7 +56,6 @@ use winit_core::window::{
5556
5657use super :: app_state:: AppState ;
5758use super :: cursor:: { CustomCursor , cursor_from_icon} ;
58- use super :: ffi;
5959use super :: monitor:: { self , MonitorHandle , flip_window_screen_coordinates, get_display_id} ;
6060use super :: util:: cgerr;
6161use super :: view:: WinitView ;
@@ -69,6 +69,8 @@ pub(crate) struct State {
6969
7070 window : Retained < NSWindow > ,
7171
72+ view : Retained < WinitView > ,
73+
7274 // During `windowDidResize`, we use this to only send Moved if the position changed.
7375 //
7476 // This is expressed in desktop coordinates, and flipped to match Winit's coordinate system.
@@ -779,6 +781,12 @@ impl WindowDelegate {
779781 let window = new_window ( app_state, & attrs, & macos_attrs, mtm)
780782 . ok_or_else ( || os_error ! ( "couldn't create `NSWindow`" ) ) ?;
781783
784+ let view: Retained < WinitView > = window
785+ . contentView ( )
786+ . expect ( "window should have a content view" )
787+ . downcast ( )
788+ . expect ( "content view should be a `WinitView`" ) ;
789+
782790 match attrs. parent_window ( ) {
783791 Some ( rwh_06:: RawWindowHandle :: AppKit ( handle) ) => {
784792 // SAFETY: Caller ensures the pointer is valid or NULL
@@ -817,6 +825,7 @@ impl WindowDelegate {
817825 let delegate = mtm. alloc ( ) . set_ivars ( State {
818826 app_state : Rc :: clone ( app_state) ,
819827 window : window. retain ( ) ,
828+ view,
820829 previous_position : Cell :: new ( flip_window_screen_coordinates ( window. frame ( ) ) ) ,
821830 previous_scale_factor : Cell :: new ( scale_factor) ,
822831 surface_resize_increments : Cell :: new ( surface_resize_increments) ,
@@ -888,8 +897,7 @@ impl WindowDelegate {
888897
889898 #[ track_caller]
890899 pub ( super ) fn view ( & self ) -> Retained < WinitView > {
891- // The view inside WinitWindow should always be set and be `WinitView`.
892- self . window ( ) . contentView ( ) . unwrap ( ) . downcast ( ) . unwrap ( )
900+ self . ivars ( ) . view . clone ( )
893901 }
894902
895903 #[ track_caller]
@@ -970,16 +978,31 @@ impl WindowDelegate {
970978 }
971979
972980 pub fn set_blur ( & self , blur : bool ) {
973- // NOTE: in general we want to specify the blur radius, but the choice of 80
974- // should be a reasonable default.
975- let radius = if blur { 80 } else { 0 } ;
976- let window_number = self . window ( ) . windowNumber ( ) ;
977- unsafe {
978- ffi:: CGSSetWindowBackgroundBlurRadius (
979- ffi:: CGSMainConnectionID ( ) ,
980- window_number,
981- radius,
981+ let window = self . window ( ) ;
982+ let view = self . view ( ) ;
983+ let currently_blurred = window
984+ . contentView ( )
985+ . is_some_and ( |content| content. downcast :: < NSVisualEffectView > ( ) . is_ok ( ) ) ;
986+ if blur == currently_blurred {
987+ return ;
988+ }
989+
990+ if blur {
991+ let mtm = MainThreadMarker :: from ( self ) ;
992+ let effect_view = NSVisualEffectView :: new ( mtm) ;
993+ effect_view. setBlendingMode ( NSVisualEffectBlendingMode :: BehindWindow ) ;
994+ effect_view. setState ( NSVisualEffectState :: Active ) ;
995+ effect_view. setMaterial ( NSVisualEffectMaterial :: WindowBackground ) ;
996+
997+ window. setContentView ( Some ( & effect_view) ) ;
998+ view. setFrame ( effect_view. bounds ( ) ) ;
999+ view. setAutoresizingMask (
1000+ NSAutoresizingMaskOptions :: ViewWidthSizable
1001+ | NSAutoresizingMaskOptions :: ViewHeightSizable ,
9821002 ) ;
1003+ effect_view. addSubview ( & view) ;
1004+ } else {
1005+ window. setContentView ( Some ( & view) ) ;
9831006 }
9841007 }
9851008
0 commit comments