Add debounce-ms recent-windows setting

This commit is contained in:
Ivan Molodetskikh
2025-11-24 08:52:04 +03:00
parent 642277f881
commit d74debda13
4 changed files with 39 additions and 12 deletions
@@ -9,6 +9,8 @@ Here is an outline of the available settings and their default values:
```kdl
recent-windows {
// off
debounce-ms 750
open-delay-ms 150
highlight {
@@ -39,6 +41,30 @@ recent-windows {
`off` disables the recent windows switcher altogether.
### `debounce-ms`
Delay, in milliseconds, between the window receiving focus and getting "committed" to the recent windows list.
When you want to focus some window, you might end up focusing some unrelated windows on the way:
- with keyboard navigation, the windows between your current one and the target one;
- with [`focus-follows-mouse`](./Configuration:-Input.md#focus-follows-mouse), the windows you happen to cross with the mouse pointer on the way to the target window.
The debounce delay prevents those intermediate windows from polluting the recent windows list.
Note that some actions, like keyboard input into the target window, will skip this delay and commit the window to the list immediately.
This way, the recent windows list stays responsive while not getting polluted too much with unintended windows.
If you want windows to appear in recent windows right away, including intermediate windows, you can reduce the delay or set it to zero:
```kdl
recent-windows {
// Commit windows to the recent windows list as soon as they're focused,
// with no debounce delay.
debounce-ms 0
}
```
### `open-delay-ms`
Delay, in milliseconds, between pressing the Alt-Tab bind and the recent windows switcher visually appearing on screen.
+2 -3
View File
@@ -56,9 +56,7 @@ pub use crate::layout::*;
pub use crate::misc::*;
pub use crate::output::{Output, OutputName, Outputs, Position, Vrr};
use crate::recent_windows::RecentWindowsPart;
pub use crate::recent_windows::{
MruDirection, MruFilter, MruPreviews, MruScope, RecentWindows, DEFAULT_MRU_COMMIT_MS,
};
pub use crate::recent_windows::{MruDirection, MruFilter, MruPreviews, MruScope, RecentWindows};
pub use crate::utils::FloatOrInt;
use crate::utils::{Flag, MergeWith as _};
pub use crate::window_rule::{FloatingPosition, RelativeTo, WindowRule};
@@ -2181,6 +2179,7 @@ mod tests {
],
recent_windows: RecentWindows {
on: false,
debounce_ms: 750,
open_delay_ms: 150,
highlight: MruHighlight {
active_color: Color {
+5 -5
View File
@@ -6,13 +6,10 @@ use smithay::input::keyboard::Keysym;
use crate::utils::{expect_only_children, MergeWith};
use crate::{Action, Bind, Color, FloatOrInt, Key, Modifiers, Trigger};
/// Delay before the window focus is considered to be locked-in for Window
/// MRU ordering. For now the delay is not configurable.
pub const DEFAULT_MRU_COMMIT_MS: u64 = 750;
#[derive(Debug, PartialEq)]
pub struct RecentWindows {
pub on: bool,
pub debounce_ms: u16,
pub open_delay_ms: u16,
pub highlight: MruHighlight,
pub previews: MruPreviews,
@@ -23,6 +20,7 @@ impl Default for RecentWindows {
fn default() -> Self {
RecentWindows {
on: true,
debounce_ms: 750,
open_delay_ms: 150,
highlight: MruHighlight::default(),
previews: MruPreviews::default(),
@@ -38,6 +36,8 @@ pub struct RecentWindowsPart {
#[knuffel(child)]
pub off: bool,
#[knuffel(child, unwrap(argument))]
pub debounce_ms: Option<u16>,
#[knuffel(child, unwrap(argument))]
pub open_delay_ms: Option<u16>,
#[knuffel(child)]
pub highlight: Option<MruHighlightPart>,
@@ -54,7 +54,7 @@ impl MergeWith<RecentWindowsPart> for RecentWindows {
self.on = false;
}
merge_clone!((self, part), open_delay_ms);
merge_clone!((self, part), debounce_ms, open_delay_ms);
merge!((self, part), highlight, previews);
if let Some(part) = &part.binds {
+6 -4
View File
@@ -16,7 +16,7 @@ use calloop::futures::Scheduler;
use niri_config::debug::PreviewRender;
use niri_config::{
Config, FloatOrInt, Key, Modifiers, OutputName, TrackLayout, WarpMouseToFocusMode,
WorkspaceReference, Xkb, DEFAULT_MRU_COMMIT_MS,
WorkspaceReference, Xkb,
};
use smithay::backend::allocator::Fourcc;
use smithay::backend::input::Keycode;
@@ -1255,11 +1255,13 @@ impl State {
// period has gone by without the focus having elsewhere.
let stamp = get_monotonic_time();
if mapped.get_focus_timestamp().is_none() {
let debounce = self.niri.config.borrow().recent_windows.debounce_ms;
let debounce = Duration::from_millis(u64::from(debounce));
if mapped.get_focus_timestamp().is_none() || debounce.is_zero() {
mapped.set_focus_timestamp(stamp);
} else {
let timer =
Timer::from_duration(Duration::from_millis(DEFAULT_MRU_COMMIT_MS));
let timer = Timer::from_duration(debounce);
let focus_token = self
.niri