Remember last pane or type of location for double and triple clicks and

correctly handle it changes between first and second or second and
third. GitHub issue 4795 from Shaobo Song.
This commit is contained in:
nicm
2026-01-12 07:48:36 +00:00
parent 426467856d
commit a443531280
2 changed files with 40 additions and 23 deletions

View File

@@ -315,6 +315,8 @@ server_client_create(int fd)
evtimer_set(&c->repeat_timer, server_client_repeat_timer, c); evtimer_set(&c->repeat_timer, server_client_repeat_timer, c);
evtimer_set(&c->click_timer, server_client_click_timer, c); evtimer_set(&c->click_timer, server_client_click_timer, c);
c->click_wp = -1;
TAILQ_INIT(&c->input_requests); TAILQ_INIT(&c->input_requests);
TAILQ_INSERT_TAIL(&clients, c, entry); TAILQ_INSERT_TAIL(&clients, c, entry);
@@ -737,21 +739,17 @@ server_client_check_mouse(struct client *c, struct key_event *event)
if (c->flags & CLIENT_DOUBLECLICK) { if (c->flags & CLIENT_DOUBLECLICK) {
evtimer_del(&c->click_timer); evtimer_del(&c->click_timer);
c->flags &= ~CLIENT_DOUBLECLICK; c->flags &= ~CLIENT_DOUBLECLICK;
if (m->b == c->click_button) { type = SECOND;
type = SECOND; x = m->x, y = m->y, b = m->b;
x = m->x, y = m->y, b = m->b; log_debug("second-click at %u,%u", x, y);
log_debug("second-click at %u,%u", x, y); c->flags |= CLIENT_TRIPLECLICK;
c->flags |= CLIENT_TRIPLECLICK;
}
} else if (c->flags & CLIENT_TRIPLECLICK) { } else if (c->flags & CLIENT_TRIPLECLICK) {
evtimer_del(&c->click_timer); evtimer_del(&c->click_timer);
c->flags &= ~CLIENT_TRIPLECLICK; c->flags &= ~CLIENT_TRIPLECLICK;
if (m->b == c->click_button) { type = TRIPLE;
type = TRIPLE; x = m->x, y = m->y, b = m->b;
x = m->x, y = m->y, b = m->b; log_debug("triple-click at %u,%u", x, y);
log_debug("triple-click at %u,%u", x, y); goto have_event;
goto have_event;
}
} }
/* DOWN is the only remaining event type. */ /* DOWN is the only remaining event type. */
@@ -761,17 +759,6 @@ server_client_check_mouse(struct client *c, struct key_event *event)
log_debug("down at %u,%u", x, y); log_debug("down at %u,%u", x, y);
c->flags |= CLIENT_DOUBLECLICK; 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: have_event:
@@ -887,6 +874,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. */ /* Stop dragging if needed. */
if (type != DRAG && if (type != DRAG &&
type != WHEEL && type != WHEEL &&

2
tmux.h
View File

@@ -1942,6 +1942,8 @@ struct client {
struct event repeat_timer; struct event repeat_timer;
struct event click_timer; struct event click_timer;
int click_where;
int click_wp;
u_int click_button; u_int click_button;
struct mouse_event click_event; struct mouse_event click_event;