diff --git a/form.go b/form.go index ab2a4777..af733003 100644 --- a/form.go +++ b/form.go @@ -66,6 +66,11 @@ type Form interface { // SetFocusToWindow sets keyboard focus to the Window specified by w. SetFocusToWindow(w Window) + + // EnteringMode returns the event that is triggered if the Form is entering + // a modal loop. Use [Disposing] to for notification when the Form is leaving + // the modal loop. + EnteringMode() *Event } type FormBase struct { @@ -84,6 +89,7 @@ type FormBase struct { startingPublisher EventPublisher titleChangedPublisher EventPublisher iconChangedPublisher EventPublisher + enteringModePublisher EventPublisher progressIndicator *ProgressIndicator icon Image prevFocusHWnd win.HWND @@ -512,6 +518,10 @@ func (fb *FormBase) Starting() *Event { return fb.startingPublisher.Event() } +func (fb *FormBase) EnteringMode() *Event { + return fb.enteringModePublisher.Event() +} + func (fb *FormBase) Activating() *Event { return fb.activatingPublisher.Event() } @@ -908,6 +918,7 @@ func (fb *FormBase) WndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) u } func (fb *FormBase) EnterMode() { + fb.enteringModePublisher.Publish() } func (fb *FormBase) Running() bool { diff --git a/go.mod b/go.mod index b8b457e8..d22c25bf 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21 require ( github.com/dblohm7/wingoes v0.0.0-20231019175336-f6e33aa7cc34 - github.com/tailscale/win v0.0.0-20241018163102-cfd3289ef17f + github.com/tailscale/win v0.0.0-20250213223159-5992cb43ca35 golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 golang.org/x/sys v0.8.0 gopkg.in/Knetic/govaluate.v3 v3.0.0 diff --git a/go.sum b/go.sum index 85660609..f4f60c8a 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/dblohm7/wingoes v0.0.0-20231019175336-f6e33aa7cc34 h1:FBMro26TLQwBk+n4fbTSmSf3QUKb09pvW4fz49lxpl0= github.com/dblohm7/wingoes v0.0.0-20231019175336-f6e33aa7cc34/go.mod h1:6NCrWM5jRefaG7iN0iMShPalLsljHWBh9v1zxM2f8Xs= -github.com/tailscale/win v0.0.0-20241018163102-cfd3289ef17f h1:13CyO8FO3blZH04ewuT9DDgm9V7G0CfjDzw8kLKx+s8= -github.com/tailscale/win v0.0.0-20241018163102-cfd3289ef17f/go.mod h1:aMd4yDHLjbOuYP6fMxj1d9ACDQlSWwYztcpybGHCQc8= +github.com/tailscale/win v0.0.0-20250213223159-5992cb43ca35 h1:wAZbkTZkqDzWsqxPh2qkBd3KvFU7tcxV0BP0Rnhkxog= +github.com/tailscale/win v0.0.0-20250213223159-5992cb43ca35/go.mod h1:aMd4yDHLjbOuYP6fMxj1d9ACDQlSWwYztcpybGHCQc8= golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o= golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= diff --git a/notifyicon.go b/notifyicon.go index 9a058c67..622dc17a 100644 --- a/notifyicon.go +++ b/notifyicon.go @@ -97,10 +97,11 @@ func (ni *NotifyIcon) wndProc(hwnd win.HWND, msg uint16, wParam uintptr) { ni.mouseDownPublisher.Publish(int(win.GET_X_LPARAM(wParam)), int(win.GET_Y_LPARAM(wParam)), LeftButton) case win.WM_LBUTTONUP: - if ni.showingContextMenu { + if ni.activeContextMenus > 0 { win.PostMessage(hwnd, win.WM_CANCELMODE, 0, 0) break } + if len(ni.mouseDownPublisher.event.handlers) == 0 && len(ni.mouseUpPublisher.event.handlers) == 0 { // If there are no mouse event handlers, then treat WM_LBUTTONUP as // a "show context menu" event; this is consistent with Windows 7 @@ -126,7 +127,7 @@ func (ni *NotifyIcon) wndProc(hwnd win.HWND, msg uint16, wParam uintptr) { ni.mouseUpPublisher.Publish(int(win.GET_X_LPARAM(wParam)), int(win.GET_Y_LPARAM(wParam)), RightButton) case win.WM_CONTEXTMENU: - if ni.showingContextMenu { + if ni.activeContextMenus > 0 { win.PostMessage(hwnd, win.WM_CANCELMODE, 0, 0) } else { ni.doContextMenu(hwnd, win.GET_X_LPARAM(wParam), win.GET_Y_LPARAM(wParam)) @@ -135,6 +136,12 @@ func (ni *NotifyIcon) wndProc(hwnd win.HWND, msg uint16, wParam uintptr) { case win.NIN_BALLOONUSERCLICK: ni.reEnableToolTip() ni.messageClickedPublisher.Publish() + + case win.WM_ENTERMENULOOP: + ni.activeContextMenus++ + + case win.WM_EXITMENULOOP: + ni.activeContextMenus-- } } @@ -162,13 +169,7 @@ func (ni *NotifyIcon) ShowContextMenu(x, y int) { } func (ni *NotifyIcon) doContextMenu(hwnd win.HWND, x, y int32) { - if ni.showingContextMenu { - return - } - ni.showingContextMenu = true - defer func() { ni.showingContextMenu = false }() - - if !ni.showingContextMenuPublisher.Publish() || !ni.contextMenu.Actions().HasVisible() { + if ni.activeContextMenus > 0 || !ni.showingContextMenuPublisher.Publish() || !ni.contextMenu.Actions().HasVisible() { return } @@ -487,9 +488,9 @@ type NotifyIcon struct { mouseUpPublisher MouseEventPublisher messageClickedPublisher EventPublisher showingContextMenuPublisher ProceedEventPublisher + activeContextMenus int // int because Win32 permits nested context menus disableShowContextMenu bool visible bool - showingContextMenu bool } // NewNotifyIcon creates and returns a new NotifyIcon.