Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ uuid = { version = "0.8", features = ["v4"], optional = true }
[target.'cfg(target_os="macos")'.dependencies]
cocoa = "0.24.0"
core-foundation = "0.9.1"
objc = "0.2.7"
objc2 = "0.6"
uuid = { version = "0.8", features = ["v4"] }

[dev-dependencies]
Expand Down
22 changes: 10 additions & 12 deletions src/gl/macos.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
// This is required because the objc crate is causing a lot of warnings: https://github.com/SSheldon/rust-objc/issues/125
// Eventually we should migrate to the objc2 crate and remove this.
#![allow(unexpected_cfgs)]

use std::ffi::c_void;
use std::str::FromStr;

Expand All @@ -21,7 +17,8 @@ use core_foundation::base::TCFType;
use core_foundation::bundle::{CFBundleGetBundleWithIdentifier, CFBundleGetFunctionPointerForName};
use core_foundation::string::CFString;

use objc::{msg_send, sel, sel_impl};
use objc2::msg_send;
use objc2::runtime::AnyObject;

use super::{GlConfig, GlError, Profile};

Expand Down Expand Up @@ -98,15 +95,16 @@ impl GlContext {
NSOpenGLView::display_(view);
parent_view.addSubview_(view);

let context: id = msg_send![view, openGLContext];
let () = msg_send![context, retain];
let context_any: *mut AnyObject = msg_send![view as *mut AnyObject, openGLContext];
let _: *mut AnyObject = msg_send![context_any, retain];
let context: id = context_any as id;

context.setValues_forParameter_(
&(config.vsync as i32),
NSOpenGLContextParameter::NSOpenGLCPSwapInterval,
);

let () = msg_send![pixel_format, release];
let () = msg_send![pixel_format as *mut AnyObject, release];

Ok(GlContext { view, context })
}
Expand All @@ -131,24 +129,24 @@ impl GlContext {
pub fn swap_buffers(&self) {
unsafe {
self.context.flushBuffer();
let () = msg_send![self.view, setNeedsDisplay: YES];
let () = msg_send![self.view as *mut AnyObject, setNeedsDisplay: YES];
}
}

/// On macOS the `NSOpenGLView` needs to be resized separtely from our main view.
pub(crate) fn resize(&self, size: NSSize) {
unsafe { NSView::setFrameSize(self.view, size) };
unsafe {
let _: () = msg_send![self.view, setNeedsDisplay: YES];
let _: () = msg_send![self.view as *mut AnyObject, setNeedsDisplay: YES];
}
}
}

impl Drop for GlContext {
fn drop(&mut self) {
unsafe {
let () = msg_send![self.context, release];
let () = msg_send![self.view, release];
let () = msg_send![self.context as *mut AnyObject, release];
let () = msg_send![self.view as *mut AnyObject, release];
}
}
}
36 changes: 32 additions & 4 deletions src/macos/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ use cocoa::appkit::{NSEvent, NSEventModifierFlags, NSEventType};
use cocoa::base::id;
use cocoa::foundation::NSString;
use keyboard_types::{Code, Key, KeyState, KeyboardEvent, Modifiers};
use objc::{msg_send, sel, sel_impl};
use objc2::msg_send;
use objc2::runtime::AnyObject;

use crate::keyboard::code_to_location;

Expand Down Expand Up @@ -282,10 +283,23 @@ impl KeyboardState {
pub(crate) fn process_native_event(&self, event: id) -> Option<KeyboardEvent> {
unsafe {
let event_type = event.eventType();
let key_code = event.keyCode();
let raw_mods = event.modifierFlags();
// `-[NSEvent keyCode]` is documented to raise
// `NSInternalInconsistencyException` when sent to non-key events.
// AppKit occasionally dispatches non-key events into
// `keyDown:` / `keyUp:` / `flagsChanged:` selectors
// (e.g. `NSAppKitDefined`, `NSSystemDefined`, or sync events
// around Cmd-Tab / input-source switches), so gate the call.
// Without this gate, the exception unwinds out of the
// `extern "C-unwind"` callback and silently swallows the event.
let key_code = match event_type {
NSEventType::NSKeyDown | NSEventType::NSKeyUp | NSEventType::NSFlagsChanged => {
event.keyCode()
}
_ => return None,
};
let code = key_code_to_code(key_code);
let location = code_to_location(code);
let raw_mods = event.modifierFlags();
let modifiers = make_modifiers(raw_mods);
let state = match event_type {
NSEventType::NSKeyDown => KeyState::Down,
Expand All @@ -311,10 +325,24 @@ impl KeyboardState {
return None;
}
}
// Already filtered above; reachable only via newly-introduced
// event types we haven't taught the layer above about.
_ => unreachable!(),
};
let is_composing = false;
let repeat: bool = event_type == NSEventType::NSKeyDown && msg_send![event, isARepeat];
// `-[NSEvent isARepeat]` is documented to raise
// `NSInternalInconsistencyException` when sent to anything other
// than keyDown/keyUp. Gate the query on the event types that
// actually carry a meaningful repeat flag — without this gate,
// the exception unwinds out of the `extern "C-unwind"` callback
// on every `flagsChanged:` press, dropping the modifier-state
// KeyboardEvent that downstream layers (e.g. baseview consumers
// that track Alt/Cmd/Shift via flagsChanged) rely on.
let repeat: bool = if event_type == NSEventType::NSKeyDown {
msg_send![event as *mut AnyObject, isARepeat]
} else {
false
};
let key = if let Some(key) = code_to_key(code) {
key
} else {
Expand Down
4 changes: 0 additions & 4 deletions src/macos/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
// This is required because the objc crate is causing a lot of warnings: https://github.com/SSheldon/rust-objc/issues/125
// Eventually we should migrate to the objc2 crate and remove this.
#![allow(unexpected_cfgs)]

mod keyboard;
mod view;
mod window;
Expand Down
Loading