aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/input/mod.rs8
-rw-r--r--src/niri.rs67
2 files changed, 48 insertions, 27 deletions
diff --git a/src/input/mod.rs b/src/input/mod.rs
index 440fcb36..7c43c896 100644
--- a/src/input/mod.rs
+++ b/src/input/mod.rs
@@ -2,7 +2,7 @@ use std::any::Any;
use std::cmp::min;
use std::collections::hash_map::Entry;
use std::collections::HashSet;
-use std::time::{Duration, Instant};
+use std::time::Duration;
use calloop::timer::{TimeoutAction, Timer};
use input::event::gesture::GestureEventCoordinates as _;
@@ -87,8 +87,8 @@ impl State {
}
}
- if should_update_cursor_timeout(&event) {
- self.niri.last_cursor_movement = Instant::now();
+ if should_reset_pointer_inactivity_timer(&event) {
+ self.niri.reset_pointer_inactivity_timer();
}
let hide_hotkey_overlay =
@@ -2561,7 +2561,7 @@ fn should_notify_activity<I: InputBackend>(event: &InputEvent<I>) -> bool {
)
}
-fn should_update_cursor_timeout<I: InputBackend>(event: &InputEvent<I>) -> bool {
+fn should_reset_pointer_inactivity_timer<I: InputBackend>(event: &InputEvent<I>) -> bool {
matches!(
event,
InputEvent::PointerAxis { .. }
diff --git a/src/niri.rs b/src/niri.rs
index 6119c4d6..7c3052ec 100644
--- a/src/niri.rs
+++ b/src/niri.rs
@@ -267,7 +267,7 @@ pub struct Niri {
/// When this happens, the pointer also loses any focus. This is so that touch can prevent
/// various tooltips from sticking around.
pub pointer_hidden: bool,
- pub last_cursor_movement: Instant,
+ pub pointer_inactivity_timer: Option<RegistrationToken>,
// FIXME: this should be able to be removed once PointerFocus takes grabs into account.
pub pointer_grab_ongoing: bool,
pub tablet_cursor_location: Option<Point<f64, Logical>>,
@@ -589,6 +589,7 @@ impl State {
// We moved the pointer, show it.
self.niri.pointer_hidden = false;
+ self.niri.reset_pointer_inactivity_timer();
// FIXME: granular
self.niri.queue_redraw_all();
@@ -991,6 +992,7 @@ impl State {
let mut window_rules_changed = false;
let mut debug_config_changed = false;
let mut shaders_changed = false;
+ let mut cursor_inactivity_timeout_changed = false;
let mut old_config = self.niri.config.borrow_mut();
// Reload the cursor.
@@ -1077,6 +1079,10 @@ impl State {
shaders_changed = true;
}
+ if config.cursor.hide_after_inactive_ms != old_config.cursor.hide_after_inactive_ms {
+ cursor_inactivity_timeout_changed = true;
+ }
+
if config.debug != old_config.debug {
debug_config_changed = true;
}
@@ -1123,6 +1129,10 @@ impl State {
self.niri.layout.update_shaders();
}
+ if cursor_inactivity_timeout_changed {
+ self.niri.reset_pointer_inactivity_timer();
+ }
+
// Can't really update xdg-decoration settings since we have to hide the globals for CSD
// due to the SDL2 bug... I don't imagine clients are prepared for the xdg-decoration
// global suddenly appearing? Either way, right now it's live-reloaded in a sense that new
@@ -1784,7 +1794,7 @@ impl Niri {
.unwrap();
drop(config_);
- Self {
+ let mut niri = Self {
config,
config_file_output_config,
@@ -1861,7 +1871,7 @@ impl Niri {
dnd_icon: None,
pointer_focus: PointerFocus::default(),
pointer_hidden: false,
- last_cursor_movement: Instant::now(),
+ pointer_inactivity_timer: None,
pointer_grab_ongoing: false,
tablet_cursor_location: None,
gesture_swipe_3f_cumulative: None,
@@ -1897,7 +1907,11 @@ impl Niri {
#[cfg(feature = "xdp-gnome-screencast")]
mapped_cast_output: HashMap::new(),
- }
+ };
+
+ niri.reset_pointer_inactivity_timer();
+
+ niri
}
#[cfg(feature = "dbus")]
@@ -2665,26 +2679,7 @@ impl Niri {
pointer_elements
}
- fn hide_cursor_after_timeout_if_needed(&mut self) {
- if self.pointer_hidden {
- return;
- }
-
- let config = self.config.borrow();
- let timeout = &config.cursor.hide_after_inactive_ms;
-
- if let Some(duration_ms) = timeout {
- let timeout = Duration::from_millis(*duration_ms as u64);
-
- if self.last_cursor_movement.elapsed() >= timeout {
- self.pointer_hidden = true;
- }
- }
- }
-
pub fn refresh_pointer_outputs(&mut self) {
- self.hide_cursor_after_timeout_if_needed();
-
if self.pointer_hidden {
return;
}
@@ -4728,6 +4723,32 @@ impl Niri {
self.queue_redraw_all();
}
}
+
+ pub fn reset_pointer_inactivity_timer(&mut self) {
+ let _span = tracy_client::span!("Niri::reset_pointer_inactivity_timer");
+
+ if let Some(token) = self.pointer_inactivity_timer.take() {
+ self.event_loop.remove(token);
+ }
+
+ let Some(timeout_ms) = self.config.borrow().cursor.hide_after_inactive_ms else {
+ return;
+ };
+
+ let duration = Duration::from_millis(timeout_ms as u64);
+ let timer = Timer::from_duration(duration);
+ let token = self
+ .event_loop
+ .insert_source(timer, move |_, _, state| {
+ state.niri.pointer_inactivity_timer = None;
+ state.niri.pointer_hidden = true;
+ state.niri.queue_redraw_all();
+
+ TimeoutAction::Drop
+ })
+ .unwrap();
+ self.pointer_inactivity_timer = Some(token);
+ }
}
pub struct ClientState {