Only create an X window for top-level windows, not for child windows.

Get rid of the X client window too, it's no longer needed.
This commit is contained in:
Alexandre Julliard 2005-01-31 16:34:07 +00:00
parent 2dd40110a0
commit f777d70a63
6 changed files with 186 additions and 399 deletions

View File

@ -638,7 +638,7 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface,
whichHWND = hFocusWindow; whichHWND = hFocusWindow;
} }
object->win_handle = whichHWND; object->win_handle = whichHWND;
object->win = (Window)GetPropA( whichHWND, "__wine_x11_client_window" ); object->win = (Window)GetPropA( whichHWND, "__wine_x11_whole_window" );
hDc = GetDC(whichHWND); hDc = GetDC(whichHWND);
object->display = get_display(hDc); object->display = get_display(hDc);

View File

@ -1375,7 +1375,7 @@ HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, D3DDEV
whichHWND = hFocusWindow; whichHWND = hFocusWindow;
} }
object->win_handle = whichHWND; object->win_handle = whichHWND;
object->win = (Window)GetPropA( whichHWND, "__wine_x11_client_window" ); object->win = (Window)GetPropA( whichHWND, "__wine_x11_whole_window" );
hDc = GetDC(whichHWND); hDc = GetDC(whichHWND);
object->display = get_display(hDc); object->display = get_display(hDc);
ReleaseDC(whichHWND, hDc); ReleaseDC(whichHWND, hDc);

View File

