mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
winex11: Implement additional XEMBED events.
This commit is contained in:
parent
ea24a5b1f4
commit
df6dc091e6
2 changed files with 98 additions and 49 deletions
|
@ -748,34 +748,22 @@ static void X11DRV_FocusIn( HWND hwnd, XEvent *xev )
|
||||||
else SetForegroundWindow( hwnd );
|
else SetForegroundWindow( hwnd );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* X11DRV_FocusOut
|
* focus_out
|
||||||
*
|
|
||||||
* Note: only top-level windows get FocusOut events.
|
|
||||||
*/
|
*/
|
||||||
static void X11DRV_FocusOut( HWND hwnd, XEvent *xev )
|
static void focus_out( Display *display , HWND hwnd )
|
||||||
{
|
{
|
||||||
XFocusChangeEvent *event = &xev->xfocus;
|
|
||||||
HWND hwnd_tmp;
|
HWND hwnd_tmp;
|
||||||
Window focus_win;
|
Window focus_win;
|
||||||
int revert;
|
int revert;
|
||||||
XIC xic;
|
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;
|
if (ximInComposeMode) return;
|
||||||
|
|
||||||
x11drv_thread_data()->last_focus = hwnd;
|
x11drv_thread_data()->last_focus = hwnd;
|
||||||
if ((xic = X11DRV_get_ic( hwnd ))) XUnsetICFocus( xic );
|
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();
|
if (hwnd == GetDesktopWindow()) reset_clipping_window();
|
||||||
return;
|
return;
|
||||||
|
@ -786,10 +774,10 @@ static void X11DRV_FocusOut( HWND hwnd, XEvent *xev )
|
||||||
/* don't reset the foreground window, if the window which is
|
/* don't reset the foreground window, if the window which is
|
||||||
getting the focus is a Wine window */
|
getting the focus is a Wine window */
|
||||||
|
|
||||||
XGetInputFocus( event->display, &focus_win, &revert );
|
XGetInputFocus( display, &focus_win, &revert );
|
||||||
if (focus_win)
|
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;
|
focus_win = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -805,6 +793,26 @@ static void X11DRV_FocusOut( HWND hwnd, XEvent *xev )
|
||||||
SetForegroundWindow( GetDesktopWindow() );
|
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);
|
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
|
* X11DRV_ReparentNotify
|
||||||
|
@ -948,8 +987,6 @@ static void X11DRV_ReparentNotify( HWND hwnd, XEvent *xev )
|
||||||
{
|
{
|
||||||
XReparentEvent *event = &xev->xreparent;
|
XReparentEvent *event = &xev->xreparent;
|
||||||
struct x11drv_win_data *data;
|
struct x11drv_win_data *data;
|
||||||
HWND parent, old_parent;
|
|
||||||
DWORD style;
|
|
||||||
|
|
||||||
if (!(data = get_win_data( hwnd ))) return;
|
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 );
|
TRACE( "%p/%lx reparented to %lx\n", hwnd, data->whole_window, event->parent );
|
||||||
release_win_data( data );
|
release_win_data( data );
|
||||||
|
|
||||||
style = GetWindowLongW( hwnd, GWL_STYLE );
|
reparent_notify( event->display, hwnd, event->parent, event->x, event->y );
|
||||||
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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1594,22 +1611,54 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
|
||||||
*/
|
*/
|
||||||
static void handle_xembed_protocol( 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])
|
switch (event->data.l[1])
|
||||||
{
|
{
|
||||||
case XEMBED_EMBEDDED_NOTIFY:
|
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;
|
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:
|
default:
|
||||||
TRACE( "win %p/%lx XEMBED message %lu(%lu)\n",
|
TRACE( "win %p/%lx XEMBED message %lu(%lu)\n",
|
||||||
hwnd, event->window, event->data.l[1], event->data.l[2] );
|
hwnd, event->window, event->data.l[1], event->data.l[2] );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
release_win_data( data );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1137,7 +1137,7 @@ void make_window_embedded( struct x11drv_win_data *data )
|
||||||
data->embedded = TRUE;
|
data->embedded = TRUE;
|
||||||
data->managed = TRUE;
|
data->managed = TRUE;
|
||||||
sync_window_style( data );
|
sync_window_style( data );
|
||||||
set_xembed_flags( data, data->mapped ? XEMBED_MAPPED : 0 );
|
set_xembed_flags( data, (data->mapped || data->embedder) ? XEMBED_MAPPED : 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue