getlantern / systray

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

Windows: execute event handler on the UI thread #226

Open Lercher opened 2 years ago

Lercher commented 2 years ago

Hi all,

probably it's too long since I've seen a message pump. However, I need some advice on how to execute something like ShowWindow(...) on the UI thread. The issue is that Windows won't bring the intended window to the foreground as a reaction to a menu item click. I speculate that Windows don't activate the window, b/c it's not the UI thread (it's some plain go routine) that calls ShowWindow().

I took a look at the implementation but couldn't find an API entry point to execute sth on the UI thread, i.e. the go routine running the message pump. What have I overlooked?

I guess, if such a thing is indeed needed, it could be a chan func() on systray, probably systray.Post. Its receiver could send the received closure to a 2nd chan func() and send a user message to the tray window as a signal. The window proc then receives this signal-user-message, receives the closure form the second chan and calls it. It's then executed on the UI thread and everything is fine.

A caller could use e.g. systray.Post <- func() { ShowWindow(sth, 1) } to finally execute ShowWindow(sth, 1) within the window proc.

Thank you, treasured reader Martin


To illustrate a very similar kind of threading issue, see e.g. https://weblog.west-wind.com/posts/2020/Oct/12/Window-Activation-Headaches-in-WPF where the author struggles with WPF and its threads. All hails to the mighty .Net dispatcher architecture.