On Wayland, fix Window::request_redraw being delayed
On Waylnad when asking for redraw before `MainEventsCleared` would result for redraw being send on the next event loop tick, which is not expectable given that it must be delivered on the same event loop tick.
This commit is contained in:
parent
fa83bace12
commit
ec2888b8b7
5 changed files with 157 additions and 115 deletions
|
|
@ -30,7 +30,7 @@ use super::{EventLoopWindowTarget, WindowId};
|
|||
|
||||
pub mod shim;
|
||||
|
||||
use shim::{WindowHandle, WindowRequest, WindowUpdate};
|
||||
use shim::{WindowCompositorUpdate, WindowHandle, WindowRequest, WindowUserRequest};
|
||||
|
||||
#[cfg(feature = "sctk-adwaita")]
|
||||
pub type WinitFrame = sctk_adwaita::AdwaitaFrame;
|
||||
|
|
@ -94,11 +94,20 @@ impl Window {
|
|||
|
||||
// Get the window that received the event.
|
||||
let window_id = super::make_wid(&surface);
|
||||
let mut window_update = winit_state.window_updates.get_mut(&window_id).unwrap();
|
||||
let mut window_compositor_update = winit_state
|
||||
.window_compositor_updates
|
||||
.get_mut(&window_id)
|
||||
.unwrap();
|
||||
|
||||
// Mark that we need a frame refresh on the DPI change.
|
||||
winit_state
|
||||
.window_user_requests
|
||||
.get_mut(&window_id)
|
||||
.unwrap()
|
||||
.refresh_frame = true;
|
||||
|
||||
// Set pending scale factor.
|
||||
window_update.scale_factor = Some(scale);
|
||||
window_update.redraw_requested = true;
|
||||
window_compositor_update.scale_factor = Some(scale);
|
||||
|
||||
surface.set_buffer_scale(scale);
|
||||
})
|
||||
|
|
@ -128,11 +137,19 @@ impl Window {
|
|||
use sctk::window::{Event, State};
|
||||
|
||||
let winit_state = dispatch_data.get::<WinitState>().unwrap();
|
||||
let mut window_update = winit_state.window_updates.get_mut(&window_id).unwrap();
|
||||
let mut window_compositor_update = winit_state
|
||||
.window_compositor_updates
|
||||
.get_mut(&window_id)
|
||||
.unwrap();
|
||||
|
||||
let mut window_user_requests = winit_state
|
||||
.window_user_requests
|
||||
.get_mut(&window_id)
|
||||
.unwrap();
|
||||
|
||||
match event {
|
||||
Event::Refresh => {
|
||||
window_update.refresh_frame = true;
|
||||
window_user_requests.refresh_frame = true;
|
||||
}
|
||||
Event::Configure { new_size, states } => {
|
||||
let is_maximized = states.contains(&State::Maximized);
|
||||
|
|
@ -140,14 +157,13 @@ impl Window {
|
|||
let is_fullscreen = states.contains(&State::Fullscreen);
|
||||
fullscreen_clone.store(is_fullscreen, Ordering::Relaxed);
|
||||
|
||||
window_update.refresh_frame = true;
|
||||
window_update.redraw_requested = true;
|
||||
window_user_requests.refresh_frame = true;
|
||||
if let Some((w, h)) = new_size {
|
||||
window_update.size = Some(LogicalSize::new(w, h));
|
||||
window_compositor_update.size = Some(LogicalSize::new(w, h));
|
||||
}
|
||||
}
|
||||
Event::Close => {
|
||||
window_update.close_window = true;
|
||||
window_compositor_update.close_window = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -234,9 +250,9 @@ impl Window {
|
|||
let size = Arc::new(Mutex::new(LogicalSize::new(width, height)));
|
||||
|
||||
// We should trigger redraw and commit the surface for the newly created window.
|
||||
let mut window_update = WindowUpdate::new();
|
||||
window_update.refresh_frame = true;
|
||||
window_update.redraw_requested = true;
|
||||
let mut window_user_request = WindowUserRequest::new();
|
||||
window_user_request.refresh_frame = true;
|
||||
window_user_request.redraw_requested = true;
|
||||
|
||||
let window_id = super::make_wid(&surface);
|
||||
let window_requests = Arc::new(Mutex::new(Vec::with_capacity(64)));
|
||||
|
|
@ -262,9 +278,13 @@ impl Window {
|
|||
.event_sink
|
||||
.push_window_event(crate::event::WindowEvent::Focused(false), window_id);
|
||||
|
||||
// Add state for the window.
|
||||
winit_state
|
||||
.window_updates
|
||||
.insert(window_id, WindowUpdate::new());
|
||||
.window_user_requests
|
||||
.insert(window_id, window_user_request);
|
||||
winit_state
|
||||
.window_compositor_updates
|
||||
.insert(window_id, WindowCompositorUpdate::new());
|
||||
|
||||
let windowing_features = event_loop_window_target.windowing_features;
|
||||
|
||||
|
|
|
|||
|
|
@ -98,56 +98,38 @@ pub enum WindowRequest {
|
|||
Close,
|
||||
}
|
||||
|
||||
/// Pending update to a window from SCTK window.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct WindowUpdate {
|
||||
// The window update comming from the compositor.
|
||||
#[derive(Default, Debug, Clone, Copy)]
|
||||
pub struct WindowCompositorUpdate {
|
||||
/// New window size.
|
||||
pub size: Option<LogicalSize<u32>>,
|
||||
|
||||
/// New scale factor.
|
||||
pub scale_factor: Option<i32>,
|
||||
|
||||
/// Close the window.
|
||||
pub close_window: bool,
|
||||
}
|
||||
|
||||
impl WindowCompositorUpdate {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Pending update to a window requested by the user.
|
||||
#[derive(Default, Debug, Clone, Copy)]
|
||||
pub struct WindowUserRequest {
|
||||
/// Whether `redraw` was requested.
|
||||
pub redraw_requested: bool,
|
||||
|
||||
/// Wether the frame should be refreshed.
|
||||
pub refresh_frame: bool,
|
||||
|
||||
/// Close the window.
|
||||
pub close_window: bool,
|
||||
}
|
||||
|
||||
impl WindowUpdate {
|
||||
impl WindowUserRequest {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
size: None,
|
||||
scale_factor: None,
|
||||
redraw_requested: false,
|
||||
refresh_frame: false,
|
||||
close_window: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn take(&mut self) -> Self {
|
||||
let size = self.size.take();
|
||||
let scale_factor = self.scale_factor.take();
|
||||
|
||||
let redraw_requested = self.redraw_requested;
|
||||
self.redraw_requested = false;
|
||||
|
||||
let refresh_frame = self.refresh_frame;
|
||||
self.refresh_frame = false;
|
||||
|
||||
let close_window = self.close_window;
|
||||
self.close_window = false;
|
||||
|
||||
Self {
|
||||
size,
|
||||
scale_factor,
|
||||
redraw_requested,
|
||||
refresh_frame,
|
||||
close_window,
|
||||
}
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -422,7 +404,8 @@ impl WindowHandle {
|
|||
#[inline]
|
||||
pub fn handle_window_requests(winit_state: &mut WinitState) {
|
||||
let window_map = &mut winit_state.window_map;
|
||||
let window_updates = &mut winit_state.window_updates;
|
||||
let window_user_requests = &mut winit_state.window_user_requests;
|
||||
let window_compositor_updates = &mut winit_state.window_compositor_updates;
|
||||
let mut windows_to_close: Vec<WindowId> = Vec::new();
|
||||
|
||||
// Process the rest of the events.
|
||||
|
|
@ -478,15 +461,15 @@ pub fn handle_window_requests(winit_state: &mut WinitState) {
|
|||
window_handle.window.set_decorate(decorations);
|
||||
|
||||
// We should refresh the frame to apply decorations change.
|
||||
let window_update = window_updates.get_mut(window_id).unwrap();
|
||||
window_update.refresh_frame = true;
|
||||
let window_request = window_user_requests.get_mut(window_id).unwrap();
|
||||
window_request.refresh_frame = true;
|
||||
}
|
||||
#[cfg(feature = "sctk-adwaita")]
|
||||
WindowRequest::CsdThemeVariant(theme) => {
|
||||
window_handle.window.set_frame_config(theme.into());
|
||||
|
||||
let window_update = window_updates.get_mut(window_id).unwrap();
|
||||
window_update.refresh_frame = true;
|
||||
let window_requst = window_user_requests.get_mut(window_id).unwrap();
|
||||
window_requst.refresh_frame = true;
|
||||
}
|
||||
#[cfg(not(feature = "sctk-adwaita"))]
|
||||
WindowRequest::CsdThemeVariant(_) => {}
|
||||
|
|
@ -494,29 +477,29 @@ pub fn handle_window_requests(winit_state: &mut WinitState) {
|
|||
window_handle.window.set_resizable(resizeable);
|
||||
|
||||
// We should refresh the frame to update button state.
|
||||
let window_update = window_updates.get_mut(window_id).unwrap();
|
||||
window_update.refresh_frame = true;
|
||||
let window_request = window_user_requests.get_mut(window_id).unwrap();
|
||||
window_request.refresh_frame = true;
|
||||
}
|
||||
WindowRequest::Title(title) => {
|
||||
window_handle.window.set_title(title);
|
||||
|
||||
// We should refresh the frame to draw new title.
|
||||
let window_update = window_updates.get_mut(window_id).unwrap();
|
||||
window_update.refresh_frame = true;
|
||||
let window_request = window_user_requests.get_mut(window_id).unwrap();
|
||||
window_request.refresh_frame = true;
|
||||
}
|
||||
WindowRequest::MinSize(size) => {
|
||||
let size = size.map(|size| (size.width, size.height));
|
||||
window_handle.window.set_min_size(size);
|
||||
|
||||
let window_update = window_updates.get_mut(window_id).unwrap();
|
||||
window_update.redraw_requested = true;
|
||||
let window_request = window_user_requests.get_mut(window_id).unwrap();
|
||||
window_request.refresh_frame = true;
|
||||
}
|
||||
WindowRequest::MaxSize(size) => {
|
||||
let size = size.map(|size| (size.width, size.height));
|
||||
window_handle.window.set_max_size(size);
|
||||
|
||||
let window_update = window_updates.get_mut(window_id).unwrap();
|
||||
window_update.redraw_requested = true;
|
||||
let window_request = window_user_requests.get_mut(window_id).unwrap();
|
||||
window_request.refresh_frame = true;
|
||||
}
|
||||
WindowRequest::FrameSize(size) => {
|
||||
if !window_handle.is_resizable.get() {
|
||||
|
|
@ -530,21 +513,21 @@ pub fn handle_window_requests(winit_state: &mut WinitState) {
|
|||
window_handle.window.resize(size.width, size.height);
|
||||
|
||||
// We should refresh the frame after resize.
|
||||
let window_update = window_updates.get_mut(window_id).unwrap();
|
||||
window_update.refresh_frame = true;
|
||||
let window_request = window_user_requests.get_mut(window_id).unwrap();
|
||||
window_request.refresh_frame = true;
|
||||
}
|
||||
WindowRequest::PassthroughMouseInput(passthrough) => {
|
||||
window_handle.passthrough_mouse_input(passthrough);
|
||||
|
||||
let window_update = window_updates.get_mut(window_id).unwrap();
|
||||
window_update.refresh_frame = true;
|
||||
let window_request = window_user_requests.get_mut(window_id).unwrap();
|
||||
window_request.refresh_frame = true;
|
||||
}
|
||||
WindowRequest::Attention(request_type) => {
|
||||
window_handle.set_user_attention(request_type);
|
||||
}
|
||||
WindowRequest::Redraw => {
|
||||
let window_update = window_updates.get_mut(window_id).unwrap();
|
||||
window_update.redraw_requested = true;
|
||||
let window_request = window_user_requests.get_mut(window_id).unwrap();
|
||||
window_request.redraw_requested = true;
|
||||
}
|
||||
WindowRequest::Close => {
|
||||
// The window was requested to be closed.
|
||||
|
|
@ -561,7 +544,8 @@ pub fn handle_window_requests(winit_state: &mut WinitState) {
|
|||
// Close the windows.
|
||||
for window in windows_to_close {
|
||||
let _ = window_map.remove(&window);
|
||||
let _ = window_updates.remove(&window);
|
||||
let _ = window_user_requests.remove(&window);
|
||||
let _ = window_compositor_updates.remove(&window);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue