- SGR (1006) release events now carry the same button number as the
press ('m' suffix marks release); the legacy 'button 3 = release'
is only used for X10/UTF8 encodings. ncurses apps (htop etc.) could
not pair press+release before, so clicks were ignored while scroll
(press-only wheel events) worked
- Each window keeps its recent raw PTY output (capped at 512 KB); on
resize the history is replayed into a fresh parser at the new width
so long lines re-wrap correctly instead of keeping old break points
- Integration: release-button and reflow checks, 33/33 passing
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- New spawn_settings action + '≡ Inställningar' button in the default
panel (≡ instead of ⚙ which has ambiguous character width): opens a
singleton settings window
- Rows: theme (cycles built-in + themes/*.toml), panel (cycles
panels/*.toml), shadow and scrollbar toggles — keyboard (arrows/
Enter/Esc) and mouse (click selects, click again activates)
- Shows where config.toml, themes/ and panels/ live
- Changes apply immediately and persist to config.toml via toml_edit;
the hot-reload watcher picks up the file writes for panels
- README and --help updated with switcher/snap/copy-mode/theme docs
- Integration suite: 30/30 (gear click, dialog opens, shadow toggle
persisted to config.toml)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- alt+c enters copy-mode on the focused terminal: arrows/PgUp/PgDn/
Home/End scroll the history, / searches (matches highlighted in the
view), n/N jump between hits, q/Esc exits back to the bottom.
Status line shows position and key help
- config.toml, panel files and the theme file are watched (1s mtime
poll): edits reload theme/panels/keybinds live without restarting —
windows and focus are untouched
- Integration suite runs the daemon in an isolated config dir and
covers copy-mode search and panel hot-reload — 27/27 passing
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- window_switcher action: overlay listing windows in most-recently-used
order; Tab/arrows cycle, Enter confirms, Esc cancels. Bound to
alt+tab with alt+w as fallback for terminals that swallow alt+tab
- snap_left/snap_right actions (alt+left/alt+right) tile the focused
window to half the content area; dragging a window to the screen
edge snaps it too
- maximize action (alt+up) toggles maximize/restore, double-click on
the title bar does the same; restore returns the pre-snap geometry
- Panel: separator between focus dot and buttons, separators between
right-docked status widgets, and item widths now use display width
(fixes rects for åäö/wide labels)
- Integration suite: 23 checks, all passing
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Theme is now a runtime struct loaded from its own TOML file
(theme = "themes/dark.toml" in config.toml, like panels), all
fields optional with built-in defaults; ships themes/dark.toml and
themes/light.toml
- shadow = true/false in config.toml, shadow_color per theme
- dim_unfocused (per theme): unfocused window content is dimmed
- BUGFIX: resizing a window no longer erases its content and history —
the vt100 parser was recreated on every resize; now uses
screen_mut().set_size() which preserves the grid and scrollback
- New integration check: window content survives mouse resize (20/20)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dropping the client's channel sender never closed the socket (the
server's reader thread keeps the connection open), so the client froze
waiting for frames. The server now sends a bye message; the client
exits cleanly on it and its socket close lets the server clean up.
Messages from already-disconnected clients are ignored. Verified
end-to-end with the real client in a PTY (exits 0, daemon survives).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- -h/--help prints a full usage overview (modes, config keys, keys, mouse)
- Run dialog now executes the typed command directly in the new window
(previously it spawned the default shell and typed the command into
it, which showed up as just an empty terminal)
- Virtual terminals get vt100 scrollback (config scrollback_lines,
default 1000): mouse wheel scrolls history when the app doesn't
capture the mouse, arrow-key fallback on the alternate screen, any
keypress jumps back to the bottom; optional scrollbar on the right
border (show_scrollbar) plus configurable default_window_size
- Exit triggered from a connected display client (ctrl+q / panel
button) now only disconnects that client — the daemon/standalone
session and its programs keep running
- Windows now paint the border zone in the desktop background color so
rounded corners actually look rounded instead of a filled square
with an inner rounded frame; popup dialogs rounded too
- Integration suite extended to 19 checks (scrollback, run dialog,
client-safe exit) — all passing
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Wide characters shifted everything after them one column to the right:
- render.rs: vt100's empty wide-continuation cell was padded to a
space, making wide chars occupy 2+1 columns — skip it entirely
- ipc.rs buffer_to_ansi: same bug for daemon frames — skip cells
covered by a preceding wide symbol (unicode-width)
- app.rs: clamp virtual terminals to >= 2 columns (vt100 0.16 has a
subtraction underflow panic on wide chars in a 1-col grid) and give
content_area a sane 80x24 default so windows spawned before the
first layout pass aren't degenerate
- main.rs: use try_send for display frames so one slow/stalled client
can no longer freeze the whole WM
- integration test: new end-to-end check that emoji do not shift the
row, plus fix a false match against the window title
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- New key_event/mouse_event client messages (crossterm serde) that run
through the complete WM event handling on the server — remote clients
get window focus, drag/resize and mouse forwarding into virtual
terminals (SGR/UTF-8/X10) identical to standalone mode
- tui-wm -c now forwards mouse events; previously only keyboard worked
remotely
- IPC unit tests + end-to-end integration test (tests/integration.py):
daemon, frames, click/scroll SGR forwarding, popups, TUI-FM in a
window — 12/12 passing
- Document the new messages in SOCKET_API.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>