Apparently, this wasn't enough to fix it in all WMs. It's simpler to just use the same sequence as normal fullscreen windows and avoid headaches with virtual desktops, and Béla reported it working as well (I couldn't reproduce it, but nothing broke for me, at least).
I know the whole NtUserGetPrimaryMonitorRect thing is wrong and only works for one monitor, but that was already the case before, so I kept it the same since it won't fix a regression and we're in code freeze.
-- v3: winex11: Move the update_desktop_fullscreen callsite to update_net_wm_states.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
It's simpler to just use the same sequence as normal fullscreen windows and avoid headaches with virtual desktops.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56149 Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/winex11.drv/desktop.c | 48 ++++---------------------------------- dlls/winex11.drv/window.c | 35 ++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 45 deletions(-)
diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c index 5867f9d16a4..739514f2e76 100644 --- a/dlls/winex11.drv/desktop.c +++ b/dlls/winex11.drv/desktop.c @@ -99,39 +99,6 @@ BOOL is_desktop_fullscreen(void) primary_rect.bottom - primary_rect.top == host_primary_rect.bottom - host_primary_rect.top); }
-static void update_desktop_fullscreen( unsigned int width, unsigned int height) -{ - Display *display = thread_display(); - XEvent xev; - - if (!display || !is_virtual_desktop()) return; - - xev.xclient.type = ClientMessage; - xev.xclient.window = root_window; - xev.xclient.message_type = x11drv_atom(_NET_WM_STATE); - xev.xclient.serial = 0; - xev.xclient.display = display; - xev.xclient.send_event = True; - xev.xclient.format = 32; - if (width == host_primary_rect.right - host_primary_rect.left && height == host_primary_rect.bottom - host_primary_rect.top) - xev.xclient.data.l[0] = _NET_WM_STATE_ADD; - else - xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE; - xev.xclient.data.l[1] = x11drv_atom(_NET_WM_STATE_FULLSCREEN); - xev.xclient.data.l[2] = 0; - xev.xclient.data.l[3] = 1; - - TRACE("action=%li\n", xev.xclient.data.l[0]); - - XSendEvent( display, DefaultRootWindow(display), False, - SubstructureRedirectMask | SubstructureNotifyMask, &xev ); - - xev.xclient.data.l[1] = x11drv_atom(_NET_WM_STATE_MAXIMIZED_VERT); - xev.xclient.data.l[2] = x11drv_atom(_NET_WM_STATE_MAXIMIZED_HORZ); - XSendEvent( display, DefaultRootWindow(display), False, - SubstructureRedirectMask | SubstructureNotifyMask, &xev ); -} - /*********************************************************************** * X11DRV_resize_desktop */ @@ -139,20 +106,13 @@ void X11DRV_resize_desktop(void) { static RECT old_virtual_rect;
- RECT primary_rect, virtual_rect; + RECT virtual_rect = NtUserGetVirtualScreenRect(); HWND hwnd = NtUserGetDesktopWindow(); - INT width, height; - - virtual_rect = NtUserGetVirtualScreenRect(); - primary_rect = NtUserGetPrimaryMonitorRect(); - width = primary_rect.right; - height = primary_rect.bottom; + LONG width = virtual_rect.right - virtual_rect.left, height = virtual_rect.bottom - virtual_rect.top;
- TRACE( "desktop %p change to (%dx%d)\n", hwnd, width, height ); - NtUserSetWindowPos( hwnd, 0, virtual_rect.left, virtual_rect.top, - virtual_rect.right - virtual_rect.left, virtual_rect.bottom - virtual_rect.top, + TRACE( "desktop %p change to (%ldx%ld)\n", hwnd, width, height ); + NtUserSetWindowPos( hwnd, 0, virtual_rect.left, virtual_rect.top, width, height, SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE ); - update_desktop_fullscreen( width, height );
if (old_virtual_rect.left != virtual_rect.left || old_virtual_rect.top != virtual_rect.top) send_message_timeout( HWND_BROADCAST, WM_X11DRV_DESKTOP_RESIZED, old_virtual_rect.left, diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index f5f2dd03662..a9d6dbf1121 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -978,6 +978,35 @@ void update_user_time( Time time ) XUnlockDisplay( gdi_display ); }
+static void update_desktop_fullscreen( Display *display ) +{ + XEvent xev; + + if (!is_virtual_desktop()) return; + + xev.xclient.type = ClientMessage; + xev.xclient.window = root_window; + xev.xclient.message_type = x11drv_atom(_NET_WM_STATE); + xev.xclient.serial = 0; + xev.xclient.display = display; + xev.xclient.send_event = True; + xev.xclient.format = 32; + xev.xclient.data.l[0] = is_desktop_fullscreen() ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + xev.xclient.data.l[1] = x11drv_atom(_NET_WM_STATE_FULLSCREEN); + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 1; + + TRACE("action=%li\n", xev.xclient.data.l[0]); + + XSendEvent( display, DefaultRootWindow(display), False, + SubstructureRedirectMask | SubstructureNotifyMask, &xev ); + + xev.xclient.data.l[1] = x11drv_atom(_NET_WM_STATE_MAXIMIZED_VERT); + xev.xclient.data.l[2] = x11drv_atom(_NET_WM_STATE_MAXIMIZED_HORZ); + XSendEvent( display, DefaultRootWindow(display), False, + SubstructureRedirectMask | SubstructureNotifyMask, &xev ); +} + /* Update _NET_WM_FULLSCREEN_MONITORS when _NET_WM_STATE_FULLSCREEN is set to support fullscreen * windows spanning multiple monitors */ static void update_net_wm_fullscreen_monitors( struct x11drv_win_data *data ) @@ -1041,7 +1070,11 @@ void update_net_wm_states( struct x11drv_win_data *data ) UINT i, style, ex_style, new_state = 0;
if (!data->managed) return; - if (data->whole_window == root_window) return; + if (data->whole_window == root_window) + { + update_desktop_fullscreen(data->display); + return; + }
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); if (style & WS_MINIMIZE)
I have no idea why it gives warning on CI but not locally (and I get the opposite warning), this formatting is so confusing. I used actually typed variables now.
Rémi Bernon (@rbernon) commented about dlls/winex11.drv/desktop.c:
{ static RECT old_virtual_rect;
- RECT primary_rect, virtual_rect;
- RECT virtual_rect = NtUserGetVirtualScreenRect(); HWND hwnd = NtUserGetDesktopWindow();
- INT width, height;
- virtual_rect = NtUserGetVirtualScreenRect();
- primary_rect = NtUserGetPrimaryMonitorRect();
- width = primary_rect.right;
- height = primary_rect.bottom;
- LONG width = virtual_rect.right - virtual_rect.left, height = virtual_rect.bottom - virtual_rect.top;
```suggestion:-0+0 INT width = virtual_rect.right - virtual_rect.left, height = virtual_rect.bottom - virtual_rect.top; ```
And keep %d in the format string. In general you should avoid LONG/DWORD on the unix side because they are going to need a different format string on 32bit vs 64bit.