Commit Graph

1003 Commits

Author SHA1 Message Date
Michael Grant
f44699a18c Merge branch 'redraw-damage-rectangles' into 4902-image-support
Brings in the WezTerm/ghostty/Windows Terminal DECSLRM (margins) coverage
from margins-terminal-detection (PR #5630), via redraw-damage-rectangles.

Two conflicts, both simple bit-flag/list collisions from independent work
on both sides adding something at the same slot:
- tmux.h: this branch's own TERM_KITTY/TERM_IMAGE_QUADRANTS/
  TERM_IMAGE_SEXTANTS (0x100/0x200/0x400) collided with upstream's new
  TERM_NOREPLACE, also assigned 0x100. Kept this branch's existing values
  (already used throughout image.c/tty-features.c) and moved
  TERM_NOREPLACE to the next free bit, 0x800 - confirmed no other code
  references the literal 0x100 value for TERM_NOREPLACE, only the symbol.
- tty-features.c: this branch's own WezTerm entry (added "sixel") and the
  incoming margins-terminal-detection change (added "margins") both
  touched the same line - combined both.

Verified: build clean with --enable-images (image_support confirmed 1);
this branch's own image-kitty-region-scroll.sh/image-sixel-region-scroll.sh
plus this session's other prompt/cross-client/margins tests all pass (3x
each); full regress suite run pending/clean per standard practice for
this branch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 08:59:12 +01:00
Michael Grant
238067acbf Merge branch 'margins-terminal-detection' into redraw-damage-rectangles
Brings in the WezTerm/ghostty/Windows Terminal DECSLRM (margins) coverage
from margins-terminal-detection (PR #5630), plus whatever independent
upstream progress that branch's master base had accumulated since this
branch last merged from master.

Conflict in screen-redraw.c's redraw_draw_pane_prompt(): this branch's own
earlier refactor (extracting redraw_make_pane_prompt(), reused by both the
normal redraw path and the Finding-2 damage-composition fix) collided with
an independent upstream fix on master (nicm, "Get x and y the right way
round, fixes crash when opening a mode prompt when the client is offset
into the window") that swapped tty_draw_line()'s px/py argument order in
this same function - this branch had diverged before that fix landed and
still had the pre-fix (buggy) order. Resolved by keeping this branch's
own refactor with the corrected argument order, verified against
tty_draw_line()'s signature (px, py - the prompt's screen is always
exactly one row, so py must be 0 and px must be the horizontal offset;
the pre-fix order passed the offset as the row instead, matching the
described crash). The other, structurally identical call site added this
session for Finding 2 (redraw_damage_draw_pane_prompt()) already had the
correct order and needed no change.

Verified: build clean; the new tty-margins-wt-session.sh and this
session's existing wide-character/prompt/cross-client tests all pass
(3x each); full regress suite passes clean twice, with only the same
pre-existing, unrelated failures already characterized this session
(prompt-words-history.sh, and untracked image-*-noflash scratch tests
from unrelated work, absent from this branch's own tracked suite).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 08:49:27 +01:00
tmux update bot
fca57a5fc9 Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Add a feature for mintty's application escape to avoid dodgy terminals whinging about not supporting it, GitHub issue 5626 from Pete Dietl.
  Only rely on the previous line wrapping when the cursor is actually on it, GitHub issue 5625 from Ben Maurer.
  Correctly write Z indexes to v2 layouts if zoomed, GitHub issue 5624.
  Do not leak waiting clients (in wait-for) if they are killed, GitHub issue 5614.
2026-09-22 11:58:43 +00:00
nicm
0e1f6ed80d Do not leak waiting clients (in wait-for) if they are killed, GitHub
issue 5614.
2026-09-22 11:58:41 +00:00
Michael Grant
bdd781770d Merge branch 'redraw-damage-rectangles' into 4902-image-support
# Conflicts:
#	server-client.c
2026-09-22 11:06:22 +01:00
Michael Grant
104a0cee99 server-client: fix damage being composed twice per redraw pass
`(~c->flags & CLIENT_ALLREDRAWFLAGS)` - for a multi-bit mask, ~x & MASK
means "at least one of these bits is unset" (almost always true), not
"none of these bits are set" as the comment and surrounding logic
clearly intend. Every floating-pane drag command unconditionally sets
CLIENT_REDRAWBORDERS (server_redraw_window_borders(), called from
cmd-resize-pane.c/cmd-join-pane.c/cmd-split-window.c) alongside
reporting window damage, so this fallback fired on every single drag
step: redraw_client_damage(c) ran here, then ran again a few lines
later at the CLIENT_ALLREDRAWFLAGS block for the exact same
rectangles. Confirmed via the server's own -vv log: a 6-step drag
produced 12 "composing damage" lines in matched pairs (identical
position and size, milliseconds apart) with no fix, 6 with it.

No memory-safety issue - redraw_client_damage() only reads w->damage,
never frees it - just wasted work rendering the same rectangles twice
per pass.

Fix: `(c->flags & CLIENT_ALLREDRAWFLAGS) == 0`, matching the comment's
actual intent.

regress/floating-pane-drag-no-double-composite.sh drags a floating
pane and asserts no two consecutive "composing damage" log lines share
the same position and size (comparing both together, since distinct
drag steps commonly share the same rectangle size and only the
position differs). Verified failing 3/3 against the pre-fix code (all
6 rectangles doubled each run) and passing 5/5 against the fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 10:09:28 +01:00
Michael Grant
a7f74730d7 server-client: don't let a drag's own sync-start defer its redraw
server_client_key_callback()'s mouse-drag dispatch opens a
synchronized-output frame (tty_sync_start()) before running the drag
callback, on every single drag motion event - deliberately, so a fast-
path write and any later damage-composed correction land in one atomic
terminal update instead of two visible frames. But
server_client_check_redraw() later in the same pass checks
EVBUFFER_LENGTH(tty->out) != 0 to decide whether to defer this pass's
redraw, and nothing drains tty->out in between (the actual write
happens later, via libevent) - so the frame-open sequence just queued
(8 bytes: "\033[?2026h" on a synchronized-output-capable terminal)
makes that check see "outstanding output" and defer against itself,
escalating the drag's damage to a full-window redraw on every single
motion event. Confirmed via the server's own -vv log: a 6-step drag
produced five "redraw deferred (8 left)" lines, one per motion event,
with no fix.

Fix: record how much was already queued at the instant the sync frame
opened (tty->sync_offset), and have the redraw check discount
anything queued after that point - it's already part of the frame
this pass is committed to flushing, not a reason to defer. If the
buffer was genuinely non-empty before the frame opened, sync_offset
holds that real backlog and deferral still happens correctly.

regress/floating-pane-drag-sync-no-self-defer.sh drags a floating pane
on a synchronized-output-capable terminal and asserts the server log
never shows the self-inflicted 8-byte deferral. Verified failing 3/3
against the pre-fix code (5 occurrences per run, matching the manual
-vv repro) and passing 5/5 against the fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 10:06:09 +01:00
Michael Grant
12d61d2e8c Merge branch 'master' into 4902-image-support
# Conflicts:
#	popup.c
#	screen-redraw.c
#	tmux.h
#	tty.c
#	window.c
2026-09-22 03:40:06 +01:00
Michael Grant
ac4daa57c9 Merge branch 'master' into redraw-damage-rectangles
# Conflicts:
#	popup.c
#	screen-redraw.c
#	tmux.h
#	tty.c
#	window.c
2026-09-21 23:25:01 +01:00
Nicholas Marriott
5aa17a0cfa Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Remove popups and all the associated overlay machinery (they were the last user of it). display-popup stays but becomes an (undocumented) compatibility command to open a floating pane.
  Fix typo (too few 0s) in CLIENT_CONTROL_DISCARD, from someone in GitHub issue 5622.
2026-09-21 12:03:10 +01:00
nicm
34cd5da4e3 Remove popups and all the associated overlay machinery (they were the last user
of it). display-popup stays but becomes an (undocumented) compatibility command
to open a floating pane.
2026-09-21 11:01:12 +00:00
Nicholas Marriott
541ca0e844 Merge branch 'master' into redraw-damage-rectangles 2026-09-21 11:09:55 +01:00
Michael Grant
729c361aad screen-redraw: stop floating-pane drags from clobbering unrelated panes
window_pane_redraw_floating() (called by every floating-pane drag/resize
command) had two conflicting redraw paths: a precise damage-rectangle
path for the dragged pane, and an unconditional server_redraw_window()
added to fix border-status recomposition (aa6b52ef) that silently
defeated it, redrawing every pane - including retransmitting unrelated
images - on every drag tick.

Chasing the border-status bug back further: it was actually caused by
an upstream regression (824a0729) that split CLIENT_REDRAWWINDOW's
redraw flags into REDRAW_ALL vs. REDRAW_ALL & ~REDRAW_OVERLAY, silently
breaking every literal `flags == REDRAW_ALL` check downstream
(REDRAW_IS_ALL()), including the one that decides whether a pane's
border-status title should be forced to recompose even when its text
hasn't logically changed. Fix this properly instead of reaching for
server_redraw_window() again: decouple overlay-drawing from the shared
flags value (it's only ever read in the one place that repaints an
overlay) so redraw_screen() can pass a genuinely literal REDRAW_ALL for
a window redraw. This also fixes a second-client-attach bug where a new
client's pane titles never appeared until their text changed, since the
per-pane title cache is shared across clients.

Also fixed a real, independent bug in server-client.c found along the
way: `~c->flags & CLIENT_ALLREDRAWFLAGS` is a 6-bit mask, so `~x & MASK`
tests "any bit unset" (almost always true) rather than "no bits set" as
intended - causing damage to be composed and transmitted twice on every
floating-drag tick.

With server_redraw_window() gone, a second problem surfaced: deferred
client redraws (common under a busy tty) still escalated any pending
window damage to a full CLIENT_REDRAWWINDOW redraw, because
server_client_loop() frees w->damage unconditionally every pass with no
tracking of whether a deferred client actually got to consume it. Fix
this by giving each client a copy of missed damage (c->pending_damage,
reusing the existing merge/collapse/16-entry-cap logic damage lists
already have) keyed by the window's id, so a client can compose it
precisely on a later pass instead of resending everything. Window ids
are monotonic and never reused, so a stale id is enough to detect and
discard damage left over from a window the client has since switched
away from or that has been destroyed.

Verified with regress/image-border-status-wipe.sh,
regress/floating-pane-drag-scrollbar-strip.sh,
regress/image-movepane-drag-noflash.sh, and
regress/image-splitwindow-resize-noflash.sh (5 runs each), the full
regress suite (twice), an ASAN/UBSAN debug build, and manual repros for
a window switch and a window destroy mid-defer.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 05:00:13 +01:00
Michael Grant
ec7f768c3a Merge branch 'master' into 4902-image-support
# Conflicts:
#	screen-redraw.c
2026-09-20 16:45:45 +01:00
tmux update bot
a958883625 Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Add remain-on-exit failed-key and a -D flag to new-pane to have a modal pane wait for Escape/C-c. Both to allow better compatibility with popups.
2026-09-10 13:04:13 +00:00
nicm
d202aa7ac1 Add remain-on-exit failed-key and a -D flag to new-pane to have a modal
pane wait for Escape/C-c. Both to allow better compatibility with
popups.
2026-09-10 13:04:11 +00:00
Nicholas Marriott
80e87aaf16 Merge branch 'master' into redraw-damage-rectangles 2026-09-09 14:05:48 +01:00
tmux update bot
1b87cb752e Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Add new-layouts flag for control clients so they can default to old layouts for backwards compatibility.
2026-09-08 11:38:06 +00:00
nicm
d9692f7ecf Add new-layouts flag for control clients so they can default to old
layouts for backwards compatibility.
2026-09-08 11:38:04 +00:00
tmux update bot
ca34d190b5 Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Do not allow cursor on/off to escape synchronized updates.
2026-09-01 23:20:22 +00:00
nicm
57a13664cc Do not allow cursor on/off to escape synchronized updates. 2026-09-01 23:20:20 +00:00
tmux update bot
dd31900f80 Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Ignore focus events earlier to avoid them interfering with prefix, GitHub issue 5539.
2026-08-28 09:02:23 +00:00
nicm
013ada58c8 Ignore focus events earlier to avoid them interfering with prefix,
GitHub issue 5539.
2026-08-28 09:02:22 +00:00
Michael Grant
48e33179d4 server-client, popup, screen-redraw: fix damage-system regressions
Fixes the four bugs caught by the regression tests added in aed1209c
(popup-drag-status-line.sh, popup-drag-wide-character.sh,
popup-drag-pane-prompt.sh, switch-client-redraw.sh), based on fixes
from Michael K. Darling (github.com/darlingm/tmux, pr5516-regression-
fixes), reviewed and adapted:

- server-client.c: server_client_set_session()'s check for whether the
  client's window actually changed compared old->curw to s->curw, but
  when old == s these read the same, already-updated field, so a
  same-session window switch was never detected. Compare against the
  client's own cached redraw scene instead (redraw_client_has_window(),
  new in screen-redraw.c/tmux.h). Taken from darlingm as-is.

- popup.c: popup_damage() only translated a popup's client-coordinate
  rectangle into window coordinates, so a popup dragged across the
  status line never triggered a status-line redraw once it moved away -
  status_redraw()'s own "skip if content unchanged" optimization
  suppressed it, since only the popup moved, not the status content.
  Now detects overlap with the status line and forces a redraw via the
  existing (previously unused) CLIENT_REDRAWSTATUSALWAYS flag, and
  properly clips the reported rectangle to the pane area for
  status-at-top/bottom/off. Taken from darlingm as-is.

- screen-redraw.c: redraw_draw_damage_rect() clipped a span to a damage
  rectangle's raw geometric edges, which have no idea what's in the
  grid, so a clip edge could land mid-character and tear a wide
  character in half. Added redraw_damage_grow_span_clip(): widen the
  clip by one cell on each edge that isn't already at the span's own
  boundary. Reimplemented simpler than darlingm's version (which walked
  grid cells per span type via a switch and direct grid lookups) -
  since no grid cell is ever wider than two columns, an unconditional
  one-cell margin is always enough to pull a split character back in,
  with no need to inspect grid content at all.

