chore: update to objc2 frameworks v0.3.2

This commit is contained in:
Mads Marquart 2025-08-21 15:58:55 +02:00 committed by Kirill Chibisov
parent d815bc089c
commit b811e9d878
13 changed files with 227 additions and 267 deletions

View file

@ -55,12 +55,12 @@ ndk = { version = "0.9.0", features = ["rwh_06"], default-features = false }
block2 = "0.6.1"
dispatch2 = { version = "0.3.0", default-features = false, features = ["std", "objc2"] }
objc2 = { version = "0.6.1", features = ["relax-sign-encoding"] }
objc2-app-kit = { version = "0.3.1", default-features = false }
objc2-core-foundation = { version = "0.3.1", default-features = false }
objc2-core-graphics = { version = "0.3.1", default-features = false }
objc2-core-video = { version = "0.3.1", default-features = false }
objc2-foundation = { version = "0.3.1", default-features = false }
objc2-ui-kit = { version = "0.3.1", default-features = false }
objc2-app-kit = { version = "0.3.2", default-features = false }
objc2-core-foundation = { version = "0.3.2", default-features = false }
objc2-core-graphics = { version = "0.3.2", default-features = false }
objc2-core-video = { version = "0.3.2", default-features = false }
objc2-foundation = { version = "0.3.2", default-features = false }
objc2-ui-kit = { version = "0.3.2", default-features = false }
# Windows dependencies.
unicode-segmentation = "1.7.1"

View file