@ -68,24 +68,14 @@ static BYTE *pKeyStateTable;
* *
* get the coordinates of a mouse event * get the coordinates of a mouse event
*/ */
static void get_coords( HWND *hwnd, Window window, int x, int y, POINT *pt ) static inline void get_coords( HWND hwnd, Window window, int x, int y, POINT *pt )
{ {
struct x11drv_win_data *data = X11DRV_get_win_data( *hwnd ); struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
if (!data) return; if (!data) return;
if (window == data->whole_window) pt->x = x + data->whole_rect.left;
{ pt->y = y + data->whole_rect.top;
x -= data->client_rect.left;
y -= data->client_rect.top;
}
pt->x = x;
pt->y = y;
if (*hwnd != GetDesktopWindow())
{
ClientToScreen( *hwnd, pt );
*hwnd = GetAncestor( *hwnd, GA_ROOT );
}
} }
@ -153,9 +143,6 @@ static void update_cursor( HWND hwnd, Window win )
{ {
struct x11drv_thread_data *data = x11drv_thread_data(); struct x11drv_thread_data *data = x11drv_thread_data();
if (win == X11DRV_get_client_window( hwnd ))
win = X11DRV_get_whole_window( hwnd ); /* always set cursor on whole window */
if (data->cursor_window != win) if (data->cursor_window != win)
{ {
data->cursor_window = win; data->cursor_window = win;
@ -559,7 +546,7 @@ void X11DRV_ButtonPress( HWND hwnd, XButtonEvent *event )
if (!hwnd) return; if (!hwnd) return;
update_cursor( hwnd, event->window ); update_cursor( hwnd, event->window );
get_coords( &hwnd, event->window, event->x, event->y, &pt ); get_coords( hwnd, event->window, event->x, event->y, &pt );
switch (buttonNum) switch (buttonNum)
{ {
@ -588,7 +575,7 @@ void X11DRV_ButtonRelease( HWND hwnd, XButtonEvent *event )
if (!hwnd) return; if (!hwnd) return;
update_cursor( hwnd, event->window ); update_cursor( hwnd, event->window );
get_coords( &hwnd, event->window, event->x, event->y, &pt ); get_coords( hwnd, event->window, event->x, event->y, &pt );
update_key_state( event->state ); update_key_state( event->state );
send_mouse_event( hwnd, button_up_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE, send_mouse_event( hwnd, button_up_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE,
pt.x, pt.y, 0, event->time ); pt.x, pt.y, 0, event->time );
@ -607,7 +594,7 @@ void X11DRV_MotionNotify( HWND hwnd, XMotionEvent *event )
if (!hwnd) return; if (!hwnd) return;
update_cursor( hwnd, event->window ); update_cursor( hwnd, event->window );
get_coords( &hwnd, event->window, event->x, event->y, &pt ); get_coords( hwnd, event->window, event->x, event->y, &pt );
update_key_state( event->state ); update_key_state( event->state );
send_mouse_event( hwnd, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, send_mouse_event( hwnd, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
pt.x, pt.y, 0, event->time ); pt.x, pt.y, 0, event->time );
@ -628,7 +615,7 @@ void X11DRV_EnterNotify( HWND hwnd, XCrossingEvent *event )
/* simulate a mouse motion event */ /* simulate a mouse motion event */
update_cursor( hwnd, event->window ); update_cursor( hwnd, event->window );
get_coords( &hwnd, event->window, event->x, event->y, &pt ); get_coords( hwnd, event->window, event->x, event->y, &pt );
update_key_state( event->state ); update_key_state( event->state );
send_mouse_event( hwnd, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, send_mouse_event( hwnd, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
pt.x, pt.y, 0, event->time ); pt.x, pt.y, 0, event->time );

View File

@ -105,8 +105,8 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
}; };
static LPCSTR whole_window_atom; static LPCSTR whole_window_atom;
static LPCSTR client_window_atom;
static LPCSTR icon_window_atom; static LPCSTR icon_window_atom;
static LPCSTR client_offset_atom;
/*********************************************************************** /***********************************************************************
* is_window_managed * is_window_managed
@ -145,17 +145,6 @@ inline static BOOL is_window_managed( HWND hwnd )
} }
/***********************************************************************
* is_client_window_mapped
*
* Check if the X client window should be mapped
*/
inline static BOOL is_client_window_mapped( struct x11drv_win_data *data )
{
return !(GetWindowLongW( data->hwnd, GWL_STYLE ) & WS_MINIMIZE) && !IsRectEmpty( &data->client_rect );
}
/*********************************************************************** /***********************************************************************
* X11DRV_is_window_rect_mapped * X11DRV_is_window_rect_mapped
* *
@ -181,8 +170,7 @@ BOOL X11DRV_is_window_rect_mapped( const RECT *rect )
*/ */
static int get_window_attributes( struct x11drv_win_data *data, XSetWindowAttributes *attr ) static int get_window_attributes( struct x11drv_win_data *data, XSetWindowAttributes *attr )
{ {
BOOL is_top_level = is_window_top_level( data->hwnd ); BOOL managed = !using_wine_desktop && is_window_managed( data->hwnd );
BOOL managed = is_top_level && is_window_managed( data->hwnd );
DWORD ex_style = GetWindowLongW( data->hwnd, GWL_EXSTYLE ); DWORD ex_style = GetWindowLongW( data->hwnd, GWL_EXSTYLE );
if (managed) WIN_SetExStyle( data->hwnd, ex_style | WS_EX_MANAGED ); if (managed) WIN_SetExStyle( data->hwnd, ex_style | WS_EX_MANAGED );
@ -193,11 +181,9 @@ static int get_window_attributes( struct x11drv_win_data *data, XSetWindowAttrib
attr->save_under = ((GetClassLongW( data->hwnd, GCL_STYLE ) & CS_SAVEBITS) != 0); attr->save_under = ((GetClassLongW( data->hwnd, GCL_STYLE ) & CS_SAVEBITS) != 0);
attr->cursor = x11drv_thread_data()->cursor; attr->cursor = x11drv_thread_data()->cursor;
attr->event_mask = (ExposureMask | PointerMotionMask | attr->event_mask = (ExposureMask | PointerMotionMask |
ButtonPressMask | ButtonReleaseMask | EnterWindowMask); ButtonPressMask | ButtonReleaseMask | EnterWindowMask |
KeyPressMask | KeyReleaseMask | StructureNotifyMask |
if (is_top_level) FocusChangeMask | KeymapStateMask);
attr->event_mask |= (KeyPressMask | KeyReleaseMask | StructureNotifyMask |
FocusChangeMask | KeymapStateMask);
return (CWOverrideRedirect | CWSaveUnder | CWEventMask | CWColormap | CWCursor); return (CWOverrideRedirect | CWSaveUnder | CWEventMask | CWColormap | CWCursor);
} }
@ -285,7 +271,7 @@ static Window create_icon_window( Display *display, struct x11drv_win_data *data
/*********************************************************************** /***********************************************************************
* destroy_icon_window * destroy_icon_window
*/ */
inline static void destroy_icon_window( Display *display, struct x11drv_win_data *data ) static void destroy_icon_window( Display *display, struct x11drv_win_data *data )
{ {
if (!data->icon_window) return; if (!data->icon_window) return;
if (x11drv_thread_data()->cursor_window == data->icon_window) if (x11drv_thread_data()->cursor_window == data->icon_window)
@ -526,14 +512,12 @@ void X11DRV_set_iconic_state( HWND hwnd )
BOOL iconic = (style & WS_MINIMIZE) != 0; BOOL iconic = (style & WS_MINIMIZE) != 0;
if (!(data = X11DRV_get_win_data( hwnd ))) return; if (!(data = X11DRV_get_win_data( hwnd ))) return;
if (!data->whole_window) return;
GetWindowRect( hwnd, &rect ); GetWindowRect( hwnd, &rect );
wine_tsx11_lock(); wine_tsx11_lock();
if (iconic) XUnmapWindow( display, data->client_window );
else if (!IsRectEmpty( &data->client_rect )) XMapWindow( display, data->client_window );
if (!(wm_hints = XGetWMHints( display, data->whole_window ))) wm_hints = XAllocWMHints(); if (!(wm_hints = XGetWMHints( display, data->whole_window ))) wm_hints = XAllocWMHints();
wm_hints->flags |= StateHint | IconPositionHint; wm_hints->flags |= StateHint | IconPositionHint;
wm_hints->initial_state = iconic ? IconicState : NormalState; wm_hints->initial_state = iconic ? IconicState : NormalState;
@ -603,69 +587,50 @@ void X11DRV_X_to_window_rect( HWND hwnd, RECT *rect )
/*********************************************************************** /***********************************************************************
* X11DRV_sync_whole_window_position * X11DRV_sync_window_position
* *
* Synchronize the X whole window position with the Windows one * Synchronize the X window position with the Windows one
*/ */
int X11DRV_sync_whole_window_position( Display *display, struct x11drv_win_data *data, int zorder ) void X11DRV_sync_window_position( Display *display, struct x11drv_win_data *data,
UINT swp_flags, const RECT *new_client_rect )
{ {
XWindowChanges changes; XWindowChanges changes;
int mask; int mask;
RECT whole_rect; RECT old_whole_rect;
whole_rect = data->window_rect; old_whole_rect = data->whole_rect;
X11DRV_window_to_X_rect( data->hwnd, &whole_rect ); data->whole_rect = data->window_rect;
mask = get_window_changes( &changes, &data->whole_rect, &whole_rect ); X11DRV_window_to_X_rect( data->hwnd, &data->whole_rect );
if (zorder) data->client_rect = *new_client_rect;
OffsetRect( &data->client_rect, -data->whole_rect.left, -data->whole_rect.top );
SetPropA( data->hwnd, client_offset_atom,
(HANDLE)MAKELONG( data->client_rect.left, data->client_rect.top ));
if (!data->whole_window) return;
if (swp_flags & SWP_WINE_NOHOSTMOVE) return;
mask = get_window_changes( &changes, &old_whole_rect, &data->whole_rect );
if (!(swp_flags & SWP_NOZORDER))
{ {
if (is_window_top_level( data->hwnd )) /* find window that this one must be after */
HWND prev = GetWindow( data->hwnd, GW_HWNDPREV );
while (prev && !(GetWindowLongW( prev, GWL_STYLE ) & WS_VISIBLE))
prev = GetWindow( prev, GW_HWNDPREV );
if (!prev) /* top child */
{ {
/* find window that this one must be after */ changes.stack_mode = Above;
HWND prev = GetWindow( data->hwnd, GW_HWNDPREV ); mask |= CWStackMode;
while (prev && !(GetWindowLongW( prev, GWL_STYLE ) & WS_VISIBLE))
prev = GetWindow( prev, GW_HWNDPREV );
if (!prev) /* top child */
{
changes.stack_mode = Above;
mask |= CWStackMode;
}
else
{
/* should use stack_mode Below but most window managers don't get it right */
/* so move it above the next one in Z order */
HWND next = GetWindow( data->hwnd, GW_HWNDNEXT );
while (next && !(GetWindowLongW( next, GWL_STYLE ) & WS_VISIBLE))
next = GetWindow( next, GW_HWNDNEXT );
if (next)
{
changes.stack_mode = Above;
changes.sibling = X11DRV_get_whole_window(next);
mask |= CWStackMode | CWSibling;
}
}
} }
else else
{ {
/* should use stack_mode Below but most window managers don't get it right */
/* so move it above the next one in Z order */
HWND next = GetWindow( data->hwnd, GW_HWNDNEXT ); HWND next = GetWindow( data->hwnd, GW_HWNDNEXT );
while (next && !(GetWindowLongW( next, GWL_STYLE ) & WS_VISIBLE))
if (GetAncestor( data->hwnd, GA_PARENT ) == GetDesktopWindow() && next = GetWindow( next, GW_HWNDNEXT );
root_window != DefaultRootWindow(display)) if (next)
{
/* in desktop mode we need the sibling to belong to the same process */
while (next)
{
if (X11DRV_get_win_data( next )) break;
next = GetWindow( next, GW_HWNDNEXT );
}
}
if (!next) /* bottom child */
{
changes.stack_mode = Below;
mask |= CWStackMode;
}
else
{ {
changes.stack_mode = Above; changes.stack_mode = Above;
changes.sibling = X11DRV_get_whole_window(next); changes.sibling = X11DRV_get_whole_window(next);
@ -674,75 +639,22 @@ int X11DRV_sync_whole_window_position( Display *display, struct x11drv_win_data
} }
} }
data->whole_rect = whole_rect;
if (mask) if (mask)
{ {
DWORD style = GetWindowLongW( data->hwnd, GWL_STYLE );
TRACE( "setting win %lx pos %ld,%ld,%ldx%ld after %lx changes=%x\n", TRACE( "setting win %lx pos %ld,%ld,%ldx%ld after %lx changes=%x\n",
data->whole_window, whole_rect.left, whole_rect.top, data->whole_window, data->whole_rect.left, data->whole_rect.top,
whole_rect.right - whole_rect.left, whole_rect.bottom - whole_rect.top, data->whole_rect.right - data->whole_rect.left,
changes.sibling, mask ); data->whole_rect.bottom - data->whole_rect.top, changes.sibling, mask );
wine_tsx11_lock(); wine_tsx11_lock();
XSync( gdi_display, False ); /* flush graphics operations before moving the window */ XSync( gdi_display, False ); /* flush graphics operations before moving the window */
wine_tsx11_unlock(); if (mask & (CWWidth|CWHeight)) set_size_hints( display, data, style );
XReconfigureWMWindow( display, data->whole_window,
if (is_window_top_level( data->hwnd )) DefaultScreen(display), mask, &changes );
{
DWORD style = GetWindowLongW( data->hwnd, GWL_STYLE );
wine_tsx11_lock();
if (mask & (CWWidth|CWHeight)) set_size_hints( display, data, style );
XReconfigureWMWindow( display, data->whole_window,
DefaultScreen(display), mask, &changes );
wine_tsx11_unlock();
}
else
{
wine_tsx11_lock();
XConfigureWindow( display, data->whole_window, mask, &changes );
wine_tsx11_unlock();
}
}
return mask;
}
/***********************************************************************
* X11DRV_sync_client_window_position
*
* Synchronize the X client window position with the Windows one
*/
int X11DRV_sync_client_window_position( Display *display, struct x11drv_win_data *data,
const RECT *new_client_rect )
{
XWindowChanges changes;
int mask;
RECT client_rect = *new_client_rect;
OffsetRect( &client_rect, -data->whole_rect.left, -data->whole_rect.top );
if ((mask = get_window_changes( &changes, &data->client_rect, &client_rect )))
{
BOOL is_mapped;
TRACE( "setting win %lx pos %ld,%ld,%ldx%ld (was %ld,%ld,%ldx%ld) after %lx changes=%x\n",
data->client_window, client_rect.left, client_rect.top,
client_rect.right - client_rect.left, client_rect.bottom - client_rect.top,
data->client_rect.left, data->client_rect.top,
data->client_rect.right - data->client_rect.left,
data->client_rect.bottom - data->client_rect.top,
changes.sibling, mask );
data->client_rect = client_rect;
is_mapped = is_client_window_mapped( data );
wine_tsx11_lock();
XSync( gdi_display, False ); /* flush graphics operations before moving the window */
if (!is_mapped) XUnmapWindow( display, data->client_window );
XConfigureWindow( display, data->client_window, mask, &changes );
if (is_mapped) XMapWindow( display, data->client_window );
wine_tsx11_unlock(); wine_tsx11_unlock();
} }
return mask;
} }
@ -760,14 +672,13 @@ static void create_desktop( Display *display, struct x11drv_win_data *data )
wine_tsx11_unlock(); wine_tsx11_unlock();
whole_window_atom = MAKEINTATOMA( GlobalAddAtomA( "__wine_x11_whole_window" )); whole_window_atom = MAKEINTATOMA( GlobalAddAtomA( "__wine_x11_whole_window" ));
client_window_atom = MAKEINTATOMA( GlobalAddAtomA( "__wine_x11_client_window" ));
icon_window_atom = MAKEINTATOMA( GlobalAddAtomA( "__wine_x11_icon_window" )); icon_window_atom = MAKEINTATOMA( GlobalAddAtomA( "__wine_x11_icon_window" ));
client_offset_atom = MAKEINTATOMA( GlobalAddAtomA( "__wine_x11_client_area_offset" ));
data->whole_window = data->client_window = root_window; data->whole_window = root_window;
data->whole_rect = data->client_rect = data->window_rect; data->whole_rect = data->client_rect = data->window_rect;
SetPropA( data->hwnd, whole_window_atom, (HANDLE)root_window ); SetPropA( data->hwnd, whole_window_atom, (HANDLE)root_window );
SetPropA( data->hwnd, client_window_atom, (HANDLE)root_window );
SetPropA( data->hwnd, "__wine_x11_visual_id", (HANDLE)visualid ); SetPropA( data->hwnd, "__wine_x11_visual_id", (HANDLE)visualid );
X11DRV_InitClipboard(); X11DRV_InitClipboard();
@ -785,9 +696,8 @@ static Window create_whole_window( Display *display, struct x11drv_win_data *dat
{ {
int cx, cy, mask; int cx, cy, mask;
XSetWindowAttributes attr; XSetWindowAttributes attr;
Window parent; XIM xim;
RECT rect; RECT rect;
BOOL is_top_level = is_window_top_level( data->hwnd );
rect = data->window_rect; rect = data->window_rect;
X11DRV_window_to_X_rect( data->hwnd, &rect ); X11DRV_window_to_X_rect( data->hwnd, &rect );
@ -795,8 +705,6 @@ static Window create_whole_window( Display *display, struct x11drv_win_data *dat
if (!(cx = rect.right - rect.left)) cx = 1; if (!(cx = rect.right - rect.left)) cx = 1;
if (!(cy = rect.bottom - rect.top)) cy = 1; if (!(cy = rect.bottom - rect.top)) cy = 1;
parent = X11DRV_get_client_window( GetAncestor( data->hwnd, GA_PARENT ) );
mask = get_window_attributes( data, &attr ); mask = get_window_attributes( data, &attr );
/* set the attributes that don't change over the lifetime of the window */ /* set the attributes that don't change over the lifetime of the window */
@ -808,7 +716,7 @@ static Window create_whole_window( Display *display, struct x11drv_win_data *dat
wine_tsx11_lock(); wine_tsx11_lock();
data->whole_rect = rect; data->whole_rect = rect;
data->whole_window = XCreateWindow( display, parent, rect.left, rect.top, cx, cy, data->whole_window = XCreateWindow( display, root_window, rect.left, rect.top, cx, cy,
0, screen_depth, InputOutput, visual, 0, screen_depth, InputOutput, visual,
mask, &attr ); mask, &attr );
@ -826,52 +734,45 @@ static Window create_whole_window( Display *display, struct x11drv_win_data *dat
changes.stack_mode = Below; changes.stack_mode = Below;
XConfigureWindow( display, data->whole_window, CWStackMode, &changes ); XConfigureWindow( display, data->whole_window, CWStackMode, &changes );
} }
XSync( display, False ); /* FIXME: should not be needed */
wine_tsx11_unlock(); wine_tsx11_unlock();
if (is_top_level) xim = x11drv_thread_data()->xim;
{ if (xim) data->xic = X11DRV_CreateIC( xim, display, data->whole_window );
XIM xim = x11drv_thread_data()->xim;
if (xim) data->xic = X11DRV_CreateIC( xim, display, data->whole_window );
X11DRV_set_wm_hints( display, data );
}
X11DRV_set_wm_hints( display, data );
SetPropA( data->hwnd, whole_window_atom, (HANDLE)data->whole_window );
return data->whole_window; return data->whole_window;
} }
/********************************************************************** /**********************************************************************
* create_client_window * destroy_whole_window
* *
* Create the client window for a given window * Destroy the whole X window for a given window.
*/ */
static Window create_client_window( Display *display, struct x11drv_win_data *data ) static void destroy_whole_window( Display *display, struct x11drv_win_data *data )
{ {
RECT rect = data->whole_rect; struct x11drv_thread_data *thread_data = x11drv_thread_data();
XSetWindowAttributes attr;
BOOL is_mapped;
OffsetRect( &rect, -data->whole_rect.left, -data->whole_rect.top ); if (!data->whole_window) return;
data->client_rect = rect;
is_mapped = is_client_window_mapped( data );
attr.event_mask = (ExposureMask | PointerMotionMask |
ButtonPressMask | ButtonReleaseMask | EnterWindowMask);
attr.bit_gravity = (GetClassLongW( data->hwnd, GCL_STYLE ) & (CS_VREDRAW | CS_HREDRAW)) ?
ForgetGravity : NorthWestGravity;
attr.backing_store = NotUseful/*WhenMapped*/;
TRACE( "win %p xwin %lx\n", data->hwnd, data->whole_window );
if (thread_data->cursor_window == data->whole_window) thread_data->cursor_window = None;
wine_tsx11_lock(); wine_tsx11_lock();
data->client_window = XCreateWindow( display, data->whole_window, 0, 0, XSync( gdi_display, False ); /* flush any reference to this drawable in GDI queue */
max( rect.right - rect.left, 1 ), XDeleteContext( display, data->whole_window, winContext );
max( rect.bottom - rect.top, 1 ), XDestroyWindow( display, data->whole_window ); /* this destroys client too */
0, screen_depth, data->whole_window = 0;
InputOutput, visual, if (data->xic)
CWEventMask | CWBitGravity | CWBackingStore, &attr ); {
XSaveContext( display, data->client_window, winContext, (char *)data->hwnd ); XUnsetICFocus( data->xic );
if (data->client_window && is_mapped) XMapWindow( display, data->client_window ); XDestroyIC( data->xic );
}
wine_tsx11_unlock(); wine_tsx11_unlock();
return data->client_window; RemovePropA( data->hwnd, whole_window_atom );
} }
@ -942,25 +843,10 @@ BOOL X11DRV_DestroyWindow( HWND hwnd )
if (!(data = X11DRV_get_win_data( hwnd ))) goto done; if (!(data = X11DRV_get_win_data( hwnd ))) goto done;
if (data->whole_window) destroy_whole_window( display, data );
{ destroy_icon_window( display, data );
TRACE( "win %p xwin %lx/%lx\n", hwnd, data->whole_window, data->client_window );
if (thread_data->cursor_window == data->whole_window) thread_data->cursor_window = None;
if (thread_data->last_focus == hwnd) thread_data->last_focus = 0;
wine_tsx11_lock();
XSync( gdi_display, False ); /* flush any reference to this drawable in GDI queue */
XDeleteContext( display, data->whole_window, winContext );
XDeleteContext( display, data->client_window, winContext );
XDestroyWindow( display, data->whole_window ); /* this destroys client too */
if (data->xic)
{
XUnsetICFocus( data->xic );
XDestroyIC( data->xic );
}
wine_tsx11_unlock();
destroy_icon_window( display, data );
}
if (thread_data->last_focus == hwnd) thread_data->last_focus = 0;
if (data->hWMIconBitmap) DeleteObject( data->hWMIconBitmap ); if (data->hWMIconBitmap) DeleteObject( data->hWMIconBitmap );
if (data->hWMIconMask) DeleteObject( data->hWMIconMask); if (data->hWMIconMask) DeleteObject( data->hWMIconMask);
wine_tsx11_lock(); wine_tsx11_lock();
@ -1012,7 +898,6 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
if (!(data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data)))) return FALSE; if (!(data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data)))) return FALSE;
data->hwnd = hwnd; data->hwnd = hwnd;
data->whole_window = 0; data->whole_window = 0;
data->client_window = 0;
data->icon_window = 0; data->icon_window = 0;
data->xic = 0; data->xic = 0;
data->hWMIconBitmap = 0; data->hWMIconBitmap = 0;
@ -1035,14 +920,11 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
return TRUE; return TRUE;
} }
if (!create_whole_window( display, data, cs->style )) goto failed; /* create an X window if it's a top level window */
if (!create_client_window( display, data )) goto failed; if (parent == GetDesktopWindow())
wine_tsx11_lock(); {
XSync( display, False ); if (!create_whole_window( display, data, cs->style )) goto failed;
wine_tsx11_unlock(); }
SetPropA( hwnd, whole_window_atom, (HANDLE)data->whole_window );
SetPropA( hwnd, client_window_atom, (HANDLE)data->client_window );
/* Call the WH_CBT hook */ /* Call the WH_CBT hook */
cbtc.lpcs = cs; cbtc.lpcs = cs;
@ -1082,7 +964,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
/* make sure the window is still valid */ /* make sure the window is still valid */
if (!(data = X11DRV_get_win_data( hwnd ))) return FALSE; if (!(data = X11DRV_get_win_data( hwnd ))) return FALSE;
X11DRV_sync_window_style( display, data ); if (data->whole_window) X11DRV_sync_window_style( display, data );
/* send WM_NCCALCSIZE */ /* send WM_NCCALCSIZE */
rect = data->window_rect; rect = data->window_rect;
@ -1100,7 +982,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
X11DRV_set_window_pos( hwnd, insert_after, &wndPtr->rectWindow, &rect, 0, 0 ); X11DRV_set_window_pos( hwnd, insert_after, &wndPtr->rectWindow, &rect, 0, 0 );
TRACE( "win %p window %ld,%ld,%ld,%ld client %ld,%ld,%ld,%ld whole %ld,%ld,%ld,%ld X client %ld,%ld,%ld,%ld xwin %x/%x\n", TRACE( "win %p window %ld,%ld,%ld,%ld client %ld,%ld,%ld,%ld whole %ld,%ld,%ld,%ld X client %ld,%ld,%ld,%ld xwin %x\n",
hwnd, wndPtr->rectWindow.left, wndPtr->rectWindow.top, hwnd, wndPtr->rectWindow.left, wndPtr->rectWindow.top,
wndPtr->rectWindow.right, wndPtr->rectWindow.bottom, wndPtr->rectWindow.right, wndPtr->rectWindow.bottom,
wndPtr->rectClient.left, wndPtr->rectClient.top, wndPtr->rectClient.left, wndPtr->rectClient.top,
@ -1109,7 +991,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
data->whole_rect.right, data->whole_rect.bottom, data->whole_rect.right, data->whole_rect.bottom,
data->client_rect.left, data->client_rect.top, data->client_rect.left, data->client_rect.top,
data->client_rect.right, data->client_rect.bottom, data->client_rect.right, data->client_rect.bottom,
(unsigned int)data->whole_window, (unsigned int)data->client_window ); (unsigned int)data->whole_window );
WIN_ReleasePtr( wndPtr ); WIN_ReleasePtr( wndPtr );
@ -1181,16 +1063,27 @@ struct x11drv_win_data *X11DRV_get_win_data( HWND hwnd )
/*********************************************************************** /***********************************************************************
* X11DRV_get_client_window * X11DRV_get_client_area_offset
* *
* Return the X window associated with the client area of a window * Return the offset of the client area relative to the x11 window.
*/ */
Window X11DRV_get_client_window( HWND hwnd ) POINT X11DRV_get_client_area_offset( HWND hwnd )
{ {
POINT pt;
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd ); struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
if (!data) return (Window)GetPropA( hwnd, client_window_atom ); if (data)
return data->client_window; {
pt.x = data->client_rect.left;
pt.y = data->client_rect.top;
}
else
{
ULONG_PTR offset = (ULONG_PTR)GetPropA( hwnd, client_offset_atom );
pt.x = (SHORT)LOWORD(offset);
pt.y = (SHORT)HIWORD(offset);
}
return pt;
} }
@ -1240,7 +1133,6 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent )
if (parent != old_parent) if (parent != old_parent)
{ {
struct x11drv_win_data *data; struct x11drv_win_data *data;
Window new_parent = X11DRV_get_client_window( parent );
if (!(data = X11DRV_get_win_data( hwnd ))) return 0; if (!(data = X11DRV_get_win_data( hwnd ))) return 0;
@ -1253,14 +1145,18 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent )
HMENU menu = (HMENU)SetWindowLongPtrW( hwnd, GWLP_ID, 0 ); HMENU menu = (HMENU)SetWindowLongPtrW( hwnd, GWLP_ID, 0 );
if (menu) DestroyMenu( menu ); if (menu) DestroyMenu( menu );
} }
if (old_parent == GetDesktopWindow())
{
/* destroy the old X windows */
destroy_whole_window( display, data );
destroy_icon_window( display, data );
}
}
else /* new top level window */
{
/* FIXME: we ignore errors since we can't really recover anyway */
create_whole_window( display, data, GetWindowLongW( hwnd, GWL_STYLE ) );
} }
if (is_window_top_level( data->hwnd )) X11DRV_set_wm_hints( display, data );
X11DRV_sync_window_style( display, data );
wine_tsx11_lock();
XReparentWindow( display, data->whole_window, new_parent,
data->whole_rect.left, data->whole_rect.top );
wine_tsx11_unlock();
} }
/* SetParent additionally needs to make hwnd the topmost window /* SetParent additionally needs to make hwnd the topmost window
@ -1343,6 +1239,7 @@ void X11DRV_SetWindowIcon( HWND hwnd, UINT type, HICON icon )
if (type != ICON_BIG) return; /* nothing to do here */ if (type != ICON_BIG) return; /* nothing to do here */
if (!(data = X11DRV_get_win_data( hwnd ))) return; if (!(data = X11DRV_get_win_data( hwnd ))) return;
if (!data->whole_window) return;
ex_style = GetWindowLongW( hwnd, GWL_EXSTYLE ); ex_style = GetWindowLongW( hwnd, GWL_EXSTYLE );
if (ex_style & WS_EX_MANAGED) if (ex_style & WS_EX_MANAGED)