- screen-redraw.c: redraw_draw_damage_rect() also never re-overlaid a
  pane's active in-pane prompt after drawing its underlying content, so
  damage crossing a prompt row erased it until an unrelated redraw
  restored it. Factored the existing full-redraw prompt-building code
  into a shared redraw_make_pane_prompt() helper and added
  redraw_damage_draw_pane_prompt(), which recomposes the prompt over
  the drawn range. Taken from darlingm as-is.

All 9 regression tests in regress/ now pass. redraw_damage_grow_span_clip
was verified independently by disabling it and confirming
popup-drag-wide-character.sh reproduces its original failure.

Co-Authored-By: Michael K. Darling <darlingm@gmail.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 10:25:29 +01:00
tmux update bot
eb77a75ab7 Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Do not leak exit message on client free, from Jeong, Heon.
  Tidy up args_make_commands reference counting to fix a memory leak, from Jeong, Heon.
2026-08-25 07:59:42 +00:00
nicm
0851650c6b Do not leak exit message on client free, from Jeong, Heon. 2026-08-25 07:59:40 +00:00
Michael Grant
6739bd03f5 Merge remote-tracking branch 'origin/master' into redraw-damage-rectangles
# Conflicts:
#	server-client.c
#	window.c
2026-08-25 08:08:17 +01:00
tmux update bot
af29c080ba Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Correct a comparison ('\0' should be 0).
  If a pane has no scrollbar, don't bother to redraw it, and if redraw is deferred change scrollbar redraws into redraw-all-scrollbars not redraw entire window. GitHub issue 5529.
