Alexandre Julliard : winex11: Improve management of the lifetime of embedded windows.

Alexandre Julliard julliard at winehq.org
Tue Nov 2 11:10:53 CDT 2010


Module: wine
Branch: master
Commit: 68f497bdccf395383dd0f8c56f7e75c95ba5c62a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=68f497bdccf395383dd0f8c56f7e75c95ba5c62a

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Nov  1 19:45:12 2010 +0100

winex11: Improve management of the lifetime of embedded windows.

---

 dlls/winex11.drv/event.c       |   68 ++++++++++++++++++++++++++++++++++++++-
 dlls/winex11.drv/systray.c     |    9 +++++
 dlls/winex11.drv/window.c      |    3 +-
 dlls/winex11.drv/x11drv.h      |    2 +
 dlls/winex11.drv/x11drv_main.c |    1 +
 5 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 9fbb002..89d3a93 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -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 */
@@ -814,6 +829,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
  */
 void X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
@@ -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 },
diff --git a/dlls/winex11.drv/systray.c b/dlls/winex11.drv/systray.c
index e500a33..9d15396 100644
--- a/dlls/winex11.drv/systray.c
+++ b/dlls/winex11.drv/systray.c
@@ -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 );
 }
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index dade30e..acf0b4d 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -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 );
 }
 
 
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 722ca85..4308823 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -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;
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 8477082..fe4a88c 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -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",




More information about the wine-cvs mailing list