v1.1.0
The first release driven by an outside report. Both features here come from #363, filed by @thachck: the sidebar layout not surviving a restart, and yanking being useless over SSH. Two small quality-of-life asks that each turned out to sit on top of a real defect.
The SSH one is worth spelling out, because it was not a plain failure. gwm only
ever shelled out to the host clipboard binaries, which write to the clipboard of
the machine gwm runs on. Over SSH to a macOS host, pbcopy is found, runs,
and exits 0 - so gwm reported yanked branch name (pbcopy) while the text sat in
a clipboard nobody could reach. A success message and an empty clipboard is worse
than an error, and it is also why the obvious design (“fall back to OSC52 when no
tool is found”) would never have fired: a tool was found, and it did succeed.
Chasing both reports surfaced three further defects that predated them - the sidebar layout being dropped on a workspace repo swap, the Settings selection walking off screen on a short terminal, and the sidebar docs naming keys that have been wrong since #290. All are fixed below.
-
[tui] clipboard- OSC52 so yanking works over SSH (#367, #368; part of #363, reported by @thachck).[tui]clipboard = "auto" # auto (default) | osc52 | toolsautoemits an OSC52 escape sequence when$SSH_TTY/$SSH_CONNECTIONis set - handing the text to the terminal emulator, which owns the clipboard you actually paste from - and uses the host tools otherwise.osc52andtoolsforce either path. Covers all four yanks (path, branch, worktree name, command logs). The status bar names the route that ran ((osc52)/(pbcopy)).Under tmux the sequence is wrapped in DCS passthrough; inside GNU screen gwm falls back to the host tools rather than emit a sequence screen would silently swallow. Payloads over 64 KiB are refused rather than truncated into a corrupt paste. Framing and base64 come from crossterm’s
CopyToClipboard(featureosc52) rather than being hand-rolled. -
[tui] sidebar_orientation- persist the sidebar layout (#365, #366; part of #363, reported by @thachck).[tui]sidebar_orientation = "stacked" # auto | side-by-side | stackedThe orientation was runtime-only and reset on every launch; only
sidebar_positionsurvived a restart. It is now seeded at startup and on config reload, and editable from the Settings panel’s TUI tab. Default staysstacked(the #217 launch layout). Unknown values are a hard error at load time, consistent withsidebar_positionandtui.open.mode.
-
The sidebar layout was ignored when switching repos in workspace mode (#366).
sync_active_reporeplaced the active config wholesale without re-deriving the sidebar from it, so a per-repo[tui]override did not apply until a reload or relaunch. This hole predated the new key:sidebar_positionhad it since workspace mode landed (#36). Both knobs now go through one shared apply, called from all three sites where the config becomes authoritative. -
The Settings selection could walk off screen on a short terminal (#368). The modal is 60% of the terminal height, so 24 lines leave about six body rows - but the renderer only scrolled the selection into view on the Keys tab, on the stated reasoning that the field tabs were “short enough to never need this”. They were not: the sixth TUI field was already off screen at 24 lines, letting you cycle and edit a setting you could not see. The existing mechanism is now used by every tab with a selection; the Worktree tab benefited too.
-
The sidebar docs named the wrong keybindings (#366). The defaults are
v(position),Space(cycle layout) andV(show/hide), but the docs saidHtoggles the position andVcycles the layout.Hhas not done that since #290 gaveh/Hto the user macros - a reader following the docs would fire a macro or hide the sidebar. Corrected across the example template, both locales, and the doc-comments. -
The oversized-clipboard message contradicted itself (#368). Truncating division rendered 65 537 bytes as
64 KiB > 64 KiB, exactly when refusing the copy. -
SidebarState::orientationdoc-comment claimed the default wasauto(#365). It has beenstackedsince #217 - live documentation of a default that did not exist, and the kind of stale comment that talks the next person into seeding the wrong value.
Changed
Section titled “Changed”- The Settings choice lists are derived from their enums
(#366). The panel writes the
selected choice verbatim into
.gwm.toml, so a list that drifted from the enum’s serde spelling would make the panel produce a file that no longer loads.label()is now aconst fnand the lists are built from it, making that drift impossible to express.
Dependencies
Section titled “Dependencies”- Bumped
regex1.12.4 → 1.13.0 (#364). crosstermgains theosc52feature, which pullsbase640.22 transitively.cargo audit --deny warningsstays clean.
Compatibility
Section titled “Compatibility”No breaking change. Both additions are new keys inside the existing [tui]
section, which the stability policy
treats as additive.
One behaviour change worth flagging: clipboard defaults to auto, so yanking
while SSH’d now routes through OSC52 instead of the remote host’s clipboard.
That is the reported bug being fixed, but if you want the remote clipboard,
clipboard = "tools" restores the previous behaviour exactly.
Known limits
Section titled “Known limits”OSC52 is never acknowledged by the terminal - gwm can report that it emitted the sequence, never that the terminal took it. Three consequences, all documented in the schema reference:
- tmux needs
set -g allow-passthrough on(off by default since tmux 3.3). The DCS wrapper is necessary but not sufficient, and gwm cannot enable it. $SSH_CONNECTIONcan be stale inside a tmux pane, soautocan guess wrong.clipboard = "osc52"/"tools"override the detection.- Terminal support varies - kitty, WezTerm, Alacritty and iTerm2 (with the setting enabled) honour OSC52; Terminal.app does not.
The OSC52 decision logic, escape framing and tmux wrapping are pinned
byte-for-byte by tests, with the base64 vectors verified against the system
base64 rather than only against the library that produces them. A real
SSH → tmux → terminal round-trip was not exercised before release: there is
no SSH host in the build environment and no acknowledgement to assert against.
If it misbehaves in your setup, please reopen
#363.