Make 'primary_monitor' return 'Option<MonitorHandle>'

Certain platforms like Wayland don't have a concept of
primary Monitor in particular. To indicate that
'primary_monitor' will return 'None' as well as in cases
where the primary monitor can't be detected.

Fixes #1683.
This commit is contained in:
Kirill Chibisov 2020-09-07 20:20:47 +03:00 committed by GitHub
parent cac627ed05
commit d103dc2631
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 86 additions and 56 deletions

View file

@ -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<MonitorHandle>`.
- **Breaking:** `primary_monitor` now returns `Option<MonitorHandle>`.
# 0.22.2 (2020-05-16)

View file

@ -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:");

View file

@ -178,11 +178,15 @@ impl<T> EventLoopWindowTarget<T> {
}
/// 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<MonitorHandle> {
self.p.primary_monitor()
}
}

View file

@ -333,13 +333,15 @@ pub struct EventLoopWindowTarget<T: 'static> {
}
impl<T: 'static> EventLoopWindowTarget<T> {
pub fn primary_monitor(&self) -> MonitorHandle {
MonitorHandle
pub fn primary_monitor(&self) -> Option<monitor::MonitorHandle> {
Some(monitor::MonitorHandle {
inner: MonitorHandle,
})
}
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
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<monitor::MonitorHandle> {
Some(monitor::MonitorHandle {
inner: MonitorHandle,
})
}
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {

View file

@ -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<T: 'static> EventLoopWindowTarget<T> {
unsafe { monitor::uiscreens() }
}
pub fn primary_monitor(&self) -> MonitorHandle {
pub fn primary_monitor(&self) -> Option<RootMonitorHandle> {
// guaranteed to be on main thread
unsafe { monitor::main_uiscreen() }
let monitor = unsafe { monitor::main_uiscreen() };
Some(RootMonitorHandle { inner: monitor })
}
}

View file

@ -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<RootMonitorHandle> {
let monitor = unsafe { monitor::main_uiscreen() };
Some(RootMonitorHandle { inner: monitor })
}
pub fn id(&self) -> WindowId {

View file

@ -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<RootMonitorHandle> {
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<T> EventLoopWindowTarget<T> {
}
#[inline]
pub fn primary_monitor(&self) -> MonitorHandle {
pub fn primary_monitor(&self) -> Option<RootMonitorHandle> {
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,
})
}
}
}

View file

@ -648,8 +648,9 @@ impl<T> EventLoopWindowTarget<T> {
available_monitors(&self.outputs)
}
pub fn primary_monitor(&self) -> MonitorHandle {
primary_monitor(&self.outputs)
pub fn primary_monitor(&self) -> Option<RootMonitorHandle> {
// 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<MonitorHandle> {
outputs.with_all(|list| {
list.iter()

View file

@ -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<RootMonitorHandle> {
// Wayland doesn't have a notion of primary monitor.
None
}
pub fn raw_window_handle(&self) -> WaylandHandle {

View file

@ -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<T: 'static> EventLoopWindowTarget<T> {
}
#[inline]
pub fn primary_monitor(&self) -> MonitorHandle {
monitor::primary_monitor()
pub fn primary_monitor(&self) -> Option<RootMonitorHandle> {
let monitor = monitor::primary_monitor();
Some(RootMonitorHandle { inner: monitor })
}
}

View file

@ -997,8 +997,9 @@ impl UnownedWindow {
}
#[inline]
pub fn primary_monitor(&self) -> MonitorHandle {
monitor::primary_monitor()
pub fn primary_monitor(&self) -> Option<RootMonitorHandle> {
let monitor = monitor::primary_monitor();
Some(RootMonitorHandle { inner: monitor })
}
#[inline]

View file

@ -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<T> WindowTarget<T> {
VecDeque::new().into_iter()
}
pub fn primary_monitor(&self) -> monitor::Handle {
monitor::Handle
pub fn primary_monitor(&self) -> Option<RootMH> {
Some(RootMH {
inner: monitor::Handle,
})
}
}

View file

@ -255,8 +255,10 @@ impl Window {
}
#[inline]
pub fn primary_monitor(&self) -> monitor::Handle {
monitor::Handle
pub fn primary_monitor(&self) -> Option<RootMH> {
Some(RootMH {
inner: monitor::Handle,
})
}
#[inline]

View file

@ -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<T> EventLoopWindowTarget<T> {
monitor::available_monitors()
}
pub fn primary_monitor(&self) -> MonitorHandle {
monitor::primary_monitor()
pub fn primary_monitor(&self) -> Option<RootMonitorHandle> {
let monitor = monitor::primary_monitor();
Some(RootMonitorHandle { inner: monitor })
}
}

View file

@ -131,8 +131,9 @@ impl Window {
available_monitors()
}
pub fn primary_monitor(&self) -> MonitorHandle {
primary_monitor()
pub fn primary_monitor(&self) -> Option<RootMonitorHandle> {
let monitor = primary_monitor();
Some(RootMonitorHandle { inner: monitor })
}
}

View file

@ -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<MonitorHandle> {
self.window.primary_monitor()
}
}