user32: Split the SetWindowPos driver backend in WindowPosChanging/Changed.

This is needed to allow updating the visible rect before invalidating
the DCEs.
This commit is contained in:
Alexandre Julliard 2008-07-02 15:40:10 +02:00
parent 0848be6a60
commit 89a3bd0c15
5 changed files with 104 additions and 66 deletions

View File

@ -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
};

View File

@ -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;

View File

@ -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;
}

View File

@ -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 );

View File

@ -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