On Wayland, disable Occluded handling

Change in state requires a redraw, however drawing when getting
`Occluded` with vsync will block indefinitely, thus the event in
it's current state is rather useless.

To solve this issue winit needs a way to determine whether the user
paused/continued their render loop, so it can commit on their behalf.

This commit also forces redraw when getting configure.

Links: https://github.com/rust-windowing/winit/issues/3442
This commit is contained in:
Kirill Chibisov
2024-01-30 13:00:10 +04:00
parent 221b2e71cd
commit 57cb3126d6
4 changed files with 16 additions and 24 deletions

View File

@@ -14,6 +14,7 @@ Unreleased` header.
- On macOS, fix incorrect IME cursor rect origin. - On macOS, fix incorrect IME cursor rect origin.
- On X11, fix swapped instance and general class names. - On X11, fix swapped instance and general class names.
- On Windows, fixed a race condition when sending an event through the loop proxy. - On Windows, fixed a race condition when sending an event through the loop proxy.
- On Wayland, disable `Occluded` event handling.
# 0.29.10 # 0.29.10

View File

@@ -574,7 +574,7 @@ pub enum WindowEvent {
/// ### Others /// ### Others
/// ///
/// - **Web:** Doesn't take into account CSS [`border`], [`padding`], or [`transform`]. /// - **Web:** Doesn't take into account CSS [`border`], [`padding`], or [`transform`].
/// - **Android / Windows / Orbital:** Unsupported. /// - **Android / Wayland / Windows / Orbital:** Unsupported.
/// ///
/// [`border`]: https://developer.mozilla.org/en-US/docs/Web/CSS/border /// [`border`]: https://developer.mozilla.org/en-US/docs/Web/CSS/border
/// [`padding`]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding /// [`padding`]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding

View File

@@ -288,12 +288,19 @@ impl WindowHandler for WinitState {
.expect("got configure for dead window.") .expect("got configure for dead window.")
.lock() .lock()
.unwrap() .unwrap()
.configure( .configure(configure, &self.shm, &self.subcompositor_state);
configure,
&self.shm, // NOTE: configure demands wl_surface::commit, however winit doesn't commit on behalf of the
&self.subcompositor_state, // users, since it can break a lot of things, thus it'll ask users to redraw instead.
&mut self.events_sink, self.window_requests
); .get_mut()
.get(&window_id)
.unwrap()
.redraw_requested
.store(true, Ordering::Relaxed);
// Manually mark that we've got an event, since configure may not generate a resize.
self.dispatched_events = true;
} }
} }

View File

@@ -29,10 +29,8 @@ use wayland_protocols_plasma::blur::client::org_kde_kwin_blur::OrgKdeKwinBlur;
use crate::dpi::{LogicalPosition, LogicalSize, PhysicalSize, Size}; use crate::dpi::{LogicalPosition, LogicalSize, PhysicalSize, Size};
use crate::error::{ExternalError, NotSupportedError}; use crate::error::{ExternalError, NotSupportedError};
use crate::event::WindowEvent; use crate::platform_impl::wayland::logical_to_physical_rounded;
use crate::platform_impl::wayland::event_loop::sink::EventSink;
use crate::platform_impl::wayland::types::kwin_blur::KWinBlurManager; use crate::platform_impl::wayland::types::kwin_blur::KWinBlurManager;
use crate::platform_impl::wayland::{logical_to_physical_rounded, make_wid};
use crate::platform_impl::WindowId; use crate::platform_impl::WindowId;
use crate::window::{CursorGrabMode, CursorIcon, ImePurpose, ResizeDirection, Theme}; use crate::window::{CursorGrabMode, CursorIcon, ImePurpose, ResizeDirection, Theme};
@@ -255,7 +253,6 @@ impl WindowState {
configure: WindowConfigure, configure: WindowConfigure,
shm: &Shm, shm: &Shm,
subcompositor: &Option<Arc<SubcompositorState>>, subcompositor: &Option<Arc<SubcompositorState>>,
event_sink: &mut EventSink,
) -> bool { ) -> bool {
// NOTE: when using fractional scaling or wl_compositor@v6 the scaling // NOTE: when using fractional scaling or wl_compositor@v6 the scaling
// should be delivered before the first configure, thus apply it to // should be delivered before the first configure, thus apply it to
@@ -299,19 +296,6 @@ impl WindowState {
let stateless = Self::is_stateless(&configure); let stateless = Self::is_stateless(&configure);
// Emit `Occluded` event on suspension change.
let occluded = configure.state.contains(XdgWindowState::SUSPENDED);
if self
.last_configure
.as_ref()
.map(|c| c.state.contains(XdgWindowState::SUSPENDED))
.unwrap_or(false)
!= occluded
{
let window_id = make_wid(self.window.wl_surface());
event_sink.push_window_event(WindowEvent::Occluded(occluded), window_id);
}
let (mut new_size, constrain) = if let Some(frame) = self.frame.as_mut() { let (mut new_size, constrain) = if let Some(frame) = self.frame.as_mut() {
// Configure the window states. // Configure the window states.
frame.update_state(configure.state); frame.update_state(configure.state);