diff --git a/rootfs/usr/share/inputplumber/devices/50-legion_go_s.yaml b/rootfs/usr/share/inputplumber/devices/50-legion_go_s.yaml
index 23b652de..be6cd848 100644
--- a/rootfs/usr/share/inputplumber/devices/50-legion_go_s.yaml
+++ b/rootfs/usr/share/inputplumber/devices/50-legion_go_s.yaml
@@ -79,15 +79,13 @@ source_devices:
   - group: gamepad
     evdev:
       vendor_id: "1a86"
-      product_id: "e310"
-      name: "{QH Electronics Controller,Legion Go S}"
-      handler: event*
-  - group: gamepad
-    evdev:
-      vendor_id: "1a86"
-      product_id: "e311"
+      product_id: "{e31[01]}"
       name: "{QH Electronics Controller,Legion Go S}"
       handler: event*
+    events:
+      # Block input events, but use device for output events
+      exclude:
+        - "*"
 
   # IMU
   - group: imu
@@ -116,4 +114,6 @@ options:
 
 # The target input device(s) to emulate by default
 target_devices:
-  - deck-uhid
+  - xbox-elite
+  - keyboard
+  - mouse
diff --git a/src/input/event/native.rs b/src/input/event/native.rs
index 589f6bf2..07aae4f4 100644
--- a/src/input/event/native.rs
+++ b/src/input/event/native.rs
@@ -198,4 +198,9 @@ impl ScheduledNativeEvent {
     pub fn is_ready(&self) -> bool {
         self.scheduled_time.elapsed() > self.wait_time
     }
+
+    /// Returns the capability that the scheduled event implements
+    pub fn as_capability(&self) -> Capability {
+        self.event.capability.clone()
+    }
 }