2026-08-25 01:46:56 +00:00
nicm
2d5328a860 If a pane has no scrollbar, don't bother to redraw it, and if redraw is
deferred change scrollbar redraws into redraw-all-scrollbars not redraw
entire window. GitHub issue 5529.
2026-08-25 01:46:55 +00:00
Michael Grant
f66eeef8a5 Added a fallback in server_client_check_redraw() as recommended by codex to catch an unserviced edge-case. 2026-08-24 13:36:34 +01:00
tmux update bot
f763f94556 Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Do not leak cached status line, from Jeong, Heon.
  Free pane fallback range when freeing pane, from Jeong, Heon.
  Do not leak path when destroying client, from Jeong, Heon.
  Do not leak format when drawing preview, from Jeong, Heon.
  Do not leak buffer name on failure, from Jeong, Heon.
2026-08-24 08:28:15 +00:00
nicm
4cabc2ae85 Do not leak path when destroying client, from Jeong, Heon. 2026-08-24 08:28:13 +00:00
Michael Grant
48cdd85886 server-client: consume window damage during the normal redraw pass
redraw_client_damage() (added previously, unused until now) is called
from server_client_check_redraw()'s normal redraw pass, and
server_client_any_pane_redraw() now also checks for pending window
damage so a client with only damage (no PANE_REDRAW/PANE_REDRAWSCROLLBAR
flags) still gets its redraw pass run.

