tenseleyflow/hyprkvm / a467c30

Browse files

fix: re-query physical Super key state before entering PostRecovery

When recovery mode detects a hotkey (Super+Arrow) it breaks out of the
event loop immediately. If Super was released right after the arrow key,
that release event would be pending but unconsumed, causing super_held
to remain true and incorrectly entering PostRecovery with a stuck Super.

Now we query the physical key state via get_key_state() before deciding
whether to enter PostRecovery, ensuring we don't create a synthetic
Super key-down when the key was already released.
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
a467c307e2970de5ede78457441559bbc3ca0ebb
Parents
bf0c29a
Tree
09c2652

2 changed files

StatusFile+-
M Cargo.lock 3 3
M hyprkvm-daemon/src/input/evdev_grab.rs 20 2
Cargo.lockmodified
@@ -1636,7 +1636,7 @@ dependencies = [
1636
 
1636
 
1637
 [[package]]
1637
 [[package]]
1638
 name = "hyprkvm-cli"
1638
 name = "hyprkvm-cli"
1639
-version = "0.6.4"
1639
+version = "0.6.5"
1640
 dependencies = [
1640
 dependencies = [
1641
  "anyhow",
1641
  "anyhow",
1642
  "clap",
1642
  "clap",
@@ -1648,7 +1648,7 @@ dependencies = [
1648
 
1648
 
1649
 [[package]]
1649
 [[package]]
1650
 name = "hyprkvm-common"
1650
 name = "hyprkvm-common"
1651
-version = "0.6.4"
1651
+version = "0.6.5"
1652
 dependencies = [
1652
 dependencies = [
1653
  "serde",
1653
  "serde",
1654
  "serde_json",
1654
  "serde_json",
@@ -1657,7 +1657,7 @@ dependencies = [
1657
 
1657
 
1658
 [[package]]
1658
 [[package]]
1659
 name = "hyprkvm-daemon"
1659
 name = "hyprkvm-daemon"
1660
-version = "0.6.4"
1660
+version = "0.6.5"
1661
 dependencies = [
1661
 dependencies = [
1662
  "anyhow",
1662
  "anyhow",
1663
  "base64",
1663
  "base64",
hyprkvm-daemon/src/input/evdev_grab.rsmodified
@@ -474,8 +474,23 @@ fn run_evdev_grabber(
474
                     // is pressed, since it never saw the original key-down (it was grabbed).
474
                     // is pressed, since it never saw the original key-down (it was grabbed).
475
                     // CRITICAL: We must keep the virtual device alive until Super is released,
475
                     // CRITICAL: We must keep the virtual device alive until Super is released,
476
                     // otherwise the kernel will auto-send key-up when the device is destroyed.
476
                     // otherwise the kernel will auto-send key-up when the device is destroyed.
477
-                    if recovery_hotkey_sent && super_held {
477
+
478
-                        tracing::info!("RECOVERY: Super still held, entering PostRecovery to maintain synthetic key-down");
478
+                    // Re-query physical key state to ensure Super is actually held
479
+                    // (we may have broken out of the event loop before processing Super release)
480
+                    let mut super_physically_held = false;
481
+                    for dev in devices.values() {
482
+                        if let Ok(key_state) = dev.get_key_state() {
483
+                            if key_state.contains(evdev::Key::new(KEY_LEFTMETA))
484
+                                || key_state.contains(evdev::Key::new(KEY_RIGHTMETA))
485
+                            {
486
+                                super_physically_held = true;
487
+                                break;
488
+                            }
489
+                        }
490
+                    }
491
+
492
+                    if recovery_hotkey_sent && super_physically_held {
493
+                        tracing::info!("RECOVERY: Super physically held, entering PostRecovery to maintain synthetic key-down");
479
 
494
 
480
                         // Create virtual keyboard and send Super key-down
495
                         // Create virtual keyboard and send Super key-down
481
                         match create_synthetic_keyboard_with_super_down() {
496
                         match create_synthetic_keyboard_with_super_down() {
@@ -493,6 +508,9 @@ fn run_evdev_grabber(
493
                         }
508
                         }
494
                     } else {
509
                     } else {
495
                         // Super already released or no hotkey detected, clean up normally
510
                         // Super already released or no hotkey detected, clean up normally
511
+                        if recovery_hotkey_sent && !super_physically_held {
512
+                            tracing::info!("RECOVERY: Super was released before PostRecovery, skipping synthetic keyboard");
513
+                        }
496
                         devices.clear();
514
                         devices.clear();
497
                         state = State::Idle;
515
                         state = State::Idle;
498
                     }
516
                     }