diff --git a/compositor/src/handlers/compositor.rs b/compositor/src/handlers/compositor.rs index 0ca21b4..4aa38bb 100644 --- a/compositor/src/handlers/compositor.rs +++ b/compositor/src/handlers/compositor.rs @@ -56,6 +56,18 @@ impl CompositorHandler for Ferese { xdg_shell::handle_commit(&mut self.popups, &mut self.space, surface); crate::backends::direct::render_all(self); } + + fn destroyed(&mut self, surface: &WlSurface) { + if self.idle_inhibitors.remove(surface).is_some() { + self.idle_notifier_state + .set_is_inhibited(!self.idle_inhibitors.is_empty()); + } + if matches!(&self.cursor_status, smithay::input::pointer::CursorImageStatus::Surface(cursor) if cursor == surface) + { + self.cursor_status = smithay::input::pointer::CursorImageStatus::default_named(); + crate::backends::direct::render_all(self); + } + } } impl BufferHandler for Ferese { diff --git a/compositor/src/handlers/mod.rs b/compositor/src/handlers/mod.rs index c92c366..2732a3c 100644 --- a/compositor/src/handlers/mod.rs +++ b/compositor/src/handlers/mod.rs @@ -13,6 +13,8 @@ use smithay::{ wayland::{ compositor::{TraversalAction, with_states, with_surface_tree_downward}, fractional_scale::{FractionalScaleHandler, with_fractional_scale}, + idle_inhibit::IdleInhibitHandler, + idle_notify::{IdleNotifierHandler, IdleNotifierState}, output::OutputHandler, pointer_constraints::{ PointerConstraint, PointerConstraintsHandler, with_pointer_constraint, @@ -73,6 +75,31 @@ impl FractionalScaleHandler for Ferese { } } +impl IdleNotifierHandler for Ferese { + fn idle_notifier_state(&mut self) -> &mut IdleNotifierState { + &mut self.idle_notifier_state + } +} + +impl IdleInhibitHandler for Ferese { + fn inhibit(&mut self, surface: WlSurface) { + let count = self.idle_inhibitors.entry(surface).or_default(); + *count = count.saturating_add(1); + self.idle_notifier_state.set_is_inhibited(true); + } + + fn uninhibit(&mut self, surface: WlSurface) { + if let Some(count) = self.idle_inhibitors.get_mut(&surface) { + *count = count.saturating_sub(1); + if *count == 0 { + self.idle_inhibitors.remove(&surface); + } + } + self.idle_notifier_state + .set_is_inhibited(!self.idle_inhibitors.is_empty()); + } +} + impl Ferese { pub fn update_fractional_scale(&self, scale: f64) { for window in self.space.elements() { @@ -160,6 +187,8 @@ impl XdgForeignHandler for Ferese { smithay::delegate_compositor!(Ferese); smithay::delegate_data_device!(Ferese); smithay::delegate_fractional_scale!(Ferese); +smithay::delegate_idle_inhibit!(Ferese); +smithay::delegate_idle_notify!(Ferese); smithay::delegate_layer_shell!(Ferese); smithay::delegate_output!(Ferese); smithay::delegate_pointer_constraints!(Ferese); diff --git a/compositor/src/input.rs b/compositor/src/input.rs index 09c2505..288253c 100644 --- a/compositor/src/input.rs +++ b/compositor/src/input.rs @@ -17,6 +17,9 @@ use ferese_layout::Direction; impl Ferese { pub fn process_input_event(&mut self, event: InputEvent) { + let seat = self.seat.clone(); + self.idle_notifier_state.notify_activity(&seat); + match event { InputEvent::Keyboard { event, .. } => { let keyboard = self.seat.get_keyboard().expect("seat has a keyboard"); diff --git a/compositor/src/state.rs b/compositor/src/state.rs index 46ed2bc..43c0cb3 100644 --- a/compositor/src/state.rs +++ b/compositor/src/state.rs @@ -31,6 +31,8 @@ use smithay::{ wayland::{ compositor::{CompositorClientState, CompositorState, with_states}, fractional_scale::FractionalScaleManagerState, + idle_inhibit::IdleInhibitManagerState, + idle_notify::IdleNotifierState, output::OutputManagerState, pointer_constraints::PointerConstraintsState, presentation::PresentationState, @@ -61,6 +63,7 @@ pub struct Ferese { pub focused_window: Option, pub cursor_status: CursorImageStatus, pub intercepted_keys: HashSet, + pub idle_inhibitors: HashMap, pub direct_backend: Option, next_window_id: u64, last_animation_tick: Instant, @@ -70,6 +73,8 @@ pub struct Ferese { pub data_device_state: DataDeviceState, pub decoration_state: XdgDecorationState, pub fractional_scale_state: FractionalScaleManagerState, + pub idle_inhibit_state: IdleInhibitManagerState, + pub idle_notifier_state: IdleNotifierState, pub output_manager_state: OutputManagerState, pub pointer_constraints_state: PointerConstraintsState, pub presentation_state: PresentationState, @@ -87,7 +92,7 @@ pub struct Ferese { impl Ferese { pub fn new( - event_loop: &mut EventLoop, + event_loop: &mut EventLoop<'static, Self>, display: Display, ) -> Result> { let display_handle = display.handle(); @@ -95,6 +100,8 @@ impl Ferese { let xdg_shell_state = XdgShellState::new::(&display_handle); let decoration_state = XdgDecorationState::new::(&display_handle); let fractional_scale_state = FractionalScaleManagerState::new::(&display_handle); + let idle_inhibit_state = IdleInhibitManagerState::new::(&display_handle); + let idle_notifier_state = IdleNotifierState::new(&display_handle, event_loop.handle()); let shm_state = ShmState::new::(&display_handle, Vec::new()); let single_pixel_buffer_state = SinglePixelBufferState::new::(&display_handle); let output_manager_state = OutputManagerState::new_with_xdg_output::(&display_handle); @@ -128,6 +135,7 @@ impl Ferese { focused_window: None, cursor_status: CursorImageStatus::default_named(), intercepted_keys: HashSet::new(), + idle_inhibitors: HashMap::new(), direct_backend: None, next_window_id: 1, last_animation_tick: start_time, @@ -137,6 +145,8 @@ impl Ferese { data_device_state, decoration_state, fractional_scale_state, + idle_inhibit_state, + idle_notifier_state, output_manager_state, pointer_constraints_state, presentation_state, @@ -155,7 +165,7 @@ impl Ferese { fn init_wayland_listener( display: Display, - event_loop: &mut EventLoop, + event_loop: &mut EventLoop<'static, Self>, ) -> Result> { let listening_socket = ListeningSocketSource::new_auto()?; let socket_name = listening_socket.socket_name().to_os_string();