diff --git a/cmd-split-window.c b/cmd-split-window.c index 5ef5425fb..f56aaac96 100644 --- a/cmd-split-window.c +++ b/cmd-split-window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-split-window.c,v 1.142 2026/07/13 10:03:27 nicm Exp $ */ +/* $OpenBSD: cmd-split-window.c,v 1.143 2026/07/13 16:07:47 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -33,13 +33,15 @@ #define SPLIT_WINDOW_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}" static enum cmd_retval cmd_split_window_exec(struct cmd *, struct cmdq_item *); +static void cmd_split_window_mouse_resize(struct client *, + struct mouse_event *); const struct cmd_entry cmd_new_pane_entry = { .name = "new-pane", .alias = "newp", - .args = { "bB:c:de:EfF:hIkl:Lm:p:PR:s:S:t:T:vWx:X:y:Y:Z", 0, -1, NULL }, - .usage = "[-bdefhIklPvWZ] [-B border-lines] " + .args = { "bB:c:de:EfF:hIkl:LMm:p:PR:s:S:t:T:vWx:X:y:Y:Z", 0, -1, NULL }, + .usage = "[-bdefhIklMPvWZ] [-B border-lines] " "[-c start-directory] [-e environment] " "[-F format] [-l size] [-m message] [-p percentage] " "[-s style] [-S active-border-style] " @@ -85,6 +87,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) struct layout_cell *lc = NULL; struct event_payload *ep; struct cmd_find_state fs; + struct key_event *event = cmdq_get_event(item); int input, empty, is_floating, flags = 0; const char *template, *style, *value; char *cause = NULL, *cp, *title; @@ -100,6 +103,11 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) flags |= SPAWN_SPLIT; } + if (args_has(args, 'M') && is_floating) { + if (event == NULL || !event->m.valid || tc == NULL) + return (CMD_RETURN_NORMAL); + } + if (is_floating) flags |= SPAWN_FLOATING; if (args_has(args, 'h')) @@ -253,6 +261,12 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) } server_redraw_session(s); + if (args_has(args, 'M') && is_floating) { + tc->tty.mouse_last_pane = new_wp->id; + tc->tty.mouse_drag_update = cmd_split_window_mouse_resize; + cmd_split_window_mouse_resize(tc, &event->m); + } + if (args_has(args, 'P')) { if ((template = args_get(args, 'F')) == NULL) template = SPLIT_WINDOW_TEMPLATE; @@ -300,3 +314,73 @@ fail: return (CMD_RETURN_ERROR); } + +static void +cmd_split_window_mouse_resize(struct client *c, struct mouse_event *m) +{ + struct window_pane *wp; + struct window *w; + struct layout_cell *lc; + enum pane_lines lines; + u_int sx, sy; + int x, y, xoff, yoff, border; + + if (c->tty.mouse_last_pane == -1) + return; + wp = window_pane_find_by_id(c->tty.mouse_last_pane); + if (wp == NULL || !window_pane_is_floating(wp)) { + c->tty.mouse_drag_update = NULL; + return; + } + w = wp->window; + lc = wp->layout_cell; + + x = m->x + m->ox; + y = m->y + m->oy; + if (m->statusat == 0 && y >= (int)m->statuslines) + y -= m->statuslines; + else if (m->statusat > 0 && y >= m->statusat) + y = m->statusat - 1; + + lines = window_pane_get_pane_lines(wp); + border = (lines != PANE_LINES_NONE); + + if (x >= (int)c->tty.mouse_drag_x) { + xoff = c->tty.mouse_drag_x + border; + sx = x - c->tty.mouse_drag_x + 1; + } else { + sx = c->tty.mouse_drag_x - x + 1; + xoff = c->tty.mouse_drag_x - sx + 1; + if (border) + xoff++; + } + if (y >= (int)c->tty.mouse_drag_y) { + yoff = c->tty.mouse_drag_y + border; + sy = y - c->tty.mouse_drag_y + 1; + } else { + sy = c->tty.mouse_drag_y - y + 1; + yoff = c->tty.mouse_drag_y - sy + 1; + if (border) + yoff++; + } + + if (border) { + if (sx <= 2) + sx = PANE_MINIMUM; + else + sx -= 2; + if (sy <= 2) + sy = PANE_MINIMUM; + else + sy -= 2; + } + if (sx < PANE_MINIMUM) + sx = PANE_MINIMUM; + if (sy < PANE_MINIMUM) + sy = PANE_MINIMUM; + + layout_set_size(lc, sx, sy, xoff, yoff); + layout_fix_panes(w, NULL); + server_redraw_window(w); + server_redraw_window_borders(w); +} diff --git a/key-bindings.c b/key-bindings.c index 92d417c5b..359a7b5cb 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key-bindings.c,v 1.186 2026/07/07 12:30:36 nicm Exp $ */ +/* $OpenBSD: key-bindings.c,v 1.187 2026/07/13 16:07:47 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -496,10 +496,10 @@ key_bindings_init(void) /* Mouse button 1 down on pane. */ "bind -n MouseDown1Pane { select-pane -t=; send -M }", - "bind -n C-MouseDown1Pane { swap-pane -s@ }", /* 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 M-MouseDrag1Pane { move-pane -M }", /* Mouse wheel up on pane. */ diff --git a/server-client.c b/server-client.c index ceb234f5a..3fb7813ca 100644 --- a/server-client.c +++ b/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.488 2026/07/13 15:03:03 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.489 2026/07/13 16:07:47 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -1169,6 +1169,10 @@ have_event: * the scrollbar, store the relative position in the slider * where the user grabbed. */ + if (c->tty.mouse_drag_flag == 0) { + c->tty.mouse_drag_x = px; + c->tty.mouse_drag_y = py; + } c->tty.mouse_drag_flag = MOUSE_BUTTONS(b) + 1; /* Only change pane if not already dragging a pane border. */ diff --git a/tmux.1 b/tmux.1 index 96ed453d1..025236b40 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.1135 2026/07/13 15:03:03 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.1136 2026/07/13 16:07:47 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -3616,7 +3616,7 @@ but a different format may be specified with .Fl F . .Tg newp .It Xo Ic new\-pane -.Op Fl bdefhIkLPvWZ +.Op Fl bdefhIkLMPvWZ .Op Fl B Ar border\-lines .Op Fl c Ar start\-directory .Op Fl e Ar environment @@ -3662,6 +3662,11 @@ to specify a percentage of the window size. .Fl B sets the pane border lines for floating panes; see .Ic pane\-border\-lines . +.Fl M +may be used when bound to a mouse drag key; the new floating pane is resized to +follow the mouse drag. +It has no effect with +.Fl L . .Pp The .Fl L diff --git a/tmux.h b/tmux.h index 05068a1ef..6930eaf53 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1400 2026/07/13 15:03:03 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1401 2026/07/13 16:07:47 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1780,6 +1780,8 @@ struct tty { u_int mouse_last_y; u_int mouse_last_b; int mouse_drag_flag; + u_int mouse_drag_x; + u_int mouse_drag_y; int mouse_scrolling_flag; int mouse_slider_mpos; int mouse_last_pane;