From bd136fca39c3d2e70c87be52ca91a04aea6e1bbb Mon Sep 17 00:00:00 2001 From: ikabrain Date: Fri, 5 Jun 2026 15:36:26 +0530 Subject: [PATCH 1/3] fix: unpack get_position() return in Ctrl+Scroll handler PyGObject returns (bool, float, float) from get_position(), not (float, float)! --- src/inlinea/ui/pdf_view.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/inlinea/ui/pdf_view.py b/src/inlinea/ui/pdf_view.py index 516e456..8626138 100644 --- a/src/inlinea/ui/pdf_view.py +++ b/src/inlinea/ui/pdf_view.py @@ -771,9 +771,9 @@ def on_scroll(self, controller, dx, dy): if event: # event.get_position() returns surface-relative coords (includes header bar) # Translate to ScrolledWindow-local coords for correct focal math - sx, sy = event.get_position() + ok, sx, sy = event.get_position() native = self.get_native() - if native: + if ok and native: nx, ny = native.get_surface_transform() p = Graphene.Point() p.x = sx - nx From e114636a7029c1df238cfaafd3b502b954414f9d Mon Sep 17 00:00:00 2001 From: ikabrain Date: Fri, 5 Jun 2026 19:54:49 +0530 Subject: [PATCH 2/3] fix: track pointer position for cursor-centered Ctrl+Scroll zoom --- src/inlinea/ui/pdf_view.py | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/src/inlinea/ui/pdf_view.py b/src/inlinea/ui/pdf_view.py index 8626138..c0fbbb6 100644 --- a/src/inlinea/ui/pdf_view.py +++ b/src/inlinea/ui/pdf_view.py @@ -1,7 +1,6 @@ import gi gi.require_version('Gtk', '4.0') -gi.require_version('Graphene', '1.0') -from gi.repository import Gtk, Adw, GLib, Gdk, GObject, Gio, Graphene +from gi.repository import Gtk, Adw, GLib, Gdk, GObject, Gio import threading import bisect @@ -195,6 +194,7 @@ def __init__(self, file): self.sidebar = None self.is_dual_mode = False self.is_continuous = True + self._pointer_pos = None key_ctrl = Gtk.EventControllerKey() key_ctrl.connect("key-pressed", self.on_key_pressed) @@ -211,6 +211,10 @@ def __init__(self, file): scroll_controller.connect("scroll", self.on_scroll) self.add_controller(scroll_controller) + motion_ctrl = Gtk.EventControllerMotion() + motion_ctrl.connect("motion", self.on_pointer_motion) + self.add_controller(motion_ctrl) + self.load_pdf() # ========== LOADING ========== @@ -490,6 +494,9 @@ def on_zoom_scale_changed(self, gesture, scale): def on_zoom_end(self, gesture, sequence): self._gesture_start_scale = self.scale + def on_pointer_motion(self, controller, x, y): + self._pointer_pos = (x, y) + def _zoom_around_focal(self, new_scale, focal): if abs(new_scale - self.scale) < 0.001: return @@ -766,25 +773,7 @@ def on_scroll(self, controller, dx, dy): state = controller.get_current_event_state() if state & Gdk.ModifierType.CONTROL_MASK: - event = controller.get_current_event() - focal = None - if event: - # event.get_position() returns surface-relative coords (includes header bar) - # Translate to ScrolledWindow-local coords for correct focal math - ok, sx, sy = event.get_position() - native = self.get_native() - if ok and native: - nx, ny = native.get_surface_transform() - p = Graphene.Point() - p.x = sx - nx - p.y = sy - ny - success, pt = native.compute_point(self, p) - if success: - focal = (pt.x, pt.y) - if focal is None: - focal = self._get_viewport_center_focal() - else: - focal = self._get_viewport_center_focal() + focal = self._pointer_pos if self._pointer_pos is not None else self._get_viewport_center_focal() new_scale = self._clamp_scale(self.scale * (1.1 if dy < 0 else 1 / 1.1)) self._zoom_around_focal(new_scale, focal) From 0314c598e64c0c8db9d9c48c510b16633083a4b4 Mon Sep 17 00:00:00 2001 From: ikabrain Date: Fri, 5 Jun 2026 21:08:16 +0530 Subject: [PATCH 3/3] fix: initialize and clear pointer position on enter/leave --- src/inlinea/ui/pdf_view.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/inlinea/ui/pdf_view.py b/src/inlinea/ui/pdf_view.py index c0fbbb6..e94bea6 100644 --- a/src/inlinea/ui/pdf_view.py +++ b/src/inlinea/ui/pdf_view.py @@ -213,6 +213,8 @@ def __init__(self, file): motion_ctrl = Gtk.EventControllerMotion() motion_ctrl.connect("motion", self.on_pointer_motion) + motion_ctrl.connect("enter", self.on_pointer_motion) + motion_ctrl.connect("leave", self.on_pointer_leave) self.add_controller(motion_ctrl) self.load_pdf() @@ -497,6 +499,9 @@ def on_zoom_end(self, gesture, sequence): def on_pointer_motion(self, controller, x, y): self._pointer_pos = (x, y) + def on_pointer_leave(self, controller): + self._pointer_pos = None + def _zoom_around_focal(self, new_scale, focal): if abs(new_scale - self.scale) < 0.001: return