| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- // ============================================================================
- // 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)
- }
|