diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c index b2c167f5..706c78de 100644 --- a/cmd-resize-pane.c +++ b/cmd-resize-pane.c @@ -29,7 +29,9 @@ static enum cmd_retval cmd_resize_pane_exec(struct cmd *, struct cmdq_item *); -static void cmd_resize_pane_mouse_update(struct client *, +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 = { @@ -80,8 +82,13 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item) 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); + if (c->tty.mouse_wp->layout_cell != NULL) { + c->tty.mouse_drag_update = cmd_resize_pane_mouse_update_tiled; + cmd_resize_pane_mouse_update_tiled(c, &event->m); + } else { + c->tty.mouse_drag_update = cmd_resize_pane_mouse_update_floating; + cmd_resize_pane_mouse_update_floating(c, &event->m); + } return (CMD_RETURN_NORMAL); } @@ -149,7 +156,125 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item) } 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; + u_int y, ly, x, lx, new_sx, new_sy; + + wl = cmd_mouse_window(m, NULL); + if (wl == NULL) { + c->tty.mouse_drag_update = NULL; + return; + } + w = wl->window; + + y = m->y + m->oy; x = m->x + m->ox; + if (m->statusat == 0 && y >= m->statuslines) + y -= m->statuslines; + else if (m->statusat > 0 && y >= (u_int)m->statusat) + y = m->statusat - 1; + ly = m->ly + m->oy; lx = m->lx + m->ox; + if (m->statusat == 0 && ly >= m->statuslines) + ly -= m->statuslines; + else if (m->statusat > 0 && ly >= (u_int)m->statusat) + ly = m->statusat - 1; + + wp = c->tty.mouse_wp; + + log_debug("%s: %%%u resize_pane xoff=%u sx=%u xy=%ux%u lxy=%ux%u", + __func__, wp->id, wp->xoff, wp->sx, x, y, lx, ly); + if (((m->lx == wp->xoff - 1) || (m->lx == wp->xoff)) && + (m->ly == wp->yoff - 1)) { + /* Top left border */ + new_sx = wp->sx + (lx - x); + if (new_sx < PANE_MINIMUM) + new_sx = PANE_MINIMUM; + new_sy = wp->sy + (ly - y); + if (new_sy < PANE_MINIMUM) + new_sy = PANE_MINIMUM; + window_pane_move(wp, x + 1, y + 1); + window_pane_resize(wp, new_sx, new_sy); + server_redraw_window(w); + } else if (((m->lx == wp->xoff + wp->sx + 1) || + (m->lx == wp->xoff + wp->sx)) && + (m->ly == wp->yoff - 1)) { + /* Top right border */ + new_sx = x - wp->xoff - 1; + if (new_sx < PANE_MINIMUM) + new_sx = PANE_MINIMUM; + new_sy = wp->sy + (ly - y); + if (new_sy < PANE_MINIMUM) + new_sy = PANE_MINIMUM; + window_pane_move(wp, wp->xoff, y + 1); + window_pane_resize(wp, new_sx, new_sy); + server_redraw_window(w); + } else if (((m->lx == wp->xoff - 1) || (m->lx == wp->xoff)) && + (m->ly == wp->yoff + wp->sy)) { + /* Bottom left border */ + new_sx = wp->sx + (lx - x); + if (new_sx < PANE_MINIMUM) + new_sx = PANE_MINIMUM; + new_sy = y - wp->yoff; + if (new_sy < PANE_MINIMUM) + return; + window_pane_move(wp, x + 1, wp->yoff); + window_pane_resize(wp, new_sx, new_sy); + server_redraw_window(w); + } else if (((m->lx == wp->xoff + wp->sx + 1) || + (m->lx == wp->xoff + wp->sx)) && + (m->ly == wp->yoff + wp->sy)) { + /* Bottom right corner */ + new_sx = x - wp->xoff - 1; + if (new_sx < PANE_MINIMUM) + new_sx = PANE_MINIMUM; + new_sy = y - wp->yoff; + if (new_sy < PANE_MINIMUM) + new_sy = PANE_MINIMUM; + window_pane_resize(wp, new_sx, new_sy); + server_redraw_window(w); + } else if (m->lx == wp->xoff + wp->sx + 1) { + /* Right border */ + new_sx = x - wp->xoff - 1; + if (new_sx < PANE_MINIMUM) + return; + window_pane_resize(wp, new_sx, wp->sy); + server_redraw_window(w); + } else if (m->lx == wp->xoff - 1) { + /* Left border */ + new_sx = wp->sx + (lx - x); + if (new_sx < PANE_MINIMUM) + return; + window_pane_move(wp, x + 1, wp->yoff); + window_pane_resize(wp, new_sx, wp->sy); + server_redraw_window(w); + } else if (m->ly == wp->yoff + wp->sy) { + /* Bottom border */ + new_sy = y - wp->yoff; + if (new_sy < PANE_MINIMUM) + return; + window_pane_resize(wp, wp->sx, new_sy); + server_redraw_window(w); + } else if (m->ly == wp->yoff - 1) { + /* Top border */ + window_pane_move(wp, wp->xoff + (x - lx), y + 1); + /* + new_sy = wp->sy + (ly - y); + if (new_sy < PANE_MINIMUM) + return; + window_pane_move(wp, wp->xoff, y + 1); + window_pane_resize(wp, wp->sx, new_sy); + */ + server_redraw_window(w); + } else { + log_debug("%s: %%%u resize_pane xoff=%u sx=%u xy=%ux%u lxy=%ux%u ", + __func__, wp->id, wp->xoff, wp->sx, x, y, lx, ly); + } +} + +static void +cmd_resize_pane_mouse_update_tiled(struct client *c, struct mouse_event *m) { struct winlink *wl; struct window *w; diff --git a/server-client.c b/server-client.c index d8d516b5..02ab0e78 100644 --- a/server-client.c +++ b/server-client.c @@ -637,6 +637,10 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py, return (SCROLLBAR_SLIDER); } else /* py > sl_bottom */ return (SCROLLBAR_DOWN); + } else if (wp->layout_cell == NULL && + (px == wp->xoff - 1 || py == wp->yoff -1)) { + /* Floating pane left or top border. */ + return (BORDER); } else { /* Must be inside the pane. */ return (PANE); @@ -1063,6 +1067,7 @@ have_event: break; } c->tty.mouse_drag_flag = 0; + c->tty.mouse_wp = NULL; c->tty.mouse_slider_mpos = -1; goto out; } @@ -1281,6 +1286,10 @@ 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) { + c->tty.mouse_wp = wp; + } if (c->tty.mouse_scrolling_flag == 0 && where == SCROLLBAR_SLIDER) { c->tty.mouse_scrolling_flag = 1; diff --git a/tmux.h b/tmux.h index 6db37de8..2d85d011 100644 --- a/tmux.h +++ b/tmux.h @@ -1596,7 +1596,7 @@ struct tty { int mouse_drag_flag; int mouse_scrolling_flag; int mouse_slider_mpos; - + struct window_pane *mouse_wp; void (*mouse_drag_update)(struct client *, struct mouse_event *); void (*mouse_drag_release)(struct client *, @@ -3266,6 +3266,7 @@ struct window_pane *window_pane_find_by_id_str(const char *); struct window_pane *window_pane_find_by_id(u_int); int window_pane_destroy_ready(struct window_pane *); void window_pane_resize(struct window_pane *, u_int, u_int); +void window_pane_move(struct window_pane *, u_int, u_int); int window_pane_set_mode(struct window_pane *, struct window_pane *, const struct window_mode *, struct cmd_find_state *, struct args *); diff --git a/window.c b/window.c index 62a53fbb..753f3abb 100644 --- a/window.c +++ b/window.c @@ -1117,6 +1117,18 @@ window_pane_resize(struct window_pane *wp, u_int sx, u_int sy) wme->mode->resize(wme, sx, sy); } +void +window_pane_move(struct window_pane *wp, u_int xoff, u_int yoff) +{ + if (xoff == wp->xoff && yoff == wp->yoff) + return; + + wp->xoff = xoff; + wp->yoff = yoff; + + log_debug("%s: %%%u resize %ux%u", __func__, wp->id, xoff, yoff); +} + int window_pane_set_mode(struct window_pane *wp, struct window_pane *swp, const struct window_mode *mode, struct cmd_find_state *fs,