diff --git a/Cargo.toml b/Cargo.toml index f0ec0d1d..a1e8ba1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/winit-appkit/src/app.rs b/winit-appkit/src/app.rs index 281b38d2..00c672cd 100644 --- a/winit-appkit/src/app.rs +++ b/winit-appkit/src/app.rs @@ -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, 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, 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, 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] diff --git a/winit-appkit/src/app_state.rs b/winit-appkit/src/app_state.rs index 4fab8d53..e0e65417 100644 --- a/winit-appkit/src/app_state.rs +++ b/winit-appkit/src/app_state.rs @@ -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); } diff --git a/winit-appkit/src/cursor.rs b/winit-appkit/src/cursor.rs index 879c9701..d358885c 100644 --- a/winit-appkit/src/cursor.rs +++ b/winit-appkit/src/cursor.rs @@ -62,10 +62,8 @@ pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Result Retained { // TODO: Handle PLists better let info_path = cursor_path.stringByAppendingPathComponent(ns_string!("info.plist")); - let info: Retained> = unsafe { - msg_send![ - >::class(), - dictionaryWithContentsOfFile: &*info_path, - ] - }; + #[allow(deprecated)] + let info: Retained> = + 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::() { @@ -216,9 +211,9 @@ pub(crate) fn cursor_from_icon(icon: CursorIcon) -> Retained { 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(), diff --git a/winit-appkit/src/event.rs b/winit-appkit/src/event.rs index d56f45ef..27685ddf 100644 --- a/winit-appkit/src/event.rs +++ b/winit-appkit/src/event.rs @@ -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> { - 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> { 0, 0, ) - } } pub fn physicalkey_to_scancode(physical_key: PhysicalKey) -> Option { diff --git a/winit-appkit/src/event_loop.rs b/winit-appkit/src/event_loop.rs index a12e8446..88c33a36 100644 --- a/winit-appkit/src/event_loop.rs +++ b/winit-appkit/src/event_loop.rs @@ -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( diff --git a/winit-appkit/src/menu.rs b/winit-appkit/src/menu.rs index 5568ff5f..976edc9c 100644 --- a/winit-appkit/src/menu.rs +++ b/winit-appkit/src/menu.rs @@ -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)); } diff --git a/winit-appkit/src/monitor.rs b/winit-appkit/src/monitor.rs index 846ed15d..b08e9087 100644 --- a/winit-appkit/src/monitor.rs +++ b/winit-appkit/src/monitor.rs @@ -65,35 +65,33 @@ impl VideoModeHandle { native_mode: NativeDisplayMode, refresh_rate_millihertz: Option, ) -> 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 { let current_display_mode = - NativeDisplayMode(unsafe { CGDisplayCopyDisplayMode(self.display_id()) }.unwrap()); + NativeDisplayMode(CGDisplayCopyDisplayMode(self.display_id()).unwrap()); refresh_rate_millihertz(self.display_id(), ¤t_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 { // // fn name(&self) -> Option> { - 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 { - 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 { 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 { - 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); diff --git a/winit-appkit/src/view.rs b/winit-appkit/src/view.rs index dc57fa7d..17bb40e3 100644 --- a/winit-appkit/src/view.rs +++ b/winit-appkit/src/view.rs @@ -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 { - 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 Retained().unwrap().to_string())) .collect(); - let dl = unsafe { sender.draggingLocation() }; + let dl = sender.draggingLocation(); let dl = self.view().convertPoint_fromView(dl, None); let position = LogicalPosition::::from((dl.x, dl.y)).to_physical(self.scale_factor()); @@ -383,7 +386,7 @@ define_class!( fn dragging_updated(&self, sender: &ProtocolObject) -> bool { trace_scope!("draggingUpdated:"); - let dl = unsafe { sender.draggingLocation() }; + let dl = sender.draggingLocation(); let dl = self.view().convertPoint_fromView(dl, None); let position = LogicalPosition::::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::().unwrap().to_string())) .collect(); - let dl = unsafe { sender.draggingLocation() }; + let dl = sender.draggingLocation(); let dl = self.view().convertPoint_fromView(dl, None); let position = LogicalPosition::::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::::from((dl.x, dl.y)).to_physical(self.scale_factor()) }); @@ -477,12 +481,12 @@ define_class!( let old = old.downcast::().unwrap(); let new = new.downcast::().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::(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::(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::().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 { - 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) { - 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 } } diff --git a/winit-uikit/src/event_loop.rs b/winit-uikit/src/event_loop.rs index 09ed87a6..f73b9440 100644 --- a/winit-uikit/src/event_loop.rs +++ b/winit-uikit/src/event_loop.rs @@ -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( ¢er, @@ -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`. diff --git a/winit-uikit/src/monitor.rs b/winit-uikit/src/monitor.rs index b1c3839e..8742f1ec 100644 --- a/winit-uikit/src/monitor.rs +++ b/winit-uikit/src/monitor.rs @@ -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)) - }); + ); } } diff --git a/winit-uikit/src/window.rs b/winit-uikit/src/window.rs index 52acb038..5af70aaf 100644 --- a/winit-uikit/src/window.rs +++ b/winit-uikit/src/window.rs @@ -161,8 +161,7 @@ impl Inner { pub fn surface_position(&self) -> PhysicalPosition { 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(); }, }