brewery
notashelf /
a8e9e9cf7f9dc70c19ee8780bf3715b00d4ca09e

beer

public

A terminal worth pouring time into

Star0tarball
clone
ssh://git@git.notashelf.dev:33/notashelf/beer.git

Commit a8e9e9cf7f9d

tarball

NotAShelf <raf@notashelf.dev> · 2026-06-26 21:04 UTC

unverified1 files changed+37-5
beer-protocols: suppress kitty key releases when event reporting is off

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I136a6bc68818a066491b63c0c212eacb6a6a6964
diff --git a/crates/beer-protocols/src/key.rs b/crates/beer-protocols/src/key.rsindex 630bca1..0dc0348 100644--- a/crates/beer-protocols/src/key.rs+++ b/crates/beer-protocols/src/key.rs@@ -185,9 +185,18 @@ pub fn kitty_encode(      let bits = kitty_mod_bits(mods);     let mod_param = bits + 1;-    // Events other than a press are only reported when asked for.+    // Events other than a press are only reported when asked for. Without+    // event reporting, repeats are re-sent as presses (legacy repeat), but a+    // release must produce nothing. Otherwise a release encodes as a press+    // and a single tap sends the key twice.     let events_ok = report_events || report_all;-    let kind = if events_ok { kind } else { KeyKind::Press };+    let kind = if events_ok {+        kind+    } else if kind == KeyKind::Release {+        return None;+    } else {+        KeyKind::Press+    };      // Lone modifier keys: only in report-all mode.     if let Some(code) = modifier_key(event.keysym) {@@ -215,9 +224,6 @@ pub fn kitty_encode(                     _ => b"\r".to_vec(),                 });             }-            if kind != KeyKind::Press && !events_ok {-                return None;-            }             Some(match func {                 Func::Number(n) => csi(n.to_string(), mod_param, kind, None, b'u'),                 Func::Tilde(n) => csi(n.to_string(), mod_param, kind, None, b'~'),@@ -478,6 +484,32 @@ mod tests {     }      #[test]+    fn kitty_release_suppressed_without_event_reporting() {+        // A release under disambiguate-only (no report-event-types, no+        // report-all) must not be re-encoded as a press, or a single tap sends+        // the key twice. Applies to both functional keys and text keys.+        assert_eq!(+            kitty_encode(&key(Keysym::Up, None), NONE, 0b1, KeyKind::Release, false),+            None+        );+        assert_eq!(+            kitty_encode(+                &key(Keysym::a, Some("a")),+                NONE,+                0b1,+                KeyKind::Release,+                false+            ),+            None+        );+        // A repeat is still re-sent as a press (legacy repeat behaviour).+        assert_eq!(+            kitty_encode(&key(Keysym::Up, None), NONE, 0b1, KeyKind::Repeat, false),+            Some(b"\x1b[A".to_vec())+        );+    }++    #[test]     fn kitty_lock_keys_do_not_leak() {         let numlock = Modifiers {             num_lock: true,