From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 28 ++++++++++++++++++++++++++++ dlls/winex11.drv/window.c | 16 ++++++++++++++++ dlls/winex11.drv/x11drv.h | 8 +++++++- dlls/winex11.drv/x11drv_main.c | 1 + 4 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 428dcb7b8b7..977a11a989b 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1204,6 +1204,23 @@ static int get_window_xembed_info( Display *display, Window window ) return ret; }
+static Window get_net_active_window( Display *display ) +{ + unsigned long count, remaining; + Window window = None, *value; + int format; + Atom type; + + if (!XGetWindowProperty( display, DefaultRootWindow( display ), x11drv_atom(_NET_ACTIVE_WINDOW), 0, + 65536 / sizeof(Window), False, XA_WINDOW, &type, &format, &count, + &remaining, (unsigned char **)&value )) + { + if (type == XA_WINDOW && format == 32) window = *value; + XFree( value ); + } + + return window; +}
/*********************************************************************** * handle_wm_state_notify @@ -1262,6 +1279,16 @@ static void handle_net_supported_notify( XPropertyEvent *event ) if (event->state == PropertyNewValue) net_supported_init( data ); }
+static void handle_net_active_window( HWND hwnd, XPropertyEvent *event ) +{ + Window window = None; + + if (event->state == PropertyNewValue) window = get_net_active_window( event->display ); + net_active_window_notify( event->serial, window, event->time ); + + NtUserPostMessage( hwnd, WM_WINE_WINDOW_STATE_CHANGED, 0, 0 ); +} + /*********************************************************************** * X11DRV_PropertyNotify */ @@ -1274,6 +1301,7 @@ static BOOL X11DRV_PropertyNotify( HWND hwnd, XEvent *xev ) if (event->atom == x11drv_atom(_XEMBED_INFO)) handle_xembed_info_notify( hwnd, event ); if (event->atom == x11drv_atom(_NET_WM_STATE)) handle_net_wm_state_notify( hwnd, event ); if (event->atom == x11drv_atom(_NET_SUPPORTED)) handle_net_supported_notify( event ); + if (event->atom == x11drv_atom(_NET_ACTIVE_WINDOW)) handle_net_active_window( hwnd, event );
return TRUE; } diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 428c7108c98..6a400b24f03 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1735,6 +1735,22 @@ void window_configure_notify( struct x11drv_win_data *data, unsigned long serial current, expected, prefix, received, NULL ); }
+void net_active_window_notify( unsigned long serial, Window value, Time time ) +{ + struct x11drv_thread_data *data = x11drv_thread_data(); + Window *desired = &data->desired_net_active_window, *pending = &data->pending_net_active_window, *current = &data->current_net_active_window; + unsigned long *expect_serial = &data->net_active_window_serial; + const char *expected, *received; + + received = wine_dbg_sprintf( "_NET_ACTIVE_WINDOW %lx/%lu", value, serial ); + expected = *expect_serial ? wine_dbg_sprintf( ", expected %lx/%lu", *pending, *expect_serial ) : ""; + if (!handle_state_change( serial, expect_serial, sizeof(value), &value, desired, pending, + current, expected, "", received, NULL )) + return; + + TRACE( "_NET_ACTIVE_WINDOW changed to %lx\n", value ); +} + BOOL window_has_pending_wm_state( HWND hwnd, UINT state ) { struct x11drv_win_data *data; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 8e383ae4c48..029648837cb 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -403,6 +403,11 @@ struct x11drv_thread_data XIValuatorClassInfo y_valuator; int xinput2_pointer; /* XInput2 master pointer device id */ #endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */ + + Window desired_net_active_window; /* active window tracking the desired / win32 state */ + Window pending_net_active_window; /* active window tracking the pending / requested state */ + Window current_net_active_window; /* active window tracking the current X11 state */ + unsigned long net_active_window_serial; /* serial of last pending _NET_ACTIVE_WINDOW request */ };
extern struct x11drv_thread_data *x11drv_init_thread_data(void); @@ -485,6 +490,7 @@ enum x11drv_atoms XATOM__ICC_PROFILE, XATOM__KDE_NET_WM_STATE_SKIP_SWITCHER, XATOM__MOTIF_WM_HINTS, + XATOM__NET_ACTIVE_WINDOW, XATOM__NET_STARTUP_INFO_BEGIN, XATOM__NET_STARTUP_INFO, XATOM__NET_SUPPORTED, @@ -666,8 +672,8 @@ extern BOOL window_has_pending_wm_state( HWND hwnd, UINT state ); extern void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value ); extern void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value ); extern void window_configure_notify( struct x11drv_win_data *data, unsigned long serial, const RECT *rect ); -extern BOOL get_window_state_updates( HWND hwnd, UINT *state_cmd, UINT *config_cmd, RECT *rect );
+extern void net_active_window_notify( unsigned long serial, Window window, Time time ); extern void net_supported_init( struct x11drv_thread_data *data );
extern Window init_clip_window(void); diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index e58d3afca63..179cdfab5da 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -126,6 +126,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] = "_ICC_PROFILE", "_KDE_NET_WM_STATE_SKIP_SWITCHER", "_MOTIF_WM_HINTS", + "_NET_ACTIVE_WINDOW", "_NET_STARTUP_INFO_BEGIN", "_NET_STARTUP_INFO", "_NET_SUPPORTED",