🎨 Optimize multi-window services
This commit is contained in:
@@ -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