Clean up macOS class declaration (#2458)
* Begin abstraction over AppKit * Clean up NSApplication delegate declaration * Clean up NSApplication override declaration * Clean up NSWindow delegate declaration * Clean up NSWindow override declaration * Clean up NSView delegate declaration
This commit is contained in:
parent
112965b4ff
commit
d67c928120
15 changed files with 873 additions and 1013 deletions
|
|
@ -4,53 +4,50 @@ use cocoa::{
|
|||
appkit::{self, NSEvent},
|
||||
base::id,
|
||||
};
|
||||
use objc::{
|
||||
declare::ClassBuilder,
|
||||
runtime::{Class, Object, Sel},
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
use objc2::foundation::NSObject;
|
||||
use objc2::{declare_class, ClassType};
|
||||
|
||||
use super::appkit::{NSApplication, NSResponder};
|
||||
use super::{app_state::AppState, event::EventWrapper, util, DEVICE_ID};
|
||||
use crate::event::{DeviceEvent, ElementState, Event};
|
||||
|
||||
pub struct AppClass(pub *const Class);
|
||||
unsafe impl Send for AppClass {}
|
||||
unsafe impl Sync for AppClass {}
|
||||
declare_class!(
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub(super) struct WinitApplication {}
|
||||
|
||||
pub static APP_CLASS: Lazy<AppClass> = Lazy::new(|| unsafe {
|
||||
let superclass = class!(NSApplication);
|
||||
let mut decl = ClassBuilder::new("WinitApp", superclass).unwrap();
|
||||
unsafe impl ClassType for WinitApplication {
|
||||
#[inherits(NSResponder, NSObject)]
|
||||
type Super = NSApplication;
|
||||
}
|
||||
|
||||
decl.add_method(sel!(sendEvent:), send_event as extern "C" fn(_, _, _));
|
||||
|
||||
AppClass(decl.register())
|
||||
});
|
||||
|
||||
// Normally, holding Cmd + any key never sends us a `keyUp` event for that key.
|
||||
// Overriding `sendEvent:` like this fixes that. (https://stackoverflow.com/a/15294196)
|
||||
// Fun fact: Firefox still has this bug! (https://bugzilla.mozilla.org/show_bug.cgi?id=1299553)
|
||||
extern "C" fn send_event(this: &Object, _sel: Sel, event: id) {
|
||||
unsafe {
|
||||
// For posterity, there are some undocumented event types
|
||||
// (https://github.com/servo/cocoa-rs/issues/155)
|
||||
// but that doesn't really matter here.
|
||||
let event_type = event.eventType();
|
||||
let modifier_flags = event.modifierFlags();
|
||||
if event_type == appkit::NSKeyUp
|
||||
&& util::has_flag(
|
||||
modifier_flags,
|
||||
appkit::NSEventModifierFlags::NSCommandKeyMask,
|
||||
)
|
||||
{
|
||||
let key_window: id = msg_send![this, keyWindow];
|
||||
let _: () = msg_send![key_window, sendEvent: event];
|
||||
} else {
|
||||
maybe_dispatch_device_event(event);
|
||||
let superclass = util::superclass(this);
|
||||
let _: () = msg_send![super(this, superclass), sendEvent: event];
|
||||
unsafe impl WinitApplication {
|
||||
// Normally, holding Cmd + any key never sends us a `keyUp` event for that key.
|
||||
// Overriding `sendEvent:` like this fixes that. (https://stackoverflow.com/a/15294196)
|
||||
// Fun fact: Firefox still has this bug! (https://bugzilla.mozilla.org/show_bug.cgi?id=1299553)
|
||||
#[sel(sendEvent:)]
|
||||
fn send_event(&self, event: id) {
|
||||
unsafe {
|
||||
// For posterity, there are some undocumented event types
|
||||
// (https://github.com/servo/cocoa-rs/issues/155)
|
||||
// but that doesn't really matter here.
|
||||
let event_type = event.eventType();
|
||||
let modifier_flags = event.modifierFlags();
|
||||
if event_type == appkit::NSKeyUp
|
||||
&& util::has_flag(
|
||||
modifier_flags,
|
||||
appkit::NSEventModifierFlags::NSCommandKeyMask,
|
||||
)
|
||||
{
|
||||
let key_window: id = msg_send![self, keyWindow];
|
||||
let _: () = msg_send![key_window, sendEvent: event];
|
||||
} else {
|
||||
maybe_dispatch_device_event(event);
|
||||
let _: () = msg_send![super(self), sendEvent: event];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
unsafe fn maybe_dispatch_device_event(event: id) {
|
||||
let event_type = event.eventType();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue