Fixed window dragging for main menu
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
use std::{env, fs::{self, read_dir}, path::{Path, PathBuf}};
|
use std::{env, fs::{self, read_dir}, path::PathBuf};
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
tauri_build::build();
|
tauri_build::build();
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ pub struct Steam {
|
|||||||
impl Steam {
|
impl Steam {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let (client, single) = Client::init_app(AppId(1430270)).unwrap();
|
let (client, single) = Client::init_app(AppId(1430270)).unwrap();
|
||||||
|
println!("Steam client initialized successfully");
|
||||||
Self { client, single }
|
Self { client, single }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,4 +24,17 @@ impl Steam {
|
|||||||
// In a real implementation with the correct API version, we would use:
|
// In a real implementation with the correct API version, we would use:
|
||||||
// self.client.get_inventory().trigger_item_drop(item_def_id);
|
// self.client.get_inventory().trigger_item_drop(item_def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn shutdown(&self) {
|
||||||
|
println!("Steam client shutting down");
|
||||||
|
// The steamworks crate handles cleanup automatically when the client is dropped
|
||||||
|
// But we can add any additional cleanup logic here if needed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Steam {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
println!("Steam client being dropped, performing cleanup");
|
||||||
|
self.shutdown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -171,12 +171,22 @@ fn next_cursor(
|
|||||||
// Command to quit the application
|
// Command to quit the application
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn quit_app(app_handle: AppHandle) {
|
fn quit_app(app_handle: AppHandle) {
|
||||||
|
println!("Quit app command received, performing cleanup");
|
||||||
|
|
||||||
|
// Clean up Steam integration
|
||||||
|
{
|
||||||
|
let steam = STEAM.lock();
|
||||||
|
steam.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up and restore default cursor before exit
|
// Clean up and restore default cursor before exit
|
||||||
match platform::restore_system_cursor() {
|
match platform::restore_system_cursor() {
|
||||||
Ok(_) => println!("Default cursor restored"),
|
Ok(_) => println!("Default cursor restored"),
|
||||||
Err(e) => eprintln!("Failed to restore default cursor: {}", e),
|
Err(e) => eprintln!("Failed to restore default cursor: {}", e),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("Cleanup complete, exiting application");
|
||||||
|
|
||||||
// Exit the application
|
// Exit the application
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
app_handle.exit(0);
|
app_handle.exit(0);
|
||||||
@@ -204,6 +214,52 @@ fn minimize_to_tray(app_handle: AppHandle) -> Result<(), String> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Command to temporarily restore system cursor (for drag operations)
|
||||||
|
#[tauri::command]
|
||||||
|
fn temporarily_restore_cursor() -> Result<(), String> {
|
||||||
|
match platform::restore_system_cursor_temporarily() {
|
||||||
|
Ok(_) => {
|
||||||
|
println!("System cursor temporarily restored for drag operation");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => Err(format!("Failed to restore system cursor: {}", e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Command to re-apply custom cursor (after drag operations)
|
||||||
|
#[tauri::command]
|
||||||
|
fn reapply_custom_cursor(state: tauri::State<AppStateWrapper>) -> Result<(), String> {
|
||||||
|
let app_state = state.0.lock();
|
||||||
|
if !app_state.cursors.is_empty() && app_state.current_index < app_state.cursors.len() {
|
||||||
|
let current_cursor = &app_state.cursors[app_state.current_index];
|
||||||
|
match platform::set_system_cursor(¤t_cursor.path) {
|
||||||
|
Ok(_) => {
|
||||||
|
println!("Custom cursor re-applied after drag operation");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => Err(format!("Failed to re-apply custom cursor: {}", e)),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err("No cursor to re-apply".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Command to manually restore default cursors
|
||||||
|
#[tauri::command]
|
||||||
|
fn restore_default_cursors() -> Result<(), String> {
|
||||||
|
println!("Manual restore default cursors command received");
|
||||||
|
match platform::restore_system_cursor() {
|
||||||
|
Ok(_) => {
|
||||||
|
println!("Default cursors restored successfully");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Failed to restore default cursors: {}", e);
|
||||||
|
Err(format!("Failed to restore default cursors: {}", e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Function to load cursor files from src/cursors directory
|
// Function to load cursor files from src/cursors directory
|
||||||
fn load_cursor_files() -> Vec<Cursor> {
|
fn load_cursor_files() -> Vec<Cursor> {
|
||||||
println!("=== RESOURCE DEBUG [load_cursor_files] ===");
|
println!("=== RESOURCE DEBUG [load_cursor_files] ===");
|
||||||
@@ -403,11 +459,20 @@ pub fn run() {
|
|||||||
}
|
}
|
||||||
"quit" => {
|
"quit" => {
|
||||||
println!("Quit requested from tray");
|
println!("Quit requested from tray");
|
||||||
|
|
||||||
|
// Clean up Steam integration
|
||||||
|
{
|
||||||
|
let steam = STEAM.lock();
|
||||||
|
steam.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up and restore default cursor before exit
|
// Clean up and restore default cursor before exit
|
||||||
match platform::restore_system_cursor() {
|
match platform::restore_system_cursor() {
|
||||||
Ok(_) => println!("Default cursor restored"),
|
Ok(_) => println!("Default cursor restored"),
|
||||||
Err(e) => eprintln!("Failed to restore default cursor: {}", e),
|
Err(e) => eprintln!("Failed to restore default cursor: {}", e),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("Cleanup complete, exiting from tray");
|
||||||
app.exit(0);
|
app.exit(0);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -441,7 +506,10 @@ pub fn run() {
|
|||||||
select_cursor,
|
select_cursor,
|
||||||
next_cursor,
|
next_cursor,
|
||||||
quit_app,
|
quit_app,
|
||||||
minimize_to_tray
|
minimize_to_tray,
|
||||||
|
temporarily_restore_cursor,
|
||||||
|
reapply_custom_cursor,
|
||||||
|
restore_default_cursors
|
||||||
])
|
])
|
||||||
.setup(|_app| {
|
.setup(|_app| {
|
||||||
// Register for events or perform additional setup
|
// Register for events or perform additional setup
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ pub type Result<T> = std::result::Result<T, String>;
|
|||||||
|
|
||||||
// Platform-agnostic interface for cursor handling
|
// Platform-agnostic interface for cursor handling
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
pub use self::windows::{set_cursor, restore_default_cursor, init};
|
pub use self::windows::{set_cursor, restore_default_cursor, restore_default_cursor_temporarily, init};
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
pub use self::macos::{set_cursor, restore_default_cursor, init};
|
pub use self::macos::{set_cursor, restore_default_cursor, init};
|
||||||
@@ -52,6 +52,20 @@ pub fn restore_system_cursor() -> Result<()> {
|
|||||||
restore_default_cursor()
|
restore_default_cursor()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cross-platform implementation for temporarily restoring default cursor
|
||||||
|
pub fn restore_system_cursor_temporarily() -> Result<()> {
|
||||||
|
println!("Temporarily restoring system cursor");
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
{
|
||||||
|
restore_default_cursor_temporarily()
|
||||||
|
}
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
{
|
||||||
|
// For non-Windows platforms, just use the regular restore for now
|
||||||
|
restore_default_cursor()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Default implementations for non-supported platforms
|
// Default implementations for non-supported platforms
|
||||||
#[cfg(not(any(target_os = "windows", target_os = "macos", target_os = "linux")))]
|
#[cfg(not(any(target_os = "windows", target_os = "macos", target_os = "linux")))]
|
||||||
pub fn set_cursor(_path: &str) -> Result<()> {
|
pub fn set_cursor(_path: &str) -> Result<()> {
|
||||||
|
|||||||
@@ -202,6 +202,13 @@ unsafe fn create_cursor_from_image(image: &RgbaImage) -> Option<SyncHCURSOR> {
|
|||||||
pub fn cleanup() {
|
pub fn cleanup() {
|
||||||
println!("Running cursor cleanup...");
|
println!("Running cursor cleanup...");
|
||||||
|
|
||||||
|
// Check if we have original cursors saved before attempting restoration
|
||||||
|
let has_original_cursors = {
|
||||||
|
let guard = ORIGINAL_CURSORS.lock().unwrap();
|
||||||
|
guard.is_some()
|
||||||
|
};
|
||||||
|
println!("Has original cursors saved: {}", has_original_cursors);
|
||||||
|
|
||||||
// Restore system cursors if they were hidden
|
// Restore system cursors if they were hidden
|
||||||
// Use swap to ensure it runs only once
|
// Use swap to ensure it runs only once
|
||||||
if CURSOR_HIDDEN.swap(false, Ordering::SeqCst) {
|
if CURSOR_HIDDEN.swap(false, Ordering::SeqCst) {
|
||||||
@@ -211,15 +218,24 @@ pub fn cleanup() {
|
|||||||
// Try multiple approaches to ensure cursors are restored
|
// Try multiple approaches to ensure cursors are restored
|
||||||
|
|
||||||
// 1. First try to restore original cursors if we saved them
|
// 1. First try to restore original cursors if we saved them
|
||||||
let original_cursors_opt = ORIGINAL_CURSORS.lock().unwrap().take();
|
let original_cursors_opt = {
|
||||||
|
let mut guard = ORIGINAL_CURSORS.lock().unwrap();
|
||||||
|
guard.take()
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(original_cursors) = original_cursors_opt {
|
if let Some(original_cursors) = original_cursors_opt {
|
||||||
println!("Restoring {} saved original cursors", original_cursors.len());
|
let total_cursors = original_cursors.len();
|
||||||
|
println!("Restoring {} saved original cursors", total_cursors);
|
||||||
|
let mut restored_count = 0;
|
||||||
for (cursor_id, cursor) in original_cursors {
|
for (cursor_id, cursor) in original_cursors {
|
||||||
if !cursor.0.is_null() {
|
if !cursor.0.is_null() {
|
||||||
// Make a copy of the original cursor
|
// Make a copy of the original cursor
|
||||||
let cursor_copy = CopyIcon(cursor.0);
|
let cursor_copy = CopyIcon(cursor.0);
|
||||||
if !cursor_copy.is_null() {
|
if !cursor_copy.is_null() {
|
||||||
if SetSystemCursor(cursor_copy, cursor_id) == 0 {
|
if SetSystemCursor(cursor_copy, cursor_id) != 0 {
|
||||||
|
restored_count += 1;
|
||||||
|
println!("Successfully restored cursor for ID: {}", cursor_id);
|
||||||
|
} else {
|
||||||
eprintln!("Failed to restore original cursor for ID: {}", cursor_id);
|
eprintln!("Failed to restore original cursor for ID: {}", cursor_id);
|
||||||
DestroyIcon(cursor_copy);
|
DestroyIcon(cursor_copy);
|
||||||
}
|
}
|
||||||
@@ -231,8 +247,25 @@ pub fn cleanup() {
|
|||||||
DestroyIcon(cursor.0);
|
DestroyIcon(cursor.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
println!("Restored {} out of {} original cursors", restored_count, total_cursors);
|
||||||
} else {
|
} else {
|
||||||
println!("No saved original cursors found");
|
println!("No saved original cursors found, using fallback restoration methods");
|
||||||
|
|
||||||
|
// Try to restore each system cursor to its default
|
||||||
|
for &cursor_id in SYSTEM_CURSORS.iter() {
|
||||||
|
let default_cursor = LoadCursorW(null_mut(), MAKEINTRESOURCEW(cursor_id as u16));
|
||||||
|
if !default_cursor.is_null() {
|
||||||
|
let cursor_copy = CopyIcon(default_cursor);
|
||||||
|
if !cursor_copy.is_null() {
|
||||||
|
if SetSystemCursor(cursor_copy, cursor_id) != 0 {
|
||||||
|
println!("Restored default cursor for ID: {}", cursor_id);
|
||||||
|
} else {
|
||||||
|
eprintln!("Failed to restore default cursor for ID: {}", cursor_id);
|
||||||
|
DestroyIcon(cursor_copy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Force Windows to reload default cursor settings
|
// 2. Force Windows to reload default cursor settings
|
||||||
@@ -310,19 +343,26 @@ pub fn hide_system_cursor() -> bool {
|
|||||||
// Save original cursors for restoration
|
// Save original cursors for restoration
|
||||||
let mut original_cursors = Vec::new();
|
let mut original_cursors = Vec::new();
|
||||||
unsafe {
|
unsafe {
|
||||||
|
println!("Saving original cursors for restoration...");
|
||||||
for &cursor_id in SYSTEM_CURSORS.iter() {
|
for &cursor_id in SYSTEM_CURSORS.iter() {
|
||||||
// Get the original cursor
|
// Get the original cursor
|
||||||
let original_cursor = CopyIcon(LoadCursorW(null_mut(), MAKEINTRESOURCEW(cursor_id as u16)));
|
let original_cursor = CopyIcon(LoadCursorW(null_mut(), MAKEINTRESOURCEW(cursor_id as u16)));
|
||||||
if !original_cursor.is_null() {
|
if !original_cursor.is_null() {
|
||||||
// Save the original cursor for restoration
|
// Save the original cursor for restoration
|
||||||
original_cursors.push((cursor_id, SyncHCURSOR(original_cursor)));
|
original_cursors.push((cursor_id, SyncHCURSOR(original_cursor)));
|
||||||
|
println!("Saved original cursor for ID: {}", cursor_id);
|
||||||
|
} else {
|
||||||
|
eprintln!("Failed to save original cursor for ID: {}", cursor_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store original cursors for restoration
|
// Store original cursors for restoration
|
||||||
if !original_cursors.is_empty() {
|
if !original_cursors.is_empty() {
|
||||||
|
println!("Storing {} original cursors for later restoration", original_cursors.len());
|
||||||
*ORIGINAL_CURSORS.lock().unwrap() = Some(original_cursors);
|
*ORIGINAL_CURSORS.lock().unwrap() = Some(original_cursors);
|
||||||
|
} else {
|
||||||
|
eprintln!("No original cursors were saved!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark as hidden - this is now just a flag to indicate we've saved the original cursors
|
// Mark as hidden - this is now just a flag to indicate we've saved the original cursors
|
||||||
@@ -497,7 +537,30 @@ unsafe fn apply_cursor_to_all_system_cursors(cursor: winapi::shared::windef::HCU
|
|||||||
success
|
success
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore the system cursor
|
// Restore the system cursor temporarily (without affecting cleanup state)
|
||||||
|
pub fn restore_cursor_temporarily() {
|
||||||
|
println!("Temporarily restoring system cursors...");
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
// Force Windows to reload default cursor settings
|
||||||
|
println!("Forcing Windows to reload default cursor settings");
|
||||||
|
SystemParametersInfoW(SPI_SETCURSORS, 0, null_mut(), 0);
|
||||||
|
|
||||||
|
// Also try the A version for maximum compatibility
|
||||||
|
super::state::reset_system_cursors();
|
||||||
|
|
||||||
|
// Reset to default arrow cursor
|
||||||
|
let arrow_cursor = LoadCursorW(null_mut(), MAKEINTRESOURCEW(IDC_ARROW as u16));
|
||||||
|
if !arrow_cursor.is_null() {
|
||||||
|
SetCursor(arrow_cursor);
|
||||||
|
println!("Reset to default arrow cursor temporarily.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Temporary cursor restoration complete.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore the system cursor permanently (full cleanup)
|
||||||
pub fn restore_cursor() {
|
pub fn restore_cursor() {
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,12 @@ pub fn restore_default_cursor() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn restore_default_cursor_temporarily() -> Result<()> {
|
||||||
|
println!("Windows platform: temporarily restoring default cursor");
|
||||||
|
cursor::restore_cursor_temporarily();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init() -> Result<()> {
|
pub fn init() -> Result<()> {
|
||||||
println!("Windows platform: initializing cursor system");
|
println!("Windows platform: initializing cursor system");
|
||||||
if !cursor::hide_system_cursor() {
|
if !cursor::hide_system_cursor() {
|
||||||
|
|||||||
@@ -47,6 +47,35 @@ function App() {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// Function to handle window focus/show events to re-apply cursor
|
||||||
|
useEffect(() => {
|
||||||
|
const setupFocusHandler = async () => {
|
||||||
|
const unlistenFocus = await appWindow.onFocusChanged(async ({ payload: focused }) => {
|
||||||
|
if (focused) {
|
||||||
|
console.log('Window gained focus, re-applying custom cursor');
|
||||||
|
try {
|
||||||
|
await invoke("reapply_custom_cursor");
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to re-apply cursor on focus:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return unlistenFocus;
|
||||||
|
};
|
||||||
|
|
||||||
|
let unlistenFocusFn;
|
||||||
|
setupFocusHandler().then(unlisten => {
|
||||||
|
unlistenFocusFn = unlisten;
|
||||||
|
}).catch(err => console.error('Failed to set up focus handler:', err));
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (unlistenFocusFn) {
|
||||||
|
unlistenFocusFn();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
// Load cursors on mount and set up event listeners
|
// Load cursors on mount and set up event listeners
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadCursors = async () => {
|
const loadCursors = async () => {
|
||||||
@@ -87,6 +116,14 @@ function App() {
|
|||||||
// Prevent the window from closing
|
// Prevent the window from closing
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
|
// Temporarily restore cursor before hiding to tray
|
||||||
|
try {
|
||||||
|
console.log('Temporarily restoring cursor before hiding to tray');
|
||||||
|
await invoke("temporarily_restore_cursor");
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to restore cursor before hiding:', error);
|
||||||
|
}
|
||||||
|
|
||||||
// Hide the window instead
|
// Hide the window instead
|
||||||
try {
|
try {
|
||||||
console.log('Calling minimizeToTray function');
|
console.log('Calling minimizeToTray function');
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
background-color: transparent; /* Reverted to original */
|
background-color: transparent; /* Reverted to original */
|
||||||
/* cursor: move; */ /* Removed, should be handled by drag region or default */
|
-webkit-app-region: drag; /* Ensure the header is draggable */
|
||||||
|
/* cursor: move; */ /* Let the system handle cursor during drag operations */
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabs-container {
|
.tabs-container {
|
||||||
@@ -64,6 +65,16 @@
|
|||||||
color: rgba(205, 214, 244, 0.8);
|
color: rgba(205, 214, 244, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dedicated drag area */
|
||||||
|
.drag-area {
|
||||||
|
flex: 1; /* Take up remaining space */
|
||||||
|
height: 100%;
|
||||||
|
min-width: 50px; /* Ensure there's always some draggable space */
|
||||||
|
-webkit-app-region: drag; /* Explicitly set as draggable */
|
||||||
|
/* cursor: move; */ /* Let the system handle cursor during drag operations */
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
/* Window control buttons */
|
/* Window control buttons */
|
||||||
.window-controls {
|
.window-controls {
|
||||||
-webkit-app-region: no-drag; /* Override drag region for buttons */
|
-webkit-app-region: no-drag; /* Override drag region for buttons */
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './Header.css';
|
import './Header.css';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
import { appWindow } from '@tauri-apps/api/window';
|
||||||
|
import { invoke } from '@tauri-apps/api/tauri';
|
||||||
import {
|
import {
|
||||||
faGripVertical,
|
faGripVertical,
|
||||||
faBoxOpen,
|
faBoxOpen,
|
||||||
@@ -36,8 +38,29 @@ function Header({ activePage, setActivePage, minimizeToTray, quitApp, settings }
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Handle window dragging programmatically as a fallback
|
||||||
|
const handleMouseDown = async (e) => {
|
||||||
|
// Only start dragging on left mouse button and if not clicking on interactive elements
|
||||||
|
if (e.button === 0 && !e.target.closest('.tab, .window-controls')) {
|
||||||
|
try {
|
||||||
|
// Temporarily restore system cursor for dragging
|
||||||
|
await invoke('temporarily_restore_cursor');
|
||||||
|
await appWindow.startDragging();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to start window dragging:', error);
|
||||||
|
} finally {
|
||||||
|
// Re-apply custom cursor after dragging
|
||||||
|
try {
|
||||||
|
await invoke('reapply_custom_cursor');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to re-apply custom cursor:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="app-header" data-tauri-drag-region>
|
<header className="app-header" data-tauri-drag-region onMouseDown={handleMouseDown}>
|
||||||
<div className="tabs-container">
|
<div className="tabs-container">
|
||||||
{navItems.map((item) => (
|
{navItems.map((item) => (
|
||||||
<div
|
<div
|
||||||
@@ -49,6 +72,10 @@ function Header({ activePage, setActivePage, minimizeToTray, quitApp, settings }
|
|||||||
<FontAwesomeIcon icon={item.icon} />
|
<FontAwesomeIcon icon={item.icon} />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
{/* Dedicated drag area */}
|
||||||
|
<div className="drag-area" title="Drag to move window"></div>
|
||||||
|
|
||||||
<div className="window-controls">
|
<div className="window-controls">
|
||||||
<button className="minimize-button" onClick={minimizeToTray} title="Minimize to Tray">
|
<button className="minimize-button" onClick={minimizeToTray} title="Minimize to Tray">
|
||||||
_
|
_
|
||||||
|
|||||||
@@ -29,7 +29,9 @@
|
|||||||
.setting-item {
|
.setting-item {
|
||||||
padding: 8px 0;
|
padding: 8px 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.setting-item label {
|
.setting-item label {
|
||||||
@@ -73,3 +75,31 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.restore-button {
|
||||||
|
background-color: var(--accent-color, #89b4fa);
|
||||||
|
color: var(--bg-color, #1e1e2e);
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.restore-button:hover {
|
||||||
|
background-color: var(--accent-hover, #74c7ec);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.restore-button:active {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-description {
|
||||||
|
font-size: 12px;
|
||||||
|
opacity: 0.7;
|
||||||
|
margin: 0;
|
||||||
|
color: var(--text-color, #cdd6f4);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { invoke } from "@tauri-apps/api/tauri";
|
||||||
import './Settings.css';
|
import './Settings.css';
|
||||||
|
|
||||||
function Settings({ settings, setSettings }) {
|
function Settings({ settings, setSettings }) {
|
||||||
@@ -10,6 +11,19 @@ function Settings({ settings, setSettings }) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Handler for restoring default cursors
|
||||||
|
const handleRestoreDefaultCursors = async () => {
|
||||||
|
try {
|
||||||
|
console.log('Manually restoring default cursors');
|
||||||
|
await invoke("restore_default_cursors");
|
||||||
|
console.log('Default cursors restored successfully');
|
||||||
|
alert('Default cursors restored successfully!');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to restore default cursors:', error);
|
||||||
|
alert('Failed to restore default cursors: ' + error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="settings-container">
|
<div className="settings-container">
|
||||||
<h2 className="content-title">Settings</h2>
|
<h2 className="content-title">Settings</h2>
|
||||||
@@ -50,6 +64,17 @@ function Settings({ settings, setSettings }) {
|
|||||||
Auto-apply cursor on selection
|
Auto-apply cursor on selection
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="setting-item">
|
||||||
|
<button
|
||||||
|
onClick={handleRestoreDefaultCursors}
|
||||||
|
className="restore-button"
|
||||||
|
>
|
||||||
|
Restore Default Cursors
|
||||||
|
</button>
|
||||||
|
<p className="setting-description">
|
||||||
|
Manually restore the system's default cursors if they're not working properly.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="settings-group">
|
<div className="settings-group">
|
||||||
|
|||||||
@@ -3,7 +3,5 @@ import ReactDOM from "react-dom/client";
|
|||||||
import App from "./App";
|
import App from "./App";
|
||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||||
<React.StrictMode>
|
|
||||||
<App />
|
<App />
|
||||||
</React.StrictMode>,
|
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user