winex11.drv: Don't create a win_data structure for the desktop window, except in the process that owns it.

Handle desktop size changes by sending a message to the desktop owner.
This commit is contained in:
Alexandre Julliard 2008-01-17 19:53:59 +01:00
parent a9e9673460
commit c19af910eb
7 changed files with 85 additions and 97 deletions

View File

@ -68,41 +68,6 @@ static void make_modes(void)
} }
} }
/***********************************************************************
* X11DRV_resize_desktop
*
* Reset the desktop window size and WM hints
*/
static int X11DRV_resize_desktop( unsigned int width, unsigned int height )
{
XSizeHints *size_hints;
Display *display = thread_display();
Window w = root_window;
/* set up */
wine_tsx11_lock();
size_hints = XAllocSizeHints();
if (!size_hints)
{
ERR("Not enough memory for window manager hints.\n" );
wine_tsx11_unlock();
return 0;
}
size_hints->min_width = size_hints->max_width = width;
size_hints->min_height = size_hints->max_height = height;
size_hints->flags = PMinSize | PMaxSize | PSize;
/* do the work */
XSetWMNormalHints( display, w, size_hints );
XResizeWindow( display, w, width, height );
/* clean up */
XFree( size_hints );
XFlush( display );
wine_tsx11_unlock();
X11DRV_handle_desktop_resize( width, height );
return 1;
}
static int X11DRV_desktop_GetCurrentMode(void) static int X11DRV_desktop_GetCurrentMode(void)
{ {
unsigned int i; unsigned int i;

View File

@ -964,6 +964,9 @@ LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
return SendMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 ); return SendMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
case WM_X11DRV_SET_WIN_FORMAT: case WM_X11DRV_SET_WIN_FORMAT:
return X11DRV_set_win_format( hwnd, (XID)wp ); return X11DRV_set_win_format( hwnd, (XID)wp );
case WM_X11DRV_RESIZE_DESKTOP:
X11DRV_resize_desktop( LOWORD(lp), HIWORD(lp) );
return 0;
default: default:
FIXME( "got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp ); FIXME( "got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp );
return 0; return 0;

View File

@ -998,6 +998,9 @@ void X11DRV_sync_window_position( Display *display, struct x11drv_win_data *data
} }
} }
/* only the size is allowed to change for the desktop window */
if (data->whole_window == root_window) mask &= CWWidth | CWHeight;
if (mask) if (mask)
{ {
DWORD style = GetWindowLongW( data->hwnd, GWL_STYLE ); DWORD style = GetWindowLongW( data->hwnd, GWL_STYLE );
@ -1225,46 +1228,27 @@ static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd )
} }
/* fill in the desktop X window id in the x11drv_win_data structure */ /* initialize the desktop window id in the desktop manager process */
static void get_desktop_xwin( Display *display, struct x11drv_win_data *data ) static void get_desktop_xwin( Display *display, struct x11drv_win_data *data )
{ {
Window win = (Window)GetPropA( data->hwnd, whole_window_prop ); data->whole_window = root_window;
if (root_window != DefaultRootWindow( display ))
if (win)
{
unsigned int width, height;
/* retrieve the real size of the desktop */
SERVER_START_REQ( get_window_rectangles )
{
req->handle = data->hwnd;
wine_server_call( req );
width = reply->window.right - reply->window.left;
height = reply->window.bottom - reply->window.top;
}
SERVER_END_REQ;
data->whole_window = win;
if (win != root_window) X11DRV_init_desktop( win, width, height );
}
else
{ {
VisualID visualid; VisualID visualid;
wine_tsx11_lock(); wine_tsx11_lock();
visualid = XVisualIDFromVisual(visual); visualid = XVisualIDFromVisual(visual);
wine_tsx11_unlock(); wine_tsx11_unlock();
data->managed = TRUE;
SetPropA( data->hwnd, managed_prop, (HANDLE)1 );
SetPropA( data->hwnd, whole_window_prop, (HANDLE)root_window ); SetPropA( data->hwnd, whole_window_prop, (HANDLE)root_window );
SetPropA( data->hwnd, visual_id_prop, (HANDLE)visualid ); SetPropA( data->hwnd, visual_id_prop, (HANDLE)visualid );
data->whole_window = root_window; set_initial_wm_hints( display, data );
X11DRV_SetWindowPos( data->hwnd, 0, &virtual_screen_rect, &virtual_screen_rect,
SWP_NOZORDER | SWP_NOACTIVATE, NULL );
if (root_window != DefaultRootWindow( display ))
{
data->managed = TRUE;
SetPropA( data->hwnd, managed_prop, (HANDLE)1 );
set_initial_wm_hints( display, data );
}
} }
SetWindowPos( data->hwnd, 0, virtual_screen_rect.left, virtual_screen_rect.top,
virtual_screen_rect.right - virtual_screen_rect.left,
virtual_screen_rect.bottom - virtual_screen_rect.top,
SWP_NOZORDER | SWP_NOACTIVATE );
} }
/********************************************************************** /**********************************************************************
@ -1272,13 +1256,39 @@ static void get_desktop_xwin( Display *display, struct x11drv_win_data *data )
*/ */
BOOL X11DRV_CreateDesktopWindow( HWND hwnd ) BOOL X11DRV_CreateDesktopWindow( HWND hwnd )
{ {
Display *display = thread_display(); unsigned int width, height;
struct x11drv_win_data *data;
if (!(data = alloc_win_data( display, hwnd ))) return FALSE; /* retrieve the real size of the desktop */
SERVER_START_REQ( get_window_rectangles )
get_desktop_xwin( display, data ); {
req->handle = hwnd;
wine_server_call( req );
width = reply->window.right - reply->window.left;
height = reply->window.bottom - reply->window.top;
}
SERVER_END_REQ;
if (!width && !height) /* not initialized yet */
{
SERVER_START_REQ( set_window_pos )
{
req->handle = hwnd;
req->previous = 0;
req->flags = SWP_NOZORDER;
req->window.left = virtual_screen_rect.left;
req->window.top = virtual_screen_rect.top;
req->window.right = virtual_screen_rect.right;
req->window.bottom = virtual_screen_rect.bottom;
req->client = req->window;
wine_server_call( req );
}
SERVER_END_REQ;
}
else
{
Window win = (Window)GetPropA( hwnd, whole_window_prop );
if (win && win != root_window) X11DRV_init_desktop( win, width, height );
}
return TRUE; return TRUE;
} }
@ -1321,18 +1331,18 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
cs->cy = 0; cs->cy = 0;
} }
/* initialize the dimensions before sending WM_GETMINMAXINFO */ if (hwnd == GetDesktopWindow()) get_desktop_xwin( display, data );
SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy ); else
X11DRV_SetWindowPos( hwnd, 0, &rect, &rect, SWP_NOZORDER | SWP_NOACTIVATE, NULL ); {
/* initialize the dimensions before sending WM_GETMINMAXINFO */
SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
X11DRV_SetWindowPos( hwnd, 0, &rect, &rect, SWP_NOZORDER | SWP_NOACTIVATE, NULL );
/* create an X window if it's a top level window */ /* create an X window if it's a top level window */
if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow()) if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow())
{ {
if (!create_whole_window( display, data, cs->style )) goto failed; if (!create_whole_window( display, data, cs->style )) goto failed;
} }
else if (hwnd == GetDesktopWindow())
{
get_desktop_xwin( display, data );
} }
/* get class or window DC if needed */ /* get class or window DC if needed */
@ -1493,7 +1503,11 @@ Window X11DRV_get_whole_window( HWND hwnd )
{ {
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, whole_window_prop ); if (!data)
{
if (hwnd == GetDesktopWindow()) return root_window;
return (Window)GetPropA( hwnd, whole_window_prop );
}
return data->whole_window; return data->whole_window;
} }

