chore: update to objc2 frameworks v0.3.2
This commit is contained in:
parent
d815bc089c
commit
b811e9d878
13 changed files with 227 additions and 267 deletions
12
Cargo.toml
12
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"
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(), ¤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 {
|
|||
//
|
||||
// <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);
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
});
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue