mirror of
https://github.com/rust-windowing/winit.git
synced 2026-06-27 23:23:14 -04:00
macOS: Avoid redundant initial resize event (#3913)
The `NSViewFrameDidChangeNotification` that we listen to is emitted when `-[NSWindow setContentView]` is called, since that sets the frame of the view as well. So now we register the notification later, so that it's not triggered at window creation. This behaviour is well described in the documentation: https://developer.apple.com/documentation/appkit/nsview/postsframechangednotifications?language=objc
This commit is contained in:
@@ -15,15 +15,15 @@ use objc2_app_kit::{
|
||||
NSAppKitVersionNumber, NSAppKitVersionNumber10_12, NSAppearance, NSAppearanceCustomization,
|
||||
NSAppearanceNameAqua, NSApplication, NSApplicationPresentationOptions, NSBackingStoreType,
|
||||
NSColor, NSDraggingDestination, NSFilenamesPboardType, NSPasteboard,
|
||||
NSRequestUserAttentionType, NSScreen, NSToolbar, NSView, NSWindowButton, NSWindowDelegate,
|
||||
NSWindowFullScreenButton, NSWindowLevel, NSWindowOcclusionState, NSWindowOrderingMode,
|
||||
NSWindowSharingType, NSWindowStyleMask, NSWindowTabbingMode, NSWindowTitleVisibility,
|
||||
NSWindowToolbarStyle,
|
||||
NSRequestUserAttentionType, NSScreen, NSToolbar, NSView, NSViewFrameDidChangeNotification,
|
||||
NSWindowButton, NSWindowDelegate, NSWindowFullScreenButton, NSWindowLevel,
|
||||
NSWindowOcclusionState, NSWindowOrderingMode, NSWindowSharingType, NSWindowStyleMask,
|
||||
NSWindowTabbingMode, NSWindowTitleVisibility, NSWindowToolbarStyle,
|
||||
};
|
||||
use objc2_foundation::{
|
||||
ns_string, CGFloat, MainThreadMarker, NSArray, NSCopying, NSDictionary, NSEdgeInsets,
|
||||
NSKeyValueChangeKey, NSKeyValueChangeNewKey, NSKeyValueChangeOldKey,
|
||||
NSKeyValueObservingOptions, NSObject, NSObjectNSDelayedPerforming,
|
||||
NSKeyValueObservingOptions, NSNotificationCenter, NSObject, NSObjectNSDelayedPerforming,
|
||||
NSObjectNSKeyValueObserverRegistration, NSObjectProtocol, NSPoint, NSRect, NSSize, NSString,
|
||||
};
|
||||
use tracing::{trace, warn};
|
||||
@@ -170,7 +170,7 @@ declare_class!(
|
||||
#[method(windowDidResize:)]
|
||||
fn window_did_resize(&self, _: Option<&AnyObject>) {
|
||||
trace_scope!("windowDidResize:");
|
||||
// NOTE: WindowEvent::SurfaceResized is reported in frameDidChange.
|
||||
// NOTE: WindowEvent::SurfaceResized is reported using NSViewFrameDidChangeNotification.
|
||||
self.emit_move_event();
|
||||
}
|
||||
|
||||
@@ -658,9 +658,9 @@ fn new_window(
|
||||
|
||||
let view = WinitView::new(
|
||||
app_state,
|
||||
&window,
|
||||
attrs.platform_specific.accepts_first_mouse,
|
||||
attrs.platform_specific.option_as_alt,
|
||||
mtm,
|
||||
);
|
||||
|
||||
// The default value of `setWantsBestResolutionOpenGLSurface:` was `false` until
|
||||
@@ -682,6 +682,23 @@ fn new_window(
|
||||
window.setContentView(Some(&view));
|
||||
window.setInitialFirstResponder(Some(&view));
|
||||
|
||||
// Configure the view to send notifications whenever its frame rectangle changes.
|
||||
//
|
||||
// We explicitly do this _after_ setting the view as the content view of the window, to
|
||||
// avoid a resize event when creating the window.
|
||||
view.setPostsFrameChangedNotifications(true);
|
||||
// `setPostsFrameChangedNotifications` posts the notification immediately, so register the
|
||||
// observer _after_, again so that the event isn't triggered initially.
|
||||
let notification_center = unsafe { NSNotificationCenter::defaultCenter() };
|
||||
unsafe {
|
||||
notification_center.addObserver_selector_name_object(
|
||||
&view,
|
||||
sel!(viewFrameDidChangeNotification:),
|
||||
Some(NSViewFrameDidChangeNotification),
|
||||
Some(&view),
|
||||
)
|
||||
}
|
||||
|
||||
if attrs.transparent {
|
||||
window.setOpaque(false);
|
||||
// See `set_transparent` for details on why we do this.
|
||||
|
||||
Reference in New Issue
Block a user