mirror of
https://github.com/System-End/hackatime-desktop.git
synced 2026-04-19 16:28:19 +00:00
fix: make windows register deeplinks
This commit is contained in:
parent
1e9eeb3c2e
commit
fa6acaf41f
5 changed files with 120 additions and 96 deletions
122
src-tauri/Cargo.lock
generated
122
src-tauri/Cargo.lock
generated
|
|
@ -294,12 +294,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
|
|
@ -518,35 +512,6 @@ dependencies = [
|
|||
"windows-link 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cocoa"
|
||||
version = "0.26.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad36507aeb7e16159dfe68db81ccc27571c3ccd4b76fb2fb72fc59e7a4b1b64c"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"block",
|
||||
"cocoa-foundation",
|
||||
"core-foundation 0.10.1",
|
||||
"core-graphics",
|
||||
"foreign-types 0.5.0",
|
||||
"libc",
|
||||
"objc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cocoa-foundation"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81411967c50ee9a1fc11365f8c585f863a22a9697c89239c452292c40ba79b0d"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"block",
|
||||
"core-foundation 0.10.1",
|
||||
"core-graphics-types",
|
||||
"objc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "combine"
|
||||
version = "4.6.7"
|
||||
|
|
@ -854,9 +819,10 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"chrono",
|
||||
"cocoa",
|
||||
"discord-rich-presence",
|
||||
"objc",
|
||||
"objc2 0.5.2",
|
||||
"objc2-app-kit 0.2.2",
|
||||
"objc2-foundation 0.2.2",
|
||||
"once_cell",
|
||||
"open",
|
||||
"rand 0.9.2",
|
||||
|
|
@ -2381,15 +2347,6 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
|
||||
|
||||
[[package]]
|
||||
name = "malloc_buf"
|
||||
version = "0.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "markup5ever"
|
||||
version = "0.14.1"
|
||||
|
|
@ -2490,7 +2447,7 @@ dependencies = [
|
|||
"gtk",
|
||||
"keyboard-types",
|
||||
"objc2 0.6.3",
|
||||
"objc2-app-kit",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
"once_cell",
|
||||
|
|
@ -2647,15 +2604,6 @@ dependencies = [
|
|||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
|
||||
dependencies = [
|
||||
"malloc_buf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc-sys"
|
||||
version = "0.3.5"
|
||||
|
|
@ -2682,6 +2630,22 @@ dependencies = [
|
|||
"objc2-exception-helper",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-app-kit"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"block2 0.5.1",
|
||||
"libc",
|
||||
"objc2 0.5.2",
|
||||
"objc2-core-data 0.2.2",
|
||||
"objc2-core-image 0.2.2",
|
||||
"objc2-foundation 0.2.2",
|
||||
"objc2-quartz-core 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-app-kit"
|
||||
version = "0.3.2"
|
||||
|
|
@ -2693,10 +2657,10 @@ dependencies = [
|
|||
"libc",
|
||||
"objc2 0.6.3",
|
||||
"objc2-cloud-kit",
|
||||
"objc2-core-data",
|
||||
"objc2-core-data 0.3.2",
|
||||
"objc2-core-foundation",
|
||||
"objc2-core-graphics",
|
||||
"objc2-core-image",
|
||||
"objc2-core-image 0.3.2",
|
||||
"objc2-core-text",
|
||||
"objc2-core-video",
|
||||
"objc2-foundation 0.3.2",
|
||||
|
|
@ -2714,6 +2678,18 @@ dependencies = [
|
|||
"objc2-foundation 0.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-data"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"block2 0.5.1",
|
||||
"objc2 0.5.2",
|
||||
"objc2-foundation 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-data"
|
||||
version = "0.3.2"
|
||||
|
|
@ -2749,6 +2725,18 @@ dependencies = [
|
|||
"objc2-io-surface",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-image"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80"
|
||||
dependencies = [
|
||||
"block2 0.5.1",
|
||||
"objc2 0.5.2",
|
||||
"objc2-foundation 0.2.2",
|
||||
"objc2-metal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-image"
|
||||
version = "0.3.2"
|
||||
|
|
@ -2865,7 +2853,7 @@ checksum = "f112d1746737b0da274ef79a23aac283376f335f4095a083a267a082f21db0c0"
|
|||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"objc2 0.6.3",
|
||||
"objc2-app-kit",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-foundation 0.3.2",
|
||||
]
|
||||
|
||||
|
|
@ -2925,7 +2913,7 @@ dependencies = [
|
|||
"bitflags 2.9.4",
|
||||
"block2 0.6.2",
|
||||
"objc2 0.6.3",
|
||||
"objc2-app-kit",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
"objc2-javascript-core",
|
||||
|
|
@ -4699,7 +4687,7 @@ dependencies = [
|
|||
"ndk-context",
|
||||
"ndk-sys",
|
||||
"objc2 0.6.3",
|
||||
"objc2-app-kit",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-foundation 0.3.2",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
|
|
@ -4765,7 +4753,7 @@ dependencies = [
|
|||
"mime",
|
||||
"muda",
|
||||
"objc2 0.6.3",
|
||||
"objc2-app-kit",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-foundation 0.3.2",
|
||||
"objc2-ui-kit",
|
||||
"objc2-web-kit",
|
||||
|
|
@ -4903,7 +4891,7 @@ checksum = "786156aa8e89e03d271fbd3fe642207da8e65f3c961baa9e2930f332bf80a1f5"
|
|||
dependencies = [
|
||||
"dunce",
|
||||
"glob",
|
||||
"objc2-app-kit",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-foundation 0.3.2",
|
||||
"open",
|
||||
"schemars 0.8.22",
|
||||
|
|
@ -4995,7 +4983,7 @@ dependencies = [
|
|||
"jni",
|
||||
"log",
|
||||
"objc2 0.6.3",
|
||||
"objc2-app-kit",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-foundation 0.3.2",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
|
|
@ -5447,7 +5435,7 @@ dependencies = [
|
|||
"libappindicator",
|
||||
"muda",
|
||||
"objc2 0.6.3",
|
||||
"objc2-app-kit",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-core-foundation",
|
||||
"objc2-core-graphics",
|
||||
"objc2-foundation 0.3.2",
|
||||
|
|
@ -5974,7 +5962,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c"
|
||||
dependencies = [
|
||||
"objc2 0.6.3",
|
||||
"objc2-app-kit",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
"raw-window-handle",
|
||||
|
|
@ -6510,7 +6498,7 @@ dependencies = [
|
|||
"libc",
|
||||
"ndk",
|
||||
"objc2 0.6.3",
|
||||
"objc2-app-kit",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
"objc2-ui-kit",
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ tauri-build = { version = "2", features = [] }
|
|||
tauri = { version = "2", features = ["tray-icon"] }
|
||||
tauri-plugin-opener = "2"
|
||||
tauri-plugin-deep-link = "2"
|
||||
tauri-plugin-single-instance = "2"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
open = "5"
|
||||
|
|
@ -41,6 +42,7 @@ once_cell = "1"
|
|||
tauri-plugin-updater = "2"
|
||||
|
||||
[target."cfg(target_os = \"macos\")".dependencies]
|
||||
cocoa = "0.26"
|
||||
objc = "0.2"
|
||||
objc2 = "0.5"
|
||||
objc2-app-kit = { version = "0.2", features = ["NSColor"] }
|
||||
objc2-foundation = "0.2"
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,24 @@ fn get_recent_logs() -> Vec<LogEntry> {
|
|||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_single_instance::init(|app, args, cwd| {
|
||||
push_log("info", "backend", format!("Single instance detected. Args: {:?}, CWD: {}", args, cwd));
|
||||
|
||||
// Show the existing window
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.show();
|
||||
let _ = window.set_focus();
|
||||
push_log("info", "backend", "Brought existing window to front".to_string());
|
||||
}
|
||||
|
||||
// Process any deep links from the new instance attempt
|
||||
for arg in args {
|
||||
if arg.starts_with("hackatime://") {
|
||||
push_log("info", "backend", format!("Processing deep link from second instance: {}", arg));
|
||||
handle_oauth_callback(&app, &arg);
|
||||
}
|
||||
}
|
||||
}))
|
||||
.plugin(tauri_plugin_process::init())
|
||||
.plugin(tauri_plugin_updater::Builder::new().build())
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
|
|
@ -149,33 +167,34 @@ pub fn run() {
|
|||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
window.set_title_bar_style(TitleBarStyle::Transparent).unwrap();
|
||||
use objc2::runtime::AnyObject;
|
||||
use objc2_app_kit::NSColor;
|
||||
use objc2::msg_send;
|
||||
|
||||
if let Err(e) = window.set_title_bar_style(TitleBarStyle::Transparent) {
|
||||
push_log("error", "backend", format!("Failed to set title bar style: {}", e));
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[allow(unexpected_cfgs)]
|
||||
{
|
||||
use cocoa::appkit::{NSColor, NSWindow};
|
||||
use cocoa::base::{id, nil};
|
||||
|
||||
let ns_window = window.ns_window().unwrap() as id;
|
||||
// Apply macOS-specific window styling with proper error handling
|
||||
if let Ok(ns_win) = window.ns_window() {
|
||||
let ns_window = ns_win as *mut AnyObject;
|
||||
unsafe {
|
||||
use objc::{msg_send, sel, sel_impl};
|
||||
use objc::runtime::NO;
|
||||
let clear_color = NSColor::clearColor();
|
||||
let _: () = msg_send![ns_window, setBackgroundColor: &*clear_color];
|
||||
let _: () = msg_send![ns_window, setOpaque: false];
|
||||
|
||||
|
||||
let bg_color = NSColor::clearColor(nil);
|
||||
ns_window.setBackgroundColor_(bg_color);
|
||||
|
||||
ns_window.setOpaque_(NO);
|
||||
|
||||
let content_view: id = msg_send![ns_window, contentView];
|
||||
let content_view: *mut AnyObject = msg_send![ns_window, contentView];
|
||||
let _: () = msg_send![content_view, setWantsLayer: true];
|
||||
|
||||
let layer: id = msg_send![content_view, layer];
|
||||
let layer: *mut AnyObject = msg_send![content_view, layer];
|
||||
let _: () = msg_send![layer, setCornerRadius: 12.0f64];
|
||||
let _: () = msg_send![layer, setMasksToBounds: true];
|
||||
|
||||
let _: () = msg_send![layer, setNeedsDisplayOnBoundsChange: true];
|
||||
}
|
||||
push_log("info", "backend", "✅ macOS window styling applied".to_string());
|
||||
} else {
|
||||
push_log("error", "backend", "Failed to get NSWindow".to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -224,7 +243,7 @@ pub fn run() {
|
|||
});
|
||||
|
||||
|
||||
#[cfg(any(target_os = "linux", all(debug_assertions, target_os = "windows")))]
|
||||
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
||||
{
|
||||
app.deep_link().register_all().unwrap_or_else(|e| {
|
||||
push_log("error", "backend", format!("Failed to register deep links: {}", e));
|
||||
|
|
@ -236,14 +255,29 @@ pub fn run() {
|
|||
|
||||
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let window_handle = window.clone();
|
||||
let _ = window.on_window_event(move |event| {
|
||||
let app_handle = app.handle().clone();
|
||||
window.on_window_event(move |event| {
|
||||
match event {
|
||||
WindowEvent::CloseRequested { api, .. } => {
|
||||
push_log("info", "backend", "🪟 Window close requested - hiding to tray".to_string());
|
||||
api.prevent_close();
|
||||
let _ = window_handle.hide();
|
||||
push_log("info", "backend", "✅ Window hidden to tray".to_string());
|
||||
|
||||
// Use the app handle to get the window and hide it asynchronously
|
||||
// This prevents potential re-entrancy issues
|
||||
let app_clone = app_handle.clone();
|
||||
std::thread::spawn(move || {
|
||||
if let Some(win) = app_clone.get_webview_window("main") {
|
||||
let _ = win.hide();
|
||||
push_log("info", "backend", "✅ Window hidden to tray".to_string());
|
||||
}
|
||||
});
|
||||
}
|
||||
WindowEvent::Resized(_) => {
|
||||
// Handle resize events gracefully - no action needed
|
||||
// This prevents potential crashes on macOS with transparent windows
|
||||
}
|
||||
WindowEvent::Moved(_) => {
|
||||
// Handle move events gracefully
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ use crate::push_log;
|
|||
|
||||
pub fn setup_app_menu(app: &AppHandle) -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let about_quit = MenuItem::with_id(app, "quit", "Quit Hackatime", true, None::<&str>)?;
|
||||
let quit_item = PredefinedMenuItem::quit(app, Some("Quit Hackatime"))?;
|
||||
let about_menu = Submenu::with_items(
|
||||
app,
|
||||
"About",
|
||||
"Hackatime",
|
||||
true,
|
||||
&[
|
||||
&about_quit,
|
||||
&quit_item,
|
||||
],
|
||||
)?;
|
||||
|
||||
|
|
@ -62,7 +62,6 @@ pub fn setup_app_menu(app: &AppHandle) -> Result<(), Box<dyn std::error::Error>>
|
|||
|
||||
app.on_menu_event(|app, event| {
|
||||
match event.id.as_ref() {
|
||||
"quit" => app.exit(0),
|
||||
"show" => {
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.show();
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"single-instance": {},
|
||||
"updater": {
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDdERjg4QTFCNTJFMDk0MUQKUldRZGxPQlNHNHI0ZlRkMDN0MGI1MnllY1dUVStZalV3dVdhcTFuREx5SGtBc0txQ2xnTWs3WU4K",
|
||||
"endpoints": [
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue