mirror of
https://github.com/tmux/tmux.git
synced 2025-12-21 00:02:29 -05:00
Add support to drag and resize floating window panes.
This commit is contained in:
parent
39d2839e37
commit
34e858ea05
@ -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 <else>",
|
||||
__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;
|
||||
|
||||
@ -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;
|
||||
|
||||
3
tmux.h
3
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 *);
|
||||
|
||||
12
window.c
12
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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user