🎨 Optimize multi-window services
This commit is contained in:
@@ -1,4 +0,0 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
export * from "./models.js";
|
||||
@@ -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<ServiceOptions> = {}) {
|
||||
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<ServiceOptions>);
|
||||
}
|
||||
}
|
||||
|
||||
export class WebviewWindow {
|
||||
|
||||
/** Creates a new WebviewWindow instance. */
|
||||
constructor($$source: Partial<WebviewWindow> = {}) {
|
||||
|
||||
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<WebviewWindow>);
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
@@ -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<WindowInfo> = {}) {
|
||||
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<WindowInfo>);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
@@ -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<application$0.Window[]> & { 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<application$0.Window[]> & { 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);
|
||||
|
||||
@@ -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<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(2155505498) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* GetCurrentThreshold 获取当前自适应阈值(用于调试或显示)
|
||||
*/
|
||||
export function GetCurrentThreshold(): Promise<number> & { 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<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(3794787039, enabled) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* RegisterWindow 注册需要吸附管理的窗口
|
||||
*/
|
||||
export function RegisterWindow(documentID: number, window: application$0.WebviewWindow | null): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(1000222723, documentID, window) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* ServiceShutdown 实现服务关闭接口
|
||||
*/
|
||||
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(1172710495) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* ServiceStartup 服务启动时初始化
|
||||
*/
|
||||
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(2456823262, options) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* SetSnapEnabled 设置是否启用窗口吸附
|
||||
*/
|
||||
export function SetSnapEnabled(enabled: boolean): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(2280126835, enabled) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* UnregisterWindow 取消注册窗口
|
||||
*/
|
||||
export function UnregisterWindow(documentID: number): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(2844230768, documentID) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
// Private type creation functions
|
||||
const $$createType0 = $Create.Map($Create.Any, $Create.Any);
|
||||
@@ -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"` // 吸附的边缘类型
|
||||
|
||||
@@ -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 键名转虚拟键码
|
||||
|
||||
@@ -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 关闭热键服务
|
||||
|
||||
@@ -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键码
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user