fix(sctk): reduce event spam for redraw requests

This commit is contained in:
Ashley Wulber 2024-10-21 23:49:59 -04:00
parent 175a71590a
commit 90c0aefa25
No known key found for this signature in database
GPG key ID: 5216D4F46A90A820
7 changed files with 53 additions and 79 deletions

View file

@ -949,7 +949,7 @@ async fn run_instance<P>(
); );
actions += 1; actions += 1;
} }
Event::Winit(window_id, event) => { Event::Winit(window_id, event::WindowEvent::RedrawRequested) => {
let Some(mut current_compositor) = compositor.as_mut() else { let Some(mut current_compositor) = compositor.as_mut() else {
continue; continue;
}; };
@ -959,6 +959,8 @@ async fn run_instance<P>(
else { else {
continue; continue;
}; };
// TODO only redraw when requested by event...
window.redraw_requested = false;
let physical_size = window.state.physical_size(); let physical_size = window.state.physical_size();
let mut logical_size = window.state.logical_size(); let mut logical_size = window.state.logical_size();
@ -1203,7 +1205,8 @@ async fn run_instance<P>(
} }
}, },
} }
}
Event::Winit(window_id, event) => {
if !is_daemon if !is_daemon
&& matches!(event, winit::event::WindowEvent::Destroyed) && matches!(event, winit::event::WindowEvent::Destroyed)
&& !is_window_opening && !is_window_opening

View file

@ -72,13 +72,6 @@ impl PlatformSpecific {
} }
} }
pub(crate) fn send_ready(&mut self) {
#[cfg(all(feature = "wayland", target_os = "linux"))]
{
self.send_wayland(wayland::Action::Ready);
}
}
pub(crate) fn update_subsurfaces( pub(crate) fn update_subsurfaces(
&mut self, &mut self,
id: window::Id, id: window::Id,

View file

@ -101,50 +101,51 @@ impl SctkEventLoop {
_ = loop_handle _ = loop_handle
.insert_source(action_rx, |event, _, state| { .insert_source(action_rx, |event, _, state| {
match event { match event {
calloop::channel::Event::Msg(e) => match e { calloop::channel::Event::Msg(e) => match e {
crate::platform_specific::Action::Action(a) => { crate::platform_specific::Action::Action(a) => {
if let Err(err) = state.handle_action(a) { if let Err(err) = state.handle_action(a) {
log::warn!("{err:?}"); log::warn!("{err:?}");
}
} }
} crate::platform_specific::Action::TrackWindow(
crate::platform_specific::Action::TrackWindow( window,
window, id,
id, ) => {
) => { state.windows.push(SctkWindow { window, id });
state.windows.push(SctkWindow { window, id });
}
crate::platform_specific::Action::RemoveWindow(id) => {
// TODO clean up popups matching the window.
state.windows.retain(|window| id != window.id);
}
crate::platform_specific::Action::SetCursor(icon) => {
if let Some(seat) = state.seats.get_mut(0) {
seat.icon = Some(icon);
seat.set_cursor(&state.connection, icon);
} }
} crate::platform_specific::Action::RemoveWindow(
crate::platform_specific::Action::RequestRedraw(id) => { id,
let e = state.frame_status.entry(id).or_insert(FrameStatus::RequestedRedraw); ) => {
if matches!(e, FrameStatus::Received) { // TODO clean up popups matching the window.
*e = FrameStatus::Ready; state.windows.retain(|window| id != window.id);
} }
crate::platform_specific::Action::SetCursor(
icon,
) => {
if let Some(seat) = state.seats.get_mut(0) {
seat.icon = Some(icon);
seat.set_cursor(&state.connection, icon);
}
}
crate::platform_specific::Action::RequestRedraw(
id,
) => {
let e = state
.frame_status
.entry(id)
.or_insert(FrameStatus::RequestedRedraw);
if matches!(e, FrameStatus::Received) {
*e = FrameStatus::Ready;
}
}
crate::platform_specific::Action::Dropped(id) => {
_ = state.destroyed.remove(&id.inner());
}
},
calloop::channel::Event::Closed => {
log::info!("Calloop channel closed.");
} }
crate::platform_specific::Action::PrePresentNotify(
_,
) => {
// TODO
}
crate::platform_specific::Action::Ready => {
state.ready = true;
}
crate::platform_specific::Action::Dropped(id) => {
_ = state.destroyed.remove(&id.inner());
}
},
calloop::channel::Event::Closed => {
log::info!("Calloop channel closed.");
} }
}
}) })
.unwrap(); .unwrap();
let wayland_source = let wayland_source =
@ -225,7 +226,6 @@ impl SctkEventLoop {
proxy, proxy,
id_map: Default::default(), id_map: Default::default(),
to_commit: HashMap::new(), to_commit: HashMap::new(),
ready: true,
destroyed: HashSet::new(), destroyed: HashSet::new(),
pending_popup: Default::default(), pending_popup: Default::default(),
activation_token_ctr: 0, activation_token_ctr: 0,
@ -303,9 +303,6 @@ impl SctkEventLoop {
} }
} }
} }
if !state.state.ready {
continue;
}
if let Err(err) = if let Err(err) =
state.event_loop.dispatch(None, &mut state.state) state.event_loop.dispatch(None, &mut state.state)
@ -370,7 +367,6 @@ impl SctkEventLoop {
); );
} }
} }
if wake_up { if wake_up {
state.state.proxy.wake_up(); state.state.proxy.wake_up();
} }

