diff --git a/pycardium/modules/py/simple_menu.py b/pycardium/modules/py/simple_menu.py
index 71439b7f151063a88fef516887e0d49a52d431fd..b9c535eeac14fcec5048b7a09377ee615161ec34 100644
--- a/pycardium/modules/py/simple_menu.py
+++ b/pycardium/modules/py/simple_menu.py
@@ -112,6 +112,14 @@ class Menu:
     .. versionadded:: 1.9
     """
 
+    timeout = None
+    """
+    Optional timeout for inactivity.  Once this timeout is reached,
+    :py:meth:`~simple_menu.Menu.on_timeout` will be called.
+
+    .. versionadded:: 1.9
+    """
+
     def on_scroll(self, item, index):
         """
         Hook when the selector scrolls to a new item.
@@ -137,6 +145,15 @@ class Menu:
         """
         pass
 
+    def on_timeout(self):
+        """
+        The inactivity timeout has been triggered.  See
+        :py:attr:`simple_menu.Menu.timeout`.
+
+        .. versionadded:: 1.9
+        """
+        self.exit()
+
     def exit(self):
         """
         Exit the event-loop.  This should be called from inside an ``on_*`` hook.
@@ -254,7 +271,11 @@ class Menu:
     def run(self):
         """Start the event-loop."""
         try:
-            for ev in button_events(timeout=self.scroll_speed):
+            timeout = self.scroll_speed
+            if self.timeout is not None and self.timeout < self.scroll_speed:
+                timeout = self.timeout
+
+            for ev in button_events(timeout):
                 if ev == buttons.BOTTOM_RIGHT:
                     self.select_time = utime.time_ms()
                     self.draw_menu(-8)
@@ -284,5 +305,10 @@ class Menu:
                         utime.sleep(1.0)
 
                 self.draw_menu()
+
+                if self.timeout is not None and (
+                    utime.time_ms() - self.select_time
+                ) > int(self.timeout * 1000):
+                    self.on_timeout()
         except _ExitMenuException:
             pass