tenseleyflow/hyprkvm / 6d08dd0

Browse files

fix: skip IPC Move when already initiating transfer in same direction

When RECOVERY hotkey and Hyprland IPC Move both fire for the same
Super+Arrow keypress, the IPC Move handler would do movefocus even
though a transfer was already being initiated. This caused double
navigation (cursor would move two windows instead of one).

Now IPC Move skips entirely if state is Initiating in the same direction.
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
6d08dd098f7bfd0bcf2203b6bec272738999aa10
Parents
a467c30
Tree
ce52ed6

1 changed file

StatusFile+-
M hyprkvm-daemon/src/main.rs 22 0
hyprkvm-daemon/src/main.rsmodified
@@ -1741,6 +1741,27 @@ async fn run_daemon(config_path: &std::path::Path) -> anyhow::Result<()> {
17411741
                         let current_state = transfer_manager.state().await;
17421742
                         info!("IPC Move {:?}: state={:?}", direction, current_state);
17431743
 
1744
+                        // If we're already initiating a transfer in this direction, skip entirely
1745
+                        // (prevents double-action when both RECOVERY hotkey and IPC Move fire)
1746
+                        if let transfer::TransferState::Initiating { target, .. } = &current_state {
1747
+                            if *target == direction {
1748
+                                tracing::info!("IPC Move {:?}: already initiating transfer, skipping", direction);
1749
+                                IpcResponse::Ok { message: "transfer already initiating".to_string() }
1750
+                            } else {
1751
+                                // Different direction - this shouldn't happen normally, but do movefocus
1752
+                                let hypr_dir = match direction {
1753
+                                    Direction::Left => "l",
1754
+                                    Direction::Right => "r",
1755
+                                    Direction::Up => "u",
1756
+                                    Direction::Down => "d",
1757
+                                };
1758
+                                match hypr_client.dispatch("movefocus", hypr_dir).await {
1759
+                                    Ok(_) => IpcResponse::Ok { message: "movefocus".to_string() },
1760
+                                    Err(e) => IpcResponse::Error { message: format!("movefocus failed: {}", e) },
1761
+                                }
1762
+                            }
1763
+                        } else {
1764
+
17441765
                         // For keyboard navigation, check if we're at the absolute edge:
17451766
                         // 1. On edge monitor (no monitor in that direction)
17461767
                         // 2. On edge window of that monitor (no window further in that direction)
@@ -1955,6 +1976,7 @@ async fn run_daemon(config_path: &std::path::Path) -> anyhow::Result<()> {
19551976
                             }
19561977
                             IpcResponse::DoLocalMove
19571978
                         }
1979
+                    } // end of else block for Initiating check
19581980
                     }
19591981
                     IpcRequest::Status => {
19601982
                         let state = format!("{:?}", transfer_manager.state().await);