aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/handlers/compositor.rs12
-rw-r--r--src/handlers/mod.rs29
-rw-r--r--src/input.rs28
-rw-r--r--src/niri.rs27
4 files changed, 86 insertions, 10 deletions
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,