Pane resizing code for floating panes, mostly by Michael Grant.

This commit is contained in:
nicm
2026-05-21 07:28:51 +00:00
parent 0057905ca0
commit 9aa9a92f72
3 changed files with 253 additions and 58 deletions

View File

@@ -29,8 +29,12 @@
static enum cmd_retval cmd_resize_pane_exec(struct cmd *, struct cmdq_item *);
static void cmd_resize_pane_mouse_update(struct client *,
struct mouse_event *);
static enum cmd_retval cmd_resize_pane_mouse_update(struct cmd *,
struct cmdq_item *);
static void cmd_resize_pane_mouse_update_floating(struct client *,
struct mouse_event *);
static void cmd_resize_pane_mouse_update_tiled(struct client *,
struct mouse_event *);
const struct cmd_entry cmd_resize_pane_entry = {
.name = "resize-pane",
@@ -51,13 +55,10 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
{
struct args *args = cmd_get_args(self);
struct cmd_find_state *target = cmdq_get_target(item);
struct key_event *event = cmdq_get_event(item);
struct window_pane *wp = target->wp;
struct winlink *wl = target->wl;
struct window *w = wl->window;
struct client *c = cmdq_get_client(item);
struct session *s = target->s;
const char *errstr;
const char *errstr;
char *cause;
u_int adjust;
int x, y, status;
@@ -75,15 +76,8 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_NORMAL);
}
if (args_has(args, 'M')) {
if (!event->m.valid || cmd_mouse_window(&event->m, &s) == NULL)
return (CMD_RETURN_NORMAL);
if (c == NULL || c->session != s)
return (CMD_RETURN_NORMAL);
c->tty.mouse_drag_update = cmd_resize_pane_mouse_update;
cmd_resize_pane_mouse_update(c, &event->m);
return (CMD_RETURN_NORMAL);
}
if (args_has(args, 'M'))
return (cmd_resize_pane_mouse_update(self, item));
if (args_has(args, 'Z')) {
if (w->flags & WINDOW_ZOOMED)
@@ -148,13 +142,158 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_NORMAL);
}
static enum cmd_retval
cmd_resize_pane_mouse_update(__unused struct cmd *self, struct cmdq_item *item)
{
struct cmd_find_state *target = cmdq_get_target(item);
struct key_event *event = cmdq_get_event(item);
struct window_pane *wp = target->wp;
struct winlink *wl = target->wl;
struct window *w = wl->window;
struct client *c = cmdq_get_client(item);
struct session *s = target->s;
if (!event->m.valid)
return (CMD_RETURN_NORMAL);
wp = cmd_mouse_pane(&event->m, &s, NULL);
if (wp == NULL || c == NULL || c->session != s)
return (CMD_RETURN_NORMAL);
if (~wp->flags & PANE_FLOATING) {
c->tty.mouse_drag_update = cmd_resize_pane_mouse_update_tiled;
cmd_resize_pane_mouse_update_tiled(c, &event->m);
return (CMD_RETURN_NORMAL);
}
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);
return (CMD_RETURN_NORMAL);
}
static void
cmd_resize_pane_mouse_update(struct client *c, struct mouse_event *m)
cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m)
{
struct winlink *wl;
struct window *w;
struct window_pane *wp;
struct layout_cell *lc;
int y, ly, x, lx, sx, sy, new_sx, new_sy;
int new_xoff, new_yoff, resizes = 0;
wp = cmd_mouse_pane(m, NULL, &wl);
if (wp == NULL) {
c->tty.mouse_drag_update = NULL;
return;
}
w = wl->window;
lc = wp->layout_cell;
sx = wp->sx;
sy = wp->sy;
y = m->y + m->oy; x = m->x + m->ox;
if (m->statusat == 0 && y >= (int)m->statuslines)
y -= m->statuslines;
else if (m->statusat > 0 && y >= m->statusat)
y = m->statusat - 1;
ly = m->ly + m->oy; lx = m->lx + m->ox;
if (m->statusat == 0 && ly >= (int)m->statuslines)
ly -= m->statuslines;
else if (m->statusat > 0 && ly >= m->statusat)
ly = m->statusat - 1;
if ((lx == wp->xoff - 1 || lx == wp->xoff) && ly == wp->yoff - 1) {
/* Top left corner. */
new_sx = lc->sx + (lx - x);
if (new_sx < PANE_MINIMUM)
new_sx = PANE_MINIMUM;
new_sy = lc->sy + (ly - y);
if (new_sy < PANE_MINIMUM)
new_sy = PANE_MINIMUM;
new_xoff = x + 1; /* because mouse is on border at xoff - 1 */
new_yoff = y + 1;
layout_set_size(lc, new_sx, new_sy, new_xoff, new_yoff);
resizes++;
} else if ((lx == wp->xoff + sx + 1 || lx == wp->xoff + sx) &&
ly == wp->yoff - 1) {
/* Top right corner. */
new_sx = x - lc->xoff;
if (new_sx < PANE_MINIMUM)
new_sx = PANE_MINIMUM;
new_sy = lc->sy + (ly - y);
if (new_sy < PANE_MINIMUM)
new_sy = PANE_MINIMUM;
new_yoff = y + 1;
layout_set_size(lc, new_sx, new_sy, lc->xoff, new_yoff);
resizes++;
} else if ((lx == wp->xoff - 1 || lx == wp->xoff) &&
ly == wp->yoff + sy) {
/* Bottom left corner. */
new_sx = lc->sx + (lx - x);
if (new_sx < PANE_MINIMUM)
new_sx = PANE_MINIMUM;
new_sy = y - lc->yoff;
if (new_sy < PANE_MINIMUM)
return;
new_xoff = x + 1;
layout_set_size(lc, new_sx, new_sy, new_xoff, lc->yoff);
resizes++;
} else if ((lx == wp->xoff + sx + 1 || lx == wp->xoff + sx) &&
ly == wp->yoff + sy) {
/* Bottom right corner. */
new_sx = x - lc->xoff;
if (new_sx < PANE_MINIMUM)
new_sx = PANE_MINIMUM;
new_sy = y - lc->yoff;
if (new_sy < PANE_MINIMUM)
new_sy = PANE_MINIMUM;
layout_set_size(lc, new_sx, new_sy, lc->xoff, lc->yoff);
resizes++;
} else if (lx == wp->xoff + sx + 1) {
/* Right border. */
new_sx = x - lc->xoff;
if (new_sx < PANE_MINIMUM)
return;
layout_set_size(lc, new_sx, lc->sy, lc->xoff, lc->yoff);
resizes++;
} else if (lx == wp->xoff - 1) {
/* Left border. */
new_sx = lc->sx + (lx - x);
if (new_sx < PANE_MINIMUM)
return;
new_xoff = x + 1;
layout_set_size(lc, new_sx, lc->sy, new_xoff, lc->yoff);
resizes++;
} else if (ly == wp->yoff + sy) {
/* Bottom border. */
new_sy = y - lc->yoff;
if (new_sy < PANE_MINIMUM)
return;
layout_set_size(lc, lc->sx, new_sy, lc->xoff, lc->yoff);
resizes++;
} else if (ly == wp->yoff - 1) {
/* Top border (move instead of resize). */
new_xoff = lc->xoff + (x - lx);
new_yoff = y + 1;
layout_set_size(lc, lc->sx, lc->sy, new_xoff, new_yoff);
resizes++;
}
if (resizes != 0) {
layout_fix_panes(w, NULL);
server_redraw_window(w);
server_redraw_window_borders(w);
}
}
static void
cmd_resize_pane_mouse_update_tiled(struct client *c, struct mouse_event *m)
{
struct winlink *wl;
struct window *w;
u_int y, ly, x, lx;
static const int offsets[][2] = {
static const int offsets[][2] = {
{ 0, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 },
};
struct layout_cell *cells[nitems(offsets)], *lc;