winit-sonoma-fix/src/platform_impl/linux/wayland/window.rs

398 lines
12 KiB
Rust
Raw Normal View History

use std::collections::VecDeque;
use std::sync::{Arc, Mutex, Weak};
use dpi::{LogicalPosition, LogicalSize};
use platform_impl::{MonitorHandle as PlatformMonitorHandle, PlatformSpecificWindowBuilderAttributes as PlAttributes};
use monitor::MonitorHandle as RootMonitorHandle;
use window::{CreationError, WindowAttributes, MouseCursor};
use sctk::surface::{get_dpi_factor, get_outputs};
use sctk::window::{ConceptFrame, Event as WEvent, Window as SWindow, Theme};
use sctk::reexports::client::Display;
use sctk::reexports::client::protocol::{wl_seat, wl_surface};
use sctk::output::OutputMgr;
use super::{make_wid, EventLoopWindowTarget, MonitorHandle, WindowId};
Event Loop 2.0 API and Windows implementation (#638) * Rename EventsLoop and associated types to EventLoop * Rename WindowEvent::Refresh to WindowEvent::Redraw * Remove second thread from win32 backend * Update run_forever to hijack thread * Replace windows Mutex with parking_lot Mutex * Implement new ControlFlow and associated events * Add StartCause::Init support, timer example * Add ability to send custom user events * Fully invert windows control flow so win32 calls into winit's callback * Add request_redraw * Rename platform to platform_impl * Rename os to platform, add Ext trait postfixes * Add platform::desktop module with EventLoopExt::run_return * Re-organize into module structure * Improve documentation * Small changes to examples * Improve docs for run and run_return * Change instances of "events_loop" to "event_loop" * Rename MonitorId to MonitorHandle * Add CHANGELOG entry * Improve WaitUntil timer precision * When SendEvent is called during event closure, buffer events * Fix resize lag when waiting in some situations * Update send test and errors that broke some examples/APIs * Improve clarity/fix typos in docs * Fix unreachable panic after setting ControlFlow to Poll during some RedrawRequested events. * Fix crash when running in release mode * Remove crossbeam dependency and make drop events work again * Remove serde implementations from ControlFlow * Fix 1.24.1 build * Fix freeze when setting decorations * Replace &EventLoop in callback with &EventLoopWindowTarget * Document and implement Debug for EventLoopWindowTarget * Fix some deadlocks that could occur when changing window state * Fix thread executor not executing closure when called from non-loop thread * Fix buffered events not getting dispatched * Fix crash with runner refcell not getting dropped * Address review feedback * Fix CHANGELOG typo * Catch panics in user callback
2019-02-06 02:30:33 +11:00
use platform_impl::platform::wayland::event_loop::{get_available_monitors, get_primary_monitor};
pub struct Window {
surface: wl_surface::WlSurface,
frame: Arc<Mutex<SWindow<ConceptFrame>>>,
outputs: OutputMgr, // Access to info for all monitors
size: Arc<Mutex<(u32, u32)>>,
kill_switch: (Arc<Mutex<bool>>, Arc<Mutex<bool>>),
display: Arc<Display>,
need_frame_refresh: Arc<Mutex<bool>>,
need_refresh: Arc<Mutex<bool>>
}
impl Window {
pub fn new<T>(evlp: &EventLoopWindowTarget<T>, attributes: WindowAttributes, pl_attribs: PlAttributes) -> Result<Window, CreationError> {
let (width, height) = attributes.dimensions.map(Into::into).unwrap_or((800, 600));
// Create the window
let size = Arc::new(Mutex::new((width, height)));
let window_store = evlp.store.clone();
let surface = evlp.env.create_surface(move |dpi, surface| {
window_store.lock().unwrap().dpi_change(&surface, dpi);
surface.set_buffer_scale(dpi);
});
let window_store = evlp.store.clone();
let my_surface = surface.clone();
let mut frame = SWindow::<ConceptFrame>::init_from_env(
&evlp.env,
surface.clone(),
(width, height),
move |event| match event {
WEvent::Configure { new_size, .. } => {
let mut store = window_store.lock().unwrap();
for window in &mut store.windows {
if window.surface.as_ref().equals(&my_surface.as_ref()) {
2018-06-15 09:42:18 +10:00
window.newsize = new_size;
*(window.need_refresh.lock().unwrap()) = true;
*(window.need_frame_refresh.lock().unwrap()) = true;
return;
}
}
}
WEvent::Refresh => {
let store = window_store.lock().unwrap();
for window in &store.windows {
if window.surface.as_ref().equals(&my_surface.as_ref()) {
*(window.need_frame_refresh.lock().unwrap()) = true;
return;
}
}
}
WEvent::Close => {
let mut store = window_store.lock().unwrap();
for window in &mut store.windows {
if window.surface.as_ref().equals(&my_surface.as_ref()) {
window.closed = true;
return;
}
}
}
},
).unwrap();
if let Some(app_id) = pl_attribs.app_id {
frame.set_app_id(app_id);
}
for &(_, ref seat) in evlp.seats.lock().unwrap().iter() {
frame.new_seat(seat);
}
// Check for fullscreen requirements
Event Loop 2.0 API and Windows implementation (#638) * Rename EventsLoop and associated types to EventLoop * Rename WindowEvent::Refresh to WindowEvent::Redraw * Remove second thread from win32 backend * Update run_forever to hijack thread * Replace windows Mutex with parking_lot Mutex * Implement new ControlFlow and associated events * Add StartCause::Init support, timer example * Add ability to send custom user events * Fully invert windows control flow so win32 calls into winit's callback * Add request_redraw * Rename platform to platform_impl * Rename os to platform, add Ext trait postfixes * Add platform::desktop module with EventLoopExt::run_return * Re-organize into module structure * Improve documentation * Small changes to examples * Improve docs for run and run_return * Change instances of "events_loop" to "event_loop" * Rename MonitorId to MonitorHandle * Add CHANGELOG entry * Improve WaitUntil timer precision * When SendEvent is called during event closure, buffer events * Fix resize lag when waiting in some situations * Update send test and errors that broke some examples/APIs * Improve clarity/fix typos in docs * Fix unreachable panic after setting ControlFlow to Poll during some RedrawRequested events. * Fix crash when running in release mode * Remove crossbeam dependency and make drop events work again * Remove serde implementations from ControlFlow * Fix 1.24.1 build * Fix freeze when setting decorations * Replace &EventLoop in callback with &EventLoopWindowTarget * Document and implement Debug for EventLoopWindowTarget * Fix some deadlocks that could occur when changing window state * Fix thread executor not executing closure when called from non-loop thread * Fix buffered events not getting dispatched * Fix crash with runner refcell not getting dropped * Address review feedback * Fix CHANGELOG typo * Catch panics in user callback
2019-02-06 02:30:33 +11:00
if let Some(RootMonitorHandle {
inner: PlatformMonitorHandle::Wayland(ref monitor_id),
}) = attributes.fullscreen
{
frame.set_fullscreen(Some(&monitor_id.proxy));
} else if attributes.maximized {
frame.set_maximized();
}
frame.set_resizable(attributes.resizable);
// set decorations
frame.set_decorate(attributes.decorations);
// set title
frame.set_title(attributes.title);
// min-max dimensions
frame.set_min_size(attributes.min_dimensions.map(Into::into));
frame.set_max_size(attributes.max_dimensions.map(Into::into));
2016-10-08 23:51:29 +11:00
let kill_switch = Arc::new(Mutex::new(false));
let need_frame_refresh = Arc::new(Mutex::new(true));
let frame = Arc::new(Mutex::new(frame));
let need_refresh = Arc::new(Mutex::new(true));
evlp.store.lock().unwrap().windows.push(InternalWindow {
closed: false,
newsize: None,
2018-06-15 09:42:18 +10:00
size: size.clone(),
need_refresh: need_refresh.clone(),
need_frame_refresh: need_frame_refresh.clone(),
surface: surface.clone(),
kill_switch: kill_switch.clone(),
frame: Arc::downgrade(&frame),
2018-06-15 09:42:18 +10:00
current_dpi: 1,
new_dpi: None,
});
evlp.evq.borrow_mut().sync_roundtrip().unwrap();
2016-10-08 23:51:29 +11:00
Ok(Window {
display: evlp.display.clone(),
surface: surface,
frame: frame,
outputs: evlp.env.outputs.clone(),
size: size,
kill_switch: (kill_switch, evlp.cleanup_needed.clone()),
need_frame_refresh,
need_refresh,
})
2017-03-05 00:04:01 +11:00
}
2016-10-08 23:51:29 +11:00
2017-03-05 00:04:01 +11:00
#[inline]
pub fn id(&self) -> WindowId {
make_wid(&self.surface)
}
pub fn set_title(&self, title: &str) {
self.frame.lock().unwrap().set_title(title.into());
}
#[inline]
pub fn show(&self) {
// TODO
}
#[inline]
pub fn hide(&self) {
// TODO
}
#[inline]
2018-06-15 09:42:18 +10:00
pub fn get_position(&self) -> Option<LogicalPosition> {
// Not possible with wayland
None
}
#[inline]
2018-06-15 09:42:18 +10:00
pub fn get_inner_position(&self) -> Option<LogicalPosition> {
// Not possible with wayland
None
}
#[inline]
2018-06-15 09:42:18 +10:00
pub fn set_position(&self, _pos: LogicalPosition) {
// Not possible with wayland
}
2018-06-15 09:42:18 +10:00
pub fn get_inner_size(&self) -> Option<LogicalSize> {
Some(self.size.lock().unwrap().clone().into())
}
pub fn request_redraw(&self) {
*self.need_refresh.lock().unwrap() = true;
}
#[inline]
2018-06-15 09:42:18 +10:00
pub fn get_outer_size(&self) -> Option<LogicalSize> {
2016-10-10 01:19:06 +11:00
let (w, h) = self.size.lock().unwrap().clone();
// let (w, h) = super::wayland_window::add_borders(w as i32, h as i32);
2018-06-15 09:42:18 +10:00
Some((w, h).into())
}
#[inline]
2016-10-10 01:19:06 +11:00
// NOTE: This will only resize the borders, the contents must be updated by the user
2018-06-15 09:42:18 +10:00
pub fn set_inner_size(&self, size: LogicalSize) {
let (w, h) = size.into();
self.frame.lock().unwrap().resize(w, h);
*(self.size.lock().unwrap()) = (w, h);
}
#[inline]
2018-06-15 09:42:18 +10:00
pub fn set_min_dimensions(&self, dimensions: Option<LogicalSize>) {
self.frame.lock().unwrap().set_min_size(dimensions.map(Into::into));
}
#[inline]
2018-06-15 09:42:18 +10:00
pub fn set_max_dimensions(&self, dimensions: Option<LogicalSize>) {
self.frame.lock().unwrap().set_max_size(dimensions.map(Into::into));
}
#[inline]
pub fn set_resizable(&self, resizable: bool) {
self.frame.lock().unwrap().set_resizable(resizable);
}
#[inline]
2018-06-15 09:42:18 +10:00
pub fn hidpi_factor(&self) -> i32 {
get_dpi_factor(&self.surface)
}
pub fn set_decorations(&self, decorate: bool) {
self.frame.lock().unwrap().set_decorate(decorate);
*(self.need_frame_refresh.lock().unwrap()) = true;
}
pub fn set_maximized(&self, maximized: bool) {
if maximized {
self.frame.lock().unwrap().set_maximized();
} else {
self.frame.lock().unwrap().unset_maximized();
}
}
Event Loop 2.0 API and Windows implementation (#638) * Rename EventsLoop and associated types to EventLoop * Rename WindowEvent::Refresh to WindowEvent::Redraw * Remove second thread from win32 backend * Update run_forever to hijack thread * Replace windows Mutex with parking_lot Mutex * Implement new ControlFlow and associated events * Add StartCause::Init support, timer example * Add ability to send custom user events * Fully invert windows control flow so win32 calls into winit's callback * Add request_redraw * Rename platform to platform_impl * Rename os to platform, add Ext trait postfixes * Add platform::desktop module with EventLoopExt::run_return * Re-organize into module structure * Improve documentation * Small changes to examples * Improve docs for run and run_return * Change instances of "events_loop" to "event_loop" * Rename MonitorId to MonitorHandle * Add CHANGELOG entry * Improve WaitUntil timer precision * When SendEvent is called during event closure, buffer events * Fix resize lag when waiting in some situations * Update send test and errors that broke some examples/APIs * Improve clarity/fix typos in docs * Fix unreachable panic after setting ControlFlow to Poll during some RedrawRequested events. * Fix crash when running in release mode * Remove crossbeam dependency and make drop events work again * Remove serde implementations from ControlFlow * Fix 1.24.1 build * Fix freeze when setting decorations * Replace &EventLoop in callback with &EventLoopWindowTarget * Document and implement Debug for EventLoopWindowTarget * Fix some deadlocks that could occur when changing window state * Fix thread executor not executing closure when called from non-loop thread * Fix buffered events not getting dispatched * Fix crash with runner refcell not getting dropped * Address review feedback * Fix CHANGELOG typo * Catch panics in user callback
2019-02-06 02:30:33 +11:00
pub fn set_fullscreen(&self, monitor: Option<RootMonitorHandle>) {
if let Some(RootMonitorHandle {
inner: PlatformMonitorHandle::Wayland(ref monitor_id),
}) = monitor
{
self.frame
.lock()
.unwrap()
.set_fullscreen(Some(&monitor_id.proxy));
} else {
self.frame.lock().unwrap().unset_fullscreen();
}
}
pub fn set_theme<T: Theme>(&self, theme: T) {
self.frame.lock().unwrap().set_theme(theme)
}
#[inline]
pub fn set_cursor(&self, _cursor: MouseCursor) {
// TODO
}
#[inline]
pub fn hide_cursor(&self, _hide: bool) {
// TODO: This isn't possible on Wayland yet
}
#[inline]
pub fn grab_cursor(&self, _grab: bool) -> Result<(), String> {
Err("Cursor grabbing is not yet possible on Wayland.".to_owned())
}
#[inline]
pub fn set_cursor_position(&self, _pos: LogicalPosition) -> Result<(), String> {
Err("Setting the cursor position is not yet possible on Wayland.".to_owned())
}
pub fn get_display(&self) -> &Display {
&*self.display
}
pub fn get_surface(&self) -> &wl_surface::WlSurface {
2016-10-08 23:51:29 +11:00
&self.surface
}
Move fullscreen modes to not touch physical resolutions (#270) * Fix X11 screen resolution change using XrandR The previous XF86 resolution switching was broken and everything seems to have moved on to xrandr. Use that instead while cleaning up the code a bit as well. * Use XRandR for actual multiscreen support in X11 * Use actual monitor names in X11 * Get rid of ptr::read usage in X11 * Use a bog standard Vec instead of VecDeque * Get rid of the XRandR mode switching stuff Wayland has made the decision that apps shouldn't change screen resolutions and just take the screens as they've been setup. In the modern world where GPU scaling is cheap and LCD panels are scaling anyway it makes no sense to make "physical" resolution changes when software should be taking care of it. This massively simplifies the code and makes it easier to extend to more niche setups like MST and videowalls. * Rename fullscreen options to match new semantics * Implement XRandR 1.5 support * Get rid of the FullScreen enum Moving to just having two states None and Some(MonitorId) and then being able to set full screen in the current monitor with something like: window.set_fullscreen(Some(window.current_monitor())); * Implement Window::get_current_monitor() Do it by iterating over the available monitors and finding which has the biggest overlap with the window. For this MonitorId needs a new get_position() that needs to be implemented for all platforms. * Add unimplemented get_position() to all MonitorId * Make get_current_monitor() platform specific * Add unimplemented get_current_monitor() to all * Implement proper primary monitor selection in X11 * Shut up some warnings * Remove libxxf86vm package from travis Since we're no longer using XF86 there's no need to keep the package around for CI. * Don't use new struct syntax * Fix indentation * Adjust Android/iOS fullscreen/maximized On Android and iOS we can assume single screen apps that are already fullscreen and maximized so there are a few methods that are implemented by just returning a fixed value or not doing anything. * Mark OSX/Win fullscreen/maximized unimplemented()! These would be safe as no-ops but we should make it explicit so there is more of an incentive to actually implement them.
2017-09-07 18:33:46 +10:00
Event Loop 2.0 API and Windows implementation (#638) * Rename EventsLoop and associated types to EventLoop * Rename WindowEvent::Refresh to WindowEvent::Redraw * Remove second thread from win32 backend * Update run_forever to hijack thread * Replace windows Mutex with parking_lot Mutex * Implement new ControlFlow and associated events * Add StartCause::Init support, timer example * Add ability to send custom user events * Fully invert windows control flow so win32 calls into winit's callback * Add request_redraw * Rename platform to platform_impl * Rename os to platform, add Ext trait postfixes * Add platform::desktop module with EventLoopExt::run_return * Re-organize into module structure * Improve documentation * Small changes to examples * Improve docs for run and run_return * Change instances of "events_loop" to "event_loop" * Rename MonitorId to MonitorHandle * Add CHANGELOG entry * Improve WaitUntil timer precision * When SendEvent is called during event closure, buffer events * Fix resize lag when waiting in some situations * Update send test and errors that broke some examples/APIs * Improve clarity/fix typos in docs * Fix unreachable panic after setting ControlFlow to Poll during some RedrawRequested events. * Fix crash when running in release mode * Remove crossbeam dependency and make drop events work again * Remove serde implementations from ControlFlow * Fix 1.24.1 build * Fix freeze when setting decorations * Replace &EventLoop in callback with &EventLoopWindowTarget * Document and implement Debug for EventLoopWindowTarget * Fix some deadlocks that could occur when changing window state * Fix thread executor not executing closure when called from non-loop thread * Fix buffered events not getting dispatched * Fix crash with runner refcell not getting dropped * Address review feedback * Fix CHANGELOG typo * Catch panics in user callback
2019-02-06 02:30:33 +11:00
pub fn get_current_monitor(&self) -> MonitorHandle {
let output = get_outputs(&self.surface).last().unwrap().clone();
MonitorHandle {
proxy: output,
mgr: self.outputs.clone(),
}
Move fullscreen modes to not touch physical resolutions (#270) * Fix X11 screen resolution change using XrandR The previous XF86 resolution switching was broken and everything seems to have moved on to xrandr. Use that instead while cleaning up the code a bit as well. * Use XRandR for actual multiscreen support in X11 * Use actual monitor names in X11 * Get rid of ptr::read usage in X11 * Use a bog standard Vec instead of VecDeque * Get rid of the XRandR mode switching stuff Wayland has made the decision that apps shouldn't change screen resolutions and just take the screens as they've been setup. In the modern world where GPU scaling is cheap and LCD panels are scaling anyway it makes no sense to make "physical" resolution changes when software should be taking care of it. This massively simplifies the code and makes it easier to extend to more niche setups like MST and videowalls. * Rename fullscreen options to match new semantics * Implement XRandR 1.5 support * Get rid of the FullScreen enum Moving to just having two states None and Some(MonitorId) and then being able to set full screen in the current monitor with something like: window.set_fullscreen(Some(window.current_monitor())); * Implement Window::get_current_monitor() Do it by iterating over the available monitors and finding which has the biggest overlap with the window. For this MonitorId needs a new get_position() that needs to be implemented for all platforms. * Add unimplemented get_position() to all MonitorId * Make get_current_monitor() platform specific * Add unimplemented get_current_monitor() to all * Implement proper primary monitor selection in X11 * Shut up some warnings * Remove libxxf86vm package from travis Since we're no longer using XF86 there's no need to keep the package around for CI. * Don't use new struct syntax * Fix indentation * Adjust Android/iOS fullscreen/maximized On Android and iOS we can assume single screen apps that are already fullscreen and maximized so there are a few methods that are implemented by just returning a fixed value or not doing anything. * Mark OSX/Win fullscreen/maximized unimplemented()! These would be safe as no-ops but we should make it explicit so there is more of an incentive to actually implement them.
2017-09-07 18:33:46 +10:00
}
Event Loop 2.0 API and Windows implementation (#638) * Rename EventsLoop and associated types to EventLoop * Rename WindowEvent::Refresh to WindowEvent::Redraw * Remove second thread from win32 backend * Update run_forever to hijack thread * Replace windows Mutex with parking_lot Mutex * Implement new ControlFlow and associated events * Add StartCause::Init support, timer example * Add ability to send custom user events * Fully invert windows control flow so win32 calls into winit's callback * Add request_redraw * Rename platform to platform_impl * Rename os to platform, add Ext trait postfixes * Add platform::desktop module with EventLoopExt::run_return * Re-organize into module structure * Improve documentation * Small changes to examples * Improve docs for run and run_return * Change instances of "events_loop" to "event_loop" * Rename MonitorId to MonitorHandle * Add CHANGELOG entry * Improve WaitUntil timer precision * When SendEvent is called during event closure, buffer events * Fix resize lag when waiting in some situations * Update send test and errors that broke some examples/APIs * Improve clarity/fix typos in docs * Fix unreachable panic after setting ControlFlow to Poll during some RedrawRequested events. * Fix crash when running in release mode * Remove crossbeam dependency and make drop events work again * Remove serde implementations from ControlFlow * Fix 1.24.1 build * Fix freeze when setting decorations * Replace &EventLoop in callback with &EventLoopWindowTarget * Document and implement Debug for EventLoopWindowTarget * Fix some deadlocks that could occur when changing window state * Fix thread executor not executing closure when called from non-loop thread * Fix buffered events not getting dispatched * Fix crash with runner refcell not getting dropped * Address review feedback * Fix CHANGELOG typo * Catch panics in user callback
2019-02-06 02:30:33 +11:00
pub fn get_available_monitors(&self) -> VecDeque<MonitorHandle> {
get_available_monitors(&self.outputs)
}
Event Loop 2.0 API and Windows implementation (#638) * Rename EventsLoop and associated types to EventLoop * Rename WindowEvent::Refresh to WindowEvent::Redraw * Remove second thread from win32 backend * Update run_forever to hijack thread * Replace windows Mutex with parking_lot Mutex * Implement new ControlFlow and associated events * Add StartCause::Init support, timer example * Add ability to send custom user events * Fully invert windows control flow so win32 calls into winit's callback * Add request_redraw * Rename platform to platform_impl * Rename os to platform, add Ext trait postfixes * Add platform::desktop module with EventLoopExt::run_return * Re-organize into module structure * Improve documentation * Small changes to examples * Improve docs for run and run_return * Change instances of "events_loop" to "event_loop" * Rename MonitorId to MonitorHandle * Add CHANGELOG entry * Improve WaitUntil timer precision * When SendEvent is called during event closure, buffer events * Fix resize lag when waiting in some situations * Update send test and errors that broke some examples/APIs * Improve clarity/fix typos in docs * Fix unreachable panic after setting ControlFlow to Poll during some RedrawRequested events. * Fix crash when running in release mode * Remove crossbeam dependency and make drop events work again * Remove serde implementations from ControlFlow * Fix 1.24.1 build * Fix freeze when setting decorations * Replace &EventLoop in callback with &EventLoopWindowTarget * Document and implement Debug for EventLoopWindowTarget * Fix some deadlocks that could occur when changing window state * Fix thread executor not executing closure when called from non-loop thread * Fix buffered events not getting dispatched * Fix crash with runner refcell not getting dropped * Address review feedback * Fix CHANGELOG typo * Catch panics in user callback
2019-02-06 02:30:33 +11:00
pub fn get_primary_monitor(&self) -> MonitorHandle {
get_primary_monitor(&self.outputs)
}
}
impl Drop for Window {
fn drop(&mut self) {
*(self.kill_switch.0.lock().unwrap()) = true;
*(self.kill_switch.1.lock().unwrap()) = true;
2016-10-08 23:51:29 +11:00
}
}
/*
* Internal store for windows
*/
struct InternalWindow {
surface: wl_surface::WlSurface,
2018-06-15 09:42:18 +10:00
newsize: Option<(u32, u32)>,
size: Arc<Mutex<(u32, u32)>>,
need_refresh: Arc<Mutex<bool>>,
need_frame_refresh: Arc<Mutex<bool>>,
closed: bool,
kill_switch: Arc<Mutex<bool>>,
frame: Weak<Mutex<SWindow<ConceptFrame>>>,
2018-06-15 09:42:18 +10:00
current_dpi: i32,
new_dpi: Option<i32>,
2016-10-08 23:51:29 +11:00
}
pub struct WindowStore {
windows: Vec<InternalWindow>,
}
2017-03-05 00:04:01 +11:00
impl WindowStore {
pub fn new() -> WindowStore {
WindowStore {
windows: Vec::new(),
}
2016-10-08 23:51:29 +11:00
}
pub fn find_wid(&self, surface: &wl_surface::WlSurface) -> Option<WindowId> {
for window in &self.windows {
if surface.as_ref().equals(&window.surface.as_ref()) {
return Some(make_wid(surface));
}
}
None
}
pub fn cleanup(&mut self) -> Vec<WindowId> {
let mut pruned = Vec::new();
self.windows.retain(|w| {
if *w.kill_switch.lock().unwrap() {
// window is dead, cleanup
pruned.push(make_wid(&w.surface));
w.surface.destroy();
false
} else {
true
}
});
pruned
}
2016-10-08 23:51:29 +11:00
pub fn new_seat(&self, seat: &wl_seat::WlSeat) {
for window in &self.windows {
if let Some(w) = window.frame.upgrade() {
w.lock().unwrap().new_seat(seat);
}
}
}
fn dpi_change(&mut self, surface: &wl_surface::WlSurface, new: i32) {
2018-06-15 09:42:18 +10:00
for window in &mut self.windows {
if surface.as_ref().equals(&window.surface.as_ref()) {
2018-06-15 09:42:18 +10:00
window.new_dpi = Some(new);
}
}
}
pub fn for_each<F>(&mut self, mut f: F)
where
F: FnMut(Option<(u32, u32)>, &mut (u32, u32), Option<i32>, bool, bool, bool, WindowId, Option<&mut SWindow<ConceptFrame>>),
2016-10-08 23:51:29 +11:00
{
for window in &mut self.windows {
let opt_arc = window.frame.upgrade();
let mut opt_mutex_lock = opt_arc.as_ref().map(|m| m.lock().unwrap());
f(
window.newsize.take(),
2018-06-15 09:42:18 +10:00
&mut *(window.size.lock().unwrap()),
window.new_dpi,
::std::mem::replace(&mut *window.need_refresh.lock().unwrap(), false),
::std::mem::replace(&mut *window.need_frame_refresh.lock().unwrap(), false),
window.closed,
make_wid(&window.surface),
opt_mutex_lock.as_mut().map(|m| &mut **m),
);
2018-06-15 09:42:18 +10:00
if let Some(dpi) = window.new_dpi.take() {
window.current_dpi = dpi;
}
// avoid re-spamming the event
window.closed = false;
}
2016-10-08 23:51:29 +11:00
}
}
Event Loop 2.0 API and Windows implementation (#638) * Rename EventsLoop and associated types to EventLoop * Rename WindowEvent::Refresh to WindowEvent::Redraw * Remove second thread from win32 backend * Update run_forever to hijack thread * Replace windows Mutex with parking_lot Mutex * Implement new ControlFlow and associated events * Add StartCause::Init support, timer example * Add ability to send custom user events * Fully invert windows control flow so win32 calls into winit's callback * Add request_redraw * Rename platform to platform_impl * Rename os to platform, add Ext trait postfixes * Add platform::desktop module with EventLoopExt::run_return * Re-organize into module structure * Improve documentation * Small changes to examples * Improve docs for run and run_return * Change instances of "events_loop" to "event_loop" * Rename MonitorId to MonitorHandle * Add CHANGELOG entry * Improve WaitUntil timer precision * When SendEvent is called during event closure, buffer events * Fix resize lag when waiting in some situations * Update send test and errors that broke some examples/APIs * Improve clarity/fix typos in docs * Fix unreachable panic after setting ControlFlow to Poll during some RedrawRequested events. * Fix crash when running in release mode * Remove crossbeam dependency and make drop events work again * Remove serde implementations from ControlFlow * Fix 1.24.1 build * Fix freeze when setting decorations * Replace &EventLoop in callback with &EventLoopWindowTarget * Document and implement Debug for EventLoopWindowTarget * Fix some deadlocks that could occur when changing window state * Fix thread executor not executing closure when called from non-loop thread * Fix buffered events not getting dispatched * Fix crash with runner refcell not getting dropped * Address review feedback * Fix CHANGELOG typo * Catch panics in user callback
2019-02-06 02:30:33 +11:00