Skip to content

Commit

Permalink
Make current_monitor return Option<MonitorHandle>
Browse files Browse the repository at this point in the history
On certain platfroms window couldn't be on any monitor
resulting in failures of `current_monitor` function on such,
since they can't return any monitor at all.

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 Aug 30, 2020
1 parent a2db4c0 commit 950da60
Show file tree
Hide file tree
Showing 12 changed files with 52 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- 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:** `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: 4 additions & 4 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().unwrap();
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,12 +258,12 @@ impl Inner {
warn!("`Window::set_ime_position` is ignored on iOS")
}

pub fn current_monitor(&self) -> RootMonitorHandle {
pub fn current_monitor(&self) -> Option<RootMonitorHandle> {
unsafe {
let uiscreen: id = msg_send![self.window, screen];
RootMonitorHandle {
Some(RootMonitorHandle {
inner: MonitorHandle::retained_new(uiscreen),
}
})
}
}

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
6 changes: 3 additions & 3 deletions src/platform_impl/macos/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -972,16 +972,16 @@ impl UnownedWindow {
}

#[inline]
pub fn current_monitor(&self) -> RootMonitorHandle {
pub fn current_monitor(&self) -> Option<RootMonitorHandle> {
unsafe {
let screen: id = msg_send![*self.ns_window, screen];
let desc = NSScreen::deviceDescription(screen);
let key = util::ns_string_id_ref("NSScreenNumber");
let value = NSDictionary::valueForKey_(desc, *key);
let display_id = msg_send![value, unsignedIntegerValue];
RootMonitorHandle {
Some(RootMonitorHandle {
inner: MonitorHandle::new(display_id),
}
})
}
}

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().unwrap();
shared_state.fullscreen = Some(Fullscreen::Borderless(current_monitor))
}
}
shared_state.in_fullscreen_transition = true;
Expand Down
8 changes: 4 additions & 4 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().unwrap()))
} else {
None
}
Expand Down Expand Up @@ -237,10 +237,10 @@ impl Window {
}

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

#[inline]
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
8 changes: 6 additions & 2 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -736,13 +736,17 @@ 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.
///
/// If `None` was returned it could mean that window isn't presented on any monitor.
/// However you must not treat it as it's minimized, obscured, or localted on some
/// virtual desktop.
///
/// ## 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 950da60

Please sign in to comment.