diff --git a/portprotonqt/input_manager.py b/portprotonqt/input_manager.py
index a9e29d5..4393236 100644
--- a/portprotonqt/input_manager.py
+++ b/portprotonqt/input_manager.py
@@ -4,7 +4,7 @@ from typing import Protocol, cast
 from evdev import InputDevice, ecodes, list_devices
 import pyudev
 from PySide6.QtWidgets import QWidget, QStackedWidget, QApplication, QScrollArea, QLineEdit, QDialog, QMenu, QComboBox, QListView
-from PySide6.QtCore import Qt, QObject, QEvent, QPoint, Signal, Slot
+from PySide6.QtCore import Qt, QObject, QEvent, QPoint, Signal, Slot, QTimer
 from PySide6.QtGui import QKeyEvent
 from portprotonqt.logger import get_logger
 from portprotonqt.image_utils import FullscreenDialog
@@ -72,7 +72,6 @@ class InputManager(QObject):
         self._parent.currentDetailPage = getattr(self._parent, 'currentDetailPage', None)
         self._parent.current_exec_line = getattr(self._parent, 'current_exec_line', None)
         self._parent.current_add_game_dialog = getattr(self._parent, 'current_add_game_dialog', None)
-
         self.axis_deadzone = axis_deadzone
         self.initial_axis_move_delay = initial_axis_move_delay
         self.repeat_axis_move_delay = repeat_axis_move_delay
@@ -84,6 +83,12 @@ class InputManager(QObject):
         self.running = True
         self._is_fullscreen = read_fullscreen_config()
 
+        # Add variables for continuous D-pad movement
+        self.dpad_timer = QTimer(self)
+        self.dpad_timer.timeout.connect(self.handle_dpad_repeat)
+        self.current_dpad_code = None  # Tracks the current D-pad axis (e.g., ABS_HAT0X, ABS_HAT0Y)
+        self.current_dpad_value = 0    # Tracks the current D-pad direction value (e.g., -1, 1)
+
         # Connect signals to slots
         self.button_pressed.connect(self.handle_button_slot)
         self.dpad_moved.connect(self.handle_dpad_slot)
@@ -239,6 +244,15 @@ class InputManager(QObject):
         except Exception as e:
             logger.error(f"Error in handle_button_slot: {e}", exc_info=True)
 
+    def handle_dpad_repeat(self) -> None:
+        """Handle repeated D-pad input while the D-pad is held."""
+        if self.current_dpad_code is not None and self.current_dpad_value != 0:
+            now = time.time()
+            if (now - self.last_move_time) >= self.current_axis_delay:
+                self.handle_dpad_slot(self.current_dpad_code, self.current_dpad_value, now)
+                self.last_move_time = now
+                self.current_axis_delay = self.repeat_axis_move_delay
+
     @Slot(int, int, float)
     def handle_dpad_slot(self, code: int, value: int, current_time: float) -> None:
         try:
@@ -253,6 +267,23 @@ class InputManager(QObject):
             focused = QApplication.focusWidget()
             popup = QApplication.activePopupWidget()
 
+            # Update D-pad state
+            if value != 0:
+                self.current_dpad_code = code
+                self.current_dpad_value = value
+                if not self.axis_moving:
+                    self.axis_moving = True
+                    self.last_move_time = current_time
+                    self.current_axis_delay = self.initial_axis_move_delay
+                    self.dpad_timer.start(int(self.repeat_axis_move_delay * 1000))  # Start timer (in milliseconds)
+            else:
+                self.current_dpad_code = None
+                self.current_dpad_value = 0
+                self.axis_moving = False
+                self.current_axis_delay = self.initial_axis_move_delay
+                self.dpad_timer.stop()  # Stop timer when D-pad is released
+                return
+
             # Handle SystemOverlay or AddGameDialog navigation with D-pad
             if isinstance(active, QDialog) and code == ecodes.ABS_HAT0Y and value != 0:
                 if not focused or not active.focusWidget():
@@ -307,19 +338,6 @@ class InputManager(QObject):
                     active.show_next()
                 return
 
-            # Handle repeated D-pad movement
-            if value != 0:
-                if not self.axis_moving:
-                    self.axis_moving = True
-                elif (current_time - self.last_move_time) < self.current_axis_delay:
-                    return
-                self.last_move_time = current_time
-                self.current_axis_delay = self.repeat_axis_move_delay
-            else:
-                self.axis_moving = False
-                self.current_axis_delay = self.initial_axis_move_delay
-                return
-
             # Library tab navigation (index 0)
             if self._parent.stackedWidget.currentIndex() == 0 and code in (ecodes.ABS_HAT0X, ecodes.ABS_HAT0Y):
                 focused = QApplication.focusWidget()
@@ -783,6 +801,7 @@ class InputManager(QObject):
     def cleanup(self) -> None:
         try:
             self.running = False
+            self.dpad_timer.stop()
             if self.gamepad_thread:
                 self.gamepad_thread.join()
             if self.gamepad: