🎨 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 TranslationService from "./translationservice.js";
|
||||||
import * as TrayService from "./trayservice.js";
|
import * as TrayService from "./trayservice.js";
|
||||||
import * as WindowService from "./windowservice.js";
|
import * as WindowService from "./windowservice.js";
|
||||||
|
import * as WindowSnapService from "./windowsnapservice.js";
|
||||||
export {
|
export {
|
||||||
BackupService,
|
BackupService,
|
||||||
ConfigService,
|
ConfigService,
|
||||||
@@ -37,7 +38,8 @@ export {
|
|||||||
ThemeService,
|
ThemeService,
|
||||||
TranslationService,
|
TranslationService,
|
||||||
TrayService,
|
TrayService,
|
||||||
WindowService
|
WindowService,
|
||||||
|
WindowSnapService
|
||||||
};
|
};
|
||||||
|
|
||||||
export * from "./models.js";
|
export * from "./models.js";
|
||||||
|
|||||||
@@ -5,9 +5,6 @@
|
|||||||
// @ts-ignore: Unused imports
|
// @ts-ignore: Unused imports
|
||||||
import {Create as $Create} from "@wailsio/runtime";
|
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
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore: Unused imports
|
// @ts-ignore: Unused imports
|
||||||
import * as http$0 from "../../../net/http/models.js";
|
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 窗口吸附服务
|
* WindowSnapService 窗口吸附服务
|
||||||
*/
|
*/
|
||||||
@@ -463,5 +424,3 @@ const $$createType3 = $Create.Map($Create.Any, $$createType2);
|
|||||||
const $$createType4 = OSInfo.createFrom;
|
const $$createType4 = OSInfo.createFrom;
|
||||||
const $$createType5 = $Create.Nullable($$createType4);
|
const $$createType5 = $Create.Nullable($$createType4);
|
||||||
const $$createType6 = $Create.Map($Create.Any, $Create.Any);
|
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
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WindowService 窗口管理服务(专注于窗口生命周期管理)
|
* WindowService 窗口管理服务
|
||||||
* @module
|
* @module
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -10,17 +10,33 @@
|
|||||||
// @ts-ignore: Unused imports
|
// @ts-ignore: Unused imports
|
||||||
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
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
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore: Unused imports
|
// @ts-ignore: Unused imports
|
||||||
import * as $models from "./models.js";
|
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 $resultPromise = $Call.ByID(1464997251) as any;
|
||||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
return $$createType1($result);
|
return $$createType0($result);
|
||||||
}) as any;
|
}) as any;
|
||||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||||
return $typingPromise;
|
return $typingPromise;
|
||||||
@@ -59,5 +75,4 @@ export function SetWindowSnapService(snapService: $models.WindowSnapService | nu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Private type creation functions
|
// Private type creation functions
|
||||||
const $$createType0 = $models.WindowInfo.createFrom;
|
const $$createType0 = $Create.Array($Create.Any);
|
||||||
const $$createType1 = $Create.Array($$createType0);
|
|
||||||
|
|||||||
@@ -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 窗口信息
|
// WindowInfo 窗口信息
|
||||||
type WindowInfo struct {
|
type WindowInfo struct {
|
||||||
DocumentID int64 `json:"documentID"` // 文档ID
|
DocumentID int64 `json:"documentID"` // 文档ID
|
||||||
Title string `json:"title"` // 窗口标题
|
|
||||||
IsSnapped bool `json:"isSnapped"` // 是否处于吸附状态
|
IsSnapped bool `json:"isSnapped"` // 是否处于吸附状态
|
||||||
SnapOffset SnapPosition `json:"snapOffset"` // 与主窗口的相对位置偏移
|
SnapOffset SnapPosition `json:"snapOffset"` // 与主窗口的相对位置偏移
|
||||||
SnapEdge SnapEdge `json:"snapEdge"` // 吸附的边缘类型
|
SnapEdge SnapEdge `json:"snapEdge"` // 吸附的边缘类型
|
||||||
|
|||||||
@@ -255,35 +255,26 @@ func (hs *HotkeyService) isWindowVisible(window *application.WebviewWindow) bool
|
|||||||
|
|
||||||
// hideAllWindows 隐藏所有窗口
|
// hideAllWindows 隐藏所有窗口
|
||||||
func (hs *HotkeyService) hideAllWindows() {
|
func (hs *HotkeyService) hideAllWindows() {
|
||||||
// 隐藏主窗口
|
|
||||||
hs.windowHelper.HideMainWindow()
|
|
||||||
|
|
||||||
// 隐藏所有子窗口
|
// 隐藏所有子窗口
|
||||||
if hs.windowService != nil {
|
if hs.windowService != nil {
|
||||||
openWindows := hs.windowService.GetOpenWindows()
|
openWindows := hs.windowService.GetOpenWindows()
|
||||||
for _, windowInfo := range openWindows {
|
for _, windowInfo := range openWindows {
|
||||||
windowInfo.Window.Hide()
|
windowInfo.Hide()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hs.logger.Debug("all windows hidden")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// showAllWindows 显示所有窗口
|
// showAllWindows 显示所有窗口
|
||||||
func (hs *HotkeyService) showAllWindows() {
|
func (hs *HotkeyService) showAllWindows() {
|
||||||
// 显示主窗口
|
|
||||||
hs.windowHelper.FocusMainWindow()
|
|
||||||
|
|
||||||
// 显示所有子窗口
|
// 显示所有子窗口
|
||||||
if hs.windowService != nil {
|
if hs.windowService != nil {
|
||||||
openWindows := hs.windowService.GetOpenWindows()
|
openWindows := hs.windowService.GetOpenWindows()
|
||||||
for _, windowInfo := range openWindows {
|
for _, windowInfo := range openWindows {
|
||||||
windowInfo.Window.Show()
|
windowInfo.Show()
|
||||||
windowInfo.Window.Restore()
|
windowInfo.Restore()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hs.logger.Debug("all windows shown")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// keyToVirtualKeyCode 键名转虚拟键码
|
// keyToVirtualKeyCode 键名转虚拟键码
|
||||||
|
|||||||
@@ -337,35 +337,26 @@ func (hs *HotkeyService) isWindowVisible(window *application.WebviewWindow) bool
|
|||||||
|
|
||||||
// hideAllWindows 隐藏所有窗口
|
// hideAllWindows 隐藏所有窗口
|
||||||
func (hs *HotkeyService) hideAllWindows() {
|
func (hs *HotkeyService) hideAllWindows() {
|
||||||
// 隐藏主窗口
|
|
||||||
hs.windowHelper.HideMainWindow()
|
|
||||||
|
|
||||||
// 隐藏所有子窗口
|
// 隐藏所有子窗口
|
||||||
if hs.windowService != nil {
|
if hs.windowService != nil {
|
||||||
openWindows := hs.windowService.GetOpenWindows()
|
openWindows := hs.windowService.GetOpenWindows()
|
||||||
for _, windowInfo := range openWindows {
|
for _, windowInfo := range openWindows {
|
||||||
windowInfo.Window.Hide()
|
windowInfo.Hide()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hs.logger.Debug("all windows hidden")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// showAllWindows 显示所有窗口
|
// showAllWindows 显示所有窗口
|
||||||
func (hs *HotkeyService) showAllWindows() {
|
func (hs *HotkeyService) showAllWindows() {
|
||||||
// 显示主窗口
|
|
||||||
hs.windowHelper.FocusMainWindow()
|
|
||||||
|
|
||||||
// 显示所有子窗口
|
// 显示所有子窗口
|
||||||
if hs.windowService != nil {
|
if hs.windowService != nil {
|
||||||
openWindows := hs.windowService.GetOpenWindows()
|
openWindows := hs.windowService.GetOpenWindows()
|
||||||
for _, windowInfo := range openWindows {
|
for _, windowInfo := range openWindows {
|
||||||
windowInfo.Window.Show()
|
windowInfo.Show()
|
||||||
windowInfo.Window.Restore()
|
windowInfo.Restore()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hs.logger.Debug("all windows shown")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServiceShutdown 关闭热键服务
|
// ServiceShutdown 关闭热键服务
|
||||||
|
|||||||
@@ -372,35 +372,26 @@ func (hs *HotkeyService) isWindowVisible(window *application.WebviewWindow) bool
|
|||||||
|
|
||||||
// hideAllWindows 隐藏所有窗口
|
// hideAllWindows 隐藏所有窗口
|
||||||
func (hs *HotkeyService) hideAllWindows() {
|
func (hs *HotkeyService) hideAllWindows() {
|
||||||
// 隐藏主窗口
|
|
||||||
hs.windowHelper.HideMainWindow()
|
|
||||||
|
|
||||||
// 隐藏所有子窗口
|
// 隐藏所有子窗口
|
||||||
if hs.windowService != nil {
|
if hs.windowService != nil {
|
||||||
openWindows := hs.windowService.GetOpenWindows()
|
openWindows := hs.windowService.GetOpenWindows()
|
||||||
for _, windowInfo := range openWindows {
|
for _, windowInfo := range openWindows {
|
||||||
windowInfo.Window.Hide()
|
windowInfo.Hide()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hs.logger.Debug("all windows hidden")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// showAllWindows 显示所有窗口
|
// showAllWindows 显示所有窗口
|
||||||
func (hs *HotkeyService) showAllWindows() {
|
func (hs *HotkeyService) showAllWindows() {
|
||||||
// 显示主窗口
|
|
||||||
hs.windowHelper.FocusMainWindow()
|
|
||||||
|
|
||||||
// 显示所有子窗口
|
// 显示所有子窗口
|
||||||
if hs.windowService != nil {
|
if hs.windowService != nil {
|
||||||
openWindows := hs.windowService.GetOpenWindows()
|
openWindows := hs.windowService.GetOpenWindows()
|
||||||
for _, windowInfo := range openWindows {
|
for _, windowInfo := range openWindows {
|
||||||
windowInfo.Window.Show()
|
windowInfo.Show()
|
||||||
windowInfo.Window.Restore()
|
windowInfo.Restore()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hs.logger.Debug("all windows shown")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// keyToX11KeyCode 键名转X11键码
|
// keyToX11KeyCode 键名转X11键码
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ func NewServiceManager() *ServiceManager {
|
|||||||
configService: configService,
|
configService: configService,
|
||||||
databaseService: databaseService,
|
databaseService: databaseService,
|
||||||
documentService: documentService,
|
documentService: documentService,
|
||||||
|
windowSnapService: windowSnapService,
|
||||||
windowService: windowService,
|
windowService: windowService,
|
||||||
migrationService: migrationService,
|
migrationService: migrationService,
|
||||||
systemService: systemService,
|
systemService: systemService,
|
||||||
@@ -189,6 +190,7 @@ func (sm *ServiceManager) GetServices() []application.Service {
|
|||||||
application.NewService(sm.testService),
|
application.NewService(sm.testService),
|
||||||
application.NewService(sm.BackupService),
|
application.NewService(sm.BackupService),
|
||||||
application.NewService(sm.httpClientService),
|
application.NewService(sm.httpClientService),
|
||||||
|
application.NewService(sm.windowSnapService),
|
||||||
}
|
}
|
||||||
return services
|
return services
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v3/pkg/application"
|
"github.com/wailsapp/wails/v3/pkg/application"
|
||||||
"voidraft/internal/common/constant"
|
"voidraft/internal/common/constant"
|
||||||
)
|
)
|
||||||
@@ -77,3 +79,45 @@ func (wh *WindowHelper) AutoShowMainWindow() {
|
|||||||
window.Show()
|
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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
|
||||||
"voidraft/internal/common/constant"
|
"voidraft/internal/common/constant"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v3/pkg/application"
|
"github.com/wailsapp/wails/v3/pkg/application"
|
||||||
@@ -11,20 +10,10 @@ import (
|
|||||||
"github.com/wailsapp/wails/v3/pkg/services/log"
|
"github.com/wailsapp/wails/v3/pkg/services/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WindowInfo 窗口信息
|
// WindowService 窗口管理服务
|
||||||
type WindowInfo struct {
|
|
||||||
Window *application.WebviewWindow
|
|
||||||
DocumentID int64
|
|
||||||
Title string
|
|
||||||
}
|
|
||||||
|
|
||||||
// WindowService 窗口管理服务(专注于窗口生命周期管理)
|
|
||||||
type WindowService struct {
|
type WindowService struct {
|
||||||
logger *log.LogService
|
logger *log.LogService
|
||||||
documentService *DocumentService
|
documentService *DocumentService
|
||||||
windows map[int64]*WindowInfo // documentID -> WindowInfo
|
|
||||||
mu sync.RWMutex
|
|
||||||
|
|
||||||
// 吸附服务引用
|
// 吸附服务引用
|
||||||
windowSnapService *WindowSnapService
|
windowSnapService *WindowSnapService
|
||||||
}
|
}
|
||||||
@@ -38,7 +27,6 @@ func NewWindowService(logger *log.LogService, documentService *DocumentService)
|
|||||||
return &WindowService{
|
return &WindowService{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
documentService: documentService,
|
documentService: documentService,
|
||||||
windows: make(map[int64]*WindowInfo),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,15 +37,14 @@ func (ws *WindowService) SetWindowSnapService(snapService *WindowSnapService) {
|
|||||||
|
|
||||||
// OpenDocumentWindow 为指定文档ID打开新窗口
|
// OpenDocumentWindow 为指定文档ID打开新窗口
|
||||||
func (ws *WindowService) OpenDocumentWindow(documentID int64) error {
|
func (ws *WindowService) OpenDocumentWindow(documentID int64) error {
|
||||||
ws.mu.Lock()
|
app := application.Get()
|
||||||
defer ws.mu.Unlock()
|
windowName := strconv.FormatInt(documentID, 10)
|
||||||
|
|
||||||
// 检查窗口是否已经存在
|
if existingWindow, exists := app.Window.GetByName(windowName); exists {
|
||||||
if windowInfo, exists := ws.windows[documentID]; exists {
|
|
||||||
// 窗口已存在,显示并聚焦
|
// 窗口已存在,显示并聚焦
|
||||||
windowInfo.Window.Show()
|
existingWindow.Show()
|
||||||
windowInfo.Window.Restore()
|
existingWindow.Restore()
|
||||||
windowInfo.Window.Focus()
|
existingWindow.Focus()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,10 +57,9 @@ func (ws *WindowService) OpenDocumentWindow(documentID int64) error {
|
|||||||
return fmt.Errorf("document not found: %d", documentID)
|
return fmt.Errorf("document not found: %d", documentID)
|
||||||
}
|
}
|
||||||
|
|
||||||
app := application.Get()
|
|
||||||
// 创建新窗口
|
// 创建新窗口
|
||||||
newWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{
|
newWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{
|
||||||
Name: strconv.FormatInt(doc.ID, 10),
|
Name: windowName,
|
||||||
Title: fmt.Sprintf("voidraft - %s", doc.Title),
|
Title: fmt.Sprintf("voidraft - %s", doc.Title),
|
||||||
Width: constant.VOIDRAFT_WINDOW_WIDTH,
|
Width: constant.VOIDRAFT_WINDOW_WIDTH,
|
||||||
Height: constant.VOIDRAFT_WINDOW_HEIGHT,
|
Height: constant.VOIDRAFT_WINDOW_HEIGHT,
|
||||||
@@ -93,26 +79,17 @@ func (ws *WindowService) OpenDocumentWindow(documentID int64) error {
|
|||||||
URL: fmt.Sprintf("/?documentId=%d", documentID),
|
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)
|
ws.registerWindowEvents(newWindow, documentID)
|
||||||
|
|
||||||
// 向吸附服务注册新窗口
|
// 向吸附服务注册新窗口
|
||||||
if ws.windowSnapService != nil {
|
if ws.windowSnapService != nil {
|
||||||
ws.windowSnapService.RegisterWindow(documentID, newWindow, doc.Title)
|
ws.windowSnapService.RegisterWindow(documentID, newWindow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 最后才移动窗口到中心
|
||||||
|
newWindow.Center()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,53 +103,50 @@ func (ws *WindowService) registerWindowEvents(window *application.WebviewWindow,
|
|||||||
|
|
||||||
// onWindowClosing 处理窗口关闭事件
|
// onWindowClosing 处理窗口关闭事件
|
||||||
func (ws *WindowService) onWindowClosing(documentID int64) {
|
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 {
|
if ws.windowSnapService != nil {
|
||||||
ws.windowSnapService.UnregisterWindow(documentID)
|
ws.windowSnapService.UnregisterWindow(documentID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetOpenWindows 获取所有打开的文档窗口
|
||||||
|
func (ws *WindowService) GetOpenWindows() []application.Window {
|
||||||
|
app := application.Get()
|
||||||
|
return app.Window.GetAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOpenWindows 获取所有打开的窗口信息
|
// GetOpenDocumentWindows 获取所有文档窗口
|
||||||
func (ws *WindowService) GetOpenWindows() []WindowInfo {
|
func (ws *WindowService) GetOpenDocumentWindows() []application.Window {
|
||||||
ws.mu.RLock()
|
app := application.Get()
|
||||||
defer ws.mu.RUnlock()
|
allWindows := app.Window.GetAll()
|
||||||
|
|
||||||
var windows []WindowInfo
|
var docWindows []application.Window
|
||||||
for _, windowInfo := range ws.windows {
|
for _, window := range allWindows {
|
||||||
windows = append(windows, *windowInfo)
|
if window.Name() != constant.VOIDRAFT_MAIN_WINDOW_NAME {
|
||||||
|
docWindows = append(docWindows, window)
|
||||||
}
|
}
|
||||||
return windows
|
}
|
||||||
|
return docWindows
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsDocumentWindowOpen 检查指定文档的窗口是否已打开
|
// IsDocumentWindowOpen 检查指定文档的窗口是否已打开
|
||||||
func (ws *WindowService) IsDocumentWindowOpen(documentID int64) bool {
|
func (ws *WindowService) IsDocumentWindowOpen(documentID int64) bool {
|
||||||
ws.mu.RLock()
|
app := application.Get()
|
||||||
defer ws.mu.RUnlock()
|
windowName := strconv.FormatInt(documentID, 10)
|
||||||
|
_, exists := app.Window.GetByName(windowName)
|
||||||
_, exists := ws.windows[documentID]
|
|
||||||
return exists
|
return exists
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServiceShutdown 实现服务关闭接口
|
// ServiceShutdown 实现服务关闭接口
|
||||||
func (ws *WindowService) ServiceShutdown() error {
|
func (ws *WindowService) ServiceShutdown() error {
|
||||||
// 关闭所有窗口
|
// 从吸附服务中取消注册所有窗口
|
||||||
ws.mu.Lock()
|
|
||||||
defer ws.mu.Unlock()
|
|
||||||
|
|
||||||
for documentID := range ws.windows {
|
|
||||||
if ws.windowSnapService != nil {
|
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)
|
ws.windowSnapService.UnregisterWindow(documentID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,16 +74,18 @@ func (wss *WindowSnapService) ServiceStartup(ctx context.Context, options applic
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RegisterWindow 注册需要吸附管理的窗口
|
// RegisterWindow 注册需要吸附管理的窗口
|
||||||
func (wss *WindowSnapService) RegisterWindow(documentID int64, window *application.WebviewWindow, title string) {
|
func (wss *WindowSnapService) RegisterWindow(documentID int64, window *application.WebviewWindow) {
|
||||||
wss.mu.Lock()
|
wss.mu.Lock()
|
||||||
defer wss.mu.Unlock()
|
defer wss.mu.Unlock()
|
||||||
|
|
||||||
|
wss.logger.Info("[WindowSnap] RegisterWindow - DocumentID: %d, SnapEnabled: %v", documentID, wss.snapEnabled)
|
||||||
|
|
||||||
// 获取初始位置
|
// 获取初始位置
|
||||||
x, y := window.Position()
|
x, y := window.Position()
|
||||||
|
wss.logger.Info("[WindowSnap] Initial position - X: %d, Y: %d", x, y)
|
||||||
|
|
||||||
windowInfo := &models.WindowInfo{
|
windowInfo := &models.WindowInfo{
|
||||||
DocumentID: documentID,
|
DocumentID: documentID,
|
||||||
Title: title,
|
|
||||||
IsSnapped: false,
|
IsSnapped: false,
|
||||||
SnapOffset: models.SnapPosition{X: 0, Y: 0},
|
SnapOffset: models.SnapPosition{X: 0, Y: 0},
|
||||||
SnapEdge: models.SnapEdgeNone,
|
SnapEdge: models.SnapEdgeNone,
|
||||||
@@ -94,6 +96,8 @@ func (wss *WindowSnapService) RegisterWindow(documentID int64, window *applicati
|
|||||||
wss.managedWindows[documentID] = windowInfo
|
wss.managedWindows[documentID] = windowInfo
|
||||||
wss.windowRefs[documentID] = window
|
wss.windowRefs[documentID] = window
|
||||||
|
|
||||||
|
wss.logger.Info("[WindowSnap] Managed windows count: %d", len(wss.managedWindows))
|
||||||
|
|
||||||
// 为窗口设置移动事件监听
|
// 为窗口设置移动事件监听
|
||||||
wss.setupWindowEvents(window, windowInfo)
|
wss.setupWindowEvents(window, windowInfo)
|
||||||
}
|
}
|
||||||
|
|||||||
1
main.go
1
main.go
@@ -91,7 +91,6 @@ func main() {
|
|||||||
})
|
})
|
||||||
mainWindow.Center()
|
mainWindow.Center()
|
||||||
window = mainWindow
|
window = mainWindow
|
||||||
|
|
||||||
trayService := serviceManager.GetTrayService()
|
trayService := serviceManager.GetTrayService()
|
||||||
// 设置系统托盘
|
// 设置系统托盘
|
||||||
systray.SetupSystemTray(mainWindow, assets, trayService)
|
systray.SetupSystemTray(mainWindow, assets, trayService)
|
||||||
|
|||||||
Reference in New Issue
Block a user