Summary
Keys that carry modifiers do not reach terminal programs. In particular Ctrl+C does not interrupt the running process, and TUI keybindings (Ctrl+P/Ctrl+N/Ctrl+D/Ctrl+W and similar) do nothing or trigger the client's own shortcut instead. Plain text typing does reach the shell, so the terminal stream and sendTyped path work; the problem is the OnKey/client.key path.
Expected: a key pressed in a focused terminal pane, including Ctrl+C, goes to Rex through client.key so Rex's Lua keymap gets the first chance and then the program receives it, exactly as in Rex.app. Custom Rex bindings and sequences (rex.bind("ctrl+b>c", ...)) should work too.
Actual: modifier keys appear to be swallowed by the client. Ctrl+C leaves a foreground process running, and TUIs never see their modifier bindings.
Reproduce
- Start a Rex server and
rexnux, and open a session with a shell. - Run
sleep 300, then pressCtrl+C. The process keeps running. - Run a TUI with modifier bindings (
btop,lazygit,vim, etc.) and press them. The binding does not fire; some open the palette or split/close a pane instead. - Add a custom Rex key sequence (
rex.bind("ctrl+b>c", "window.new")) and press it. It never fires.
Ordinary typing (echo hi) works and appears in the Rex capture, so this is specific to modified/special keys.
Suspects in this client
internal/ui/workspace.go(appShortcut): unconditionally takesCtrl/Cmd+K,P,N,T,D,Wand,inside every terminal. That is exactly the set many TUIs bind (Ctrl+Pin fzf/vim,Ctrl+N/Ctrl+Din shells and editors,Ctrl+Win readline), so those can never reach the program.internal/ui/term.go(ensureTerm->OnKey): sends onlyaction: "press"events and never releases. It also has no path for Rex key sequences (prefix), so customrex.bind("ctrl+b>c")bindings cannot work.internal/ui/workspace.go(terminalBlock): callstv.Focus()only whenview.ActiveWindowID == w.WindowIDand the block matchesw.FocusedBlockIDora.focusBlock. A stale view, a preview/peek window, or a pane-tab group can leave no terminal focused, in which caseOnKeyis never called at all. Worth checking that the active terminal always owns keyboard focus, and that clicking a pane re-focuses its terminal (not just the Rexfocus_blockcall).internal/rex/api.go(Client.Key):KeyEventhas noprefixfield. Rex documentsprefixfor multi-key bindings; without it the server can never resolve a sequence.internal/ui/term.go(keyInfo): maps Ctrl+letters tokey_*with emptytext, which matches the API doc's example, but it should be checked against a real server while fixing this.
Related: #2 is the same input-routing problem for pointer events. Maybe both should be fixed together, since both come from the terminal element's input handling versus the pane card's own handlers.
Environment
- rexnux
76952ad(main, after #6) - MyGo v0.7.4, terminal plugin (libghostty-vt)
- Go 1.27.3
- Linux/Wayland, Hyprland
- Rex server 0.1.0-preview.12, API revision 8