View File

@ -873,30 +873,36 @@ static BOOL CALLBACK update_windows_on_desktop_resize( HWND hwnd, LPARAM lparam
/*********************************************************************** /***********************************************************************
* X11DRV_handle_desktop_resize * X11DRV_resize_desktop
*/ */
void X11DRV_handle_desktop_resize( unsigned int width, unsigned int height ) void X11DRV_resize_desktop( unsigned int width, unsigned int height )
{ {
HWND hwnd = GetDesktopWindow(); HWND hwnd = GetDesktopWindow();
struct x11drv_win_data *data; struct x11drv_win_data *data;
struct desktop_resize_data resize_data; struct desktop_resize_data resize_data;
if (!(data = X11DRV_get_win_data( hwnd ))) return;
SetRect( &resize_data.old_screen_rect, 0, 0, screen_width, screen_height ); SetRect( &resize_data.old_screen_rect, 0, 0, screen_width, screen_height );
resize_data.old_virtual_rect = virtual_screen_rect; resize_data.old_virtual_rect = virtual_screen_rect;
screen_width = width; screen_width = width;
screen_height = height; screen_height = height;
xinerama_init(); xinerama_init();
TRACE("desktop %p change to (%dx%d)\n", hwnd, width, height);
data->lock_changes++;
X11DRV_SetWindowPos( hwnd, 0, &virtual_screen_rect, &virtual_screen_rect,
SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE, NULL );
data->lock_changes--;
ClipCursor(NULL); ClipCursor(NULL);
SendMessageTimeoutW( HWND_BROADCAST, WM_DISPLAYCHANGE, screen_bpp,
MAKELPARAM( width, height ), SMTO_ABORTIFHUNG, 2000, NULL ); if (!(data = X11DRV_get_win_data( hwnd )))
{
SendMessageW( hwnd, WM_X11DRV_RESIZE_DESKTOP, 0, MAKELPARAM( width, height ) );
}
else
{
TRACE( "desktop %p change to (%dx%d)\n", hwnd, width, height );
SetWindowPos( hwnd, 0, virtual_screen_rect.left, virtual_screen_rect.top,
virtual_screen_rect.right - virtual_screen_rect.left,
virtual_screen_rect.bottom - virtual_screen_rect.top,
SWP_NOZORDER | SWP_NOACTIVATE );
SendMessageTimeoutW( HWND_BROADCAST, WM_DISPLAYCHANGE, screen_bpp,
MAKELPARAM( width, height ), SMTO_ABORTIFHUNG, 2000, NULL );
}
EnumWindows( update_windows_on_desktop_resize, (LPARAM)&resize_data ); EnumWindows( update_windows_on_desktop_resize, (LPARAM)&resize_data );
} }

View File

@ -644,7 +644,8 @@ enum x11drv_window_messages
{ {
WM_X11DRV_ACQUIRE_SELECTION = 0x80001000, WM_X11DRV_ACQUIRE_SELECTION = 0x80001000,
WM_X11DRV_DELETE_WINDOW, WM_X11DRV_DELETE_WINDOW,
WM_X11DRV_SET_WIN_FORMAT WM_X11DRV_SET_WIN_FORMAT,
WM_X11DRV_RESIZE_DESKTOP
}; };
/* _NET_WM_STATE properties that we keep track of */ /* _NET_WM_STATE properties that we keep track of */
@ -733,7 +734,7 @@ extern void X11DRV_set_wm_hints( Display *display, struct x11drv_win_data *data
extern void xinerama_init(void); extern void xinerama_init(void);
extern void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height ); extern void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height );
extern void X11DRV_handle_desktop_resize(unsigned int width, unsigned int height); extern void X11DRV_resize_desktop(unsigned int width, unsigned int height);
extern void X11DRV_Settings_AddDepthModes(void); extern void X11DRV_Settings_AddDepthModes(void);
extern void X11DRV_Settings_AddOneMode(unsigned int width, unsigned int height, unsigned int bpp, unsigned int freq); extern void X11DRV_Settings_AddOneMode(unsigned int width, unsigned int height, unsigned int bpp, unsigned int freq);
extern int X11DRV_Settings_CreateDriver(LPDDHALINFO info); extern int X11DRV_Settings_CreateDriver(LPDDHALINFO info);

