[4.1.0] - 2026-10-01
Added
- OSC 10 / 11 / 12 colour queries from panes (
OSC 11 ; ?is how Neovim and
others tell a dark theme from a light one) are answered with the host
terminal's default foreground, background and cursor colours, as
OSC N ; rgb:RRRR/GGGG/BBBBended like the query (BEL or ST). wtmux draws
every pane cell with the default colour, so these are the colours the pane
really shows. At startup, right after the VS16 width probe, wtmux asks the
host for the three colours followed by a CPR and reads up to the CPR (on
Unix straight from the tty, since crossterm's reader would take the
replies for key presses). With no host answer nothing is made up and the
query stays unanswered, as before. Setting a
colour is still ignored. Measured on WezTerm, Windows Terminal Preview 1.25
and the Ghostty Windows port: all three answer with 16-bitrgb:specs,
in query order and ahead of the CPR. The bundled OpenConsole forwards the
queries to wtmux; the inbox conhost swallows them. - Pane-side synchronized output (DEC mode 2026). A child that wraps a frame
inCSI ? 2026 h...CSI ? 2026 lno longer has its half-drawn frame
painted: the pane keeps showing what it last drew, output is still parsed
into the grid, and one render is released when the frame ends. The hold
also ends on RIS, on a real size change, when the session stops, and after
one second, so a child that never sends?2026lcannot freeze its pane
(the timeout clears the mode bit). A frame that begins and ends inside one
read is rendered as usual. Known limitations: a full redraw (the first
paint, a tab switch, a focus move between panes, which advances the
layout generation without changing any size, or a layout change that
keeps a pane's size) still paints the pane's current grid, and so do the
copy-mode view and popups, so a half-drawn frame can show until the frame
ends and the held lines are painted (the post-resize ConPTY replay window
has the same exception). How long that can last has not been measured;
the one-second cap bounds it. A resize ends the hold itself but not the
Windows ConPTY replay window that follows it. - DECRQM.
CSI ? Ps $ pandCSI Ps $ pare answered with
CSI [?] Ps ; Pm $ yfor the modes wtmux actually tracks (DEC 1, 7, 25,
47/1047/1049, 1004, 2004, 1000/1002/1003/1006/1015, 2026, 9001; ANSI 4 and
20): 1 = set, 2 = reset. Every other mode reports 0 (not recognized) rather
than promising behavior wtmux lacks; 47, 1047 and 1049 all report whether
the alternate screen is active. The sequence is recognized only with
exactly$(or? $) as intermediates, so DECSTR and DECSCL are
unaffected, and a colon subparameter is rejected. Measured 2026-10-01: the
bundled OpenConsole forwards these queries (and?2026h/l, OSC 10/11,
XTVERSION) to wtmux, while the inbox conhost answers DA1, DECRQM and CPR
itself and swallows OSC 10/11, so the answers matter with the bundled
ConPTY.
Fixed
- A
conpty.dllwithoutOpenConsole.exenext to it was reported as a
bundled ConPTY while the pane silently ran on the inbox conhost.
Measured:CreatePseudoConsolesucceeds without error in that case, and
the output is the inbox conhost's. wtmux now uses a directory only when it
holds both files; a loneconpty.dllis skipped with a warning on stderr
and the next candidate (finally kernel32) is tried, sowtmux --version
and the host actually in use agree. The Inno Setup installer script had
skipifsourcedoesntexiston each file separately and could package the
DLL alone;build-inno-installer.ps1now passes/DBundleConPtyonly
whenvendor\conptyholds the pair (compilingwtmux.issby hand
bundles nothing). The other packaging scripts already required both.
Only the presence of the pair is checked, not that their versions match. - Resizing a pane narrower could push the prompt down by rows of nothing.
The rewrap counted a row's trailing spaces as content, so a row cleared by
writing spaces across its whole width (which is how the OpenConsole host
clears a line) became two or three rows. Measured on the inbox conhost and
the bundled OpenConsole, which agree: the last row of a logical line does
not count its trailing spaces (whatever their attributes), rows that wrap
on keep their full width, and a wrapped line whose tail vanishes keeps one
extra empty row when its content ends exactly on the new width, with the
cursor following onto it.ConsoleBuffer(the Windows default) follows
this exactly;LocalReflowdrops only spaces with default attributes, so
a background-coloured run survives. Not reproduced: three cursor
positions at very small widths (160 spaces to 20 columns, 240 to 30 and
20), where the console lands above where its own wrapping puts the end of
the text and no rule is known.