menus.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. //go:build windows
  2. package wintray
  3. import (
  4. "fmt"
  5. "log/slog"
  6. "unsafe"
  7. "golang.org/x/sys/windows"
  8. )
  9. const (
  10. updatAvailableMenuID = 1
  11. updateMenuID = updatAvailableMenuID + 1
  12. separatorMenuID = updateMenuID + 1
  13. diagLogsMenuID = separatorMenuID + 1
  14. diagSeparatorMenuID = diagLogsMenuID + 1
  15. quitMenuID = diagSeparatorMenuID + 1
  16. )
  17. func (t *winTray) initMenus() error {
  18. if err := t.addOrUpdateMenuItem(diagLogsMenuID, 0, diagLogsMenuTitle, false); err != nil {
  19. return fmt.Errorf("unable to create menu entries %w\n", err)
  20. }
  21. if err := t.addSeparatorMenuItem(diagSeparatorMenuID, 0); err != nil {
  22. return fmt.Errorf("unable to create menu entries %w", err)
  23. }
  24. if err := t.addOrUpdateMenuItem(quitMenuID, 0, quitMenuTitle, false); err != nil {
  25. return fmt.Errorf("unable to create menu entries %w\n", err)
  26. }
  27. return nil
  28. }
  29. func (t *winTray) UpdateAvailable(ver string) error {
  30. if !t.updateNotified {
  31. slog.Debug("updating menu and sending notification for new update")
  32. if err := t.addOrUpdateMenuItem(updatAvailableMenuID, 0, updateAvailableMenuTitle, true); err != nil {
  33. return fmt.Errorf("unable to create menu entries %w", err)
  34. }
  35. if err := t.addOrUpdateMenuItem(updateMenuID, 0, updateMenutTitle, false); err != nil {
  36. return fmt.Errorf("unable to create menu entries %w", err)
  37. }
  38. if err := t.addSeparatorMenuItem(separatorMenuID, 0); err != nil {
  39. return fmt.Errorf("unable to create menu entries %w", err)
  40. }
  41. iconFilePath, err := iconBytesToFilePath(wt.updateIcon)
  42. if err != nil {
  43. return fmt.Errorf("unable to write icon data to temp file: %w", err)
  44. }
  45. if err := wt.setIcon(iconFilePath); err != nil {
  46. return fmt.Errorf("unable to set icon: %w", err)
  47. }
  48. t.updateNotified = true
  49. t.pendingUpdate = true
  50. // Now pop up the notification
  51. t.muNID.Lock()
  52. defer t.muNID.Unlock()
  53. copy(t.nid.InfoTitle[:], windows.StringToUTF16(updateTitle))
  54. copy(t.nid.Info[:], windows.StringToUTF16(fmt.Sprintf(updateMessage, ver)))
  55. t.nid.Flags |= NIF_INFO
  56. t.nid.Timeout = 10
  57. t.nid.Size = uint32(unsafe.Sizeof(*wt.nid))
  58. err = t.nid.modify()
  59. if err != nil {
  60. return err
  61. }
  62. }
  63. return nil
  64. }