diff --git a/screen-redraw.c b/screen-redraw.c index d3328dc8..cce06011 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -165,7 +165,7 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp, if (px == wp->xoff + wp->sx + sb_w - 1) return (SCREEN_REDRAW_BORDER_RIGHT); } - } else { /* sb_pos == PANE_SCROLLBARS_RIGHT or disabled*/ + } else { /* sb_pos == PANE_SCROLLBARS_RIGHT or disabled */ if (wp->xoff == 0 && px == wp->sx + sb_w) if (!hsplit || (hsplit && py <= wp->sy / 2)) return (SCREEN_REDRAW_BORDER_RIGHT); @@ -732,6 +732,78 @@ screen_redraw_draw_borders_style(struct screen_redraw_ctx *ctx, u_int x, return (&wp->border_gc); } +/* Draw arrow indicator if enabled. */ +static void +screen_redraw_draw_border_arrows(struct screen_redraw_ctx *ctx, u_int i, + u_int j, u_int cell_type, struct window_pane *wp, + struct window_pane *active, struct grid_cell *gc) +{ + struct client *c = ctx->c; + struct session *s = c->session; + struct window *w = s->curw->window; + struct options *oo = w->options; + u_int x = ctx->ox + i, y = ctx->oy + j; + int value, arrows = 0, border; + + if (wp == NULL) + return; + if (i != wp->xoff + 1 && j != wp->yoff + 1) + return; + + value = options_get_number(oo, "pane-border-indicators"); + if (value != PANE_BORDER_ARROWS && value != PANE_BORDER_BOTH) + return; + + border = screen_redraw_pane_border(ctx, active, x, y); + if (border == SCREEN_REDRAW_INSIDE) + return; + + if (i == wp->xoff + 1) { + if (border == SCREEN_REDRAW_OUTSIDE) { + if (screen_redraw_two_panes(wp->window, 1)) { + if (active == TAILQ_FIRST(&w->panes)) + border = SCREEN_REDRAW_BORDER_BOTTOM; + else + border = SCREEN_REDRAW_BORDER_TOP; + arrows = 1; + } + } else { + if (cell_type == CELL_LEFTRIGHT) + arrows = 1; + else if (cell_type == CELL_TOPJOIN && + border == SCREEN_REDRAW_BORDER_BOTTOM) + arrows = 1; + else if (cell_type == CELL_BOTTOMJOIN && + border == SCREEN_REDRAW_BORDER_TOP) + arrows = 1; + } + } + if (j == wp->yoff + 1) { + if (border == SCREEN_REDRAW_OUTSIDE) { + if (screen_redraw_two_panes(wp->window, 0)) { + if (active == TAILQ_FIRST(&w->panes)) + border = SCREEN_REDRAW_BORDER_RIGHT; + else + border = SCREEN_REDRAW_BORDER_LEFT; + arrows = 1; + } + } else { + if (cell_type == CELL_TOPBOTTOM) + arrows = 1; + else if (cell_type == CELL_LEFTJOIN && + border == SCREEN_REDRAW_BORDER_RIGHT) + arrows = 1; + else if (cell_type == CELL_RIGHTJOIN && + border == SCREEN_REDRAW_BORDER_LEFT) + arrows = 1; + } + } + if (arrows) { + gc->attr |= GRID_ATTR_CHARSET; + utf8_set(&gc->data, BORDER_MARKERS[border]); + } +} + /* Draw a border cell. */ static void screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j) @@ -747,7 +819,7 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j) const struct grid_cell *tmp; struct overlay_ranges r; u_int cell_type, x = ctx->ox + i, y = ctx->oy + j; - int arrows = 0, border, isolates; + int isolates; if (c->overlay_check != NULL) { c->overlay_check(c, c->overlay_data, x, y, 1, &r); @@ -795,32 +867,7 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j) if (isolates) tty_puts(tty, END_ISOLATE); - switch (options_get_number(oo, "pane-border-indicators")) { - case PANE_BORDER_ARROWS: - case PANE_BORDER_BOTH: - arrows = 1; - break; - } - - if (wp != NULL && arrows) { - border = screen_redraw_pane_border(ctx, active, x, y); - if (((i == wp->xoff + 1 && - (cell_type == CELL_LEFTRIGHT || - (cell_type == CELL_TOPJOIN && - border == SCREEN_REDRAW_BORDER_BOTTOM) || - (cell_type == CELL_BOTTOMJOIN && - border == SCREEN_REDRAW_BORDER_TOP))) || - (j == wp->yoff + 1 && - (cell_type == CELL_TOPBOTTOM || - (cell_type == CELL_LEFTJOIN && - border == SCREEN_REDRAW_BORDER_RIGHT) || - (cell_type == CELL_RIGHTJOIN && - border == SCREEN_REDRAW_BORDER_LEFT)))) && - screen_redraw_check_is(ctx, x, y, active)) { - gc.attr |= GRID_ATTR_CHARSET; - utf8_set(&gc.data, BORDER_MARKERS[border]); - } - } + screen_redraw_draw_border_arrows(ctx, i, j, cell_type, wp, active, &gc); tty_cell(tty, &gc, &grid_default_cell, NULL, NULL); if (isolates) diff --git a/server-client.c b/server-client.c index 6881a141..1ea2fe3e 100644 --- a/server-client.c +++ b/server-client.c @@ -311,6 +311,8 @@ server_client_create(int fd) evtimer_set(&c->repeat_timer, server_client_repeat_timer, c); evtimer_set(&c->click_timer, server_client_click_timer, c); + c->click_wp = -1; + TAILQ_INIT(&c->input_requests); TAILQ_INSERT_TAIL(&clients, c, entry); @@ -733,21 +735,17 @@ server_client_check_mouse(struct client *c, struct key_event *event) if (c->flags & CLIENT_DOUBLECLICK) { evtimer_del(&c->click_timer); c->flags &= ~CLIENT_DOUBLECLICK; - if (m->b == c->click_button) { - type = SECOND; - x = m->x, y = m->y, b = m->b; - log_debug("second-click at %u,%u", x, y); - c->flags |= CLIENT_TRIPLECLICK; - } + type = SECOND; + x = m->x, y = m->y, b = m->b; + log_debug("second-click at %u,%u", x, y); + c->flags |= CLIENT_TRIPLECLICK; } else if (c->flags & CLIENT_TRIPLECLICK) { evtimer_del(&c->click_timer); c->flags &= ~CLIENT_TRIPLECLICK; - if (m->b == c->click_button) { - type = TRIPLE; - x = m->x, y = m->y, b = m->b; - log_debug("triple-click at %u,%u", x, y); - goto have_event; - } + type = TRIPLE; + x = m->x, y = m->y, b = m->b; + log_debug("triple-click at %u,%u", x, y); + goto have_event; } /* DOWN is the only remaining event type. */ @@ -757,17 +755,6 @@ server_client_check_mouse(struct client *c, struct key_event *event) log_debug("down at %u,%u", x, y); c->flags |= CLIENT_DOUBLECLICK; } - - if (KEYC_CLICK_TIMEOUT != 0) { - memcpy(&c->click_event, m, sizeof c->click_event); - c->click_button = m->b; - - log_debug("click timer started"); - tv.tv_sec = KEYC_CLICK_TIMEOUT / 1000; - tv.tv_usec = (KEYC_CLICK_TIMEOUT % 1000) * 1000L; - evtimer_del(&c->click_timer); - evtimer_add(&c->click_timer, &tv); - } } have_event: @@ -883,6 +870,34 @@ have_event: } } + /* Reset click type or add a click timer if needed. */ + if (type == DOWN || + type == SECOND || + type == TRIPLE) { + if (type != DOWN && + (m->b != c->click_button || + where != (enum mouse_where)c->click_where || + m->wp != c->click_wp)) { + type = DOWN; + log_debug("click sequence reset at %u,%u", x, y); + c->flags &= ~CLIENT_TRIPLECLICK; + c->flags |= CLIENT_DOUBLECLICK; + } + + if (type != TRIPLE && KEYC_CLICK_TIMEOUT != 0) { + memcpy(&c->click_event, m, sizeof c->click_event); + c->click_button = m->b; + c->click_where = where; + c->click_wp = m->wp; + + log_debug("click timer started"); + tv.tv_sec = KEYC_CLICK_TIMEOUT / 1000; + tv.tv_usec = (KEYC_CLICK_TIMEOUT % 1000) * 1000L; + evtimer_del(&c->click_timer); + evtimer_add(&c->click_timer, &tv); + } + } + /* Stop dragging if needed. */ if (type != DRAG && type != WHEEL && diff --git a/tmux.h b/tmux.h index f1e769d1..09d0d52b 100644 --- a/tmux.h +++ b/tmux.h @@ -1977,6 +1977,8 @@ struct client { struct event repeat_timer; struct event click_timer; + int click_where; + int click_wp; u_int click_button; struct mouse_event click_event;