diff --git a/src/input/target/dualsense.rs b/src/input/target/dualsense.rs
index b9b24493..70e2e831 100644
--- a/src/input/target/dualsense.rs
+++ b/src/input/target/dualsense.rs
@@ -1009,7 +1009,13 @@ impl TargetInputDevice for DualSenseDevice {
         if self.queued_events.is_empty() {
             return None;
         }
-        Some(self.queued_events.drain(..).collect())
+        let (ready, pending): (Vec<_>, Vec<_>) =
+            self.queued_events.drain(..).partition(|e| e.is_ready());
+        self.queued_events = pending;
+        if ready.is_empty() {
+            return None;
+        }
+        Some(ready)
     }
 
     fn stop(&mut self) -> Result<(), InputError> {
diff --git a/src/input/target/horipad_steam.rs b/src/input/target/horipad_steam.rs
index 009d284e..c204e277 100644
--- a/src/input/target/horipad_steam.rs
+++ b/src/input/target/horipad_steam.rs
@@ -313,9 +313,7 @@ impl HoripadSteamDevice {
         report_number: u8,
         _report_type: uhid_virt::ReportType,
     ) -> Result<(), Box<dyn Error>> {
-        log::debug!(
-            "Received GetReport request: id: {id}, report_number: {report_number}"
-        );
+        log::debug!("Received GetReport request: id: {id}, report_number: {report_number}");
         if let Err(e) = self.device.write_get_report_reply(id, 1, vec![]) {
             log::warn!("Failed to write get report reply: {:?}", e);
             return Err(e.to_string().into());
@@ -372,7 +370,13 @@ impl TargetInputDevice for HoripadSteamDevice {
         if self.queued_events.is_empty() {
             return None;
         }
-        Some(self.queued_events.drain(..).collect())
+        let (ready, pending): (Vec<_>, Vec<_>) =
+            self.queued_events.drain(..).partition(|e| e.is_ready());
+        self.queued_events = pending;
+        if ready.is_empty() {
+            return None;
+        }
+        Some(ready)
     }
 
     fn stop(&mut self) -> Result<(), InputError> {
diff --git a/src/input/target/mod.rs b/src/input/target/mod.rs
index 0530bc90..42cee2b0 100644
--- a/src/input/target/mod.rs
+++ b/src/input/target/mod.rs
@@ -537,6 +537,7 @@ impl<T: TargetInputDevice + TargetOutputDevice + Send + 'static> TargetDriver<T>
                         i += 1;
                     }
                     for event in ready_events.drain(..) {
+                        log::trace!("Emmiting scheduled event: {event:?}");
                         let mut implementation = self.implementation.lock().unwrap();
                         if let Err(e) = implementation.write_event(event.into()) {
                             log::error!("Error writing event: {e:?}");
diff --git a/src/input/target/steam_deck.rs b/src/input/target/steam_deck.rs
index 071be6a9..78b57632 100644
--- a/src/input/target/steam_deck.rs
+++ b/src/input/target/steam_deck.rs
@@ -70,7 +70,7 @@ impl Default for SteamDeckConfig {
 
 // The minimum amount of time that button up events must wait after
 // a button down event.
-const MIN_FRAME_TIME: Duration = Duration::from_millis(80);
+const MIN_FRAME_TIME: Duration = Duration::from_millis(8);
 
 pub struct SteamDeckDevice {
     chip_id: [u8; 15],
@@ -927,6 +927,14 @@ impl TargetInputDevice for SteamDeckDevice {
                 log::trace!("Button down: {cap:?}");
                 // Keep track of button down events
                 self.pressed_events.insert(cap.clone(), Instant::now());
+                // Clear any stale up events for this capability
+                self.queued_events.retain(|scheduled| {
+                    let found = scheduled.as_capability() == cap;
+                    if found {
+                        log::trace!("Found stale queued release for {cap:?}, Clearing.");
+                    }
+                    !found
+                });
             } else {
                 log::trace!("Button up: {cap:?}");
                 // If the event is a button up event, check to
@@ -1004,11 +1012,18 @@ impl TargetInputDevice for SteamDeckDevice {
         ])
     }
 
+    /// Returns any events in the queue up to the [TargetDriver]
     fn scheduled_events(&mut self) -> Option<Vec<ScheduledNativeEvent>> {
         if self.queued_events.is_empty() {
             return None;
         }
-        Some(self.queued_events.drain(..).collect())
+        let (ready, pending): (Vec<_>, Vec<_>) =
+            self.queued_events.drain(..).partition(|e| e.is_ready());
+        self.queued_events = pending;
+        if ready.is_empty() {
+            return None;
+        }
+        Some(ready)
     }
 
     /// Stop the virtual USB read/write threads
diff --git a/src/input/target/steam_deck_uhid.rs b/src/input/target/steam_deck_uhid.rs
index 3bf3f2a6..3996f592 100644
--- a/src/input/target/steam_deck_uhid.rs
+++ b/src/input/target/steam_deck_uhid.rs
@@ -47,7 +47,7 @@ use super::{
 
 // The minimum amount of time that button up events must wait after
 // a button down event.
-const MIN_FRAME_TIME: Duration = Duration::from_millis(80);
+const MIN_FRAME_TIME: Duration = Duration::from_millis(8);
 
 pub struct SteamDeckUhidDevice {
     chip_id: [u8; 15],
@@ -735,6 +735,14 @@ impl TargetInputDevice for SteamDeckUhidDevice {
                 log::trace!("Button down: {cap:?}");
                 // Keep track of button down events
                 self.pressed_events.insert(cap.clone(), Instant::now());
+                // Clear any stale up events for this capability
+                self.queued_events.retain(|scheduled| {
+                    let found = scheduled.as_capability() == cap;
+                    if found {
+                        log::trace!("Found stale queued release for {cap:?}, Clearing.");
+                    }
+                    !found
+                });
             } else {
                 log::trace!("Button up: {cap:?}");
                 // If the event is a button up event, check to
@@ -812,11 +820,18 @@ impl TargetInputDevice for SteamDeckUhidDevice {
         ])
     }
 
+    /// Returns any events in the queue up to the [TargetDriver]
     fn scheduled_events(&mut self) -> Option<Vec<ScheduledNativeEvent>> {
         if self.queued_events.is_empty() {
             return None;
         }
-        Some(self.queued_events.drain(..).collect())
+        let (ready, pending): (Vec<_>, Vec<_>) =
+            self.queued_events.drain(..).partition(|e| e.is_ready());
+        self.queued_events = pending;
+        if ready.is_empty() {
+            return None;
+        }
+        Some(ready)
     }
 
     fn stop(&mut self) -> Result<(), InputError> {
diff --git a/src/input/target/ultimate2_wireless.rs b/src/input/target/ultimate2_wireless.rs
index c9b6f083..a6a19796 100644
--- a/src/input/target/ultimate2_wireless.rs
+++ b/src/input/target/ultimate2_wireless.rs
@@ -379,11 +379,18 @@ impl TargetInputDevice for Ultimate2WirelessDevice {
         ])
     }
 
+    /// Returns any events in the queue up to the [TargetDriver]
     fn scheduled_events(&mut self) -> Option<Vec<ScheduledNativeEvent>> {
         if self.queued_events.is_empty() {
             return None;
         }
-        Some(self.queued_events.drain(..).collect())
+        let (ready, pending): (Vec<_>, Vec<_>) =
+            self.queued_events.drain(..).partition(|e| e.is_ready());
+        self.queued_events = pending;
+        if ready.is_empty() {
+            return None;
+        }
+        Some(ready)
     }
 
     fn stop(&mut self) -> Result<(), InputError> {
diff --git a/src/input/target/xpad.rs b/src/input/target/xpad.rs
index be45c8f7..daa2f1bb 100644
--- a/src/input/target/xpad.rs
+++ b/src/input/target/xpad.rs
@@ -286,7 +286,13 @@ impl TargetInputDevice for XBoxController {
         if self.queued_events.is_empty() {
             return None;
         }
-        Some(self.queued_events.drain(..).collect())
+        let (ready, pending): (Vec<_>, Vec<_>) =
+            self.queued_events.drain(..).partition(|e| e.is_ready());
+        self.queued_events = pending;
+        if ready.is_empty() {
+            return None;
+        }
+        Some(ready)
     }
 
     /// Clear any local state on the target device.
