From 1c1d0a4e914e9d09e79af2b15374da46971c494a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 13 Sep 2017 23:34:00 +0530 Subject: [PATCH] Port mouse cursor change over hyperlinks to C --- kitty/mouse.c | 8 ++++++-- kitty/screen.c | 6 ++++++ kitty/screen.h | 1 + kitty/unicode-data.h | 5 +++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/kitty/mouse.c b/kitty/mouse.c index c8d1a6ba2..1b95e0342 100644 --- a/kitty/mouse.c +++ b/kitty/mouse.c @@ -6,6 +6,8 @@ */ #include "state.h" +#include "screen.h" +#include "lineops.h" #include extern void set_click_cursor(bool yes); @@ -21,7 +23,7 @@ contains_mouse(Window *w) { static inline bool cell_for_pos(Window *w, unsigned int *x, unsigned int *y) { unsigned int qx = (unsigned int)((double)global_state.mouse_x / global_state.cell_width); - unsigned int qy = (unsigned int)((double)global_state.mouse_x / global_state.cell_width); + unsigned int qy = (unsigned int)((double)global_state.mouse_y / global_state.cell_height); bool ret = false; Screen *screen = w->render_data.screen; if (screen && qx <= screen->columns && qy <= screen->lines) { @@ -34,6 +36,8 @@ void handle_move_event(Window *w, int UNUSED button, int UNUSED modifiers) { unsigned int x, y; if (cell_for_pos(w, &x, &y)) { + Line *line = screen_visual_line(w->render_data.screen, y); + has_click_cursor = (line && line_url_start_at(line, x) < line->xnum) ? true : false; if (x != w->mouse_cell_x || y != w->mouse_cell_y) { w->mouse_cell_x = x; w->mouse_cell_y = y; } @@ -75,7 +79,7 @@ mouse_event(int button, int modifiers) { } else { Tab *t = global_state.tabs + global_state.active_tab; for (size_t i = 0; i < t->num_windows; i++) { - if (contains_mouse(t->windows + i)) { + if (contains_mouse(t->windows + i) && t->windows[i].render_data.screen) { handle_event(t->windows + i, button, modifiers); break; } diff --git a/kitty/screen.c b/kitty/screen.c index cfb3a2bea..396baf306 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -1208,6 +1208,12 @@ line(Screen *self, PyObject *val) { return (PyObject*) self->linebuf->line; } +Line* +screen_visual_line(Screen *self, index_type y) { + if (y >= self->lines) return NULL; + return visual_line_(self, y); +} + static PyObject* visual_line(Screen *self, PyObject *args) { // The line corresponding to the yth visual line, taking into account scrolling diff --git a/kitty/screen.h b/kitty/screen.h index 09b3451b2..3e802ff51 100644 --- a/kitty/screen.h +++ b/kitty/screen.h @@ -64,6 +64,7 @@ bool screen_is_selection_dirty(Screen *self); bool screen_invert_colors(Screen *self); void screen_update_cell_data(Screen *self, void *address, size_t sz); bool screen_is_cursor_visible(Screen *self); +Line* screen_visual_line(Screen *self, index_type y); unsigned long screen_current_char_width(Screen *self); #define DECLARE_CH_SCREEN_HANDLER(name) void screen_##name(Screen *screen); DECLARE_CH_SCREEN_HANDLER(bell) diff --git a/kitty/unicode-data.h b/kitty/unicode-data.h index d65f96adb..3f1cdfe5d 100644 --- a/kitty/unicode-data.h +++ b/kitty/unicode-data.h @@ -17,3 +17,8 @@ static inline bool is_word_char(uint32_t ch) { return uc_is_general_category_withtable(ch, UC_CATEGORY_MASK_L | UC_CATEGORY_MASK_N); } + +static inline bool +is_url_char(uint32_t ch) { + return ch && !uc_is_general_category_withtable(ch, UC_CATEGORY_MASK_C | UC_CATEGORY_MASK_Z); +}