Implement idle-notify and idle-inhibit

This commit is contained in:
Ivan Molodetskikh
2024-02-08 13:51:54 +04:00
parent d8dcadc5b2
commit b9116c579a
5 changed files with 88 additions and 12 deletions
Generated
+2 -2
View File
@@ -2963,7 +2963,7 @@ checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
[[package]] [[package]]
name = "smithay" name = "smithay"
version = "0.3.0" version = "0.3.0"
source = "git+https://github.com/Smithay/smithay.git#070d29c01dd51175d17a16922ade85ab854b9e94" source = "git+https://github.com/Smithay/smithay.git#774e45a445dd595ea9d18b32ef1cad15ca0ef548"
dependencies = [ dependencies = [
"appendlist", "appendlist",
"bitflags 2.4.2", "bitflags 2.4.2",
@@ -3035,7 +3035,7 @@ dependencies = [
[[package]] [[package]]
name = "smithay-drm-extras" name = "smithay-drm-extras"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/Smithay/smithay.git#070d29c01dd51175d17a16922ade85ab854b9e94" source = "git+https://github.com/Smithay/smithay.git#774e45a445dd595ea9d18b32ef1cad15ca0ef548"
dependencies = [ dependencies = [
"drm", "drm",
"edid-rs", "edid-rs",
+10 -2
View File
@@ -97,7 +97,11 @@ impl CompositorHandler for State {
// This is a root surface commit. It might have mapped a previously-unmapped toplevel. // 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()) { if let Entry::Occupied(entry) = self.niri.unmapped_windows.entry(surface.clone()) {
let is_mapped = 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 { if is_mapped {
// The toplevel got mapped. // The toplevel got mapped.
@@ -140,7 +144,11 @@ impl CompositorHandler for State {
// This is a commit of a previously-mapped toplevel. // This is a commit of a previously-mapped toplevel.
let is_mapped = 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 { if !is_mapped {
// The toplevel got unmapped. // The toplevel got unmapped.
+25 -4
View File
@@ -22,6 +22,8 @@ use smithay::reexports::wayland_server::Resource;
use smithay::utils::{Logical, Rectangle, Size}; use smithay::utils::{Logical, Rectangle, Size};
use smithay::wayland::compositor::{send_surface_state, with_states}; use smithay::wayland::compositor::{send_surface_state, with_states};
use smithay::wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier}; 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::input_method::{InputMethodHandler, PopupSurface};
use smithay::wayland::output::OutputHandler; use smithay::wayland::output::OutputHandler;
use smithay::wayland::pointer_constraints::PointerConstraintsHandler; use smithay::wayland::pointer_constraints::PointerConstraintsHandler;
@@ -42,10 +44,11 @@ use smithay::wayland::session_lock::{
}; };
use smithay::{ use smithay::{
delegate_cursor_shape, delegate_data_control, delegate_data_device, delegate_dmabuf, delegate_cursor_shape, delegate_data_control, delegate_data_device, delegate_dmabuf,
delegate_input_method_manager, delegate_output, delegate_pointer_constraints, delegate_idle_inhibit, delegate_idle_notify, delegate_input_method_manager, delegate_output,
delegate_pointer_gestures, delegate_presentation, delegate_primary_selection, delegate_pointer_constraints, delegate_pointer_gestures, delegate_presentation,
delegate_relative_pointer, delegate_seat, delegate_security_context, delegate_session_lock, delegate_primary_selection, delegate_relative_pointer, delegate_seat,
delegate_tablet_manager, delegate_text_input_manager, delegate_virtual_keyboard_manager, delegate_security_context, delegate_session_lock, delegate_tablet_manager,
delegate_text_input_manager, delegate_virtual_keyboard_manager,
}; };
use crate::delegate_foreign_toplevel; use crate::delegate_foreign_toplevel;
@@ -300,6 +303,24 @@ impl SecurityContextHandler for State {
} }
delegate_security_context!(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 { impl ForeignToplevelHandler for State {
fn foreign_toplevel_manager_state(&mut self) -> &mut ForeignToplevelManagerState { fn foreign_toplevel_manager_state(&mut self) -> &mut ForeignToplevelManagerState {
&mut self.niri.foreign_toplevel_state &mut self.niri.foreign_toplevel_state
+25 -3
View File
@@ -49,9 +49,24 @@ impl State {
// here. // here.
self.niri.layout.advance_animations(get_monotonic_time()); self.niri.layout.advance_animations(get_monotonic_time());
// Power on monitors if they were off. if self.niri.monitors_active {
if should_activate_monitors(&event) { // Notify the idle-notifier of activity.
self.niri.activate_monitors(&mut self.backend); 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 = 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 { fn allowed_when_locked(action: &Action) -> bool {
matches!( matches!(
action, action,
+26 -1
View File
@@ -50,7 +50,7 @@ use smithay::reexports::wayland_server::backend::{
ClientData, ClientId, DisconnectReason, GlobalId, ClientData, ClientId, DisconnectReason, GlobalId,
}; };
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; 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::{ use smithay::utils::{
ClockSource, Logical, Monotonic, Physical, Point, Rectangle, Scale, Size, Transform, ClockSource, Logical, Monotonic, Physical, Point, Rectangle, Scale, Size, Transform,
SERIAL_COUNTER, SERIAL_COUNTER,
@@ -61,6 +61,8 @@ use smithay::wayland::compositor::{
}; };
use smithay::wayland::cursor_shape::CursorShapeManagerState; use smithay::wayland::cursor_shape::CursorShapeManagerState;
use smithay::wayland::dmabuf::DmabufState; 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::input_method::{InputMethodManagerState, InputMethodSeat};
use smithay::wayland::output::OutputManagerState; use smithay::wayland::output::OutputManagerState;
use smithay::wayland::pointer_constraints::{with_pointer_constraint, PointerConstraintsState}; use smithay::wayland::pointer_constraints::{with_pointer_constraint, PointerConstraintsState};
@@ -160,6 +162,8 @@ pub struct Niri {
pub pointer_gestures_state: PointerGesturesState, pub pointer_gestures_state: PointerGesturesState,
pub relative_pointer_state: RelativePointerManagerState, pub relative_pointer_state: RelativePointerManagerState,
pub pointer_constraints_state: PointerConstraintsState, pub pointer_constraints_state: PointerConstraintsState,
pub idle_notifier_state: IdleNotifierState<State>,
pub idle_inhibit_manager_state: IdleInhibitManagerState,
pub data_device_state: DataDeviceState, pub data_device_state: DataDeviceState,
pub primary_selection_state: PrimarySelectionState, pub primary_selection_state: PrimarySelectionState,
pub data_control_state: DataControlState, pub data_control_state: DataControlState,
@@ -176,6 +180,8 @@ pub struct Niri {
// this toplevel surface). // this toplevel surface).
pub keyboard_focus: Option<WlSurface>, pub keyboard_focus: Option<WlSurface>,
pub idle_inhibiting_surfaces: HashSet<WlSurface>,
pub cursor_manager: CursorManager, pub cursor_manager: CursorManager,
pub cursor_texture_cache: CursorTextureCache, pub cursor_texture_cache: CursorTextureCache,
pub cursor_shape_manager_state: CursorShapeManagerState, pub cursor_shape_manager_state: CursorShapeManagerState,
@@ -328,6 +334,7 @@ impl State {
self.niri.cursor_manager.check_cursor_image_surface_alive(); self.niri.cursor_manager.check_cursor_image_surface_alive();
self.niri.refresh_pointer_outputs(); self.niri.refresh_pointer_outputs();
self.niri.popups.cleanup(); self.niri.popups.cleanup();
self.niri.refresh_idle_inhibit();
self.refresh_popup_grab(); self.refresh_popup_grab();
self.update_keyboard_focus(); self.update_keyboard_focus();
self.refresh_pointer_focus(); self.refresh_pointer_focus();
@@ -848,6 +855,8 @@ impl Niri {
let pointer_gestures_state = PointerGesturesState::new::<State>(&display_handle); let pointer_gestures_state = PointerGesturesState::new::<State>(&display_handle);
let relative_pointer_state = RelativePointerManagerState::new::<State>(&display_handle); let relative_pointer_state = RelativePointerManagerState::new::<State>(&display_handle);
let pointer_constraints_state = PointerConstraintsState::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 data_device_state = DataDeviceState::new::<State>(&display_handle);
let primary_selection_state = PrimarySelectionState::new::<State>(&display_handle); let primary_selection_state = PrimarySelectionState::new::<State>(&display_handle);
let data_control_state = DataControlState::new::<State, _>( let data_control_state = DataControlState::new::<State, _>(
@@ -1006,6 +1015,8 @@ impl Niri {
pointer_gestures_state, pointer_gestures_state,
relative_pointer_state, relative_pointer_state,
pointer_constraints_state, pointer_constraints_state,
idle_notifier_state,
idle_inhibit_manager_state,
data_device_state, data_device_state,
primary_selection_state, primary_selection_state,
data_control_state, data_control_state,
@@ -1017,6 +1028,7 @@ impl Niri {
seat, seat,
keyboard_focus: None, keyboard_focus: None,
idle_inhibiting_surfaces: HashSet::new(),
cursor_manager, cursor_manager,
cursor_texture_cache: Default::default(), cursor_texture_cache: Default::default(),
cursor_shape_manager_state, 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>( pub fn render<R: NiriRenderer>(
&self, &self,
renderer: &mut R, renderer: &mut R,