Fullscreen exclusive windows are treated as undecorated managed windows and the window rect as the rendering area, instead of client rect.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winex11.drv/event.c | 2 +- dlls/winex11.drv/opengl.c | 28 ++++++++++++++++++++++++ dlls/winex11.drv/window.c | 45 ++++++++++++++++++++++++++++++--------- dlls/winex11.drv/x11drv.h | 1 + 4 files changed, 65 insertions(+), 11 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 07f7a1ad502..30d15b9a236 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1160,7 +1160,7 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev ) data->window_rect.bottom - data->window_rect.top, cx, cy );
style = GetWindowLongW( data->hwnd, GWL_STYLE ); - if ((style & WS_CAPTION) == WS_CAPTION) + if ((style & WS_CAPTION) == WS_CAPTION && !data->fullscreen_exclusive) { read_net_wm_states( event->display, data ); if ((data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED))) diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 7fb97f5f446..997df873b16 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -3043,6 +3043,30 @@ static BOOL X11DRV_wglSwapIntervalEXT(int interval) return ret; }
+ +/** + * X11DRV_wglSetFullscreenExclusiveWINE + * + * WGL_WINE_fullscreen_exclusive: wglSetFullscreenExclusiveWINE + */ +static BOOL X11DRV_wglSetFullscreenExclusiveWINE(HWND hwnd, int fullscreen_exclusive) +{ + struct x11drv_win_data *data; + + TRACE("(%p,%d)\n", hwnd, fullscreen_exclusive); + + if (!(data = get_win_data( hwnd ))) + { + WARN("not a proper window %p\n", hwnd); + return FALSE; + } + + data->fullscreen_exclusive = fullscreen_exclusive; + release_win_data( data ); + return TRUE; +} + + /** * X11DRV_wglSetPixelFormatWINE * @@ -3213,6 +3237,10 @@ static void X11DRV_WineGL_LoadExtensions(void)
/* WINE-specific WGL Extensions */
+ /* In WineD3D we need the ability to make a window fullscreen exclusive. */ + register_extension( "WGL_WINE_fullscreen_exclusive" ); + opengl_funcs.ext.p_wglSetFullscreenExclusiveWINE = X11DRV_wglSetFullscreenExclusiveWINE; + /* In WineD3D we need the ability to set the pixel format more than once (e.g. after a device reset). * The default wglSetPixelFormat doesn't allow this, so add our own which allows it. */ diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 723f0c6e7b0..144da39f3ab 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -227,6 +227,7 @@ static BOOL is_window_managed( struct x11drv_win_data *data, UINT swp_flags, con DWORD style, ex_style;
if (!managed_mode) return FALSE; + if (data->fullscreen_exclusive) return TRUE;
/* child windows are not managed */ style = GetWindowLongW( data->hwnd, GWL_STYLE ); @@ -272,7 +273,8 @@ static inline BOOL is_window_resizable( struct x11drv_win_data *data, DWORD styl { if (style & WS_THICKFRAME) return TRUE; /* Metacity needs the window to be resizable to make it fullscreen */ - return is_window_rect_fullscreen( &data->whole_rect ); + return is_window_rect_fullscreen( &data->whole_rect ) || + data->fullscreen_exclusive; }
@@ -285,6 +287,7 @@ static unsigned long get_mwm_decorations( struct x11drv_win_data *data, unsigned long ret = 0;
if (!decorated_mode) return 0; + if (data->fullscreen_exclusive) return 0;
if (IsRectEmpty( &data->window_rect )) return 0; if (data->shaped) return 0; @@ -944,7 +947,9 @@ void update_net_wm_states( struct x11drv_win_data *data ) style = GetWindowLongW( data->hwnd, GWL_STYLE ); if (style & WS_MINIMIZE) new_state |= data->net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED)); - if (is_window_rect_fullscreen( &data->whole_rect )) + if (data->fullscreen_exclusive) + new_state |= (1 << NET_WM_STATE_FULLSCREEN); + else if (is_window_rect_fullscreen( &data->whole_rect )) { if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION) new_state |= (1 << NET_WM_STATE_MAXIMIZED); @@ -1298,10 +1303,20 @@ static void sync_client_position( struct x11drv_win_data *data,
if (!data->client_window) return;
- changes.x = data->client_rect.left - data->whole_rect.left; - changes.y = data->client_rect.top - data->whole_rect.top; - changes.width = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 ); - changes.height = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 ); + if (data->fullscreen_exclusive) + { + changes.x = data->whole_rect.left; + changes.y = data->whole_rect.top; + changes.width = min( max( 1, data->whole_rect.right - data->whole_rect.left ), 65535 ); + changes.height = min( max( 1, data->whole_rect.bottom - data->whole_rect.top ), 65535 ); + } + else + { + changes.x = data->client_rect.left - data->whole_rect.left; + changes.y = data->client_rect.top - data->whole_rect.top; + changes.width = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 ); + changes.height = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 ); + }
if (changes.x != old_client_rect->left - old_whole_rect->left) mask |= CWX; if (changes.y != old_client_rect->top - old_whole_rect->top) mask |= CWY; @@ -1456,10 +1471,20 @@ Window create_client_window( HWND hwnd, const XVisualInfo *visual ) attr.backing_store = NotUseful; attr.border_pixel = 0;
- x = data->client_rect.left - data->whole_rect.left; - y = data->client_rect.top - data->whole_rect.top; - cx = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 ); - cy = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 ); + if (data->fullscreen_exclusive) + { + x = data->whole_rect.left; + y = data->whole_rect.top; + cx = min( max( 1, data->whole_rect.right - data->whole_rect.left ), 65535 ); + cy = min( max( 1, data->whole_rect.bottom - data->whole_rect.top ), 65535 ); + } + else + { + x = data->client_rect.left - data->whole_rect.left; + y = data->client_rect.top - data->whole_rect.top; + cx = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 ); + cy = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 ); + }
ret = data->client_window = XCreateWindow( gdi_display, data->whole_window ? data->whole_window : dummy_parent, diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 98cab8947be..baa0f7478e9 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -565,6 +565,7 @@ struct x11drv_win_data RECT whole_rect; /* X window rectangle for the whole window relative to parent */ RECT client_rect; /* client area relative to parent */ XIC xic; /* X input context */ + BOOL fullscreen_exclusive : 1; /* is window fullscreen exclusive? */ BOOL managed : 1; /* is window managed? */ BOOL mapped : 1; /* is window mapped? (in either normal or iconic state) */ BOOL iconic : 1; /* is window in iconic state? */