diff --git a/CHANGELOG.md b/CHANGELOG.md index 3658c23d..3acb79f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,9 +25,10 @@ - **Breaking:** On Web, `set_cursor_position` and `set_cursor_grab` will now always return an error. - **Breaking:** `PixelDelta` scroll events now return a `PhysicalPosition`. - On NetBSD, fixed crash due to incorrect detection of the main thread. -- **Breaking:** The virtual key code `Subtract` has been renamed to `NumpadSubtract` -- **Breaking:** On X11, `-` key is mapped to the `Minus` virtual key code, instead of `Subtract` +- **Breaking:** The virtual key code `Subtract` has been renamed to `NumpadSubtract`. +- **Breaking:** On X11, `-` key is mapped to the `Minus` virtual key code, instead of `Subtract`. - On macOS, fix inverted horizontal scroll. +- **Breaking:** `current_monitor` now returns `Option`. # 0.22.2 (2020-05-16) diff --git a/examples/multithreaded.rs b/examples/multithreaded.rs index 60f9d802..4141775e 100644 --- a/examples/multithreaded.rs +++ b/examples/multithreaded.rs @@ -21,7 +21,7 @@ fn main() { .build(&event_loop) .unwrap(); - let mut video_modes: Vec<_> = window.current_monitor().video_modes().collect(); + let mut video_modes: Vec<_> = window.current_monitor().unwrap().video_modes().collect(); let mut video_mode_id = 0usize; let (tx, rx) = mpsc::channel(); @@ -34,7 +34,7 @@ fn main() { // was moved to an another monitor, so that the window // appears on this monitor instead when we go fullscreen let previous_video_mode = video_modes.iter().cloned().nth(video_mode_id); - video_modes = window.current_monitor().video_modes().collect(); + video_modes = window.current_monitor().unwrap().video_modes().collect(); video_mode_id = video_mode_id.min(video_modes.len()); let video_mode = video_modes.iter().nth(video_mode_id); @@ -83,7 +83,7 @@ fn main() { } F => window.set_fullscreen(match (state, modifiers.alt()) { (true, false) => { - Some(Fullscreen::Borderless(window.current_monitor())) + Some(Fullscreen::Borderless(window.current_monitor().unwrap())) } (true, true) => Some(Fullscreen::Exclusive( video_modes.iter().nth(video_mode_id).unwrap().clone(), diff --git a/examples/window_debug.rs b/examples/window_debug.rs index f6e960a7..e8de3cf0 100644 --- a/examples/window_debug.rs +++ b/examples/window_debug.rs @@ -70,7 +70,7 @@ fn main() { size.width * size.height } - let monitor = window.current_monitor(); + let monitor = window.current_monitor().unwrap(); if let Some(mode) = monitor .video_modes() .max_by(|a, b| area(a.size()).cmp(&area(b.size()))) @@ -84,7 +84,7 @@ fn main() { if window.fullscreen().is_some() { window.set_fullscreen(None); } else { - let monitor = window.current_monitor(); + let monitor = window.current_monitor().unwrap(); window.set_fullscreen(Some(Fullscreen::Borderless(monitor))); } } diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index 453815d8..db759ed5 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -391,10 +391,10 @@ impl Window { v } - pub fn current_monitor(&self) -> monitor::MonitorHandle { - monitor::MonitorHandle { + pub fn current_monitor(&self) -> Option { + Some(monitor::MonitorHandle { inner: MonitorHandle, - } + }) } pub fn scale_factor(&self) -> f64 { diff --git a/src/platform_impl/ios/window.rs b/src/platform_impl/ios/window.rs index 5fa83e90..2be710e2 100644 --- a/src/platform_impl/ios/window.rs +++ b/src/platform_impl/ios/window.rs @@ -224,7 +224,7 @@ impl Inner { pub fn fullscreen(&self) -> Option { unsafe { - let monitor = self.current_monitor(); + let monitor = self.current_monitor_inner(); let uiscreen = monitor.inner.ui_screen(); let screen_space_bounds = self.screen_frame(); let screen_bounds: CGRect = msg_send![uiscreen, bounds]; @@ -258,7 +258,8 @@ impl Inner { warn!("`Window::set_ime_position` is ignored on iOS") } - pub fn current_monitor(&self) -> RootMonitorHandle { + // Allow directly accessing the current monitor internally without unwrapping. + fn current_monitor_inner(&self) -> RootMonitorHandle { unsafe { let uiscreen: id = msg_send![self.window, screen]; RootMonitorHandle { @@ -267,6 +268,10 @@ impl Inner { } } + pub fn current_monitor(&self) -> Option { + Some(self.current_monitor_inner()) + } + pub fn available_monitors(&self) -> VecDeque { unsafe { monitor::uiscreens() } } diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 73b84777..c2214ace 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -425,9 +425,22 @@ impl Window { } #[inline] - pub fn current_monitor(&self) -> RootMonitorHandle { - RootMonitorHandle { - inner: x11_or_wayland!(match self; Window(window) => window.current_monitor(); as MonitorHandle), + pub fn current_monitor(&self) -> Option { + match self { + #[cfg(feature = "x11")] + &Window::X(ref window) => { + let current_monitor = MonitorHandle::X(window.current_monitor()); + Some(RootMonitorHandle { + inner: current_monitor, + }) + } + #[cfg(feature = "wayland")] + &Window::Wayland(ref window) => { + let current_monitor = MonitorHandle::Wayland(window.current_monitor()?); + Some(RootMonitorHandle { + inner: current_monitor, + }) + } } } diff --git a/src/platform_impl/linux/wayland/window.rs b/src/platform_impl/linux/wayland/window.rs index a0be1e9d..11c38466 100644 --- a/src/platform_impl/linux/wayland/window.rs +++ b/src/platform_impl/linux/wayland/window.rs @@ -334,8 +334,10 @@ impl Window { pub fn fullscreen(&self) -> Option { if *(self.fullscreen.lock().unwrap()) { + // If the monitor cannot be determined, we cannot report any fullscreen mode. + let current_monitor = self.current_monitor()?; Some(Fullscreen::Borderless(RootMonitorHandle { - inner: PlatformMonitorHandle::Wayland(self.current_monitor()), + inner: PlatformMonitorHandle::Wayland(current_monitor), })) } else { None @@ -396,12 +398,12 @@ impl Window { &self.surface } - pub fn current_monitor(&self) -> MonitorHandle { - let output = get_outputs(&self.surface).last().unwrap().clone(); - MonitorHandle { + pub fn current_monitor(&self) -> Option { + let output = get_outputs(&self.surface).last()?.clone(); + Some(MonitorHandle { proxy: output, mgr: self.outputs.clone(), - } + }) } pub fn available_monitors(&self) -> VecDeque { diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 175cf733..919fc2c7 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -972,7 +972,8 @@ impl UnownedWindow { } #[inline] - pub fn current_monitor(&self) -> RootMonitorHandle { + // Allow directly accessing the current monitor internally without unwrapping. + pub(crate) fn current_monitor_inner(&self) -> RootMonitorHandle { unsafe { let screen: id = msg_send![*self.ns_window, screen]; let desc = NSScreen::deviceDescription(screen); @@ -985,6 +986,11 @@ impl UnownedWindow { } } + #[inline] + pub fn current_monitor(&self) -> Option { + Some(self.current_monitor_inner()) + } + #[inline] pub fn available_monitors(&self) -> VecDeque { monitor::available_monitors() diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 8c49e773..9d106e15 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -450,7 +450,8 @@ extern "C" fn window_will_enter_fullscreen(this: &Object, _: Sel, _: id) { // Otherwise, we must've reached fullscreen by the user clicking // on the green fullscreen button. Update state! None => { - shared_state.fullscreen = Some(Fullscreen::Borderless(window.current_monitor())) + let current_monitor = window.current_monitor_inner(); + shared_state.fullscreen = Some(Fullscreen::Borderless(current_monitor)) } } shared_state.in_fullscreen_transition = true; diff --git a/src/platform_impl/web/window.rs b/src/platform_impl/web/window.rs index bcf70116..5f2cae62 100644 --- a/src/platform_impl/web/window.rs +++ b/src/platform_impl/web/window.rs @@ -201,7 +201,7 @@ impl Window { #[inline] pub fn fullscreen(&self) -> Option { if self.canvas.is_fullscreen() { - Some(Fullscreen::Borderless(self.current_monitor())) + Some(Fullscreen::Borderless(self.current_monitor_inner())) } else { None } @@ -237,12 +237,18 @@ impl Window { } #[inline] - pub fn current_monitor(&self) -> RootMH { + // Allow directly accessing the current monitor internally without unwrapping. + fn current_monitor_inner(&self) -> RootMH { RootMH { inner: monitor::Handle, } } + #[inline] + pub fn current_monitor(&self) -> Option { + Some(self.current_monitor_inner()) + } + #[inline] pub fn available_monitors(&self) -> VecDequeIter { VecDeque::new().into_iter() diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index 3b8dc98f..34406310 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -577,10 +577,10 @@ impl Window { } #[inline] - pub fn current_monitor(&self) -> RootMonitorHandle { - RootMonitorHandle { + pub fn current_monitor(&self) -> Option { + Some(RootMonitorHandle { inner: monitor::current_monitor(self.window.0), - } + }) } #[inline] diff --git a/src/window.rs b/src/window.rs index a00cd7c0..b8bec50b 100644 --- a/src/window.rs +++ b/src/window.rs @@ -736,13 +736,15 @@ impl Window { /// Monitor info functions. impl Window { - /// Returns the monitor on which the window currently resides + /// Returns the monitor on which the window currently resides. + /// + /// Returns `None` if current monitor can't be detected. /// /// ## Platform-specific /// /// **iOS:** Can only be called on the main thread. #[inline] - pub fn current_monitor(&self) -> MonitorHandle { + pub fn current_monitor(&self) -> Option { self.window.current_monitor() }