Sebastian Lackner : winex11: Implement additional XEMBED events.

Alexandre Julliard julliard at winehq.org
Mon Nov 11 14:08:16 CST 2013


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

Author: Sebastian Lackner <sebastian at fds-team.de>
Date:   Sat Oct 26 18:34:32 2013 +0200

winex11: Implement additional XEMBED events.

---

 dlls/winex11.drv/event.c  |  145 ++++++++++++++++++++++++++++++---------------
 dlls/winex11.drv/window.c |    2 +-
 2 files changed, 98 insertions(+), 49 deletions(-)

diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 4218949..64188bc 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -748,34 +748,22 @@ static void X11DRV_FocusIn( HWND hwnd, XEvent *xev )
     else SetForegroundWindow( hwnd );
 }
 
-
 /**********************************************************************
- *              X11DRV_FocusOut
- *
- * Note: only top-level windows get FocusOut events.
+ *              focus_out
  */
-static void X11DRV_FocusOut( HWND hwnd, XEvent *xev )
-{
-    XFocusChangeEvent *event = &xev->xfocus;
+ static void focus_out( Display *display , HWND hwnd )
+ {
     HWND hwnd_tmp;
     Window focus_win;
     int revert;
     XIC xic;
 
-    TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] );
-
-    if (event->detail == NotifyPointer)
-    {
-        if (!hwnd && event->window == x11drv_thread_data()->clip_window) reset_clipping_window();
-        return;
-    }
-    if (!hwnd) return;
     if (ximInComposeMode) return;
 
     x11drv_thread_data()->last_focus = hwnd;
     if ((xic = X11DRV_get_ic( hwnd ))) XUnsetICFocus( xic );
 
-    if (root_window != DefaultRootWindow(event->display))
+    if (root_window != DefaultRootWindow(display))
     {
         if (hwnd == GetDesktopWindow()) reset_clipping_window();
         return;
@@ -786,10 +774,10 @@ static void X11DRV_FocusOut( HWND hwnd, XEvent *xev )
     /* don't reset the foreground window, if the window which is
        getting the focus is a Wine window */
 
-    XGetInputFocus( event->display, &focus_win, &revert );
+    XGetInputFocus( display, &focus_win, &revert );
     if (focus_win)
     {
-        if (XFindContext( event->display, focus_win, winContext, (char **)&hwnd_tmp ) != 0)
+        if (XFindContext( display, focus_win, winContext, (char **)&hwnd_tmp ) != 0)
             focus_win = 0;
     }
 
@@ -805,6 +793,26 @@ static void X11DRV_FocusOut( HWND hwnd, XEvent *xev )
             SetForegroundWindow( GetDesktopWindow() );
         }
     }
+ }
+
+/**********************************************************************
+ *              X11DRV_FocusOut
+ *
+ * Note: only top-level windows get FocusOut events.
+ */
+static void X11DRV_FocusOut( HWND hwnd, XEvent *xev )
+{
+    XFocusChangeEvent *event = &xev->xfocus;
+
+    TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] );
+
+    if (event->detail == NotifyPointer)
+    {
+        if (!hwnd && event->window == x11drv_thread_data()->clip_window) reset_clipping_window();
+        return;
+    }
+    if (!hwnd) return;
+    focus_out( event->display, hwnd );
 }
 
 
@@ -940,6 +948,37 @@ static BOOL is_net_wm_state_maximized( Display *display, struct x11drv_win_data
     return (ret == 2);
 }
 
