Refactor macOS to use new objc2 features (#2465)

* Remove UnownedWindow::inner_rect

* Refactor custom view to use much less `unsafe`

The compiler fence is safe to get rid of now since `interpretKeyEvents` takes `&mut self`

* Refactor Window to use much less unsafe

* Refactor NSApplication usage to have much less unsafe

* Remove cocoa dependency

* Enable `deny(unsafe_op_in_unsafe_fn)` on macOS

Also re-enable clippy `let_unit_value` lint

* Remove #[macro_use] on macOS

* Refactor window delegate to use much less unsafe
This commit is contained in:
Mads Marquart 2022-09-08 16:45:29 +02:00 committed by GitHub
parent 05dd31b8ea
commit 340f951d10
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 2756 additions and 2335 deletions

View file

@ -1,14 +1,10 @@
use std::collections::VecDeque;
use cocoa::{
appkit::{self, NSEvent},
base::id,
};
use objc2::foundation::NSObject;
use objc2::{declare_class, ClassType};
use objc2::{declare_class, msg_send, ClassType};
use super::appkit::{NSApplication, NSResponder};
use super::{app_state::AppState, event::EventWrapper, util, DEVICE_ID};
use super::appkit::{NSApplication, NSEvent, NSEventModifierFlags, NSEventType, NSResponder};
use super::{app_state::AppState, event::EventWrapper, DEVICE_ID};
use crate::event::{DeviceEvent, ElementState, Event};
declare_class!(
@ -25,37 +21,33 @@ declare_class!(
// 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];
fn send_event(&self, event: &NSEvent) {
// 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.type_();
let modifier_flags = event.modifierFlags();
if event_type == NSEventType::NSKeyUp
&& modifier_flags.contains(NSEventModifierFlags::NSCommandKeyMask)
{
if let Some(key_window) = self.keyWindow() {
unsafe { key_window.sendEvent(event) };
}
} else {
maybe_dispatch_device_event(event);
unsafe { msg_send![super(self), sendEvent: event] }
}
}
}
);
unsafe fn maybe_dispatch_device_event(event: id) {
let event_type = event.eventType();
fn maybe_dispatch_device_event(event: &NSEvent) {
let event_type = event.type_();
match event_type {
appkit::NSMouseMoved
| appkit::NSLeftMouseDragged
| appkit::NSOtherMouseDragged
| appkit::NSRightMouseDragged => {
NSEventType::NSMouseMoved
| NSEventType::NSLeftMouseDragged
| NSEventType::NSOtherMouseDragged
| NSEventType::NSRightMouseDragged => {
let mut events = VecDeque::with_capacity(3);
let delta_x = event.deltaX() as f64;
@ -92,7 +84,9 @@ unsafe fn maybe_dispatch_device_event(event: id) {
AppState::queue_events(events);
}
appkit::NSLeftMouseDown | appkit::NSRightMouseDown | appkit::NSOtherMouseDown => {
NSEventType::NSLeftMouseDown
| NSEventType::NSRightMouseDown
| NSEventType::NSOtherMouseDown => {
let mut events = VecDeque::with_capacity(1);
events.push_back(EventWrapper::StaticEvent(Event::DeviceEvent {
@ -105,7 +99,7 @@ unsafe fn maybe_dispatch_device_event(event: id) {
AppState::queue_events(events);
}
appkit::NSLeftMouseUp | appkit::NSRightMouseUp | appkit::NSOtherMouseUp => {
NSEventType::NSLeftMouseUp | NSEventType::NSRightMouseUp | NSEventType::NSOtherMouseUp => {
let mut events = VecDeque::with_capacity(1);
events.push_back(EventWrapper::StaticEvent(Event::DeviceEvent {