zellij
zellij copied to clipboard
reencode termwiz keycodes as current_buffer isnt reliable
It's not reliable because current_buffer can sometimes contain multiple instructions at once, which are mistakenly treated as a single one. For example, if it holds [KeyCode, MouseMove], the parser might interpret it as one large KeyCode and print it directly to the terminal, leading to issues like this: https://github.com/zellij-org/zellij/issues/932
Interesting find! I want to believe this is the cause of some issues we've been seeing over SSH with scroll events printing clear text escape codes to the active terminal pane. I do however want to test this and find real world cases on which this has an effect before moving forward.
Is this a fix for an issue you've been experiencing?
Yep, ive experienced this bug. Whenever i press a key and move my mouse i get a sequence of mouse events in my terminal. Is this reproducible on your machine? If not, i would happily help you with testing.
My setup is macos + alacritty, if it helps
Gotcha. I'm sending some people here who experienced the issues I'm hoping this fix will solve. I want to try and understand its impact better before moving forward. One way or another, I think we'll merge this fix but I might want to adjust it or add things to it beforehand. Thanks for your patience and diligence!
I have built from main with this patch applied, and it does not fix my issue. I can open (or comment on) a new Issue if that's better, but I'll post my details here for now.
To reproduce:
- Run Windows Terminal, Wezterm or Alacritty (on Windows)
- ssh into a Linux box (i.e.
ssh -t hostname) - Run zellij
- Wave the mouse around a bit.
After a couple seconds, strings like <35;149;19m will appear (always starting <35;). If I stop waving, everything goes mostly back to normal. It happens with the default Zellij layout and a single pane, and even if I make sure that the mouse always stays well within the borders of the pane.
The problem is more acute with Alacritty, but still easily reproducible with a couple seconds of mouse waving on the other two. I cannot reproduce this with PuTTY (but PuTTY is useless to me since it doesn't support OSC-52). Running with mouse_mode false makes the problem go away (but of course that causes other more serious usability issues).
Hey @abatkin - thanks for checking this out! Would you be willing to keep helping troubleshoot this? I am not reproducing your issue, but it might be because I'm not on windows (and unfortunately do not have access to a windows machine).
I added some logs to this branch, as well as a possible fix for your specific issue. I hope @kewaopcode doesn't mind!
My ask from you @abatkin is: please run this branch again with my changes and try to reproduce your issue. If you are able to reproduce it, please paste the relevant logs here. Their location is system-dependent but they are usually located somewhere in the /tmp folder. For me they are at /tmp/zellij-1000/zellij-log/zellij.log. (you might want to clear this file before reproducing the issue).
Much appreciated!
@abatkin The problem is that i didnt bother to fix the kitty protocol, can you force your terminal to not use it? and set the support_kitty_keyboard_protocol to false in zellij. I will probably fix it today or tomorrow
@abatkin The problem is that i didnt bother to fix the kitty protocol, can you force your terminal to not use it? and set the
support_kitty_keyboard_protocolto false in zellij. I will probably fix it today or tomorrow
@Andrew15-5 you too
@abatkin The problem is that i didnt bother to fix the kitty protocol, can you force your terminal to not use it? and set the
support_kitty_keyboard_protocolto false in zellij. I will probably fix it today or tomorrow
For @abatkin I don't think this is the issue, since as far as I know Windows Terminal does not support the kitty keyboard protocol. Also what they're reporting is mouse movements which are encoded by termwiz. I hope with my changes we can get to the bottom of this.
@abatkin The problem is that i didnt bother to fix the kitty protocol, can you force your terminal to not use it? and set the
support_kitty_keyboard_protocolto false in zellij. I will probably fix it today or tomorrowFor @abatkin I don't think this is the issue, since as far as I know Windows Terminal does not support the kitty keyboard protocol. Also what they're reporting is mouse movements which are encoded by termwiz. I hope with my changes we can get to the bottom of this.
yes, i thought he is the guy who opened that issue.
set the
support_kitty_keyboard_protocolto false in zellij
Woah! It does remove the problem. I have no idea what exactly does this do, but perhaps this already is good enough, definitely better than fiddling with locking state.
So... I tested without this, because otherwise nothing with be triggered(?)
set the
support_kitty_keyboard_protocolto false in zellijWoah! It does remove the problem. I have no idea what exactly does this do, but perhaps this already is good enough, definitely better than fiddling with locking state.
So... I tested without this, because otherwise nothing with be triggered(?)
Thank you! I will notify you when i make the kitty support on this branch
edit: as for your logs, InputInstruction::KeyWithModifierEvent: KeyWithModifier { bare_key: Char('d'), key_modifiers: {Ctrl} }, raw_bytes: [27, 91, 49, 48, 48, 59, 49, 51, 51, 117] is the problem, we are working on a KeyWithModifier, but the payload is full of garbage ("\ESC[100;133u")
@imsnif I just pushed this fix for kitty protocol. Please review my code, im unsure about .drain(..) part, as i am not a rust dev, i may be missing some memory-related stuff. Also, please check that unwrap(), i dont think its a good decision there. Anyways, this commit fixes kitty protocol on my machine. @Andrew15-5 can you try it?
Doesn't fix it.
@imsnif I just pushed this fix for kitty protocol. Please review my code, im unsure about .drain(..) part, as i am not a rust dev, i may be missing some memory-related stuff. Also, please check that unwrap(), i dont think its a good decision there.
Sure. I first want to wait for @abatkin to get a chance to check my changes before we finalize everything here.
I've been having a similar issue in Windows Terminal using zellij over ssh, particularly when focusing back to my terminal after a few minutes of being away. It's hard to reproduce, but I pulled down / compiled this branch today and managed to capture the log output of the issue happening. You can see the <A-[> getting consumed among other things. Hope this is helpful!
Zellij Log
INFO |zellij_client::input_hand| 2025-05-07 12:33:48.733 [input_handler] [zellij-client/src/input_handler.rs:374]: send_to_server, ClientToServerMsg::Action: MouseEvent(MouseEvent { event_type: Motion, left: false, right: false, middle: false, wheel_up: false, wheel_down: false, shift: false, alt: false, ctrl: false, position: Position { line: Line(59), column: Column(8) } })
INFO |zellij_client::stdin_hand| 2025-05-07 12:34:06.264 [stdin_handler] [zellij-client/src/stdin_handler.rs:66]: RECEIVED ON STDIN: "\u{1b}[<0;42;17M\u{1b}[<0;"
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.265 [input_handler] [zellij-client/src/input_handler.rs:189]: InputEvent::Mouse: MouseEvent { x: 42, y: 17, mouse_buttons: MouseButtons(LEFT), modifiers: NONE }
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.265 [input_handler] [zellij-client/src/input_handler.rs:374]: send_to_server, ClientToServerMsg::Action: MouseEvent(MouseEvent { event_type: Press, left: true, right: false, middle: false, wheel_up: false, wheel_down: false, shift: false, alt: false, ctrl: false, position: Position { line: Line(16), column: Column(41) } })
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.265 [input_handler] [zellij-client/src/input_handler.rs:167]: InputEvent::Key: KeyEvent { key: Char('['), modifiers: ALT }
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.265 [input_handler] [zellij-client/src/input_handler.rs:271]: send_to_server ClientToServerMsg::Key: key: KeyWithModifier { bare_key: Char('['), key_modifiers: {Alt} }, raw_bytes: [27, 91], is_kitty_keyboard_protocol: false
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.265 [input_handler] [zellij-client/src/input_handler.rs:167]: InputEvent::Key: KeyEvent { key: Char('<'), modifiers: NONE }
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.265 [input_handler] [zellij-client/src/input_handler.rs:271]: send_to_server ClientToServerMsg::Key: key: KeyWithModifier { bare_key: Char('<'), key_modifiers: {} }, raw_bytes: [60], is_kitty_keyboard_protocol: false
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.265 [input_handler] [zellij-client/src/input_handler.rs:167]: InputEvent::Key: KeyEvent { key: Char('0'), modifiers: NONE }
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.265 [input_handler] [zellij-client/src/input_handler.rs:271]: send_to_server ClientToServerMsg::Key: key: KeyWithModifier { bare_key: Char('0'), key_modifiers: {} }, raw_bytes: [48], is_kitty_keyboard_protocol: false
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.265 [input_handler] [zellij-client/src/input_handler.rs:167]: InputEvent::Key: KeyEvent { key: Char(';'), modifiers: NONE }
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.265 [input_handler] [zellij-client/src/input_handler.rs:271]: send_to_server ClientToServerMsg::Key: key: KeyWithModifier { bare_key: Char(';'), key_modifiers: {} }, raw_bytes: [59], is_kitty_keyboard_protocol: false
INFO |zellij_client::stdin_hand| 2025-05-07 12:34:06.328 [stdin_handler] [zellij-client/src/stdin_handler.rs:66]: RECEIVED ON STDIN: "42;17m"
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.328 [input_handler] [zellij-client/src/input_handler.rs:167]: InputEvent::Key: KeyEvent { key: Char('4'), modifiers: NONE }
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.328 [input_handler] [zellij-client/src/input_handler.rs:271]: send_to_server ClientToServerMsg::Key: key: KeyWithModifier { bare_key: Char('4'), key_modifiers: {} }, raw_bytes: [52], is_kitty_keyboard_protocol: false
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.328 [input_handler] [zellij-client/src/input_handler.rs:167]: InputEvent::Key: KeyEvent { key: Char('2'), modifiers: NONE }
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.328 [input_handler] [zellij-client/src/input_handler.rs:271]: send_to_server ClientToServerMsg::Key: key: KeyWithModifier { bare_key: Char('2'), key_modifiers: {} }, raw_bytes: [50], is_kitty_keyboard_protocol: false
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.328 [input_handler] [zellij-client/src/input_handler.rs:167]: InputEvent::Key: KeyEvent { key: Char(';'), modifiers: NONE }
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.328 [input_handler] [zellij-client/src/input_handler.rs:271]: send_to_server ClientToServerMsg::Key: key: KeyWithModifier { bare_key: Char(';'), key_modifiers: {} }, raw_bytes: [59], is_kitty_keyboard_protocol: false
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.328 [input_handler] [zellij-client/src/input_handler.rs:167]: InputEvent::Key: KeyEvent { key: Char('1'), modifiers: NONE }
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.328 [input_handler] [zellij-client/src/input_handler.rs:271]: send_to_server ClientToServerMsg::Key: key: KeyWithModifier { bare_key: Char('1'), key_modifiers: {} }, raw_bytes: [49], is_kitty_keyboard_protocol: false
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.328 [input_handler] [zellij-client/src/input_handler.rs:167]: InputEvent::Key: KeyEvent { key: Char('7'), modifiers: NONE }
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.328 [input_handler] [zellij-client/src/input_handler.rs:271]: send_to_server ClientToServerMsg::Key: key: KeyWithModifier { bare_key: Char('7'), key_modifiers: {} }, raw_bytes: [55], is_kitty_keyboard_protocol: false
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.328 [input_handler] [zellij-client/src/input_handler.rs:167]: InputEvent::Key: KeyEvent { key: Char('m'), modifiers: NONE }
INFO |zellij_client::input_hand| 2025-05-07 12:34:06.328 [input_handler] [zellij-client/src/input_handler.rs:271]: send_to_server ClientToServerMsg::Key: key: KeyWithModifier { bare_key: Char('m'), key_modifiers: {} }, raw_bytes: [109], is_kitty_keyboard_protocol: false
I've been having a similar issue in Windows Terminal using zellij over ssh, particularly when focusing back to my terminal after a few minutes of being away. It's hard to reproduce, but I pulled down / compiled this branch today and managed to capture the log output of the issue happening. You can see the
<A-[>getting consumed among other things. Hope this is helpful!
Nice! I see the issue here, thanks. I'll fix this in a different PR before the next version. I think while this PR didn't fix this specific issue, it made it much easier to debug.
I'll go over this PR and merge it soon. Thanks everyone!
As you predicted, setting support_kitty_keyboard_protocol to false didn't help, and neither iteration of this PR seems to have helped (re-tested only in Windows Terminal).
Log attached (from the head of main with this PR applied, and kitty protocol still disabled). I did the following:
- Launch zellij
- Typed "hello" (enter)
- waved my mouse around fora while until it printed escapes
- pressed Ctrl+C
- Typed "goodbye" (enter)
- Pressed Ctrl+D to exit
Interestingly, I can't reproduce this on two other Windows boxes. There are a bunch of other major differences in the setups though, so it's hard to tell what is the cause. All are Windows 11 (though probably different patch levels, maybe slightly different versions of Windows Terminal) and the same zellij revisions. I can't go into all the details here, except to say that the "broken" one uses a particular virtualization system and client, and the "working" ones (one is a VM, the other a physical machine) use different remote access tools and a different target Linux (Fedora). But who knows what is the actual cause. Maybe I just didn't wave the mouse around enough ;)
Thanks for the checking and for the logs @abatkin ! You're experiencing the same issue as https://github.com/zellij-org/zellij/pull/4150#issuecomment-2859617013. Essentially the bytes received over STDIN through the ssh connection are fragmented and our parser doesn't deal with this well.
I'll fix it in a separate PR before the next release. Thanks again!
I can now reliably reproduce this on different machines, using Alacritty (on Windows 11) using Windows built-in CLI ssh client. Based on what @imsnif just said, I figured it may have to do with latency, so I spun up an EC2 Instance (AL2023) in Tokyo (I'm US East Coast) and boom! Turns out I can also spin one up in N. Virginia and reproduce it just fine. It's just when connecting to machines on my LAN that I can't get it to happen.
Hey @kewaopcode - I'm circling back to this finally. Would you mind rebasing from main?
@imsnif sure, but i already cleaned up the whole setup, can you rebase it by yourself?
Not without force-pushing.
Been playing a bit more with this and found that unfortunately the reencode solution won't work out very well. There are some cases in which the encoded events strip info from the raw bytes (eg. Ctrl j vs. Enter) that we use for post-processing.
I'm in the process of working out an asynchronous debounce to solve segmented STDIN as described here https://github.com/zellij-org/zellij/pull/4150#issuecomment-2859617013 and here https://github.com/zellij-org/zellij/pull/4150#issuecomment-2861501013
Essentially what we will be doing is only passing STDIN sequences that are exact matches to events (along with their relevant raw_bytes for post-processing) and having a 50ms (configurable) debouncer that flushes the parser and interprets the remaining pending bytes as events (for stuff like the ESC key).
This is dependent on some changes in termwiz though, so I'm waiting on that before moving forward with the implementation: https://github.com/wezterm/wezterm/issues/7076
Ctrl jvs.Enter
I updated NixOS a few days ago, and kitty with it. I rebuilt zellij from this branch, and now with support_kitty_keyboard_protocol false I can't use Ctrl+j in Neovim autocompletion menu. Well, and in zsh back search too. But if I enable it back, the https://github.com/zellij-org/zellij/issues/4178 appears again... At least the main branch still works good.
Additionally, there is now Escape+p keymap that probably triggers this first one:
bind "Alt p" { TogglePaneInGroup; }
bind "Alt Shift p" { ToggleGroupMarking; }
I guess I have to disable it. Not that I read about the new commands anyway.