View file

@ -377,7 +377,6 @@ pub struct SctkState {
pub(crate) id_map: HashMap<ObjectId, core::window::Id>, pub(crate) id_map: HashMap<ObjectId, core::window::Id>,
pub(crate) to_commit: HashMap<core::window::Id, WlSurface>, pub(crate) to_commit: HashMap<core::window::Id, WlSurface>,
pub(crate) destroyed: HashSet<core::window::Id>, pub(crate) destroyed: HashSet<core::window::Id>,
pub(crate) ready: bool,
pub(crate) pending_popup: Option<(SctkPopupSettings, usize)>, pub(crate) pending_popup: Option<(SctkPopupSettings, usize)>,
pub(crate) activation_token_ctr: u32, pub(crate) activation_token_ctr: u32,

View file

@ -28,11 +28,9 @@ pub(crate) enum Action {
Action(iced_runtime::platform_specific::wayland::Action), Action(iced_runtime::platform_specific::wayland::Action),
SetCursor(CursorIcon), SetCursor(CursorIcon),
RequestRedraw(ObjectId), RequestRedraw(ObjectId),
PrePresentNotify(ObjectId),
TrackWindow(Arc<dyn winit::window::Window>, window::Id), TrackWindow(Arc<dyn winit::window::Window>, window::Id),
RemoveWindow(window::Id), RemoveWindow(window::Id),
Dropped(SurfaceIdWrapper), Dropped(SurfaceIdWrapper),
Ready,
} }
impl std::fmt::Debug for Action { impl std::fmt::Debug for Action {
@ -45,16 +43,12 @@ impl std::fmt::Debug for Action {
Self::RequestRedraw(arg0) => { Self::RequestRedraw(arg0) => {
f.debug_tuple("RequestRedraw").field(arg0).finish() f.debug_tuple("RequestRedraw").field(arg0).finish()
} }
Self::PrePresentNotify(arg0) => {
f.debug_tuple("PrePresentNotify").field(arg0).finish()
}
Self::TrackWindow(_arg0, arg1) => { Self::TrackWindow(_arg0, arg1) => {
f.debug_tuple("TrackWindow").field(arg1).finish() f.debug_tuple("TrackWindow").field(arg1).finish()
} }
Self::RemoveWindow(arg0) => { Self::RemoveWindow(arg0) => {
f.debug_tuple("RemoveWindow").field(arg0).finish() f.debug_tuple("RemoveWindow").field(arg0).finish()
} }
Self::Ready => write!(f, "Ready"),
Self::Dropped(_surface_id_wrapper) => write!(f, "Dropped"), Self::Dropped(_surface_id_wrapper) => write!(f, "Dropped"),
} }
} }

