When double or triple clicking ignore clicks if they are "far" from each other
Fixes #1093
This commit is contained in:
parent
b44345d78e
commit
a0ff625f61
@ -89,6 +89,9 @@ Changelog
|
|||||||
- Fix incorrect text-antialiasing when using very low background opacity
|
- Fix incorrect text-antialiasing when using very low background opacity
|
||||||
(:iss:`1005`)
|
(:iss:`1005`)
|
||||||
|
|
||||||
|
- When double or triple clicking ignore clicks if they are "far" from each
|
||||||
|
other (:iss:`1093`)
|
||||||
|
|
||||||
0.12.3 [2018-09-29]
|
0.12.3 [2018-09-29]
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -85,7 +85,7 @@ encode_mouse_event_impl(unsigned int x, unsigned int y, int mouse_tracking_proto
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
encode_mouse_event(Window *w, int button, MouseAction action, int mods) {
|
encode_mouse_event(Window *w, int button, MouseAction action, int mods) {
|
||||||
unsigned int x = w->mouse_cell_x + 1, y = w->mouse_cell_y + 1; // 1 based indexing
|
unsigned int x = w->mouse_pos.cell_x + 1, y = w->mouse_pos.cell_y + 1; // 1 based indexing
|
||||||
Screen *screen = w->render_data.screen;
|
Screen *screen = w->render_data.screen;
|
||||||
return encode_mouse_event_impl(x, y, screen->modes.mouse_tracking_protocol, button, action, mods);
|
return encode_mouse_event_impl(x, y, screen->modes.mouse_tracking_protocol, button, action, mods);
|
||||||
|
|
||||||
@ -142,6 +142,7 @@ cell_for_pos(Window *w, unsigned int *x, unsigned int *y, OSWindow *os_window) {
|
|||||||
mouse_x = MIN(MAX(mouse_x, left), right);
|
mouse_x = MIN(MAX(mouse_x, left), right);
|
||||||
mouse_y = MIN(MAX(mouse_y, top), bottom);
|
mouse_y = MIN(MAX(mouse_y, top), bottom);
|
||||||
}
|
}
|
||||||
|
w->mouse_pos.x = mouse_x - left; w->mouse_pos.y = mouse_y - top;
|
||||||
if (mouse_x < left || mouse_y < top || mouse_x > right || mouse_y > bottom) return false;
|
if (mouse_x < left || mouse_y < top || mouse_x > right || mouse_y > bottom) return false;
|
||||||
if (mouse_x >= g->right) qx = screen->columns - 1;
|
if (mouse_x >= g->right) qx = screen->columns - 1;
|
||||||
else if (mouse_x >= g->left) qx = (unsigned int)((double)(mouse_x - g->left) / os_window->fonts_data->cell_width);
|
else if (mouse_x >= g->left) qx = (unsigned int)((double)(mouse_x - g->left) / os_window->fonts_data->cell_width);
|
||||||
@ -164,14 +165,14 @@ update_drag(bool from_button, Window *w, bool is_release, int modifiers) {
|
|||||||
global_state.active_drag_in_window = 0;
|
global_state.active_drag_in_window = 0;
|
||||||
w->last_drag_scroll_at = 0;
|
w->last_drag_scroll_at = 0;
|
||||||
if (screen->selection.in_progress)
|
if (screen->selection.in_progress)
|
||||||
screen_update_selection(screen, w->mouse_cell_x, w->mouse_cell_y, true);
|
screen_update_selection(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
global_state.active_drag_in_window = w->id;
|
global_state.active_drag_in_window = w->id;
|
||||||
screen_start_selection(screen, w->mouse_cell_x, w->mouse_cell_y, modifiers == (int)OPT(rectangle_select_modifiers) || modifiers == ((int)OPT(rectangle_select_modifiers) | GLFW_MOD_SHIFT), EXTEND_CELL);
|
screen_start_selection(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y, modifiers == (int)OPT(rectangle_select_modifiers) || modifiers == ((int)OPT(rectangle_select_modifiers) | GLFW_MOD_SHIFT), EXTEND_CELL);
|
||||||
}
|
}
|
||||||
} else if (screen->selection.in_progress) {
|
} else if (screen->selection.in_progress) {
|
||||||
screen_update_selection(screen, w->mouse_cell_x, w->mouse_cell_y, false);
|
screen_update_selection(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,7 +202,7 @@ static inline void
|
|||||||
extend_selection(Window *w) {
|
extend_selection(Window *w) {
|
||||||
Screen *screen = w->render_data.screen;
|
Screen *screen = w->render_data.screen;
|
||||||
if (screen_has_selection(screen)) {
|
if (screen_has_selection(screen)) {
|
||||||
screen_update_selection(screen, w->mouse_cell_x, w->mouse_cell_y, false);
|
screen_update_selection(screen, w->mouse_pos.cell_x, w->mouse_pos.cell_y, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,8 +277,8 @@ HANDLER(handle_move_event) {
|
|||||||
if (!cell_for_pos(w, &x, &y, global_state.callback_os_window)) return;
|
if (!cell_for_pos(w, &x, &y, global_state.callback_os_window)) return;
|
||||||
Screen *screen = w->render_data.screen;
|
Screen *screen = w->render_data.screen;
|
||||||
detect_url(screen, x, y);
|
detect_url(screen, x, y);
|
||||||
bool mouse_cell_changed = x != w->mouse_cell_x || y != w->mouse_cell_y;
|
bool mouse_cell_changed = x != w->mouse_pos.cell_x || y != w->mouse_pos.cell_y;
|
||||||
w->mouse_cell_x = x; w->mouse_cell_y = y;
|
w->mouse_pos.cell_x = x; w->mouse_pos.cell_y = y;
|
||||||
bool handle_in_kitty = (
|
bool handle_in_kitty = (
|
||||||
(screen->modes.mouse_tracking_mode == ANY_MODE ||
|
(screen->modes.mouse_tracking_mode == ANY_MODE ||
|
||||||
(screen->modes.mouse_tracking_mode == MOTION_MODE && button >= 0)) &&
|
(screen->modes.mouse_tracking_mode == MOTION_MODE && button >= 0)) &&
|
||||||
@ -304,14 +305,14 @@ multi_click(Window *w, unsigned int count) {
|
|||||||
index_type start, end;
|
index_type start, end;
|
||||||
bool found_selection = false;
|
bool found_selection = false;
|
||||||
SelectionExtendMode mode = EXTEND_CELL;
|
SelectionExtendMode mode = EXTEND_CELL;
|
||||||
unsigned int y1 = w->mouse_cell_y, y2 = w->mouse_cell_y;
|
unsigned int y1 = w->mouse_pos.cell_y, y2 = w->mouse_pos.cell_y;
|
||||||
switch(count) {
|
switch(count) {
|
||||||
case 2:
|
case 2:
|
||||||
found_selection = screen_selection_range_for_word(screen, w->mouse_cell_x, &y1, &y2, &start, &end);
|
found_selection = screen_selection_range_for_word(screen, w->mouse_pos.cell_x, &y1, &y2, &start, &end);
|
||||||
mode = EXTEND_WORD;
|
mode = EXTEND_WORD;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
found_selection = screen_selection_range_for_line(screen, w->mouse_cell_y, &start, &end);
|
found_selection = screen_selection_range_for_line(screen, w->mouse_pos.cell_y, &start, &end);
|
||||||
mode = EXTEND_LINE;
|
mode = EXTEND_LINE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -323,19 +324,39 @@ multi_click(Window *w, unsigned int count) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline double
|
||||||
|
distance(double x1, double y1, double x2, double y2) {
|
||||||
|
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
|
||||||
|
}
|
||||||
|
|
||||||
HANDLER(add_click) {
|
HANDLER(add_click) {
|
||||||
ClickQueue *q = &w->click_queue;
|
ClickQueue *q = &w->click_queue;
|
||||||
if (q->length == CLICK_QUEUE_SZ) { memmove(q->clicks, q->clicks + 1, sizeof(Click) * (CLICK_QUEUE_SZ - 1)); q->length--; }
|
if (q->length == CLICK_QUEUE_SZ) { memmove(q->clicks, q->clicks + 1, sizeof(Click) * (CLICK_QUEUE_SZ - 1)); q->length--; }
|
||||||
double now = monotonic();
|
double now = monotonic();
|
||||||
#define N(n) (q->clicks[q->length - n])
|
#define N(n) (q->clicks[q->length - n])
|
||||||
N(0).at = now; N(0).button = button; N(0).modifiers = modifiers;
|
N(0).at = now; N(0).button = button; N(0).modifiers = modifiers; N(0).x = w->mouse_pos.x; N(0).y = w->mouse_pos.y;
|
||||||
q->length++;
|
q->length++;
|
||||||
|
double multi_click_allowed_radius = 1.2 * global_state.callback_os_window->fonts_data->cell_height;
|
||||||
// Now dispatch the multi-click if any
|
// Now dispatch the multi-click if any
|
||||||
if (q->length > 2 && N(1).at - N(3).at <= 2 * OPT(click_interval)) {
|
if (q->length > 2) {
|
||||||
multi_click(w, 3);
|
// possible triple-click
|
||||||
q->length = 0;
|
if (
|
||||||
} else if (q->length > 1 && N(1).at - N(2).at <= OPT(click_interval)) {
|
N(1).at - N(3).at <= 2 * OPT(click_interval) &&
|
||||||
multi_click(w, 2);
|
distance(N(1).x, N(1).y, N(3).x, N(3).y) <= multi_click_allowed_radius
|
||||||
|
) {
|
||||||
|
multi_click(w, 3);
|
||||||
|
q->length = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (q->length > 1) {
|
||||||
|
// possible double-click
|
||||||
|
if (
|
||||||
|
N(1).at - N(2).at <= OPT(click_interval) &&
|
||||||
|
distance(N(1).x, N(1).y, N(2).x, N(2).y) <= multi_click_allowed_radius
|
||||||
|
) {
|
||||||
|
multi_click(w, 2);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#undef N
|
#undef N
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,6 +52,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
double at;
|
double at;
|
||||||
int button, modifiers;
|
int button, modifiers;
|
||||||
|
double x, y;
|
||||||
} Click;
|
} Click;
|
||||||
|
|
||||||
#define CLICK_QUEUE_SZ 3
|
#define CLICK_QUEUE_SZ 3
|
||||||
@ -67,7 +68,10 @@ typedef struct {
|
|||||||
CursorShape last_cursor_shape;
|
CursorShape last_cursor_shape;
|
||||||
PyObject *title;
|
PyObject *title;
|
||||||
ScreenRenderData render_data;
|
ScreenRenderData render_data;
|
||||||
unsigned int mouse_cell_x, mouse_cell_y;
|
struct {
|
||||||
|
unsigned int cell_x, cell_y;
|
||||||
|
double x, y;
|
||||||
|
} mouse_pos;
|
||||||
WindowGeometry geometry;
|
WindowGeometry geometry;
|
||||||
ClickQueue click_queue;
|
ClickQueue click_queue;
|
||||||
double last_drag_scroll_at;
|
double last_drag_scroll_at;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user