View File

@ -131,75 +131,12 @@ static HRGN get_server_visible_region( HWND hwnd, HWND top, UINT flags )
*/ */
static HWND get_top_clipping_window( HWND hwnd ) static HWND get_top_clipping_window( HWND hwnd )
{ {
HWND ret = 0; HWND ret = GetAncestor( hwnd, GA_ROOT );
if (!using_wine_desktop) ret = GetAncestor( hwnd, GA_ROOT );
if (!ret) ret = GetDesktopWindow(); if (!ret) ret = GetDesktopWindow();
return ret; return ret;
} }
/***********************************************************************
* expose_window
*
* Expose a region of a given window.
*/
static void expose_window( HWND hwnd, RECT *rect, HRGN rgn, int flags )
{
POINT offset;
HWND top = 0;
HWND *list;
int i;
/* find the top most parent that doesn't clip children or siblings and
* invalidate the area on its parent, including all children */
if ((list = WIN_ListParents( hwnd )))
{
HWND current = hwnd;
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
for (i = 0; list[i] && list[i] != GetDesktopWindow(); i++)
{
if (!(style & WS_CLIPSIBLINGS)) top = current;
style = GetWindowLongW( list[i], GWL_STYLE );
if (!(style & WS_CLIPCHILDREN)) top = current;
current = list[i];
}
if (top)
{
/* find the parent of the top window, reusing the parent list */
if (top == hwnd) i = 0;
else
{
for (i = 0; list[i]; i++) if (list[i] == top) break;
if (list[i] && list[i+1]) i++;
}
if (list[i] != GetDesktopWindow()) top = list[i];
flags &= ~RDW_FRAME; /* parent will invalidate children frame anyway */
flags |= RDW_ALLCHILDREN;
}
HeapFree( GetProcessHeap(), 0, list );
}
if (!top) top = hwnd;
/* make coords relative to top */
offset.x = offset.y = 0;
MapWindowPoints( hwnd, top, &offset, 1 );
if (rect)
{
OffsetRect( rect, offset.x, offset.y );
RedrawWindow( top, rect, 0, flags );
}
else
{
OffsetRgn( rgn, offset.x, offset.y );
RedrawWindow( top, NULL, rgn, flags );
}
}
/*********************************************************************** /***********************************************************************
* X11DRV_Expose * X11DRV_Expose
*/ */
@ -207,7 +144,7 @@ void X11DRV_Expose( HWND hwnd, XExposeEvent *event )
{ {
RECT rect; RECT rect;
struct x11drv_win_data *data; struct x11drv_win_data *data;
int flags = RDW_INVALIDATE | RDW_ERASE; int flags = RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN;
TRACE( "win %p (%lx) %d,%d %dx%d\n", TRACE( "win %p (%lx) %d,%d %dx%d\n",
hwnd, event->window, event->x, event->y, event->width, event->height ); hwnd, event->window, event->x, event->y, event->width, event->height );
@ -219,14 +156,15 @@ void X11DRV_Expose( HWND hwnd, XExposeEvent *event )
rect.right = rect.left + event->width; rect.right = rect.left + event->width;
rect.bottom = rect.top + event->height; rect.bottom = rect.top + event->height;
if (event->window != data->client_window) /* whole window or icon window */ if (rect.left < data->client_rect.left ||
{ rect.top < data->client_rect.top ||
flags |= RDW_FRAME; rect.right > data->client_rect.right ||
/* make position relative to client area instead of window */ rect.bottom > data->client_rect.bottom) flags |= RDW_FRAME;
OffsetRect( &rect, -data->client_rect.left, -data->client_rect.top );
}
expose_window( hwnd, &rect, 0, flags ); /* make position relative to client area instead of window */
OffsetRect( &rect, -data->client_rect.left, -data->client_rect.top );
RedrawWindow( hwnd, &rect, 0, flags );
} }
@ -239,7 +177,6 @@ void X11DRV_Expose( HWND hwnd, XExposeEvent *event )
BOOL X11DRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags ) BOOL X11DRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
{ {
HWND top = get_top_clipping_window( hwnd ); HWND top = get_top_clipping_window( hwnd );
WND *win = WIN_GetPtr( hwnd );
struct x11drv_escape_set_drawable escape; struct x11drv_escape_set_drawable escape;
escape.mode = IncludeInferiors; escape.mode = IncludeInferiors;
@ -248,46 +185,39 @@ BOOL X11DRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
if (top != hwnd) if (top != hwnd)
{ {
/* find the top most parent that doesn't clip siblings */ POINT client_offset;
HWND clipping_parent = 0;
HWND *list = WIN_ListParents( hwnd );
if (list)
{
int i;
for (i = 0; list[i] != top; i++)
{
LONG style = GetWindowLongW( list[i], GWL_STYLE );
if (!(style & WS_CLIPSIBLINGS)) clipping_parent = list[i];
}
HeapFree( GetProcessHeap(), 0, list );
}
if (clipping_parent)
clipping_parent = GetAncestor( clipping_parent, GA_PARENT );
else if (!(flags & DCX_CLIPSIBLINGS) || (flags & DCX_WINDOW))
clipping_parent = GetAncestor( hwnd, GA_PARENT );
else
clipping_parent = hwnd;
escape.org.x = escape.org.y = 0;
escape.drawable_org.x = escape.drawable_org.y = 0;
if (flags & DCX_WINDOW) if (flags & DCX_WINDOW)
{ {
escape.org.x = win->rectWindow.left - win->rectClient.left; RECT rect;
escape.org.y = win->rectWindow.top - win->rectClient.top; GetWindowRect( hwnd, &rect );
escape.org.x = rect.left;
escape.org.y = rect.top;
MapWindowPoints( 0, top, &escape.org, 1 );
escape.drawable_org.x = rect.left - escape.org.x;
escape.drawable_org.y = rect.top - escape.org.y;
} }
MapWindowPoints( hwnd, clipping_parent, &escape.org, 1 ); else
MapWindowPoints( clipping_parent, 0, &escape.drawable_org, 1 ); {
escape.drawable = X11DRV_get_client_window( clipping_parent ); escape.org.x = escape.org.y = 0;
escape.drawable_org.x = escape.drawable_org.y = 0;
MapWindowPoints( hwnd, top, &escape.org, 1 );
MapWindowPoints( top, 0, &escape.drawable_org, 1 );
}
/* now make origins relative to the X window and not the client area */
client_offset = X11DRV_get_client_area_offset( top );
escape.org.x += client_offset.x;
escape.org.y += client_offset.y;
escape.drawable_org.x -= client_offset.x;
escape.drawable_org.y -= client_offset.y;
escape.drawable = X11DRV_get_whole_window( top );
} }
else else
{ {
struct x11drv_win_data *data; struct x11drv_win_data *data;
if (!(data = X11DRV_get_win_data( hwnd ))) if (!(data = X11DRV_get_win_data( hwnd ))) return FALSE;
{
WIN_ReleasePtr( win );
return FALSE;
}
if (IsIconic( hwnd )) if (IsIconic( hwnd ))
{ {
@ -296,21 +226,21 @@ BOOL X11DRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
escape.org.y = 0; escape.org.y = 0;
escape.drawable_org = escape.org; escape.drawable_org = escape.org;
} }
else if (flags & DCX_WINDOW) else
{ {
escape.drawable = data->whole_window; escape.drawable = data->whole_window;
escape.drawable_org.x = data->whole_rect.left; escape.drawable_org.x = data->whole_rect.left;
escape.drawable_org.y = data->whole_rect.top; escape.drawable_org.y = data->whole_rect.top;
escape.org.x = win->rectWindow.left - data->whole_rect.left; if (flags & DCX_WINDOW)
escape.org.y = win->rectWindow.top - data->whole_rect.top; {
} escape.org.x = data->window_rect.left - data->whole_rect.left;
else escape.org.y = data->window_rect.top - data->whole_rect.top;
{ }
escape.drawable = data->client_window; else
escape.drawable_org.x = win->rectClient.left; {
escape.drawable_org.y = win->rectClient.top; escape.org.x = data->client_rect.left;
escape.org.x = 0; escape.org.y = data->client_rect.top;
escape.org.y = 0; }
} }
} }
@ -329,8 +259,6 @@ BOOL X11DRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
SelectVisRgn16( HDC_16(hdc), HRGN_16(visRgn) ); SelectVisRgn16( HDC_16(hdc), HRGN_16(visRgn) );
DeleteObject( visRgn ); DeleteObject( visRgn );
} }
WIN_ReleasePtr( win );
return TRUE; return TRUE;
} }
@ -636,34 +564,25 @@ void X11DRV_SetWindowStyle( HWND hwnd, DWORD old_style )
if (changed & WS_VISIBLE) if (changed & WS_VISIBLE)
{ {
if (X11DRV_is_window_rect_mapped( &data->window_rect )) if (data->whole_window && X11DRV_is_window_rect_mapped( &data->window_rect ))
{ {
if (new_style & WS_VISIBLE) if (new_style & WS_VISIBLE)
{ {
TRACE( "mapping win %p\n", hwnd ); TRACE( "mapping win %p\n", hwnd );
if (is_window_top_level( hwnd )) X11DRV_sync_window_style( display, data );
{ X11DRV_set_wm_hints( display, data );
X11DRV_sync_window_style( display, data );
X11DRV_set_wm_hints( display, data );
}
wine_tsx11_lock(); wine_tsx11_lock();
XMapWindow( display, data->whole_window ); XMapWindow( display, data->whole_window );
wine_tsx11_unlock(); wine_tsx11_unlock();
} }
else if (!is_window_top_level( hwnd )) /* don't unmap managed windows */ /* we don't unmap windows, that causes trouble with the window manager */
{
TRACE( "unmapping win %p\n", hwnd );
wine_tsx11_lock();
XUnmapWindow( display, data->whole_window );
wine_tsx11_unlock();
}
} }
DCE_InvalidateDCE( hwnd, &data->window_rect ); DCE_InvalidateDCE( hwnd, &data->window_rect );
} }
if (changed & WS_DISABLED) if (changed & WS_DISABLED)
{ {
if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_MANAGED) if (data->whole_window && (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_MANAGED))
{ {
XWMHints *wm_hints; XWMHints *wm_hints;
wine_tsx11_lock(); wine_tsx11_lock();
@ -748,14 +667,7 @@ BOOL X11DRV_set_window_pos( HWND hwnd, HWND insert_after, const RECT *rectWindow
/* FIXME: copy the valid bits */ /* FIXME: copy the valid bits */
if (swp_flags & SWP_WINE_NOHOSTMOVE) if (data->whole_window)
{
data->whole_rect = *rectWindow;
X11DRV_window_to_X_rect( hwnd, &data->whole_rect );
if (data->client_window != data->whole_window)
X11DRV_sync_client_window_position( display, data, rectClient );
}
else if (data->whole_window) /* don't do anything if X window not created yet */
{ {
if ((old_style & WS_VISIBLE) && !(new_style & WS_VISIBLE)) if ((old_style & WS_VISIBLE) && !(new_style & WS_VISIBLE))
{ {
@ -773,21 +685,20 @@ BOOL X11DRV_set_window_pos( HWND hwnd, HWND insert_after, const RECT *rectWindow
XUnmapWindow( display, data->whole_window ); XUnmapWindow( display, data->whole_window );
wine_tsx11_unlock(); wine_tsx11_unlock();
} }
}
X11DRV_sync_whole_window_position( display, data, !(swp_flags & SWP_NOZORDER) ); X11DRV_sync_window_position( display, data, swp_flags, rectClient );
X11DRV_sync_client_window_position( display, data, rectClient );
if (data->whole_window)
{
if (!(old_style & WS_VISIBLE) && (new_style & WS_VISIBLE)) if (!(old_style & WS_VISIBLE) && (new_style & WS_VISIBLE))
{ {
/* window got shown, map it */ /* window got shown, map it */
if (X11DRV_is_window_rect_mapped( rectWindow )) if (X11DRV_is_window_rect_mapped( rectWindow ))
{ {
TRACE( "mapping win %p\n", hwnd ); TRACE( "mapping win %p\n", hwnd );
if (is_window_top_level( hwnd )) X11DRV_sync_window_style( display, data );
{ X11DRV_set_wm_hints( display, data );
X11DRV_sync_window_style( display, data );
X11DRV_set_wm_hints( display, data );
}
wine_tsx11_lock(); wine_tsx11_lock();
XMapWindow( display, data->whole_window ); XMapWindow( display, data->whole_window );
wine_tsx11_unlock(); wine_tsx11_unlock();
@ -1226,7 +1137,7 @@ void X11DRV_MapNotify( HWND hwnd, XMapEvent *event )
rect.bottom = y + height; rect.bottom = y + height;
X11DRV_X_to_window_rect( hwnd, &rect ); X11DRV_X_to_window_rect( hwnd, &rect );
DCE_InvalidateDCE( hwnd, &win->rectWindow ); DCE_InvalidateDCE( hwnd, &data->window_rect );
if (win->flags & WIN_RESTORE_MAX) style |= WS_MAXIMIZE; if (win->flags & WIN_RESTORE_MAX) style |= WS_MAXIMIZE;
WIN_SetStyle( hwnd, style, WS_MINIMIZE ); WIN_SetStyle( hwnd, style, WS_MINIMIZE );
@ -1878,8 +1789,8 @@ void X11DRV_SysCommandSizeMove( HWND hwnd, WPARAM wParam )
gdi_display = display; gdi_display = display;
wine_tsx11_unlock(); wine_tsx11_unlock();
} }
whole_win = X11DRV_get_whole_window(hwnd); whole_win = X11DRV_get_whole_window( GetAncestor(hwnd,GA_ROOT) );
parent_win = parent ? X11DRV_get_client_window(parent) : root_window; parent_win = parent ? X11DRV_get_whole_window( GetAncestor(parent,GA_ROOT) ) : root_window;
wine_tsx11_lock(); wine_tsx11_lock();
XGrabPointer( display, whole_win, False, XGrabPointer( display, whole_win, False,

View File

@ -531,7 +531,6 @@ struct x11drv_win_data
{ {
HWND hwnd; /* hwnd that this private data belongs to */ HWND hwnd; /* hwnd that this private data belongs to */
Window whole_window; /* X window for the complete window */ Window whole_window; /* X window for the complete window */
Window client_window; /* X window for the client area */
Window icon_window; /* X window for the icon */ Window icon_window; /* X window for the icon */
RECT window_rect; /* USER window rectangle relative to parent */ RECT window_rect; /* USER window rectangle relative to parent */
RECT whole_rect; /* X window rectangle for the whole window relative to parent */ RECT whole_rect; /* X window rectangle for the whole window relative to parent */
@ -542,16 +541,11 @@ struct x11drv_win_data
}; };
extern struct x11drv_win_data *X11DRV_get_win_data( HWND hwnd ); extern struct x11drv_win_data *X11DRV_get_win_data( HWND hwnd );
extern Window X11DRV_get_client_window( HWND hwnd ); extern POINT X11DRV_get_client_area_offset( HWND hwnd );
extern Window X11DRV_get_whole_window( HWND hwnd ); extern Window X11DRV_get_whole_window( HWND hwnd );
extern BOOL X11DRV_is_window_rect_mapped( const RECT *rect ); extern BOOL X11DRV_is_window_rect_mapped( const RECT *rect );
extern XIC X11DRV_get_ic( HWND hwnd ); extern XIC X11DRV_get_ic( HWND hwnd );
inline static BOOL is_window_top_level( HWND hwnd )
{
return (root_window == DefaultRootWindow(gdi_display) &&
GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow());
}
/* X context to associate a hwnd to an X window */ /* X context to associate a hwnd to an X window */
extern XContext winContext; extern XContext winContext;
@ -569,10 +563,8 @@ extern void X11DRV_X_to_window_rect( HWND hwnd, RECT *rect );
extern void X11DRV_create_desktop_thread(void); extern void X11DRV_create_desktop_thread(void);
extern Window X11DRV_create_desktop( XVisualInfo *desktop_vi, const char *geometry ); extern Window X11DRV_create_desktop( XVisualInfo *desktop_vi, const char *geometry );
extern void X11DRV_sync_window_style( Display *display, struct x11drv_win_data *data ); extern void X11DRV_sync_window_style( Display *display, struct x11drv_win_data *data );
extern int X11DRV_sync_whole_window_position( Display *display, struct x11drv_win_data *data, extern void X11DRV_sync_window_position( Display *display, struct x11drv_win_data *data,
int zorder ); UINT swp_flags, const RECT *new_client_rect );
extern int X11DRV_sync_client_window_position( Display *display, struct x11drv_win_data *data,
const RECT *new_client_rect );
extern BOOL X11DRV_set_window_pos( HWND hwnd, HWND insert_after, const RECT *rectWindow, extern BOOL X11DRV_set_window_pos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
const RECT *rectClient, UINT swp_flags, UINT wvr_flags ); const RECT *rectClient, UINT swp_flags, UINT wvr_flags );
extern void X11DRV_set_wm_hints( Display *display, struct x11drv_win_data *data ); extern void X11DRV_set_wm_hints( Display *display, struct x11drv_win_data *data );