View file

@ -16,19 +16,7 @@ use winit::{
use crate::platform_specific::SurfaceIdWrapper; use crate::platform_specific::SurfaceIdWrapper;
use super::event_loop::state::{ use super::event_loop::state::{Common, CommonSurface, SctkState, TOKEN_CTR};
Common, CommonSurface, SctkLayerSurface, SctkLockSurface, SctkPopup,
SctkState, TOKEN_CTR,
};
#[derive(Debug)]
pub(crate) enum Surface {
Popup(SctkPopup),
Layer(SctkLayerSurface),
Lock(SctkLockSurface),
}
impl Surface {}
#[derive(Debug)] #[derive(Debug)]
pub struct SctkWinitWindow { pub struct SctkWinitWindow {
@ -38,7 +26,6 @@ pub struct SctkWinitWindow {
common: Arc<Mutex<Common>>, common: Arc<Mutex<Common>>,
display: WlDisplay, display: WlDisplay,
pub(crate) queue_handle: QueueHandle<SctkState>, pub(crate) queue_handle: QueueHandle<SctkState>,
wait_redraw: bool,
} }
impl Drop for SctkWinitWindow { impl Drop for SctkWinitWindow {
@ -63,7 +50,6 @@ impl SctkWinitWindow {
surface, surface,
display, display,
queue_handle, queue_handle,
wait_redraw: false,
}) })
} }
} }
@ -88,9 +74,6 @@ impl winit::window::Window for SctkWinitWindow {
fn pre_present_notify(&self) { fn pre_present_notify(&self) {
let surface = self.surface.wl_surface(); let surface = self.surface.wl_surface();
_ = surface.frame(&self.queue_handle, surface.clone()); _ = surface.frame(&self.queue_handle, surface.clone());
_ = self
.tx
.send(Action::PrePresentNotify(self.surface.wl_surface().id()));
} }
fn set_cursor(&self, cursor: winit_core::cursor::Cursor) { fn set_cursor(&self, cursor: winit_core::cursor::Cursor) {

View file

@ -86,6 +86,7 @@ where
drag_resize_window_func: None, drag_resize_window_func: None,
prev_dnd_destination_rectangles_count: 0, prev_dnd_destination_rectangles_count: 0,
viewport_version: 0, viewport_version: 0,
redraw_requested: false,
}, },
); );
@ -191,6 +192,7 @@ where
pub redraw_at: Option<Instant>, pub redraw_at: Option<Instant>,
preedit: Option<Preedit<P::Renderer>>, preedit: Option<Preedit<P::Renderer>>,
ime_state: Option<(Rectangle, input_method::Purpose)>, ime_state: Option<(Rectangle, input_method::Purpose)>,
pub(crate) redraw_requested: bool,
} }
impl<P, C> Window<P, C> impl<P, C> Window<P, C>
@ -219,11 +221,15 @@ where
pub fn request_redraw(&mut self, redraw_request: RedrawRequest) { pub fn request_redraw(&mut self, redraw_request: RedrawRequest) {
match redraw_request { match redraw_request {
RedrawRequest::NextFrame => { RedrawRequest::NextFrame => {
self.raw.request_redraw(); if !self.redraw_requested {
self.redraw_requested = true;
self.raw.request_redraw();
}
self.redraw_at = None; self.redraw_at = None;
} }
RedrawRequest::At(at) => { RedrawRequest::At(at) => {
self.redraw_at = Some(at); self.redraw_at = Some(at);
self.redraw_requested = false;
} }
RedrawRequest::Wait => {} RedrawRequest::Wait => {}
} }