diff --git a/CHANGELOG.md b/CHANGELOG.md index 3acb79f4..3690e2af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ - **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`. +- **Breaking:** `primary_monitor` now returns `Option`. # 0.22.2 (2020-05-16) diff --git a/examples/video_modes.rs b/examples/video_modes.rs index 366c5195..e19a0b03 100644 --- a/examples/video_modes.rs +++ b/examples/video_modes.rs @@ -3,7 +3,13 @@ use winit::event_loop::EventLoop; fn main() { simple_logger::init().unwrap(); let event_loop = EventLoop::new(); - let monitor = event_loop.primary_monitor(); + let monitor = match event_loop.primary_monitor() { + Some(monitor) => monitor, + None => { + println!("No primary monitor detected."); + return; + } + }; println!("Listing available video modes:"); diff --git a/src/event_loop.rs b/src/event_loop.rs index 02402930..efc67efd 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -178,11 +178,15 @@ impl EventLoopWindowTarget { } /// Returns the primary monitor of the system. + /// + /// Returns `None` if it can't identify any monitor as a primary one. + /// + /// ## Platform-specific + /// + /// **Wayland:** Always returns `None`. #[inline] - pub fn primary_monitor(&self) -> MonitorHandle { - MonitorHandle { - inner: self.p.primary_monitor(), - } + pub fn primary_monitor(&self) -> Option { + self.p.primary_monitor() } } diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index db759ed5..471dd15d 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -333,13 +333,15 @@ pub struct EventLoopWindowTarget { } impl EventLoopWindowTarget { - pub fn primary_monitor(&self) -> MonitorHandle { - MonitorHandle + pub fn primary_monitor(&self) -> Option { + Some(monitor::MonitorHandle { + inner: MonitorHandle, + }) } pub fn available_monitors(&self) -> VecDeque { let mut v = VecDeque::with_capacity(1); - v.push_back(self.primary_monitor()); + v.push_back(MonitorHandle); v } } @@ -381,8 +383,10 @@ impl Window { WindowId } - pub fn primary_monitor(&self) -> MonitorHandle { - MonitorHandle + pub fn primary_monitor(&self) -> Option { + Some(monitor::MonitorHandle { + inner: MonitorHandle, + }) } pub fn available_monitors(&self) -> VecDeque { diff --git a/src/platform_impl/ios/event_loop.rs b/src/platform_impl/ios/event_loop.rs index 9536e942..1680c98a 100644 --- a/src/platform_impl/ios/event_loop.rs +++ b/src/platform_impl/ios/event_loop.rs @@ -13,6 +13,7 @@ use crate::{ event_loop::{ ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootEventLoopWindowTarget, }, + monitor::MonitorHandle as RootMonitorHandle, platform::ios::Idiom, }; @@ -56,9 +57,11 @@ impl EventLoopWindowTarget { unsafe { monitor::uiscreens() } } - pub fn primary_monitor(&self) -> MonitorHandle { + pub fn primary_monitor(&self) -> Option { // guaranteed to be on main thread - unsafe { monitor::main_uiscreen() } + let monitor = unsafe { monitor::main_uiscreen() }; + + Some(RootMonitorHandle { inner: monitor }) } } diff --git a/src/platform_impl/ios/window.rs b/src/platform_impl/ios/window.rs index 2be710e2..a7deb61b 100644 --- a/src/platform_impl/ios/window.rs +++ b/src/platform_impl/ios/window.rs @@ -276,8 +276,9 @@ impl Inner { unsafe { monitor::uiscreens() } } - pub fn primary_monitor(&self) -> MonitorHandle { - unsafe { monitor::main_uiscreen() } + pub fn primary_monitor(&self) -> Option { + let monitor = unsafe { monitor::main_uiscreen() }; + Some(RootMonitorHandle { inner: monitor }) } pub fn id(&self) -> WindowId { diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index c2214ace..43fd8451 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -463,8 +463,18 @@ impl Window { } #[inline] - pub fn primary_monitor(&self) -> MonitorHandle { - x11_or_wayland!(match self; Window(window) => window.primary_monitor(); as MonitorHandle) + pub fn primary_monitor(&self) -> Option { + match self { + #[cfg(feature = "x11")] + &Window::X(ref window) => { + let primary_monitor = MonitorHandle::X(window.primary_monitor()); + Some(RootMonitorHandle { + inner: primary_monitor, + }) + } + #[cfg(feature = "wayland")] + &Window::Wayland(ref window) => window.primary_monitor(), + } } pub fn raw_window_handle(&self) -> RawWindowHandle { @@ -682,15 +692,16 @@ impl EventLoopWindowTarget { } #[inline] - pub fn primary_monitor(&self) -> MonitorHandle { + pub fn primary_monitor(&self) -> Option { match *self { #[cfg(feature = "wayland")] - EventLoopWindowTarget::Wayland(ref evlp) => { - MonitorHandle::Wayland(evlp.primary_monitor()) - } + EventLoopWindowTarget::Wayland(ref evlp) => evlp.primary_monitor(), #[cfg(feature = "x11")] EventLoopWindowTarget::X(ref evlp) => { - MonitorHandle::X(evlp.x_connection().primary_monitor()) + let primary_monitor = MonitorHandle::X(evlp.x_connection().primary_monitor()); + Some(RootMonitorHandle { + inner: primary_monitor, + }) } } } diff --git a/src/platform_impl/linux/wayland/event_loop.rs b/src/platform_impl/linux/wayland/event_loop.rs index 77215b9c..4dd66f12 100644 --- a/src/platform_impl/linux/wayland/event_loop.rs +++ b/src/platform_impl/linux/wayland/event_loop.rs @@ -648,8 +648,9 @@ impl EventLoopWindowTarget { available_monitors(&self.outputs) } - pub fn primary_monitor(&self) -> MonitorHandle { - primary_monitor(&self.outputs) + pub fn primary_monitor(&self) -> Option { + // Wayland doesn't have a notion of primary monitor. + None } } @@ -1121,19 +1122,6 @@ impl MonitorHandle { } } -pub fn primary_monitor(outputs: &OutputMgr) -> MonitorHandle { - outputs.with_all(|list| { - if let Some(&(_, ref proxy, _)) = list.first() { - MonitorHandle { - proxy: proxy.clone(), - mgr: outputs.clone(), - } - } else { - panic!("No monitor is available.") - } - }) -} - pub fn available_monitors(outputs: &OutputMgr) -> VecDeque { outputs.with_all(|list| { list.iter() diff --git a/src/platform_impl/linux/wayland/window.rs b/src/platform_impl/linux/wayland/window.rs index 11c38466..c61ff19e 100644 --- a/src/platform_impl/linux/wayland/window.rs +++ b/src/platform_impl/linux/wayland/window.rs @@ -10,8 +10,7 @@ use crate::{ error::{ExternalError, NotSupportedError, OsError as RootOsError}, monitor::MonitorHandle as RootMonitorHandle, platform_impl::{ - platform::wayland::event_loop::{available_monitors, primary_monitor}, - MonitorHandle as PlatformMonitorHandle, + platform::wayland::event_loop::available_monitors, MonitorHandle as PlatformMonitorHandle, PlatformSpecificWindowBuilderAttributes as PlAttributes, }, window::{CursorIcon, Fullscreen, WindowAttributes}, @@ -410,8 +409,9 @@ impl Window { available_monitors(&self.outputs) } - pub fn primary_monitor(&self) -> MonitorHandle { - primary_monitor(&self.outputs) + pub fn primary_monitor(&self) -> Option { + // Wayland doesn't have a notion of primary monitor. + None } pub fn raw_window_handle(&self) -> WaylandHandle { diff --git a/src/platform_impl/macos/event_loop.rs b/src/platform_impl/macos/event_loop.rs index 0d88d979..5b3d96b0 100644 --- a/src/platform_impl/macos/event_loop.rs +++ b/src/platform_impl/macos/event_loop.rs @@ -12,6 +12,7 @@ use cocoa::{ use crate::{ event::Event, event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootWindowTarget}, + monitor::MonitorHandle as RootMonitorHandle, platform_impl::platform::{ app::APP_CLASS, app_delegate::APP_DELEGATE_CLASS, @@ -41,8 +42,9 @@ impl EventLoopWindowTarget { } #[inline] - pub fn primary_monitor(&self) -> MonitorHandle { - monitor::primary_monitor() + pub fn primary_monitor(&self) -> Option { + let monitor = monitor::primary_monitor(); + Some(RootMonitorHandle { inner: monitor }) } } diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 919fc2c7..d2b01403 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -997,8 +997,9 @@ impl UnownedWindow { } #[inline] - pub fn primary_monitor(&self) -> MonitorHandle { - monitor::primary_monitor() + pub fn primary_monitor(&self) -> Option { + let monitor = monitor::primary_monitor(); + Some(RootMonitorHandle { inner: monitor }) } #[inline] diff --git a/src/platform_impl/web/event_loop/window_target.rs b/src/platform_impl/web/event_loop/window_target.rs index 0815bd40..f26f984a 100644 --- a/src/platform_impl/web/event_loop/window_target.rs +++ b/src/platform_impl/web/event_loop/window_target.rs @@ -2,6 +2,7 @@ use super::{super::monitor, backend, device, proxy::Proxy, runner, window}; use crate::dpi::{PhysicalSize, Size}; use crate::event::{DeviceId, ElementState, Event, KeyboardInput, TouchPhase, WindowEvent}; use crate::event_loop::ControlFlow; +use crate::monitor::MonitorHandle as RootMH; use crate::window::{Theme, WindowId}; use std::clone::Clone; use std::collections::{vec_deque::IntoIter as VecDequeIter, VecDeque}; @@ -237,7 +238,9 @@ impl WindowTarget { VecDeque::new().into_iter() } - pub fn primary_monitor(&self) -> monitor::Handle { - monitor::Handle + pub fn primary_monitor(&self) -> Option { + Some(RootMH { + inner: monitor::Handle, + }) } } diff --git a/src/platform_impl/web/window.rs b/src/platform_impl/web/window.rs index 5f2cae62..165661fa 100644 --- a/src/platform_impl/web/window.rs +++ b/src/platform_impl/web/window.rs @@ -255,8 +255,10 @@ impl Window { } #[inline] - pub fn primary_monitor(&self) -> monitor::Handle { - monitor::Handle + pub fn primary_monitor(&self) -> Option { + Some(RootMH { + inner: monitor::Handle, + }) } #[inline] diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index eb0a6576..9227bceb 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -34,6 +34,7 @@ use crate::{ dpi::{PhysicalPosition, PhysicalSize}, event::{DeviceEvent, Event, Force, KeyboardInput, Touch, TouchPhase, WindowEvent}, event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW}, + monitor::MonitorHandle as RootMonitorHandle, platform_impl::platform::{ dark_mode::try_dark_mode, dpi::{become_dpi_aware, dpi_to_scale_factor, enable_non_client_dpi_scaling}, @@ -255,8 +256,9 @@ impl EventLoopWindowTarget { monitor::available_monitors() } - pub fn primary_monitor(&self) -> MonitorHandle { - monitor::primary_monitor() + pub fn primary_monitor(&self) -> Option { + let monitor = monitor::primary_monitor(); + Some(RootMonitorHandle { inner: monitor }) } } diff --git a/src/platform_impl/windows/monitor.rs b/src/platform_impl/windows/monitor.rs index 7fa4c73d..ff88d102 100644 --- a/src/platform_impl/windows/monitor.rs +++ b/src/platform_impl/windows/monitor.rs @@ -131,8 +131,9 @@ impl Window { available_monitors() } - pub fn primary_monitor(&self) -> MonitorHandle { - primary_monitor() + pub fn primary_monitor(&self) -> Option { + let monitor = primary_monitor(); + Some(RootMonitorHandle { inner: monitor }) } } diff --git a/src/window.rs b/src/window.rs index b8bec50b..1977d32c 100644 --- a/src/window.rs +++ b/src/window.rs @@ -765,16 +765,17 @@ impl Window { /// Returns the primary monitor of the system. /// + /// Returns `None` if it can't identify any monitor as a primary one. + /// /// This is the same as `EventLoopWindowTarget::primary_monitor`, and is provided for convenience. /// /// ## Platform-specific /// /// **iOS:** Can only be called on the main thread. + /// **Wayland:** Always returns `None`. #[inline] - pub fn primary_monitor(&self) -> MonitorHandle { - MonitorHandle { - inner: self.window.primary_monitor(), - } + pub fn primary_monitor(&self) -> Option { + self.window.primary_monitor() } }