mirror of
https://github.com/tmux/tmux.git
synced 2026-05-30 14:16:18 +00:00
Pane resizing code for floating panes, mostly by Michael Grant.
This commit is contained in:
@@ -29,8 +29,12 @@
|
|||||||
|
|
||||||
static enum cmd_retval cmd_resize_pane_exec(struct cmd *, struct cmdq_item *);
|
static enum cmd_retval cmd_resize_pane_exec(struct cmd *, struct cmdq_item *);
|
||||||
|
|
||||||
static void cmd_resize_pane_mouse_update(struct client *,
|
static enum cmd_retval cmd_resize_pane_mouse_update(struct cmd *,
|
||||||
struct mouse_event *);
|
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 = {
|
const struct cmd_entry cmd_resize_pane_entry = {
|
||||||
.name = "resize-pane",
|
.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 args *args = cmd_get_args(self);
|
||||||
struct cmd_find_state *target = cmdq_get_target(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 window_pane *wp = target->wp;
|
||||||
struct winlink *wl = target->wl;
|
struct winlink *wl = target->wl;
|
||||||
struct window *w = wl->window;
|
struct window *w = wl->window;
|
||||||
struct client *c = cmdq_get_client(item);
|
const char *errstr;
|
||||||
struct session *s = target->s;
|
|
||||||
const char *errstr;
|
|
||||||
char *cause;
|
char *cause;
|
||||||
u_int adjust;
|
u_int adjust;
|
||||||
int x, y, status;
|
int x, y, status;
|
||||||
@@ -75,15 +76,8 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args_has(args, 'M')) {
|
if (args_has(args, 'M'))
|
||||||
if (!event->m.valid || cmd_mouse_window(&event->m, &s) == NULL)
|
return (cmd_resize_pane_mouse_update(self, 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);
|
|
||||||
return (CMD_RETURN_NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args_has(args, 'Z')) {
|
if (args_has(args, 'Z')) {
|
||||||
if (w->flags & WINDOW_ZOOMED)
|
if (w->flags & WINDOW_ZOOMED)
|
||||||
@@ -148,13 +142,158 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
return (CMD_RETURN_NORMAL);
|
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
|
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 winlink *wl;
|
||||||
struct window *w;
|
struct window *w;
|
||||||
u_int y, ly, x, lx;
|
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 },
|
{ 0, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 },
|
||||||
};
|
};
|
||||||
struct layout_cell *cells[nitems(offsets)], *lc;
|
struct layout_cell *cells[nitems(offsets)], *lc;
|
||||||
|
|||||||
136
server-client.c
136
server-client.c
@@ -603,7 +603,7 @@ server_client_exec(struct client *c, const char *cmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static enum key_code_mouse_location
|
static enum key_code_mouse_location
|
||||||
server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py,
|
server_client_check_mouse_in_pane(struct window_pane *wp, int px, int py,
|
||||||
u_int *sl_mpos)
|
u_int *sl_mpos)
|
||||||
{
|
{
|
||||||
struct window *w = wp->window;
|
struct window *w = wp->window;
|
||||||
@@ -611,7 +611,7 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py,
|
|||||||
struct window_pane *fwp;
|
struct window_pane *fwp;
|
||||||
int pane_status, sb, sb_pos, sb_w, sb_pad;
|
int pane_status, sb, sb_pos, sb_w, sb_pad;
|
||||||
int pane_status_line, sl_top, sl_bottom;
|
int pane_status_line, sl_top, sl_bottom;
|
||||||
int bdr_bottom, bdr_top, bdr_right;
|
int bdr_bottom, bdr_top, bdr_left, bdr_right;
|
||||||
|
|
||||||
sb = options_get_number(wo, "pane-scrollbars");
|
sb = options_get_number(wo, "pane-scrollbars");
|
||||||
sb_pos = options_get_number(wo, "pane-scrollbars-position");
|
sb_pos = options_get_number(wo, "pane-scrollbars-position");
|
||||||
@@ -634,32 +634,37 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py,
|
|||||||
|
|
||||||
/* Check if point is within the pane or scrollbar. */
|
/* Check if point is within the pane or scrollbar. */
|
||||||
if (((pane_status != PANE_STATUS_OFF &&
|
if (((pane_status != PANE_STATUS_OFF &&
|
||||||
(int)py != pane_status_line && py != wp->yoff + wp->sy) ||
|
py != pane_status_line && py != wp->yoff + (int)wp->sy) ||
|
||||||
(wp->yoff == 0 && py < wp->sy) ||
|
(wp->yoff == 0 && py < (int)wp->sy) ||
|
||||||
((int)py >= wp->yoff && py < wp->yoff + wp->sy)) &&
|
(py >= wp->yoff && py < wp->yoff + (int)wp->sy)) &&
|
||||||
((sb_pos == PANE_SCROLLBARS_RIGHT &&
|
((sb_pos == PANE_SCROLLBARS_RIGHT &&
|
||||||
(int)px < (int)wp->xoff + (int)wp->sx + sb_pad + sb_w) ||
|
px < wp->xoff + (int)wp->sx + sb_pad + sb_w) ||
|
||||||
(sb_pos == PANE_SCROLLBARS_LEFT &&
|
(sb_pos == PANE_SCROLLBARS_LEFT &&
|
||||||
(int)px < (int)wp->xoff + (int)wp->sx - sb_pad - sb_w))) {
|
px < wp->xoff + (int)wp->sx - sb_pad - sb_w))) {
|
||||||
/* Check if in the scrollbar. */
|
/* Check if in the scrollbar. */
|
||||||
if ((sb_pos == PANE_SCROLLBARS_RIGHT &&
|
if ((sb_pos == PANE_SCROLLBARS_RIGHT &&
|
||||||
((int)px >= (int)wp->xoff + (int)wp->sx + sb_pad &&
|
(px >= wp->xoff + (int)wp->sx + sb_pad &&
|
||||||
(int)px < (int)wp->xoff + (int)wp->sx + sb_pad + sb_w)) ||
|
px < wp->xoff + (int)wp->sx + sb_pad + sb_w)) ||
|
||||||
(sb_pos == PANE_SCROLLBARS_LEFT &&
|
(sb_pos == PANE_SCROLLBARS_LEFT &&
|
||||||
((int)px >= (int)wp->xoff - sb_pad - sb_w &&
|
(px >= wp->xoff - sb_pad - sb_w &&
|
||||||
(int)px < (int)wp->xoff - sb_pad))) {
|
px < wp->xoff - sb_pad))) {
|
||||||
/* Check where inside the scrollbar. */
|
/* Check where inside the scrollbar. */
|
||||||
sl_top = wp->yoff + wp->sb_slider_y;
|
sl_top = wp->yoff + wp->sb_slider_y;
|
||||||
sl_bottom = (wp->yoff + wp->sb_slider_y +
|
sl_bottom = (wp->yoff + wp->sb_slider_y +
|
||||||
wp->sb_slider_h - 1);
|
wp->sb_slider_h - 1);
|
||||||
if ((int)py < sl_top)
|
if (py < sl_top)
|
||||||
return (KEYC_MOUSE_LOCATION_SCROLLBAR_UP);
|
return (KEYC_MOUSE_LOCATION_SCROLLBAR_UP);
|
||||||
else if ((int)py >= sl_top &&
|
else if (py >= sl_top && py <= sl_bottom) {
|
||||||
(int)py <= sl_bottom) {
|
|
||||||
*sl_mpos = (py - wp->sb_slider_y - wp->yoff);
|
*sl_mpos = (py - wp->sb_slider_y - wp->yoff);
|
||||||
return (KEYC_MOUSE_LOCATION_SCROLLBAR_SLIDER);
|
return (KEYC_MOUSE_LOCATION_SCROLLBAR_SLIDER);
|
||||||
} else /* py > sl_bottom */
|
} else /* py > sl_bottom */
|
||||||
return (KEYC_MOUSE_LOCATION_SCROLLBAR_DOWN);
|
return (KEYC_MOUSE_LOCATION_SCROLLBAR_DOWN);
|
||||||
|
} else if (wp->flags & PANE_FLOATING &&
|
||||||
|
(px == wp->xoff - 1 ||
|
||||||
|
py == wp->yoff - 1 ||
|
||||||
|
py == wp->yoff + (int)wp->sy)) {
|
||||||
|
/* Floating pane left, bottom or top border. */
|
||||||
|
return (KEYC_MOUSE_LOCATION_BORDER);
|
||||||
} else {
|
} else {
|
||||||
/* Must be inside the pane. */
|
/* Must be inside the pane. */
|
||||||
return (KEYC_MOUSE_LOCATION_PANE);
|
return (KEYC_MOUSE_LOCATION_PANE);
|
||||||
@@ -671,22 +676,35 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py,
|
|||||||
(~fwp->flags & PANE_ZOOMED))
|
(~fwp->flags & PANE_ZOOMED))
|
||||||
continue;
|
continue;
|
||||||
bdr_top = fwp->yoff - 1;
|
bdr_top = fwp->yoff - 1;
|
||||||
bdr_bottom = fwp->yoff + (int)fwp->sy;
|
bdr_bottom = fwp->yoff + fwp->sy;
|
||||||
if (sb_pos == PANE_SCROLLBARS_LEFT)
|
if (sb_pos == PANE_SCROLLBARS_LEFT)
|
||||||
bdr_right = fwp->xoff + (int)fwp->sx;
|
bdr_right = fwp->xoff + fwp->sx;
|
||||||
else
|
else {
|
||||||
/* PANE_SCROLLBARS_RIGHT or none. */
|
/* PANE_SCROLLBARS_RIGHT or none. */
|
||||||
bdr_right = fwp->xoff + (int)fwp->sx +
|
bdr_right = fwp->xoff + fwp->sx + sb_pad + sb_w;
|
||||||
sb_pad + sb_w;
|
|
||||||
if ((int)py >= (int)fwp->yoff - 1 &&
|
|
||||||
py <= fwp->yoff + fwp->sy) {
|
|
||||||
if ((int)px == bdr_right)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if ((int)px >= (int)fwp->xoff - 1 &&
|
if (py >= fwp->yoff - 1 &&
|
||||||
px <= fwp->xoff + fwp->sx) {
|
py <= fwp->yoff + (int)fwp->sy) {
|
||||||
if ((int)py == bdr_bottom || (int)py == bdr_top)
|
if (px == bdr_right)
|
||||||
break;
|
break;
|
||||||
|
if (wp->flags & PANE_FLOATING) {
|
||||||
|
/* Floating pane, check left border. */
|
||||||
|
bdr_left = fwp->xoff - 1;
|
||||||
|
if (px == bdr_left)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (px >= fwp->xoff - 1 &&
|
||||||
|
px <= fwp->xoff + (int)fwp->sx) {
|
||||||
|
bdr_bottom = fwp->yoff + fwp->sy;
|
||||||
|
if (py == bdr_bottom)
|
||||||
|
break;
|
||||||
|
if (wp->flags & PANE_FLOATING) {
|
||||||
|
/* Floating pane, check top border. */
|
||||||
|
bdr_top = fwp->yoff - 1;
|
||||||
|
if (py == bdr_top)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fwp != NULL)
|
if (fwp != NULL)
|
||||||
@@ -703,7 +721,7 @@ server_client_check_mouse(struct client *c, struct key_event *event)
|
|||||||
struct session *s = c->session, *fs;
|
struct session *s = c->session, *fs;
|
||||||
struct window *w = s->curw->window;
|
struct window *w = s->curw->window;
|
||||||
struct winlink *fwl;
|
struct winlink *fwl;
|
||||||
struct window_pane *wp, *fwp;
|
struct window_pane *wp, *fwp, *lwp = NULL;
|
||||||
u_int x, y, sx, sy, px, py, n, sl_mpos = 0;
|
u_int x, y, sx, sy, px, py, n, sl_mpos = 0;
|
||||||
u_int b, bn;
|
u_int b, bn;
|
||||||
int ignore = 0;
|
int ignore = 0;
|
||||||
@@ -716,6 +734,13 @@ server_client_check_mouse(struct client *c, struct key_event *event)
|
|||||||
log_debug("%s mouse %02x at %u,%u (last %u,%u) (%d)", c->name, m->b,
|
log_debug("%s mouse %02x at %u,%u (last %u,%u) (%d)", c->name, m->b,
|
||||||
m->x, m->y, m->lx, m->ly, c->tty.mouse_drag_flag);
|
m->x, m->y, m->lx, m->ly, c->tty.mouse_drag_flag);
|
||||||
|
|
||||||
|
/* Find last pane, if any. */
|
||||||
|
if (c->tty.mouse_last_pane != -1) {
|
||||||
|
lwp = window_pane_find_by_id(c->tty.mouse_last_pane);
|
||||||
|
if (lwp != NULL)
|
||||||
|
log_debug("%s mouse last pane %%%u", c->name, lwp->id);
|
||||||
|
}
|
||||||
|
|
||||||
/* What type of event is this? */
|
/* What type of event is this? */
|
||||||
if (event->key == KEYC_DOUBLECLICK) {
|
if (event->key == KEYC_DOUBLECLICK) {
|
||||||
type = KEYC_TYPE_DOUBLECLICK;
|
type = KEYC_TYPE_DOUBLECLICK;
|
||||||
@@ -859,9 +884,13 @@ have_event:
|
|||||||
* scrollbar.
|
* scrollbar.
|
||||||
*/
|
*/
|
||||||
if (loc == KEYC_MOUSE_LOCATION_NOWHERE) {
|
if (loc == KEYC_MOUSE_LOCATION_NOWHERE) {
|
||||||
if (c->tty.mouse_scrolling_flag)
|
if (c->tty.mouse_scrolling_flag) {
|
||||||
loc = KEYC_MOUSE_LOCATION_SCROLLBAR_SLIDER;
|
if (lwp != NULL) {
|
||||||
else {
|
loc = KEYC_MOUSE_LOCATION_SCROLLBAR_SLIDER;
|
||||||
|
m->wp = lwp->id;
|
||||||
|
m->w = lwp->window->id;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
px = x;
|
px = x;
|
||||||
if (m->statusat == 0 && y >= m->statuslines)
|
if (m->statusat == 0 && y >= m->statuslines)
|
||||||
py = y - m->statuslines;
|
py = y - m->statuslines;
|
||||||
@@ -878,8 +907,13 @@ have_event:
|
|||||||
px = px + m->ox;
|
px = px + m->ox;
|
||||||
py = py + m->oy;
|
py = py + m->oy;
|
||||||
|
|
||||||
/* Try inside the pane. */
|
if (type == KEYC_TYPE_MOUSEDRAG && lwp != NULL) {
|
||||||
wp = window_get_active_at(w, px, py);
|
/* Use pane from last mouse event. */
|
||||||
|
wp = lwp;
|
||||||
|
} else {
|
||||||
|
/* Try inside the pane. */
|
||||||
|
wp = window_get_active_at(w, px, py);
|
||||||
|
}
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return (KEYC_UNKNOWN);
|
return (KEYC_UNKNOWN);
|
||||||
loc = server_client_check_mouse_in_pane(wp, px, py,
|
loc = server_client_check_mouse_in_pane(wp, px, py,
|
||||||
@@ -958,6 +992,7 @@ have_event:
|
|||||||
type = KEYC_TYPE_MOUSEDRAGEND;
|
type = KEYC_TYPE_MOUSEDRAGEND;
|
||||||
c->tty.mouse_drag_flag = 0;
|
c->tty.mouse_drag_flag = 0;
|
||||||
c->tty.mouse_slider_mpos = -1;
|
c->tty.mouse_slider_mpos = -1;
|
||||||
|
c->tty.mouse_last_pane = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert to a key binding. */
|
/* Convert to a key binding. */
|
||||||
@@ -966,6 +1001,7 @@ have_event:
|
|||||||
if (wp != NULL &&
|
if (wp != NULL &&
|
||||||
wp != w->active &&
|
wp != w->active &&
|
||||||
options_get_number(s->options, "focus-follows-mouse")) {
|
options_get_number(s->options, "focus-follows-mouse")) {
|
||||||
|
window_redraw_active_switch(w, wp);
|
||||||
window_set_active_pane(w, wp, 1);
|
window_set_active_pane(w, wp, 1);
|
||||||
server_redraw_window_borders(w);
|
server_redraw_window_borders(w);
|
||||||
server_status_window(w);
|
server_status_window(w);
|
||||||
@@ -982,6 +1018,12 @@ have_event:
|
|||||||
* where the user grabbed.
|
* where the user grabbed.
|
||||||
*/
|
*/
|
||||||
c->tty.mouse_drag_flag = MOUSE_BUTTONS(b) + 1;
|
c->tty.mouse_drag_flag = MOUSE_BUTTONS(b) + 1;
|
||||||
|
|
||||||
|
/* Only change pane if not already dragging a pane border. */
|
||||||
|
if (lwp == NULL) {
|
||||||
|
lwp = wp = window_get_active_at(w, px, py);
|
||||||
|
c->tty.mouse_last_pane = wp->id;
|
||||||
|
}
|
||||||
if (c->tty.mouse_scrolling_flag == 0 &&
|
if (c->tty.mouse_scrolling_flag == 0 &&
|
||||||
loc == KEYC_MOUSE_LOCATION_SCROLLBAR_SLIDER) {
|
loc == KEYC_MOUSE_LOCATION_SCROLLBAR_SLIDER) {
|
||||||
c->tty.mouse_scrolling_flag = 1;
|
c->tty.mouse_scrolling_flag = 1;
|
||||||
@@ -1723,6 +1765,7 @@ server_client_reset_state(struct client *c)
|
|||||||
struct options *oo = c->session->options;
|
struct options *oo = c->session->options;
|
||||||
int mode = 0, cursor, flags;
|
int mode = 0, cursor, flags;
|
||||||
u_int cx = 0, cy = 0, ox, oy, sx, sy, n;
|
u_int cx = 0, cy = 0, ox, oy, sx, sy, n;
|
||||||
|
struct visible_ranges *r;
|
||||||
|
|
||||||
if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
|
if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
|
||||||
return;
|
return;
|
||||||
@@ -1735,7 +1778,7 @@ server_client_reset_state(struct client *c)
|
|||||||
if (c->overlay_draw != NULL) {
|
if (c->overlay_draw != NULL) {
|
||||||
if (c->overlay_mode != NULL)
|
if (c->overlay_mode != NULL)
|
||||||
s = c->overlay_mode(c, c->overlay_data, &cx, &cy);
|
s = c->overlay_mode(c, c->overlay_data, &cx, &cy);
|
||||||
} else if (c->prompt_string == NULL)
|
} else if (wp != NULL && c->prompt_string == NULL)
|
||||||
s = wp->screen;
|
s = wp->screen;
|
||||||
else
|
else
|
||||||
s = c->status.active;
|
s = c->status.active;
|
||||||
@@ -1763,22 +1806,30 @@ server_client_reset_state(struct client *c)
|
|||||||
cy = tty->sy - 1;
|
cy = tty->sy - 1;
|
||||||
}
|
}
|
||||||
cx = c->prompt_cursor;
|
cx = c->prompt_cursor;
|
||||||
} else if (c->overlay_draw == NULL) {
|
} else if (wp != NULL && c->overlay_draw == NULL) {
|
||||||
cursor = 0;
|
cursor = 0;
|
||||||
tty_window_offset(tty, &ox, &oy, &sx, &sy);
|
tty_window_offset(tty, &ox, &oy, &sx, &sy);
|
||||||
if (wp->xoff + s->cx >= ox && wp->xoff + s->cx <= ox + sx &&
|
if (wp->xoff + (int)s->cx >= (int)ox &&
|
||||||
wp->yoff + s->cy >= oy && wp->yoff + s->cy <= oy + sy) {
|
wp->xoff + (int)s->cx <= (int)ox + (int)sx &&
|
||||||
|
wp->yoff + (int)s->cy >= (int)oy &&
|
||||||
|
wp->yoff + (int)s->cy <= (int)oy + (int)sy) {
|
||||||
cursor = 1;
|
cursor = 1;
|
||||||
|
|
||||||
cx = wp->xoff + s->cx - ox;
|
cx = wp->xoff + (int)s->cx - (int)ox;
|
||||||
cy = wp->yoff + s->cy - oy;
|
cy = wp->yoff + (int)s->cy - (int)oy;
|
||||||
|
|
||||||
if (status_at_line(c) == 0)
|
if (status_at_line(c) == 0)
|
||||||
cy += status_line_size(c);
|
cy += status_line_size(c);
|
||||||
}
|
}
|
||||||
|
r = screen_redraw_get_visible_ranges(wp, cx, cy, 1, NULL);
|
||||||
|
if (!screen_redraw_is_visible(r, cx))
|
||||||
|
cursor = 0;
|
||||||
|
|
||||||
if (!cursor)
|
if (!cursor)
|
||||||
mode &= ~MODE_CURSOR;
|
mode &= ~MODE_CURSOR;
|
||||||
}
|
} else if (c->overlay_mode == NULL || s == NULL)
|
||||||
|
mode &= ~MODE_CURSOR;
|
||||||
|
|
||||||
log_debug("%s: cursor to %u,%u", __func__, cx, cy);
|
log_debug("%s: cursor to %u,%u", __func__, cx, cy);
|
||||||
tty_cursor(tty, cx, cy);
|
tty_cursor(tty, cx, cy);
|
||||||
|
|
||||||
@@ -2119,7 +2170,7 @@ server_client_set_path(struct client *c)
|
|||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
const char *path;
|
const char *path;
|
||||||
|
|
||||||
if (s->curw == NULL)
|
if (s->curw == NULL || s->curw->window->active == NULL)
|
||||||
return;
|
return;
|
||||||
if (s->curw->window->active->base.path == NULL)
|
if (s->curw->window->active->base.path == NULL)
|
||||||
path = "";
|
path = "";
|
||||||
@@ -2733,6 +2784,11 @@ server_client_remove_pane(struct window_pane *wp)
|
|||||||
RB_REMOVE(client_windows, &c->windows, cw);
|
RB_REMOVE(client_windows, &c->windows, cw);
|
||||||
free(cw);
|
free(cw);
|
||||||
}
|
}
|
||||||
|
if (c->tty.mouse_last_pane == (int)wp->id) {
|
||||||
|
c->tty.mouse_last_pane = -1;
|
||||||
|
c->tty.mouse_drag_update = NULL;
|
||||||
|
c->tty.mouse_scrolling_flag = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
tmux.h
2
tmux.h
@@ -1674,7 +1674,7 @@ struct tty {
|
|||||||
int mouse_drag_flag;
|
int mouse_drag_flag;
|
||||||
int mouse_scrolling_flag;
|
int mouse_scrolling_flag;
|
||||||
int mouse_slider_mpos;
|
int mouse_slider_mpos;
|
||||||
|
int mouse_last_pane;
|
||||||
void (*mouse_drag_update)(struct client *,
|
void (*mouse_drag_update)(struct client *,
|
||||||
struct mouse_event *);
|
struct mouse_event *);
|
||||||
void (*mouse_drag_release)(struct client *,
|
void (*mouse_drag_release)(struct client *,
|
||||||
|
|||||||
Reference in New Issue
Block a user