Fixed close hotkey not working so it works now
This commit is contained in:
+114
-11
@@ -76,17 +76,36 @@ pub fn update_app(state: &mut CursorRush, message: Message) -> Task<Message> {
|
||||
if let Some(shared) = &state.shared_state {
|
||||
if let Ok(mut shared_state) = shared.lock() {
|
||||
shared_state.running = false;
|
||||
println!("Set running flag to false in shared state");
|
||||
} else {
|
||||
println!("Failed to lock shared state to set running flag");
|
||||
}
|
||||
} else {
|
||||
println!("Shared state not available when handling Quit message");
|
||||
}
|
||||
|
||||
// Unregister hotkeys if possible
|
||||
if let Some(_) = &state.hotkey_manager {
|
||||
println!("Unregistering hotkeys before exit");
|
||||
// We don't have a list of registered hotkeys, so we'll just drop the manager
|
||||
// The hotkeys will be unregistered when the manager is dropped
|
||||
println!("Hotkey manager will be dropped during exit");
|
||||
} else {
|
||||
println!("No hotkey manager available to unregister hotkeys");
|
||||
}
|
||||
|
||||
// Restore the system cursor before exiting
|
||||
platform::restore_cursor();
|
||||
println!("System cursor restored");
|
||||
|
||||
// Cleanly drop the tray icon *before* exiting iced
|
||||
// This removes the icon from the system tray immediately
|
||||
if let Some(tray) = state.tray_icon.take() {
|
||||
println!("Dropping tray icon...");
|
||||
drop(tray);
|
||||
println!("Tray icon explicitly dropped.");
|
||||
} else {
|
||||
println!("No tray icon to drop");
|
||||
}
|
||||
|
||||
// Use iced's exit mechanism for a cleaner shutdown
|
||||
@@ -213,9 +232,10 @@ pub struct CursorRush {
|
||||
pub shared_state: Option<Arc<Mutex<SharedState>>>,
|
||||
pub main_window: Option<iced::window::Id>, // Store the main window ID
|
||||
pub tray_icon: Option<tray_icon::TrayIcon>, // Store the TrayIcon object to keep it alive
|
||||
pub hotkey_manager: Option<GlobalHotKeyManager>, // Store the hotkey manager to keep it alive
|
||||
}
|
||||
|
||||
// Make sure the default impl initializes tray_icon to None
|
||||
// Make sure the default impl initializes tray_icon and hotkey_manager to None
|
||||
impl Default for CursorRush {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
@@ -224,6 +244,7 @@ impl Default for CursorRush {
|
||||
shared_state: None,
|
||||
main_window: None,
|
||||
tray_icon: None, // Initialize as None
|
||||
hotkey_manager: None, // Initialize as None
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -240,6 +261,22 @@ pub fn app_subscription(_state: &CursorRush) -> Subscription<Message> {
|
||||
// Return TrayEvent which is essentially a no-op
|
||||
Message::TrayEvent
|
||||
},
|
||||
// Add a fallback keyboard handler for Ctrl+Shift+F12
|
||||
iced::Event::Keyboard(iced::keyboard::Event::KeyPressed {
|
||||
key,
|
||||
modifiers,
|
||||
..
|
||||
}) => {
|
||||
// Check if Ctrl+Shift+F12 is pressed
|
||||
if key == iced::keyboard::Key::Named(iced::keyboard::key::Named::F12) &&
|
||||
modifiers.control() &&
|
||||
modifiers.shift() {
|
||||
println!("Detected Ctrl+Shift+F12 via iced keyboard event");
|
||||
Message::Quit
|
||||
} else {
|
||||
Message::TrayEvent // No-op for other key events
|
||||
}
|
||||
},
|
||||
// Handle other events
|
||||
_ => Message::TrayEvent, // Use TrayEvent as a no-op message
|
||||
}
|
||||
@@ -326,20 +363,38 @@ pub fn boot_app() -> (CursorRush, Task<Message>) {
|
||||
eprintln!("Failed to initialize tray icon, application might not function correctly in background.");
|
||||
}
|
||||
|
||||
setup_hotkeys(shared_state.clone());
|
||||
// Set up hotkeys and store the manager in the application state
|
||||
state.hotkey_manager = setup_hotkeys(shared_state.clone());
|
||||
if state.hotkey_manager.is_none() {
|
||||
eprintln!("Failed to initialize hotkey manager, hotkeys will not work!");
|
||||
} else {
|
||||
println!("Hotkey manager successfully initialized and stored in application state");
|
||||
}
|
||||
|
||||
(state, Task::none())
|
||||
}
|
||||
|
||||
// Set up global hotkeys
|
||||
fn setup_hotkeys(shared_state: Arc<Mutex<SharedState>>) {
|
||||
fn setup_hotkeys(shared_state: Arc<Mutex<SharedState>>) -> Option<GlobalHotKeyManager> {
|
||||
// Set up global hotkey manager
|
||||
let hotkey_manager = match GlobalHotKeyManager::new() {
|
||||
Ok(manager) => manager,
|
||||
Ok(manager) => {
|
||||
println!("Successfully created hotkey manager");
|
||||
manager
|
||||
},
|
||||
Err(e) => {
|
||||
eprintln!("Failed to create hotkey manager: {}", e);
|
||||
// Continue without hotkey support
|
||||
GlobalHotKeyManager::new().expect("Critical failure: could not create hotkey manager")
|
||||
match GlobalHotKeyManager::new() {
|
||||
Ok(manager) => {
|
||||
println!("Second attempt to create hotkey manager succeeded");
|
||||
manager
|
||||
},
|
||||
Err(e) => {
|
||||
eprintln!("Critical failure: could not create hotkey manager on second attempt: {}", e);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -351,10 +406,13 @@ fn setup_hotkeys(shared_state: Arc<Mutex<SharedState>>) {
|
||||
Code::F12,
|
||||
);
|
||||
|
||||
println!("Attempting to register Ctrl+Shift+F12 as exit hotkey");
|
||||
|
||||
// Register the hotkey with better error handling
|
||||
match hotkey_manager.register(hotkey) {
|
||||
let registered_hotkey = match hotkey_manager.register(hotkey) {
|
||||
Ok(_) => {
|
||||
println!("Successfully registered Ctrl+Shift+F12 as exit hotkey");
|
||||
hotkey
|
||||
},
|
||||
Err(e) => {
|
||||
eprintln!("Failed to register hotkey: {}", e);
|
||||
@@ -364,21 +422,50 @@ fn setup_hotkeys(shared_state: Arc<Mutex<SharedState>>) {
|
||||
Code::F12,
|
||||
);
|
||||
|
||||
println!("Attempting to register fallback hotkey Ctrl+Alt+F12");
|
||||
match hotkey_manager.register(fallback_hotkey) {
|
||||
Ok(_) => println!("Registered fallback hotkey Ctrl+Alt+F12 instead"),
|
||||
Err(e) => eprintln!("Failed to register fallback hotkey: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(_) => {
|
||||
println!("Registered fallback hotkey Ctrl+Alt+F12 instead");
|
||||
fallback_hotkey
|
||||
},
|
||||
Err(e) => {
|
||||
eprintln!("Failed to register fallback hotkey: {}", e);
|
||||
|
||||
// Try one more fallback with just F12
|
||||
let last_fallback = GlobalHotKey::new(None, Code::F12);
|
||||
println!("Attempting to register last fallback hotkey F12");
|
||||
match hotkey_manager.register(last_fallback) {
|
||||
Ok(_) => {
|
||||
println!("Registered last fallback hotkey F12");
|
||||
last_fallback
|
||||
},
|
||||
Err(e) => {
|
||||
eprintln!("Failed to register any hotkey: {}", e);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
println!("Hotkey registered: {:?}", registered_hotkey);
|
||||
println!("Press Ctrl+Shift+F12 to exit the application");
|
||||
|
||||
// We can't clone the hotkey manager, so we'll use Arc to share it
|
||||
let manager_arc = Arc::new(hotkey_manager);
|
||||
let manager_for_thread = Arc::clone(&manager_arc);
|
||||
|
||||
// Spawn a thread to listen for hotkeys
|
||||
let state_clone = shared_state.clone();
|
||||
thread::spawn(move || {
|
||||
println!("Hotkey listener thread started");
|
||||
let event_receiver = global_hotkey::GlobalHotKeyEvent::receiver();
|
||||
|
||||
// Keep a reference to the manager in this thread to ensure it stays alive
|
||||
let _manager_ref = &manager_for_thread;
|
||||
println!("Hotkey manager reference maintained in thread");
|
||||
|
||||
loop {
|
||||
match event_receiver.try_recv() {
|
||||
Ok(event) => {
|
||||
@@ -388,15 +475,20 @@ fn setup_hotkeys(shared_state: Arc<Mutex<SharedState>>) {
|
||||
// Send Quit message instead of direct exit
|
||||
// Get the global sender
|
||||
if let Some(tx) = TRAY_SENDER.lock().unwrap().as_ref() {
|
||||
println!("Found global sender, sending Quit message");
|
||||
if let Err(e) = tx.unbounded_send(Message::Quit) {
|
||||
eprintln!("Failed to send Quit message from hotkey thread: {}", e);
|
||||
// Fallback to direct exit if channel fails
|
||||
println!("Using fallback exit mechanism");
|
||||
platform::restore_cursor();
|
||||
std::process::exit(0);
|
||||
} else {
|
||||
println!("Successfully sent Quit message through channel");
|
||||
}
|
||||
} else {
|
||||
eprintln!("Hotkey: Global sender not initialized yet");
|
||||
// Fallback to direct exit if sender not available
|
||||
println!("Global sender not available, using direct exit");
|
||||
platform::restore_cursor();
|
||||
std::process::exit(0);
|
||||
}
|
||||
@@ -417,4 +509,15 @@ fn setup_hotkeys(shared_state: Arc<Mutex<SharedState>>) {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Return the hotkey manager from the Arc so it can be stored in the application state
|
||||
match Arc::try_unwrap(manager_arc) {
|
||||
Ok(manager) => Some(manager),
|
||||
Err(_arc) => {
|
||||
// If we can't unwrap the Arc (which shouldn't happen), extract a clone from it
|
||||
println!("Warning: Could not unwrap Arc<GlobalHotKeyManager>, using a new instance");
|
||||
// Create a new instance as a fallback
|
||||
GlobalHotKeyManager::new().ok()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ impl Steam {
|
||||
Self { client, single }
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn drop_item(&self) {
|
||||
unsafe {
|
||||
let mut r = 0;
|
||||
|
||||
Reference in New Issue
Block a user