diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-02-08 13:51:54 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-02-09 15:50:40 +0400 |
| commit | b9116c579a6e99cae5393912fc9ed28674f5d3e5 (patch) | |
| tree | 9b2a165b839154cca60f2efd626c26dd6b3a9d71 | |
| parent | d8dcadc5b279c11e8cb8d1b0b064cc2b62c04099 (diff) | |
| download | niri-b9116c579a6e99cae5393912fc9ed28674f5d3e5.tar.gz niri-b9116c579a6e99cae5393912fc9ed28674f5d3e5.tar.bz2 niri-b9116c579a6e99cae5393912fc9ed28674f5d3e5.zip | |
Implement idle-notify and idle-inhibit
| -rw-r--r-- | Cargo.lock | 4 | ||||
| -rw-r--r-- | src/handlers/compositor.rs | 12 | ||||
| -rw-r--r-- | src/handlers/mod.rs | 29 | ||||
| -rw-r--r-- | src/input.rs | 28 | ||||
| -rw-r--r-- | src/niri.rs | 27 |
5 files changed, 88 insertions, 12 deletions
@@ -2963,7 +2963,7 @@ checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "smithay" version = "0.3.0" -source = "git+https://github.com/Smithay/smithay.git#070d29c01dd51175d17a16922ade85ab854b9e94" +source = "git+https://github.com/Smithay/smithay.git#774e45a445dd595ea9d18b32ef1cad15ca0ef548" dependencies = [ "appendlist", "bitflags 2.4.2", @@ -3035,7 +3035,7 @@ dependencies = [ [[package]] name = "smithay-drm-extras" version = "0.1.0" -source = "git+https://github.com/Smithay/smithay.git#070d29c01dd51175d17a16922ade85ab854b9e94" +source = "git+https://github.com/Smithay/smithay.git#774e45a445dd595ea9d18b32ef1cad15ca0ef548" dependencies = [ "drm", "edid-rs", diff --git a/src/handlers/compositor.rs b/src/handlers/compositor.rs index 5522e48d..fba025e8 100644 --- a/src/handlers/compositor.rs +++ b/src/handlers/compositor.rs @@ -97,7 +97,11 @@ impl CompositorHandler for State { // This is a root surface commit. It might have mapped a previously-unmapped toplevel. if let Entry::Occupied(entry) = self.niri.unmapped_windows.entry(surface.clone()) { let is_mapped = - with_renderer_surface_state(surface, |state| state.buffer().is_some()); + with_renderer_surface_state(surface, |state| state.buffer().is_some()) + .unwrap_or_else(|| { + error!("no renderer surface state even though we use commit handler"); + false + }); if is_mapped { // The toplevel got mapped. @@ -140,7 +144,11 @@ impl CompositorHandler for State { // This is a commit of a previously-mapped toplevel. let is_mapped = - with_renderer_surface_state(surface, |state| state.buffer().is_some()); + with_renderer_surface_state(surface, |state| state.buffer().is_some()) + .unwrap_or_else(|| { + error!("no renderer surface state even though we use commit handler"); + false + }); if !is_mapped { // The toplevel got unmapped. diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 07fb1a64..f11ff4d6 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -22,6 +22,8 @@ use smithay::reexports::wayland_server::Resource; use smithay::utils::{Logical, Rectangle, Size}; use smithay::wayland::compositor::{send_surface_state, with_states}; use smithay::wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier}; +use smithay::wayland::idle_inhibit::IdleInhibitHandler; +use smithay::wayland::idle_notify::{IdleNotifierHandler, IdleNotifierState}; use smithay::wayland::input_method::{InputMethodHandler, PopupSurface}; use smithay::wayland::output::OutputHandler; use smithay::wayland::pointer_constraints::PointerConstraintsHandler; @@ -42,10 +44,11 @@ use smithay::wayland::session_lock::{ }; use smithay::{ delegate_cursor_shape, delegate_data_control, delegate_data_device, delegate_dmabuf, - delegate_input_method_manager, delegate_output, delegate_pointer_constraints, - delegate_pointer_gestures, delegate_presentation, delegate_primary_selection, - delegate_relative_pointer, delegate_seat, delegate_security_context, delegate_session_lock, - delegate_tablet_manager, delegate_text_input_manager, delegate_virtual_keyboard_manager, + delegate_idle_inhibit, delegate_idle_notify, delegate_input_method_manager, delegate_output, + delegate_pointer_constraints, delegate_pointer_gestures, delegate_presentation, + delegate_primary_selection, delegate_relative_pointer, delegate_seat, + delegate_security_context, delegate_session_lock, delegate_tablet_manager, + delegate_text_input_manager, delegate_virtual_keyboard_manager, }; use crate::delegate_foreign_toplevel; @@ -300,6 +303,24 @@ impl SecurityContextHandler for State { } delegate_security_context!(State); +impl IdleNotifierHandler for State { + fn idle_notifier_state(&mut self) -> &mut IdleNotifierState<Self> { + &mut self.niri.idle_notifier_state + } +} +delegate_idle_notify!(State); + +impl IdleInhibitHandler for State { + fn inhibit(&mut self, surface: WlSurface) { + self.niri.idle_inhibiting_surfaces.insert(surface); + } + + fn uninhibit(&mut self, surface: WlSurface) { + self.niri.idle_inhibiting_surfaces.remove(&surface); + } +} +delegate_idle_inhibit!(State); + impl ForeignToplevelHandler for State { fn foreign_toplevel_manager_state(&mut self) -> &mut ForeignToplevelManagerState { &mut self.niri.foreign_toplevel_state diff --git a/src/input.rs b/src/input.rs index 387969f3..30d8e100 100644 --- a/src/input.rs +++ b/src/input.rs @@ -49,9 +49,24 @@ impl State { // here. self.niri.layout.advance_animations(get_monotonic_time()); - // Power on monitors if they were off. - if should_activate_monitors(&event) { - self.niri.activate_monitors(&mut self.backend); + if self.niri.monitors_active { + // Notify the idle-notifier of activity. + if should_notify_activity(&event) { + self.niri + .idle_notifier_state + .notify_activity(&self.niri.seat); + } + } else { + // Power on monitors if they were off. + if should_activate_monitors(&event) { + self.niri.activate_monitors(&mut self.backend); + + // Notify the idle-notifier of activity only if we're also powering on the + // monitors. + self.niri + .idle_notifier_state + .notify_activity(&self.niri.seat); + } } let hide_hotkey_overlay = @@ -1497,6 +1512,13 @@ fn should_hide_exit_confirm_dialog<I: InputBackend>(event: &InputEvent<I>) -> bo } } +fn should_notify_activity<I: InputBackend>(event: &InputEvent<I>) -> bool { + match event { + InputEvent::DeviceAdded { .. } | InputEvent::DeviceRemoved { .. } => false, + _ => true, + } +} + fn allowed_when_locked(action: &Action) -> bool { matches!( action, diff --git a/src/niri.rs b/src/niri.rs index 78a85d29..c0e33969 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -50,7 +50,7 @@ use smithay::reexports::wayland_server::backend::{ ClientData, ClientId, DisconnectReason, GlobalId, }; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; -use smithay::reexports::wayland_server::{Display, DisplayHandle}; +use smithay::reexports::wayland_server::{Display, DisplayHandle, Resource}; use smithay::utils::{ ClockSource, Logical, Monotonic, Physical, Point, Rectangle, Scale, Size, Transform, SERIAL_COUNTER, @@ -61,6 +61,8 @@ use smithay::wayland::compositor::{ }; use smithay::wayland::cursor_shape::CursorShapeManagerState; use smithay::wayland::dmabuf::DmabufState; +use smithay::wayland::idle_inhibit::IdleInhibitManagerState; +use smithay::wayland::idle_notify::IdleNotifierState; use smithay::wayland::input_method::{InputMethodManagerState, InputMethodSeat}; use smithay::wayland::output::OutputManagerState; use smithay::wayland::pointer_constraints::{with_pointer_constraint, PointerConstraintsState}; @@ -160,6 +162,8 @@ pub struct Niri { pub pointer_gestures_state: PointerGesturesState, pub relative_pointer_state: RelativePointerManagerState, pub pointer_constraints_state: PointerConstraintsState, + pub idle_notifier_state: IdleNotifierState<State>, + pub idle_inhibit_manager_state: IdleInhibitManagerState, pub data_device_state: DataDeviceState, pub primary_selection_state: PrimarySelectionState, pub data_control_state: DataControlState, @@ -176,6 +180,8 @@ pub struct Niri { // this toplevel surface). pub keyboard_focus: Option<WlSurface>, + pub idle_inhibiting_surfaces: HashSet<WlSurface>, + pub cursor_manager: CursorManager, pub cursor_texture_cache: CursorTextureCache, pub cursor_shape_manager_state: CursorShapeManagerState, @@ -328,6 +334,7 @@ impl State { self.niri.cursor_manager.check_cursor_image_surface_alive(); self.niri.refresh_pointer_outputs(); self.niri.popups.cleanup(); + self.niri.refresh_idle_inhibit(); self.refresh_popup_grab(); self.update_keyboard_focus(); self.refresh_pointer_focus(); @@ -848,6 +855,8 @@ impl Niri { let pointer_gestures_state = PointerGesturesState::new::<State>(&display_handle); let relative_pointer_state = RelativePointerManagerState::new::<State>(&display_handle); let pointer_constraints_state = PointerConstraintsState::new::<State>(&display_handle); + let idle_notifier_state = IdleNotifierState::new(&display_handle, event_loop.clone()); + let idle_inhibit_manager_state = IdleInhibitManagerState::new::<State>(&display_handle); let data_device_state = DataDeviceState::new::<State>(&display_handle); let primary_selection_state = PrimarySelectionState::new::<State>(&display_handle); let data_control_state = DataControlState::new::<State, _>( @@ -1006,6 +1015,8 @@ impl Niri { pointer_gestures_state, relative_pointer_state, pointer_constraints_state, + idle_notifier_state, + idle_inhibit_manager_state, data_device_state, primary_selection_state, data_control_state, @@ -1017,6 +1028,7 @@ impl Niri { seat, keyboard_focus: None, + idle_inhibiting_surfaces: HashSet::new(), cursor_manager, cursor_texture_cache: Default::default(), cursor_shape_manager_state, @@ -1863,6 +1875,19 @@ impl Niri { } } + pub fn refresh_idle_inhibit(&mut self) { + let _span = tracy_client::span!("Niri::refresh_idle_inhibit"); + + self.idle_inhibiting_surfaces.retain(|s| s.is_alive()); + + let is_inhibited = self.idle_inhibiting_surfaces.iter().any(|surface| { + with_states(surface, |states| { + surface_primary_scanout_output(surface, states).is_some() + }) + }); + self.idle_notifier_state.set_is_inhibited(is_inhibited); + } + pub fn render<R: NiriRenderer>( &self, renderer: &mut R, |
