Disambiguate between click and doublepress
A doubleprpess should not generate a click event
This commit is contained in:
parent
c6c203da43
commit
76c9f46438
@ -157,7 +157,9 @@ number ``b1 ... b8`` can be used to refer to upto eight buttons on a mouse.
|
||||
``event-type`` is one ``press``, ``release``, ``doublepress``, ``triplepress``,
|
||||
``click`` and ``doubleclick``. ``modes`` indicates whether the action is
|
||||
performed when the mouse is grabbed by the terminal application or not. It can
|
||||
have one or more or the values, ``grabbed,ungrabbed``.
|
||||
have one or more or the values, ``grabbed,ungrabbed``. Note that the click
|
||||
and double click events have a delay of :opt:`click_interval` to disambiguate
|
||||
from double and triple presses.
|
||||
|
||||
You can run kitty with the :option:`kitty --debug-input` command line option
|
||||
to see mouse events. See the builtin actions below to get a sense of what is possible.
|
||||
|
||||
@ -480,11 +480,42 @@ mouse_open_url(Window *w) {
|
||||
screen_open_url(screen);
|
||||
}
|
||||
|
||||
typedef struct PendingClick {
|
||||
id_type window_id;
|
||||
int button, count, modifiers;
|
||||
bool grabbed;
|
||||
monotonic_t at;
|
||||
} PendingClick;
|
||||
|
||||
static void
|
||||
free_pending_click(id_type timer_id UNUSED, void *pc) { free(pc); }
|
||||
|
||||
void
|
||||
send_pending_click_to_window(Window *w, void *data) {
|
||||
PendingClick *pc = (PendingClick*)data;
|
||||
ClickQueue *q = &w->click_queues[pc->button];
|
||||
// only send click if no presses have happened since the release that triggered the click
|
||||
if (q->length && q->clicks[q->length - 1].at <= pc->at) {
|
||||
dispatch_mouse_event(w, pc->button, pc->count, pc->modifiers, pc->grabbed);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dispatch_possible_click(Window *w, int button, int modifiers) {
|
||||
Screen *screen = w->render_data.screen;
|
||||
int count = multi_click_count(w, button);
|
||||
if (release_is_click(w, button)) dispatch_mouse_event(w, button, count == 2 ? -3 : -2, modifiers, screen->modes.mouse_tracking_mode != 0);
|
||||
if (release_is_click(w, button)) {
|
||||
PendingClick *pc = calloc(sizeof(PendingClick), 1);
|
||||
if (pc) {
|
||||
pc->window_id = w->id;
|
||||
pc->at = monotonic();
|
||||
pc->button = button;
|
||||
pc->count = count == 2 ? -3 : -2;
|
||||
pc->modifiers = modifiers;
|
||||
pc->grabbed = screen->modes.mouse_tracking_mode != 0;
|
||||
add_main_loop_timer(OPT(click_interval), false, send_pending_click_to_window_id, pc, free_pending_click);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HANDLER(handle_button_event) {
|
||||
|
||||
@ -525,6 +525,24 @@ make_window_context_current(id_type window_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
send_pending_click_to_window_id(id_type timer_id UNUSED, void *data) {
|
||||
id_type window_id = *((id_type*)data);
|
||||
for (size_t o = 0; o < global_state.num_os_windows; o++) {
|
||||
OSWindow *osw = global_state.os_windows + o;
|
||||
for (size_t t = 0; t < osw->num_tabs; t++) {
|
||||
Tab *qtab = osw->tabs + t;
|
||||
for (size_t w = 0; w < qtab->num_windows; w++) {
|
||||
Window *window = qtab->windows + w;
|
||||
if (window->id == window_id) {
|
||||
send_pending_click_to_window(window, data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Python API {{{
|
||||
#define PYWRAP0(name) static PyObject* py##name(PYNOARG)
|
||||
|
||||
@ -292,3 +292,5 @@ Window* window_for_window_id(id_type kitty_window_id);
|
||||
void mouse_open_url(Window *w);
|
||||
void mouse_selection(Window *w, int code, int button);
|
||||
const char* format_mods(unsigned mods);
|
||||
void send_pending_click_to_window_id(id_type, void*);
|
||||
void send_pending_click_to_window(Window*, void*);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user