diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index 17884b6..0c94b66 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -12,7 +12,10 @@ "core:window:allow-set-ignore-cursor-events", "core:window:allow-set-position", "core:window:allow-set-size", + "core:window:allow-set-always-on-top", "core:window:allow-current-monitor", + "core:window:allow-show", + "core:window:allow-hide", "global-shortcut:allow-register", "global-shortcut:allow-unregister", "global-shortcut:allow-is-registered" diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 8a2fcb0..ed546b0 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -7,7 +7,7 @@ use tauri::{ tray::TrayIconBuilder, Emitter, Manager, }; -// global shortcut disabled during dev +use tauri_plugin_global_shortcut::{GlobalShortcutExt, Shortcut, ShortcutState}; // --------------------------------------------------------------------------- // Data structures @@ -64,10 +64,10 @@ fn apply_click_through(app: &tauri::AppHandle, ignore: bool) { } } -/// Show the overlay window and capture mouse events. +/// Show the overlay window, cover the screen, and capture mouse events. fn show_overlay(app: &tauri::AppHandle) { if let Some(window) = app.get_webview_window("overlay") { - // Force window to cover the primary screen (fixes maximized/center conflict on macOS) + // Force window to cover the primary screen if let Ok(Some(monitor)) = window.current_monitor() { let size = monitor.size(); let pos = monitor.position(); @@ -76,18 +76,25 @@ fn show_overlay(app: &tauri::AppHandle) { } let _ = window.show(); let _ = window.set_focus(); - // Re-assert always-on-top so the overlay sits above every app let _ = window.set_always_on_top(true); - let r = window.set_ignore_cursor_events(false); - println!( - "[DrawOver] show_overlay — focus+ignore_cursor result: {:?}", - r - ); + let _ = window.set_ignore_cursor_events(false); + println!("[DrawOver] show_overlay — overlay visible + capturing"); } else { eprintln!("[DrawOver] show_overlay — overlay window not found!"); } } +/// Hide the overlay window so the user can interact with apps behind it. +/// Strokes are preserved — they'll reappear when draw mode is toggled back on. +fn hide_overlay(app: &tauri::AppHandle) { + if let Some(window) = app.get_webview_window("overlay") { + // Make click-through first so mouse events don't get swallowed + let _ = window.set_ignore_cursor_events(true); + let _ = window.hide(); + println!("[DrawOver] hide_overlay — overlay hidden, strokes preserved"); + } +} + // --------------------------------------------------------------------------- // Core draw-mode toggle logic (shared between command, tray, and shortcut) // --------------------------------------------------------------------------- @@ -104,15 +111,14 @@ fn do_toggle_draw_mode(state: &Mutex, app: &tauri::AppHandle) -> bool println!("[DrawOver] do_toggle_draw_mode -> {}", mode); if mode { - // Become a regular app so the overlay can take focus & capture mouse + // Draw mode ON: show overlay and capture mouse for drawing #[cfg(target_os = "macos")] let _ = app.set_activation_policy(tauri::ActivationPolicy::Regular); show_overlay(app); } else { - // Keep clickable so FAB/tray can re-enter draw mode - apply_click_through(app, false); - #[cfg(target_os = "macos")] - let _ = app.set_activation_policy(tauri::ActivationPolicy::Regular); + // Draw mode OFF: hide overlay so user can interact with apps behind it. + // Strokes are preserved in AppState — re-shown when toggled back. + hide_overlay(app); } let _ = app.emit("draw-mode-toggled", mode); @@ -300,15 +306,28 @@ pub fn run() { // ----- Tray icon ----- setup_tray(handle)?; - // ----- Global shortcut: DISABLED (phantom toggle) ----- - // let shortcut: Shortcut = "Alt+Shift+D".parse()?; - // handle.global_shortcut().on_shortcut(shortcut, ...)?; - - // ----- Initial state: overlay clickable ----- + // ----- Global shortcut: Alt+Shift+D (Option+Shift+D on macOS) ----- + let shortcut: Shortcut = "Alt+Shift+D".parse()?; + println!("[DrawOver] registering global shortcut: Alt+Shift+D"); + handle + .global_shortcut() + .on_shortcut(shortcut, move |app, _shortcut, event| { + if event.state == ShortcutState::Pressed { + println!("[DrawOver] global shortcut triggered"); + let state = app.state::>(); + do_toggle_draw_mode(state.inner(), app); + } + }) + .map_err(|e| { + eprintln!("[DrawOver] FAILED to register global shortcut: {}", e); + e + })?; + + // ----- Initial state: overlay hidden (not drawing) ----- #[cfg(target_os = "macos")] - app.set_activation_policy(tauri::ActivationPolicy::Regular); - apply_click_through(app.handle(), false); - println!("[DrawOver] startup complete — overlay clickable"); + app.set_activation_policy(tauri::ActivationPolicy::Accessory); + hide_overlay(app.handle()); + println!("[DrawOver] startup complete — overlay hidden, press Alt+Shift+D to draw"); Ok(()) }) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index ae04b93..3d23a52 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -20,8 +20,9 @@ "alwaysOnTop": true, "decorations": false, "transparent": true, - "skipTaskbar": false, + "skipTaskbar": true, "resizable": false, + "visible": false, "width": 1920, "height": 1080, "center": true diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index b6e74f3..2137215 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -15,7 +15,6 @@ let isDrawing = $state(false); let currentPoints: Point[] = []; let dpr = 1; - let pdown = $state(0); // Store subscription values for template reactivity let drawModeOn = $state(false); @@ -53,7 +52,6 @@ } function onPointerDown(e: PointerEvent): void { - pdown++; console.log('[DrawOver] pointerdown', { drawModeOn, button: e.button, type: e.pointerType }); if (!drawModeOn) return; if (e.button !== 0 && e.pointerType === 'mouse') return; @@ -294,16 +292,16 @@
-
- mode:{drawModeOn} tool:{tool} cls:{drawModeOn ? 'CAPTURE' : 'pass'} pdown:{pdown} strokes:{strokes.length} -
- - + {#if drawModeOn} + + {/if}