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 Some(shared) = &state.shared_state {
|
||||||
if let Ok(mut shared_state) = shared.lock() {
|
if let Ok(mut shared_state) = shared.lock() {
|
||||||
shared_state.running = false;
|
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
|
// Restore the system cursor before exiting
|
||||||
platform::restore_cursor();
|
platform::restore_cursor();
|
||||||
|
println!("System cursor restored");
|
||||||
|
|
||||||
// Cleanly drop the tray icon *before* exiting iced
|
// Cleanly drop the tray icon *before* exiting iced
|
||||||
// This removes the icon from the system tray immediately
|
// This removes the icon from the system tray immediately
|
||||||
if let Some(tray) = state.tray_icon.take() {
|
if let Some(tray) = state.tray_icon.take() {
|
||||||
|
println!("Dropping tray icon...");
|
||||||
drop(tray);
|
drop(tray);
|
||||||
println!("Tray icon explicitly dropped.");
|
println!("Tray icon explicitly dropped.");
|
||||||
|
} else {
|
||||||
|
println!("No tray icon to drop");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use iced's exit mechanism for a cleaner shutdown
|
// Use iced's exit mechanism for a cleaner shutdown
|
||||||
@@ -213,9 +232,10 @@ pub struct CursorRush {
|
|||||||
pub shared_state: Option<Arc<Mutex<SharedState>>>,
|
pub shared_state: Option<Arc<Mutex<SharedState>>>,
|
||||||
pub main_window: Option<iced::window::Id>, // Store the main window ID
|
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 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 {
|
impl Default for CursorRush {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -224,6 +244,7 @@ impl Default for CursorRush {
|
|||||||
shared_state: None,
|
shared_state: None,
|
||||||
main_window: None,
|
main_window: None,
|
||||||
tray_icon: None, // Initialize as 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
|
// Return TrayEvent which is essentially a no-op
|
||||||
Message::TrayEvent
|
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
|
// Handle other events
|
||||||
_ => Message::TrayEvent, // Use TrayEvent as a no-op message
|
_ => 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.");
|
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())
|
(state, Task::none())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up global hotkeys
|
// 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
|
// Set up global hotkey manager
|
||||||
let hotkey_manager = match GlobalHotKeyManager::new() {
|
let hotkey_manager = match GlobalHotKeyManager::new() {
|
||||||
Ok(manager) => manager,
|
Ok(manager) => {
|
||||||
|
println!("Successfully created hotkey manager");
|
||||||
|
manager
|
||||||
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Failed to create hotkey manager: {}", e);
|
eprintln!("Failed to create hotkey manager: {}", e);
|
||||||
// Continue without hotkey support
|
// 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,
|
Code::F12,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
println!("Attempting to register Ctrl+Shift+F12 as exit hotkey");
|
||||||
|
|
||||||
// Register the hotkey with better error handling
|
// Register the hotkey with better error handling
|
||||||
match hotkey_manager.register(hotkey) {
|
let registered_hotkey = match hotkey_manager.register(hotkey) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
println!("Successfully registered Ctrl+Shift+F12 as exit hotkey");
|
println!("Successfully registered Ctrl+Shift+F12 as exit hotkey");
|
||||||
|
hotkey
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Failed to register hotkey: {}", e);
|
eprintln!("Failed to register hotkey: {}", e);
|
||||||
@@ -364,21 +422,50 @@ fn setup_hotkeys(shared_state: Arc<Mutex<SharedState>>) {
|
|||||||
Code::F12,
|
Code::F12,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
println!("Attempting to register fallback hotkey Ctrl+Alt+F12");
|
||||||
match hotkey_manager.register(fallback_hotkey) {
|
match hotkey_manager.register(fallback_hotkey) {
|
||||||
Ok(_) => println!("Registered fallback hotkey Ctrl+Alt+F12 instead"),
|
Ok(_) => {
|
||||||
Err(e) => eprintln!("Failed to register fallback hotkey: {}", e),
|
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");
|
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
|
// Spawn a thread to listen for hotkeys
|
||||||
let state_clone = shared_state.clone();
|
let state_clone = shared_state.clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
println!("Hotkey listener thread started");
|
println!("Hotkey listener thread started");
|
||||||
let event_receiver = global_hotkey::GlobalHotKeyEvent::receiver();
|
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 {
|
loop {
|
||||||
match event_receiver.try_recv() {
|
match event_receiver.try_recv() {
|
||||||
Ok(event) => {
|
Ok(event) => {
|
||||||
@@ -388,15 +475,20 @@ fn setup_hotkeys(shared_state: Arc<Mutex<SharedState>>) {
|
|||||||
// Send Quit message instead of direct exit
|
// Send Quit message instead of direct exit
|
||||||
// Get the global sender
|
// Get the global sender
|
||||||
if let Some(tx) = TRAY_SENDER.lock().unwrap().as_ref() {
|
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) {
|
if let Err(e) = tx.unbounded_send(Message::Quit) {
|
||||||
eprintln!("Failed to send Quit message from hotkey thread: {}", e);
|
eprintln!("Failed to send Quit message from hotkey thread: {}", e);
|
||||||
// Fallback to direct exit if channel fails
|
// Fallback to direct exit if channel fails
|
||||||
|
println!("Using fallback exit mechanism");
|
||||||
platform::restore_cursor();
|
platform::restore_cursor();
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
|
} else {
|
||||||
|
println!("Successfully sent Quit message through channel");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
eprintln!("Hotkey: Global sender not initialized yet");
|
eprintln!("Hotkey: Global sender not initialized yet");
|
||||||
// Fallback to direct exit if sender not available
|
// Fallback to direct exit if sender not available
|
||||||
|
println!("Global sender not available, using direct exit");
|
||||||
platform::restore_cursor();
|
platform::restore_cursor();
|
||||||
std::process::exit(0);
|
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 }
|
Self { client, single }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn drop_item(&self) {
|
pub fn drop_item(&self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut r = 0;
|
let mut r = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user