fix: alt-tab focus history MRU ordering, repeat handling, and quick release
This commit is contained in:
+18
-37
@@ -24,7 +24,6 @@ use wayland_protocols_wlr::layer_shell::v1::client::{
|
||||
use wayland_protocols::wp::cursor_shape::v1::client::wp_cursor_shape_device_v1::Shape;
|
||||
|
||||
use crate::app::{App, Ending};
|
||||
use crate::config::AltTabMode;
|
||||
use crate::shm;
|
||||
use crate::theme::{Rect, fit_centred};
|
||||
|
||||
@@ -338,7 +337,7 @@ impl App {
|
||||
}
|
||||
|
||||
fn key(&mut self, code: u32, qh: &QueueHandle<Self>) {
|
||||
if self.is_alt_tab && is_trigger_modifier(code) {
|
||||
if is_trigger_modifier(code) {
|
||||
self.latched_modifiers.insert(code);
|
||||
}
|
||||
// Arm client-side repeat for navigation keys.
|
||||
@@ -380,10 +379,7 @@ impl App {
|
||||
self.repeat_key = None;
|
||||
self.repeat_next = None;
|
||||
}
|
||||
if self.is_alt_tab
|
||||
&& self.latched_modifiers.remove(&code)
|
||||
&& self.latched_modifiers.is_empty()
|
||||
{
|
||||
if self.latched_modifiers.remove(&code) && self.latched_modifiers.is_empty() {
|
||||
if self.ending == Ending::Running {
|
||||
self.picked = self.tiles.get(self.sel).map(|t| t.target.clone());
|
||||
self.ending = Ending::Picked;
|
||||
@@ -412,7 +408,7 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
fn keyboard_enter(&mut self, keys: Vec<u8>, qh: &QueueHandle<Self>) {
|
||||
fn keyboard_enter(&mut self, keys: Vec<u8>, _qh: &QueueHandle<Self>) {
|
||||
self.focused = true;
|
||||
let held_keys: Vec<u32> = keys
|
||||
.chunks_exact(4)
|
||||
@@ -429,41 +425,26 @@ impl App {
|
||||
.filter(|&k| is_trigger_modifier(k))
|
||||
.collect();
|
||||
|
||||
if !held_modifiers.is_empty() && self.alt_tab != AltTabMode::No {
|
||||
self.is_alt_tab = true;
|
||||
for &m in &held_modifiers {
|
||||
self.latched_modifiers.insert(m);
|
||||
}
|
||||
for &m in &held_modifiers {
|
||||
self.latched_modifiers.insert(m);
|
||||
}
|
||||
|
||||
if self.is_alt_tab && !self.initial_stepped {
|
||||
self.initial_stepped = true;
|
||||
if self.alt_tab == AltTabMode::Auto {
|
||||
if self.latched_modifiers.is_empty() {
|
||||
// Auto mode: no modifier held on enter means the mod was
|
||||
// released before focus arrived — commit immediately.
|
||||
if self.ending == Ending::Running {
|
||||
self.picked = self.tiles.get(self.sel).map(|t| t.target.clone());
|
||||
self.ending = Ending::Picked;
|
||||
}
|
||||
} else {
|
||||
// Modifier is held: step selection now.
|
||||
let step = if self.shift { -1 } else { 1 };
|
||||
self.move_sel(step, qh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For both Yes and Auto: if we are in alt-tab mode but no modifier is
|
||||
// currently held, the mod was released before keyboard focus arrived.
|
||||
// Commit the current selection immediately.
|
||||
if self.is_alt_tab && self.latched_modifiers.is_empty() && self.ending == Ending::Running {
|
||||
if self.alt_tab == AltTabMode::Yes
|
||||
|| (self.alt_tab == AltTabMode::Auto && self.initial_stepped)
|
||||
{
|
||||
// If no modifier is held on enter, the modifier (and/or Tab) was
|
||||
// released before focus was acquired: commit selection immediately!
|
||||
if self.latched_modifiers.is_empty() {
|
||||
if self.ending == Ending::Running {
|
||||
self.picked = self.tiles.get(self.sel).map(|t| t.target.clone());
|
||||
self.ending = Ending::Picked;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// A modifier is held. If Tab is also held upon enter, arm key-repeat
|
||||
// immediately so holding Tab cycles through windows.
|
||||
if held_keys.iter().any(|&k| k == KEY_TAB) {
|
||||
let delay = std::time::Duration::from_millis(self.repeat_delay_ms as u64);
|
||||
self.repeat_key = Some(KEY_TAB);
|
||||
self.repeat_next = Some(std::time::Instant::now() + delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user