From 6140b77741a8d8a180d4dd01cc65b2c83ec25b91 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Thu, 23 Jan 2025 16:42:32 +0100 Subject: [PATCH] idle_notifier: respect idle inhibitors for v1 --- src/compositor.rs | 1 + src/ifs/ext_idle_notification_v1.rs | 1 + src/ifs/ext_idle_notifier_v1.rs | 30 ++++++++++++++++++----------- src/state.rs | 26 +++++++++++++++++++++++-- 4 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index a77d6170..738d370f 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -203,6 +203,7 @@ fn start_compositor2( timeout_changed: Default::default(), inhibitors: Default::default(), inhibitors_changed: Default::default(), + inhibited_idle_notifications: Default::default(), backend_idle: Cell::new(true), }, run_args, diff --git a/src/ifs/ext_idle_notification_v1.rs b/src/ifs/ext_idle_notification_v1.rs index 935ddfbb..4ecd7b08 100644 --- a/src/ifs/ext_idle_notification_v1.rs +++ b/src/ifs/ext_idle_notification_v1.rs @@ -26,6 +26,7 @@ pub struct ExtIdleNotificationV1 { impl ExtIdleNotificationV1 { fn detach(&self) { self.seat.remove_idle_notification(self); + self.client.state.idle.remove_inhibited_notification(self); self.task.take(); } } diff --git a/src/ifs/ext_idle_notifier_v1.rs b/src/ifs/ext_idle_notifier_v1.rs index 4135834f..6df798f9 100644 --- a/src/ifs/ext_idle_notifier_v1.rs +++ b/src/ifs/ext_idle_notifier_v1.rs @@ -52,6 +52,7 @@ impl ExtIdleNotifierV1 { id: ExtIdleNotificationV1Id, timeout: u32, seat: WlSeatId, + skip_if_inhibited: bool, ) -> Result<(), ExtIdleNotifierV1Error> { let seat = self.client.lookup(seat)?; let notification = Rc::new(ExtIdleNotificationV1 { @@ -66,11 +67,10 @@ impl ExtIdleNotifierV1 { }); track!(self.client, notification); self.client.add_client_obj(¬ification)?; - let future = self - .client - .state - .eng - .spawn("idle notifier", run(notification.clone())); + let future = self.client.state.eng.spawn( + "idle notifier", + run(notification.clone(), skip_if_inhibited), + ); notification.task.set(Some(future)); Ok(()) } @@ -89,7 +89,7 @@ impl ExtIdleNotifierV1RequestHandler for ExtIdleNotifierV1 { req: GetIdleNotification, _slf: &Rc, ) -> Result<(), Self::Error> { - self.create_notification(req.id, req.timeout, req.seat) + self.create_notification(req.id, req.timeout, req.seat, true) } fn get_input_idle_notification( @@ -97,11 +97,11 @@ impl ExtIdleNotifierV1RequestHandler for ExtIdleNotifierV1 { req: GetInputIdleNotification, _slf: &Rc, ) -> Result<(), Self::Error> { - self.create_notification(req.id, req.timeout, req.seat) + self.create_notification(req.id, req.timeout, req.seat, false) } } -async fn run(n: Rc) { +async fn run(n: Rc, skip_if_inhibited: bool) { loop { let now = n.client.state.now_usec(); let elapsed = now.saturating_sub(n.seat.last_input()); @@ -117,10 +117,18 @@ async fn run(n: Rc) { return; } } else { - n.send_idled(); - n.seat.add_idle_notification(&n); + let idle = &n.client.state.idle; + let send_idle = !skip_if_inhibited || idle.inhibitors.is_empty(); + if send_idle { + n.send_idled(); + n.seat.add_idle_notification(&n); + } else { + idle.add_inhibited_notification(&n); + } n.resume.triggered().await; - n.send_resumed(); + if send_idle { + n.send_resumed(); + } } } } diff --git a/src/state.rs b/src/state.rs index 6a958b72..242243e3 100644 --- a/src/state.rs +++ b/src/state.rs @@ -34,6 +34,7 @@ use { globals::{Globals, GlobalsError, RemovableWaylandGlobal, WaylandGlobal}, ifs::{ ext_foreign_toplevel_list_v1::ExtForeignToplevelListV1, + ext_idle_notification_v1::ExtIdleNotificationV1, ext_session_lock_v1::ExtSessionLockV1, ipc::{ data_control::DataControlDeviceIds, x_data_device::XIpcDeviceIds, DataOfferIds, @@ -94,8 +95,8 @@ use { }, wheel::Wheel, wire::{ - ExtForeignToplevelListV1Id, JayRenderCtxId, JaySeatEventsId, JayWorkspaceWatcherId, - ZwpLinuxDmabufFeedbackV1Id, + ExtForeignToplevelListV1Id, ExtIdleNotificationV1Id, JayRenderCtxId, JaySeatEventsId, + JayWorkspaceWatcherId, ZwpLinuxDmabufFeedbackV1Id, }, xkbcommon::{KeyboardStateIds, XkbContext, XkbKeymap, XkbState}, xwayland::{self, XWaylandEvent}, @@ -264,6 +265,8 @@ pub struct IdleState { pub inhibitors: CopyHashMap>, pub inhibitors_changed: Cell, pub backend_idle: Cell, + pub inhibited_idle_notifications: + CopyHashMap<(ClientId, ExtIdleNotificationV1Id), Rc>, } impl IdleState { @@ -283,6 +286,25 @@ impl IdleState { self.inhibitors.remove(&inhibitor.inhibit_id); self.inhibitors_changed.set(true); self.change.trigger(); + if self.inhibitors.is_empty() { + self.resume_inhibited_notifications(); + } + } + + fn resume_inhibited_notifications(&self) { + for notification in self.inhibited_idle_notifications.lock().drain_values() { + notification.resume.trigger(); + } + } + + pub fn add_inhibited_notification(&self, n: &Rc) { + self.inhibited_idle_notifications + .set((n.client.id, n.id), n.clone()); + } + + pub fn remove_inhibited_notification(&self, n: &ExtIdleNotificationV1) { + self.inhibited_idle_notifications + .remove(&(n.client.id, n.id)); } }