diff --git a/kitty/tabs.py b/kitty/tabs.py index c552c3e36..78433b9e6 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -125,6 +125,8 @@ class TabManager(Thread): glfw.glfwSetCharModsCallback(glfw_window, partial(self.queue_action, self.on_text_input)) glfw.glfwSetKeyCallback(glfw_window, partial(self.queue_action, self.on_key)) glfw.glfwSetMouseButtonCallback(glfw_window, partial(self.queue_action, self.on_mouse_button)) + glfw.glfwSetScrollCallback(glfw_window, partial(self.queue_action, self.on_mouse_scroll)) + glfw.glfwSetCursorPosCallback(glfw_window, partial(self.queue_action, self.on_mouse_move)) glfw.glfwSetWindowFocusCallback(glfw_window, partial(self.queue_action, self.on_focus)) self.tabs = deque() self.tabs.append(Tab(opts, args)) @@ -311,13 +313,25 @@ class TabManager(Thread): if w is not None: w.focus_changed(focused) + def window_for_pos(self, x, y): + for w in self.active_tab: + if w.contains(x, y): + return w + def on_mouse_button(self, window, button, action, mods): - if action == glfw_constants.GLFW_RELEASE: - if button == glfw_constants.GLFW_MOUSE_BUTTON_MIDDLE: - w = self.active_window - if w is not None: - w.paste_from_selection() - return + w = self.window_for_pos(*glfw.glfwGetCursorPos(window)) + if w is not None: + w.on_mouse_button(button, action, mods) + + def on_mouse_move(self, window, xpos, ypos): + w = self.window_for_pos(*glfw.glfwGetCursorPos(window)) + if w is not None: + w.on_mouse_move(xpos, ypos) + + def on_mouse_scroll(self, window, x, y): + w = self.window_for_pos(*glfw.glfwGetCursorPos(window)) + if w is not None: + w.on_mouse_scroll(x, y) # GUI thread API {{{ def render(self): diff --git a/kitty/window.py b/kitty/window.py index af8e3c19e..5fc170155 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -8,6 +8,7 @@ import subprocess from functools import partial import glfw +import glfw_constants from .char_grid import CharGrid from .constants import wakeup, tab_manager, appname, WindowGeometry from .fast_data_types import ( @@ -47,6 +48,10 @@ class Window: self.char_grid.update_position(new_geometry) self.geometry = new_geometry + def contains(self, x, y): + g = self.geometry + return g.left <= x <= g.right and g.top <= y <= g.bottom + def close(self): tab_manager().close_window(self) @@ -109,6 +114,19 @@ class Window: def request_capabilities(self, q): self.write_to_child(get_capabilities(q)) + def on_mouse_button(self, button, action, mods): + # ignore_mouse_mode = mods == glfw_constants.GLFW_MOD_SHIFT + if action == glfw_constants.GLFW_RELEASE: + if button == glfw_constants.GLFW_MOUSE_BUTTON_MIDDLE: + self.paste_from_selection() + return + + def on_mouse_move(self, xpos, ypos): + pass + + def on_mouse_scroll(self, x, y): + pass + # actions {{{ def paste(self, text):