[1/2] winex11: Send XEMBED_REQUEST_FOCUS request for embedded windows (try 5)
Sebastian Lackner
sebastian at fds-team.de
Wed Nov 13 11:17:03 CST 2013
Changelog:
- Check data->embedded flag instead of using GetPropA
- Removed previous patch number 3, will be added (in a modified form)
later as a separate patch (required for OpenGL content in embedded
windows, non-OpenGL-content also works without this one)
---
dlls/winex11.drv/event.c | 73
++++++++++++++++++++++++++++++++-------------
dlls/winex11.drv/window.c | 36 ++++++++++++++++++++++
dlls/winex11.drv/x11drv.h | 2 ++
3 files changed, 91 insertions(+), 20 deletions(-)
-------------- next part --------------
>From 3956155cdeae2461035e272881c0a860310e4d83 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian at fds-team.de>
Date: Wed, 13 Nov 2013 16:59:38 +0100
Subject: winex11: Send XEMBED_REQUEST_FOCUS request for embedded windows
---
dlls/winex11.drv/event.c | 73 ++++++++++++++++++++++++++++++++-------------
dlls/winex11.drv/window.c | 36 ++++++++++++++++++++++
dlls/winex11.drv/x11drv.h | 2 ++
3 files changed, 91 insertions(+), 20 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 64188bc..abe8ecd 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -182,6 +182,32 @@ static inline void free_event_data( XEvent *event )
#endif
}
+
+/***********************************************************************
+ * xembed_request_focus
+ */
+static 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
*
@@ -532,26 +558,37 @@ static inline BOOL can_activate_window( HWND hwnd )
/**********************************************************************
* set_input_focus
*
- * Try to force focus for non-managed windows.
+ * Try to force focus for embedded or 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 (!(data = get_win_data( hwnd ))) return;
- if (!window) return;
+ 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;
+ 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( display, window, CWStackMode, &changes );
- XSetInputFocus( display, window, RevertToParent, timestamp );
+ /* 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 );
+
+ }
+
+ release_win_data( data );
}
/**********************************************************************
@@ -904,7 +941,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 );
}
@@ -1363,12 +1400,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 );
+ if (!(hwnd = get_ancestor_input_root( hwnd ))) return;
+ set_input_focus( hwnd );
}
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index e78f226..713d843 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -1140,6 +1140,42 @@ void make_window_embedded( struct x11drv_win_data *data )
set_xembed_flags( data, (data->mapped || data->embedder) ? XEMBED_MAPPED : 0 );
}
+/***********************************************************************
+ * is_window_embedded
+ */
+BOOL is_window_embedded( HWND hwnd )
+{
+ struct x11drv_win_data *data;
+ BOOL is_embedded = FALSE;
+
+ if ((data = get_win_data( hwnd )))
+ {
+ is_embedded = data->embedded;
+ release_win_data(data);
+ }
+
+ return is_embedded;
+}
+
+/***********************************************************************
+ * get_ancestor_input_root
+ */
+HWND get_ancestor_input_root( HWND hwnd )
+{
+ HWND parent;
+
+ if (!hwnd) return NULL;
+ for (;;)
+ {
+ if (is_window_embedded(hwnd))
+ break;
+ parent = GetAncestor(hwnd, GA_PARENT);
+ if (!parent || parent == GetDesktopWindow())
+ break;
+ hwnd = parent;
+ }
+ return hwnd;
+}
/***********************************************************************
* X11DRV_window_to_X_rect
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 98386ce..f048cb4 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -582,6 +582,8 @@ extern Window init_clip_window(void) DECLSPEC_HIDDEN;
extern void update_user_time( Time time ) DECLSPEC_HIDDEN;
extern void update_net_wm_states( struct x11drv_win_data *data ) DECLSPEC_HIDDEN;
extern void make_window_embedded( struct x11drv_win_data *data ) DECLSPEC_HIDDEN;
+extern BOOL is_window_embedded( HWND hwnd ) DECLSPEC_HIDDEN;
+extern HWND get_ancestor_input_root( HWND hwnd ) DECLSPEC_HIDDEN;
extern Window create_client_window( struct x11drv_win_data *data, const XVisualInfo *visual ) DECLSPEC_HIDDEN;
extern void set_window_visual( struct x11drv_win_data *data, const XVisualInfo *vis ) DECLSPEC_HIDDEN;
extern void change_systray_owner( Display *display, Window systray_window ) DECLSPEC_HIDDEN;
--
1.7.9.5
More information about the wine-patches
mailing list