server_client_check_redraw() now returns whether the redraw was deferred
(waiting for outstanding tty output to drain) rather than performed. A
deferred redraw no longer escalates to a full CLIENT_REDRAWWINDOW to
avoid losing what was pending - server_client_loop() now only clears
PANE_REDRAW, PANE_REDRAWSCROLLBAR and window damage once every client
viewing a window actually drew this pass (tracked via a new per-window
redraw_deferred flag), otherwise they're left in place and retried in
their normal, narrowly-scoped form.

server_client_set_session() now redraws only if the client's session or
current window actually changed, not on every call (e.g. switch-client
-t= from clicking a pane name in the status line resolves here even
when nothing besides the active pane changed).

A drag callback's mouse_drag_update() now opens a sync region itself
(tty_sync_start()) before its first write, so a fast-path write it makes
directly and a later correction arriving via redraw_client_damage() end
up in the same atomic terminal update instead of two visible frames.
2026-08-22 16:36:25 +01:00
tmux update bot
8dfa903346 Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Add a way for floating panes to stay above zoom (-A) flag. Use by default for modal panes to match popups.
2026-08-20 12:57:29 +00:00
nicm
95a7170709 Add a way for floating panes to stay above zoom (-A) flag. Use by
default for modal panes to match popups.
2026-08-20 12:57:26 +00:00
tmux update bot
bf7bbba7ea Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Add a -K flag to new-pane to make a modal pane capture all keys like popups used to.
2026-08-19 13:10:09 +00:00
nicm
b28b1b7b9a Add a -K flag to new-pane to make a modal pane capture all keys like
popups used to.
2026-08-19 13:10:08 +00:00
tmux update bot
efaa1fe31c Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  If writing a file fails, propagate the error to the server via a new message. Use a client flag rather than bumping the protocol version. GitHub issue 5451.
  Add default terminal features for Rio, GitHub issue 5489 from Raphael Amorim.
