@@ -3,8 +3,10 @@ import type { ChatProvider } from '@xsai-ext/providers/utils'
33
44import workletUrl from ' @proj-airi/stage-ui/workers/vad/process.worklet?worker&url'
55
6+ import { defineInvoke } from ' @moeru/eventa'
67import { electron } from ' @proj-airi/electron-eventa'
78import {
9+ useElectronEventaContext ,
810 useElectronEventaInvoke ,
911 useElectronMouseAroundWindowBorder ,
1012 useElectronMouseInElement ,
@@ -24,11 +26,13 @@ import { useProvidersStore } from '@proj-airi/stage-ui/stores/providers'
2426import { useSettings , useSettingsAudioDevice } from ' @proj-airi/stage-ui/stores/settings'
2527import { refDebounced , useBroadcastChannel } from ' @vueuse/core'
2628import { storeToRefs } from ' pinia'
29+ import { isLinux } from ' std-env'
2730import { computed , onUnmounted , ref , toRef , watch } from ' vue'
2831
2932import ControlsIsland from ' ../components/stage-islands/controls-island/index.vue'
3033import ResourceStatusIsland from ' ../components/stage-islands/resource-status-island/index.vue'
3134
35+ import { electronStartDraggingWindow } from ' ../../shared/eventa'
3236import { useControlsIslandStore } from ' ../stores/controls-island'
3337import { useWindowStore } from ' ../stores/window'
3438
@@ -78,10 +82,17 @@ const isAroundWindowBorderFor250Ms = refDebounced(isAroundWindowBorder, 250)
7882
7983const setIgnoreMouseEvents = useElectronEventaInvoke (electron .window .setIgnoreMouseEvents )
8084
81- const { scale, positionInPercentageString } = storeToRefs (useLive2d ())
85+ const context = useElectronEventaContext ()
86+ const startDraggingWindow = ! isLinux ? defineInvoke (context .value , electronStartDraggingWindow ) : undefined
87+
88+ const live2dStore = useLive2d ()
89+ const { scale, positionInPercentageString } = storeToRefs (live2dStore )
8290const { live2dLookAtX, live2dLookAtY } = storeToRefs (useWindowStore ())
8391const { fadeOnHoverEnabled } = storeToRefs (useControlsIslandStore ())
8492
93+ // Drag hint for window dragging
94+ const showDragHint = ref (false )
95+
8596watch (componentStateStage , () => isLoading .value = componentStateStage .value !== ' mounted' , { immediate: true })
8697
8798const { pause, resume } = watch (isTransparent , (transparent ) => {
@@ -322,6 +333,16 @@ watch([stream, () => vadLoaded.value], async ([s, loaded]) => {
322333 relative z-2 h-full overflow-hidden rounded-xl
323334 transition =" opacity duration-500 ease-in-out"
324335 >
336+ <div
337+ v-show =" !isLoading"
338+ absolute left-0 top-0 z-10 h-12 w-full
339+ cursor-move
340+ :class =" { 'drag-region': isLinux }"
341+ @mousedown =" startDraggingWindow?.()"
342+ @mouseenter =" showDragHint = true"
343+ @mouseleave =" showDragHint = false"
344+ />
345+
325346 <div
326347 v-show =" !isLoading"
327348 :class =" [
0 commit comments