From c41ede4d203d4d52b612a2cb623d8028b7be01b7 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 13 Sep 2017 12:33:16 +0530 Subject: [PATCH] Dont use a timer for mouse hiding --- kitty/boss.py | 20 +++----------------- kitty/child-monitor.c | 9 ++++++--- kitty/glfw.c | 27 ++++++++++++++++++++++----- kitty/state.c | 6 +++++- kitty/state.h | 6 +++--- 5 files changed, 39 insertions(+), 29 deletions(-) diff --git a/kitty/boss.py b/kitty/boss.py index a6572e3b3..38fe87f08 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -12,10 +12,9 @@ from .constants import ( mouse_cursor_pos, set_boss, viewport_size, wakeup ) from .fast_data_types import ( - GLFW_CURSOR, GLFW_CURSOR_HIDDEN, GLFW_CURSOR_NORMAL, GLFW_MOUSE_BUTTON_1, - GLFW_PRESS, GLFW_REPEAT, ChildMonitor, Timers as _Timers, - destroy_global_data, destroy_sprite_map, glfw_post_empty_event, - layout_sprite_map + GLFW_MOUSE_BUTTON_1, GLFW_PRESS, GLFW_REPEAT, ChildMonitor, + Timers as _Timers, destroy_global_data, destroy_sprite_map, + glfw_post_empty_event, layout_sprite_map ) from .fonts.render import render_cell_wrapper, set_font_family from .keys import ( @@ -116,7 +115,6 @@ class Boss: self.tab_manager.init(startup_session) layout_sprite_map(cell_size.width, cell_size.height, render_cell_wrapper) self.glfw_window.set_click_cursor(False) - self.show_mouse_cursor() @property def current_tab_bar_height(self): @@ -281,7 +279,6 @@ class Boss: def on_mouse_button(self, window, button, action, mods): mouse_button_pressed[button] = action == GLFW_PRESS - self.show_mouse_cursor() x, y = mouse_cursor_pos w = self.window_for_pos(x, y) if w is None: @@ -304,7 +301,6 @@ class Boss: def on_mouse_move(self, window, xpos, ypos): mouse_cursor_pos[:2] = xpos, ypos = int( xpos * viewport_size.x_ratio), int(ypos * viewport_size.y_ratio) - self.show_mouse_cursor() w = self.window_for_pos(xpos, ypos) if w is not None: w.on_mouse_move(xpos, ypos) @@ -312,20 +308,10 @@ class Boss: self.change_mouse_cursor(self.in_tab_bar(ypos)) def on_mouse_scroll(self, window, x, y): - self.show_mouse_cursor() w = self.window_for_pos(*mouse_cursor_pos) if w is not None: w.on_mouse_scroll(x, y) - def show_mouse_cursor(self): - self.glfw_window.set_input_mode(GLFW_CURSOR, GLFW_CURSOR_NORMAL) - if self.opts.mouse_hide_wait > 0: - self.ui_timers.add( - self.opts.mouse_hide_wait, self.hide_mouse_cursor) - - def hide_mouse_cursor(self): - self.glfw_window.set_input_mode(GLFW_CURSOR, GLFW_CURSOR_HIDDEN) - def change_mouse_cursor(self, click=False): self.glfw_window.set_click_cursor(click) diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index 1cc018d90..502ea224b 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -469,9 +469,8 @@ render_cursor(ChildMonitor *self, Window *w, double now) { } static inline bool -render(ChildMonitor *self, double *timeout) { +render(ChildMonitor *self, double *timeout, double now) { PyObject *ret; - double now = monotonic(); double time_since_last_render = now - last_render_at; if (time_since_last_render > self->repaint_delay) { draw_borders(); @@ -549,13 +548,17 @@ cm_thread_write(PyObject UNUSED *self, PyObject *args) { Py_RETURN_NONE; } +extern void hide_mouse_cursor(); + static PyObject* main_loop(ChildMonitor *self) { #define main_loop_doc "The main thread loop" double timeout = 0, t; while (!glfwWindowShouldClose(glfw_window_id)) { - if (!render(self, &timeout)) break; + double now = monotonic(); + if (!render(self, &timeout, now)) break; + if (global_state.mouse_visible && OPT(mouse_hide_wait) > 0 && now - global_state.last_mouse_activity_at > OPT(mouse_hide_wait)) hide_mouse_cursor(); t = timers_timeout(self->timers); timeout = MIN(timeout, t); if (timeout < 0) glfwWaitEvents(); diff --git a/kitty/glfw.c b/kitty/glfw.c index e78a264e5..da9b3836b 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -64,25 +64,42 @@ key_callback(GLFWwindow UNUSED *w, int key, int scancode, int action, int mods) } static void -mouse_button_callback(GLFWwindow UNUSED *w, int button, int action, int mods) { +mouse_button_callback(GLFWwindow *w, int button, int action, int mods) { + if (!global_state.mouse_visible) { glfwSetInputMode(w, GLFW_CURSOR, GLFW_CURSOR_NORMAL); global_state.mouse_visible = true; } + double now = monotonic(); + global_state.last_mouse_activity_at = now; WINDOW_CALLBACK(mouse_button_callback, "iii", button, action, mods); } static void -scroll_callback(GLFWwindow UNUSED *w, double xoffset, double yoffset) { +scroll_callback(GLFWwindow *w, double xoffset, double yoffset) { + if (!global_state.mouse_visible) { glfwSetInputMode(w, GLFW_CURSOR, GLFW_CURSOR_NORMAL); global_state.mouse_visible = true; } + double now = monotonic(); + global_state.last_mouse_activity_at = now; WINDOW_CALLBACK(scroll_callback, "dd", xoffset, yoffset); } static void -cursor_pos_callback(GLFWwindow UNUSED *w, double x, double y) { - global_state.cursor_blink_zero_time = monotonic(); +cursor_pos_callback(GLFWwindow *w, double x, double y) { + if (!global_state.mouse_visible) { glfwSetInputMode(w, GLFW_CURSOR, GLFW_CURSOR_NORMAL); global_state.mouse_visible = true; } + double now = monotonic(); + global_state.last_mouse_activity_at = now; + global_state.cursor_blink_zero_time = now; WINDOW_CALLBACK(cursor_pos_callback, "dd", x, y); } +void +hide_mouse_cursor() { + glfwSetInputMode(the_window->window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); + global_state.mouse_visible = false; +} + static void window_focus_callback(GLFWwindow UNUSED *w, int focused) { global_state.application_focused = focused ? true : false; - global_state.cursor_blink_zero_time = monotonic(); + double now = monotonic(); + global_state.last_mouse_activity_at = now; + global_state.cursor_blink_zero_time = now; WINDOW_CALLBACK(window_focus_callback, "O", focused ? Py_True : Py_False); } // }}} diff --git a/kitty/state.c b/kitty/state.c index 9016e30c0..4ff1fc2ca 100644 --- a/kitty/state.c +++ b/kitty/state.c @@ -110,6 +110,7 @@ PYWRAP1(set_options) { S(cursor_stop_blinking_after, PyFloat_AsDouble); S(cursor_shape, PyLong_AsLong); S(cursor_opacity, PyFloat_AsDouble); + S(mouse_hide_wait, PyFloat_AsDouble); #undef S Py_RETURN_NONE; } @@ -192,8 +193,11 @@ static PyMethodDef module_methods[] = { bool init_state(PyObject *module) { + double now = monotonic(); global_state.application_focused = true; - global_state.cursor_blink_zero_time = monotonic(); + global_state.cursor_blink_zero_time = now; + global_state.last_mouse_activity_at = now; + global_state.mouse_visible = true; if (PyModule_AddFunctions(module, module_methods) != 0) return false; return true; } diff --git a/kitty/state.h b/kitty/state.h index aba866d23..af43a6fa4 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -10,7 +10,7 @@ #define OPT(name) global_state.opts.name typedef struct { - double visual_bell_duration, cursor_blink_interval, cursor_stop_blinking_after; + double visual_bell_duration, cursor_blink_interval, cursor_stop_blinking_after, mouse_hide_wait; bool enable_audio_bell; CursorShape cursor_shape; double cursor_opacity; @@ -39,8 +39,8 @@ typedef struct { Tab tabs[MAX_CHILDREN]; unsigned int active_tab, num_tabs; ScreenRenderData tab_bar_render_data; - bool application_focused; - double cursor_blink_zero_time; + bool application_focused, mouse_visible; + double cursor_blink_zero_time, last_mouse_activity_at; double logical_dpi_x, logical_dpi_y; int viewport_width, viewport_height; } GlobalState;