fyne-io / systray

a cross platfrom Go library to place an icon and menu in the notification area
Apache License 2.0
223 stars 41 forks source link

Forcefully delete the taskbar icon during quit on Windows #36

Closed EssGeeEich closed 1 year ago

EssGeeEich commented 1 year ago

Taskbar-only apps are currently hanging in the taskbar area after being closed.

This patch forcefully deletes the taskbar menu, finally removing the icon once and for all.

andydotxyz commented 1 year ago

Can you please provide steps to replicate the problem that is being fixed? I have not seen this happen before so it's hard to test the change.

EssGeeEich commented 1 year ago

This is a snippet with which I can reproduce the behavior (Win11 x64).

func main() {
    a := app.New()

    if desk, ok := a.(desktop.App); ok {
        menu := fyne.NewMenu("Example")
        desk.SetSystemTrayMenu(menu)
    }

    go func() {
        time.Sleep(2 * time.Second)
        a.Quit()
    }()

    a.Run()
}

Running this snippet, the tray icon will become "ghosted".

Even after this patch, you have to call defer systray.Quit() to see that the tray icon finally disappears. Another pull request will follow on the fyne repository, calling systray.Quit() behind the scenes, making this happen automatically.

Further tests show me that about 7 times out of 10, systrayExit() will be called twice while quitting the application after the first commit. The second commit avoids the occasional second call to systrayExit().

Edit: See also: https://github.com/fyne-io/fyne/pull/3597

andydotxyz commented 1 year ago

Looking at this PR further the new code appears to be a duplication of the code that is called after an app is asked to exit. Are you sure the correct fix is not just the Fyne PR you opened? https://github.com/fyne-io/fyne/pull/3597

To be sure you should perhaps try and replicate the problem without Fyne code (just using this systray package). It is possible that you will see it is not a problem when run alone.

EssGeeEich commented 1 year ago

I did test this condition with just the fyne PR and it seemed like that wasn't enough on its own - altough I was still using the fyne app loop.

What I saw is that without another window, no WM_DESTROY message was being received by systray's wndProc and the call to Quit wasn't enough to produce one such WM_DESTROY message.

I will update this PR with the requested changes as soon as I am able to.

EssGeeEich commented 1 year ago

I have double-checked and I can double-confirm that the issue is still happening -- at least with an external app loop. In any case, this change should be non-breaking for every other application. I have just pushed a commit, reducing code duplication.

andydotxyz commented 1 year ago

I have upgraded the Fyne repo develop branch to use this version now :)