From cd1f049a3ec97d435119a980e37466a27400ebba Mon Sep 17 00:00:00 2001 From: kossLAN Date: Fri, 29 May 2026 19:43:08 -0400 Subject: [PATCH] state: split idle handling --- src/state.rs | 126 ++---------------------------------------- src/state/idle.rs | 138 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 120 deletions(-) create mode 100644 src/state/idle.rs diff --git a/src/state.rs b/src/state.rs index cd47bd99..e763c96b 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,9 +1,11 @@ mod animations; mod connectors; +mod idle; mod rendering; pub(crate) use animations::LayoutAnimationCandidate; pub use connectors::{ConnectorData, DrmDevData, OutputData}; +pub use idle::IdleState; use { crate::{ @@ -15,7 +17,7 @@ use { Backend, BackendConnectorStateSerials, BackendEvent, ConnectorId, ConnectorIds, DrmDeviceId, DrmDeviceIds, HardwareCursorUpdate, InputDevice, InputDeviceGroupIds, InputDeviceId, InputDeviceIds, TabletIds, TabletInit, TabletPadIds, TabletPadInit, - TabletToolIds, transaction::{BackendConnectorTransactionError, ConnectorTransaction}, + TabletToolIds, }, backends::dummy::DummyBackend, cli::RunArgs, @@ -43,7 +45,6 @@ use { icons::Icons, ifs::{ ext_foreign_toplevel_list_v1::ExtForeignToplevelListV1, - ext_idle_notification_v1::ExtIdleNotificationV1, ext_session_lock_v1::ExtSessionLockV1, head_management::{ HeadNames, jay_head_manager_session_v1::{HeadManagerEvent, JayHeadManagerSessionV1}, @@ -67,7 +68,7 @@ use { wl_subsurface::SubsurfaceIds, x_surface::xwindow::{Xwindow, XwindowId}, xdg_surface::XdgSurfaceConfigureEvent, - zwp_idle_inhibitor_v1::{IdleInhibitorId, IdleInhibitorIds, ZwpIdleInhibitorV1}, + zwp_idle_inhibitor_v1::IdleInhibitorIds, zwp_input_popup_surface_v2::ZwpInputPopupSurfaceV2, }, wlr_output_manager::WlrOutputManagerState, @@ -117,7 +118,7 @@ use { virtual_output::VirtualOutputs, wheel::Wheel, wire::{ - ExtForeignToplevelListV1Id, ExtIdleNotificationV1Id, JayHeadManagerSessionV1Id, + ExtForeignToplevelListV1Id, JayHeadManagerSessionV1Id, JayRenderCtxId, JaySeatEventsId, JayWorkspaceWatcherId, ZwlrForeignToplevelManagerV1Id, ZwpLinuxDmabufFeedbackV1Id, }, @@ -132,7 +133,7 @@ use { ops::{Deref, DerefMut}, rc::{Rc, Weak}, sync::Arc, - time::{Duration, SystemTime}, + time::SystemTime, }, uapi::{OwnedFd, c}, }; @@ -321,74 +322,6 @@ pub struct XWaylandState { pub display: CloneCell>>, } -pub struct IdleState { - pub input: Cell, - pub change: AsyncEvent, - pub timeout: Cell, - pub grace_period: Cell, - pub key_press_enables_dpms: Cell, - pub mouse_move_enables_dpms: Cell, - pub timeout_changed: Cell, - pub inhibitors: CopyHashMap>, - pub inhibitors_changed: Cell, - pub backend_idle: Cell, - pub dpms_off_by_command: Cell, - pub inhibited_idle_notifications: - CopyHashMap<(ClientId, ExtIdleNotificationV1Id), Rc>, - pub in_grace_period: Cell, -} - -impl IdleState { - pub fn set_timeout(&self, state: &State, timeout: Duration) { - self.timeout.set(timeout); - self.timeout_changed(state); - } - - pub fn set_grace_period(&self, state: &State, grace_period: Duration) { - self.grace_period.set(grace_period); - self.timeout_changed(state); - } - - fn timeout_changed(&self, _state: &State) { - self.timeout_changed.set(true); - self.change.trigger(); - } - - pub fn add_inhibitor(&self, state: &State, inhibitor: &Rc) { - self.inhibitors.set(inhibitor.inhibit_id, inhibitor.clone()); - self.inhibitors_changed(state); - } - - pub fn remove_inhibitor(&self, state: &State, inhibitor: &ZwpIdleInhibitorV1) { - self.inhibitors.remove(&inhibitor.inhibit_id); - self.inhibitors_changed(state); - if self.inhibitors.is_empty() { - self.resume_inhibited_notifications(); - } - } - - fn inhibitors_changed(&self, _state: &State) { - self.inhibitors_changed.set(true); - self.change.trigger(); - } - - 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)); - } -} - pub struct InputDeviceData { pub _handler: SpawnedFuture<()>, pub id: InputDeviceId, @@ -839,19 +772,6 @@ impl State { } } - pub fn input_occurred(self: &Rc, key_press: bool, mouse_move: bool) { - if self.idle.dpms_off_by_command.get() { - let enable_dpms = key_press && self.idle.key_press_enables_dpms.get() - || mouse_move && self.idle.mouse_move_enables_dpms.get(); - if enable_dpms && let Err(e) = self.set_dpms_active(true) { - log::error!("Could not enable DPMS after input: {}", ErrorFmt(e)); - } - } - if !self.idle.input.replace(true) { - self.idle.change.trigger(); - } - } - pub fn start_xwayland(self: &Rc) { if !self.xwayland.enabled.get() { return; @@ -1098,40 +1018,6 @@ impl State { seat } - pub fn set_backend_idle(&self, idle: bool) { - if self.idle.backend_idle.replace(idle) != idle { - self.root.update_visible(self); - } - } - - pub fn set_connectors_active( - self: &Rc, - active: bool, - ) -> Result<(), BackendConnectorTransactionError> { - let mut tran = ConnectorTransaction::new(self); - for connector in self.connectors.lock().values() { - let mut state = connector.state.borrow().clone(); - state.active = active; - tran.add(&connector.connector, state)?; - } - tran.prepare()?.apply()?.commit(); - self.set_backend_idle(!active); - Ok(()) - } - - pub fn set_dpms_active( - self: &Rc, - active: bool, - ) -> Result<(), BackendConnectorTransactionError> { - self.set_connectors_active(active)?; - self.idle.dpms_off_by_command.set(!active); - Ok(()) - } - - pub fn root_visible(&self) -> bool { - !self.idle.backend_idle.get() - } - pub fn find_closest_output(&self, mut x: i32, mut y: i32) -> (Rc, i32, i32) { let mut optimal_dist = i128::MAX; let mut optimal_output = None; diff --git a/src/state/idle.rs b/src/state/idle.rs new file mode 100644 index 00000000..2637326e --- /dev/null +++ b/src/state/idle.rs @@ -0,0 +1,138 @@ +use { + crate::{ + backend::transaction::{BackendConnectorTransactionError, ConnectorTransaction}, + client::ClientId, + ifs::{ + ext_idle_notification_v1::ExtIdleNotificationV1, + wl_surface::zwp_idle_inhibitor_v1::{ + IdleInhibitorId, ZwpIdleInhibitorV1, + }, + }, + utils::{ + asyncevent::AsyncEvent, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, + hash_map_ext::HashMapExt, + }, + wire::ExtIdleNotificationV1Id, + }, + std::{cell::Cell, rc::Rc, time::Duration}, +}; + +use super::State; + +pub struct IdleState { + pub input: Cell, + pub change: AsyncEvent, + pub timeout: Cell, + pub grace_period: Cell, + pub key_press_enables_dpms: Cell, + pub mouse_move_enables_dpms: Cell, + pub timeout_changed: Cell, + pub inhibitors: CopyHashMap>, + pub inhibitors_changed: Cell, + pub backend_idle: Cell, + pub dpms_off_by_command: Cell, + pub inhibited_idle_notifications: + CopyHashMap<(ClientId, ExtIdleNotificationV1Id), Rc>, + pub in_grace_period: Cell, +} + +impl IdleState { + pub fn set_timeout(&self, state: &State, timeout: Duration) { + self.timeout.set(timeout); + self.timeout_changed(state); + } + + pub fn set_grace_period(&self, state: &State, grace_period: Duration) { + self.grace_period.set(grace_period); + self.timeout_changed(state); + } + + fn timeout_changed(&self, _state: &State) { + self.timeout_changed.set(true); + self.change.trigger(); + } + + pub fn add_inhibitor(&self, state: &State, inhibitor: &Rc) { + self.inhibitors.set(inhibitor.inhibit_id, inhibitor.clone()); + self.inhibitors_changed(state); + } + + pub fn remove_inhibitor(&self, state: &State, inhibitor: &ZwpIdleInhibitorV1) { + self.inhibitors.remove(&inhibitor.inhibit_id); + self.inhibitors_changed(state); + if self.inhibitors.is_empty() { + self.resume_inhibited_notifications(); + } + } + + fn inhibitors_changed(&self, _state: &State) { + self.inhibitors_changed.set(true); + self.change.trigger(); + } + + 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)); + } +} + +impl State { + pub fn input_occurred(self: &Rc, key_press: bool, mouse_move: bool) { + if self.idle.dpms_off_by_command.get() { + let enable_dpms = key_press && self.idle.key_press_enables_dpms.get() + || mouse_move && self.idle.mouse_move_enables_dpms.get(); + if enable_dpms && let Err(e) = self.set_dpms_active(true) { + log::error!("Could not enable DPMS after input: {}", ErrorFmt(e)); + } + } + if !self.idle.input.replace(true) { + self.idle.change.trigger(); + } + } + + pub fn set_backend_idle(&self, idle: bool) { + if self.idle.backend_idle.replace(idle) != idle { + self.root.update_visible(self); + } + } + + pub fn set_connectors_active( + self: &Rc, + active: bool, + ) -> Result<(), BackendConnectorTransactionError> { + let mut tran = ConnectorTransaction::new(self); + for connector in self.connectors.lock().values() { + let mut state = connector.state.borrow().clone(); + state.active = active; + tran.add(&connector.connector, state)?; + } + tran.prepare()?.apply()?.commit(); + self.set_backend_idle(!active); + Ok(()) + } + + pub fn set_dpms_active( + self: &Rc, + active: bool, + ) -> Result<(), BackendConnectorTransactionError> { + self.set_connectors_active(active)?; + self.idle.dpms_off_by_command.set(!active); + Ok(()) + } + + pub fn root_visible(&self) -> bool { + !self.idle.backend_idle.get() + } + +}