diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c index b00c0d78..88c050b3 100644 --- a/cmd-resize-pane.c +++ b/cmd-resize-pane.c @@ -29,10 +29,12 @@ static enum cmd_retval cmd_resize_pane_exec(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 *); +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", @@ -53,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; @@ -77,23 +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) - 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) { - 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); - } else { - c->tty.mouse_drag_update = cmd_resize_pane_mouse_update_tiled; - cmd_resize_pane_mouse_update_tiled(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) @@ -158,6 +142,37 @@ 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_floating(struct client *c, struct mouse_event *m) { @@ -165,8 +180,7 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m) struct window *w; struct window_pane *wp; struct layout_cell *lc; - u_int y, ly, x, lx; - int new_sx, new_sy; + 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); @@ -176,108 +190,95 @@ cmd_resize_pane_mouse_update_floating(struct client *c, struct mouse_event *m) } 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 >= m->statuslines) + if (m->statusat == 0 && y >= (int)m->statuslines) y -= m->statuslines; - else if (m->statusat > 0 && y >= (u_int)m->statusat) + 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 >= (u_int)m->statuslines) + if (m->statusat == 0 && ly >= (int)m->statuslines) ly -= m->statuslines; - else if (m->statusat > 0 && ly >= (u_int)m->statusat) + else if (m->statusat > 0 && ly >= m->statusat) ly = m->statusat - 1; - log_debug("%s: %%%u resize_pane xoff=%d sx=%u xy=%ux%u lxy=%ux%u", - __func__, wp->id, wp->xoff, wp->sx, x, y, lx, ly); - if ((((int)lx == wp->xoff - 1) || ((int)lx == wp->xoff)) && - ((int)ly == wp->yoff - 1)) { - /* Top left corner */ - new_sx = (int)lc->sx + ((int)lx - (int)x); + 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 = (int)lc->sy + ((int)ly - (int)y); + 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_xoff = x + 1; /* because mouse is on border at xoff - 1 */ new_yoff = y + 1; - layout_set_size(lc, (u_int)new_sx, (u_int)new_sy, new_xoff, new_yoff); + layout_set_size(lc, new_sx, new_sy, new_xoff, new_yoff); resizes++; - } else if ((((int)lx == wp->xoff + (int)wp->sx + 1) || - ((int)lx == wp->xoff + (int)wp->sx)) && - ((int)ly == wp->yoff - 1)) { - /* Top right corner */ - new_sx = (int)x - lc->xoff; + } 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 = (int)lc->sy + ((int)ly - (int)y); + new_sy = lc->sy + (ly - y); if (new_sy < PANE_MINIMUM) new_sy = PANE_MINIMUM; new_yoff = y + 1; - layout_set_size(lc, (u_int)new_sx, (u_int)new_sy, lc->xoff, new_yoff); + layout_set_size(lc, new_sx, new_sy, lc->xoff, new_yoff); resizes++; - } else if ((((int)lx == wp->xoff - 1) || ((int)lx == wp->xoff)) && - ((int)ly == wp->yoff + (int)wp->sy)) { - /* Bottom left corner */ - new_sx = (int)lc->sx + ((int)lx - (int)x); + } 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 = (int)y - lc->yoff; + new_sy = y - lc->yoff; if (new_sy < PANE_MINIMUM) return; new_xoff = x + 1; - layout_set_size(lc, (u_int)new_sx, (u_int)new_sy, new_xoff, lc->yoff); + layout_set_size(lc, new_sx, new_sy, new_xoff, lc->yoff); resizes++; - } else if ((((int)lx == wp->xoff + (int)wp->sx + 1) || - ((int)lx == wp->xoff + (int)wp->sx)) && - ((int)ly == wp->yoff + (int)wp->sy)) { - /* Bottom right corner */ - new_sx = (int)x - lc->xoff; + } 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 = (int)y - lc->yoff; + new_sy = y - lc->yoff; if (new_sy < PANE_MINIMUM) new_sy = PANE_MINIMUM; - layout_set_size(lc, (u_int)new_sx, (u_int)new_sy, lc->xoff, lc->yoff); + layout_set_size(lc, new_sx, new_sy, lc->xoff, lc->yoff); resizes++; - } else if ((int)lx == wp->xoff + (int)wp->sx + 1) { - /* Right border */ - new_sx = (int)x - lc->xoff; + } else if (lx == wp->xoff + sx + 1) { + /* Right border. */ + new_sx = x - lc->xoff; if (new_sx < PANE_MINIMUM) return; - layout_set_size(lc, (u_int)new_sx, lc->sy, lc->xoff, lc->yoff); + layout_set_size(lc, new_sx, lc->sy, lc->xoff, lc->yoff); resizes++; - } else if ((int)lx == wp->xoff - 1) { - /* Left border */ - new_sx = (int)lc->sx + ((int)lx - (int)x); + } 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, (u_int)new_sx, lc->sy, new_xoff, lc->yoff); + layout_set_size(lc, new_sx, lc->sy, new_xoff, lc->yoff); resizes++; - } else if ((int)ly == wp->yoff + (int)wp->sy) { - /* Bottom border */ - new_sy = (int)y - lc->yoff; + } 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, (u_int)new_sy, lc->xoff, lc->yoff); + layout_set_size(lc, lc->sx, new_sy, lc->xoff, lc->yoff); resizes++; - } else if ((int)ly == wp->yoff - 1) { - /* Top border (move instead of resize) */ - new_xoff = lc->xoff + ((int)x - (int)lx); + } 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); - /* To resize instead of move: - new_sy = wp->sy + (ly - y); - if (new_sy < PANE_MINIMUM) - return; - new_yoff = y + 1; - layout_set_size(lc, lc->sx, new_sy, lc->xoff, new_yoff); - */ resizes++; - } else { - log_debug("%s: %%%u resize_pane xoff=%d sx=%u xy=%ux%u lxy=%ux%u ", - __func__, wp->id, wp->xoff, wp->sx, x, y, lx, ly); } if (resizes != 0) { layout_fix_panes(w, NULL); @@ -292,7 +293,7 @@ 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; diff --git a/server-client.c b/server-client.c index ba6f3a83..60169277 100644 --- a/server-client.c +++ b/server-client.c @@ -599,7 +599,7 @@ server_client_exec(struct client *c, const char *cmd) } 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) { struct window *w = wp->window; @@ -630,36 +630,35 @@ 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. */ if (((pane_status != PANE_STATUS_OFF && - (int)py != pane_status_line && (int)py != wp->yoff + (int)wp->sy) || - (wp->yoff == 0 && py < wp->sy) || - ((int)py >= wp->yoff && (int)py < wp->yoff + (int)wp->sy)) && + py != pane_status_line && py != wp->yoff + (int)wp->sy) || + (wp->yoff == 0 && py < (int)wp->sy) || + (py >= wp->yoff && py < wp->yoff + (int)wp->sy)) && ((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 && - (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. */ if ((sb_pos == PANE_SCROLLBARS_RIGHT && - ((int)px >= (int)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 && + px < wp->xoff + (int)wp->sx + sb_pad + sb_w)) || (sb_pos == PANE_SCROLLBARS_LEFT && - ((int)px >= (int)wp->xoff - sb_pad - sb_w && - (int)px < (int)wp->xoff - sb_pad))) { + (px >= wp->xoff - sb_pad - sb_w && + px < wp->xoff - sb_pad))) { /* Check where inside the scrollbar. */ sl_top = wp->yoff + wp->sb_slider_y; sl_bottom = (wp->yoff + wp->sb_slider_y + wp->sb_slider_h - 1); - if ((int)py < sl_top) + if (py < sl_top) return (KEYC_MOUSE_LOCATION_SCROLLBAR_UP); - else if ((int)py >= sl_top && - (int)py <= sl_bottom) { + else if (py >= sl_top && py <= sl_bottom) { *sl_mpos = (py - wp->sb_slider_y - wp->yoff); return (KEYC_MOUSE_LOCATION_SCROLLBAR_SLIDER); } else /* py > sl_bottom */ return (KEYC_MOUSE_LOCATION_SCROLLBAR_DOWN); } else if (wp->flags & PANE_FLOATING && - ((int)px == wp->xoff - 1 || - (int)py == wp->yoff - 1 || - (int)py == wp->yoff + (int)wp->sy)) { + (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 { @@ -673,33 +672,33 @@ server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py, (~fwp->flags & PANE_ZOOMED)) continue; bdr_top = fwp->yoff - 1; - bdr_bottom = fwp->yoff + (int)fwp->sy; + bdr_bottom = fwp->yoff + fwp->sy; if (sb_pos == PANE_SCROLLBARS_LEFT) - bdr_right = fwp->xoff + (int)fwp->sx; - else + bdr_right = fwp->xoff + fwp->sx; + else { /* PANE_SCROLLBARS_RIGHT or none. */ - bdr_right = fwp->xoff + (int)fwp->sx + - sb_pad + sb_w; - if ((int)py >= fwp->yoff - 1 && - (int)py <= fwp->yoff + (int)fwp->sy) { - if ((int)px == bdr_right) + bdr_right = fwp->xoff + fwp->sx + sb_pad + sb_w; + } + if (py >= fwp->yoff - 1 && + py <= fwp->yoff + (int)fwp->sy) { + if (px == bdr_right) break; if (wp->flags & PANE_FLOATING) { - /* Floating pane, check if left border. */ + /* Floating pane, check left border. */ bdr_left = fwp->xoff - 1; - if ((int)px == bdr_left) + if (px == bdr_left) break; } } - if ((int)px >= fwp->xoff - 1 && - (int)px <= fwp->xoff + (int)fwp->sx) { - bdr_bottom = fwp->yoff + (int)fwp->sy; - if ((int)py == bdr_bottom) + 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 if top border. */ + /* Floating pane, check top border. */ bdr_top = fwp->yoff - 1; - if ((int)py == bdr_top) + if (py == bdr_top) break; } } @@ -989,7 +988,7 @@ have_event: type = KEYC_TYPE_MOUSEDRAGEND; c->tty.mouse_drag_flag = 0; c->tty.mouse_slider_mpos = -1; - c->tty.mouse_last_pane = -1; + c->tty.mouse_last_pane = -1; } /* Convert to a key binding. */ @@ -998,7 +997,7 @@ have_event: if (wp != NULL && wp != w->active && options_get_number(s->options, "focus-follows-mouse")) { - window_redraw_active_switch(w, wp); /* xxx needed? */ + window_redraw_active_switch(w, wp); window_set_active_pane(w, wp, 1); server_redraw_window_borders(w); server_status_window(w); @@ -1415,14 +1414,6 @@ forward_key: } if (c->flags & CLIENT_READONLY) goto out; - if (wp != NULL && - options_get_number(wp->options, "remain-on-exit") == 3 && - (wp->flags & PANE_EXITED) && - !KEYC_IS_MOUSE(key) && !KEYC_IS_PASTE(key)) { - options_set_number(wp->options, "remain-on-exit", 0); - server_destroy_pane(wp, 0); - goto out; - } if (wp != NULL) window_pane_key(wp, c, s, wl, key, m); goto out; @@ -1807,6 +1798,7 @@ server_client_reset_state(struct client *c) struct options *oo = c->session->options; int mode = 0, cursor, flags; u_int cx = 0, cy = 0, ox, oy, sx, sy, n; + struct visible_ranges *r; if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED)) return; @@ -1856,14 +1848,14 @@ server_client_reset_state(struct client *c) wp->yoff + (int)s->cy <= (int)oy + (int)sy) { cursor = 1; - cx = (u_int)(wp->xoff + (int)s->cx - (int)ox); - cy = (u_int)(wp->yoff + (int)s->cy - (int)oy); + cx = wp->xoff + (int)s->cx - (int)ox; + cy = wp->yoff + (int)s->cy - (int)oy; if (status_at_line(c) == 0) cy += status_line_size(c); } - if (!screen_redraw_is_visible( - screen_redraw_get_visible_ranges(wp, cx, cy, 1, NULL), cx)) + r = screen_redraw_get_visible_ranges(wp, cx, cy, 1, NULL); + if (!screen_redraw_is_visible(r, cx)) cursor = 0; if (!cursor) diff --git a/tmux.h b/tmux.h index 4908419d..57392984 100644 --- a/tmux.h +++ b/tmux.h @@ -1712,7 +1712,7 @@ struct tty { int mouse_drag_flag; int mouse_scrolling_flag; int mouse_slider_mpos; - int mouse_last_pane; + int mouse_last_pane; void (*mouse_drag_update)(struct client *, struct mouse_event *); void (*mouse_drag_release)(struct client *, diff --git a/window.c b/window.c index bf0d90f1..6cb175c3 100644 --- a/window.c +++ b/window.c @@ -805,26 +805,41 @@ window_add_pane(struct window *w, struct window_pane *other, u_int hlimit, void window_lost_pane(struct window *w, struct window_pane *wp) { + struct window_pane *wpp, *twpp; + log_debug("%s: @%u pane %%%u", __func__, w->id, wp->id); if (wp == marked_pane.wp) server_clear_marked(); window_pane_stack_remove(&w->last_panes, wp); - if (wp == w->active) { - w->active = TAILQ_FIRST(&w->last_panes); - if (w->active == NULL) { - w->active = TAILQ_PREV(wp, window_panes, entry); - if (w->active == NULL) - w->active = TAILQ_NEXT(wp, entry); - } - if (w->active != NULL) { - window_pane_stack_remove(&w->last_panes, w->active); - w->active->flags |= PANE_CHANGED; - notify_window("window-pane-changed", w); - window_update_focus(w); + if (wp != w->active) + return; + + /* Try to find a good fit. */ + wpp = TAILQ_FIRST(&w->last_panes); + if (wpp == NULL || wpp->flags & PANE_HIDDEN) { + wpp = TAILQ_PREV(wp, window_panes, entry); + if (wpp == NULL || wpp->flags & PANE_HIDDEN) + wpp = TAILQ_NEXT(wp, entry); + } + /* Try to find any fit. */ + if (wpp == NULL || (wpp->flags & PANE_HIDDEN)) { + TAILQ_FOREACH_SAFE(wpp, &w->panes, entry, twpp) { + if (wpp != wp && (~wpp->flags & PANE_HIDDEN)) + break; } } + if (wpp != NULL && (wpp->flags & PANE_HIDDEN)) + wpp = NULL; + + w->active = wpp; + if (w->active != NULL) { + window_pane_stack_remove(&w->last_panes, w->active); + w->active->flags |= PANE_CHANGED; + notify_window("window-pane-changed", w); + window_update_focus(w); + } } void