Move available_monitors and primary_monitor to EventLoopWindowTarget (#1616)

This commit is contained in:
Xavier L'Heureux 2020-07-04 15:46:41 -04:00 committed by GitHub
parent dd866a74a6
commit 3d5d05eac7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 121 additions and 110 deletions

View file

@ -1,5 +1,6 @@
# Unreleased # Unreleased
- On all platforms, `available_monitors` and `primary_monitor` are now on `EventLoopWindowTarget` rather than `EventLoop` to list monitors event in the event loop.
- On Unix, X11 and Wayland are now optional features (enabled by default) - On Unix, X11 and Wayland are now optional features (enabled by default)
- On X11, fix deadlock when calling `set_fullscreen_inner`. - On X11, fix deadlock when calling `set_fullscreen_inner`.
- On Web, prevent the webpage from scrolling when the user is focused on a winit canvas - On Web, prevent the webpage from scrolling when the user is focused on a winit canvas

View file

@ -155,11 +155,20 @@ impl<T> EventLoop<T> {
event_loop_proxy: self.event_loop.create_proxy(), event_loop_proxy: self.event_loop.create_proxy(),
} }
} }
}
impl<T> Deref for EventLoop<T> {
type Target = EventLoopWindowTarget<T>;
fn deref(&self) -> &EventLoopWindowTarget<T> {
self.event_loop.window_target()
}
}
impl<T> EventLoopWindowTarget<T> {
/// Returns the list of all the monitors available on the system. /// Returns the list of all the monitors available on the system.
#[inline] #[inline]
pub fn available_monitors(&self) -> impl Iterator<Item = MonitorHandle> { pub fn available_monitors(&self) -> impl Iterator<Item = MonitorHandle> {
self.event_loop self.p
.available_monitors() .available_monitors()
.into_iter() .into_iter()
.map(|inner| MonitorHandle { inner }) .map(|inner| MonitorHandle { inner })
@ -169,18 +178,11 @@ impl<T> EventLoop<T> {
#[inline] #[inline]
pub fn primary_monitor(&self) -> MonitorHandle { pub fn primary_monitor(&self) -> MonitorHandle {
MonitorHandle { MonitorHandle {
inner: self.event_loop.primary_monitor(), inner: self.p.primary_monitor(),
} }
} }
} }
impl<T> Deref for EventLoop<T> {
type Target = EventLoopWindowTarget<T>;
fn deref(&self) -> &EventLoopWindowTarget<T> {
self.event_loop.window_target()
}
}
/// Used to send custom events to `EventLoop`. /// Used to send custom events to `EventLoop`.
pub struct EventLoopProxy<T: 'static> { pub struct EventLoopProxy<T: 'static> {
event_loop_proxy: platform_impl::EventLoopProxy<T>, event_loop_proxy: platform_impl::EventLoopProxy<T>,

View file

@ -3,11 +3,11 @@
//! If you want to get basic information about a monitor, you can use the [`MonitorHandle`][monitor_handle] //! If you want to get basic information about a monitor, you can use the [`MonitorHandle`][monitor_handle]
//! type. This is retreived from one of the following methods, which return an iterator of //! type. This is retreived from one of the following methods, which return an iterator of
//! [`MonitorHandle`][monitor_handle]: //! [`MonitorHandle`][monitor_handle]:
//! - [`EventLoop::available_monitors`][loop_get] //! - [`EventLoopWindowTarget::available_monitors`][loop_get]
//! - [`Window::available_monitors`][window_get]. //! - [`Window::available_monitors`][window_get].
//! //!
//! [monitor_handle]: crate::monitor::MonitorHandle //! [monitor_handle]: crate::monitor::MonitorHandle
//! [loop_get]: crate::event_loop::EventLoop::available_monitors //! [loop_get]: crate::event_loop::EventLoopWindowTarget::available_monitors
//! [window_get]: crate::window::Window::available_monitors //! [window_get]: crate::window::Window::available_monitors
use crate::{ use crate::{
dpi::{PhysicalPosition, PhysicalSize}, dpi::{PhysicalPosition, PhysicalSize},

View file

@ -295,16 +295,6 @@ impl<T: 'static> EventLoop<T> {
&self.window_target &self.window_target
} }
pub fn primary_monitor(&self) -> MonitorHandle {
MonitorHandle
}
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
let mut v = VecDeque::with_capacity(1);
v.push_back(self.primary_monitor());
v
}
pub fn create_proxy(&self) -> EventLoopProxy<T> { pub fn create_proxy(&self) -> EventLoopProxy<T> {
EventLoopProxy { EventLoopProxy {
queue: self.user_queue.clone(), queue: self.user_queue.clone(),
@ -339,6 +329,18 @@ pub struct EventLoopWindowTarget<T: 'static> {
_marker: std::marker::PhantomData<T>, _marker: std::marker::PhantomData<T>,
} }
impl<T: 'static> EventLoopWindowTarget<T> {
pub fn primary_monitor(&self) -> MonitorHandle {
MonitorHandle
}
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
let mut v = VecDeque::with_capacity(1);
v.push_back(self.primary_monitor());
v
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct WindowId; pub struct WindowId;

View file

@ -49,6 +49,18 @@ pub struct EventLoopWindowTarget<T: 'static> {
sender_to_clone: Sender<T>, sender_to_clone: Sender<T>,
} }
impl<T: 'static> EventLoopWindowTarget<T> {
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
// guaranteed to be on main thread
unsafe { monitor::uiscreens() }
}
pub fn primary_monitor(&self) -> MonitorHandle {
// guaranteed to be on main thread
unsafe { monitor::main_uiscreen() }
}
}
pub struct EventLoop<T: 'static> { pub struct EventLoop<T: 'static> {
window_target: RootEventLoopWindowTarget<T>, window_target: RootEventLoopWindowTarget<T>,
} }
@ -115,16 +127,6 @@ impl<T: 'static> EventLoop<T> {
EventLoopProxy::new(self.window_target.p.sender_to_clone.clone()) EventLoopProxy::new(self.window_target.p.sender_to_clone.clone())
} }
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
// guaranteed to be on main thread
unsafe { monitor::uiscreens() }
}
pub fn primary_monitor(&self) -> MonitorHandle {
// guaranteed to be on main thread
unsafe { monitor::main_uiscreen() }
}
pub fn window_target(&self) -> &RootEventLoopWindowTarget<T> { pub fn window_target(&self) -> &RootEventLoopWindowTarget<T> {
&self.window_target &self.window_target
} }

