mirror of
https://github.com/moku-project/Moku.git
synced 2026-06-13 01:09:56 -05:00
Fix: Exit Button Works
This commit is contained in:
Generated
+1
@@ -2008,6 +2008,7 @@ name = "moku"
|
||||
version = "0.9.3"
|
||||
dependencies = [
|
||||
"dirs 5.0.1",
|
||||
"libc",
|
||||
"reqwest 0.12.28",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
||||
@@ -28,6 +28,7 @@ serde_json = "1"
|
||||
walkdir = "2"
|
||||
sysinfo = "0.32"
|
||||
dirs = "5"
|
||||
libc = "0.2"
|
||||
urlencoding = "2"
|
||||
tokio = { version = "1", features = ["rt-multi-thread"] }
|
||||
reqwest = { version = "0.12", features = ["blocking"] }
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "Default permissions for Moku",
|
||||
"windows": ["main"],
|
||||
"windows": [
|
||||
"main"
|
||||
],
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"core:tray:default",
|
||||
@@ -31,6 +33,7 @@
|
||||
"core:window:allow-outer-position",
|
||||
"core:window:allow-scale-factor",
|
||||
"process:default",
|
||||
"process:allow-exit",
|
||||
"process:allow-restart",
|
||||
"http:default",
|
||||
"http:allow-fetch",
|
||||
|
||||
+91
-2
@@ -2,11 +2,20 @@ mod commands;
|
||||
mod server;
|
||||
|
||||
use std::sync::Mutex;
|
||||
use tauri::{Manager, WindowEvent};
|
||||
use tauri::{
|
||||
menu::{Menu, MenuItem, PredefinedMenuItem},
|
||||
tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent},
|
||||
Manager, WindowEvent,
|
||||
};
|
||||
use tauri_plugin_shell::process::CommandChild;
|
||||
|
||||
pub struct ServerState(pub Mutex<Option<CommandChild>>);
|
||||
|
||||
fn do_quit(app: &tauri::AppHandle) {
|
||||
server::kill_tachidesk(app);
|
||||
app.exit(0);
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
@@ -44,7 +53,87 @@ pub fn run() {
|
||||
commands::biometric::windows_hello_authenticate,
|
||||
commands::biometric::windows_hello_available,
|
||||
])
|
||||
.setup(|_app| Ok(()))
|
||||
.setup(|app| {
|
||||
let lock_path = app
|
||||
.path()
|
||||
.app_data_dir()
|
||||
.unwrap_or_default()
|
||||
.join(".moku.lock");
|
||||
|
||||
let lock_file = std::fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.open(&lock_path)
|
||||
.ok();
|
||||
|
||||
let already_running = lock_file.as_ref().map(|f| {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::io::AsRawFd;
|
||||
unsafe { libc::flock(f.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) != 0 }
|
||||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use std::os::windows::io::AsRawHandle;
|
||||
use windows::Win32::Foundation::HANDLE;
|
||||
use windows::Win32::Storage::FileSystem::{
|
||||
LockFileEx, LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY,
|
||||
};
|
||||
let handle = HANDLE(f.as_raw_handle() as isize);
|
||||
let mut overlapped = windows::Win32::System::IO::OVERLAPPED::default();
|
||||
!unsafe {
|
||||
LockFileEx(handle, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, 1, 0, &mut overlapped)
|
||||
}.as_bool()
|
||||
}
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
{ false }
|
||||
}).unwrap_or(false);
|
||||
|
||||
if already_running {
|
||||
app.handle().exit(0);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
std::mem::forget(lock_file);
|
||||
|
||||
let show = MenuItem::with_id(app, "show", "Show Moku", true, None::<&str>)?;
|
||||
let sep = PredefinedMenuItem::separator(app)?;
|
||||
let quit = MenuItem::with_id(app, "quit", "Quit Moku", true, None::<&str>)?;
|
||||
let menu = Menu::with_items(app, &[&show, &sep, &quit])?;
|
||||
|
||||
TrayIconBuilder::new()
|
||||
.icon(app.default_window_icon().unwrap().clone())
|
||||
.menu(&menu)
|
||||
.show_menu_on_left_click(false)
|
||||
.tooltip("Moku")
|
||||
.on_menu_event(|app, event| match event.id.as_ref() {
|
||||
"show" => {
|
||||
if let Some(win) = app.get_webview_window("main") {
|
||||
let _ = win.show();
|
||||
let _ = win.set_focus();
|
||||
}
|
||||
}
|
||||
"quit" => do_quit(app),
|
||||
_ => {}
|
||||
})
|
||||
.on_tray_icon_event(|tray, event| {
|
||||
if let TrayIconEvent::Click {
|
||||
button: MouseButton::Left,
|
||||
button_state: MouseButtonState::Up,
|
||||
..
|
||||
} = event
|
||||
{
|
||||
let app = tray.app_handle();
|
||||
if let Some(win) = app.get_webview_window("main") {
|
||||
let _ = win.show();
|
||||
let _ = win.set_focus();
|
||||
}
|
||||
}
|
||||
})
|
||||
.build(app)?;
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.on_window_event(|window, event| {
|
||||
if let WindowEvent::Destroyed = event {
|
||||
server::kill_tachidesk(window.app_handle());
|
||||
|
||||
Reference in New Issue
Block a user