From 89a3bd0c1514eb59c537d0f0fa318395c33156cf Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 2 Jul 2008 15:40:10 +0200 Subject: [PATCH] user32: Split the SetWindowPos driver backend in WindowPosChanging/Changed. This is needed to allow updating the visible rect before invalidating the DCEs. --- dlls/user32/driver.c | 55 +++++++++++++++-------- dlls/user32/user_private.h | 3 +- dlls/user32/winpos.c | 36 +++++++++++---- dlls/winex11.drv/window.c | 73 +++++++++++++++---------------- dlls/winex11.drv/winex11.drv.spec | 3 +- 5 files changed, 104 insertions(+), 66 deletions(-) diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c index 305e1e5a46e..7daffd9b0c0 100644 --- a/dlls/user32/driver.c +++ b/dlls/user32/driver.c @@ -115,13 +115,14 @@ static const USER_DRIVER *load_driver(void) GET_USER_FUNC(SetCapture); GET_USER_FUNC(SetFocus); GET_USER_FUNC(SetParent); - GET_USER_FUNC(SetWindowPos); GET_USER_FUNC(SetWindowRgn); GET_USER_FUNC(SetWindowIcon); GET_USER_FUNC(SetWindowStyle); GET_USER_FUNC(SetWindowText); GET_USER_FUNC(SysCommand); GET_USER_FUNC(WindowMessage); + GET_USER_FUNC(WindowPosChanging); + GET_USER_FUNC(WindowPosChanged); #undef GET_USER_FUNC } @@ -377,12 +378,6 @@ static void nulldrv_SetParent( HWND hwnd, HWND parent, HWND old_parent ) { } -static void nulldrv_SetWindowPos( HWND hwnd, HWND insert_after, UINT swp_flags, - const RECT *window_rect, const RECT *client_rect, - const RECT *visible_rect, const RECT *valid_rects ) -{ -} - static int nulldrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw ) { return 1; @@ -410,6 +405,18 @@ static LRESULT nulldrv_WindowMessage( HWND hwnd, UINT msg, WPARAM wparam, LPARAM return 0; } +static void nulldrv_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flags, + const RECT *window_rect, const RECT *client_rect, + RECT *visible_rect ) +{ +} + +static void nulldrv_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, + const RECT *window_rect, const RECT *client_rect, + const RECT *visible_rect, const RECT *valid_rects ) +{ +} + static USER_DRIVER null_driver = { /* keyboard functions */ @@ -461,13 +468,14 @@ static USER_DRIVER null_driver = nulldrv_SetCapture, nulldrv_SetFocus, nulldrv_SetParent, - nulldrv_SetWindowPos, nulldrv_SetWindowRgn, nulldrv_SetWindowIcon, nulldrv_SetWindowStyle, nulldrv_SetWindowText, nulldrv_SysCommand, - nulldrv_WindowMessage + nulldrv_WindowMessage, + nulldrv_WindowPosChanging, + nulldrv_WindowPosChanged }; @@ -698,14 +706,6 @@ static void loaderdrv_SetParent( HWND hwnd, HWND parent, HWND old_parent ) load_driver()->pSetParent( hwnd, parent, old_parent ); } -static void loaderdrv_SetWindowPos( HWND hwnd, HWND insert_after, UINT swp_flags, - const RECT *window_rect, const RECT *client_rect, - const RECT *visible_rect, const RECT *valid_rects ) -{ - load_driver()->pSetWindowPos( hwnd, insert_after, swp_flags, window_rect, - client_rect, visible_rect, valid_rects ); -} - static int loaderdrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw ) { return load_driver()->pSetWindowRgn( hwnd, hrgn, redraw ); @@ -736,6 +736,22 @@ static LRESULT loaderdrv_WindowMessage( HWND hwnd, UINT msg, WPARAM wparam, LPAR return load_driver()->pWindowMessage( hwnd, msg, wparam, lparam ); } +static void loaderdrv_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flags, + const RECT *window_rect, const RECT *client_rect, + RECT *visible_rect ) +{ + load_driver()->pWindowPosChanging( hwnd, insert_after, swp_flags, + window_rect, client_rect, visible_rect ); +} + +static void loaderdrv_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, + const RECT *window_rect, const RECT *client_rect, + const RECT *visible_rect, const RECT *valid_rects ) +{ + load_driver()->pWindowPosChanged( hwnd, insert_after, swp_flags, window_rect, + client_rect, visible_rect, valid_rects ); +} + static USER_DRIVER lazy_load_driver = { /* keyboard functions */ @@ -787,11 +803,12 @@ static USER_DRIVER lazy_load_driver = loaderdrv_SetCapture, loaderdrv_SetFocus, loaderdrv_SetParent, - loaderdrv_SetWindowPos, loaderdrv_SetWindowRgn, loaderdrv_SetWindowIcon, loaderdrv_SetWindowStyle, loaderdrv_SetWindowText, loaderdrv_SysCommand, - loaderdrv_WindowMessage + loaderdrv_WindowMessage, + loaderdrv_WindowPosChanging, + loaderdrv_WindowPosChanged }; diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 8bb1ef9a5f3..fc5a16dacbb 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -151,13 +151,14 @@ typedef struct tagUSER_DRIVER { void (*pSetCapture)(HWND,UINT); void (*pSetFocus)(HWND); void (*pSetParent)(HWND,HWND,HWND); - void (*pSetWindowPos)(HWND,HWND,UINT,const RECT *,const RECT *,const RECT *,const RECT *); int (*pSetWindowRgn)(HWND,HRGN,BOOL); void (*pSetWindowIcon)(HWND,UINT,HICON); void (*pSetWindowStyle)(HWND,DWORD); void (*pSetWindowText)(HWND,LPCWSTR); LRESULT (*pSysCommand)(HWND,WPARAM,LPARAM); LRESULT (*pWindowMessage)(HWND,UINT,WPARAM,LPARAM); + void (*pWindowPosChanging)(HWND,HWND,UINT,const RECT *,const RECT *,RECT *); + void (*pWindowPosChanged)(HWND,HWND,UINT,const RECT *,const RECT *,const RECT *,const RECT *); } USER_DRIVER; extern const USER_DRIVER *USER_Driver DECLSPEC_HIDDEN; diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index 7398152a7a8..0f93f60ce4b 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -1880,7 +1880,11 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, { WND *win; BOOL ret; - RECT visible_rect, old_window_rect; + RECT visible_rect, old_visible_rect, old_window_rect; + + visible_rect = *window_rect; + USER_Driver->pWindowPosChanging( hwnd, insert_after, swp_flags, + window_rect, client_rect, &visible_rect ); if (!(win = WIN_GetPtr( hwnd ))) return FALSE; if (win == WND_DESKTOP || win == WND_OTHER_PROCESS) return FALSE; @@ -1907,10 +1911,10 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, win->dwExStyle = reply->new_ex_style; win->rectWindow = *window_rect; win->rectClient = *client_rect; - visible_rect.left = reply->visible.left; - visible_rect.top = reply->visible.top; - visible_rect.right = reply->visible.right; - visible_rect.bottom = reply->visible.bottom; + old_visible_rect.left = reply->visible.left; + old_visible_rect.top = reply->visible.top; + old_visible_rect.right = reply->visible.right; + old_visible_rect.bottom = reply->visible.bottom; } } SERVER_END_REQ; @@ -1918,13 +1922,29 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, if (ret) { - /* FIXME: should update visible rect before invalidating DCE */ + if (memcmp( &visible_rect, &old_visible_rect, sizeof(RECT) )) + { + TRACE( "%p: need to update visible rect %s -> %s\n", hwnd, + wine_dbgstr_rect(&visible_rect), wine_dbgstr_rect(&old_visible_rect) ); + SERVER_START_REQ( set_window_visible_rect ) + { + req->handle = hwnd; + req->flags = swp_flags; + req->visible.left = visible_rect.left; + req->visible.top = visible_rect.top; + req->visible.right = visible_rect.right; + req->visible.bottom = visible_rect.bottom; + wine_server_call( req ); + } + SERVER_END_REQ; + } + if (((swp_flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE) || (swp_flags & (SWP_HIDEWINDOW | SWP_SHOWWINDOW | SWP_STATECHANGED))) invalidate_dce( hwnd, &old_window_rect ); - USER_Driver->pSetWindowPos( hwnd, insert_after, swp_flags, window_rect, - client_rect, &visible_rect, valid_rects ); + USER_Driver->pWindowPosChanged( hwnd, insert_after, swp_flags, window_rect, + client_rect, &visible_rect, valid_rects ); } return ret; } diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 0b416d9cdff..a45f04b004f 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1914,11 +1914,41 @@ void X11DRV_SetFocus( HWND hwnd ) /*********************************************************************** - * SetWindowPos (X11DRV.@) + * WindowPosChanging (X11DRV.@) */ -void X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, UINT swp_flags, - const RECT *rectWindow, const RECT *rectClient, - const RECT *visible_rect, const RECT *valid_rects ) +void X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flags, + const RECT *window_rect, const RECT *client_rect, RECT *visible_rect ) +{ + struct x11drv_win_data *data = X11DRV_get_win_data( hwnd ); + DWORD style = GetWindowLongW( hwnd, GWL_STYLE ); + + if (!data) + { + /* create the win data if the window is being made visible */ + if (!(style & WS_VISIBLE) && !(swp_flags & SWP_SHOWWINDOW)) return; + if (!(data = X11DRV_create_win_data( hwnd ))) return; + } + + /* check if we need to switch the window to managed */ + if (!data->managed && data->whole_window && is_window_managed( hwnd, swp_flags, window_rect )) + { + TRACE( "making win %p/%lx managed\n", hwnd, data->whole_window ); + if (data->mapped) unmap_window( thread_display(), data ); + data->managed = TRUE; + SetPropA( hwnd, managed_prop, (HANDLE)1 ); + } + + *visible_rect = *window_rect; + X11DRV_window_to_X_rect( data, visible_rect ); +} + + +/*********************************************************************** + * WindowPosChanged (X11DRV.@) + */ +void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, + const RECT *rectWindow, const RECT *rectClient, + const RECT *visible_rect, const RECT *valid_rects ) { struct x11drv_thread_data *thread_data; Display *display; @@ -1927,47 +1957,16 @@ void X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, UINT swp_flags, RECT old_whole_rect, old_client_rect; int event_type; - if (!data) - { - /* create the win data if the window is being made visible */ - if (!(new_style & WS_VISIBLE)) return; - if (!(data = X11DRV_create_win_data( hwnd ))) return; - } + if (!data) return; thread_data = x11drv_thread_data(); display = thread_data->display; - /* check if we need to switch the window to managed */ - if (!data->managed && data->whole_window && is_window_managed( hwnd, swp_flags, rectWindow )) - { - TRACE( "making win %p/%lx managed\n", hwnd, data->whole_window ); - if (data->mapped) unmap_window( display, data ); - data->managed = TRUE; - SetPropA( hwnd, managed_prop, (HANDLE)1 ); - } - old_whole_rect = data->whole_rect; old_client_rect = data->client_rect; data->window_rect = *rectWindow; - data->whole_rect = *rectWindow; + data->whole_rect = *visible_rect; data->client_rect = *rectClient; - X11DRV_window_to_X_rect( data, &data->whole_rect ); - if (memcmp( visible_rect, &data->whole_rect, sizeof(RECT) )) - { - TRACE( "%p: need to update visible rect %s -> %s\n", hwnd, - wine_dbgstr_rect(visible_rect), wine_dbgstr_rect(&data->whole_rect) ); - SERVER_START_REQ( set_window_visible_rect ) - { - req->handle = hwnd; - req->flags = swp_flags; - req->visible.left = data->whole_rect.left; - req->visible.top = data->whole_rect.top; - req->visible.right = data->whole_rect.right; - req->visible.bottom = data->whole_rect.bottom; - wine_server_call( req ); - } - SERVER_END_REQ; - } TRACE( "win %p window %s client %s style %08x flags %08x\n", hwnd, wine_dbgstr_rect(rectWindow), wine_dbgstr_rect(rectClient), new_style, swp_flags ); diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec index 6d469f8ee1f..459ea9e6bdc 100644 --- a/dlls/winex11.drv/winex11.drv.spec +++ b/dlls/winex11.drv/winex11.drv.spec @@ -108,12 +108,13 @@ @ cdecl SetFocus(long) X11DRV_SetFocus @ cdecl SetParent(long long long) X11DRV_SetParent @ cdecl SetWindowIcon(long long long) X11DRV_SetWindowIcon -@ cdecl SetWindowPos(long long long ptr ptr ptr ptr) X11DRV_SetWindowPos @ cdecl SetWindowRgn(long long long) X11DRV_SetWindowRgn @ cdecl SetWindowStyle(ptr long) X11DRV_SetWindowStyle @ cdecl SetWindowText(long wstr) X11DRV_SetWindowText @ cdecl SysCommand(long long) X11DRV_SysCommand @ cdecl WindowMessage(long long long long) X11DRV_WindowMessage +@ cdecl WindowPosChanging(long long long ptr ptr ptr) X11DRV_WindowPosChanging +@ cdecl WindowPosChanged(long long long ptr ptr ptr ptr) X11DRV_WindowPosChanged # WinTab32 @ cdecl AttachEventQueueToTablet(long) X11DRV_AttachEventQueueToTablet