View file

@ -602,35 +602,6 @@ impl<T: 'static> EventLoop<T> {
Ok(EventLoop::X(x11::EventLoop::new(xconn))) Ok(EventLoop::X(x11::EventLoop::new(xconn)))
} }
#[inline]
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
match *self {
#[cfg(feature = "wayland")]
EventLoop::Wayland(ref evlp) => evlp
.available_monitors()
.into_iter()
.map(MonitorHandle::Wayland)
.collect(),
#[cfg(feature = "x11")]
EventLoop::X(ref evlp) => evlp
.x_connection()
.available_monitors()
.into_iter()
.map(MonitorHandle::X)
.collect(),
}
}
#[inline]
pub fn primary_monitor(&self) -> MonitorHandle {
match *self {
#[cfg(feature = "wayland")]
EventLoop::Wayland(ref evlp) => MonitorHandle::Wayland(evlp.primary_monitor()),
#[cfg(feature = "x11")]
EventLoop::X(ref evlp) => MonitorHandle::X(evlp.x_connection().primary_monitor()),
}
}
pub fn create_proxy(&self) -> EventLoopProxy<T> { pub fn create_proxy(&self) -> EventLoopProxy<T> {
x11_or_wayland!(match self; EventLoop(evlp) => evlp.create_proxy(); as EventLoopProxy) x11_or_wayland!(match self; EventLoop(evlp) => evlp.create_proxy(); as EventLoopProxy)
} }
@ -677,6 +648,39 @@ impl<T> EventLoopWindowTarget<T> {
_ => false, _ => false,
} }
} }
#[inline]
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
match *self {
#[cfg(feature = "wayland")]
EventLoopWindowTarget::Wayland(ref evlp) => evlp
.available_monitors()
.into_iter()
.map(MonitorHandle::Wayland)
.collect(),
#[cfg(feature = "x11")]
EventLoopWindowTarget::X(ref evlp) => evlp
.x_connection()
.available_monitors()
.into_iter()
.map(MonitorHandle::X)
.collect(),
}
}
#[inline]
pub fn primary_monitor(&self) -> MonitorHandle {
match *self {
#[cfg(feature = "wayland")]
EventLoopWindowTarget::Wayland(ref evlp) => {
MonitorHandle::Wayland(evlp.primary_monitor())
}
#[cfg(feature = "x11")]
EventLoopWindowTarget::X(ref evlp) => {
MonitorHandle::X(evlp.x_connection().primary_monitor())
}
}
}
} }
fn sticky_exit_callback<T, F>( fn sticky_exit_callback<T, F>(

View file

@ -245,8 +245,6 @@ pub struct EventLoop<T: 'static> {
poll: Poll, poll: Poll,
// The wayland display // The wayland display
pub display: Arc<Display>, pub display: Arc<Display>,
// The output manager
pub outputs: OutputMgr,
// The cursor manager // The cursor manager
cursor_manager: Arc<Mutex<CursorManager>>, cursor_manager: Arc<Mutex<CursorManager>>,
kbd_channel: Receiver<Event<'static, ()>>, kbd_channel: Receiver<Event<'static, ()>>,
@ -277,6 +275,8 @@ pub struct EventLoopWindowTarget<T> {
pub display: Arc<Display>, pub display: Arc<Display>,
// The list of seats // The list of seats
pub seats: Arc<Mutex<Vec<(u32, wl_seat::WlSeat)>>>, pub seats: Arc<Mutex<Vec<(u32, wl_seat::WlSeat)>>>,
// The output manager
pub outputs: OutputMgr,
_marker: ::std::marker::PhantomData<T>, _marker: ::std::marker::PhantomData<T>,
} }
@ -418,10 +418,10 @@ impl<T: 'static> EventLoop<T> {
.unwrap(); .unwrap();
let cursor_manager_clone = cursor_manager.clone(); let cursor_manager_clone = cursor_manager.clone();
let outputs = env.outputs.clone();
Ok(EventLoop { Ok(EventLoop {
poll, poll,
display: display.clone(), display: display.clone(),
outputs: env.outputs.clone(),
user_sender, user_sender,
user_channel, user_channel,
kbd_channel, kbd_channel,
@ -435,6 +435,7 @@ impl<T: 'static> EventLoop<T> {
cleanup_needed: Arc::new(Mutex::new(false)), cleanup_needed: Arc::new(Mutex::new(false)),
seats, seats,
display, display,
outputs,
_marker: ::std::marker::PhantomData, _marker: ::std::marker::PhantomData,
}), }),
_marker: ::std::marker::PhantomData, _marker: ::std::marker::PhantomData,
@ -633,14 +634,6 @@ impl<T: 'static> EventLoop<T> {
callback(Event::LoopDestroyed, &self.window_target, &mut control_flow); callback(Event::LoopDestroyed, &self.window_target, &mut control_flow);
} }
pub fn primary_monitor(&self) -> MonitorHandle {
primary_monitor(&self.outputs)
}
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
available_monitors(&self.outputs)
}
pub fn window_target(&self) -> &RootELW<T> { pub fn window_target(&self) -> &RootELW<T> {
&self.window_target &self.window_target
} }
@ -650,6 +643,14 @@ impl<T> EventLoopWindowTarget<T> {
pub fn display(&self) -> &Display { pub fn display(&self) -> &Display {
&*self.display &*self.display
} }
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
available_monitors(&self.outputs)
}
pub fn primary_monitor(&self) -> MonitorHandle {
primary_monitor(&self.outputs)
}
} }
/* /*

View file

@ -258,10 +258,6 @@ impl<T: 'static> EventLoop<T> {
&self.target &self.target
} }
pub(crate) fn x_connection(&self) -> &Arc<XConnection> {
get_xtarget(&self.target).x_connection()
}
pub fn run_return<F>(&mut self, mut callback: F) pub fn run_return<F>(&mut self, mut callback: F)
where where
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow), F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),

View file

@ -34,6 +34,18 @@ impl<T> Default for EventLoopWindowTarget<T> {
} }
} }
impl<T: 'static> EventLoopWindowTarget<T> {
#[inline]
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
monitor::available_monitors()
}
#[inline]
pub fn primary_monitor(&self) -> MonitorHandle {
monitor::primary_monitor()
}
}
pub struct EventLoop<T: 'static> { pub struct EventLoop<T: 'static> {
window_target: Rc<RootWindowTarget<T>>, window_target: Rc<RootWindowTarget<T>>,
_delegate: IdRef, _delegate: IdRef,
@ -68,16 +80,6 @@ impl<T> EventLoop<T> {
} }
} }
#[inline]
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
monitor::available_monitors()
}
#[inline]
pub fn primary_monitor(&self) -> MonitorHandle {
monitor::primary_monitor()
}
pub fn window_target(&self) -> &RootWindowTarget<T> { pub fn window_target(&self) -> &RootWindowTarget<T> {
&self.window_target &self.window_target
} }

View file

@ -27,14 +27,6 @@ impl<T> EventLoop<T> {
} }
} }
pub fn available_monitors(&self) -> VecDequeIter<monitor::Handle> {
VecDeque::new().into_iter()
}
pub fn primary_monitor(&self) -> monitor::Handle {
monitor::Handle
}
pub fn run<F>(self, mut event_handler: F) -> ! pub fn run<F>(self, mut event_handler: F) -> !
where where
F: 'static F: 'static

View file

@ -1,9 +1,10 @@
use super::{backend, device, proxy::Proxy, runner, window}; use super::{super::monitor, backend, device, proxy::Proxy, runner, window};
use crate::dpi::{PhysicalSize, Size}; use crate::dpi::{PhysicalSize, Size};
use crate::event::{DeviceId, ElementState, Event, KeyboardInput, TouchPhase, WindowEvent}; use crate::event::{DeviceId, ElementState, Event, KeyboardInput, TouchPhase, WindowEvent};
use crate::event_loop::ControlFlow; use crate::event_loop::ControlFlow;
use crate::window::{Theme, WindowId}; use crate::window::{Theme, WindowId};
use std::clone::Clone; use std::clone::Clone;
use std::collections::{vec_deque::IntoIter as VecDequeIter, VecDeque};
pub struct WindowTarget<T: 'static> { pub struct WindowTarget<T: 'static> {
pub(crate) runner: runner::Shared<T>, pub(crate) runner: runner::Shared<T>,
@ -213,4 +214,12 @@ impl<T> WindowTarget<T> {
}); });
}); });
} }
pub fn available_monitors(&self) -> VecDequeIter<monitor::Handle> {
VecDeque::new().into_iter()
}
pub fn primary_monitor(&self) -> monitor::Handle {
monitor::Handle
}
} }

View file

@ -4,6 +4,7 @@ mod runner;
use parking_lot::Mutex; use parking_lot::Mutex;
use std::{ use std::{
collections::VecDeque,
marker::PhantomData, marker::PhantomData,
mem, panic, ptr, mem, panic, ptr,
rc::Rc, rc::Rc,
@ -38,7 +39,8 @@ use crate::{
dpi::{become_dpi_aware, dpi_to_scale_factor, enable_non_client_dpi_scaling}, dpi::{become_dpi_aware, dpi_to_scale_factor, enable_non_client_dpi_scaling},
drop_handler::FileDropHandler, drop_handler::FileDropHandler,
event::{self, handle_extended_keys, process_key_params, vkey_to_winit_vkey}, event::{self, handle_extended_keys, process_key_params, vkey_to_winit_vkey},
monitor, raw_input, util, monitor::{self, MonitorHandle},
raw_input, util,
window_state::{CursorFlags, WindowFlags, WindowState}, window_state::{CursorFlags, WindowFlags, WindowState},
wrap_device_id, WindowId, DEVICE_ID, wrap_device_id, WindowId, DEVICE_ID,
}, },
@ -247,6 +249,15 @@ impl<T> EventLoopWindowTarget<T> {
target_window: self.thread_msg_target, target_window: self.thread_msg_target,
} }
} }
// TODO: Investigate opportunities for caching
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
monitor::available_monitors()
}
pub fn primary_monitor(&self) -> MonitorHandle {
monitor::primary_monitor()
}
} }
fn main_thread_id() -> DWORD { fn main_thread_id() -> DWORD {
@ -851,7 +862,7 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
window_pos.cy = new_monitor_rect.bottom - new_monitor_rect.top; window_pos.cy = new_monitor_rect.bottom - new_monitor_rect.top;
} }
*fullscreen_monitor = crate::monitor::MonitorHandle { *fullscreen_monitor = crate::monitor::MonitorHandle {
inner: monitor::MonitorHandle::new(new_monitor), inner: MonitorHandle::new(new_monitor),
}; };
} }
} }

View file

@ -11,7 +11,7 @@ use std::{
io, mem, ptr, io, mem, ptr,
}; };
use super::{util, EventLoop}; use super::util;
use crate::{ use crate::{
dpi::{PhysicalPosition, PhysicalSize}, dpi::{PhysicalPosition, PhysicalSize},
monitor::{MonitorHandle as RootMonitorHandle, VideoMode as RootVideoMode}, monitor::{MonitorHandle as RootMonitorHandle, VideoMode as RootVideoMode},
@ -126,17 +126,6 @@ pub fn current_monitor(hwnd: HWND) -> MonitorHandle {
MonitorHandle::new(hmonitor) MonitorHandle::new(hmonitor)
} }
impl<T> EventLoop<T> {
// TODO: Investigate opportunities for caching
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
available_monitors()
}
pub fn primary_monitor(&self) -> MonitorHandle {
primary_monitor()
}
}
impl Window { impl Window {
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> { pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
available_monitors() available_monitors()

View file

@ -758,7 +758,7 @@ impl Window {
/// Returns the list of all the monitors available on the system. /// Returns the list of all the monitors available on the system.
/// ///
/// This is the same as `EventLoop::available_monitors`, and is provided for convenience. /// This is the same as `EventLoopWindowTarget::available_monitors`, and is provided for convenience.
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
@ -773,7 +773,7 @@ impl Window {
/// Returns the primary monitor of the system. /// Returns the primary monitor of the system.
/// ///
/// This is the same as `EventLoop::primary_monitor`, and is provided for convenience. /// This is the same as `EventLoopWindowTarget::primary_monitor`, and is provided for convenience.
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///