aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/input/mod.rs45
-rw-r--r--src/niri.rs21
2 files changed, 64 insertions, 2 deletions
diff --git a/src/input/mod.rs b/src/input/mod.rs
index 53781047..440fcb36 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;
+use std::time::{Duration, Instant};
use calloop::timer::{TimeoutAction, Timer};
use input::event::gesture::GestureEventCoordinates as _;
@@ -87,6 +87,10 @@ impl State {
}
}
+ if should_update_cursor_timeout(&event) {
+ self.niri.last_cursor_movement = Instant::now();
+ }
+
let hide_hotkey_overlay =
self.niri.hotkey_overlay.is_open() && should_hide_hotkey_overlay(&event);
@@ -307,6 +311,10 @@ impl State {
}
}
+ if pressed {
+ self.hide_cursor_if_needed();
+ }
+
let Some(Some(bind)) = self.niri.seat.get_keyboard().unwrap().input(
self,
event.key_code(),
@@ -349,7 +357,10 @@ impl State {
self.handle_bind(bind.clone());
- // Start the key repeat timer if necessary.
+ self.start_key_repeat(bind);
+ }
+
+ fn start_key_repeat(&mut self, bind: Bind) {
if !bind.repeat {
return;
}
@@ -383,6 +394,22 @@ impl State {
self.niri.bind_repeat_timer = Some(token);
}
+ fn hide_cursor_if_needed(&mut self) {
+ if !self.niri.config.borrow().cursor.hide_on_key_press {
+ return;
+ }
+
+ // niri keeps this set only while actively using a tablet, which means the cursor position
+ // is likely to change almost immediately, causing pointer_hidden to just flicker back and
+ // forth.
+ if self.niri.tablet_cursor_location.is_some() {
+ return;
+ }
+
+ self.niri.pointer_hidden = true;
+ self.niri.queue_redraw_all();
+ }
+
pub fn handle_bind(&mut self, bind: Bind) {
let Some(cooldown) = bind.cooldown else {
self.do_action(bind.action, bind.allow_when_locked);
@@ -2534,6 +2561,20 @@ fn should_notify_activity<I: InputBackend>(event: &InputEvent<I>) -> bool {
)
}
+fn should_update_cursor_timeout<I: InputBackend>(event: &InputEvent<I>) -> bool {
+ matches!(
+ event,
+ InputEvent::PointerAxis { .. }
+ | InputEvent::PointerButton { .. }
+ | InputEvent::PointerMotion { .. }
+ | InputEvent::PointerMotionAbsolute { .. }
+ | InputEvent::TabletToolAxis { .. }
+ | InputEvent::TabletToolButton { .. }
+ | InputEvent::TabletToolProximity { .. }
+ | InputEvent::TabletToolTip { .. }
+ )
+}
+
fn allowed_when_locked(action: &Action) -> bool {
matches!(
action,
diff --git a/src/niri.rs b/src/niri.rs
index 396852bf..6119c4d6 100644
--- a/src/niri.rs
+++ b/src/niri.rs
@@ -267,6 +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,
// 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>>,
@@ -1860,6 +1861,7 @@ impl Niri {
dnd_icon: None,
pointer_focus: PointerFocus::default(),
pointer_hidden: false,
+ last_cursor_movement: Instant::now(),
pointer_grab_ongoing: false,
tablet_cursor_location: None,
gesture_swipe_3f_cumulative: None,
@@ -2663,7 +2665,26 @@ 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;
}