Skip to content

Commit d2dc83d

Browse files
committed
All window events work!
1 parent 7c7fcc9 commit d2dc83d

File tree

7 files changed

+400
-278
lines changed

7 files changed

+400
-278
lines changed

src/platform_impl/macos/app.rs

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use cocoa::{appkit, base::id};
2+
use objc::{declare::ClassDecl, runtime::{Class, Object, Sel}};
3+
4+
use platform_impl::platform::util;
5+
6+
pub struct AppClass(pub *const Class);
7+
unsafe impl Send for AppClass {}
8+
unsafe impl Sync for AppClass {}
9+
10+
lazy_static! {
11+
pub static ref APP_CLASS: AppClass = unsafe {
12+
let superclass = class!(NSApplication);
13+
let mut decl = ClassDecl::new("WinitApp", superclass).unwrap();
14+
15+
decl.add_method(
16+
sel!(sendEvent:),
17+
send_event as extern fn(&Object, Sel, id),
18+
);
19+
20+
AppClass(decl.register())
21+
};
22+
}
23+
24+
// Normally, holding Cmd + any key never sends us a `keyUp` event for that key.
25+
// Overriding `sendEvent:` like this fixes that. (https://stackoverflow.com/a/15294196)
26+
// Fun fact: Firefox still has this bug! (https://bugzilla.mozilla.org/show_bug.cgi?id=1299553)
27+
extern fn send_event(this: &Object, _sel: Sel, event: id) {
28+
unsafe {
29+
use self::appkit::NSEvent;
30+
// For posterity, there are some undocumented event types
31+
// (https://github.com/servo/cocoa-rs/issues/155)
32+
// but that doesn't really matter here.
33+
let event_type = event.eventType();
34+
let modifier_flags = event.modifierFlags();
35+
if event_type == appkit::NSKeyUp && util::has_flag(
36+
modifier_flags,
37+
appkit::NSEventModifierFlags::NSCommandKeyMask,
38+
) {
39+
let key_window: id = msg_send![this, keyWindow];
40+
let _: () = msg_send![key_window, sendEvent:event];
41+
} else {
42+
let superclass = util::superclass(this);
43+
let _: () = msg_send![super(this, superclass), sendEvent:event];
44+
}
45+
}
46+
}

0 commit comments

Comments
 (0)