diff --git a/flake.nix b/flake.nix index 2bdecbac9d..d33070ad51 100644 --- a/flake.nix +++ b/flake.nix @@ -140,7 +140,7 @@ enterShell = with pkgs; '' # Export a LD_LIBRARY_PATH without libudev-zero as libgudev not likey export SLIMEVR_RUST_LD_LIBRARY_PATH="$LD_LIBRARY_PATH" - export LD_LIBRARY_PATH="${libudev-zero}/lib:$LD_LIBRARY_PATH" + export LD_LIBRARY_PATH="${libudev-zero}/lib:${libayatana-appindicator}/lib:$LD_LIBRARY_PATH" # GStreamer plugins won't be found without this export GST_PLUGIN_SYSTEM_PATH_1_0="${pkgs.gst_all_1.gstreamer.out}/lib/gstreamer-1.0:${pkgs.gst_all_1.gst-plugins-base}/lib/gstreamer-1.0:${pkgs.gst_all_1.gst-plugins-good}/lib/gstreamer-1.0:${pkgs.gst_all_1.gst-plugins-bad}/lib/gstreamer-1.0" ''; diff --git a/gui/src-tauri/capabilities/migrated.json b/gui/src-tauri/capabilities/migrated.json index 5e8916e035..c284614949 100644 --- a/gui/src-tauri/capabilities/migrated.json +++ b/gui/src-tauri/capabilities/migrated.json @@ -6,14 +6,7 @@ "main" ], "permissions": [ - "core:path:default", - "core:event:default", - "core:window:default", - "core:app:default", - "core:resources:default", - "core:menu:default", - "core:tray:default", - "core:webview:default", + "core:default", "core:window:allow-close", "core:window:allow-toggle-maximize", "core:window:allow-minimize", @@ -21,6 +14,8 @@ "core:window:allow-hide", "core:window:allow-show", "core:window:allow-set-focus", + "core:window:allow-destroy", + "core:window:allow-request-user-attention", "core:window:allow-set-decorations", "store:default", "os:allow-os-type", diff --git a/gui/src-tauri/src/main.rs b/gui/src-tauri/src/main.rs index fda7f594a1..f40da30ab0 100644 --- a/gui/src-tauri/src/main.rs +++ b/gui/src-tauri/src/main.rs @@ -13,7 +13,8 @@ use clap::Parser; use color_eyre::Result; use state::WindowState; use tauri::Emitter; -use tauri::{Manager, RunEvent, WindowEvent}; +use tauri::WindowEvent; +use tauri::{Manager, RunEvent}; use tauri_plugin_shell::process::CommandChild; use crate::util::{ diff --git a/gui/src/components/TopBar.tsx b/gui/src/components/TopBar.tsx index 4e5f76f44d..c9495a4d6c 100644 --- a/gui/src/components/TopBar.tsx +++ b/gui/src/components/TopBar.tsx @@ -1,4 +1,3 @@ -import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; import { ReactNode, useContext, useEffect, useState } from 'react'; import { NavLink, useMatch } from 'react-router-dom'; import { @@ -25,11 +24,16 @@ import { invoke } from '@tauri-apps/api/core'; import { useTrackers } from '@/hooks/tracker'; import { TrackersStillOnModal } from './TrackersStillOnModal'; import { useConfig } from '@/hooks/config'; -import { listen } from '@tauri-apps/api/event'; +import { listen, TauriEvent } from '@tauri-apps/api/event'; import { TrayOrExitModal } from './TrayOrExitModal'; import { error } from '@/utils/logging'; import { useDoubleTap } from 'use-double-tap'; import { isTrayAvailable } from '@/utils/tauri'; +import { + CloseRequestedEvent, + getCurrentWindow, + UserAttentionType, +} from '@tauri-apps/api/window'; export function VersionTag() { return ( @@ -70,10 +74,11 @@ export function TopBar({ const doesMatchSettings = useMatch({ path: '/settings/*', }); + const closeApp = async () => { await saveConfig(); await invoke('update_window_state'); - await getCurrentWebviewWindow().close(); + await getCurrentWindow().destroy(); }; const tryCloseApp = async (dontTray = false) => { if (isTrayAvailable && config?.useTray === null) { @@ -81,8 +86,8 @@ export function TopBar({ return; } - if (config?.useTray && !dontTray) { - await getCurrentWebviewWindow().hide(); + if (isTrayAvailable && config?.useTray && !dontTray) { + await getCurrentWindow().hide(); await invoke('update_tray_text'); } else if ( config?.connectedTrackersWarning && @@ -95,25 +100,42 @@ export function TopBar({ await closeApp(); } }; + const showVersionBind = useDoubleTap(() => setShowVersionMobile(true)); const unshowVersionBind = useDoubleTap(() => setShowVersionMobile(false)); useEffect(() => { - const unlisten = listen('try-close', async () => { - const window = getCurrentWebviewWindow(); + const unlistenTrayClose = listen('try-close', async () => { + const window = getCurrentWindow(); await window.show(); + await window.requestUserAttention(UserAttentionType.Critical); await window.setFocus(); if (isTrayAvailable) await invoke('update_tray_text'); await tryCloseApp(true); }); + + const unlistenCloseRequested = getCurrentWindow().listen( + TauriEvent.WINDOW_CLOSE_REQUESTED, + async (data) => { + const ev = new CloseRequestedEvent(data); + ev.preventDefault(); + await tryCloseApp(); + } + ); + return () => { - unlisten.then((fn) => fn()); + unlistenTrayClose.then((fn) => fn()); + unlistenCloseRequested.then((fn) => fn()); }; - }, [config?.useTray, config?.connectedTrackersWarning]); + }, [ + config?.useTray, + config?.connectedTrackersWarning, + JSON.stringify(connectedIMUTrackers.map((t) => t.tracker.status)), + ]); useEffect(() => { if (config === null || !isTauri) return; - getCurrentWebviewWindow().setDecorations(config?.decorations).catch(error); + getCurrentWindow().setDecorations(config?.decorations).catch(error); }, [config?.decorations]); useEffect(() => { @@ -252,13 +274,13 @@ export function TopBar({ <>