2026-08-17 09:45:11 +00:00
nicm
1729bb8e8a If writing a file fails, propagate the error to the server via a new
message. Use a client flag rather than bumping the protocol version.
GitHub issue 5451.
2026-08-17 09:45:10 +00:00
tmux update bot
36381f0884 Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Do not attempt to drain write buffer on stuck clients, since it requires a weird dance to make libevent do it. Instead, just ignore the client and destroy the buffer normally if not drained in 10 seconds.
2026-08-04 15:37:15 +00:00
nicm
5cd1976a4a Do not attempt to drain write buffer on stuck clients, since it requires
a weird dance to make libevent do it. Instead, just ignore the client
and destroy the buffer normally if not drained in 10 seconds.
2026-08-04 15:37:14 +00:00
tmux update bot
7a431ec7b9 Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Do not let a stuck client prevent the server from exiting - give up after 10 seconds. GitHub issue 5444 from Ben Maurer.
2026-08-03 21:33:23 +00:00
nicm
114aa68082 Do not let a stuck client prevent the server from exiting - give up
after 10 seconds. GitHub issue 5444 from Ben Maurer.
2026-08-03 21:33:21 +00:00
tmux update bot
5534f1ac32 Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Store status position in new mouse event for menus so the position is correct later.
2026-07-28 15:09:08 +00:00
nicm
9f2c535909 Store status position in new mouse event for menus so the position is
correct later.
2026-07-28 15:09:07 +00:00
tmux update bot
242239b561 Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Add A modifier to cycle through a series of values, GitHub issue 5412 from Fernando Daciuk.
2026-07-22 15:11:40 +00:00
nicm
bd4ac02994 Add A modifier to cycle through a series of values, GitHub issue 5412
from Fernando Daciuk.
2026-07-22 15:11:38 +00:00
tmux update bot
7abb9af062 Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Clip floating panes exactly at window edge, don't let the border creep into the first outside column.
  Invalidate scene when window is resized.
  Add a -C flag to new-pane to have a modal pane close when the mouse is clicked outside it, GitHub issue 5400.
2026-07-21 15:06:24 +00:00
nicm
8bf2a4e807 Add a -C flag to new-pane to have a modal pane close when the mouse is
clicked outside it, GitHub issue 5400.
2026-07-21 15:06:22 +00:00
tmux update bot
6dacc024f0 Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master:
  Remove the active-pane flag for now, there are some gaps in how this works and I don't like it. May come back in a different form (maybe just for windows).
2026-07-17 14:08:10 +00:00