winex11: Add some generic support for XEMBED client windows.

This commit is contained in:
Alexandre Julliard 2008-04-09 15:46:33 +02:00
parent ea59ea5904
commit a0ac99c536
3 changed files with 66 additions and 27 deletions

View File

@ -69,8 +69,6 @@ static BOOL delete_icon( struct tray_icon *icon );
#define SYSTEM_TRAY_BEGIN_MESSAGE 1
#define SYSTEM_TRAY_CANCEL_MESSAGE 2
#define XEMBED_MAPPED (1 << 0)
#define ICON_BORDER 2
/* retrieves icon record by owner window and ID */
@ -228,23 +226,13 @@ static void dock_systray_window( HWND hwnd, Window systray_window )
struct x11drv_win_data *data;
XEvent ev;
XSetWindowAttributes attr;
unsigned long info[2];
if (!(data = X11DRV_get_win_data( hwnd )) &&
!(data = X11DRV_create_win_data( hwnd ))) return;
TRACE( "icon window %p/%lx managed %u\n", data->hwnd, data->whole_window, data->managed );
/* the window _cannot_ be mapped if we intend to dock with an XEMBED tray */
assert( !data->mapped );
/* set XEMBED protocol data on the window */
info[0] = 0; /* protocol version */
info[1] = XEMBED_MAPPED; /* flags */
wine_tsx11_lock();
XChangeProperty( display, data->whole_window, x11drv_atom(_XEMBED_INFO),
x11drv_atom(_XEMBED_INFO), 32, PropModeReplace, (unsigned char*)info, 2 );
make_window_embedded( display, data );
/* send the docking request message */
ev.xclient.type = ClientMessage;
@ -256,15 +244,13 @@ static void dock_systray_window( HWND hwnd, Window systray_window )
ev.xclient.data.l[2] = data->whole_window;
ev.xclient.data.l[3] = 0;
ev.xclient.data.l[4] = 0;
wine_tsx11_lock();
XSendEvent( display, systray_window, False, NoEventMask, &ev );
attr.background_pixmap = ParentRelative;
attr.bit_gravity = ForgetGravity;
XChangeWindowAttributes( display, data->whole_window, CWBackPixmap | CWBitGravity, &attr );
XChangeWindowAttributes( display, data->client_window, CWBackPixmap | CWBitGravity, &attr );
wine_tsx11_unlock();
data->mapped = TRUE;
data->wm_state = NormalState;
}

View File

@ -204,19 +204,42 @@ static void update_net_wm_states( Display *display, struct x11drv_win_data *data
}
/***********************************************************************
* set_xembed_flags
*/
static void set_xembed_flags( Display *display, struct x11drv_win_data *data, unsigned long flags )
{
unsigned long info[2];
info[0] = 0; /* protocol version */
info[1] = flags;
wine_tsx11_lock();
XChangeProperty( display, data->whole_window, x11drv_atom(_XEMBED_INFO),
x11drv_atom(_XEMBED_INFO), 32, PropModeReplace, (unsigned char*)info, 2 );
wine_tsx11_unlock();
}
/***********************************************************************
* map_window
*/
static void map_window( Display *display, struct x11drv_win_data *data, DWORD new_style )
{
TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
wait_for_withdrawn_state( display, data, TRUE );
update_net_wm_states( display, data );
X11DRV_sync_window_style( display, data );
wine_tsx11_lock();
XMapWindow( display, data->whole_window );
XFlush( display );
wine_tsx11_unlock();
if (!data->embedded)
{
update_net_wm_states( display, data );
X11DRV_sync_window_style( display, data );
wine_tsx11_lock();
XMapWindow( display, data->whole_window );
XFlush( display );
wine_tsx11_unlock();
}
else set_xembed_flags( display, data, XEMBED_MAPPED );
data->mapped = TRUE;
data->iconic = (new_style & WS_MINIMIZE) != 0;
}
@ -228,16 +251,42 @@ static void map_window( Display *display, struct x11drv_win_data *data, DWORD ne
static void unmap_window( Display *display, struct x11drv_win_data *data )
{
TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
wait_for_withdrawn_state( display, data, FALSE );
wine_tsx11_lock();
if (data->managed) XWithdrawWindow( display, data->whole_window, DefaultScreen(display) );
else XUnmapWindow( display, data->whole_window );
wine_tsx11_unlock();
if (!data->embedded)
{
wait_for_withdrawn_state( display, data, FALSE );
wine_tsx11_lock();
if (data->managed) XWithdrawWindow( display, data->whole_window, DefaultScreen(display) );
else XUnmapWindow( display, data->whole_window );
wine_tsx11_unlock();
}
else set_xembed_flags( display, data, 0 );
data->mapped = FALSE;
data->net_wm_state = 0;
}
/***********************************************************************
* make_window_embedded
*/
void make_window_embedded( Display *display, struct x11drv_win_data *data )
{
if (data->mapped)
{
/* the window cannot be mapped before being embedded */
unmap_window( display, data );
data->embedded = TRUE;
map_window( display, data, 0 );
}
else
{
data->embedded = TRUE;
set_xembed_flags( display, data, 0 );
}
}
/***********************************************************************
* SetWindowStyle (X11DRV.@)
*

View File

@ -695,6 +695,7 @@ struct x11drv_win_data
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? */
BOOL embedded : 1; /* is window an XEMBED client? */
int wm_state; /* current value of the WM_STATE property */
DWORD net_wm_state; /* bit mask of active x11drv_net_wm_state values */
HBITMAP hWMIconBitmap;
@ -717,6 +718,7 @@ extern void flush_gl_drawable( X11DRV_PDEVICE *physDev );
extern int get_window_wm_state( Display *display, struct x11drv_win_data *data );
extern void wait_for_withdrawn_state( Display *display, struct x11drv_win_data *data, BOOL set );
extern void make_window_embedded( Display *display, struct x11drv_win_data *data );
/* X context to associate a hwnd to an X window */
extern XContext winContext;
@ -773,4 +775,6 @@ extern void X11DRV_DDHAL_SwitchMode(DWORD dwModeIndex, LPVOID fb_addr, LPVIDMEM
extern LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode );
extern void WIN_invalidate_dce( HWND hwnd, const RECT *rect );
#define XEMBED_MAPPED (1 << 0)
#endif /* __WINE_X11DRV_H */