mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-11 13:31:29 +11:00
MacOS fix CursorEntered
and CursorLeft
events fired at old window size. (#1335)
* On macOS, Fix `CursorEntered` and `CursorLeft` * Add CHANGELOG Co-authored-by: Freya Gentz <zegentzy@protonmail.com>
This commit is contained in:
parent
d9bda3e985
commit
dd768fe655
|
@ -1,5 +1,6 @@
|
|||
# Unreleased
|
||||
|
||||
- On macOS, fix `CursorEntered` and `CursorLeft` events fired at old window size.
|
||||
- On macOS, fix error when `set_fullscreen` is called during fullscreen transition.
|
||||
- On all platforms except mobile and WASM, implement `Window::set_minimized`.
|
||||
- On X11, fix `CursorEntered` event being generated for non-winit windows.
|
||||
|
|
|
@ -9,7 +9,7 @@ use std::{
|
|||
use cocoa::{
|
||||
appkit::{NSApp, NSEvent, NSEventModifierFlags, NSEventPhase, NSView, NSWindow},
|
||||
base::{id, nil},
|
||||
foundation::{NSPoint, NSRect, NSSize, NSString, NSUInteger},
|
||||
foundation::{NSInteger, NSPoint, NSRect, NSSize, NSString, NSUInteger},
|
||||
};
|
||||
use objc::{
|
||||
declare::ClassDecl,
|
||||
|
@ -42,6 +42,7 @@ struct ViewState {
|
|||
raw_characters: Option<String>,
|
||||
is_key_down: bool,
|
||||
modifiers: ModifiersState,
|
||||
tracking_rect: Option<NSInteger>,
|
||||
}
|
||||
|
||||
pub fn new_view(ns_window: id) -> (IdRef, Weak<Mutex<util::Cursor>>) {
|
||||
|
@ -54,6 +55,7 @@ pub fn new_view(ns_window: id) -> (IdRef, Weak<Mutex<util::Cursor>>) {
|
|||
raw_characters: None,
|
||||
is_key_down: false,
|
||||
modifiers: Default::default(),
|
||||
tracking_rect: None,
|
||||
};
|
||||
unsafe {
|
||||
// This is free'd in `dealloc`
|
||||
|
@ -228,6 +230,10 @@ lazy_static! {
|
|||
sel!(cancelOperation:),
|
||||
cancel_operation as extern "C" fn(&Object, Sel, id),
|
||||
);
|
||||
decl.add_method(
|
||||
sel!(frameDidChange:),
|
||||
frame_did_change as extern "C" fn(&Object, Sel, id),
|
||||
);
|
||||
decl.add_ivar::<*mut c_void>("winitState");
|
||||
decl.add_ivar::<id>("markedText");
|
||||
let protocol = Protocol::get("NSTextInputClient").unwrap();
|
||||
|
@ -253,6 +259,19 @@ extern "C" fn init_with_winit(this: &Object, _sel: Sel, state: *mut c_void) -> i
|
|||
let marked_text =
|
||||
<id as NSMutableAttributedString>::init(NSMutableAttributedString::alloc(nil));
|
||||
(*this).set_ivar("markedText", marked_text);
|
||||
let _: () = msg_send![this, setPostsFrameChangedNotifications: YES];
|
||||
|
||||
let notification_center: &Object =
|
||||
msg_send![class!(NSNotificationCenter), defaultCenter];
|
||||
let notification_name =
|
||||
NSString::alloc(nil).init_str("NSViewFrameDidChangeNotification");
|
||||
let _: () = msg_send![
|
||||
notification_center,
|
||||
addObserver: this
|
||||
selector: sel!(frameDidChange:)
|
||||
name: notification_name
|
||||
object: this
|
||||
];
|
||||
}
|
||||
this
|
||||
}
|
||||
|
@ -261,17 +280,46 @@ extern "C" fn init_with_winit(this: &Object, _sel: Sel, state: *mut c_void) -> i
|
|||
extern "C" fn view_did_move_to_window(this: &Object, _sel: Sel) {
|
||||
trace!("Triggered `viewDidMoveToWindow`");
|
||||
unsafe {
|
||||
let state_ptr: *mut c_void = *this.get_ivar("winitState");
|
||||
let state = &mut *(state_ptr as *mut ViewState);
|
||||
|
||||
if let Some(tracking_rect) = state.tracking_rect.take() {
|
||||
let _: () = msg_send![this, removeTrackingRect: tracking_rect];
|
||||
}
|
||||
|
||||
let rect: NSRect = msg_send![this, visibleRect];
|
||||
let _: () = msg_send![this,
|
||||
let tracking_rect: NSInteger = msg_send![this,
|
||||
addTrackingRect:rect
|
||||
owner:this
|
||||
userData:nil
|
||||
assumeInside:NO
|
||||
];
|
||||
state.tracking_rect = Some(tracking_rect);
|
||||
}
|
||||
trace!("Completed `viewDidMoveToWindow`");
|
||||
}
|
||||
|
||||
extern "C" fn frame_did_change(this: &Object, _sel: Sel, _event: id) {
|
||||
unsafe {
|
||||
let state_ptr: *mut c_void = *this.get_ivar("winitState");
|
||||
let state = &mut *(state_ptr as *mut ViewState);
|
||||
|
||||
if let Some(tracking_rect) = state.tracking_rect.take() {
|
||||
let _: () = msg_send![this, removeTrackingRect: tracking_rect];
|
||||
}
|
||||
|
||||
let rect: NSRect = msg_send![this, visibleRect];
|
||||
let tracking_rect: NSInteger = msg_send![this,
|
||||
addTrackingRect:rect
|
||||
owner:this
|
||||
userData:nil
|
||||
assumeInside:NO
|
||||
];
|
||||
|
||||
state.tracking_rect = Some(tracking_rect);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" fn draw_rect(this: &Object, _sel: Sel, rect: NSRect) {
|
||||
unsafe {
|
||||
let state_ptr: *mut c_void = *this.get_ivar("winitState");
|
||||
|
|
Loading…
Reference in a new issue