winex11: Send XEMBED_REQUEST_FOCUS request for embedded windows.

This commit is contained in:
Sebastian Lackner 2013-11-13 16:59:38 +01:00 committed by Alexandre Julliard
parent 815f252b4a
commit 2e0ca3e746
1 changed files with 48 additions and 9 deletions

View File

@ -182,6 +182,31 @@ static inline void free_event_data( XEvent *event )
#endif #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);
XFlush( display );
}
/*********************************************************************** /***********************************************************************
* X11DRV_register_event_handler * X11DRV_register_event_handler
* *
@ -532,14 +557,14 @@ static inline BOOL can_activate_window( HWND hwnd )
/********************************************************************** /**********************************************************************
* set_input_focus * 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( struct x11drv_win_data *data )
{ {
XWindowChanges changes; XWindowChanges changes;
DWORD timestamp; DWORD timestamp;
if (!window) return; if (!data->whole_window) return;
if (EVENT_x11_time_to_win32_time(0)) if (EVENT_x11_time_to_win32_time(0))
/* ICCCM says don't use CurrentTime, so try to use last message time if possible */ /* ICCCM says don't use CurrentTime, so try to use last message time if possible */
@ -550,8 +575,13 @@ static void set_input_focus( Display *display, Window window )
/* Set X focus and install colormap */ /* Set X focus and install colormap */
changes.stack_mode = Above; changes.stack_mode = Above;
XConfigureWindow( display, window, CWStackMode, &changes ); XConfigureWindow( data->display, data->whole_window, CWStackMode, &changes );
XSetInputFocus( display, window, RevertToParent, timestamp );
if (data->embedder)
xembed_request_focus( data->display, data->embedder, timestamp );
else
XSetInputFocus( data->display, data->whole_window, RevertToParent, timestamp );
} }
/********************************************************************** /**********************************************************************
@ -904,7 +934,7 @@ static void X11DRV_MapNotify( HWND hwnd, XEvent *event )
{ {
HWND hwndFocus = GetFocus(); HWND hwndFocus = GetFocus();
if (hwndFocus && IsChild( hwnd, hwndFocus )) if (hwndFocus && IsChild( hwnd, hwndFocus ))
set_input_focus( data->display, data->whole_window ); set_input_focus( data );
} }
release_win_data( data ); release_win_data( data );
} }
@ -1365,9 +1395,18 @@ void CDECL X11DRV_SetFocus( HWND hwnd )
{ {
struct x11drv_win_data *data; struct x11drv_win_data *data;
if (!(hwnd = GetAncestor( hwnd, GA_ROOT ))) return; HWND parent;
if (!(data = get_win_data( hwnd ))) return;
if (!data->managed) set_input_focus( data->display, data->whole_window ); for (;;)
{
if (!(data = get_win_data( hwnd ))) return;
if (data->embedded) break;
parent = GetAncestor( hwnd, GA_PARENT );
if (!parent || parent == GetDesktopWindow()) break;
release_win_data( data );
hwnd = parent;
}
if (!data->managed || data->embedder) set_input_focus( data );
release_win_data( data ); release_win_data( data );
} }