@@ -3,10 +3,12 @@ import type { Event } from '@tauri-apps/api/event'
33import { PhysicalPosition , PhysicalSize } from '@tauri-apps/api/dpi'
44import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'
55import { availableMonitors } from '@tauri-apps/api/window'
6+ import { useDebounceFn } from '@vueuse/core'
67import { isNumber } from 'es-toolkit/compat'
78import { onMounted , ref } from 'vue'
89
910import { useAppStore } from '@/stores/app'
11+ import { getCursorMonitor } from '@/utils/monitor'
1012
1113export type WindowState = Record < string , Partial < PhysicalPosition & PhysicalSize > | undefined >
1214
@@ -21,8 +23,32 @@ export function useWindowState() {
2123 appWindow . onMoved ( onChange )
2224
2325 appWindow . onResized ( onChange )
26+
27+ appWindow . onScaleChanged ( clampToMonitor )
2428 } )
2529
30+ const clampToMonitor = useDebounceFn ( async ( ) => {
31+ const monitor = await getCursorMonitor ( )
32+
33+ if ( ! monitor ) return
34+
35+ const { position : monitorPos , size : monitorSize } = monitor
36+ const windowSize = await appWindow . outerSize ( )
37+ const windowPos = await appWindow . outerPosition ( )
38+
39+ const minX = monitorPos . x
40+ const maxX = monitorPos . x + monitorSize . width - windowSize . width
41+ const minY = monitorPos . y
42+ const maxY = monitorPos . y + monitorSize . height - windowSize . height
43+
44+ const clampedX = Math . max ( minX , Math . min ( windowPos . x , maxX ) )
45+ const clampedY = Math . max ( minY , Math . min ( windowPos . y , maxY ) )
46+
47+ if ( clampedX === windowPos . x && clampedY === windowPos . y ) return
48+
49+ return appWindow . setPosition ( new PhysicalPosition ( clampedX , clampedY ) )
50+ } , 500 )
51+
2652 const onChange = async ( event : Event < PhysicalPosition | PhysicalSize > ) => {
2753 const minimized = await appWindow . isMinimized ( )
2854
@@ -31,6 +57,8 @@ export function useWindowState() {
3157 appStore . windowState [ label ] ??= { }
3258
3359 Object . assign ( appStore . windowState [ label ] , event . payload )
60+
61+ clampToMonitor ( )
3462 }
3563
3664 const restoreState = async ( ) => {
@@ -58,6 +86,8 @@ export function useWindowState() {
5886 }
5987
6088 isRestored . value = true
89+
90+ clampToMonitor ( )
6191 }
6292
6393 return {
0 commit comments