winex11: Improve management of the lifetime of embedded windows.

This commit is contained in:
Alexandre Julliard 2010-11-01 19:45:12 +01:00
parent 8c963852f8
commit 68f497bdcc
5 changed files with 80 additions and 3 deletions

View File

@ -72,11 +72,26 @@ extern BOOL ximInComposeMode;
#define DndURL 128 /* KDE drag&drop */
#define XEMBED_EMBEDDED_NOTIFY 0
#define XEMBED_WINDOW_ACTIVATE 1
#define XEMBED_WINDOW_DEACTIVATE 2
#define XEMBED_REQUEST_FOCUS 3
#define XEMBED_FOCUS_IN 4
#define XEMBED_FOCUS_OUT 5
#define XEMBED_FOCUS_NEXT 6
#define XEMBED_FOCUS_PREV 7
#define XEMBED_MODALITY_ON 10
#define XEMBED_MODALITY_OFF 11
#define XEMBED_REGISTER_ACCELERATOR 12
#define XEMBED_UNREGISTER_ACCELERATOR 13
#define XEMBED_ACTIVATE_ACCELERATOR 14
/* Event handlers */
static void X11DRV_FocusIn( HWND hwnd, XEvent *event );
static void X11DRV_FocusOut( HWND hwnd, XEvent *event );
static void X11DRV_Expose( HWND hwnd, XEvent *event );
static void X11DRV_MapNotify( HWND hwnd, XEvent *event );
static void X11DRV_ReparentNotify( HWND hwnd, XEvent *event );
static void X11DRV_ConfigureNotify( HWND hwnd, XEvent *event );
static void X11DRV_PropertyNotify( HWND hwnd, XEvent *event );
static void X11DRV_ClientMessage( HWND hwnd, XEvent *event );
@ -111,7 +126,7 @@ static struct event_handler handlers[MAX_EVENT_HANDLERS] =
/* UnmapNotify */
{ MapNotify, X11DRV_MapNotify },
/* MapRequest */
/* ReparentNotify */
{ ReparentNotify, X11DRV_ReparentNotify },
{ ConfigureNotify, X11DRV_ConfigureNotify },
/* ConfigureRequest */
/* GravityNotify */
@ -127,7 +142,7 @@ static struct event_handler handlers[MAX_EVENT_HANDLERS] =
{ MappingNotify, X11DRV_MappingNotify },
};
static int nb_event_handlers = 18; /* change this if you add handlers above */
static int nb_event_handlers = 19; /* change this if you add handlers above */
/* return the name of an X event */
@ -813,6 +828,30 @@ static BOOL is_net_wm_state_maximized( Display *display, struct x11drv_win_data
}
/***********************************************************************
* X11DRV_ReparentNotify
*/
static void X11DRV_ReparentNotify( HWND hwnd, XEvent *xev )
{
XReparentEvent *event = &xev->xreparent;
struct x11drv_win_data *data;
if (!(data = X11DRV_get_win_data( hwnd ))) return;
if (!data->embedded) return;
if (event->parent == root_window)
{
TRACE( "%p/%lx reparented to root\n", hwnd, data->whole_window );
data->embedder = 0;
SendMessageW( hwnd, WM_CLOSE, 0, 0 );
}
else
{
TRACE( "%p/%lx reparented to %lx\n", hwnd, data->whole_window, event->parent );
data->embedder = event->parent;
}
}
/***********************************************************************
* X11DRV_ConfigureNotify
*/
@ -1334,6 +1373,30 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
}
}
/**********************************************************************
* handle_xembed_protocol
*/
static void handle_xembed_protocol( HWND hwnd, XClientMessageEvent *event )
{
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
if (!data) return;
switch (event->data.l[1])
{
case XEMBED_EMBEDDED_NOTIFY:
TRACE( "win %p/%lx XEMBED_EMBEDDED_NOTIFY owner %lx\n", hwnd, event->window, event->data.l[3] );
data->embedder = event->data.l[3];
break;
default:
TRACE( "win %p/%lx XEMBED message %lu(%lu)\n",
hwnd, event->window, event->data.l[1], event->data.l[2] );
break;
}
}
/**********************************************************************
* handle_dnd_protocol
*/
@ -1366,6 +1429,7 @@ struct client_message_handler
static const struct client_message_handler client_messages[] =
{
{ XATOM_WM_PROTOCOLS, handle_wm_protocols },
{ XATOM__XEMBED, handle_xembed_protocol },
{ XATOM_DndProtocol, handle_dnd_protocol },
{ XATOM_XdndEnter, X11DRV_XDND_EnterEvent },
{ XATOM_XdndPosition, X11DRV_XDND_PositionEvent },

View File

@ -309,6 +309,15 @@ static LRESULT WINAPI tray_icon_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPAR
case WM_TIMER:
if (!IsWindow( icon->owner )) delete_icon( icon );
return 0;
case WM_CLOSE:
if (icon->display == -1)
{
TRACE( "icon %u no longer embedded\n", icon->id );
hide_icon( icon );
add_to_standalone_tray( icon );
}
return 0;
}
return DefWindowProcW( hwnd, msg, wparam, lparam );
}

View File

@ -1890,8 +1890,9 @@ void X11DRV_DestroyNotify( HWND hwnd, XEvent *event )
if (!(data = X11DRV_get_win_data( hwnd ))) return;
FIXME( "window %p/%lx destroyed from the outside\n", hwnd, data->whole_window );
if (!data->embedded) FIXME( "window %p/%lx destroyed from the outside\n", hwnd, data->whole_window );
destroy_whole_window( display, data, TRUE );
if (data->embedded) SendMessageW( hwnd, WM_CLOSE, 0, 0 );
}

View File

@ -660,6 +660,7 @@ enum x11drv_atoms
XATOM__NET_WM_WINDOW_TYPE_NORMAL,
XATOM__NET_WM_WINDOW_TYPE_UTILITY,
XATOM__NET_WORKAREA,
XATOM__XEMBED,
XATOM__XEMBED_INFO,
XATOM_XdndAware,
XATOM_XdndEnter,
@ -758,6 +759,7 @@ struct x11drv_win_data
BOOL shaped : 1; /* is window using a custom region shape? */
int wm_state; /* current value of the WM_STATE property */
DWORD net_wm_state; /* bit mask of active x11drv_net_wm_state values */
Window embedder; /* window id of embedder */
unsigned long configure_serial; /* serial number of last configure request */
HBITMAP hWMIconBitmap;
HBITMAP hWMIconMask;

View File

@ -160,6 +160,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
"_NET_WM_WINDOW_TYPE_NORMAL",
"_NET_WM_WINDOW_TYPE_UTILITY",
"_NET_WORKAREA",
"_XEMBED",
"_XEMBED_INFO",
"XdndAware",
"XdndEnter",