From 78e5a395dac9604e851f781b6810247ead7928e3 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Mon, 28 Feb 2022 11:47:38 +0300 Subject: [PATCH] On Wayland, fix resize not propagating properly On Wayland window size and scaling are double buffered, so winit should send redraw requested for a client on the next frame as well. --- CHANGELOG.md | 1 + .../linux/wayland/event_loop/mod.rs | 30 ++++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54f5a13bc8..e08d1b51b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ And please only add new entries to the top of this list, right below the `# Unre - **Breaking:** Replaced `EventLoopExtMacOS` with `EventLoopBuilderExtMacOS` (which also has renamed methods). - **Breaking:** Replaced `EventLoopExtWindows` with `EventLoopBuilderExtWindows` (which also has renamed methods). - **Breaking:** Replaced `EventLoopExtUnix` with `EventLoopBuilderExtUnix` (which also has renamed methods). +- On Wayland, fix resize and scale factor changes not being propagated properly. # 0.26.1 (2022-01-05) diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index 7228fc5eea..9e97225fd2 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -24,7 +24,7 @@ use crate::platform_impl::EventLoopWindowTarget as PlatformEventLoopWindowTarget use super::env::{WindowingFeatures, WinitEnv}; use super::output::OutputManager; use super::seat::SeatManager; -use super::window::shim::{self, WindowUpdate}; +use super::window::shim::{self, WindowRequest, WindowUpdate}; use super::{DeviceId, WindowId}; mod proxy; @@ -249,7 +249,8 @@ impl EventLoop { } // Process 'new' pending updates. - self.with_state(|state| { + self.with_window_target(|window_target| { + let state = window_target.state.get_mut(); window_updates.clear(); window_updates.extend( state @@ -261,7 +262,8 @@ impl EventLoop { for (window_id, window_update) in window_updates.iter_mut() { if let Some(scale_factor) = window_update.scale_factor.map(|f| f as f64) { - let mut physical_size = self.with_state(|state| { + let mut physical_size = self.with_window_target(|window_target| { + let state = window_target.state.get_mut(); let window_handle = state.window_map.get(window_id).unwrap(); let mut size = window_handle.size.lock().unwrap(); @@ -294,7 +296,8 @@ impl EventLoop { } if let Some(size) = window_update.size.take() { - let physical_size = self.with_state(|state| { + let physical_size = self.with_window_target(|window_target| { + let state = window_target.state.get_mut(); let window_handle = state.window_map.get_mut(window_id).unwrap(); let mut window_size = window_handle.size.lock().unwrap(); @@ -320,6 +323,15 @@ impl EventLoop { // Mark that refresh isn't required, since we've done it right now. window_update.refresh_frame = false; + // Queue request for redraw into the next iteration of the loop, since + // resize and scale factor changes are double buffered. + window_handle + .pending_window_requests + .lock() + .unwrap() + .push(WindowRequest::Redraw); + window_target.event_loop_awakener.ping(); + physical_size }); @@ -356,7 +368,8 @@ impl EventLoop { // The purpose of the back buffer and that swap is to not hold borrow_mut when // we're doing callback to the user, since we can double borrow if the user decides // to create a window in one of those callbacks. - self.with_state(|state| { + self.with_window_target(|window_target| { + let state = window_target.state.get_mut(); std::mem::swap( &mut event_sink_back_buffer, &mut state.event_sink.window_events, @@ -381,7 +394,8 @@ impl EventLoop { for (window_id, window_update) in window_updates.iter() { // Handle refresh of the frame. if window_update.refresh_frame { - self.with_state(|state| { + self.with_window_target(|window_target| { + let state = window_target.state.get_mut(); let window_handle = state.window_map.get_mut(window_id).unwrap(); window_handle.window.refresh(); if !window_update.redraw_requested { @@ -526,9 +540,9 @@ impl EventLoop { &self.window_target } - fn with_state U>(&mut self, f: F) -> U { + fn with_window_target) -> U>(&mut self, f: F) -> U { let state = match &mut self.window_target.p { - PlatformEventLoopWindowTarget::Wayland(window_target) => window_target.state.get_mut(), + PlatformEventLoopWindowTarget::Wayland(window_target) => window_target, #[cfg(feature = "x11")] _ => unreachable!(), };