+/***********************************************************************
+ *           reparent_notify
+ */
+static void reparent_notify( Display *display, HWND hwnd, Window xparent, int x, int y )
+{
+    HWND parent, old_parent;
+    DWORD style;
+
+    style = GetWindowLongW( hwnd, GWL_STYLE );
+    if (xparent == root_window)
+    {
+        parent = GetDesktopWindow();
+        style = (style & ~WS_CHILD) | WS_POPUP;
+    }
+    else
+    {
+        if (!(parent = create_foreign_window( display, xparent ))) return;
+        style = (style & ~WS_POPUP) | WS_CHILD;
+    }
+
+    ShowWindow( hwnd, SW_HIDE );
+    old_parent = SetParent( hwnd, parent );
+    SetWindowLongW( hwnd, GWL_STYLE, style );
+    SetWindowPos( hwnd, HWND_TOP, x, y, 0, 0,
+                  SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOCOPYBITS |
+                  ((style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0) );
+
+    /* make old parent destroy itself if it no longer has children */
+    if (old_parent != GetDesktopWindow()) PostMessageW( old_parent, WM_CLOSE, 0, 0 );
+}
+
 
 /***********************************************************************
  *           X11DRV_ReparentNotify
@@ -948,8 +987,6 @@ static void X11DRV_ReparentNotify( HWND hwnd, XEvent *xev )
 {
     XReparentEvent *event = &xev->xreparent;
     struct x11drv_win_data *data;
-    HWND parent, old_parent;
-    DWORD style;
 
     if (!(data = get_win_data( hwnd ))) return;
 
@@ -975,27 +1012,7 @@ static void X11DRV_ReparentNotify( HWND hwnd, XEvent *xev )
     TRACE( "%p/%lx reparented to %lx\n", hwnd, data->whole_window, event->parent );
     release_win_data( data );
 
-    style = GetWindowLongW( hwnd, GWL_STYLE );
-    if (event->parent == root_window)
-    {
-        parent = GetDesktopWindow();
-        style = (style & ~WS_CHILD) | WS_POPUP;
-    }
-    else
-    {
-        if (!(parent = create_foreign_window( event->display, event->parent ))) return;
-        style = (style & ~WS_POPUP) | WS_CHILD;
-    }
-
-    ShowWindow( hwnd, SW_HIDE );
-    old_parent = SetParent( hwnd, parent );
-    SetWindowLongW( hwnd, GWL_STYLE, style );
-    SetWindowPos( hwnd, HWND_TOP, event->x, event->y, 0, 0,
-                  SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOCOPYBITS |
-                  ((style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0) );
-
-    /* make old parent destroy itself if it no longer has children */
-    if (old_parent != GetDesktopWindow()) PostMessageW( old_parent, WM_CLOSE, 0, 0 );
+    reparent_notify( event->display, hwnd, event->parent, event->x, event->y );
 }
 
 
@@ -1594,22 +1611,54 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
  */
 static void handle_xembed_protocol( HWND hwnd, XClientMessageEvent *event )
 {
-    struct x11drv_win_data *data = 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];
+        {
+            struct x11drv_win_data *data = get_win_data( hwnd );
+            if (!data) break;
+
+            TRACE( "win %p/%lx XEMBED_EMBEDDED_NOTIFY owner %lx\n", hwnd, event->window, event->data.l[3] );
+            data->embedder = event->data.l[3];
+
+            /* window has been marked as embedded before (e.g. systray) */
+            if (data->embedded)
+            {
+                release_win_data( data );
+                break;
+            }
+
+            make_window_embedded( data );
+            release_win_data( data );
+            reparent_notify( event->display, hwnd, event->data.l[3], 0, 0 );
+        }
+        break;
+
+    case XEMBED_WINDOW_DEACTIVATE:
+        TRACE( "win %p/%lx XEMBED_WINDOW_DEACTIVATE message\n", hwnd, event->window );
+        focus_out( event->display, GetAncestor( hwnd, GA_ROOT ) );
+        break;
+
+    case XEMBED_FOCUS_OUT:
+        TRACE( "win %p/%lx XEMBED_FOCUS_OUT message\n", hwnd, event->window );
+        focus_out( event->display, GetAncestor( hwnd, GA_ROOT ) );
         break;
+
+    case XEMBED_MODALITY_ON:
+        TRACE( "win %p/%lx XEMBED_MODALITY_ON message\n", hwnd, event->window );
+        EnableWindow( hwnd, FALSE );
+        break;
+
+    case XEMBED_MODALITY_OFF:
+        TRACE( "win %p/%lx XEMBED_MODALITY_OFF message\n", hwnd, event->window );
+        EnableWindow( hwnd, TRUE );
+        break;
+
     default:
         TRACE( "win %p/%lx XEMBED message %lu(%lu)\n",
                hwnd, event->window, event->data.l[1], event->data.l[2] );
         break;
     }
-    release_win_data( data );
 }
 
 
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index a76e80d..e78f226 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -1137,7 +1137,7 @@ void make_window_embedded( struct x11drv_win_data *data )
     data->embedded = TRUE;
     data->managed = TRUE;
     sync_window_style( data );
-    set_xembed_flags( data, data->mapped ? XEMBED_MAPPED : 0 );
+    set_xembed_flags( data, (data->mapped || data->embedder) ? XEMBED_MAPPED : 0 );
 }
 
 




More information about the wine-cvs mailing list