aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2025-11-22 11:10:08 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2025-11-22 11:15:35 +0300
commitcfc01b895c0c7cbb9692852488675cc46693bd2a (patch)
tree21ff64a13a2433d53aa8b8154a78f6c869bfdb73
parent4e609f931904318d97dd7892d5fdb3c7a059dac6 (diff)
downloadniri-cfc01b895c0c7cbb9692852488675cc46693bd2a.tar.gz
niri-cfc01b895c0c7cbb9692852488675cc46693bd2a.tar.bz2
niri-cfc01b895c0c7cbb9692852488675cc46693bd2a.zip
Add hack to make Orca + Shift + A work better
-rw-r--r--src/input/mod.rs43
1 files changed, 37 insertions, 6 deletions
diff --git a/src/input/mod.rs b/src/input/mod.rs
index bc41e88a..81e5d863 100644
--- a/src/input/mod.rs
+++ b/src/input/mod.rs
@@ -420,18 +420,49 @@ impl State {
serial,
time,
|this, mods, keysym| {
+ let key_code = event.key_code();
+ let modified = keysym.modified_sym();
+ let raw = keysym.raw_latin_sym_or_raw_current_sym();
+ let modifiers = modifiers_from_state(*mods);
+
// After updating XKB state from accessibility-grabbed keys, return right away and
// don't handle them.
#[cfg(feature = "dbus")]
if block != KbMonBlock::Pass {
- return FilterResult::Intercept(None);
+ // HACK: there's a slight problem with this code. Here we filter out keys
+ // consumed by accessibility from getting sent to the Wayland client. However,
+ // the Wayland client can still receive these keys from the wl_keyboard
+ // enter/modifiers events. In particular, this can easily happen when opening
+ // the Orca actions menu with Orca + Shift + A: in most cases, when this menu
+ // opens, Shift is still held down, so the menu receives it in
+ // wl_keyboard.enter/modifiers. Then the menu won't react to Enter presses
+ // until the user taps Shift again to "release" it (since the initial Shift
+ // release will be intercepted here).
+ //
+ // I don't think there's any good way of dealing with this apart from keeping a
+ // separate xkb state for accessibility, so that we can track the pressed
+ // modifiers without accidentally leaking them to wl_keyboard.enter. So for now
+ // let's forward modifier releases to the clients here to deal with the most
+ // common case.
+ if !pressed
+ && matches!(
+ modified,
+ Keysym::Shift_L
+ | Keysym::Shift_R
+ | Keysym::Control_L
+ | Keysym::Control_R
+ | Keysym::Super_L
+ | Keysym::Super_R
+ | Keysym::Alt_L
+ | Keysym::Alt_R
+ )
+ {
+ return FilterResult::Forward;
+ } else {
+ return FilterResult::Intercept(None);
+ }
}
- let key_code = event.key_code();
- let modified = keysym.modified_sym();
- let raw = keysym.raw_latin_sym_or_raw_current_sym();
- let modifiers = modifiers_from_state(*mods);
-
if this.niri.exit_confirm_dialog.is_open() && pressed {
if raw == Some(Keysym::Return) {
info!("quitting after confirming exit dialog");