Fix mouse interactions in terminal.

This commit is contained in:
Greyson Parrelli
2026-08-13 11:46:48 -04:00
parent 71b3c93521
commit 2daeb6125f
4 changed files with 669 additions and 70 deletions
+27 -1
View File
@@ -113,7 +113,7 @@ Window.zig sidebar + GtkStack of views, tab management, shortcuts
View.zig one tab's content: its panes, their layout, and drag handling
Layout.zig the split tree: nodes, rearranging, GtkPaned materialization
Pane.zig content plus its header, drag source, and drop target
Terminal.zig GtkDrawingArea: Cairo/Pango renderer + input handling
Terminal.zig GtkDrawingArea: Cairo/Pango renderer, keyboard, mouse, selection
Browser.zig WebKitWebView plus a nav/address bar and a find bar
webkit.zig hand-written bindings for the WebKitGTK calls we make
Layouts.zig saved tab templates: model, JSON on disk, {{substitution}}
@@ -403,6 +403,7 @@ in principle, but a terminal grid is small.
| `Ctrl+Shift+W` | close the focused pane (closes the tab with its last one) |
| `Ctrl+Shift+←/→/↑/↓` | move the focused pane within its view |
| `Ctrl+Shift+V` | paste into a terminal (bracketed-paste aware, refuses unsafe pastes) |
| `Ctrl+Shift+C` | copy the terminal selection |
| `Ctrl+Shift+R` | rename the current tab (empty name = follow the terminal) |
| `Ctrl+Shift+Z` | zoom the focused pane to fill the tab, and back |
| `Ctrl+F` | find in the focused web page (web panes only — see [Find in page](#find-in-page)) |
@@ -418,6 +419,31 @@ competes with the content's own mouse handling.
Both add-pane shortcuts are also buttons in every pane header, which is how you
open a web view without remembering the chord.
## The mouse in a terminal
A terminal's pointer has two possible owners, and which one has it depends on
what is running.
Ordinarily it is the window's. Dragging selects text, double-click takes a
word and triple-click a line, `Ctrl` while dragging selects a rectangle, and
the wheel moves through the scrollback. Selecting fills the primary selection,
so middle-click pastes what was last highlighted; `Ctrl+Shift+C` puts it on the
clipboard proper.
But a full-screen program can ask for the mouse itself (DEC modes 1000-1003),
and from then on clicks, drags and wheel notches are encoded and handed
straight to it. That is what makes a TUI's buttons clickable and what makes
Claude Code scroll. While a program holds the pointer the cursor goes back to
an arrow, as a reminder that a drag will not select anything. **Holding shift
takes it back** for the length of that drag, so there is always a way to copy
text out of a full-screen application.
One case sits between the two. Pagers — `less`, `man`, anything built on them —
run on the alternate screen, which has no scrollback for the wheel to move
through, and most of them never ask for the mouse. There the wheel becomes
arrow keys (DEC mode 1007), which is what those programs are waiting for
anyway.
## Zoom
A split that was the right shape for watching two things at once is usually the