@ -30,8 +30,8 @@ extern "C-unwind" fn send_event(app: &NSApplication, sel: Sel, 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 = unsafe { event.r#type() };
let modifier_flags = unsafe { event.modifierFlags() };
let event_type = event.r#type();
let modifier_flags = event.modifierFlags();
if event_type == NSEventType::KeyUp && modifier_flags.contains(NSEventModifierFlags::Command) {
if let Some(key_window) = app.keyWindow() {
key_window.sendEvent(event);
@ -98,15 +98,15 @@ pub(crate) fn override_send_event(global_app: &NSApplication) {
}
fn maybe_dispatch_device_event(app_state: &Rc<AppState>, event: &NSEvent) {
let event_type = unsafe { event.r#type() };
let event_type = event.r#type();
#[allow(non_upper_case_globals)]
match event_type {
NSEventType::MouseMoved
| NSEventType::LeftMouseDragged
| NSEventType::OtherMouseDragged
| NSEventType::RightMouseDragged => {
let delta_x = unsafe { event.deltaX() } as f64;
let delta_y = unsafe { event.deltaY() } as f64;
let delta_x = event.deltaX() as f64;
let delta_y = event.deltaY() as f64;
if delta_x != 0.0 || delta_y != 0.0 {
app_state.maybe_queue_with_handler(move |app, event_loop| {
@ -117,7 +117,7 @@ fn maybe_dispatch_device_event(app_state: &Rc<AppState>, event: &NSEvent) {
}
},
NSEventType::LeftMouseDown | NSEventType::RightMouseDown | NSEventType::OtherMouseDown => {
let button = unsafe { event.buttonNumber() } as u32;
let button = event.buttonNumber() as u32;
app_state.maybe_queue_with_handler(move |app, event_loop| {
app.device_event(event_loop, None, DeviceEvent::Button {
button,
@ -126,7 +126,7 @@ fn maybe_dispatch_device_event(app_state: &Rc<AppState>, event: &NSEvent) {
});
},
NSEventType::LeftMouseUp | NSEventType::RightMouseUp | NSEventType::OtherMouseUp => {
let button = unsafe { event.buttonNumber() } as u32;
let button = event.buttonNumber() as u32;
app_state.maybe_queue_with_handler(move |app, event_loop| {
app.device_event(event_loop, None, DeviceEvent::Button {
button,
@ -153,16 +153,14 @@ mod tests {
let Some(mtm) = MainThreadMarker::new() else { return };
// Create a new application, without making it the shared application.
let app = unsafe { NSApplication::new(mtm) };
let app = NSApplication::new(mtm);
override_send_event(&app);
// Test calling twice works.
override_send_event(&app);
// FIXME(madsmtm): Can't test this yet, need some way to mock AppState.
// unsafe {
// let event = super::super::event::dummy_event().unwrap();
// app.sendEvent(&event)
// }
// let event = super::super::event::dummy_event().unwrap();
// app.sendEvent(&event)
}
#[test]

View file

@ -117,7 +117,7 @@ impl AppState {
// - https://github.com/rust-windowing/winit/issues/261
// - https://github.com/rust-windowing/winit/issues/3958
let is_bundled =
unsafe { NSRunningApplication::currentApplication().bundleIdentifier().is_some() };
NSRunningApplication::currentApplication().bundleIdentifier().is_some();
if !is_bundled {
app.setActivationPolicy(NSApplicationActivationPolicy::Regular);
}

View file

@ -62,10 +62,8 @@ pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Result<Retained<NSCurso
unsafe { slice::from_raw_parts_mut(bitmap.bitmapData(), cursor.buffer().len()) };
bitmap_data.copy_from_slice(cursor.buffer());
let image = unsafe {
NSImage::initWithSize(NSImage::alloc(), NSSize::new(width.into(), height.into()))
};
unsafe { image.addRepresentation(&bitmap) };
let image = NSImage::initWithSize(NSImage::alloc(), NSSize::new(width.into(), height.into()));
image.addRepresentation(&bitmap);
let hotspot = NSPoint::new(cursor.hotspot_x() as f64, cursor.hotspot_y() as f64);
@ -140,12 +138,9 @@ unsafe fn load_webkit_cursor(name: &NSString) -> Retained<NSCursor> {
// TODO: Handle PLists better
let info_path = cursor_path.stringByAppendingPathComponent(ns_string!("info.plist"));
let info: Retained<NSDictionary<NSObject, NSObject>> = unsafe {
msg_send![
<NSDictionary<NSObject, NSObject>>::class(),
dictionaryWithContentsOfFile: &*info_path,
]
};
#[allow(deprecated)]
let info: Retained<NSDictionary<NSObject, NSObject>> =
unsafe { NSDictionary::dictionaryWithContentsOfFile(&info_path) }.unwrap();
let mut x = 0.0;
if let Some(n) = info.objectForKey(ns_string!("hotx")) {
if let Ok(n) = n.downcast::<NSNumber>() {
@ -216,9 +211,9 @@ pub(crate) fn cursor_from_icon(icon: CursorIcon) -> Retained<NSCursor> {
CursorIcon::EwResize | CursorIcon::ColResize => NSCursor::resizeLeftRightCursor(),
CursorIcon::NsResize | CursorIcon::RowResize => NSCursor::resizeUpDownCursor(),
CursorIcon::Help => _helpCursor(),
CursorIcon::ZoomIn if available!(macos = 15.0) => unsafe { NSCursor::zoomInCursor() },
CursorIcon::ZoomIn if available!(macos = 15.0) => NSCursor::zoomInCursor(),
CursorIcon::ZoomIn => _zoomInCursor(),
CursorIcon::ZoomOut if available!(macos = 15.0) => unsafe { NSCursor::zoomOutCursor() },
CursorIcon::ZoomOut if available!(macos = 15.0) => NSCursor::zoomOutCursor(),
CursorIcon::ZoomOut => _zoomOutCursor(),
CursorIcon::NeResize => _windowResizeNorthEastCursor(),
CursorIcon::NwResize => _windowResizeNorthWestCursor(),

View file

@ -67,9 +67,7 @@ pub fn get_modifierless_char(scancode: u16) -> Key {
// Ignores all modifiers except for SHIFT (yes, even ALT is ignored).
fn get_logical_key_char(ns_event: &NSEvent, modifierless_chars: &str) -> Key {
let string = unsafe { ns_event.charactersIgnoringModifiers() }
.map(|s| s.to_string())
.unwrap_or_default();
let string = ns_event.charactersIgnoringModifiers().map(|s| s.to_string()).unwrap_or_default();
if string.is_empty() {
// Probably a dead key
let first_char = modifierless_chars.chars().next();
@ -85,7 +83,7 @@ pub(crate) fn create_key_event(ns_event: &NSEvent, is_press: bool, is_repeat: bo
use ElementState::{Pressed, Released};
let state = if is_press { Pressed } else { Released };
let scancode = unsafe { ns_event.keyCode() };
let scancode = ns_event.keyCode();
let mut physical_key = scancode_to_physicalkey(scancode as u32);
// NOTE: The logical key should heed both SHIFT and ALT if possible.
@ -95,7 +93,7 @@ pub(crate) fn create_key_event(ns_event: &NSEvent, is_press: bool, is_repeat: bo
// * Pressing CTRL SHIFT A: logical key should also be "A"
// This is not easy to tease out of `NSEvent`, but we do our best.
let characters = unsafe { ns_event.characters() }.map(|s| s.to_string()).unwrap_or_default();
let characters = ns_event.characters().map(|s| s.to_string()).unwrap_or_default();
let text_with_all_modifiers = if characters.is_empty() {
None
} else {
@ -111,7 +109,7 @@ pub(crate) fn create_key_event(ns_event: &NSEvent, is_press: bool, is_repeat: bo
// `get_modifierless_char/key_without_modifiers` ignores ALL modifiers.
let key_without_modifiers = get_modifierless_char(scancode);
let modifiers = unsafe { ns_event.modifierFlags() };
let modifiers = ns_event.modifierFlags();
let has_ctrl = modifiers.contains(NSEventModifierFlags::Control);
let has_cmd = modifiers.contains(NSEventModifierFlags::Command);
@ -302,15 +300,15 @@ const NX_DEVICERALTKEYMASK: NSEventModifierFlags = NSEventModifierFlags(0x000000
const NX_DEVICERCTLKEYMASK: NSEventModifierFlags = NSEventModifierFlags(0x00002000);
pub(super) fn lalt_pressed(event: &NSEvent) -> bool {
unsafe { event.modifierFlags() }.contains(NX_DEVICELALTKEYMASK)
event.modifierFlags().contains(NX_DEVICELALTKEYMASK)
}
pub(super) fn ralt_pressed(event: &NSEvent) -> bool {
unsafe { event.modifierFlags() }.contains(NX_DEVICERALTKEYMASK)
event.modifierFlags().contains(NX_DEVICERALTKEYMASK)
}
pub(super) fn event_mods(event: &NSEvent) -> Modifiers {
let flags = unsafe { event.modifierFlags() };
let flags = event.modifierFlags();
let mut state = ModifiersState::empty();
let mut pressed_mods = ModifiersKeys::empty();
@ -334,8 +332,7 @@ pub(super) fn event_mods(event: &NSEvent) -> Modifiers {
}
pub(super) fn dummy_event() -> Option<Retained<NSEvent>> {
unsafe {
NSEvent::otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2(
NSEvent::otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2(
NSEventType::ApplicationDefined,
NSPoint::new(0.0, 0.0),
NSEventModifierFlags(0),
@ -346,7 +343,6 @@ pub(super) fn dummy_event() -> Option<Retained<NSEvent>> {
0,
0,
)
}
}
pub fn physicalkey_to_scancode(physical_key: PhysicalKey) -> Option<u32> {

View file

@ -191,7 +191,7 @@ impl EventLoop {
// Override `sendEvent:` on the application to forward to our application state.
override_send_event(&app);
let center = unsafe { NSNotificationCenter::defaultCenter() };
let center = NSNotificationCenter::defaultCenter();
let weak_app_state = Rc::downgrade(&app_state);
let _did_finish_launching_observer = create_observer(

View file

@ -82,7 +82,7 @@ pub fn initialize(app: &NSApplication) {
app_menu.addItem(&quit_item);
app_menu_item.setSubmenu(Some(&app_menu));
unsafe { app.setServicesMenu(Some(&services_menu)) };
app.setServicesMenu(Some(&services_menu));
app.setMainMenu(Some(&menubar));
}

View file

@ -65,35 +65,33 @@ impl VideoModeHandle {
native_mode: NativeDisplayMode,
refresh_rate_millihertz: Option<NonZeroU32>,
) -> Self {
unsafe {
// The bit-depth is basically always 32 since macOS 10.12.
#[allow(deprecated)]
let pixel_encoding =
CGDisplayMode::pixel_encoding(Some(&native_mode.0)).unwrap().to_string();
let bit_depth = if pixel_encoding.eq_ignore_ascii_case(ffi::IO32BitDirectPixels) {
NonZeroU16::new(32)
} else if pixel_encoding.eq_ignore_ascii_case(ffi::IO16BitDirectPixels) {
NonZeroU16::new(16)
} else if pixel_encoding.eq_ignore_ascii_case(ffi::kIO30BitDirectPixels) {
NonZeroU16::new(30)
} else if pixel_encoding.eq_ignore_ascii_case(ffi::kIO64BitDirectPixels) {
NonZeroU16::new(64)
} else {
warn!(?pixel_encoding, "unknown bit depth");
None
};
// The bit-depth is basically always 32 since macOS 10.12.
#[allow(deprecated)]
let pixel_encoding =
CGDisplayMode::pixel_encoding(Some(&native_mode.0)).unwrap().to_string();
let bit_depth = if pixel_encoding.eq_ignore_ascii_case(ffi::IO32BitDirectPixels) {
NonZeroU16::new(32)
} else if pixel_encoding.eq_ignore_ascii_case(ffi::IO16BitDirectPixels) {
NonZeroU16::new(16)
} else if pixel_encoding.eq_ignore_ascii_case(ffi::kIO30BitDirectPixels) {
NonZeroU16::new(30)
} else if pixel_encoding.eq_ignore_ascii_case(ffi::kIO64BitDirectPixels) {
NonZeroU16::new(64)
} else {
warn!(?pixel_encoding, "unknown bit depth");
None
};
let mode = VideoMode::new(
PhysicalSize::new(
CGDisplayMode::pixel_width(Some(&native_mode.0)) as u32,
CGDisplayMode::pixel_height(Some(&native_mode.0)) as u32,
),
bit_depth,
refresh_rate_millihertz,
);
let mode = VideoMode::new(
PhysicalSize::new(
CGDisplayMode::pixel_width(Some(&native_mode.0)) as u32,
CGDisplayMode::pixel_height(Some(&native_mode.0)) as u32,
),
bit_depth,
refresh_rate_millihertz,
);
VideoModeHandle { mode, monitor: monitor.clone(), native_mode }
}
Self { mode, monitor: monitor.clone(), native_mode }
}
}
@ -137,7 +135,7 @@ impl MonitorHandle {
fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
let current_display_mode =
NativeDisplayMode(unsafe { CGDisplayCopyDisplayMode(self.display_id()) }.unwrap());
NativeDisplayMode(CGDisplayCopyDisplayMode(self.display_id()).unwrap());
refresh_rate_millihertz(self.display_id(), &current_display_mode)
}
@ -159,7 +157,7 @@ impl MonitorHandle {
};
modes.into_iter().map(move |mode| {
let cg_refresh_rate_hertz = unsafe { CGDisplayMode::refresh_rate(Some(&mode)) };
let cg_refresh_rate_hertz = CGDisplayMode::refresh_rate(Some(&mode));
// CGDisplayModeGetRefreshRate returns 0.0 for any display that
// isn't a CRT
@ -202,7 +200,7 @@ impl MonitorHandleProvider for MonitorHandle {
//
// <https://github.com/glfw/glfw/blob/57cbded0760a50b9039ee0cb3f3c14f60145567c/src/cocoa_monitor.m#L44-L126>
fn name(&self) -> Option<std::borrow::Cow<'_, str>> {
let screen_num = unsafe { CGDisplayModelNumber(self.display_id()) };
let screen_num = CGDisplayModelNumber(self.display_id());
Some(format!("Monitor #{screen_num}").into())
}
@ -210,7 +208,7 @@ impl MonitorHandleProvider for MonitorHandle {
// This is already in screen coordinates. If we were using `NSScreen`,
// then a conversion would've been needed:
// flip_window_screen_coordinates(self.ns_screen(mtm)?.frame())
let bounds = unsafe { CGDisplayBounds(self.display_id()) };
let bounds = CGDisplayBounds(self.display_id());
let position = LogicalPosition::new(bounds.origin.x, bounds.origin.y);
Some(position.to_physical(self.scale_factor()))
}
@ -225,8 +223,7 @@ impl MonitorHandleProvider for MonitorHandle {
}
fn current_video_mode(&self) -> Option<VideoMode> {
let mode =
NativeDisplayMode(unsafe { CGDisplayCopyDisplayMode(self.display_id()) }.unwrap());
let mode = NativeDisplayMode(CGDisplayCopyDisplayMode(self.display_id()).unwrap());
let refresh_rate_millihertz = refresh_rate_millihertz(self.display_id(), &mode);
Some(VideoModeHandle::new(self.clone(), mode, refresh_rate_millihertz).mode)
}
@ -264,7 +261,7 @@ pub fn available_monitors() -> VecDeque<MonitorHandle> {
pub fn primary_monitor() -> MonitorHandle {
// Display ID just fetched from `CGMainDisplayID`, should be fine to unwrap.
MonitorHandle::new(unsafe { CGMainDisplayID() }).expect("invalid display ID")
MonitorHandle::new(CGMainDisplayID()).expect("invalid display ID")
}
impl fmt::Debug for MonitorHandle {
@ -315,40 +312,38 @@ pub(crate) fn flip_window_screen_coordinates(frame: NSRect) -> NSPoint {
// It is intentional that we use `CGMainDisplayID` (as opposed to
// `NSScreen::mainScreen`), because that's what the screen coordinates
// are relative to, no matter which display the window is currently on.
let main_screen_height = unsafe { CGDisplayBounds(CGMainDisplayID()) }.size.height;
let main_screen_height = CGDisplayBounds(CGMainDisplayID()).size.height;
let y = main_screen_height - frame.size.height - frame.origin.y;
NSPoint::new(frame.origin.x, y)
}
fn refresh_rate_millihertz(id: CGDirectDisplayID, mode: &NativeDisplayMode) -> Option<NonZeroU32> {
unsafe {
let refresh_rate = CGDisplayMode::refresh_rate(Some(&mode.0));
if refresh_rate > 0.0 {
return NonZeroU32::new((refresh_rate * 1000.0).round() as u32);
}
let mut display_link = std::ptr::null_mut();
#[allow(deprecated)]
if CVDisplayLink::create_with_cg_display(id, NonNull::from(&mut display_link))
!= kCVReturnSuccess
{
return None;
}
let display_link = CFRetained::from_raw(NonNull::new(display_link).unwrap());
#[allow(deprecated)]
let time = display_link.nominal_output_video_refresh_period();
// This value is indefinite if an invalid display link was specified
if time.flags & CVTimeFlags::IsIndefinite.0 != 0 {
return None;
}
(time.timeScale as i64)
.checked_div(time.timeValue)
.map(|v| (v * 1000) as u32)
.and_then(NonZeroU32::new)
let refresh_rate = CGDisplayMode::refresh_rate(Some(&mode.0));
if refresh_rate > 0.0 {
return NonZeroU32::new((refresh_rate * 1000.0).round() as u32);
}
let mut display_link = std::ptr::null_mut();
#[allow(deprecated)]
if unsafe { CVDisplayLink::create_with_cg_display(id, NonNull::from(&mut display_link)) }
!= kCVReturnSuccess
{
return None;
}
let display_link = unsafe { CFRetained::from_raw(NonNull::new(display_link).unwrap()) };
#[allow(deprecated)]
let time = display_link.nominal_output_video_refresh_period();
// This value is indefinite if an invalid display link was specified
if time.flags & CVTimeFlags::IsIndefinite.0 != 0 {
return None;
}
(time.timeScale as i64)
.checked_div(time.timeValue)
.map(|v| (v * 1000) as u32)
.and_then(NonZeroU32::new)
}
#[cfg(test)]
@ -395,7 +390,7 @@ mod tests {
// Assertion failed: (did_initialize), function CGS_REQUIRE_INIT, file CGInitialization.c, line 44.
// ```
// See https://github.com/JXA-Cookbook/JXA-Cookbook/issues/27#issuecomment-277517668
let _ = unsafe { CGMainDisplayID() };
let _ = CGMainDisplayID();
let handle = MonitorHandle(CFUUID::new(None).unwrap());
assert_eq!(handle.display_id(), 0);

View file

@ -292,7 +292,7 @@ define_class!(
self.queue_event(WindowEvent::Ime(Ime::Enabled));
}
if unsafe { self.hasMarkedText() } {
if self.hasMarkedText() {
self.ivars().ime_state.set(ImeState::Preedit);
} else {
// In case the preedit was cleared, set IME into the Ground state.
@ -305,8 +305,8 @@ define_class!(
None
} else {
// Convert the selected range from UTF-16 indices to UTF-8 indices.
let sub_string_a = unsafe { string.substringToIndex(selected_range.location) };
let sub_string_b = unsafe { string.substringToIndex(selected_range.end()) };
let sub_string_a = string.substringToIndex(selected_range.location);
let sub_string_b = string.substringToIndex(selected_range.end());
let lowerbound_utf8 = sub_string_a.len();
let upperbound_utf8 = sub_string_b.len();
Some((lowerbound_utf8, upperbound_utf8))
@ -391,7 +391,7 @@ define_class!(
let is_control = string.chars().next().is_some_and(|c| c.is_control());
// Commit only if we have marked text.
if unsafe { self.hasMarkedText() } && self.is_ime_enabled() && !is_control {
if self.hasMarkedText() && self.is_ime_enabled() && !is_control {
self.queue_event(WindowEvent::Ime(Ime::Preedit(String::new(), None)));
self.queue_event(WindowEvent::Ime(Ime::Commit(string)));
self.ivars().ime_state.set(ImeState::Committed);
@ -414,8 +414,7 @@ define_class!(
self.ivars().forward_key_to_app.set(true);
if unsafe { self.hasMarkedText() } && self.ivars().ime_state.get() == ImeState::Preedit
{
if self.hasMarkedText() && self.ivars().ime_state.get() == ImeState::Preedit {
// Leave preedit so that we also report the key-up for this key.
self.ivars().ime_state.set(ImeState::Ground);
}
@ -467,7 +466,7 @@ define_class!(
// is not handled by IME and should be handled by the application)
if self.ivars().ime_capabilities.get().is_some() {
let events_for_nsview = NSArray::from_slice(&[&*event]);
unsafe { self.interpretKeyEvents(&events_for_nsview) };
self.interpretKeyEvents(&events_for_nsview);
// If the text was committed we must treat the next keyboard event as IME related.
if self.ivars().ime_state.get() == ImeState::Committed {
@ -490,7 +489,7 @@ define_class!(
};
if !had_ime_input || self.ivars().forward_key_to_app.get() {
let key_event = create_key_event(&event, true, unsafe { event.isARepeat() });
let key_event = create_key_event(&event, true, event.isARepeat());
self.queue_event(WindowEvent::KeyboardInput {
device_id: None,
event: key_event,
@ -557,7 +556,7 @@ define_class!(
.expect("could not find current event");
self.update_modifiers(&event, false);
let event = create_key_event(&event, true, unsafe { event.isARepeat() });
let event = create_key_event(&event, true, event.isARepeat());
self.queue_event(WindowEvent::KeyboardInput {
device_id: None,
@ -676,8 +675,8 @@ define_class!(
self.mouse_motion(event);
let delta = {
let (x, y) = unsafe { (event.scrollingDeltaX(), event.scrollingDeltaY()) };
if unsafe { event.hasPreciseScrollingDeltas() } {
let (x, y) = (event.scrollingDeltaX(), event.scrollingDeltaY());
if event.hasPreciseScrollingDeltas() {
let delta = LogicalPosition::new(x, y).to_physical(self.scale_factor());
MouseScrollDelta::PixelDelta(delta)
} else {
@ -690,10 +689,10 @@ define_class!(
// momentum phase is recorded (or rather, the started/ended cases of the
// momentum phase) then we report the touch phase.
#[allow(non_upper_case_globals)]
let phase = match unsafe { event.momentumPhase() } {
let phase = match event.momentumPhase() {
NSEventPhase::MayBegin | NSEventPhase::Began => TouchPhase::Started,
NSEventPhase::Ended | NSEventPhase::Cancelled => TouchPhase::Ended,
_ => match unsafe { event.phase() } {
_ => match event.phase() {
NSEventPhase::MayBegin | NSEventPhase::Began => TouchPhase::Started,
NSEventPhase::Ended | NSEventPhase::Cancelled => TouchPhase::Ended,
_ => TouchPhase::Moved,
@ -715,7 +714,7 @@ define_class!(
self.mouse_motion(event);
#[allow(non_upper_case_globals)]
let phase = match unsafe { event.phase() } {
let phase = match event.phase() {
NSEventPhase::Began => TouchPhase::Started,
NSEventPhase::Changed => TouchPhase::Moved,
NSEventPhase::Cancelled => TouchPhase::Cancelled,
@ -725,7 +724,7 @@ define_class!(
self.queue_event(WindowEvent::PinchGesture {
device_id: None,
delta: unsafe { event.magnification() },
delta: event.magnification(),
phase,
});
}
@ -746,7 +745,7 @@ define_class!(
self.mouse_motion(event);
#[allow(non_upper_case_globals)]
let phase = match unsafe { event.phase() } {
let phase = match event.phase() {
NSEventPhase::Began => TouchPhase::Started,
NSEventPhase::Changed => TouchPhase::Moved,
NSEventPhase::Cancelled => TouchPhase::Cancelled,
@ -756,7 +755,7 @@ define_class!(
self.queue_event(WindowEvent::RotationGesture {
device_id: None,
delta: unsafe { event.rotation() },
delta: event.rotation(),
phase,
});
}
@ -767,8 +766,8 @@ define_class!(
self.queue_event(WindowEvent::TouchpadPressure {
device_id: None,
pressure: unsafe { event.pressure() },
stage: unsafe { event.stage() } as i64,
pressure: event.pressure(),
stage: event.stage() as i64,
});
}
@ -931,8 +930,8 @@ impl WinitView {
// later will work though, since the flags are attached to the event and contain valid
// information.
'send_event: {
if is_flags_changed_event && unsafe { ns_event.keyCode() } != 0 {
let scancode = unsafe { ns_event.keyCode() };
if is_flags_changed_event && ns_event.keyCode() != 0 {
let scancode = ns_event.keyCode();
let physical_key = scancode_to_physicalkey(scancode as u32);
let logical_key = code_to_key(physical_key, scancode);
@ -1064,7 +1063,7 @@ impl WinitView {
|| view_point.x > frame.size.width
|| view_point.y > frame.size.height
{
let mouse_buttons_down = unsafe { NSEvent::pressedMouseButtons() };
let mouse_buttons_down = NSEvent::pressedMouseButtons();
if mouse_buttons_down == 0 {
// Point is outside of the client area (view) and no buttons are pressed
return;
@ -1082,7 +1081,7 @@ impl WinitView {
}
fn mouse_view_point(&self, event: &NSEvent) -> LogicalPosition<f64> {
let window_point = unsafe { event.locationInWindow() };
let window_point = event.locationInWindow();
let view_point = self.convertPoint_fromView(window_point, None);
LogicalPosition::new(view_point.x, view_point.y)
@ -1096,7 +1095,7 @@ fn mouse_button(event: &NSEvent) -> MouseButton {
// For the other events, it's always set to 0.
// MacOS only defines the left, right and middle buttons, 3..=31 are left as generic buttons,
// but 3 and 4 are very commonly used as Back and Forward by hardware vendors and applications.
match unsafe { event.buttonNumber() } {
match event.buttonNumber() {
0 => MouseButton::Left,
1 => MouseButton::Right,
2 => MouseButton::Middle,
@ -1120,12 +1119,10 @@ fn replace_event(event: &NSEvent, option_as_alt: OptionAsAlt) -> Retained<NSEven
&& !ev_mods.meta_key();
if ignore_alt_characters {
let ns_chars = unsafe {
event.charactersIgnoringModifiers().expect("expected characters to be non-null")
};
let ns_chars =
event.charactersIgnoringModifiers().expect("expected characters to be non-null");
unsafe {
NSEvent::keyEventWithType_location_modifierFlags_timestamp_windowNumber_context_characters_charactersIgnoringModifiers_isARepeat_keyCode(
NSEvent::keyEventWithType_location_modifierFlags_timestamp_windowNumber_context_characters_charactersIgnoringModifiers_isARepeat_keyCode(
event.r#type(),
event.locationInWindow(),
event.modifierFlags(),
@ -1138,7 +1135,6 @@ fn replace_event(event: &NSEvent, option_as_alt: OptionAsAlt) -> Retained<NSEven
event.keyCode(),
)
.unwrap()
}
} else {
event.copy()
}

View file

@ -19,12 +19,14 @@ use objc2::{
use objc2_app_kit::{
NSAppKitVersionNumber, NSAppKitVersionNumber10_12, NSAppearance, NSAppearanceCustomization,
NSAppearanceNameAqua, NSApplication, NSApplicationPresentationOptions, NSBackingStoreType,
NSColor, NSDraggingDestination, NSDraggingInfo, NSFilenamesPboardType,
NSRequestUserAttentionType, NSScreen, NSToolbar, NSView, NSViewFrameDidChangeNotification,
NSWindow, NSWindowButton, NSWindowDelegate, NSWindowFullScreenButton, NSWindowLevel,
NSWindowOcclusionState, NSWindowOrderingMode, NSWindowSharingType, NSWindowStyleMask,
NSWindowTabbingMode, NSWindowTitleVisibility, NSWindowToolbarStyle,
NSColor, NSDraggingDestination, NSDraggingInfo, NSRequestUserAttentionType, NSScreen,
NSToolbar, NSView, NSViewFrameDidChangeNotification, NSWindow, NSWindowButton,
NSWindowDelegate, NSWindowLevel, NSWindowOcclusionState, NSWindowOrderingMode,
NSWindowSharingType, NSWindowStyleMask, NSWindowTabbingMode, NSWindowTitleVisibility,
NSWindowToolbarStyle,
};
#[allow(deprecated)]
use objc2_app_kit::{NSFilenamesPboardType, NSWindowFullScreenButton};
use objc2_core_foundation::{CGFloat, CGPoint};
use objc2_core_graphics::{
kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, kCGDisplayFadeReservationInvalidToken,
@ -350,7 +352,8 @@ define_class!(
use std::path::PathBuf;
let pb = unsafe { sender.draggingPasteboard() };
let pb = sender.draggingPasteboard();
#[allow(deprecated)]
let filenames = pb
.propertyListForType(unsafe { NSFilenamesPboardType })
.unwrap()
@ -361,7 +364,7 @@ define_class!(
.map(|file| PathBuf::from(file.downcast::<NSString>().unwrap().to_string()))
.collect();
let dl = unsafe { sender.draggingLocation() };
let dl = sender.draggingLocation();
let dl = self.view().convertPoint_fromView(dl, None);
let position =
LogicalPosition::<f64>::from((dl.x, dl.y)).to_physical(self.scale_factor());
@ -383,7 +386,7 @@ define_class!(
fn dragging_updated(&self, sender: &ProtocolObject<dyn NSDraggingInfo>) -> bool {
trace_scope!("draggingUpdated:");
let dl = unsafe { sender.draggingLocation() };
let dl = sender.draggingLocation();
let dl = self.view().convertPoint_fromView(dl, None);
let position =
LogicalPosition::<f64>::from((dl.x, dl.y)).to_physical(self.scale_factor());
@ -407,7 +410,8 @@ define_class!(
use std::path::PathBuf;
let pb = unsafe { sender.draggingPasteboard() };
let pb = sender.draggingPasteboard();
#[allow(deprecated)]
let filenames = pb
.propertyListForType(unsafe { NSFilenamesPboardType })
.unwrap()
@ -418,7 +422,7 @@ define_class!(
.map(|file| PathBuf::from(file.downcast::<NSString>().unwrap().to_string()))
.collect();
let dl = unsafe { sender.draggingLocation() };
let dl = sender.draggingLocation();
let dl = self.view().convertPoint_fromView(dl, None);
let position =
LogicalPosition::<f64>::from((dl.x, dl.y)).to_physical(self.scale_factor());
@ -440,7 +444,7 @@ define_class!(
trace_scope!("draggingExited:");
let position = sender.map(|sender| {
let dl = unsafe { sender.draggingLocation() };
let dl = sender.draggingLocation();
let dl = self.view().convertPoint_fromView(dl, None);
LogicalPosition::<f64>::from((dl.x, dl.y)).to_physical(self.scale_factor())
});
@ -477,12 +481,12 @@ define_class!(
let old = old.downcast::<NSAppearance>().unwrap();
let new = new.downcast::<NSAppearance>().unwrap();
trace!(old = %unsafe { old.name() }, new = %unsafe { new.name() }, "effectiveAppearance changed");
trace!(old = %old.name(), new = %new.name(), "effectiveAppearance changed");
// Ignore the change if the window's theme is customized by the user (since in that
// case the `effectiveAppearance` is only emitted upon said customization, and then
// it's triggered directly by a user action, and we don't want to emit the event).
if unsafe { self.window().appearance() }.is_some() {
if self.window().appearance().is_some() {
return;
}
@ -505,9 +509,7 @@ define_class!(
impl Drop for WindowDelegate {
fn drop(&mut self) {
unsafe {
self.window().removeObserver_forKeyPath(self, ns_string!("effectiveAppearance"));
}
unsafe { self.window().removeObserver_forKeyPath(self, ns_string!("effectiveAppearance")) };
}
}
@ -666,12 +668,10 @@ fn new_window(
window.setMovableByWindowBackground(true);
}
if macos_attrs.unified_titlebar {
unsafe {
// The toolbar style is ignored if there is no toolbar, so it is
// necessary to add one.
window.setToolbar(Some(&NSToolbar::new(mtm)));
window.setToolbarStyle(NSWindowToolbarStyle::Unified);
}
// The toolbar style is ignored if there is no toolbar, so it is
// necessary to add one.
window.setToolbar(Some(&NSToolbar::new(mtm)));
window.setToolbarStyle(NSWindowToolbarStyle::Unified);
}
if !attrs.enabled_buttons.contains(WindowButtons::MAXIMIZE) {
@ -720,7 +720,7 @@ fn new_window(
view.setPostsFrameChangedNotifications(true);
// `setPostsFrameChangedNotifications` posts the notification immediately, so register the
// observer _after_, again so that the event isn't triggered initially.
let notification_center = unsafe { NSNotificationCenter::defaultCenter() };
let notification_center = NSNotificationCenter::defaultCenter();
unsafe {
notification_center.addObserver_selector_name_object(
&view,
@ -733,10 +733,11 @@ fn new_window(
if attrs.transparent {
window.setOpaque(false);
// See `set_transparent` for details on why we do this.
window.setBackgroundColor(unsafe { Some(&NSColor::clearColor()) });
window.setBackgroundColor(Some(&NSColor::clearColor()));
}
// register for drag and drop operations.
#[allow(deprecated)]
window.registerForDraggedTypes(&NSArray::from_slice(&[unsafe { NSFilenamesPboardType }]));
Some(window)
@ -790,7 +791,7 @@ impl WindowDelegate {
let scale_factor = window.backingScaleFactor() as _;
if let Some(appearance) = theme_to_appearance(attrs.preferred_theme) {
unsafe { window.setAppearance(Some(&appearance)) };
window.setAppearance(Some(&appearance));
}
let delegate = mtm.alloc().set_ivars(State {
@ -945,11 +946,8 @@ impl WindowDelegate {
// transparent, as in that case, the transparent contents will just be drawn on top of
// the background color. As such, to allow the window to be transparent, we must also set
// the background color to one with an empty alpha channel.
let color = if transparent {
unsafe { NSColor::clearColor() }
} else {
unsafe { NSColor::windowBackgroundColor() }
};
let color =
if transparent { NSColor::clearColor() } else { NSColor::windowBackgroundColor() };
self.window().setBackgroundColor(Some(&color));
}
@ -958,7 +956,7 @@ impl WindowDelegate {
// NOTE: in general we want to specify the blur radius, but the choice of 80
// should be a reasonable default.
let radius = if blur { 80 } else { 0 };
let window_number = unsafe { self.window().windowNumber() };
let window_number = self.window().windowNumber();
unsafe {
ffi::CGSSetWindowBackgroundBlurRadius(
ffi::CGSMainConnectionID(),
@ -1017,7 +1015,7 @@ impl WindowDelegate {
NSPoint::new(position.x, position.y),
self.window().frame().size,
));
unsafe { self.window().setFrameOrigin(point) };
self.window().setFrameOrigin(point);
}
#[inline]
@ -1039,17 +1037,15 @@ impl WindowDelegate {
let insets = if self.view().respondsToSelector(sel!(safeAreaInsets)) {
// Includes NSWindowStyleMask::FullSizeContentView by default, and the notch because
// we've set it up with `additionalSafeAreaInsets`.
unsafe { self.view().safeAreaInsets() }
self.view().safeAreaInsets()
} else {
// If `safeAreaInsets` is not available, we'll have to do the calculation ourselves.
let window_rect = unsafe {
self.window().convertRectFromScreen(
self.window().contentRectForFrameRect(self.window().frame()),
)
};
let window_rect = self.window().convertRectFromScreen(
self.window().contentRectForFrameRect(self.window().frame()),
);
// This includes NSWindowStyleMask::FullSizeContentView.
let layout_rect = unsafe { self.window().contentLayoutRect() };
let layout_rect = self.window().contentLayoutRect();
// Calculate the insets from window coordinates in AppKit's coordinate system.
NSEdgeInsets {
@ -1079,7 +1075,7 @@ impl WindowDelegate {
let min_size = dimensions.to_logical::<CGFloat>(self.scale_factor());
let min_size = NSSize::new(min_size.width, min_size.height);
unsafe { self.window().setContentMinSize(min_size) };
self.window().setContentMinSize(min_size);
// If necessary, resize the window to match constraint
let mut current_size = self.window().contentRectForFrameRect(self.window().frame()).size;
@ -1101,7 +1097,7 @@ impl WindowDelegate {
let max_size = dimensions.to_logical::<CGFloat>(scale_factor);
let max_size = NSSize::new(max_size.width, max_size.height);
unsafe { self.window().setContentMaxSize(max_size) };
self.window().setContentMaxSize(max_size);
// If necessary, resize the window to match constraint
let mut current_size = self.window().contentRectForFrameRect(self.window().frame()).size;
@ -1246,7 +1242,7 @@ impl WindowDelegate {
};
// TODO: Do this for real https://stackoverflow.com/a/40922095/5435443
cgerr(unsafe { CGAssociateMouseAndMouseCursorPosition(associate_mouse_cursor) })?;
cgerr(CGAssociateMouseAndMouseCursorPosition(associate_mouse_cursor))?;
Ok(())
}
@ -1274,8 +1270,8 @@ impl WindowDelegate {
x: window_position.x + cursor_position.x,
y: window_position.y + cursor_position.y,
};
cgerr(unsafe { CGWarpMouseCursorPosition(point) })?;
cgerr(unsafe { CGAssociateMouseAndMouseCursorPosition(true) })?;
cgerr(CGWarpMouseCursorPosition(point))?;
cgerr(CGAssociateMouseAndMouseCursorPosition(true))?;
Ok(())
}
@ -1356,7 +1352,7 @@ impl WindowDelegate {
if minimized {
self.window().miniaturize(Some(self));
} else {
unsafe { self.window().deminiaturize(Some(self)) };
self.window().deminiaturize(Some(self));
}
}
@ -1450,7 +1446,7 @@ impl WindowDelegate {
let old_screen = self.window().screen().unwrap();
if old_screen != new_screen {
unsafe { self.window().setFrameOrigin(new_screen.frame().origin) };
self.window().setFrameOrigin(new_screen.frame().origin);
}
}
@ -1475,25 +1471,23 @@ impl WindowDelegate {
self.ivars().save_presentation_opts.replace(Some(app.presentationOptions()));
}
unsafe {
// Fade to black (and wait for the fade to complete) to hide the
// flicker from capturing the display and switching display mode
if cgerr(CGAcquireDisplayFadeReservation(5.0, &mut fade_token)).is_ok() {
CGDisplayFade(
fade_token,
0.3,
kCGDisplayBlendNormal,
kCGDisplayBlendSolidColor,
0.0,
0.0,
0.0,
true,
);
}
cgerr(CGDisplayCapture(display_id)).unwrap();
// Fade to black (and wait for the fade to complete) to hide the
// flicker from capturing the display and switching display mode
if cgerr(unsafe { CGAcquireDisplayFadeReservation(5.0, &mut fade_token) }).is_ok() {
CGDisplayFade(
fade_token,
0.3,
kCGDisplayBlendNormal,
kCGDisplayBlendSolidColor,
0.0,
0.0,
0.0,
true,
);
}
cgerr(CGDisplayCapture(display_id)).unwrap();
let monitor = monitor.cast_ref::<MonitorHandle>().unwrap();
let video_mode =
match monitor.video_mode_handles().find(|mode| &mode.mode == video_mode) {
@ -1501,25 +1495,25 @@ impl WindowDelegate {
None => return,
};
unsafe {
cgerr(CGDisplaySetDisplayMode(display_id, Some(&video_mode.native_mode.0), None))
.expect("failed to set video mode");
cgerr(unsafe {
CGDisplaySetDisplayMode(display_id, Some(&video_mode.native_mode.0), None)
})
.expect("failed to set video mode");
// After the display has been configured, fade back in
// asynchronously
if fade_token != kCGDisplayFadeReservationInvalidToken {
CGDisplayFade(
fade_token,
0.6,
kCGDisplayBlendSolidColor,
kCGDisplayBlendNormal,
0.0,
0.0,
0.0,
false,
);
CGReleaseDisplayFadeReservation(fade_token);
}
// After the display has been configured, fade back in
// asynchronously
if fade_token != kCGDisplayFadeReservationInvalidToken {
CGDisplayFade(
fade_token,
0.6,
kCGDisplayBlendSolidColor,
kCGDisplayBlendNormal,
0.0,
0.0,
0.0,
false,
);
CGReleaseDisplayFadeReservation(fade_token);
}
}
@ -1582,7 +1576,7 @@ impl WindowDelegate {
| NSApplicationPresentationOptions::HideMenuBar;
app.setPresentationOptions(presentation_options);
let window_level = unsafe { CGShieldingWindowLevel() } as NSWindowLevel + 1;
let window_level = CGShieldingWindowLevel() as NSWindowLevel + 1;
self.window().setLevel(window_level);
},
(Some(Fullscreen::Exclusive(monitor, _)), Some(Fullscreen::Borderless(_))) => {
@ -1797,9 +1791,8 @@ impl WindowDelegate {
}
pub fn theme(&self) -> Option<Theme> {
unsafe { self.window().appearance() }
.map(|appearance| appearance_to_theme(&appearance))
.or_else(|| {
self.window().appearance().map(|appearance| appearance_to_theme(&appearance)).or_else(
|| {
let mtm = MainThreadMarker::from(self);
let app = NSApplication::sharedApplication(mtm);
@ -1808,11 +1801,12 @@ impl WindowDelegate {
} else {
Some(Theme::Light)
}
})
},
)
}
pub fn set_theme(&self, theme: Option<Theme>) {
unsafe { self.window().setAppearance(theme_to_appearance(theme).as_deref()) };
self.window().setAppearance(theme_to_appearance(theme).as_deref());
}
#[inline]
@ -1836,10 +1830,8 @@ impl WindowDelegate {
fn restore_and_release_display(monitor: &MonitorHandle) {
let available_monitors = monitor::available_monitors();
if available_monitors.contains(monitor) {
unsafe {
CGRestorePermanentDisplayConfiguration();
cgerr(CGDisplayRelease(monitor.native_id() as _)).unwrap();
};
CGRestorePermanentDisplayConfiguration();
cgerr(CGDisplayRelease(monitor.native_id() as _)).unwrap();
} else {
warn!(
monitor = monitor.name().map(|name| name.to_string()),
@ -1901,7 +1893,7 @@ impl WindowExtMacOS for WindowDelegate {
// Configure the safe area rectangle, to ensure that we don't obscure the notch.
if NSScreen::class().responds_to(sel!(safeAreaInsets)) {
unsafe { self.view().setAdditionalSafeAreaInsets(screen.safeAreaInsets()) };
self.view().setAdditionalSafeAreaInsets(screen.safeAreaInsets());
}
// Fullscreen windows can't be resized, minimized, or moved
@ -1920,14 +1912,12 @@ impl WindowExtMacOS for WindowDelegate {
}
if NSScreen::class().responds_to(sel!(safeAreaInsets)) {
unsafe {
self.view().setAdditionalSafeAreaInsets(NSEdgeInsets {
top: 0.0,
left: 0.0,
bottom: 0.0,
right: 0.0,
});
}
self.view().setAdditionalSafeAreaInsets(NSEdgeInsets {
top: 0.0,
left: 0.0,
bottom: 0.0,
right: 0.0,
});
}
self.window().setFrame_display(frame, true);
@ -1965,7 +1955,7 @@ impl WindowExtMacOS for WindowDelegate {
#[inline]
fn select_previous_tab(&self) {
unsafe { self.window().selectPreviousTab(None) }
self.window().selectPreviousTab(None)
}
#[inline]
@ -1975,7 +1965,7 @@ impl WindowExtMacOS for WindowDelegate {
return;
}
if let Some(group) = self.window().tabGroup() {
if let Some(windows) = unsafe { self.window().tabbedWindows() } {
if let Some(windows) = self.window().tabbedWindows() {
if index < windows.len() {
group.setSelectedWindow(Some(&windows.objectAtIndex(index)));
}
@ -1985,7 +1975,7 @@ impl WindowExtMacOS for WindowDelegate {
#[inline]
fn num_tabs(&self) -> usize {
unsafe { self.window().tabbedWindows() }.map(|windows| windows.len()).unwrap_or(1)
self.window().tabbedWindows().map(|windows| windows.len()).unwrap_or(1)
}
fn is_document_edited(&self) -> bool {
@ -2018,26 +2008,20 @@ impl WindowExtMacOS for WindowDelegate {
if unified_titlebar {
let mtm = MainThreadMarker::from(self);
unsafe {
// The toolbar style is ignored if there is no toolbar, so it is
// necessary to add one.
window.setToolbar(Some(&NSToolbar::new(mtm)));
window.setToolbarStyle(NSWindowToolbarStyle::Unified);
}
// The toolbar style is ignored if there is no toolbar, so it is
// necessary to add one.
window.setToolbar(Some(&NSToolbar::new(mtm)));
window.setToolbarStyle(NSWindowToolbarStyle::Unified);
} else {
unsafe {
window.setToolbar(None);
window.setToolbarStyle(NSWindowToolbarStyle::Automatic);
}
window.setToolbar(None);
window.setToolbarStyle(NSWindowToolbarStyle::Automatic);
}
}
fn unified_titlebar(&self) -> bool {
let window = self.window();
unsafe {
window.toolbar().is_some() && window.toolbarStyle() == NSWindowToolbarStyle::Unified
}
window.toolbar().is_some() && window.toolbarStyle() == NSWindowToolbarStyle::Unified
}
}

View file

@ -154,7 +154,7 @@ impl EventLoop {
// this line sets up the main run loop before `UIApplicationMain`
setup_control_flow_observers();
let center = unsafe { NSNotificationCenter::defaultCenter() };
let center = NSNotificationCenter::defaultCenter();
let _did_finish_launching_observer = create_observer(
&center,
@ -181,7 +181,7 @@ impl EventLoop {
// `applicationWillEnterForeground:`
unsafe { UIApplicationWillEnterForegroundNotification },
move |notification| {
let app = unsafe { notification.object() }.expect(
let app = notification.object().expect(
"UIApplicationWillEnterForegroundNotification to have application object",
);
// The `object` in `UIApplicationWillEnterForegroundNotification` is documented to
@ -195,7 +195,7 @@ impl EventLoop {
// `applicationDidEnterBackground:`
unsafe { UIApplicationDidEnterBackgroundNotification },
move |notification| {
let app = unsafe { notification.object() }.expect(
let app = notification.object().expect(
"UIApplicationDidEnterBackgroundNotification to have application object",
);
// The `object` in `UIApplicationDidEnterBackgroundNotification` is documented to be
@ -209,7 +209,8 @@ impl EventLoop {
// `applicationWillTerminate:`
unsafe { UIApplicationWillTerminateNotification },
move |notification| {
let app = unsafe { notification.object() }
let app = notification
.object()
.expect("UIApplicationWillTerminateNotification to have application object");
// The `object` in `UIApplicationWillTerminateNotification` is (somewhat) documented
// to be `UIApplication`.

View file

@ -271,8 +271,8 @@ mod tests {
let main = UIScreen::mainScreen(mtm);
assert!(UIScreen::screens(mtm).iter().any(|screen| ptr::eq(&*screen, &*main)));
assert!(unsafe {
assert!(
NSSet::setWithArray(&UIScreen::screens(mtm)).containsObject(&UIScreen::mainScreen(mtm))
});
);
}
}

View file

@ -161,8 +161,7 @@ impl Inner {
pub fn surface_position(&self) -> PhysicalPosition<i32> {
let view_position = self.view.frame().origin;
let position =
unsafe { self.window.convertPoint_fromView(view_position, Some(&self.view)) };
let position = self.window.convertPoint_fromView(view_position, Some(&self.view));
let position = LogicalPosition::new(position.x, position.y);
position.to_physical(self.scale_factor())
}
@ -393,9 +392,7 @@ impl Inner {
}
*current_caps = Some(capabilities);
unsafe {
self.view.becomeFirstResponder();
}
self.view.becomeFirstResponder();
},
ImeRequest::Update(_) => {
if current_caps.is_none() {
@ -404,9 +401,7 @@ impl Inner {
},
ImeRequest::Disable => {
*current_caps = None;
unsafe {
self.view.resignFirstResponder();
}
self.view.resignFirstResponder();
},
}