From c56bc9ed05fa991ab56b0dfb192a758fb5dc0495 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 20 May 2026 13:41:13 +0100 Subject: [PATCH] Store pane ID for mouse last pane instead of a pointer to the pane. --- cmd-resize-pane.c | 19 +++++++++---------- server-client.c | 38 ++++++++++++++++++++++++-------------- tmux.h | 2 +- tty.c | 1 + window-copy.c | 5 +---- 5 files changed, 36 insertions(+), 29 deletions(-) diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c index e1d6438d..b00c0d78 100644 --- a/cmd-resize-pane.c +++ b/cmd-resize-pane.c @@ -78,13 +78,14 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item) } if (args_has(args, 'M')) { - if (!event->m.valid || cmd_mouse_window(&event->m, &s) == NULL) + if (!event->m.valid) return (CMD_RETURN_NORMAL); - if (c == NULL || c->session != s) + wp = cmd_mouse_pane(&event->m, &s, NULL); + if (wp == NULL || c == NULL || c->session != s) return (CMD_RETURN_NORMAL); - if (c->tty.mouse_wp->flags & PANE_FLOATING) { - window_redraw_active_switch(w, c->tty.mouse_wp); - window_set_active_pane(w, c->tty.mouse_wp, 1); + if (wp->flags & PANE_FLOATING) { + window_redraw_active_switch(w, wp); + window_set_active_pane(w, wp, 1); c->tty.mouse_drag_update = cmd_resize_pane_mouse_update_floating; cmd_resize_pane_mouse_update_floating(c, &event->m); } else { @@ -168,12 +169,13 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m) int new_sx, new_sy; int new_xoff, new_yoff, resizes = 0; - wl = cmd_mouse_window(m, NULL); - if (wl == NULL) { + wp = cmd_mouse_pane(m, NULL, &wl); + if (wp == NULL) { c->tty.mouse_drag_update = NULL; return; } w = wl->window; + lc = wp->layout_cell; y = m->y + m->oy; x = m->x + m->ox; if (m->statusat == 0 && y >= m->statuslines) @@ -186,9 +188,6 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m) else if (m->statusat > 0 && ly >= (u_int)m->statusat) ly = m->statusat - 1; - wp = c->tty.mouse_wp; - lc = wp->layout_cell; - log_debug("%s: %%%u resize_pane xoff=%d sx=%u xy=%ux%u lxy=%ux%u", __func__, wp->id, wp->xoff, wp->sx, x, y, lx, ly); if ((((int)lx == wp->xoff - 1) || ((int)lx == wp->xoff)) && diff --git a/server-client.c b/server-client.c index 7a812f95..ba6f3a83 100644 --- a/server-client.c +++ b/server-client.c @@ -718,7 +718,7 @@ server_client_check_mouse(struct client *c, struct key_event *event) struct session *s = c->session, *fs; struct window *w = s->curw->window; struct winlink *fwl; - struct window_pane *wp, *fwp; + struct window_pane *wp, *fwp, *lwp = NULL; u_int x, y, sx, sy, px, py, n, sl_mpos = 0; u_int b, bn; int ignore = 0; @@ -731,6 +731,13 @@ server_client_check_mouse(struct client *c, struct key_event *event) log_debug("%s mouse %02x at %u,%u (last %u,%u) (%d)", c->name, m->b, m->x, m->y, m->lx, m->ly, c->tty.mouse_drag_flag); + /* Find last pane, if any. */ + if (c->tty.mouse_last_pane != -1) { + lwp = window_pane_find_by_id(c->tty.mouse_last_pane); + if (lwp != NULL) + log_debug("%s mouse last pane %%%u", c->name, lwp->id); + } + /* What type of event is this? */ if (event->key == KEYC_DOUBLECLICK) { type = KEYC_TYPE_DOUBLECLICK; @@ -875,9 +882,11 @@ have_event: */ if (loc == KEYC_MOUSE_LOCATION_NOWHERE) { if (c->tty.mouse_scrolling_flag) { - loc = KEYC_MOUSE_LOCATION_SCROLLBAR_SLIDER; - m->wp = c->tty.mouse_wp->id; - m->w = c->tty.mouse_wp->window->id; + if (lwp != NULL) { + loc = KEYC_MOUSE_LOCATION_SCROLLBAR_SLIDER; + m->wp = lwp->id; + m->w = lwp->window->id; + } } else { px = x; if (m->statusat == 0 && y >= m->statuslines) @@ -895,13 +904,13 @@ have_event: px = px + m->ox; py = py + m->oy; - if (type == KEYC_TYPE_MOUSEDRAG && - c->tty.mouse_wp != NULL) + if (type == KEYC_TYPE_MOUSEDRAG && lwp != NULL) { /* Use pane from last mouse event. */ - wp = c->tty.mouse_wp; - else + wp = lwp; + } else { /* Try inside the pane. */ wp = window_get_active_at(w, px, py); + } if (wp == NULL) return (KEYC_UNKNOWN); loc = server_client_check_mouse_in_pane(wp, px, py, @@ -979,8 +988,8 @@ have_event: */ type = KEYC_TYPE_MOUSEDRAGEND; c->tty.mouse_drag_flag = 0; - c->tty.mouse_wp = NULL; c->tty.mouse_slider_mpos = -1; + c->tty.mouse_last_pane = -1; } /* Convert to a key binding. */ @@ -1006,10 +1015,11 @@ have_event: * where the user grabbed. */ c->tty.mouse_drag_flag = MOUSE_BUTTONS(b) + 1; + /* Only change pane if not already dragging a pane border. */ - if (c->tty.mouse_wp == NULL) { - wp = window_get_active_at(w, px, py); - c->tty.mouse_wp = wp; + if (lwp == NULL) { + lwp = wp = window_get_active_at(w, px, py); + c->tty.mouse_last_pane = wp->id; } if (c->tty.mouse_scrolling_flag == 0 && loc == KEYC_MOUSE_LOCATION_SCROLLBAR_SLIDER) { @@ -2820,8 +2830,8 @@ server_client_remove_pane(struct window_pane *wp) RB_REMOVE(client_windows, &c->windows, cw); free(cw); } - if (c->tty.mouse_wp == wp) { - c->tty.mouse_wp = NULL; + if (c->tty.mouse_last_pane == (int)wp->id) { + c->tty.mouse_last_pane = -1; c->tty.mouse_drag_update = NULL; c->tty.mouse_scrolling_flag = 0; } diff --git a/tmux.h b/tmux.h index e58a583c..4a6051c1 100644 --- a/tmux.h +++ b/tmux.h @@ -1719,7 +1719,7 @@ struct tty { int mouse_drag_flag; int mouse_scrolling_flag; int mouse_slider_mpos; - struct window_pane *mouse_wp; + int mouse_last_pane; void (*mouse_drag_update)(struct client *, struct mouse_event *); void (*mouse_drag_release)(struct client *, diff --git a/tty.c b/tty.c index 2079bffd..6e622804 100644 --- a/tty.c +++ b/tty.c @@ -108,6 +108,7 @@ tty_init(struct tty *tty, struct client *c) tty->cstyle = SCREEN_CURSOR_DEFAULT; tty->ccolour = -1; tty->fg = tty->bg = -1; + tty->mouse_last_pane = -1; if (tcgetattr(c->fd, &tty->tio) != 0) return (-1); diff --git a/window-copy.c b/window-copy.c index 96e3bd11..acb7cd88 100644 --- a/window-copy.c +++ b/window-copy.c @@ -6507,10 +6507,7 @@ window_copy_drag_update(struct client *c, struct mouse_event *m) if (c == NULL) return; - if (c->tty.mouse_wp != NULL) - wp = c->tty.mouse_wp; - else - wp = cmd_mouse_pane(m, NULL, NULL); + wp = cmd_mouse_pane(m, NULL, NULL); if (wp == NULL) return; wme = TAILQ_FIRST(&wp->modes);