Skip to content

Commit

Permalink
Make 'current_monitor' return 'Option<MonitorHandle>'
Browse files Browse the repository at this point in the history
On certain platforms window couldn't be on any monitor
resulting in failures of 'current_monitor' function.

Such issue was happening on Wayland, since the window
isn't on any monitor, unless the user has drawn something into it.

Returning 'Option<MonitorHandle>' will give an ability to
handle such situations gracefully by properly indicating that
there's no current monitor.

Fixes rust-windowing#793.
  • Loading branch information
kchibisov committed Sep 6, 2020
1 parent e2cf2a5 commit 7030548
Show file tree
Hide file tree
Showing 12 changed files with 60 additions and 29 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<MonitorHandle>`.

# 0.22.2 (2020-05-16)

Expand Down
6 changes: 3 additions & 3 deletions examples/multithreaded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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);

Expand Down Expand Up @@ -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(),
Expand Down
4 changes: 2 additions & 2 deletions examples/window_debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())))
Expand All @@ -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)));
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/platform_impl/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,10 +391,10 @@ impl Window {
v
}

pub fn current_monitor(&self) -> monitor::MonitorHandle {
monitor::MonitorHandle {
pub fn current_monitor(&self) -> Option<monitor::MonitorHandle> {
Some(monitor::MonitorHandle {
inner: MonitorHandle,
}
})
}

pub fn scale_factor(&self) -> f64 {
Expand Down
8 changes: 6 additions & 2 deletions src/platform_impl/ios/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ impl Inner {

pub fn fullscreen(&self) -> Option<Fullscreen> {
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];
Expand Down Expand Up @@ -258,7 +258,7 @@ impl Inner {
warn!("`Window::set_ime_position` is ignored on iOS")
}

pub fn current_monitor(&self) -> RootMonitorHandle {
fn current_monitor_inner(&self) -> RootMonitorHandle {
unsafe {
let uiscreen: id = msg_send![self.window, screen];
RootMonitorHandle {
Expand All @@ -267,6 +267,10 @@ impl Inner {
}
}

pub fn current_monitor(&self) -> Option<RootMonitorHandle> {
Some(self.current_monitor_inner())
}

pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
unsafe { monitor::uiscreens() }
}
Expand Down
19 changes: 16 additions & 3 deletions src/platform_impl/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<RootMonitorHandle> {
match self {
#[cfg(feature = "x11")]
&Window::X(ref window) => {
let current_monitor = window.current_monitor();
Some(RootMonitorHandle {
inner: MonitorHandle::X(current_monitor),
})
}
#[cfg(feature = "wayland")]
&Window::Wayland(ref window) => {
let current_monitor = window.current_monitor()?;
Some(RootMonitorHandle {
inner: MonitorHandle::Wayland(current_monitor),
})
}
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/platform_impl/linux/wayland/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ impl Window {
pub fn fullscreen(&self) -> Option<Fullscreen> {
if *(self.fullscreen.lock().unwrap()) {
Some(Fullscreen::Borderless(RootMonitorHandle {
inner: PlatformMonitorHandle::Wayland(self.current_monitor()),
inner: PlatformMonitorHandle::Wayland(self.current_monitor().unwrap()),
}))
} else {
None
Expand Down Expand Up @@ -396,12 +396,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<MonitorHandle> {
let output = get_outputs(&self.surface).last()?.clone();
Some(MonitorHandle {
proxy: output,
mgr: self.outputs.clone(),
}
})
}

pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
Expand Down
7 changes: 6 additions & 1 deletion src/platform_impl/macos/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,7 @@ impl UnownedWindow {
}

#[inline]
pub fn current_monitor(&self) -> RootMonitorHandle {
pub(crate) fn current_monitor_inner(&self) -> RootMonitorHandle {
unsafe {
let screen: id = msg_send![*self.ns_window, screen];
let desc = NSScreen::deviceDescription(screen);
Expand All @@ -985,6 +985,11 @@ impl UnownedWindow {
}
}

#[inline]
pub fn current_monitor(&self) -> Option<RootMonitorHandle> {
Some(self.current_monitor_inner())
}

#[inline]
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
monitor::available_monitors()
Expand Down
3 changes: 2 additions & 1 deletion src/platform_impl/macos/window_delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
9 changes: 7 additions & 2 deletions src/platform_impl/web/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ impl Window {
#[inline]
pub fn fullscreen(&self) -> Option<Fullscreen> {
if self.canvas.is_fullscreen() {
Some(Fullscreen::Borderless(self.current_monitor()))
Some(Fullscreen::Borderless(self.current_monitor_inner()))
} else {
None
}
Expand Down Expand Up @@ -237,12 +237,17 @@ impl Window {
}

#[inline]
pub fn current_monitor(&self) -> RootMH {
fn current_monitor_inner(&self) -> RootMH {
RootMH {
inner: monitor::Handle,
}
}

#[inline]
pub fn current_monitor(&self) -> Option<RootMH> {
Some(self.current_monitor_inner())
}

#[inline]
pub fn available_monitors(&self) -> VecDequeIter<monitor::Handle> {
VecDeque::new().into_iter()
Expand Down
6 changes: 3 additions & 3 deletions src/platform_impl/windows/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,10 +577,10 @@ impl Window {
}

#[inline]
pub fn current_monitor(&self) -> RootMonitorHandle {
RootMonitorHandle {
pub fn current_monitor(&self) -> Option<RootMonitorHandle> {
Some(RootMonitorHandle {
inner: monitor::current_monitor(self.window.0),
}
})
}

#[inline]
Expand Down
6 changes: 4 additions & 2 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<MonitorHandle> {
self.window.current_monitor()
}

Expand Down

0 comments on commit 7030548

Please sign in to comment.