windowcompact.go 2.7 KB

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