From: Jactry Zeng Subject: [2/2 v3] winex11.drv: Implement FlashWindow with _NET_WM_STATE_DEMANDS_ATTENTION. Message-Id: <560B950A.9050500@codeweavers.com> Date: Wed, 30 Sep 2015 15:53:46 +0800 Superseded patch 114559. Thanks Dmitry for help! ChangeLog: v3: - Use x11drv_atom instead of XInternAtom; - Only do XSendEvent() when data->mapped is true. v2: - Use _NET_WM_STATE_DEMANDS_ATTENTION instead of Urgency. Signed-off-by: Jactry Zeng --- dlls/user32/driver.c | 16 ++++++++++++++-- dlls/user32/user_private.h | 1 + dlls/user32/win.c | 1 + dlls/winex11.drv/window.c | 29 +++++++++++++++++++++++++++++ dlls/winex11.drv/winex11.drv.spec | 1 + dlls/winex11.drv/x11drv.h | 1 + dlls/winex11.drv/x11drv_main.c | 1 + 7 files changed, 48 insertions(+), 2 deletions(-) diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c index ced8836..5ae292e 100644 --- a/dlls/user32/driver.c +++ b/dlls/user32/driver.c @@ -153,6 +153,7 @@ static const USER_DRIVER *load_driver(void) GET_USER_FUNC(WindowPosChanging); GET_USER_FUNC(WindowPosChanged); GET_USER_FUNC(SystemParametersInfo); + GET_USER_FUNC(FlashWindow); #undef GET_USER_FUNC } @@ -506,6 +507,10 @@ static BOOL CDECL nulldrv_SystemParametersInfo( UINT action, UINT int_param, voi return FALSE; } +static void CDECL nulldrv_FlashWindow( HWND hWnd, BOOL bInvert ) +{ +} + static USER_DRIVER null_driver = { /* keyboard functions */ @@ -565,7 +570,8 @@ static USER_DRIVER null_driver = nulldrv_WindowPosChanging, nulldrv_WindowPosChanged, /* system parameters */ - nulldrv_SystemParametersInfo + nulldrv_SystemParametersInfo, + nulldrv_FlashWindow }; @@ -755,6 +761,11 @@ static BOOL CDECL loaderdrv_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDW return load_driver()->pUpdateLayeredWindow( hwnd, info, window_rect ); } +static void CDECL loaderdrv_FlashWindow( HWND hWnd, BOOL bInvert ) +{ + load_driver()->pFlashWindow( hWnd, bInvert ); +} + static USER_DRIVER lazy_load_driver = { /* keyboard functions */ @@ -814,5 +825,6 @@ static USER_DRIVER lazy_load_driver = nulldrv_WindowPosChanging, nulldrv_WindowPosChanged, /* system parameters */ - nulldrv_SystemParametersInfo + nulldrv_SystemParametersInfo, + loaderdrv_FlashWindow }; diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index d3affb0..1f9bf7c 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -116,6 +116,7 @@ typedef struct tagUSER_DRIVER { void (CDECL *pWindowPosChanged)(HWND,HWND,UINT,const RECT *,const RECT *,const RECT *,const RECT *,struct window_surface*); /* system parameters */ BOOL (CDECL *pSystemParametersInfo)(UINT,UINT,void*,UINT); + void (CDECL *pFlashWindow)(HWND, BOOL); } USER_DRIVER; extern const USER_DRIVER *USER_Driver DECLSPEC_HIDDEN; diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 523d640..d6446e2 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -3432,6 +3432,7 @@ BOOL WINAPI FlashWindow( HWND hWnd, BOOL bInvert ) wndPtr->flags &= ~WIN_NCACTIVATED; } WIN_ReleasePtr( wndPtr ); + USER_Driver->pFlashWindow( hWnd, bInvert ); return TRUE; } else diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index b7ec06e..ed3f270 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2767,3 +2767,32 @@ failed: release_win_data( data ); return -1; } + +void X11DRV_FlashWindow( HWND hwnd, BOOL bInvert ) +{ + struct x11drv_win_data *data = get_win_data( hwnd ); + XEvent xev; + + if (!data) + return; + + if (data->mapped) + { + xev.type = ClientMessage; + xev.xclient.window = data->whole_window; + xev.xclient.message_type = x11drv_atom( _NET_WM_STATE ); + xev.xclient.serial = 0; + xev.xclient.display = data->display; + xev.xclient.send_event = True; + xev.xclient.format = 32; + xev.xclient.data.l[0] = _NET_WM_STATE_ADD; + xev.xclient.data.l[1] = x11drv_atom( _NET_WM_STATE_DEMANDS_ATTENTION ); + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 1; + xev.xclient.data.l[4] = 0; + + XSendEvent( data->display, DefaultRootWindow( data->display ), False, + SubstructureNotifyMask, &xev ); + } + release_win_data( data ); +} diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec index d9bbebc..f5d0f0d 100644 --- a/dlls/winex11.drv/winex11.drv.spec +++ b/dlls/winex11.drv/winex11.drv.spec @@ -52,6 +52,7 @@ @ cdecl WindowPosChanging(long long long ptr ptr ptr ptr) X11DRV_WindowPosChanging @ cdecl WindowPosChanged(long long long ptr ptr ptr ptr ptr) X11DRV_WindowPosChanged @ cdecl SystemParametersInfo(long long ptr long) X11DRV_SystemParametersInfo +@ cdecl FlashWindow(long long) X11DRV_FlashWindow # WinTab32 @ cdecl AttachEventQueueToTablet(long) X11DRV_AttachEventQueueToTablet diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index cb4b0bb..2694d23 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -421,6 +421,7 @@ enum x11drv_atoms XATOM__NET_WM_PING, XATOM__NET_WM_STATE, XATOM__NET_WM_STATE_ABOVE, + XATOM__NET_WM_STATE_DEMANDS_ATTENTION, XATOM__NET_WM_STATE_FULLSCREEN, XATOM__NET_WM_STATE_MAXIMIZED_HORZ, XATOM__NET_WM_STATE_MAXIMIZED_VERT, diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 85c69bf..d4f5c84 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -138,6 +138,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] = "_NET_WM_PING", "_NET_WM_STATE", "_NET_WM_STATE_ABOVE", + "_NET_WM_STATE_DEMANDS_ATTENTION", "_NET_WM_STATE_FULLSCREEN", "_NET_WM_STATE_MAXIMIZED_HORZ", "_NET_WM_STATE_MAXIMIZED_VERT",