From bdc480ea1e2bf5cacfb383a4176415eb5848cc5d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Hamal=20Dvo=C5=99=C3=A1k?= <mordae@anilinux.org>
Date: Sat, 8 Mar 2025 21:33:58 +0100
Subject: [PATCH] Add seeking

---
 lazy_player/__init__.py | 54 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 52 insertions(+), 2 deletions(-)

diff --git a/lazy_player/__init__.py b/lazy_player/__init__.py
index e7061b5..6781809 100644
--- a/lazy_player/__init__.py
+++ b/lazy_player/__init__.py
@@ -166,9 +166,8 @@ class MainWindow(Gtk.ApplicationWindow):
                 string_obj = cast(Gtk.StringObject, selected_item)
                 self.file_info_label.set_text(string_obj.get_string())
 
-    def _on_key_pressed(
+    def _on_video_key_pressed(
         self,
-        controller: Gtk.EventControllerKey,
         keyval: int,
         keycode: int,
         state: Gdk.ModifierType,
@@ -179,8 +178,59 @@ class MainWindow(Gtk.ApplicationWindow):
             self.list_view.grab_focus()
             return True
 
+        elif keyval == Gdk.keyval_from_name("Left"):
+            self._seek_relative(-10)
+            return True
+
+        elif keyval == Gdk.keyval_from_name("Right"):
+            self._seek_relative(10)
+            return True
+
+        elif keyval == Gdk.keyval_from_name("Up"):
+            self._seek_relative(60)
+            return True
+
+        elif keyval == Gdk.keyval_from_name("Down"):
+            self._seek_relative(-60)
+            return True
+
         return False
 
+    def _on_key_pressed(
+        self,
+        controller: Gtk.EventControllerKey,
+        keyval: int,
+        keycode: int,
+        state: Gdk.ModifierType,
+    ) -> bool:
+        # If we're showing video, handle keys differently
+        if self.stack.get_visible_child_name() == "overlay":
+            return self._on_video_key_pressed(keyval, keycode, state)
+        return False
+
+    def _seek_relative(self, offset: int) -> None:
+        """Seek relative to current position by offset seconds"""
+        playbin = self.pipeline.get_by_name("playbin")
+        if not playbin:
+            return
+
+        # Query current position
+        success, current = self.pipeline.query_position(Gst.Format.TIME)
+        if not success:
+            return
+
+        # Convert offset to nanoseconds and add to current
+        new_pos = current + (offset * Gst.SECOND)
+
+        # Ensure we don't seek before start
+        if new_pos < 0:
+            new_pos = 0
+
+        # Perform seek
+        self.pipeline.seek_simple(
+            Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, new_pos
+        )
+
     def _populate_file_list(self) -> None:
         # TODO: Implement proper version sort (strverscmp equivalent)