From cbb97b961c62ff31fe746204e203a4000afac42e Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 15 Jul 2026 10:38:31 +0000 Subject: [PATCH] Add a mouse binding for empty areas of the window so C-Drag works on them as well. --- key-bindings.c | 3 +- server-client.c | 76 ++++++++++++++++++++++++------------------------- tmux.1 | 5 ++-- tmux.h | 5 +++- 4 files changed, 47 insertions(+), 42 deletions(-) diff --git a/key-bindings.c b/key-bindings.c index f90307fc1..ff6111870 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key-bindings.c,v 1.188 2026/07/13 16:30:28 nicm Exp $ */ +/* $OpenBSD: key-bindings.c,v 1.189 2026/07/15 10:38:31 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -503,6 +503,7 @@ key_bindings_init(void) /* Mouse button 1 drag on pane. */ "bind -n MouseDrag1Pane { if -F '#{||:#{pane_in_mode},#{mouse_any_flag}}' { send -M } { copy-mode -M } }", "bind -n C-MouseDrag1Pane { new-pane -M }", + "bind -n C-MouseDrag1Empty { new-pane -M }", "bind -n M-MouseDrag1Pane { move-pane -M }", /* Mouse wheel up on pane. */ diff --git a/server-client.c b/server-client.c index 0a85dcb03..cebf213bb 100644 --- a/server-client.c +++ b/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.491 2026/07/14 19:07:03 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.492 2026/07/15 10:38:31 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -1033,46 +1033,46 @@ have_event: * Not on status line. Adjust position and check for border, pane, or * scrollbar. */ - if (loc == KEYC_MOUSE_LOCATION_NOWHERE) { - if (c->tty.mouse_scrolling_flag) { - if (lwp != NULL) { - loc = KEYC_MOUSE_LOCATION_SCROLLBAR_SLIDER; - m->wp = lwp->id; - m->w = lwp->window->id; - } + if (loc == KEYC_MOUSE_LOCATION_NOWHERE && c->tty.mouse_scrolling_flag) { + if (lwp != NULL) { + loc = KEYC_MOUSE_LOCATION_SCROLLBAR_SLIDER; + m->wp = lwp->id; + m->w = lwp->window->id; + } + } else if (loc == KEYC_MOUSE_LOCATION_NOWHERE) { + px = x; + if (m->statusat == 0 && y >= m->statuslines) + py = y - m->statuslines; + else if (m->statusat > 0 && y >= (u_int)m->statusat) + py = m->statusat - 1; + else + py = y; + + tty_window_offset(&c->tty, &m->ox, &m->oy, &sx, &sy); + log_debug("mouse window @%u at %u,%u (%ux%u)", w->id, m->ox, + m->oy, sx, sy); + if (px > sx || py > sy) { + server_client_update_scrollbar_hover(c, type, -1, -1); + return (KEYC_UNKNOWN); + } + px = px + m->ox; + py = py + m->oy; + server_client_update_scrollbar_hover(c, type, px, py); + + if (type == KEYC_TYPE_MOUSEDRAG && lwp != NULL) { + /* Use pane from last mouse event. */ + wp = lwp; + } else { + /* Try inside the pane. */ + wp = window_get_active_at(w, px, py); + } + if (wp == NULL) { + loc = KEYC_MOUSE_LOCATION_EMPTY; + m->w = w->id; + log_debug("mouse %u,%u on empty area", x, y); } else { - px = x; - if (m->statusat == 0 && y >= m->statuslines) - py = y - m->statuslines; - else if (m->statusat > 0 && y >= (u_int)m->statusat) - py = m->statusat - 1; - else - py = y; - - tty_window_offset(&c->tty, &m->ox, &m->oy, &sx, &sy); - log_debug("mouse window @%u at %u,%u (%ux%u)", - w->id, m->ox, m->oy, sx, sy); - if (px > sx || py > sy) { - server_client_update_scrollbar_hover(c, type, - -1, -1); - return (KEYC_UNKNOWN); - } - px = px + m->ox; - py = py + m->oy; - server_client_update_scrollbar_hover(c, type, px, py); - - if (type == KEYC_TYPE_MOUSEDRAG && lwp != NULL) { - /* Use pane from last mouse event. */ - 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, &sl_mpos); - if (loc == KEYC_MOUSE_LOCATION_PANE) { log_debug("mouse %u,%u on pane %%%u", x, y, wp->id); diff --git a/tmux.1 b/tmux.1 index a393c5954..5ab57c8b1 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.1140 2026/07/14 17:17:18 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.1141 2026/07/15 10:38:31 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: July 14 2026 $ +.Dd $Mdocdate: July 15 2026 $ .Dt TMUX 1 .Os .Sh NAME @@ -6618,6 +6618,7 @@ and a location suffix, one of the following: .It Li "ScrollbarSlider" Ta "the scrollbar slider" .It Li "ScrollbarUp" Ta "above the scrollbar slider" .It Li "ScrollbarDown" Ta "below the scrollbar slider" +.It Li "Empty" Ta "empty space in the window" .It Li "ControlN" Ta "on control range N" .El .Pp diff --git a/tmux.h b/tmux.h index 535e77613..abba612ea 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1404 2026/07/14 19:07:03 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1405 2026/07/15 10:38:31 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -181,6 +181,7 @@ enum key_code_mouse_location { KEYC_MOUSE_LOCATION_SCROLLBAR_UP, KEYC_MOUSE_LOCATION_SCROLLBAR_SLIDER, KEYC_MOUSE_LOCATION_SCROLLBAR_DOWN, + KEYC_MOUSE_LOCATION_EMPTY, KEYC_MOUSE_LOCATION_CONTROL0, /* keep order */ KEYC_MOUSE_LOCATION_CONTROL1, KEYC_MOUSE_LOCATION_CONTROL2, @@ -237,6 +238,7 @@ enum key_code_mouse_location { KEYC_MOUSE_KEY(KEYC_ ## t, KEYC_TYPE_ ## t, SCROLLBAR_UP), \ KEYC_MOUSE_KEY(KEYC_ ## t, KEYC_TYPE_ ## t, SCROLLBAR_SLIDER), \ KEYC_MOUSE_KEY(KEYC_ ## t, KEYC_TYPE_ ## t, SCROLLBAR_DOWN), \ + KEYC_MOUSE_KEY(KEYC_ ## t, KEYC_TYPE_ ## t, EMPTY), \ KEYC_MOUSE_KEY(KEYC_ ## t, KEYC_TYPE_ ## t, CONTROL0), \ KEYC_MOUSE_KEY(KEYC_ ## t, KEYC_TYPE_ ## t, CONTROL1), \ KEYC_MOUSE_KEY(KEYC_ ## t, KEYC_TYPE_ ## t, CONTROL2), \ @@ -271,6 +273,7 @@ enum key_code_mouse_location { { #s "ScrollbarUp", KEYC_ ## name ## _SCROLLBAR_UP }, \ { #s "ScrollbarSlider", KEYC_ ## name ## _SCROLLBAR_SLIDER }, \ { #s "ScrollbarDown", KEYC_ ## name ## _SCROLLBAR_DOWN }, \ + { #s "Empty", KEYC_ ## name ## _EMPTY }, \ { #s "Border", KEYC_ ## name ## _BORDER }, \ { #s "Control0", KEYC_ ## name ## _CONTROL0 }, \ { #s "Control1", KEYC_ ## name ## _CONTROL1 }, \