feat(desktop): always-on-top for main and detached windows
This commit is contained in:
1 parent
933ed6a670
commit
78d8076c53
18 files changed
+262
-11
No files matched your search
@@ -2,6 +2,7 @@ import { ref, onMounted, onUnmounted } from "vue";
|
||||
import { isTauriRuntime } from "@/lib/backend/tauriRuntime";
|
||||
import { isMacOS } from "@/lib/backend/platform";
|
||||
import * as api from "@/lib/backend/api";
|
||||
import { raiseDetachedWindowsAboveMain, WINDOW_ALWAYS_ON_TOP_CHANGED_EVENT, type WindowAlwaysOnTopChangedPayload } from "@/lib/app/windowAlwaysOnTop";
|
||||
|
||||
const MIN_UI_SCALE = 0.75;
|
||||
const MAX_UI_SCALE = 2;
|
||||
@@ -44,19 +45,29 @@ export function shouldDrawDesktopWindowFrame(isMac: boolean, isDesktop = true, i
|
||||
export function useWindowControls() {
|
||||
const isMaximized = ref(false);
|
||||
const isFullscreen = ref(false);
|
||||
const isAlwaysOnTop = ref(false);
|
||||
const isMac = isMacOS();
|
||||
const isDesktop = isTauriRuntime();
|
||||
const showControls = shouldShowWindowControls(isMac, isDesktop);
|
||||
|
||||
let unlisten: (() => void) | null = null;
|
||||
let unlistenResize: (() => void) | null = null;
|
||||
let unlistenFocus: (() => void) | null = null;
|
||||
let unlistenAlwaysOnTop: (() => void) | null = null;
|
||||
|
||||
async function updateWindowState() {
|
||||
if (!isDesktop) return;
|
||||
const { getCurrentWindow } = await import("@tauri-apps/api/window");
|
||||
const currentWindow = getCurrentWindow();
|
||||
const [maximized, fullscreen] = await Promise.all([currentWindow.isMaximized(), currentWindow.isFullscreen()]);
|
||||
const [maximized, fullscreen, alwaysOnTop] = await Promise.all([currentWindow.isMaximized(), currentWindow.isFullscreen(), currentWindow.isAlwaysOnTop()]);
|
||||
isMaximized.value = maximized;
|
||||
isFullscreen.value = fullscreen;
|
||||
isAlwaysOnTop.value = alwaysOnTop;
|
||||
}
|
||||
|
||||
async function refreshAlwaysOnTopState() {
|
||||
if (!isDesktop) return;
|
||||
const { getCurrentWindow } = await import("@tauri-apps/api/window");
|
||||
isAlwaysOnTop.value = await getCurrentWindow().isAlwaysOnTop();
|
||||
}
|
||||
|
||||
async function minimize() {
|
||||
@@ -70,6 +81,18 @@ export function useWindowControls() {
|
||||
setTimeout(updateWindowState, 50);
|
||||
}
|
||||
|
||||
async function toggleAlwaysOnTop() {
|
||||
if (!isDesktop) return;
|
||||
const { getCurrentWindow } = await import("@tauri-apps/api/window");
|
||||
const currentWindow = getCurrentWindow();
|
||||
const next = !isAlwaysOnTop.value;
|
||||
await currentWindow.setAlwaysOnTop(next);
|
||||
isAlwaysOnTop.value = await currentWindow.isAlwaysOnTop();
|
||||
if (next && currentWindow.label === "main") {
|
||||
await raiseDetachedWindowsAboveMain();
|
||||
}
|
||||
}
|
||||
|
||||
async function close() {
|
||||
if (!isDesktop) return;
|
||||
await api.requestAppClose();
|
||||
@@ -79,14 +102,26 @@ export function useWindowControls() {
|
||||
if (!isDesktop) return;
|
||||
await updateWindowState();
|
||||
const { getCurrentWindow } = await import("@tauri-apps/api/window");
|
||||
const unlistenFn = await getCurrentWindow().onResized(() => {
|
||||
const currentWindow = getCurrentWindow();
|
||||
const windowLabel = currentWindow.label;
|
||||
unlistenResize = await currentWindow.onResized(() => {
|
||||
void updateWindowState();
|
||||
});
|
||||
unlisten = unlistenFn;
|
||||
unlistenFocus = await currentWindow.onFocusChanged(({ payload: focused }) => {
|
||||
if (focused) void refreshAlwaysOnTopState();
|
||||
});
|
||||
const { listen } = await import("@tauri-apps/api/event");
|
||||
unlistenAlwaysOnTop = await listen<WindowAlwaysOnTopChangedPayload>(WINDOW_ALWAYS_ON_TOP_CHANGED_EVENT, (event) => {
|
||||
const payload = event.payload;
|
||||
if (!payload || payload.windowLabel !== windowLabel || typeof payload.alwaysOnTop !== "boolean") return;
|
||||
isAlwaysOnTop.value = payload.alwaysOnTop;
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
unlisten?.();
|
||||
unlistenResize?.();
|
||||
unlistenFocus?.();
|
||||
unlistenAlwaysOnTop?.();
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -95,8 +130,10 @@ export function useWindowControls() {
|
||||
showControls,
|
||||
isMaximized,
|
||||
isFullscreen,
|
||||
isAlwaysOnTop,
|
||||
minimize,
|
||||
toggleMaximize,
|
||||
toggleAlwaysOnTop,
|
||||
close,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user