From 1d4ef5d5f0852370549a1b2237b59853568c44f9 Mon Sep 17 00:00:00 2001 From: JobyGitGud Date: Mon, 5 May 2025 19:39:13 -0500 Subject: [PATCH] Optimize cursor handling: hide system cursor once at startup instead of on every swap --- src/main.rs | 17 +++++++----- src/platform.rs | 69 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 74 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index 3cceadd..044e8e2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -151,12 +151,12 @@ fn validate_cursor_image(path: &Path) -> bool { fn apply_cursor(path: &Path) -> bool { // Validate the cursor image if validate_cursor_image(path) { - // Use platform-specific cursor setting - if platform::set_cursor(path) { - println!("Successfully set cursor"); + // Use platform-specific cursor image update (not hiding system cursor again) + if platform::update_cursor_image(path) { + println!("Successfully updated cursor image"); return true; } else { - eprintln!("Failed to set cursor"); + eprintln!("Failed to update cursor image"); } } false @@ -252,7 +252,12 @@ fn boot() -> (CursorRush, Task) { 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() { apply_cursor(&cursor.path); // Explicitly call render_cursor to ensure the render thread starts @@ -468,7 +473,7 @@ fn setup_tray_icon( if !state.cursors.is_empty() { state.current_index = (state.current_index + 1) % state.cursors.len(); 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); platform::render_cursor(); // Ensure render starts/updates state.current_cursor_image = image_open(&cursor.path).ok().map(|img| img.to_rgba8()); diff --git a/src/platform.rs b/src/platform.rs index 8843ced..822b18a 100644 --- a/src/platform.rs +++ b/src/platform.rs @@ -630,7 +630,8 @@ del "%~f0" 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_original_cursors(); @@ -673,10 +674,14 @@ del "%~f0" } 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 match image_open(path) { Ok(img) => { @@ -719,7 +724,6 @@ del "%~f0" } // 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(); 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 pub fn restore_cursor() { println!("Explicit restore_cursor called"); @@ -872,6 +889,20 @@ del "%~f0" mod macos { 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 { // macOS cursor implementation would go here // This is a placeholder - actual implementation would require @@ -896,6 +927,20 @@ mod macos { mod linux { 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 { // Linux cursor implementation would go here // This is a placeholder - actual implementation would require @@ -943,15 +988,27 @@ pub fn show_window() { // Export the appropriate implementation based on platform #[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")] -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")] -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 +#[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")))] pub fn set_cursor(_path: &Path) -> bool { println!("Cursor swapping not supported on this platform");