https://bugs.winehq.org/show_bug.cgi?id=40828
--- Comment #14 from Olivier F. R. Dierick o.dierick@piezo-forte.be --- Created attachment 63192 --> https://bugs.winehq.org/attachment.cgi?id=63192 other way to fix issue
Hold on.
Hamish Claxton's efforts at fixing the issue awakened my interest into it. I reviewed his patches and thought that there was room for improvements. So I dug into the code base and ended with another approach:
The visibility of the taskbar is handled by do_hide_systray() and do_show_systray(). Those functions are called at certain events. do_show_systray() calls SetWindowPos() with HWND_TOPMOST and without SWP_NOZORDER. That causes the taskbar to be pushed on top of the window stack when do_show_systray() is called. Since WM_DISPLAYCHANGE calls do_show_systray() the taskbar comes to the foreground when the resolution changes.
Now for the fix: At first I thought about putting a condition when there is a fullscreen window in the foreground, as Hamish Claxton wanted to do, but I remembered that wine already hides the taskbar when a fullscreen window is open (the issue happens only when resolution changes). So I looked at how this was achieved. It actually amounts to a simple matter of Z order: When the taskbar is created do_show_systray() is called and the taskbar is pushed to the top of the window stack. This happens at the start of the virutal desktop, so there is no other window at that time. When the app creates its window, it's put to the top of the windows stack, so above the taskbar. When it is a fullscreen window, the taskbar is hidden (in fact, any window will cover the taskbar, just move or maximize a window over the taskbar and you'll see). So far so well. Then, when the resolution changes, WM_DISPLAYCHANGE calls do_show_systray() and the taskbar is pushed on top again. Since the window app is already open, it is no more above the taskbar and the issue happens.
So, the fix is to NOT push the taskbar to the top of the z order in any case. There is no drawback because the taskbar has never stuck 'above all windows' anyway.
And it also fix another potential issue: When an icon is added to the systray, show_icon() calls do_show_systray(). If it happens while a fullscreen window is open, it will push the taskbar on top of it too and cause the issue.