This patch fixes a bug where if using the Wine virtual desktop, changing resolutions in a fullscreen game would cause the systray to be drawn over the game window.
Furthermore it also handles borderless fullscreen modes.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=40828 Signed-off-by: Hamish Claxton hamishclaxton@gmail.com --- v4: Rewritten - properly checks the foreground window. Also now supports fullscreen borderless modes. Fixed a spelling mistake.
programs/explorer/systray.c | 68 +++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-)
diff --git a/programs/explorer/systray.c b/programs/explorer/systray.c index 3d36f74e16..0d727a7302 100644 --- a/programs/explorer/systray.c +++ b/programs/explorer/systray.c @@ -99,7 +99,7 @@ static unsigned int alloc_displayed; static unsigned int nb_displayed; static struct icon **displayed; /* array of currently displayed icons */
-static BOOL hide_systray, enable_shell; +static BOOL systray_hidden, hide_systray, enable_shell; static int icon_cx, icon_cy, tray_width, tray_height; static int start_button_width, taskbar_button_width; static WCHAR start_label[50]; @@ -107,6 +107,9 @@ static WCHAR start_label[50]; static struct icon *balloon_icon; static HWND balloon_window;
+/* Fullscreen checking */ +static BOOL fullscreen; + #define MIN_DISPLAYED 8 #define ICON_BORDER 2
@@ -780,7 +783,13 @@ static LRESULT WINAPI tray_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
case WM_DISPLAYCHANGE: if (hide_systray || (!nb_displayed && !enable_shell)) do_hide_systray(); - else do_show_systray(); + /* Show the systray if the foreground window is not fullscreen */ + else if ( !fullscreen ) { + do_show_systray(); + systray_hidden = FALSE; + InvalidateRect( tray_window, NULL, TRUE ); /* Force a redraw of the systray */ + SendMessageW( GetDesktopWindow(), WM_PARENTNOTIFY, 0, 0 ); /* Notify desktop of update */ + } break;
case WM_TIMER: @@ -879,6 +888,60 @@ static LRESULT WINAPI tray_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l return 0; }
+/* + Check if a window is fullscreen, accounting for a maximum + difference of two pixels on width and height for borderless + fullscreen modes +*/ +static BOOL is_window_fullscreen( HWND window ) +{ + int width_delta, height_delta; + RECT window_rect, desktop_rect; + + if ( window == GetShellWindow() + || window == GetDesktopWindow() + || window == tray_window ) return FALSE; + + GetWindowRect( window, &window_rect ); + GetWindowRect( GetDesktopWindow(), &desktop_rect ); + + width_delta = window_rect.right - desktop_rect.right; + height_delta = window_rect.bottom - desktop_rect.bottom; + + return ( width_delta >= 0 + && width_delta <= 2 + && height_delta >= 0 + && height_delta <= 2 ); +} + +/* Handle systray visibility */ +void handle_systray( void ) +{ + /* Check if fullscreen and the foreground window is not fullscreen */ + if ( fullscreen && !is_window_fullscreen( GetForegroundWindow() ) ) + fullscreen = FALSE; + + /* Check if not fullscreen and the foreground window is fullscreen */ + else if ( !fullscreen && is_window_fullscreen( GetForegroundWindow() ) ) + fullscreen = TRUE; + + /* Hide the systray */ + if ( ( hide_systray || ( !nb_displayed && !enable_shell ) + || fullscreen ) && !systray_hidden ) + { + do_hide_systray(); + systray_hidden = TRUE; + } + + /* Show the systray */ + else if ( !fullscreen && systray_hidden ) + { + do_show_systray(); + systray_hidden = FALSE; + InvalidateRect( tray_window, NULL, TRUE ); /* Force a redraw of the systray */ + } +} + /* notification posted to the desktop window */ void handle_parent_notify( HWND hwnd, WPARAM wp ) { @@ -893,6 +956,7 @@ void handle_parent_notify( HWND hwnd, WPARAM wp ) break; } sync_taskbar_buttons(); + handle_systray(); }
/* this function creates the listener window */
Hi Hamish,
Can't you also use handle_systray in tray_wndproc? It seems a bit duplicate to me to have so similar logic twice.
On a sidenote, is there a free program to test against?
Regards, Fabian Maurer
Hi Fabian,
This patch has been superseded by much simpler patch: https://www.winehq.org/pipermail/wine-devel/2019-January/137311.html
The idea is that I now create some additional taskbar settings which would use my current patch as stated here: https://bugs.winehq.org/show_bug.cgi?id=46437
I recommend you test the new patch and sign it off. As for your question about any free programs to test against, well I can't think of any off the top of my head. It'd be better if you installed Steam, which is free, and then tested the patch against one of the free games on Steam.
Thanks in Advance, Hamish
On Sat, Jan 5, 2019 at 7:07 PM Fabian Maurer dark.shadow4@web.de wrote:
Hi Hamish,
Can't you also use handle_systray in tray_wndproc? It seems a bit duplicate to me to have so similar logic twice.
On a sidenote, is there a free program to test against?
Regards,
Fabian Maurer
Le mardi 08 janvier 2019 à 13:08 +1000, Hamish Claxton a écrit :
Hi Fabian,
The idea is that I now create some additional taskbar settings which would use my current patch as stated here: https://bugs.winehq.org/show_bug.cgi?id=46437 Thanks in Advance, Hamish
Hi Hamish,
You're not required to implement the settings yourself. I apologize if I made it sounds like it. I planned to do the UI, registry and hook parts myself, as separate patches.
In the end there will be a new boolean value 'taskbar_always_ontop' to check at the start of handle_systray_visibility().
Your patch will be part of the patchset and you'll get credit for it.
Of course, you're welcome to contribute to the other parts in any way you want (testing/reviewing/coding).
Regards,
Hi Olivier,
No no, I just say that sometimes, its a community effort of course.
Thanks for the credit though. I will probably end up helping out with the other parts, however probably won't for a while as Uni is starting back up.
Thanks in Advance, Hamish
On Tue, Jan 8, 2019 at 5:24 PM Olivier F. R. Dierick < o.dierick@piezo-forte.be> wrote:
Le mardi 08 janvier 2019 à 13:08 +1000, Hamish Claxton a écrit :
Hi Fabian,
The idea is that I now create some additional taskbar settings which would use my current patch as stated here: https://bugs.winehq.org/show_bug.cgi?id=46437 Thanks in Advance, Hamish
Hi Hamish,
You're not required to implement the settings yourself. I apologize if I made it sounds like it. I planned to do the UI, registry and hook parts myself, as separate patches.
In the end there will be a new boolean value 'taskbar_always_ontop' to check at the start of handle_systray_visibility().
Your patch will be part of the patchset and you'll get credit for it.
Of course, you're welcome to contribute to the other parts in any way you want (testing/reviewing/coding).
Regards,
Olivier F. R. Dierick o.dierick@piezo-forte.be