Replace the per-cell image marker with sparse placement spans attached to
grid lines. A placement owns all of its spans and records the input
protocol, application image and placement IDs, z-index, and creation order.
This retains overlapping image layers without storing a list in every grid
cell. Grid operations move, split, clip, and remove only the affected spans.
Use the input protocol to determine image/text interaction: later text
damages SIXEL spans, while Kitty placements remain and are ordered by their
z-index. Rendering then adapts that one logical scene for each client,
rather than changing its semantics according to whether the outer terminal
uses Kitty or SIXEL.
mage reference. Deferred pane redraws explain the intermittent “image never appears” behavior.
Fixed:
- Preserves image metadata while updating the text underlay in the collected ASCII path: grid.c:779
- Handles the single-cell/non-ASCII path and schedules an image redraw: screen-write.c:2631
- Uses the requested if/else for new_id.
- Adds a deterministic regression reproducing point (2): regress/image-support.sh:240
This matches Kitty’s requirement that normal text operations must not affect graphics; graphics require
explicit deletion. Kitty graphics protocol
Two more fixes based on Michael K. Darling's branch
(github.com/darlingm/tmux, pr5516-regression-fixes), taken as-is -
neither is caught by any test in regress/ yet, found by code review
rather than a failing test:
- screen_write_redraw_cb() (screen-write.c) reported damage for only a
single row, using ttyctx->ocy as if every fallback redraw were a
single-cell write. But it's also the callback for cases that can
legitimately span many rows - a large scroll-region fallback
(tty_redraw_region(), when tty_large_region() or the pane is
obscured), a full reset, and entering/leaving the alternate screen.
For those, only the top row of the affected area ever got marked as
damaged, leaving the rest stale until an unrelated redraw happened to
cover it. Changed the shared tty_ctx_redraw_cb typedef to carry
(py, ny) - the actual row range - and updated every call site to pass
the range it actually knows about, instead of hardcoding a single
row.
- window_pane_redraw_floating() (window.c) never refreshed the status
line after moving/resizing a floating pane, so a status format
depending on that pane's geometry (e.g. #{pane_width}) could go
stale until an unrelated status refresh happened. Added a
server_status_window(w) call.
Also confirmed the window_pane_scrollbar_intersects() parameter
naming cleanup (loop -> wp) discussed earlier was already done in an
earlier "Cleanup." commit - nothing left to do there.
All 9 tests in regress/ plus the two pre-existing floating-pane tests
plus a further 19-test sweep of redraw/tty/input/sync-adjacent
regress tests pass.
Co-Authored-By: Michael K. Darling <darlingm@gmail.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* refs/remotes/tmux-openbsd/master:
Always use synchronized updates in copy mode (like when not in the active pane), since copy mode will almost always moved the cursor. From Artem Goldenberg in GitHub issue 5525.
Introduce a per-window list of damaged rectangles (struct redraw_damage)
and redraw_damage_window() to record them, redraw_client_damage() to
consume them by composing exactly the damaged cells (via a new
redraw_draw_damage_rect(), which also force-refreshes any pane-status
span it touches, since window_make_pane_status()'s content-diff check
has no way to know the physical cells were disturbed by something else).
redraw_draw_span() now takes an explicit [clip_x, clip_x + clip_n) range
instead of always drawing a span's full width, so a damage rectangle can
redraw just the portion of a span it actually covers.
screen_write_redraw_cb() - the fallback when a write can't be applied
directly to the terminal - now reports damage for just the affected row
via this mechanism, instead of unconditionally flagging the whole pane
for a full redraw.
* refs/remotes/tmux-openbsd/master:
Store background colour in padding cells and correctly clear adjacent cells when tabs are overwritten, GitHu issue 5441 from Ayman Bagabas.
Exit failure on socket failure, from Rayan Salhab.
Pessimize compiler flags for screen-redraw.c to prevent tmux from dumping core upon startup on landisk.
* refs/remotes/tmux-openbsd/master:
Also set ntitles to 0 when creating screen in the first place.
Reset title count when freeing titles, GitHub issue 5429 from Brett Smith.
Do not loop forever if the combining character is too long, GitHub issue 5434 from me at qdrs dot dev.
* refs/remotes/tmux-openbsd/master:
Change cellused/size to 16 bits and time to 32 bits in grid_line and add the OSC 133 positions (size stays the same).
* refs/remotes/tmux-openbsd/master:
build: don't exit
build: always attempt portable merge
build: capture openbsd-base before filtering
build: fetch cutover master before merge
Use _exit in child after fork, from Yayo Razo in GitHub issue 5376.
Add missing calloc check and use fatal. Prompted by a similar change from Yayo Razo.
actions: use published openbsd-git as base update
github actions: automate updates
Do not make pty fds blocking again until all the data has been consumed or control mode clients can get stuck, GitHub issue 5356 from Ben Maurer.
Add formats and events for OSC 133 commmands, as well as a -T flag to set-hook -B to only fire when the format is true.
Replace the notification system with events. Events can carry a payload of additional payload (to reduce problems with lifetime of objects) and are delivered to one or more event sinks. This is more powerful and reduces the complex dependencies between control mode and hooks. Events are now used for hooks, control mode notifications and for monitors (set-hook -B).
additional payload (to reduce problems with lifetime of objects) and are
delivered to one or more event sinks. This is more powerful and reduces the
complex dependencies between control mode and hooks. Events are now used for
hooks, control mode notifications and for monitors (set-hook -B).
wait-for can now wait for an event to fire (-E flag, with -F to for filter),
with -v to print the payload, as well as listing (-l) waiting clients on an
event and forcing one to wake (-w).
A few additional hooks are also now available (pane-created, pane-resized, etc)
and some of the existing ones have additional format variables available.
replaces the previous "modal" behaviour where the pane would be resized,
which tended to make a mess. Instead, the scrollbar appears when
scrolling or when hovered over with the mouse and disappears a
(configurable) short period later. From Michael Grant.
is generated and cached in the client: it holds positions and sizes of
panes, borders and so on. The scene is invalidated when a pane is moved
or resized or relevant option is changed. This scene is then drawn to
the client as needed and text and colours are filled in. With Michael
Grant.