// ============================================================================ // windowcompact.go — 拖动手柄:窗口缩小/还原 + 圆点闪烁 // // 1. 双击 Tab 栏左侧拖动手柄:在「全尺寸」与「仅手柄大小」之间切换窗口, // 供快速收拢 / 展开窗口。 // 2. API 服务可通过 POST /api/handle/flash 触发圆点闪烁(颜色 + 大小变化), // 向所有前端窗口广播 handleFlash 事件,前端据此运行动画。 // // 关键实现细节:Wails 无边框窗口仍带 WS_THICKFRAME|WS_SYSMENU| // WS_MIN/MAXIMIZEBOX 等样式位,DWM 对它们强制最小宽度(约 136px), // WM_GETMINMAXINFO 的 PtMinTrackSize 无法覆盖。因此收拢/还原的具体尺寸与 // 样式切换由平台实现 compactEnterCompact / compactExitCompact 完成 // (Windows 下临时剥离这些样式位,还原时恢复)。 // ============================================================================ package main import "sync" // 拖动手柄窗口压缩状态(用锁保护跨协程访问) var ( compactMu sync.Mutex compactActive bool // 是否处于「仅手柄」压缩状态 compactW, compactH int // 压缩前保存的窗口尺寸(还原用) ) const ( // 手柄目标尺寸:与收拢圆点同大小(32px),收拢后窗口恰好是一个圆点, // 圆点填满窗口可继续拖动、双击还原。 compactWinWidth = 32 compactWinHeight = 32 ) // ToggleWindowCompact 双击拖动手柄:在「全尺寸」与「仅手柄大小」之间切换。 // 返回切换后是否处于紧凑(仅手柄)状态;前端据此切换 UI(隐藏内容、显示居中还原圆点)。 func (s *SettingsService) ToggleWindowCompact() bool { if mainWindow == nil { return false } compactMu.Lock() defer compactMu.Unlock() if !compactActive { // 首次收拢:记录当前尺寸,缩到仅手柄大小 compactW, compactH = mainWindow.Size() compactActive = true // 收拢期间禁止拖拽边缘改变窗口大小(Wails 的 JS 与 Win32 命中测试都受此开关控制) mainWindow.SetResizable(false) compactEnterCompact(mainWindow, compactWinWidth, compactWinHeight) return true } // 还原到压缩前尺寸 compactActive = false compactExitCompact(mainWindow, compactW, compactH) mainWindow.SetResizable(true) // 还原后恢复可调整大小 return false } // HandleFlash 触发拖动手柄圆点闪烁:向所有前端窗口广播 handleFlash 事件。 // count 为闪烁次数(<=0 默认 3 次)。前端订阅后播放颜色 + 大小变化动画。 func (s *SettingsService) HandleFlash(count int) { if count <= 0 { count = 3 } app.Event.Emit("handleFlash", count) }