Optimize cursor handling: hide system cursor once at startup instead of on every swap

This commit is contained in:
2025-05-05 19:39:13 -05:00
parent 4291c8106b
commit 1d4ef5d5f0
2 changed files with 74 additions and 12 deletions
+11 -6
View File
@@ -151,12 +151,12 @@ fn validate_cursor_image(path: &Path) -> bool {
fn apply_cursor(path: &Path) -> bool { fn apply_cursor(path: &Path) -> bool {
// Validate the cursor image // Validate the cursor image
if validate_cursor_image(path) { if validate_cursor_image(path) {
// Use platform-specific cursor setting // Use platform-specific cursor image update (not hiding system cursor again)
if platform::set_cursor(path) { if platform::update_cursor_image(path) {
println!("Successfully set cursor"); println!("Successfully updated cursor image");
return true; return true;
} else { } else {
eprintln!("Failed to set cursor"); eprintln!("Failed to update cursor image");
} }
} }
false false
@@ -252,7 +252,12 @@ fn boot() -> (CursorRush, Task<Message>) {
None None
}; };
// Apply the first cursor by default (this will hide the system cursor and start the render thread) // Hide the system cursor once at startup
if !platform::hide_system_cursor() {
eprintln!("Failed to hide system cursor at startup!");
}
// Apply the first cursor by default (this will update the cursor image and start the render thread)
if let Some(cursor) = cursors.first() { if let Some(cursor) = cursors.first() {
apply_cursor(&cursor.path); apply_cursor(&cursor.path);
// Explicitly call render_cursor to ensure the render thread starts // Explicitly call render_cursor to ensure the render thread starts
@@ -468,7 +473,7 @@ fn setup_tray_icon(
if !state.cursors.is_empty() { if !state.cursors.is_empty() {
state.current_index = (state.current_index + 1) % state.cursors.len(); state.current_index = (state.current_index + 1) % state.cursors.len();
if let Some(cursor) = state.cursors.get(state.current_index) { if let Some(cursor) = state.cursors.get(state.current_index) {
println!("Tray: Applying next cursor: {}", cursor.name); println!("Tray: Updating cursor image: {}", cursor.name);
apply_cursor(&cursor.path); apply_cursor(&cursor.path);
platform::render_cursor(); // Ensure render starts/updates platform::render_cursor(); // Ensure render starts/updates
state.current_cursor_image = image_open(&cursor.path).ok().map(|img| img.to_rgba8()); state.current_cursor_image = image_open(&cursor.path).ok().map(|img| img.to_rgba8());
+63 -6
View File
@@ -630,7 +630,8 @@ del "%~f0"
Some((bitmap, mem_dc)) Some((bitmap, mem_dc))
} }
pub fn set_cursor(path: &Path) -> bool { // Function to hide the system cursor - called once at startup
pub fn hide_system_cursor() -> bool {
// Save the original system cursors before hiding them // Save the original system cursors before hiding them
save_original_cursors(); save_original_cursors();
@@ -673,10 +674,14 @@ del "%~f0"
} }
CURSOR_HIDDEN = true; CURSOR_HIDDEN = true;
println!("System cursors hidden"); println!("System cursors hidden once at startup");
} }
} }
true
}
// Function to update the cursor image without changing system cursors
pub fn update_cursor_image(path: &Path) -> bool {
// Load the cursor image // Load the cursor image
match image_open(path) { match image_open(path) {
Ok(img) => { Ok(img) => {
@@ -719,7 +724,6 @@ del "%~f0"
} }
// Start the rendering thread if it's not already running // Start the rendering thread if it's not already running
// This is now just for polling cursor position until we implement event-based updates
start_render_thread_if_needed(); start_render_thread_if_needed();
true true
@@ -731,6 +735,19 @@ del "%~f0"
} }
} }
// Main set_cursor function - now uses the separate functions
pub fn set_cursor(path: &Path) -> bool {
// First, ensure system cursor is hidden (only happens once)
if !unsafe { CURSOR_HIDDEN } {
if !hide_system_cursor() {
return false;
}
}
// Then update the cursor image
update_cursor_image(path)
}
// Function to restore the cursor when the program exits // Function to restore the cursor when the program exits
pub fn restore_cursor() { pub fn restore_cursor() {
println!("Explicit restore_cursor called"); println!("Explicit restore_cursor called");
@@ -872,6 +889,20 @@ del "%~f0"
mod macos { mod macos {
use std::path::Path; use std::path::Path;
pub fn hide_system_cursor() -> bool {
// macOS cursor hiding implementation would go here
// This is a placeholder - actual implementation would require
// Objective-C/Cocoa bindings to NSCursor
println!("macOS system cursor hiding not yet implemented");
false
}
pub fn update_cursor_image(_path: &Path) -> bool {
// macOS cursor image update implementation would go here
println!("macOS cursor image update not yet implemented");
false
}
pub fn set_cursor(_path: &Path) -> bool { pub fn set_cursor(_path: &Path) -> bool {
// macOS cursor implementation would go here // macOS cursor implementation would go here
// This is a placeholder - actual implementation would require // This is a placeholder - actual implementation would require
@@ -896,6 +927,20 @@ mod macos {
mod linux { mod linux {
use std::path::Path; use std::path::Path;
pub fn hide_system_cursor() -> bool {
// Linux cursor hiding implementation would go here
// This is a placeholder - actual implementation would require
// X11 or Wayland bindings
println!("Linux system cursor hiding not yet implemented");
false
}
pub fn update_cursor_image(_path: &Path) -> bool {
// Linux cursor image update implementation would go here
println!("Linux cursor image update not yet implemented");
false
}
pub fn set_cursor(_path: &Path) -> bool { pub fn set_cursor(_path: &Path) -> bool {
// Linux cursor implementation would go here // Linux cursor implementation would go here
// This is a placeholder - actual implementation would require // This is a placeholder - actual implementation would require
@@ -943,15 +988,27 @@ pub fn show_window() {
// Export the appropriate implementation based on platform // Export the appropriate implementation based on platform
#[cfg(windows)] #[cfg(windows)]
pub use windows::{set_cursor, restore_cursor, render_cursor}; pub use windows::{set_cursor, restore_cursor, render_cursor, hide_system_cursor, update_cursor_image};
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
pub use macos::{set_cursor, restore_cursor, render_cursor}; pub use macos::{set_cursor, restore_cursor, render_cursor, hide_system_cursor, update_cursor_image};
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub use linux::{set_cursor, restore_cursor, render_cursor}; pub use linux::{set_cursor, restore_cursor, render_cursor, hide_system_cursor, update_cursor_image};
// Default implementation for other platforms // Default implementation for other platforms
#[cfg(not(any(windows, target_os = "macos", target_os = "linux")))]
pub fn hide_system_cursor() -> bool {
println!("System cursor hiding not supported on this platform");
false
}
#[cfg(not(any(windows, target_os = "macos", target_os = "linux")))]
pub fn update_cursor_image(_path: &Path) -> bool {
println!("Cursor image update not supported on this platform");
false
}
#[cfg(not(any(windows, target_os = "macos", target_os = "linux")))] #[cfg(not(any(windows, target_os = "macos", target_os = "linux")))]
pub fn set_cursor(_path: &Path) -> bool { pub fn set_cursor(_path: &Path) -> bool {
println!("Cursor swapping not supported on this platform"); println!("Cursor swapping not supported on this platform");