diff --git a/input.c b/input.c index d83da9f0e..97c3038f7 100644 --- a/input.c +++ b/input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: input.c,v 1.274 2026/10/12 17:04:48 nicm Exp $ */ +/* $OpenBSD: input.c,v 1.275 2026/10/12 18:47:52 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -936,6 +936,7 @@ input_reset(struct input_ctx *ictx, int clear) screen_write_start_pane(sctx, wp, &wp->base); else screen_write_start(sctx, &wp->base); + sctx->flags |= SCREEN_WRITE_INPUT; screen_write_reset(sctx); screen_write_stop(sctx); } @@ -1064,6 +1065,7 @@ input_parse_buffer(struct window_pane *wp, const u_char *buf, size_t len) screen_write_start_pane(sctx, wp, &wp->base); else screen_write_start(sctx, &wp->base); + sctx->flags |= SCREEN_WRITE_INPUT; log_debug("%s: %%%u %s, %zu bytes: %.*s", __func__, wp->id, ictx->state->name, len, (int)len, buf); @@ -1083,6 +1085,7 @@ input_parse_screen(struct input_ctx *ictx, struct screen *s, return; screen_write_start_callback(sctx, s, cb, arg); + sctx->flags |= SCREEN_WRITE_INPUT; input_parse(ictx, buf, len); screen_write_stop(sctx); } diff --git a/mode-tree.c b/mode-tree.c index 222047f61..011294aec 100644 --- a/mode-tree.c +++ b/mode-tree.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mode-tree.c,v 1.103 2026/09/24 18:59:00 nicm Exp $ */ +/* $OpenBSD: mode-tree.c,v 1.104 2026/10/12 18:23:25 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott @@ -701,8 +701,17 @@ mode_tree_build(struct mode_tree_data *mtd) static void mode_tree_remove_ref(struct mode_tree_data *mtd) { - if (--mtd->references == 0) - free(mtd); + if (--mtd->references != 0) + return; + + mode_tree_clear_prompt(mtd); + mode_tree_free_items(&mtd->children); + mode_tree_clear_lines(mtd); + screen_free(&mtd->screen); + + free(mtd->search); + free(mtd->filter); + free(mtd); } void @@ -713,14 +722,6 @@ mode_tree_free(struct mode_tree_data *mtd) if (mtd->zoomed == 0) server_unzoom_window(wp->window); - mode_tree_clear_prompt(mtd); - mode_tree_free_items(&mtd->children); - mode_tree_clear_lines(mtd); - screen_free(&mtd->screen); - - free(mtd->search); - free(mtd->filter); - mtd->dead = 1; mode_tree_remove_ref(mtd); } @@ -1095,7 +1096,7 @@ mode_tree_prompt_accept(struct cmdq_item *item, void *data) struct client *c = cmdq_get_client(item); key_code key = 'y'; - if (mtd->prompt != NULL && c != NULL) + if (!mtd->dead && mtd->prompt != NULL && c != NULL) mode_tree_key(mtd, c, &key, NULL, NULL, NULL); mode_tree_remove_ref(mtd); @@ -1122,7 +1123,6 @@ mode_tree_prompt_free_callback(void *data) mtp->mtd->prompt_data = NULL; if (mtp->freecb != NULL) mtp->freecb(mtp->data); - mode_tree_remove_ref(mtp->mtd); free(mtp); } @@ -1152,8 +1152,6 @@ mode_tree_set_prompt(struct mode_tree_data *mtd, struct client *c, mtp->inputcb = inputcb; mtp->freecb = freecb; mtp->data = data; - - mtd->references++; mtd->prompt_top = options_get_number(oo, "status-position") == 0; memset(&pd, 0, sizeof pd); @@ -1524,6 +1522,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key, if (mtd->prompt != NULL) { redraw = 0; prompt = mtd->prompt; + mtd->references++; mtp = mtd->prompt_data; if (mtp != NULL) @@ -1548,6 +1547,11 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key, } } else result = prompt_key(prompt, *key, &redraw); + if (mtd->dead) { + mode_tree_remove_ref(mtd); + *key = KEYC_NONE; + return (1); + } if (mtd->prompt_data == mtp && mtp != NULL) mtp->c = NULL; @@ -1563,6 +1567,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key, mode_tree_draw(mtd); mtd->wp->flags |= PANE_REDRAW; } + mode_tree_remove_ref(mtd); if (result != PROMPT_KEY_NOT_HANDLED) { *key = KEYC_NONE; return (0); diff --git a/screen-write.c b/screen-write.c index bc2cedd2c..228860c7a 100644 --- a/screen-write.c +++ b/screen-write.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen-write.c,v 1.299 2026/10/05 08:41:23 nicm Exp $ */ +/* $OpenBSD: screen-write.c,v 1.300 2026/10/12 18:47:52 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -2651,8 +2651,9 @@ screen_write_collect_insert_clear(struct screen_write_ctx *ctx, u_int px, * background so the columns it covered do not lose their colour. */ static void -screen_write_clear_cell(struct grid *gd, u_int px, u_int py) +screen_write_clear_cell(struct screen_write_ctx *ctx, u_int px, u_int py) { + struct grid *gd = ctx->s->grid; struct grid_cell gc; int bg; @@ -2717,7 +2718,7 @@ screen_write_collect_end(struct screen_write_ctx *ctx) grid_view_get_cell(s->grid, xx, s->cy, &gc); if (~gc.flags & GRID_FLAG_PADDING) break; - screen_write_clear_cell(s->grid, xx, s->cy); + screen_write_clear_cell(ctx, xx, s->cy); log_debug("%s: padding erased (before) at %u (cx %u)", __func__, xx, s->cx); } @@ -2726,7 +2727,7 @@ screen_write_collect_end(struct screen_write_ctx *ctx) grid_view_get_cell(s->grid, 0, s->cy, &gc); if (gc.data.width > 1 || (gc.flags & GRID_FLAG_PADDING)) { - screen_write_clear_cell(s->grid, xx, s->cy); + screen_write_clear_cell(ctx, xx, s->cy); log_debug("%s: padding erased (before) at %u " "(cx %u)", __func__, xx, s->cx); } @@ -2750,7 +2751,7 @@ screen_write_collect_end(struct screen_write_ctx *ctx) grid_view_get_cell(s->grid, xx, s->cy, &gc); if (~gc.flags & GRID_FLAG_PADDING) break; - screen_write_clear_cell(s->grid, xx, s->cy); + screen_write_clear_cell(ctx, xx, s->cy); log_debug("%s: padding erased (after) at %u (cx %u)", __func__, xx, s->cx); } @@ -3177,12 +3178,12 @@ screen_write_overwrite(struct screen_write_ctx *ctx, struct grid_cell *gc, if (~tmp_gc.flags & GRID_FLAG_PADDING) break; log_debug("%s: padding at %u,%u", __func__, xx, s->cy); - screen_write_clear_cell(gd, xx, s->cy); + screen_write_clear_cell(ctx, xx, s->cy); } /* Overwrite the character at the start of this padding. */ log_debug("%s: character at %u,%u", __func__, xx, s->cy); - screen_write_clear_cell(gd, xx, s->cy); + screen_write_clear_cell(ctx, xx, s->cy); done = 1; } @@ -3200,7 +3201,7 @@ screen_write_overwrite(struct screen_write_ctx *ctx, struct grid_cell *gc, break; log_debug("%s: overwrite at %u,%u", __func__, xx, s->cy); - screen_write_clear_cell(gd, xx, s->cy); + screen_write_clear_cell(ctx, xx, s->cy); done = 1; } } diff --git a/tmux.h b/tmux.h index 37a504ac8..2fba98929 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1457 2026/10/12 12:35:03 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1458 2026/10/12 18:47:52 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1135,6 +1135,7 @@ struct screen_write_ctx { #define SCREEN_WRITE_SYNC 0x1 #define SCREEN_WRITE_OBSCURED 0x2 #define SCREEN_WRITE_CHECKED_IF_OBSCURED 0x4 +#define SCREEN_WRITE_INPUT 0x8 screen_write_init_ctx_cb init_ctx_cb; void *arg; diff --git a/window-tree.c b/window-tree.c index 7e90a5a2f..cbb9a5ba8 100644 --- a/window-tree.c +++ b/window-tree.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-tree.c,v 1.96 2026/08/25 07:23:30 nicm Exp $ */ +/* $OpenBSD: window-tree.c,v 1.97 2026/10/12 18:23:25 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott @@ -1344,12 +1344,10 @@ window_tree_kill_current_callback(struct client *c, void *modedata, if (tolower((u_char) s[0]) != 'y' || s[1] != '\0') return (PROMPT_CLOSE); + data->references++; window_tree_kill_each(data, mode_tree_get_current(mtd), c, KEYC_NONE); server_renumber_all(); - - data->references++; cmdq_append(c, cmdq_get_callback(window_tree_command_done, data)); - return (PROMPT_CLOSE); } @@ -1365,12 +1363,10 @@ window_tree_kill_tagged_callback(struct client *c, void *modedata, if (tolower((u_char) s[0]) != 'y' || s[1] != '\0') return (PROMPT_CLOSE); + data->references++; mode_tree_each_tagged(mtd, window_tree_kill_each, c, KEYC_NONE, 1); server_renumber_all(); - - data->references++; cmdq_append(c, cmdq_get_callback(window_tree_command_done, data)); - return (PROMPT_CLOSE); } @@ -1453,6 +1449,8 @@ window_tree_key(struct window_mode_entry *wme, struct client *c, item = mode_tree_get_current(data->data); finished = mode_tree_key(data->data, c, &key, m, &x, &y); + if (data->dead) + return; again: if (item != (new_item = mode_tree_get_current(data->data))) {