[3/5] winex11: Send XEMBED_REQUEST_FOCUS request for embedded windows
Sebastian Lackner
sebastian at fds-team.de
Tue Sep 24 17:59:49 CDT 2013
---
dlls/winex11.drv/event.c | 73
++++++++++++++++++++++++++++++++-------------
dlls/winex11.drv/window.c | 16 ++++++++++
dlls/winex11.drv/x11drv.h | 1 +
3 files changed, 70 insertions(+), 20 deletions(-)
-------------- next part --------------
From cf58839244e15b487688c85f4b78aa81a6d2e713 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian at fds-team.de>
Date: Tue, 24 Sep 2013 20:35:38 +0200
Subject: winex11: Send XEMBED_REQUEST_FOCUS request for embedded windows
---
dlls/winex11.drv/event.c | 73 ++++++++++++++++++++++++++++++++-------------
dlls/winex11.drv/window.c | 16 ++++++++++
dlls/winex11.drv/x11drv.h | 1 +
3 files changed, 70 insertions(+), 20 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 4dcdd68..93892e5 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 );
}
/**********************************************************************
@@ -899,7 +936,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 );
}
@@ -1350,12 +1387,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_root_embedded( hwnd ))) return;
+ set_input_focus( hwnd );
}
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 1ff36eb..0c7b55f 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -1139,6 +1139,22 @@ void make_window_embedded( struct x11drv_win_data *data )
set_xembed_flags( data, data->mapped ? XEMBED_MAPPED : 0 );
}
+/***********************************************************************
+ * get_ancestor_root_embedded
+ */
+HWND get_ancestor_root_embedded( HWND hwnd )
+{
+ HWND parent;
+ if (!hwnd) return NULL;
+ for (;;)
+ {
+ parent = GetAncestor(hwnd, GA_PARENT);
+ if (!parent || parent == GetDesktopWindow() || (Window)GetPropA( parent, foreign_window_prop ))
+ 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 bfcea89..8920adc 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -585,6 +585,7 @@ 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 HWND get_ancestor_root_embedded( 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