mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-23 02:05:33 +07:00
Implement idle-notify and idle-inhibit
This commit is contained in:
Generated
+2
-2
@@ -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",
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user