diff --git a/lazy_player/__init__.py b/lazy_player/__init__.py
index 8fa0d07..a9e6ba9 100644
--- a/lazy_player/__init__.py
+++ b/lazy_player/__init__.py
@@ -3,7 +3,7 @@ from __future__ import annotations
 import os
 import sys
 from pathlib import Path
-from typing import Any, cast, overload
+from typing import Any, cast
 
 import gi
 
@@ -152,13 +152,13 @@ class MainWindow(Gtk.ApplicationWindow):
                     self._populate_file_list()
                     return
 
-                position = self._load_attribute("position", 0)
+                position = file_item.load_attribute("position", 0)
 
                 # Start playing the video
                 full_path = os.path.abspath(file_item.full_path)
                 self.playbin.set_property("uri", f"file://{full_path}")
 
-                track = self._load_attribute("subtitle_track", -2)
+                track = file_item.load_attribute("subtitle_track", -2)
 
                 if track >= 0:
                     flags = self.playbin.get_property("flags")
@@ -207,18 +207,10 @@ class MainWindow(Gtk.ApplicationWindow):
         self.set_child(self.stack)
 
     @property
-    def currently_playing(self):
+    def selection(self) -> FileItem:
         selected_item = self.selection_model.get_selected_item()
-
-        if not selected_item:
-            return None
-
-        file_item = cast(FileItem, selected_item)
-
-        if file_item.file_type == FileType.DIRECTORY:
-            return None
-
-        return file_item.full_path
+        assert selected_item
+        return cast(FileItem, selected_item)
 
     def _setup_list_item(self, factory: Gtk.SignalListItemFactory, list_item: Gtk.ListItem):
         # Create horizontal box to hold icon and label
@@ -367,46 +359,15 @@ class MainWindow(Gtk.ApplicationWindow):
 
     def _save_position(self) -> None:
         """Save current playback position as xattr"""
+        file_item = self.selection
+        assert file_item.file_type != FileType.DIRECTORY
 
         success, position = self.pipeline.query_position(Gst.Format.TIME)
         success2, duration = self.pipeline.query_duration(Gst.Format.TIME)
 
         if success and success2:
-            self._save_attribute("position", position)
-            self._save_attribute("duration", duration)
-
-    def _save_attribute(self, name: str, value: str | float | int | None):
-        path = self.currently_playing
-
-        if path is None:
-            return
-
-        try:
-            if value is None:
-                os.removexattr(path, f"user.lazy_player.{name}")
-            else:
-                os.setxattr(path, f"user.lazy_player.{name}", str(value).encode("utf8"))
-        except OSError as err:
-            print(err, file=sys.stderr)
-
-    @overload
-    def _load_attribute(self, name: str, dfl: str) -> str: ...
-
-    @overload
-    def _load_attribute(self, name: str, dfl: int) -> int: ...
-
-    def _load_attribute(self, name: str, dfl: str | int) -> str | int:
-        path = self.currently_playing
-
-        if path is None:
-            return dfl
-
-        try:
-            strval = os.getxattr(path, f"user.lazy_player.{name}")
-            return type(dfl)(strval)
-        except OSError as err:
-            print(err, file=sys.stderr)
-            return dfl
+            file_item.save_attribute("position", position)
+            file_item.save_attribute("duration", duration)
 
     def _cycle_subtitles(self) -> None:
         """Cycle through available subtitle tracks, including off state"""
@@ -427,7 +388,9 @@ class MainWindow(Gtk.ApplicationWindow):
             self.playbin.set_property("current-text", 0)
             track_info = self._get_subtitle_info(0)
             self.show_overlay_text(f"Subtitle track: {track_info}")
-            self._save_attribute("subtitle_track", 0)
+            file_item = self.selection
+            assert file_item.file_type != FileType.DIRECTORY
+            file_item.save_attribute("subtitle_track", 0)
             return
 
         # If we're on the last track, disable subtitles
@@ -435,7 +398,9 @@ class MainWindow(Gtk.ApplicationWindow):
             flags &= ~0x00000004  # TEXT flag
             self.playbin.set_property("flags", flags)
             self.show_overlay_text("Subtitles: Off")
-            self._save_attribute("subtitle_track", -1)
+            file_item = self.selection
+            assert file_item.file_type != FileType.DIRECTORY
+            file_item.save_attribute("subtitle_track", -1)
             return
 
         # Otherwise cycle to next track
@@ -443,7 +408,9 @@ class MainWindow(Gtk.ApplicationWindow):
         self.playbin.set_property("current-text", next_track)
         track_info = self._get_subtitle_info(next_track)
         self.show_overlay_text(f"Subtitle track: {track_info}")
-        self._save_attribute("subtitle_track", next_track)
+        file_item = self.selection
+        assert file_item.file_type != FileType.DIRECTORY
+        file_item.save_attribute("subtitle_track", next_track)
 
     def show_overlay_text(self, text: str, timeout_seconds: float = 1.0) -> None:
         """Show text in a centered overlay that disappears after timeout"""
diff --git a/lazy_player/file_model.py b/lazy_player/file_model.py
index 25b617e..00b4bb1 100644
--- a/lazy_player/file_model.py
+++ b/lazy_player/file_model.py
@@ -1,7 +1,9 @@
 from __future__ import annotations
 
 import os
+import sys
 from enum import Enum, auto
+from typing import overload
 
 import gi
 
@@ -39,3 +41,26 @@ class FileItem(GObject.Object):
             return FileItem(name, FileType.VIDEO, path)
 
         raise ValueError(f"Unsupported file type: {path}")
+
+    @overload
+    def load_attribute(self, name: str, dfl: str) -> str: ...
+
+    @overload
+    def load_attribute(self, name: str, dfl: int) -> int: ...
+
+    def load_attribute(self, name: str, dfl: str | int) -> str | int:
+        try:
+            strval = os.getxattr(self.full_path, f"user.lazy_player.{name}")
+            return type(dfl)(strval)
+        except OSError as err:
+            print(err, file=sys.stderr)
+            return dfl
+
+    def save_attribute(self, name: str, value: str | float | int | None) -> None:
+        try:
+            if value is None:
+                os.removexattr(self.full_path, f"user.lazy_player.{name}")
+            else:
+                os.setxattr(self.full_path, f"user.lazy_player.{name}", str(value).encode("utf8"))
+        except OSError as err:
+            print(err, file=sys.stderr)