View File

@ -229,7 +229,7 @@ static LONG X11DRV_XRandR_SetCurrentMode(int mode)
wine_tsx11_unlock(); wine_tsx11_unlock();
if (stat == RRSetConfigSuccess) if (stat == RRSetConfigSuccess)
{ {
X11DRV_handle_desktop_resize( dd_modes[mode].dwWidth, dd_modes[mode].dwHeight ); X11DRV_resize_desktop( dd_modes[mode].dwWidth, dd_modes[mode].dwHeight );
return DISP_CHANGE_SUCCESSFUL; return DISP_CHANGE_SUCCESSFUL;
} }

View File

@ -131,8 +131,7 @@ static LONG X11DRV_XF86VM_SetCurrentMode(int mode)
#endif #endif
XSync(gdi_display, False); XSync(gdi_display, False);
wine_tsx11_unlock(); wine_tsx11_unlock();
X11DRV_handle_desktop_resize( real_xf86vm_modes[mode]->hdisplay, X11DRV_resize_desktop( real_xf86vm_modes[mode]->hdisplay, real_xf86vm_modes[mode]->vdisplay );
real_xf86vm_modes[mode]->vdisplay );
return DISP_CHANGE_SUCCESSFUL; return DISP_CHANGE_SUCCESSFUL;
} }