[2/3] winex11: Send XEMBED_REQUEST_FOCUS request for embedded windows

Sebastian Lackner sebastian at fds-team.de
Mon Sep 23 12:40:03 CDT 2013


---
 dlls/winex11.drv/event.c |   79
+++++++++++++++++++++++++++++++++++-----------
 1 file changed, 60 insertions(+), 19 deletions(-)




-------------- next part --------------
From fa69c9c5fb33f533efa49d8f23e1e0446caf2b3c Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian at fds-team.de>
Date: Sun, 22 Sep 2013 02:29:14 +0200
Subject: winex11: Send XEMBED_REQUEST_FOCUS request for embedded windows

---
 dlls/winex11.drv/event.c |   79 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 60 insertions(+), 19 deletions(-)

diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 0942ae7..cf7a914 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -182,6 +182,31 @@ static inline void free_event_data( XEvent *event )
 #endif
 }
 
+
+/***********************************************************************
+ *           xembed_request_focus
+ */
+void xembed_request_focus(Display *display, Window window, DWORD timestamp){
+    XEvent xev;
+
+    xev.xclient.type = ClientMessage;
+    xev.xclient.window = window;
+    xev.xclient.message_type = x11drv_atom(_XEMBED);
+    xev.xclient.serial = 0;
+    xev.xclient.display = display;
+    xev.xclient.send_event = True;
+    xev.xclient.format = 32;
+
+    xev.xclient.data.l[0] = timestamp;
+    xev.xclient.data.l[1] = XEMBED_REQUEST_FOCUS;
+    xev.xclient.data.l[2] = 0;
+    xev.xclient.data.l[3] = 0;
+    xev.xclient.data.l[4] = 0;
+
+    XSendEvent(display, window, False, NoEventMask, &xev);
+    XSync(display, False);
+}
+
 /***********************************************************************
  *           X11DRV_register_event_handler
  *
@@ -534,24 +559,36 @@ static inline BOOL can_activate_window( HWND hwnd )
  *
  * Try to force focus for non-managed windows.
  */
-static void set_input_focus( Display *display, Window window )
+static void set_input_focus( HWND hwnd )
 {
     XWindowChanges changes;
     DWORD timestamp;
+    struct x11drv_win_data *data;
 
-    if (!window) return;
+    if (!(data = get_win_data( hwnd ))) return;
 
-    if (EVENT_x11_time_to_win32_time(0))
-        /* ICCCM says don't use CurrentTime, so try to use last message time if possible */
-        /* FIXME: this is not entirely correct */
-        timestamp = GetMessageTime() - EVENT_x11_time_to_win32_time(0);
-    else
-        timestamp = CurrentTime;
+    if (data->whole_window && (data->embedder || !data->managed))
+    {
+
+        if (EVENT_x11_time_to_win32_time(0))
+            /* ICCCM says don't use CurrentTime, so try to use last message time if possible */
+            /* FIXME: this is not entirely correct */
+            timestamp = GetMessageTime() - EVENT_x11_time_to_win32_time(0);
+        else
+            timestamp = CurrentTime;
+
+        /* Set X focus and install colormap */
+        changes.stack_mode = Above;
+        XConfigureWindow( data->display, data->whole_window, CWStackMode, &changes );
+
+        if (data->embedder)
+            xembed_request_focus( data->display, data->embedder, timestamp );
+        else
+            XSetInputFocus( data->display, data->whole_window, RevertToParent, timestamp );
+
+    }
 
-    /* Set X focus and install colormap */
-    changes.stack_mode = Above;
-    XConfigureWindow( display, window, CWStackMode, &changes );
-    XSetInputFocus( display, window, RevertToParent, timestamp );
+    release_win_data( data );
 }
 
 /**********************************************************************
@@ -562,6 +599,7 @@ static void set_focus( Display *display, HWND hwnd, Time time )
     HWND focus;
     Window win;
     GUITHREADINFO threadinfo;
+    struct x11drv_win_data *data;
 
     TRACE( "setting foreground window to %p\n", hwnd );
     SetForegroundWindow( hwnd );
@@ -576,7 +614,14 @@ static void set_focus( Display *display, HWND hwnd, Time time )
     if (win)
     {
         TRACE( "setting focus to %p (%lx) time=%ld\n", focus, win, time );
-        XSetInputFocus( display, win, RevertToParent, time );
+        data = get_win_data( hwnd );
+
+        if (data && data->embedder)
+            xembed_request_focus( display, data->embedder, time );
+        else
+            XSetInputFocus( display, win, RevertToParent, time );
+
+        release_win_data( data );
     }
 }
 
@@ -899,7 +944,7 @@ static void X11DRV_MapNotify( HWND hwnd, XEvent *event )
     {
         HWND hwndFocus = GetFocus();
         if (hwndFocus && IsChild( hwnd, hwndFocus ))
-            set_input_focus( data->display, data->whole_window );
+            set_input_focus( hwnd );
     }
     release_win_data( data );
 }
@@ -1341,12 +1386,8 @@ void wait_for_withdrawn_state( HWND hwnd, BOOL set )
  */
 void CDECL X11DRV_SetFocus( HWND hwnd )
 {
-    struct x11drv_win_data *data;
-
     if (!(hwnd = GetAncestor( hwnd, GA_ROOT ))) return;
-    if (!(data = get_win_data( hwnd ))) return;
-    if (!data->managed) set_input_focus( data->display, data->whole_window );
-    release_win_data( data );
+    set_input_focus( hwnd );
 }
 
 
-- 
1.7.9.5


More information about the wine-patches mailing list