Skip to content

Commit c47bb2e

Browse files
committed
Private CGSSetWindowBackgroundBlurRadius call removed; NSVisualEffectView replacement.
1 parent 27e17e3 commit c47bb2e

5 files changed

Lines changed: 45 additions & 31 deletions

File tree

winit-appkit/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ objc2-app-kit = { workspace = true, features = [
5454
"NSTrackingArea",
5555
"NSToolbar",
5656
"NSView",
57+
"NSVisualEffectView",
5758
"NSWindow",
5859
"NSWindowScripting",
5960
"NSWindowTabGroup",

winit-appkit/src/ffi.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
use std::ffi::c_void;
66

7-
use objc2::ffi::NSInteger;
8-
use objc2::runtime::AnyObject;
97
use objc2_core_foundation::{CFString, CFUUID, cf_type};
108
use objc2_core_graphics::CGDirectDisplayID;
119

@@ -28,17 +26,6 @@ unsafe extern "C" {
2826
pub fn CGDisplayGetDisplayIDFromUUID(uuid: &CFUUID) -> CGDirectDisplayID;
2927
}
3028

31-
#[link(name = "CoreGraphics", kind = "framework")]
32-
unsafe extern "C" {
33-
// Wildly used private APIs; Apple uses them for their Terminal.app.
34-
pub fn CGSMainConnectionID() -> *mut AnyObject;
35-
pub fn CGSSetWindowBackgroundBlurRadius(
36-
connection_id: *mut AnyObject,
37-
window_id: NSInteger,
38-
radius: i64,
39-
) -> i32;
40-
}
41-
4229
#[repr(transparent)]
4330
pub struct TISInputSource(std::ffi::c_void);
4431

winit-appkit/src/view.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ define_class!(
141141
#[unsafe(super(NSView, NSResponder, NSObject))]
142142
#[ivars = ViewState]
143143
#[name = "WinitView"]
144+
#[derive(Debug)]
144145
pub(super) struct WinitView;
145146

146147
/// This documentation attribute makes rustfmt work for some reason?

winit-appkit/src/window_delegate.rs

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ use objc2::{
1818
};
1919
use 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)]
2930
use objc2_app_kit::{NSFilenamesPboardType, NSWindowFullScreenButton};
@@ -55,7 +56,6 @@ use winit_core::window::{
5556

5657
use super::app_state::AppState;
5758
use super::cursor::{CustomCursor, cursor_from_icon};
58-
use super::ffi;
5959
use super::monitor::{self, MonitorHandle, flip_window_screen_coordinates, get_display_id};
6060
use super::util::cgerr;
6161
use 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

winit/src/changelog/unreleased.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,5 @@ changelog entry.
6767
- On macOS, fix borderless game presentation options not sticking after switching spaces.
6868
- On macOS, fix IME being locked on (regardless of requests to disable) after being enabled once.
6969
- On macOS, fix a panic and incorrect cursor position in Ime::Preedit when the preedit string contains special characters (ie. emojis) caused by incorrect UTF-16 to UTF-8 offset conversion.
70+
- On macOS fix private `CGSSetWindowBackgroundBlurRadius` call causing App Store rejection, `NSVisualEffectView` replacement.
71+

0 commit comments

Comments
 (0)