diff --git a/apps/stage-tamagotchi/src/main/index.ts b/apps/stage-tamagotchi/src/main/index.ts
index a575cdd41..2eaa6db30 100644
--- a/apps/stage-tamagotchi/src/main/index.ts
+++ b/apps/stage-tamagotchi/src/main/index.ts
@@ -214,7 +214,11 @@ app.whenReady().then(async () => {
const settingsWindow = injeca.provide('windows:settings', {
dependsOn: { widgetsManager, beatSync, autoUpdater, devtoolsWindow: devtoolsMarkdownStressWindow, serverChannel, godotStageManager, mcpStdioManager, i18n, windowAuthManager, globalShortcut, spotlightWindow },
- build: async ({ dependsOn }) => setupSettingsWindowReusableFunc(dependsOn),
+ build: async ({ dependsOn }) =>
+ setupSettingsWindowReusableFunc({
+ ...dependsOn,
+ getMainWindow: () => userFacingMainWindow,
+ }),
})
const mainWindow = injeca.provide('windows:main', {
diff --git a/apps/stage-tamagotchi/src/main/windows/main/rpc/index.electron.ts b/apps/stage-tamagotchi/src/main/windows/main/rpc/index.electron.ts
index 20c2501b7..3a7370d8f 100644
--- a/apps/stage-tamagotchi/src/main/windows/main/rpc/index.electron.ts
+++ b/apps/stage-tamagotchi/src/main/windows/main/rpc/index.electron.ts
@@ -15,7 +15,7 @@ import { defineInvokeHandler } from '@moeru/eventa'
import { createContext } from '@moeru/eventa/adapters/electron/main'
import { ipcMain } from 'electron'
-import { electronOpenChat, electronOpenMainDevtools, electronOpenSettings, noticeWindowEventa } from '../../../../shared/eventa'
+import { electronCenterMainWindow, electronOpenChat, electronOpenMainDevtools, electronOpenSettings, noticeWindowEventa } from '../../../../shared/eventa'
import { createAuthService } from '../../../services/airi/auth'
import { createGodotStageService } from '../../../services/airi/godot-stage'
import { createMcpServersService } from '../../../services/airi/mcp-servers'
@@ -23,6 +23,7 @@ import { createOnboardingService } from '../../../services/airi/onboarding'
import { createWidgetsService } from '../../../services/airi/widgets'
import { createAutoUpdaterService } from '../../../services/electron'
import { toggleWindowShow } from '../../shared'
+import { centerWindowOnDisplay } from '../../shared/display'
import { setupBaseWindowElectronInvokes } from '../../shared/window'
export async function setupMainWindowElectronInvokes(params: {
@@ -54,6 +55,7 @@ export async function setupMainWindowElectronInvokes(params: {
createOnboardingService({ context, onboardingWindowManager: params.onboardingWindowManager, mainWindow: params.window })
createAuthService({ context, window: params.window, windowAuthManager: params.windowAuthManager })
+ defineInvokeHandler(context, electronCenterMainWindow, () => centerWindowOnDisplay(params.window))
defineInvokeHandler(context, electronOpenMainDevtools, () => params.window.webContents.openDevTools({ mode: 'detach' }))
defineInvokeHandler(context, electronOpenSettings, payload => params.settingsWindow.openWindow(payload?.route))
defineInvokeHandler(context, electronOpenChat, async () => toggleWindowShow(await params.chatWindow()))
diff --git a/apps/stage-tamagotchi/src/main/windows/settings/index.ts b/apps/stage-tamagotchi/src/main/windows/settings/index.ts
index 2b877433f..8a7fe5e3e 100644
--- a/apps/stage-tamagotchi/src/main/windows/settings/index.ts
+++ b/apps/stage-tamagotchi/src/main/windows/settings/index.ts
@@ -31,6 +31,7 @@ export function setupSettingsWindowReusableFunc(params: {
widgetsManager: WidgetsWindowManager
autoUpdater: AutoUpdater
devtoolsWindow: DevtoolsWindowManager
+ getMainWindow?: () => BrowserWindow | undefined
onWindowCreated?: (window: BrowserWindow) => void
serverChannel: ServerChannel
godotStageManager: GodotStageManager
@@ -73,6 +74,7 @@ export function setupSettingsWindowReusableFunc(params: {
widgetsManager: params.widgetsManager,
autoUpdater: params.autoUpdater,
devtoolsWindow: params.devtoolsWindow,
+ getMainWindow: params.getMainWindow,
serverChannel: params.serverChannel,
godotStageManager: params.godotStageManager,
mcpStdioManager: params.mcpStdioManager,
diff --git a/apps/stage-tamagotchi/src/main/windows/settings/rpc/index.electron.ts b/apps/stage-tamagotchi/src/main/windows/settings/rpc/index.electron.ts
index f125c81dc..66a9d04aa 100644
--- a/apps/stage-tamagotchi/src/main/windows/settings/rpc/index.electron.ts
+++ b/apps/stage-tamagotchi/src/main/windows/settings/rpc/index.electron.ts
@@ -16,6 +16,7 @@ import { createContext } from '@moeru/eventa/adapters/electron/main'
import { ipcMain } from 'electron'
import {
+ electronCenterMainWindow,
electronOpenDevtoolsWindow,
electronOpenSettingsDevtools,
electronSpotlightShortcutGet,
@@ -26,6 +27,7 @@ import { createGodotStageService } from '../../../services/airi/godot-stage'
import { createMcpServersService } from '../../../services/airi/mcp-servers'
import { createWidgetsService } from '../../../services/airi/widgets'
import { createAutoUpdaterService } from '../../../services/electron'
+import { centerWindowOnDisplay } from '../../shared/display'
import { setupBaseWindowElectronInvokes } from '../../shared/window'
export async function setupSettingsWindowInvokes(params: {
@@ -33,6 +35,7 @@ export async function setupSettingsWindowInvokes(params: {
widgetsManager: WidgetsWindowManager
autoUpdater: AutoUpdater
devtoolsWindow: DevtoolsWindowManager
+ getMainWindow?: () => BrowserWindow | undefined
serverChannel: ServerChannel
godotStageManager: GodotStageManager
mcpStdioManager: McpStdioManager
@@ -59,6 +62,7 @@ export async function setupSettingsWindowInvokes(params: {
// Register the global shortcut service for the settings window.
params.globalShortcut.registerWindow({ context, window: params.settingsWindow })
+ defineInvokeHandler(context, electronCenterMainWindow, () => centerWindowOnDisplay(params.getMainWindow?.()))
defineInvokeHandler(context, electronSpotlightShortcutGet, () => params.spotlightWindow.getShortcutAccelerator())
defineInvokeHandler(context, electronSpotlightShortcutSet, (payload) => {
if (payload?.accelerator === undefined)
diff --git a/apps/stage-tamagotchi/src/main/windows/shared/display.test.ts b/apps/stage-tamagotchi/src/main/windows/shared/display.test.ts
index 6da6145d3..81b7e833d 100644
--- a/apps/stage-tamagotchi/src/main/windows/shared/display.test.ts
+++ b/apps/stage-tamagotchi/src/main/windows/shared/display.test.ts
@@ -1,8 +1,16 @@
import type { Rectangle } from 'electron'
+import { screen } from 'electron'
import { describe, expect, it, vi } from 'vitest'
-import { computeResizedBoundsAnchoredToDominantDisplay, heightFrom, mapForBreakpoints, widthFrom } from './display'
+import {
+ centerWindowOnDisplay,
+ computeCenteredWindowBounds,
+ computeResizedBoundsAnchoredToDominantDisplay,
+ heightFrom,
+ mapForBreakpoints,
+ widthFrom,
+} from './display'
// NOTICE:
// Mocking 'electron' is needed to prevent Vitest from attempting to resolve/load the real Electron binary during tests.
@@ -132,3 +140,102 @@ describe('computeResizedBoundsAnchoredToDominantDisplay', () => {
expect(bounds.height).toBe(600)
})
})
+
+/**
+ * @example
+ * computeCenteredWindowBounds({ displayWorkArea, windowBounds })
+ */
+describe('computeCenteredWindowBounds', () => {
+ /**
+ * @example
+ * A 450x600 window is centered without changing its size.
+ */
+ it('preserves the window size and centers it inside the display work area', () => {
+ const result = computeCenteredWindowBounds({
+ displayWorkArea: { x: 0, y: 25, width: 1440, height: 875 },
+ windowBounds: { x: 1200, y: 700, width: 450, height: 600 },
+ })
+
+ expect(result).toEqual({ x: 495, y: 162, width: 450, height: 600 })
+ })
+
+ /**
+ * @example
+ * A display above and left of the primary screen keeps negative coordinates.
+ */
+ it('supports display work areas with negative origins', () => {
+ const result = computeCenteredWindowBounds({
+ displayWorkArea: { x: -1920, y: -1080, width: 1920, height: 1055 },
+ windowBounds: { x: -2300, y: -1300, width: 500, height: 620 },
+ })
+
+ expect(result).toEqual({ x: -1210, y: -863, width: 500, height: 620 })
+ })
+
+ /**
+ * @example
+ * An oversized window starts at the work-area origin instead of moving farther off-screen.
+ */
+ it('keeps oversized windows anchored inside the display work area origin', () => {
+ const result = computeCenteredWindowBounds({
+ displayWorkArea: { x: 120, y: 45, width: 800, height: 500 },
+ windowBounds: { x: -2000, y: -900, width: 1000, height: 640 },
+ })
+
+ expect(result).toEqual({ x: 120, y: 45, width: 1000, height: 640 })
+ })
+})
+
+/**
+ * @example
+ * centerWindowOnDisplay(window)
+ */
+describe('centerWindowOnDisplay', () => {
+ /**
+ * @example
+ * The recovered window receives centered bounds and becomes visible.
+ */
+ it('sets centered bounds and shows the window', () => {
+ const windowBounds = { x: 1200, y: 700, width: 450, height: 600 }
+ const displayWorkArea = { x: 0, y: 25, width: 1440, height: 875 }
+ const setBounds = vi.fn()
+ const show = vi.fn()
+ vi.mocked(screen.getDisplayMatching).mockReturnValue({ workArea: displayWorkArea } as Electron.Display)
+
+ const result = centerWindowOnDisplay({
+ getBounds: () => windowBounds,
+ isDestroyed: () => false,
+ setBounds,
+ show,
+ })
+
+ expect(result).toEqual({ x: 495, y: 162, width: 450, height: 600 })
+ expect(screen.getDisplayMatching).toHaveBeenCalledWith(windowBounds)
+ expect(setBounds).toHaveBeenCalledWith({ x: 495, y: 162, width: 450, height: 600 })
+ expect(show).toHaveBeenCalledTimes(1)
+ })
+
+ /**
+ * @example
+ * A missing main window reports a stable domain error to the renderer.
+ */
+ it('rejects recovery when the target window is unavailable', () => {
+ expect(() => centerWindowOnDisplay(undefined)).toThrowError('Main AIRI window is not available.')
+ })
+
+ /**
+ * @example
+ * A destroyed window is rejected before Electron bounds methods are called.
+ */
+ it('rejects recovery when the target window was destroyed', () => {
+ const getBounds = vi.fn()
+
+ expect(() => centerWindowOnDisplay({
+ getBounds,
+ isDestroyed: () => true,
+ setBounds: vi.fn(),
+ show: vi.fn(),
+ })).toThrowError('Main AIRI window is not available.')
+ expect(getBounds).not.toHaveBeenCalled()
+ })
+})
diff --git a/apps/stage-tamagotchi/src/main/windows/shared/display.ts b/apps/stage-tamagotchi/src/main/windows/shared/display.ts
index 4701f1865..4dbf6f4e8 100644
--- a/apps/stage-tamagotchi/src/main/windows/shared/display.ts
+++ b/apps/stage-tamagotchi/src/main/windows/shared/display.ts
@@ -9,6 +9,62 @@ export function currentDisplayBounds(window: BrowserWindow) {
return nearbyDisplay.bounds
}
+/**
+ * Computes bounds that center a window inside an Electron display work area.
+ *
+ * Use when:
+ * - Recovering a desktop window that was moved outside the visible work area
+ * - Preserving the current window size while changing only its position
+ *
+ * Expects:
+ * - Both rectangles use Electron logical display coordinates
+ * - The display work area excludes menu bars, docks, and taskbars
+ *
+ * Returns:
+ * - Centered bounds that preserve the window width and height
+ */
+export function computeCenteredWindowBounds(options: {
+ displayWorkArea: Rectangle
+ windowBounds: Rectangle
+}): Rectangle {
+ const centeredOffsetX = Math.floor((options.displayWorkArea.width - options.windowBounds.width) / 2)
+ const centeredOffsetY = Math.floor((options.displayWorkArea.height - options.windowBounds.height) / 2)
+
+ return {
+ x: options.displayWorkArea.x + Math.max(0, centeredOffsetX),
+ y: options.displayWorkArea.y + Math.max(0, centeredOffsetY),
+ width: options.windowBounds.width,
+ height: options.windowBounds.height,
+ }
+}
+
+/**
+ * Centers and reveals an Electron window on the display matching its current bounds.
+ *
+ * Use when:
+ * - A renderer requests recovery of an off-screen AIRI window
+ * - A hidden window must become visible after its position is restored
+ *
+ * Expects:
+ * - The window is alive and supports Electron's bounds APIs
+ *
+ * Returns:
+ * - The centered bounds applied to the window
+ */
+export function centerWindowOnDisplay(window: Pick | undefined): Rectangle {
+ if (!window || window.isDestroyed())
+ throw new Error('Main AIRI window is not available.')
+
+ const windowBounds = window.getBounds()
+ const displayWorkArea = screen.getDisplayMatching(windowBounds).workArea
+ const centeredBounds = computeCenteredWindowBounds({ displayWorkArea, windowBounds })
+
+ window.setBounds(centeredBounds)
+ window.show()
+
+ return centeredBounds
+}
+
export interface ResizableDisplayArea {
/** Full display bounds used to decide which physical display owns most of a window. */
bounds: Rectangle
diff --git a/apps/stage-tamagotchi/src/renderer/components/stage-islands/controls-island/index.vue b/apps/stage-tamagotchi/src/renderer/components/stage-islands/controls-island/index.vue
index a9cc2bd02..093ade735 100644
--- a/apps/stage-tamagotchi/src/renderer/components/stage-islands/controls-island/index.vue
+++ b/apps/stage-tamagotchi/src/renderer/components/stage-islands/controls-island/index.vue
@@ -19,6 +19,7 @@ import IndicatorMicVolume from './indicator-mic-volume.vue'
import {
electron,
electronAppQuit,
+ electronCenterMainWindow,
electronOpenChat,
electronOpenSettings,
electronStartDraggingWindow,
@@ -38,6 +39,7 @@ const openChat = useElectronEventaInvoke(electronOpenChat)
const isLinux = useElectronEventaInvoke(electron.app.isLinux)
const closeWindow = useElectronEventaInvoke(electronAppQuit)
const setAlwaysOnTop = useElectronEventaInvoke(electronWindowSetAlwaysOnTop)
+const centerMainWindow = useElectronEventaInvoke(electronCenterMainWindow)
const expanded = ref(false)
const islandRef = ref()
@@ -128,6 +130,13 @@ const startDraggingWindow = !isLinux() ? defineInvoke(context.value, electronSta
function refreshWindow() {
window.location.reload()
}
+
+/**
+ * Requests the main process to move the AIRI desktop window back to screen center.
+ */
+function resetMainWindowPosition() {
+ centerMainWindow().catch(console.error)
+}
@@ -187,6 +196,15 @@ function refreshWindow() {
+
+
+
+
+
+ {{ t('tamagotchi.stage.controls-island.center-main-window') }}
+
+
+
diff --git a/apps/stage-tamagotchi/src/renderer/pages/settings/data/components/desktop-reset-section.vue b/apps/stage-tamagotchi/src/renderer/pages/settings/data/components/desktop-reset-section.vue
index b0f4d7f54..fa21a8e73 100644
--- a/apps/stage-tamagotchi/src/renderer/pages/settings/data/components/desktop-reset-section.vue
+++ b/apps/stage-tamagotchi/src/renderer/pages/settings/data/components/desktop-reset-section.vue
@@ -1,18 +1,25 @@
@@ -37,6 +57,9 @@ async function resetDesktopState() {
+
{{ t('settings.pages.data.sections.desktop.reset') }}
diff --git a/apps/stage-tamagotchi/src/shared/eventa/index.ts b/apps/stage-tamagotchi/src/shared/eventa/index.ts
index 682f32b93..818b602ac 100644
--- a/apps/stage-tamagotchi/src/shared/eventa/index.ts
+++ b/apps/stage-tamagotchi/src/shared/eventa/index.ts
@@ -26,6 +26,7 @@ import type {
VrmLoadStartTracePayload,
VrmUpdateFrameTracePayload,
} from '@proj-airi/stage-ui-three/trace'
+import type { Rectangle } from 'electron'
import { defineEventa, defineInvokeEventa } from '@moeru/eventa'
@@ -33,6 +34,7 @@ export const electronStartTrackMousePosition = defineInvokeEventa('eventa:invoke
export const electronStartDraggingWindow = defineInvokeEventa('eventa:invoke:electron:start-dragging-window')
export const electronOpenMainDevtools = defineInvokeEventa('eventa:invoke:electron:windows:main:devtools:open')
+export const electronCenterMainWindow = defineInvokeEventa('eventa:invoke:electron:windows:main:center')
export const electronOpenSettings = defineInvokeEventa('eventa:invoke:electron:windows:settings:open')
export const electronSettingsNavigate = defineEventa<{ route: string }>('eventa:event:electron:windows:settings:navigate')
export const electronOpenChat = defineInvokeEventa('eventa:invoke:electron:windows:chat:open')
diff --git a/packages/i18n/src/locales/en/settings.yaml b/packages/i18n/src/locales/en/settings.yaml
index ae8f3a334..3399d303e 100644
--- a/packages/i18n/src/locales/en/settings.yaml
+++ b/packages/i18n/src/locales/en/settings.yaml
@@ -456,6 +456,7 @@ pages:
desktop:
title: Reset desktop settings & states
description: Clear AIRI desktop settings and runtime state.
+ center: Move desktop window to center
reset: Reset desktop data
confirmations:
tooltip: Are you sure?
@@ -469,6 +470,7 @@ pages:
modules_reset: Module settings reset.
providers_reset: Provider settings reset.
all_deleted: All local data deleted.
+ desktop_window_centered: Desktop window moved to screen center.
desktop_reset: Desktop data reset.
models:
description: Live2D, VRM, Spine, etc.
diff --git a/packages/i18n/src/locales/en/tamagotchi/stage.yaml b/packages/i18n/src/locales/en/tamagotchi/stage.yaml
index 388e504fd..4be6cfefc 100644
--- a/packages/i18n/src/locales/en/tamagotchi/stage.yaml
+++ b/packages/i18n/src/locales/en/tamagotchi/stage.yaml
@@ -15,6 +15,7 @@ docs:
'open-settings': Open settings
'open-chat': Open Chat
'refresh': Refresh
+ 'center-main-window': Move to screen center
'open-hearing-controls': Open hearing Controls
'drag-to-move-window': Drag to move window
'switch-to-light-mode': Switch to light mode
diff --git a/packages/i18n/src/locales/es/settings.yaml b/packages/i18n/src/locales/es/settings.yaml
index c2531da5e..ce465b455 100644
--- a/packages/i18n/src/locales/es/settings.yaml
+++ b/packages/i18n/src/locales/es/settings.yaml
@@ -437,6 +437,7 @@ pages:
desktop:
title: Restablecer ajustes de escritorio y estados
description: Limpiar ajustes de escritorio y estado de ejecución de AIRI.
+ center: Mover la ventana de escritorio al centro
reset: Restablecer datos de escritorio
confirmations:
tooltip: '¿Estás seguro?'
@@ -450,6 +451,7 @@ pages:
modules_reset: Ajustes del módulo restablecidos.
providers_reset: Ajustes del proveedor restablecidos.
all_deleted: Todos los datos locales eliminados.
+ desktop_window_centered: Ventana de escritorio movida al centro de la pantalla.
desktop_reset: Datos de escritorio restablecidos.
models:
description: Live2D, VRM, Spine, etc.
diff --git a/packages/i18n/src/locales/es/tamagotchi/stage.yaml b/packages/i18n/src/locales/es/tamagotchi/stage.yaml
index 38c969866..f4f81a078 100644
--- a/packages/i18n/src/locales/es/tamagotchi/stage.yaml
+++ b/packages/i18n/src/locales/es/tamagotchi/stage.yaml
@@ -15,6 +15,7 @@ docs:
'open-settings': Abrir configuración
'open-chat': Abrir Chat
'refresh': Actualizar
+ 'center-main-window': Mover al centro de la pantalla
'open-hearing-controls': Abrir controles de audición
'drag-to-move-window': Arrastra para mover la ventana
'switch-to-light-mode': Cambiar a modo claro
diff --git a/packages/i18n/src/locales/fr/settings.yaml b/packages/i18n/src/locales/fr/settings.yaml
index de1e176b7..9a84db610 100644
--- a/packages/i18n/src/locales/fr/settings.yaml
+++ b/packages/i18n/src/locales/fr/settings.yaml
@@ -437,6 +437,7 @@ pages:
desktop:
title: Réinitialiser les paramètres et états du bureau
description: Effacer les paramètres du bureau AIRI et l'état d'exécution.
+ center: Recentrer la fenêtre du bureau
reset: Réinitialiser les données du bureau
confirmations:
tooltip: Êtes-vous sûr(e) ?
@@ -450,6 +451,7 @@ pages:
modules_reset: Paramètres du module réinitialisés.
providers_reset: Paramètres du fournisseur réinitialisés.
all_deleted: Toutes les données locales ont été supprimées.
+ desktop_window_centered: Fenêtre du bureau recentrée sur l’écran.
desktop_reset: Données du bureau réinitialisées.
models:
description: Live2D, VRM, Spine, etc.
diff --git a/packages/i18n/src/locales/fr/tamagotchi/stage.yaml b/packages/i18n/src/locales/fr/tamagotchi/stage.yaml
index 8386e1c85..0f5da92db 100644
--- a/packages/i18n/src/locales/fr/tamagotchi/stage.yaml
+++ b/packages/i18n/src/locales/fr/tamagotchi/stage.yaml
@@ -15,6 +15,7 @@ docs:
'open-settings': Ouvrir les paramètres
'open-chat': Ouvrir le Chat
'refresh': Actualiser
+ 'center-main-window': Recentrer sur l’écran
'open-hearing-controls': Ouvrir les contrôles d'écoute
'drag-to-move-window': Glisser pour déplacer la fenêtre
'switch-to-light-mode': Passer au mode clair
diff --git a/packages/i18n/src/locales/ja/settings.yaml b/packages/i18n/src/locales/ja/settings.yaml
index c4dbfecaf..082ce02ac 100644
--- a/packages/i18n/src/locales/ja/settings.yaml
+++ b/packages/i18n/src/locales/ja/settings.yaml
@@ -437,6 +437,7 @@ pages:
desktop:
title: デスクトップの設定と状態をリセット
description: AIRIデスクトップの設定と実行時の状態を消去します。
+ center: デスクトップウィンドウを中央へ移動
reset: デスクトップのデータをリセット
confirmations:
tooltip: 本当によろしいですか?
@@ -450,6 +451,7 @@ pages:
modules_reset: モジュールの設定をリセットしました。
providers_reset: プロバイダーの設定をリセットしました。
all_deleted: すべてのローカルデータを削除しました。
+ desktop_window_centered: デスクトップウィンドウを画面中央へ移動しました。
desktop_reset: デスクトップのデータをリセットしました。
models:
description: Live2D、VRM、Spine、など。
diff --git a/packages/i18n/src/locales/ja/tamagotchi/stage.yaml b/packages/i18n/src/locales/ja/tamagotchi/stage.yaml
index f130b7390..7503df1de 100644
--- a/packages/i18n/src/locales/ja/tamagotchi/stage.yaml
+++ b/packages/i18n/src/locales/ja/tamagotchi/stage.yaml
@@ -15,6 +15,7 @@ docs:
'open-settings': 設定を開く
'open-chat': チャットを開く
'refresh': 再読み込み
+ 'center-main-window': 画面中央へ移動
'open-hearing-controls': 聴覚コントロールを開く
'drag-to-move-window': ウィンドウをドラッグして移動
'switch-to-light-mode': ライトモードに切り替え
diff --git a/packages/i18n/src/locales/ko/settings.yaml b/packages/i18n/src/locales/ko/settings.yaml
index f5ba6cabf..2d2fbc9ad 100644
--- a/packages/i18n/src/locales/ko/settings.yaml
+++ b/packages/i18n/src/locales/ko/settings.yaml
@@ -437,6 +437,7 @@ pages:
desktop:
title: 데스크탑 설정 및 상태 초기화
description: AIRI 데스크탑 설정 및 런타임 상태를 전부 지웁니다.
+ center: 데스크탑 창을 중앙으로 이동
reset: 데스크탑 데이터 지우기
confirmations:
tooltip: 정말 진행하실 건가요?
@@ -450,6 +451,7 @@ pages:
modules_reset: 모듈 설정이 초기화되었습니다.
providers_reset: 제공자 설정이 초기화되었습니다.
all_deleted: 로컬 데이터가 초기화되었습니다.
+ desktop_window_centered: 데스크탑 창을 화면 중앙으로 이동했습니다.
desktop_reset: 데스크탑 데이터가 초기화되었습니다.
models:
description: Live2D, VRM, Spine, 기타 등등.
diff --git a/packages/i18n/src/locales/ko/tamagotchi/stage.yaml b/packages/i18n/src/locales/ko/tamagotchi/stage.yaml
index db170bd62..32d7c0d0c 100644
--- a/packages/i18n/src/locales/ko/tamagotchi/stage.yaml
+++ b/packages/i18n/src/locales/ko/tamagotchi/stage.yaml
@@ -15,6 +15,7 @@ docs:
'open-settings': 설정 열기
'open-chat': 채팅 열기
'refresh': 새로고침
+ 'center-main-window': 화면 중앙으로 이동
'open-hearing-controls': 듣기 제어 열기
'drag-to-move-window': 드레그하여 창 이동
'switch-to-light-mode': 라이트 모드로 전환
diff --git a/packages/i18n/src/locales/ru/settings.yaml b/packages/i18n/src/locales/ru/settings.yaml
index 622ddc87e..15ed12ce1 100644
--- a/packages/i18n/src/locales/ru/settings.yaml
+++ b/packages/i18n/src/locales/ru/settings.yaml
@@ -437,6 +437,7 @@ pages:
desktop:
title: Сбросить настройки и состояния рабочего стола
description: Очистить настройки AIRI рабочего стола и состояние рабочего времени.
+ center: Переместить окно в центр экрана
reset: Сбросить данные для рабочего стола
confirmations:
tooltip: Вы уверены?
@@ -450,6 +451,7 @@ pages:
modules_reset: Настройки модуля сброшены.
providers_reset: Настройки провайдера сброшены.
all_deleted: Все локальные данные удалены.
+ desktop_window_centered: Окно рабочего стола перемещено в центр экрана.
desktop_reset: Данные рабочего стола сброшены.
models:
description: Live2D, VRM, Spine и др.
diff --git a/packages/i18n/src/locales/ru/tamagotchi/stage.yaml b/packages/i18n/src/locales/ru/tamagotchi/stage.yaml
index 6de68765b..89d1fcfb1 100644
--- a/packages/i18n/src/locales/ru/tamagotchi/stage.yaml
+++ b/packages/i18n/src/locales/ru/tamagotchi/stage.yaml
@@ -15,6 +15,7 @@ docs:
'open-settings': Открыть настройки
'open-chat': Открыть чат
'refresh': Обновить результаты
+ 'center-main-window': Переместить в центр экрана
'open-hearing-controls': Управление слухом
'drag-to-move-window': Перетащите окно
'switch-to-light-mode': Переключить на светлую тему
diff --git a/packages/i18n/src/locales/vi/settings.yaml b/packages/i18n/src/locales/vi/settings.yaml
index 2ee9bede5..f5f5b9c4e 100644
--- a/packages/i18n/src/locales/vi/settings.yaml
+++ b/packages/i18n/src/locales/vi/settings.yaml
@@ -437,6 +437,7 @@ pages:
desktop:
title: Đặt lại thiết lập máy tính
description: Xóa các cài đặt và trạng thái thực thi của AIRI trên máy tính.
+ center: Di chuyển cửa sổ desktop về giữa màn hình
reset: Đặt lại dữ liệu desktop
confirmations:
tooltip: Bạn chắc chứ?
@@ -450,6 +451,7 @@ pages:
modules_reset: Đã đặt lại cài đặt mô-đun.
providers_reset: Đã đặt lại cài đặt nhà cung cấp.
all_deleted: Tất cả dữ liệu cục bộ đã bị xóa.
+ desktop_window_centered: Đã di chuyển cửa sổ desktop về giữa màn hình.
desktop_reset: Đã đặt lại dữ liệu ứng dụng máy tính.
models:
description: Live2D, VRM, Spine, v.v.
diff --git a/packages/i18n/src/locales/vi/tamagotchi/stage.yaml b/packages/i18n/src/locales/vi/tamagotchi/stage.yaml
index 722c25899..555ee14cd 100644
--- a/packages/i18n/src/locales/vi/tamagotchi/stage.yaml
+++ b/packages/i18n/src/locales/vi/tamagotchi/stage.yaml
@@ -15,6 +15,7 @@ docs:
'open-settings': Mở cài đặt
'open-chat': Mở trò chuyện
'refresh': Làm mới
+ 'center-main-window': Di chuyển về giữa màn hình
'open-hearing-controls': Kiểm soát thính giác mở
'drag-to-move-window': Kéo để di chuyển cửa sổ
'switch-to-light-mode': Chuyển sang chế độ sáng
diff --git a/packages/i18n/src/locales/zh-Hans/settings.yaml b/packages/i18n/src/locales/zh-Hans/settings.yaml
index 86f6452bf..a9bbdef01 100644
--- a/packages/i18n/src/locales/zh-Hans/settings.yaml
+++ b/packages/i18n/src/locales/zh-Hans/settings.yaml
@@ -437,6 +437,7 @@ pages:
desktop:
title: 重置桌面设置和状态
description: 清除 AIRI 桌面设置和运行状态。
+ center: 将 AIRI 窗口移回屏幕中心
reset: 重置桌面数据
confirmations:
tooltip: 您确定吗?
@@ -450,6 +451,7 @@ pages:
modules_reset: 重置模块设置。
providers_reset: 服务端设置重置。
all_deleted: 已删除所有本地数据。
+ desktop_window_centered: AIRI 窗口已移回屏幕中心。
desktop_reset: 桌面数据重置。
models:
description: Live2D, VRM, Spine, etc.
diff --git a/packages/i18n/src/locales/zh-Hans/tamagotchi/stage.yaml b/packages/i18n/src/locales/zh-Hans/tamagotchi/stage.yaml
index 7dd207128..737b8ddaf 100644
--- a/packages/i18n/src/locales/zh-Hans/tamagotchi/stage.yaml
+++ b/packages/i18n/src/locales/zh-Hans/tamagotchi/stage.yaml
@@ -15,6 +15,7 @@ docs:
'open-settings': 打开设置
'open-chat': 打开聊天
'refresh': 刷新
+ 'center-main-window': 移回屏幕中心
'open-hearing-controls': 打开听力控制
'drag-to-move-window': 拖动以移动窗口
'switch-to-light-mode': 切换到亮色模式
diff --git a/packages/i18n/src/locales/zh-Hant/settings.yaml b/packages/i18n/src/locales/zh-Hant/settings.yaml
index 791402cf1..6f7699198 100644
--- a/packages/i18n/src/locales/zh-Hant/settings.yaml
+++ b/packages/i18n/src/locales/zh-Hant/settings.yaml
@@ -437,6 +437,7 @@ pages:
desktop:
title: 重設桌面設定與狀態
description: 清除 AIRI 桌面設定與執行階段狀態
+ center: 將桌寵移回螢幕中央
reset: 重設桌面資料
confirmations:
tooltip: 您確定嗎?
@@ -450,6 +451,7 @@ pages:
modules_reset: 模組設定已重設
providers_reset: 服務提供者設定已重設
all_deleted: 所有本機資料已刪除
+ desktop_window_centered: 桌寵視窗已移回螢幕中央。
desktop_reset: 桌面資料已重設
models:
description: Live2D, VRM, Spine, etc.
diff --git a/packages/i18n/src/locales/zh-Hant/tamagotchi/stage.yaml b/packages/i18n/src/locales/zh-Hant/tamagotchi/stage.yaml
index e9834359d..5f86eac87 100644
--- a/packages/i18n/src/locales/zh-Hant/tamagotchi/stage.yaml
+++ b/packages/i18n/src/locales/zh-Hant/tamagotchi/stage.yaml
@@ -15,6 +15,7 @@ docs:
'open-settings': 開啟設定
'open-chat': 打開聊天
'refresh': 重新整理
+ 'center-main-window': 移回螢幕中央
'open-hearing-controls': 開啟聽力控制
'drag-to-move-window': 長按以移動視窗
'switch-to-light-mode': 切換至亮色模式