diff --git a/cmd/main/main.go b/cmd/main/main.go index 1f4b378..b9ecce9 100644 --- a/cmd/main/main.go +++ b/cmd/main/main.go @@ -18,11 +18,15 @@ func main() { return } - icon := ui.CreateNotifyIcon(ui.UIContext{ + uicontext := &ui.UIContext{ Logger: mgr.Logger, LogFile: mgr.logfilepath, Version: Version, - }) + } + statuslist := ui.NewStatusList() + ui.CreateStatusWindow(uicontext, statuslist) + + icon := ui.CreateNotifyIcon(uicontext) icon.Logger.Info().Str("version", Version).Msg("Starting PotatoDrive") defer icon.Close() @@ -32,9 +36,8 @@ func main() { return } - statuslist := ui.NewStatusList() icon.AddAction("Show statuses", func() { - go ui.StatusWindow(statuslist) + uicontext.MainWindow.Show() }) keys, _ := mgr.InstanceList() @@ -47,7 +50,11 @@ func main() { icon.Logger.Err(err).Msgf("%s is offline %v", keyname, err) } }, - FileStateCallback: statuslist.AddState, + FileStateCallback: func(fss core.FileSyncState) { + go uicontext.MainWindow.Synchronize(func() { + statuslist.AddState(fss) + }) + }, } err := mgr.StartInstance(keyname, context) if err != nil { diff --git a/ui/aboutdialog.go b/ui/aboutdialog.go index 8a3c4bb..d0c6f06 100644 --- a/ui/aboutdialog.go +++ b/ui/aboutdialog.go @@ -16,7 +16,7 @@ func openlink(link *walk.LinkLabelLink) { } } -func aboutDialog(_ walk.Form, context UIContext) (int, error) { +func aboutDialog(_ walk.Form, context *UIContext) (int, error) { return MainWindow{ Title: "About PotatoDrive", Icon: "#2\\0409", diff --git a/ui/notifyicon.go b/ui/notifyicon.go index 7ae9e02..251f1d1 100644 --- a/ui/notifyicon.go +++ b/ui/notifyicon.go @@ -16,10 +16,12 @@ type UIContext struct { Logger zerolog.Logger LogFile string Version string + + *walk.MainWindow } type NotifyIcon struct { - UIContext + *UIContext *walk.MainWindow zerolog.Logger @@ -66,7 +68,7 @@ func (ui *NotifyIcon) Close() { ui.ni.Dispose() } -func CreateNotifyIcon(context UIContext) *NotifyIcon { +func CreateNotifyIcon(context *UIContext) *NotifyIcon { ui := &NotifyIcon{ UIContext: context, } diff --git a/ui/statuswindow.go b/ui/statuswindow.go index 1d66195..17cdb5a 100644 --- a/ui/statuswindow.go +++ b/ui/statuswindow.go @@ -2,10 +2,12 @@ package ui import ( "log" + "syscall" "github.com/balazsgrill/potatodrive/core" "github.com/lxn/walk" . "github.com/lxn/walk/declarative" + "github.com/lxn/win" ) type StatusList struct { @@ -38,8 +40,7 @@ func (sl *StatusList) AddState(state core.FileSyncState) { sl.PublishItemsReset() } -func StatusWindow(model *StatusList) { - var mw *walk.MainWindow +func CreateStatusWindow(context *UIContext, model *StatusList) { var lb *walk.ListBox styler := &Styler{ @@ -54,12 +55,13 @@ func StatusWindow(model *StatusList) { styler.loadIcons() if err := (MainWindow{ - AssignTo: &mw, + AssignTo: &context.MainWindow, Title: "PotatoDrive status", MinSize: Size{200, 200}, Size: Size{800, 600}, Font: Font{Family: "Segoe UI", PointSize: 9}, Layout: VBox{}, + Visible: false, Children: []Widget{ Composite{ DoubleBuffering: true, @@ -77,5 +79,15 @@ func StatusWindow(model *StatusList) { }).Create(); err != nil { log.Fatal(err) } - mw.Run() + + // https://github.com/lxn/walk/issues/326#issuecomment-461074992 + var prevWndProcPtr uintptr + prevWndProcPtr = win.SetWindowLongPtr(context.MainWindow.Handle(), win.GWL_WNDPROC, + syscall.NewCallback(func(hWnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr { + if msg == win.WM_CLOSE { + win.ShowWindow(hWnd, win.SW_HIDE) + return 0 + } + return win.CallWindowProc(prevWndProcPtr, hWnd, msg, wParam, lParam) + })) }