From 1f0254822f10c591f1dab806cf947ce07a339d3c Mon Sep 17 00:00:00 2001 From: landaiqing Date: Wed, 5 Nov 2025 00:10:26 +0800 Subject: [PATCH] :art: Optimize multi-window services --- .../wails/v3/pkg/application/index.ts | 4 - .../wails/v3/pkg/application/models.ts | 80 ------------- .../voidraft/internal/services/index.ts | 4 +- .../voidraft/internal/services/models.ts | 41 ------- .../internal/services/windowservice.ts | 27 ++++- .../internal/services/windowsnapservice.ts | 94 +++++++++++++++ internal/models/window.go | 1 - internal/services/hotkey_service.go | 15 +-- internal/services/hotkey_service_darwin.go | 15 +-- internal/services/hotkey_service_linux.go | 15 +-- internal/services/service_manager.go | 2 + internal/services/window_helper.go | 44 +++++++ internal/services/window_service.go | 108 +++++++----------- internal/services/window_snap_service.go | 8 +- main.go | 1 - 15 files changed, 220 insertions(+), 239 deletions(-) delete mode 100644 frontend/bindings/github.com/wailsapp/wails/v3/pkg/application/index.ts delete mode 100644 frontend/bindings/github.com/wailsapp/wails/v3/pkg/application/models.ts create mode 100644 frontend/bindings/voidraft/internal/services/windowsnapservice.ts diff --git a/frontend/bindings/github.com/wailsapp/wails/v3/pkg/application/index.ts b/frontend/bindings/github.com/wailsapp/wails/v3/pkg/application/index.ts deleted file mode 100644 index c9d993a..0000000 --- a/frontend/bindings/github.com/wailsapp/wails/v3/pkg/application/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL -// This file is automatically generated. DO NOT EDIT - -export * from "./models.js"; diff --git a/frontend/bindings/github.com/wailsapp/wails/v3/pkg/application/models.ts b/frontend/bindings/github.com/wailsapp/wails/v3/pkg/application/models.ts deleted file mode 100644 index 8ba4c74..0000000 --- a/frontend/bindings/github.com/wailsapp/wails/v3/pkg/application/models.ts +++ /dev/null @@ -1,80 +0,0 @@ -// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL -// This file is automatically generated. DO NOT EDIT - -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore: Unused imports -import {Create as $Create} from "@wailsio/runtime"; - -/** - * ServiceOptions provides optional parameters for calls to [NewService]. - */ -export class ServiceOptions { - /** - * Name can be set to override the name of the service - * for logging and debugging purposes. - * - * If empty, it will default - * either to the value obtained through the [ServiceName] interface, - * or to the type name. - */ - "Name": string; - - /** - * If the service instance implements [http.Handler], - * it will be mounted on the internal asset server - * at the prefix specified by Route. - */ - "Route": string; - - /** - * MarshalError will be called if non-nil - * to marshal to JSON the error values returned by this service's methods. - * - * MarshalError is not allowed to fail, - * but it may return a nil slice to fall back - * to the globally configured error handler. - * - * If the returned slice is not nil, it must contain valid JSON. - */ - "MarshalError": any; - - /** Creates a new ServiceOptions instance. */ - constructor($$source: Partial = {}) { - if (!("Name" in $$source)) { - this["Name"] = ""; - } - if (!("Route" in $$source)) { - this["Route"] = ""; - } - if (!("MarshalError" in $$source)) { - this["MarshalError"] = null; - } - - Object.assign(this, $$source); - } - - /** - * Creates a new ServiceOptions instance from a string or object. - */ - static createFrom($$source: any = {}): ServiceOptions { - let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source; - return new ServiceOptions($$parsedSource as Partial); - } -} - -export class WebviewWindow { - - /** Creates a new WebviewWindow instance. */ - constructor($$source: Partial = {}) { - - Object.assign(this, $$source); - } - - /** - * Creates a new WebviewWindow instance from a string or object. - */ - static createFrom($$source: any = {}): WebviewWindow { - let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source; - return new WebviewWindow($$parsedSource as Partial); - } -} diff --git a/frontend/bindings/voidraft/internal/services/index.ts b/frontend/bindings/voidraft/internal/services/index.ts index 84245b4..63c3e4b 100644 --- a/frontend/bindings/voidraft/internal/services/index.ts +++ b/frontend/bindings/voidraft/internal/services/index.ts @@ -19,6 +19,7 @@ import * as ThemeService from "./themeservice.js"; import * as TranslationService from "./translationservice.js"; import * as TrayService from "./trayservice.js"; import * as WindowService from "./windowservice.js"; +import * as WindowSnapService from "./windowsnapservice.js"; export { BackupService, ConfigService, @@ -37,7 +38,8 @@ export { ThemeService, TranslationService, TrayService, - WindowService + WindowService, + WindowSnapService }; export * from "./models.js"; diff --git a/frontend/bindings/voidraft/internal/services/models.ts b/frontend/bindings/voidraft/internal/services/models.ts index c69eaa2..391b0a2 100644 --- a/frontend/bindings/voidraft/internal/services/models.ts +++ b/frontend/bindings/voidraft/internal/services/models.ts @@ -5,9 +5,6 @@ // @ts-ignore: Unused imports import {Create as $Create} from "@wailsio/runtime"; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore: Unused imports -import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unused imports import * as http$0 from "../../../net/http/models.js"; @@ -394,42 +391,6 @@ export class SystemInfo { } } -/** - * WindowInfo 窗口信息 - */ -export class WindowInfo { - "Window": application$0.WebviewWindow | null; - "DocumentID": number; - "Title": string; - - /** Creates a new WindowInfo instance. */ - constructor($$source: Partial = {}) { - if (!("Window" in $$source)) { - this["Window"] = null; - } - if (!("DocumentID" in $$source)) { - this["DocumentID"] = 0; - } - if (!("Title" in $$source)) { - this["Title"] = ""; - } - - Object.assign(this, $$source); - } - - /** - * Creates a new WindowInfo instance from a string or object. - */ - static createFrom($$source: any = {}): WindowInfo { - const $$createField0_0 = $$createType8; - let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source; - if ("Window" in $$parsedSource) { - $$parsedSource["Window"] = $$createField0_0($$parsedSource["Window"]); - } - return new WindowInfo($$parsedSource as Partial); - } -} - /** * WindowSnapService 窗口吸附服务 */ @@ -463,5 +424,3 @@ const $$createType3 = $Create.Map($Create.Any, $$createType2); const $$createType4 = OSInfo.createFrom; const $$createType5 = $Create.Nullable($$createType4); const $$createType6 = $Create.Map($Create.Any, $Create.Any); -const $$createType7 = application$0.WebviewWindow.createFrom; -const $$createType8 = $Create.Nullable($$createType7); diff --git a/frontend/bindings/voidraft/internal/services/windowservice.ts b/frontend/bindings/voidraft/internal/services/windowservice.ts index 1bc1812..478480d 100644 --- a/frontend/bindings/voidraft/internal/services/windowservice.ts +++ b/frontend/bindings/voidraft/internal/services/windowservice.ts @@ -2,7 +2,7 @@ // This file is automatically generated. DO NOT EDIT /** - * WindowService 窗口管理服务(专注于窗口生命周期管理) + * WindowService 窗口管理服务 * @module */ @@ -10,17 +10,33 @@ // @ts-ignore: Unused imports import {Call as $Call, Create as $Create} from "@wailsio/runtime"; +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore: Unused imports +import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js"; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unused imports import * as $models from "./models.js"; /** - * GetOpenWindows 获取所有打开的窗口信息 + * GetOpenDocumentWindows 获取所有文档窗口 */ -export function GetOpenWindows(): Promise<$models.WindowInfo[]> & { cancel(): void } { +export function GetOpenDocumentWindows(): Promise & { cancel(): void } { + let $resultPromise = $Call.ByID(3057936408) as any; + let $typingPromise = $resultPromise.then(($result: any) => { + return $$createType0($result); + }) as any; + $typingPromise.cancel = $resultPromise.cancel.bind($resultPromise); + return $typingPromise; +} + +/** + * GetOpenWindows 获取所有打开的文档窗口 + */ +export function GetOpenWindows(): Promise & { cancel(): void } { let $resultPromise = $Call.ByID(1464997251) as any; let $typingPromise = $resultPromise.then(($result: any) => { - return $$createType1($result); + return $$createType0($result); }) as any; $typingPromise.cancel = $resultPromise.cancel.bind($resultPromise); return $typingPromise; @@ -59,5 +75,4 @@ export function SetWindowSnapService(snapService: $models.WindowSnapService | nu } // Private type creation functions -const $$createType0 = $models.WindowInfo.createFrom; -const $$createType1 = $Create.Array($$createType0); +const $$createType0 = $Create.Array($Create.Any); diff --git a/frontend/bindings/voidraft/internal/services/windowsnapservice.ts b/frontend/bindings/voidraft/internal/services/windowsnapservice.ts new file mode 100644 index 0000000..b0bd3d0 --- /dev/null +++ b/frontend/bindings/voidraft/internal/services/windowsnapservice.ts @@ -0,0 +1,94 @@ +// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL +// This file is automatically generated. DO NOT EDIT + +/** + * WindowSnapService 窗口吸附服务 + * @module + */ + +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore: Unused imports +import {Call as $Call, Create as $Create} from "@wailsio/runtime"; + +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore: Unused imports +import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js"; + +/** + * Cleanup 清理资源 + */ +export function Cleanup(): Promise & { cancel(): void } { + let $resultPromise = $Call.ByID(2155505498) as any; + return $resultPromise; +} + +/** + * GetCurrentThreshold 获取当前自适应阈值(用于调试或显示) + */ +export function GetCurrentThreshold(): Promise & { cancel(): void } { + let $resultPromise = $Call.ByID(3176419026) as any; + return $resultPromise; +} + +/** + * GetDiagnosticInfo 获取诊断信息(用于调试) + */ +export function GetDiagnosticInfo(): Promise<{ [_: string]: any }> & { cancel(): void } { + let $resultPromise = $Call.ByID(39381769) as any; + let $typingPromise = $resultPromise.then(($result: any) => { + return $$createType0($result); + }) as any; + $typingPromise.cancel = $resultPromise.cancel.bind($resultPromise); + return $typingPromise; +} + +/** + * OnWindowSnapConfigChanged 处理窗口吸附配置变更 + */ +export function OnWindowSnapConfigChanged(enabled: boolean): Promise & { cancel(): void } { + let $resultPromise = $Call.ByID(3794787039, enabled) as any; + return $resultPromise; +} + +/** + * RegisterWindow 注册需要吸附管理的窗口 + */ +export function RegisterWindow(documentID: number, window: application$0.WebviewWindow | null): Promise & { cancel(): void } { + let $resultPromise = $Call.ByID(1000222723, documentID, window) as any; + return $resultPromise; +} + +/** + * ServiceShutdown 实现服务关闭接口 + */ +export function ServiceShutdown(): Promise & { cancel(): void } { + let $resultPromise = $Call.ByID(1172710495) as any; + return $resultPromise; +} + +/** + * ServiceStartup 服务启动时初始化 + */ +export function ServiceStartup(options: application$0.ServiceOptions): Promise & { cancel(): void } { + let $resultPromise = $Call.ByID(2456823262, options) as any; + return $resultPromise; +} + +/** + * SetSnapEnabled 设置是否启用窗口吸附 + */ +export function SetSnapEnabled(enabled: boolean): Promise & { cancel(): void } { + let $resultPromise = $Call.ByID(2280126835, enabled) as any; + return $resultPromise; +} + +/** + * UnregisterWindow 取消注册窗口 + */ +export function UnregisterWindow(documentID: number): Promise & { cancel(): void } { + let $resultPromise = $Call.ByID(2844230768, documentID) as any; + return $resultPromise; +} + +// Private type creation functions +const $$createType0 = $Create.Map($Create.Any, $Create.Any); diff --git a/internal/models/window.go b/internal/models/window.go index 95d1edf..2e3e814 100644 --- a/internal/models/window.go +++ b/internal/models/window.go @@ -32,7 +32,6 @@ type SnapPosition struct { // WindowInfo 窗口信息 type WindowInfo struct { DocumentID int64 `json:"documentID"` // 文档ID - Title string `json:"title"` // 窗口标题 IsSnapped bool `json:"isSnapped"` // 是否处于吸附状态 SnapOffset SnapPosition `json:"snapOffset"` // 与主窗口的相对位置偏移 SnapEdge SnapEdge `json:"snapEdge"` // 吸附的边缘类型 diff --git a/internal/services/hotkey_service.go b/internal/services/hotkey_service.go index 7f9e5dc..5eaca9b 100644 --- a/internal/services/hotkey_service.go +++ b/internal/services/hotkey_service.go @@ -255,35 +255,26 @@ func (hs *HotkeyService) isWindowVisible(window *application.WebviewWindow) bool // hideAllWindows 隐藏所有窗口 func (hs *HotkeyService) hideAllWindows() { - // 隐藏主窗口 - hs.windowHelper.HideMainWindow() - // 隐藏所有子窗口 if hs.windowService != nil { openWindows := hs.windowService.GetOpenWindows() for _, windowInfo := range openWindows { - windowInfo.Window.Hide() + windowInfo.Hide() } } - hs.logger.Debug("all windows hidden") } // showAllWindows 显示所有窗口 func (hs *HotkeyService) showAllWindows() { - // 显示主窗口 - hs.windowHelper.FocusMainWindow() - // 显示所有子窗口 if hs.windowService != nil { openWindows := hs.windowService.GetOpenWindows() for _, windowInfo := range openWindows { - windowInfo.Window.Show() - windowInfo.Window.Restore() + windowInfo.Show() + windowInfo.Restore() } } - - hs.logger.Debug("all windows shown") } // keyToVirtualKeyCode 键名转虚拟键码 diff --git a/internal/services/hotkey_service_darwin.go b/internal/services/hotkey_service_darwin.go index 91260b0..a0857b1 100644 --- a/internal/services/hotkey_service_darwin.go +++ b/internal/services/hotkey_service_darwin.go @@ -337,35 +337,26 @@ func (hs *HotkeyService) isWindowVisible(window *application.WebviewWindow) bool // hideAllWindows 隐藏所有窗口 func (hs *HotkeyService) hideAllWindows() { - // 隐藏主窗口 - hs.windowHelper.HideMainWindow() - // 隐藏所有子窗口 if hs.windowService != nil { openWindows := hs.windowService.GetOpenWindows() for _, windowInfo := range openWindows { - windowInfo.Window.Hide() + windowInfo.Hide() } } - hs.logger.Debug("all windows hidden") } // showAllWindows 显示所有窗口 func (hs *HotkeyService) showAllWindows() { - // 显示主窗口 - hs.windowHelper.FocusMainWindow() - // 显示所有子窗口 if hs.windowService != nil { openWindows := hs.windowService.GetOpenWindows() for _, windowInfo := range openWindows { - windowInfo.Window.Show() - windowInfo.Window.Restore() + windowInfo.Show() + windowInfo.Restore() } } - - hs.logger.Debug("all windows shown") } // ServiceShutdown 关闭热键服务 diff --git a/internal/services/hotkey_service_linux.go b/internal/services/hotkey_service_linux.go index 01ad86b..a2a1625 100644 --- a/internal/services/hotkey_service_linux.go +++ b/internal/services/hotkey_service_linux.go @@ -372,35 +372,26 @@ func (hs *HotkeyService) isWindowVisible(window *application.WebviewWindow) bool // hideAllWindows 隐藏所有窗口 func (hs *HotkeyService) hideAllWindows() { - // 隐藏主窗口 - hs.windowHelper.HideMainWindow() - // 隐藏所有子窗口 if hs.windowService != nil { openWindows := hs.windowService.GetOpenWindows() for _, windowInfo := range openWindows { - windowInfo.Window.Hide() + windowInfo.Hide() } } - hs.logger.Debug("all windows hidden") } // showAllWindows 显示所有窗口 func (hs *HotkeyService) showAllWindows() { - // 显示主窗口 - hs.windowHelper.FocusMainWindow() - // 显示所有子窗口 if hs.windowService != nil { openWindows := hs.windowService.GetOpenWindows() for _, windowInfo := range openWindows { - windowInfo.Window.Show() - windowInfo.Window.Restore() + windowInfo.Show() + windowInfo.Restore() } } - - hs.logger.Debug("all windows shown") } // keyToX11KeyCode 键名转X11键码 diff --git a/internal/services/service_manager.go b/internal/services/service_manager.go index 83241e9..299ff49 100644 --- a/internal/services/service_manager.go +++ b/internal/services/service_manager.go @@ -145,6 +145,7 @@ func NewServiceManager() *ServiceManager { configService: configService, databaseService: databaseService, documentService: documentService, + windowSnapService: windowSnapService, windowService: windowService, migrationService: migrationService, systemService: systemService, @@ -189,6 +190,7 @@ func (sm *ServiceManager) GetServices() []application.Service { application.NewService(sm.testService), application.NewService(sm.BackupService), application.NewService(sm.httpClientService), + application.NewService(sm.windowSnapService), } return services } diff --git a/internal/services/window_helper.go b/internal/services/window_helper.go index c119d90..92807c3 100644 --- a/internal/services/window_helper.go +++ b/internal/services/window_helper.go @@ -1,6 +1,8 @@ package services import ( + "strconv" + "github.com/wailsapp/wails/v3/pkg/application" "voidraft/internal/common/constant" ) @@ -77,3 +79,45 @@ func (wh *WindowHelper) AutoShowMainWindow() { window.Show() } } + +// GetDocumentWindow 根据文档ID获取窗口(利用 Wails3 的 WindowManager) +func (wh *WindowHelper) GetDocumentWindow(documentID int64) (application.Window, bool) { + app := application.Get() + windowName := strconv.FormatInt(documentID, 10) + return app.Window.GetByName(windowName) +} + +// GetAllDocumentWindows 获取所有文档窗口(排除主窗口) +func (wh *WindowHelper) GetAllDocumentWindows() []application.Window { + app := application.Get() + allWindows := app.Window.GetAll() + + var docWindows []application.Window + for _, window := range allWindows { + // 跳过主窗口 + if window.Name() != constant.VOIDRAFT_MAIN_WINDOW_NAME { + docWindows = append(docWindows, window) + } + } + return docWindows +} + +// FocusDocumentWindow 聚焦指定文档的窗口 +func (wh *WindowHelper) FocusDocumentWindow(documentID int64) bool { + if window, exists := wh.GetDocumentWindow(documentID); exists { + window.Show() + window.Restore() + window.Focus() + return true + } + return false +} + +// CloseDocumentWindow 关闭指定文档的窗口 +func (wh *WindowHelper) CloseDocumentWindow(documentID int64) bool { + if window, exists := wh.GetDocumentWindow(documentID); exists { + window.Close() + return true + } + return false +} diff --git a/internal/services/window_service.go b/internal/services/window_service.go index 5b0ab59..c3ba1b3 100644 --- a/internal/services/window_service.go +++ b/internal/services/window_service.go @@ -3,7 +3,6 @@ package services import ( "fmt" "strconv" - "sync" "voidraft/internal/common/constant" "github.com/wailsapp/wails/v3/pkg/application" @@ -11,20 +10,10 @@ import ( "github.com/wailsapp/wails/v3/pkg/services/log" ) -// WindowInfo 窗口信息 -type WindowInfo struct { - Window *application.WebviewWindow - DocumentID int64 - Title string -} - -// WindowService 窗口管理服务(专注于窗口生命周期管理) +// WindowService 窗口管理服务 type WindowService struct { logger *log.LogService documentService *DocumentService - windows map[int64]*WindowInfo // documentID -> WindowInfo - mu sync.RWMutex - // 吸附服务引用 windowSnapService *WindowSnapService } @@ -38,7 +27,6 @@ func NewWindowService(logger *log.LogService, documentService *DocumentService) return &WindowService{ logger: logger, documentService: documentService, - windows: make(map[int64]*WindowInfo), } } @@ -49,15 +37,14 @@ func (ws *WindowService) SetWindowSnapService(snapService *WindowSnapService) { // OpenDocumentWindow 为指定文档ID打开新窗口 func (ws *WindowService) OpenDocumentWindow(documentID int64) error { - ws.mu.Lock() - defer ws.mu.Unlock() + app := application.Get() + windowName := strconv.FormatInt(documentID, 10) - // 检查窗口是否已经存在 - if windowInfo, exists := ws.windows[documentID]; exists { + if existingWindow, exists := app.Window.GetByName(windowName); exists { // 窗口已存在,显示并聚焦 - windowInfo.Window.Show() - windowInfo.Window.Restore() - windowInfo.Window.Focus() + existingWindow.Show() + existingWindow.Restore() + existingWindow.Focus() return nil } @@ -70,10 +57,9 @@ func (ws *WindowService) OpenDocumentWindow(documentID int64) error { return fmt.Errorf("document not found: %d", documentID) } - app := application.Get() // 创建新窗口 newWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{ - Name: strconv.FormatInt(doc.ID, 10), + Name: windowName, Title: fmt.Sprintf("voidraft - %s", doc.Title), Width: constant.VOIDRAFT_WINDOW_WIDTH, Height: constant.VOIDRAFT_WINDOW_HEIGHT, @@ -93,26 +79,17 @@ func (ws *WindowService) OpenDocumentWindow(documentID int64) error { URL: fmt.Sprintf("/?documentId=%d", documentID), }) - newWindow.Center() - - app.Window.Add(newWindow) - - // 保存窗口信息 - windowInfo := &WindowInfo{ - Window: newWindow, - DocumentID: documentID, - Title: doc.Title, - } - ws.windows[documentID] = windowInfo - // 注册窗口事件 ws.registerWindowEvents(newWindow, documentID) // 向吸附服务注册新窗口 if ws.windowSnapService != nil { - ws.windowSnapService.RegisterWindow(documentID, newWindow, doc.Title) + ws.windowSnapService.RegisterWindow(documentID, newWindow) } + // 最后才移动窗口到中心 + newWindow.Center() + return nil } @@ -126,53 +103,50 @@ func (ws *WindowService) registerWindowEvents(window *application.WebviewWindow, // onWindowClosing 处理窗口关闭事件 func (ws *WindowService) onWindowClosing(documentID int64) { - ws.mu.Lock() - defer ws.mu.Unlock() - - windowInfo, exists := ws.windows[documentID] - if exists { - windowInfo.Window.Close() - delete(ws.windows, documentID) - - // 从吸附服务中取消注册 - if ws.windowSnapService != nil { - ws.windowSnapService.UnregisterWindow(documentID) - } + // 从吸附服务中取消注册 + if ws.windowSnapService != nil { + ws.windowSnapService.UnregisterWindow(documentID) } } -// GetOpenWindows 获取所有打开的窗口信息 -func (ws *WindowService) GetOpenWindows() []WindowInfo { - ws.mu.RLock() - defer ws.mu.RUnlock() +// GetOpenWindows 获取所有打开的文档窗口 +func (ws *WindowService) GetOpenWindows() []application.Window { + app := application.Get() + return app.Window.GetAll() +} - var windows []WindowInfo - for _, windowInfo := range ws.windows { - windows = append(windows, *windowInfo) +// GetOpenDocumentWindows 获取所有文档窗口 +func (ws *WindowService) GetOpenDocumentWindows() []application.Window { + app := application.Get() + allWindows := app.Window.GetAll() + + var docWindows []application.Window + for _, window := range allWindows { + if window.Name() != constant.VOIDRAFT_MAIN_WINDOW_NAME { + docWindows = append(docWindows, window) + } } - return windows + return docWindows } // IsDocumentWindowOpen 检查指定文档的窗口是否已打开 func (ws *WindowService) IsDocumentWindowOpen(documentID int64) bool { - ws.mu.RLock() - defer ws.mu.RUnlock() - - _, exists := ws.windows[documentID] + app := application.Get() + windowName := strconv.FormatInt(documentID, 10) + _, exists := app.Window.GetByName(windowName) return exists } // ServiceShutdown 实现服务关闭接口 func (ws *WindowService) ServiceShutdown() error { - // 关闭所有窗口 - ws.mu.Lock() - defer ws.mu.Unlock() - - for documentID := range ws.windows { - if ws.windowSnapService != nil { - ws.windowSnapService.UnregisterWindow(documentID) + // 从吸附服务中取消注册所有窗口 + if ws.windowSnapService != nil { + windows := ws.GetOpenDocumentWindows() + for _, window := range windows { + if documentID, err := strconv.ParseInt(window.Name(), 10, 64); err == nil { + ws.windowSnapService.UnregisterWindow(documentID) + } } } - return nil } diff --git a/internal/services/window_snap_service.go b/internal/services/window_snap_service.go index 0308a87..a1f6276 100644 --- a/internal/services/window_snap_service.go +++ b/internal/services/window_snap_service.go @@ -74,16 +74,18 @@ func (wss *WindowSnapService) ServiceStartup(ctx context.Context, options applic } // RegisterWindow 注册需要吸附管理的窗口 -func (wss *WindowSnapService) RegisterWindow(documentID int64, window *application.WebviewWindow, title string) { +func (wss *WindowSnapService) RegisterWindow(documentID int64, window *application.WebviewWindow) { wss.mu.Lock() defer wss.mu.Unlock() + wss.logger.Info("[WindowSnap] RegisterWindow - DocumentID: %d, SnapEnabled: %v", documentID, wss.snapEnabled) + // 获取初始位置 x, y := window.Position() + wss.logger.Info("[WindowSnap] Initial position - X: %d, Y: %d", x, y) windowInfo := &models.WindowInfo{ DocumentID: documentID, - Title: title, IsSnapped: false, SnapOffset: models.SnapPosition{X: 0, Y: 0}, SnapEdge: models.SnapEdgeNone, @@ -94,6 +96,8 @@ func (wss *WindowSnapService) RegisterWindow(documentID int64, window *applicati wss.managedWindows[documentID] = windowInfo wss.windowRefs[documentID] = window + wss.logger.Info("[WindowSnap] Managed windows count: %d", len(wss.managedWindows)) + // 为窗口设置移动事件监听 wss.setupWindowEvents(window, windowInfo) } diff --git a/main.go b/main.go index b391ed6..e406930 100644 --- a/main.go +++ b/main.go @@ -91,7 +91,6 @@ func main() { }) mainWindow.Center() window = mainWindow - trayService := serviceManager.GetTrayService() // 设置系统托盘 systray.SetupSystemTray(mainWindow, assets, trayService)