Merge branch 'master' into floating_panes

This commit is contained in:
Dane Jensen
2026-06-12 12:07:41 -07:00
7 changed files with 105 additions and 22 deletions

View File

@@ -63,7 +63,7 @@ tmux -vv -Ltest -f/dev/null new
Or if you need your configuration: Or if you need your configuration:
~~~base ~~~bash
tmux kill-server tmux kill-server
tmux -vv new tmux -vv new
~~~ ~~~

View File

@@ -70,6 +70,7 @@ cmd_send_keys_inject_key(struct cmdq_item *item, struct cmdq_item *after,
struct key_table *table = NULL; struct key_table *table = NULL;
struct key_binding *bd; struct key_binding *bd;
struct key_event *event; struct key_event *event;
struct cmdq_item *new_after = after;
if (args_has(args, 'K')) { if (args_has(args, 'K')) {
if (tc == NULL) if (tc == NULL)
@@ -77,10 +78,16 @@ cmd_send_keys_inject_key(struct cmdq_item *item, struct cmdq_item *after,
event = xcalloc(1, sizeof *event); event = xcalloc(1, sizeof *event);
event->key = key|KEYC_SENT; event->key = key|KEYC_SENT;
memset(&event->m, 0, sizeof event->m); memset(&event->m, 0, sizeof event->m);
if (server_client_handle_key(tc, event) == 0) { if (after == NULL) {
free(event->buf); if (server_client_handle_key(tc, event) != 0)
free(event); return (item);
} else {
if (server_client_handle_key_after(tc, event, after,
&new_after) != 0)
return (new_after);
} }
free(event->buf);
free(event);
return (item); return (item);
} }
@@ -229,8 +236,10 @@ cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item)
if (count == 0) { if (count == 0) {
if (args_has(args, 'N') || args_has(args, 'R')) if (args_has(args, 'N') || args_has(args, 'R'))
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
after = args_has(args, 'K') ? item : NULL;
for (; np != 0; np--) for (; np != 0; np--)
cmd_send_keys_inject_key(item, NULL, args, event->key); after = cmd_send_keys_inject_key(item, after, args,
event->key);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1161,7 +1161,8 @@ screen_write_redraw_line(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
ttyctx->ocx = cx; ttyctx->ocx = cx;
ttyctx->ocy = yy; ttyctx->ocy = yy;
tty_write(tty_cmd_cell, ttyctx); if (~s->mode & MODE_SYNC)
tty_write(tty_cmd_cell, ttyctx);
} }
} }
} }
@@ -1208,6 +1209,8 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx)
screen_write_initctx(ctx, &ttyctx, 1, 1); screen_write_initctx(ctx, &ttyctx, 1, 1);
if (s->mode & MODE_SYNC)
return;
if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) {
tty_write(tty_cmd_alignmenttest, &ttyctx); tty_write(tty_cmd_alignmenttest, &ttyctx);
return; return;
@@ -1247,6 +1250,8 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
screen_write_collect_flush(ctx, 0, __func__); screen_write_collect_flush(ctx, 0, __func__);
ttyctx.n = nx; ttyctx.n = nx;
if (s->mode & MODE_SYNC)
return;
if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) {
tty_write(tty_cmd_insertcharacter, &ttyctx); tty_write(tty_cmd_insertcharacter, &ttyctx);
return; return;
@@ -1286,6 +1291,8 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
screen_write_collect_flush(ctx, 0, __func__); screen_write_collect_flush(ctx, 0, __func__);
ttyctx.n = nx; ttyctx.n = nx;
if (s->mode & MODE_SYNC)
return;
if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) {
tty_write(tty_cmd_deletecharacter, &ttyctx); tty_write(tty_cmd_deletecharacter, &ttyctx);
return; return;
@@ -1325,6 +1332,8 @@ screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
screen_write_collect_flush(ctx, 0, __func__); screen_write_collect_flush(ctx, 0, __func__);
ttyctx.n = nx; ttyctx.n = nx;
if (s->mode & MODE_SYNC)
return;
if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) {
tty_write(tty_cmd_clearcharacter, &ttyctx); tty_write(tty_cmd_clearcharacter, &ttyctx);
return; return;
@@ -1364,6 +1373,8 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
screen_write_collect_flush(ctx, 0, __func__); screen_write_collect_flush(ctx, 0, __func__);
ttyctx.n = ny; ttyctx.n = ny;
if (s->mode & MODE_SYNC)
return;
if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) {
tty_write(tty_cmd_insertline, &ttyctx); tty_write(tty_cmd_insertline, &ttyctx);
return; return;
@@ -1389,6 +1400,8 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
screen_write_collect_flush(ctx, 0, __func__); screen_write_collect_flush(ctx, 0, __func__);
ttyctx.n = ny; ttyctx.n = ny;
if (s->mode & MODE_SYNC)
return;
if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) {
tty_write(tty_cmd_insertline, &ttyctx); tty_write(tty_cmd_insertline, &ttyctx);
return; return;
@@ -1428,6 +1441,8 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
screen_write_collect_flush(ctx, 0, __func__); screen_write_collect_flush(ctx, 0, __func__);
ttyctx.n = ny; ttyctx.n = ny;
if (s->mode & MODE_SYNC)
return;
if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) {
tty_write(tty_cmd_deleteline, &ttyctx); tty_write(tty_cmd_deleteline, &ttyctx);
return; return;
@@ -1453,6 +1468,8 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
screen_write_collect_flush(ctx, 0, __func__); screen_write_collect_flush(ctx, 0, __func__);
ttyctx.n = ny; ttyctx.n = ny;
if (s->mode & MODE_SYNC)
return;
if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) {
tty_write(tty_cmd_deleteline, &ttyctx); tty_write(tty_cmd_deleteline, &ttyctx);
return; return;
@@ -1594,6 +1611,8 @@ screen_write_reverseindex(struct screen_write_ctx *ctx, u_int bg)
screen_write_initctx(ctx, &ttyctx, 1, 1); screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg; ttyctx.bg = bg;
if (s->mode & MODE_SYNC)
return;
if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) {
tty_write(tty_cmd_reverseindex, &ttyctx); tty_write(tty_cmd_reverseindex, &ttyctx);
return; return;
@@ -1725,6 +1744,8 @@ screen_write_scrolldown(struct screen_write_ctx *ctx, u_int lines, u_int bg)
screen_write_collect_flush(ctx, 0, __func__); screen_write_collect_flush(ctx, 0, __func__);
ttyctx.n = lines; ttyctx.n = lines;
if (s->mode & MODE_SYNC)
return;
if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) { if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED || ctx->wp == NULL) {
tty_write(tty_cmd_scrolldown, &ttyctx); tty_write(tty_cmd_scrolldown, &ttyctx);
return; return;
@@ -1776,6 +1797,8 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
screen_write_collect_clear(ctx, s->cy + 1, sy - (s->cy + 1)); screen_write_collect_clear(ctx, s->cy + 1, sy - (s->cy + 1));
screen_write_collect_flush(ctx, 0, __func__); screen_write_collect_flush(ctx, 0, __func__);
if (s->mode & MODE_SYNC)
return;
if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED) { if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED) {
tty_write(tty_cmd_clearendofscreen, &ttyctx); tty_write(tty_cmd_clearendofscreen, &ttyctx);
return; return;
@@ -1850,6 +1873,8 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx, u_int bg)
screen_write_collect_clear(ctx, 0, s->cy); screen_write_collect_clear(ctx, 0, s->cy);
screen_write_collect_flush(ctx, 0, __func__); screen_write_collect_flush(ctx, 0, __func__);
if (s->mode & MODE_SYNC)
return;
if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED) { if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED) {
tty_write(tty_cmd_clearstartofscreen, &ttyctx); tty_write(tty_cmd_clearstartofscreen, &ttyctx);
return; return;
@@ -1923,6 +1948,8 @@ screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg)
screen_write_collect_clear(ctx, 0, sy); screen_write_collect_clear(ctx, 0, sy);
if (s->mode & MODE_SYNC)
return;
if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED) { if (~ttyctx.flags & TTY_CTX_PANE_OBSCURED) {
tty_write(tty_cmd_clearscreen, &ttyctx); tty_write(tty_cmd_clearscreen, &ttyctx);
return; return;
@@ -2579,7 +2606,8 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
if (s->mode & MODE_INSERT) { if (s->mode & MODE_INSERT) {
screen_write_collect_flush(ctx, 0, __func__); screen_write_collect_flush(ctx, 0, __func__);
ttyctx.n = width; ttyctx.n = width;
tty_write(tty_cmd_insertcharacter, &ttyctx); if (~s->mode & MODE_SYNC)
tty_write(tty_cmd_insertcharacter, &ttyctx);
} }
/* If not writing, done now. */ /* If not writing, done now. */
@@ -2603,7 +2631,8 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
for (i = 0, vis = 0; i < r->used; i++) for (i = 0, vis = 0; i < r->used; i++)
vis += r->ranges[i].nx; vis += r->ranges[i].nx;
if (vis >= width) { if (vis >= width) {
tty_write(tty_cmd_cell, &ttyctx); if (~s->mode & MODE_SYNC)
tty_write(tty_cmd_cell, &ttyctx);
return; return;
} }
@@ -2612,6 +2641,8 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
* spaces in the visible regions. * spaces in the visible regions.
*/ */
utf8_set(&tmp_gc.data, ' '); utf8_set(&tmp_gc.data, ' ');
if (s->mode & MODE_SYNC)
return;
for (i = 0; i < r->used; i++) { for (i = 0; i < r->used; i++) {
ri = &r->ranges[i]; ri = &r->ranges[i];
if (ri->nx == 0) if (ri->nx == 0)
@@ -2753,7 +2784,8 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc)
ttyctx.cell = &last; ttyctx.cell = &last;
if (force_wide) if (force_wide)
ttyctx.flags |= TTY_CTX_CELL_INVALIDATE; ttyctx.flags |= TTY_CTX_CELL_INVALIDATE;
tty_write(tty_cmd_cell, &ttyctx); if (~s->mode & MODE_SYNC)
tty_write(tty_cmd_cell, &ttyctx);
screen_write_set_cursor(ctx, cx, cy); screen_write_set_cursor(ctx, cx, cy);
return (1); return (1);

View File

@@ -1164,11 +1164,11 @@ server_client_repeat_time(struct client *c, struct key_binding *bd)
static enum cmd_retval static enum cmd_retval
server_client_key_callback(struct cmdq_item *item, void *data) server_client_key_callback(struct cmdq_item *item, void *data)
{ {
struct client *c = cmdq_get_client(item);
struct key_event *event = data; struct key_event *event = data;
struct client *c, *ec = event->client;
key_code key = event->key; key_code key = event->key;
struct mouse_event *m = &event->m; struct mouse_event *m = &event->m;
struct session *s = c->session; struct session *s;
struct winlink *wl; struct winlink *wl;
struct window_pane *wp; struct window_pane *wp;
struct window_mode_entry *wme; struct window_mode_entry *wme;
@@ -1180,6 +1180,12 @@ server_client_key_callback(struct cmdq_item *item, void *data)
struct cmd_find_state fs; struct cmd_find_state fs;
key_code key0, prefix, prefix2; key_code key0, prefix, prefix2;
if (ec != NULL)
c = ec;
else
c = cmdq_get_client(item);
s = c->session;
/* Check the client is good to accept input. */ /* Check the client is good to accept input. */
if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS)) if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS))
goto out; goto out;
@@ -1426,14 +1432,17 @@ paste_key:
out: out:
if (s != NULL && key != KEYC_FOCUS_OUT) if (s != NULL && key != KEYC_FOCUS_OUT)
server_client_update_latest(c); server_client_update_latest(c);
if (ec != NULL)
server_client_unref(ec);
free(event->buf); free(event->buf);
free(event); free(event);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
/* Handle a key event. */ /* Handle a key event. */
int static int
server_client_handle_key(struct client *c, struct key_event *event) server_client_handle_key0(struct client *c, struct key_event *event,
struct cmdq_item *after, struct cmdq_item **next)
{ {
struct session *s = c->session; struct session *s = c->session;
struct cmdq_item *item; struct cmdq_item *item;
@@ -1487,10 +1496,31 @@ server_client_handle_key(struct client *c, struct key_event *event)
* previous keys. * previous keys.
*/ */
item = cmdq_get_callback(server_client_key_callback, event); item = cmdq_get_callback(server_client_key_callback, event);
if (after != NULL) {
event->client = c;
c->references++;
item = cmdq_insert_after(after, item);
if (next != NULL)
*next = item;
return (1);
}
cmdq_append(c, item); cmdq_append(c, item);
return (1); return (1);
} }
int
server_client_handle_key(struct client *c, struct key_event *event)
{
return (server_client_handle_key0(c, event, NULL, NULL));
}
int
server_client_handle_key_after(struct client *c, struct key_event *event,
struct cmdq_item *after, struct cmdq_item **next)
{
return (server_client_handle_key0(c, event, after, next));
}
/* Client functions that need to happen every loop. */ /* Client functions that need to happen every loop. */
void void
server_client_loop(void) server_client_loop(void)
@@ -1782,7 +1812,7 @@ server_client_reset_state(struct client *c)
struct window_pane *wp = server_client_get_pane(c), *loop; struct window_pane *wp = server_client_get_pane(c), *loop;
struct screen *s = NULL; struct screen *s = NULL;
struct options *oo = c->session->options; struct options *oo = c->session->options;
int mode = 0, cursor, flags; int mode = 0, cursor, flags, pane_mode = 0;
u_int cx = 0, cy = 0, ox, oy, sx, sy, n; u_int cx = 0, cy = 0, ox, oy, sx, sy, n;
struct visible_ranges *r; struct visible_ranges *r;
@@ -1827,6 +1857,8 @@ server_client_reset_state(struct client *c)
cx = c->prompt_cursor; cx = c->prompt_cursor;
} else if (wp != NULL && c->overlay_draw == NULL) { } else if (wp != NULL && c->overlay_draw == NULL) {
cursor = 0; cursor = 0;
pane_mode = wp->base.mode;
tty_window_offset(tty, &ox, &oy, &sx, &sy); tty_window_offset(tty, &ox, &oy, &sx, &sy);
if (wp->xoff + (int)s->cx >= (int)ox && if (wp->xoff + (int)s->cx >= (int)ox &&
wp->xoff + (int)s->cx <= (int)ox + (int)sx && wp->xoff + (int)s->cx <= (int)ox + (int)sx &&
@@ -1845,13 +1877,14 @@ server_client_reset_state(struct client *c)
cy += status_line_size(c); cy += status_line_size(c);
} }
if (!cursor) if ((pane_mode & MODE_SYNC) || !cursor)
mode &= ~MODE_CURSOR; mode &= ~MODE_CURSOR;
} else if (c->overlay_mode == NULL || s == NULL) } else if (c->overlay_mode == NULL || s == NULL)
mode &= ~MODE_CURSOR; mode &= ~MODE_CURSOR;
if (~pane_mode & MODE_SYNC) {
log_debug("%s: cursor to %u,%u", __func__, cx, cy); log_debug("%s: cursor to %u,%u", __func__, cx, cy);
tty_cursor(tty, cx, cy); tty_cursor(tty, cx, cy);
}
/* /*
* Set mouse mode if requested. To support dragging, always use button * Set mouse mode if requested. To support dragging, always use button

11
sort.c
View File

@@ -65,7 +65,12 @@ sort_buffer_cmp(const void *a0, const void *b0)
result = strcmp(pa->name, pb->name); result = strcmp(pa->name, pb->name);
break; break;
case SORT_CREATION: case SORT_CREATION:
result = pa->order - pb->order; if (pa->order > pb->order)
result = -1;
else if (pa->order < pb->order)
result = 1;
else
result = 0;
break; break;
case SORT_SIZE: case SORT_SIZE:
result = pa->size - pb->size; result = pa->size - pb->size;
@@ -251,11 +256,11 @@ sort_winlink_cmp(const void *a0, const void *b0)
break; break;
case SORT_CREATION: case SORT_CREATION:
if (timercmp(&wa->creation_time, &wb->creation_time, >)) { if (timercmp(&wa->creation_time, &wb->creation_time, >)) {
result = -1; result = 1;
break; break;
} }
if (timercmp(&wa->creation_time, &wb->creation_time, <)) { if (timercmp(&wa->creation_time, &wb->creation_time, <)) {
result = 1; result = -1;
break; break;
} }
break; break;

4
tmux.h
View File

@@ -1629,6 +1629,8 @@ struct mouse_event {
/* Key event. */ /* Key event. */
struct key_event { struct key_event {
struct client *client;
key_code key; key_code key;
struct mouse_event m; struct mouse_event m;
@@ -3091,6 +3093,8 @@ void server_client_set_key_table(struct client *, const char *);
const char *server_client_get_key_table(struct client *); const char *server_client_get_key_table(struct client *);
int server_client_check_nested(struct client *); int server_client_check_nested(struct client *);
int server_client_handle_key(struct client *, struct key_event *); int server_client_handle_key(struct client *, struct key_event *);
int server_client_handle_key_after(struct client *, struct key_event *,
struct cmdq_item *, struct cmdq_item **);
struct client *server_client_create(int); struct client *server_client_create(int);
int server_client_open(struct client *, char **); int server_client_open(struct client *, char **);
void server_client_unref(struct client *); void server_client_unref(struct client *);

View File

@@ -181,7 +181,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
bg = ngc.bg; bg = ngc.bg;
} }
} }
tty_attributes(tty, &last, style_ctx); tty_attributes(tty, &last, style_ctx);
log_debug("%s: clearing %u padding cells", __func__, cx); log_debug("%s: clearing %u padding cells", __func__, cx);
tty_draw_line_clear(tty, atx, aty, cx, style_ctx->defaults, bg, 0); tty_draw_line_clear(tty, atx, aty, cx, style_ctx->defaults, bg, 0);
if (cx == ex) if (cx == ex)