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 */