From: Jactry Zeng Subject: [2/2 v4 resend] winex11.drv: Implement FlashWindowEx. Message-Id: <560F4DED.5040903@codeweavers.com> Date: Sat, 3 Oct 2015 11:39:25 +0800 Superseded patch 114739. ChangeLog: v4: - Rename driver entry to FlashWindowEx; - Put FlashWindowEx/pFlashWindowEx in right place; - Add CDECL for X11DRV_FlashWindowEx. 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 | 12 ++++++++++++ dlls/user32/user_private.h | 1 + dlls/user32/win.c | 9 +++++++++ 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, 54 insertions(+) diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c index ced8836..e527213 100644 --- a/dlls/user32/driver.c +++ b/dlls/user32/driver.c @@ -134,6 +134,7 @@ static const USER_DRIVER *load_driver(void) GET_USER_FUNC(CreateDesktopWindow); GET_USER_FUNC(CreateWindow); GET_USER_FUNC(DestroyWindow); + GET_USER_FUNC(FlashWindowEx); GET_USER_FUNC(GetDC); GET_USER_FUNC(MsgWaitForMultipleObjectsEx); GET_USER_FUNC(ReleaseDC); @@ -410,6 +411,10 @@ static void CDECL nulldrv_DestroyWindow( HWND hwnd ) { } +static void CDECL nulldrv_FlashWindowEx( PFLASHWINFO pfinfo ) +{ +} + static void CDECL nulldrv_GetDC( HDC hdc, HWND hwnd, HWND top_win, const RECT *win_rect, const RECT *top_rect, DWORD flags ) { @@ -546,6 +551,7 @@ static USER_DRIVER null_driver = nulldrv_CreateDesktopWindow, nulldrv_CreateWindow, nulldrv_DestroyWindow, + nulldrv_FlashWindowEx, nulldrv_GetDC, nulldrv_MsgWaitForMultipleObjectsEx, nulldrv_ReleaseDC, @@ -733,6 +739,11 @@ static BOOL CDECL loaderdrv_CreateWindow( HWND hwnd ) return load_driver()->pCreateWindow( hwnd ); } +static void CDECL loaderdrv_FlashWindowEx( PFLASHWINFO pfinfo ) +{ + load_driver()->pFlashWindowEx( pfinfo ); +} + static void CDECL loaderdrv_GetDC( HDC hdc, HWND hwnd, HWND top_win, const RECT *win_rect, const RECT *top_rect, DWORD flags ) { @@ -795,6 +806,7 @@ static USER_DRIVER lazy_load_driver = loaderdrv_CreateDesktopWindow, loaderdrv_CreateWindow, nulldrv_DestroyWindow, + loaderdrv_FlashWindowEx, loaderdrv_GetDC, nulldrv_MsgWaitForMultipleObjectsEx, nulldrv_ReleaseDC, diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index d3affb0..273f303 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -96,6 +96,7 @@ typedef struct tagUSER_DRIVER { BOOL (CDECL *pCreateDesktopWindow)(HWND); BOOL (CDECL *pCreateWindow)(HWND); void (CDECL *pDestroyWindow)(HWND); + void (CDECL *pFlashWindowEx)( PFLASHWINFO ); void (CDECL *pGetDC)(HDC,HWND,HWND,const RECT *,const RECT *,DWORD); DWORD (CDECL *pMsgWaitForMultipleObjectsEx)(DWORD,const HANDLE*,DWORD,DWORD,DWORD); void (CDECL *pReleaseDC)(HWND,HDC); diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 530c5f0..b07f632 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -3414,9 +3414,16 @@ BOOL WINAPI AnyPopup(void) BOOL WINAPI FlashWindow( HWND hWnd, BOOL bInvert ) { WND *wndPtr; + FLASHWINFO finfo; TRACE("%p\n", hWnd); + finfo.cbSize = sizeof(FLASHWINFO); + finfo.dwFlags = bInvert ? FLASHW_ALL : FLASHW_STOP; + finfo.uCount = 1; + finfo.dwTimeout = 0; + finfo.hwnd = hWnd; + if (IsIconic( hWnd )) { RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_FRAME ); @@ -3432,6 +3439,7 @@ BOOL WINAPI FlashWindow( HWND hWnd, BOOL bInvert ) wndPtr->flags &= ~WIN_NCACTIVATED; } WIN_ReleasePtr( wndPtr ); + USER_Driver->pFlashWindowEx( &finfo ); return TRUE; } else @@ -3447,6 +3455,7 @@ BOOL WINAPI FlashWindow( HWND hWnd, BOOL bInvert ) WIN_ReleasePtr( wndPtr ); SendMessageW( hWnd, WM_NCACTIVATE, wparam, 0 ); + USER_Driver->pFlashWindowEx( &finfo ); return wparam; } } diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index b7ec06e..b763677 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 CDECL X11DRV_FlashWindowEx( PFLASHWINFO pfinfo ) +{ + struct x11drv_win_data *data = get_win_data( pfinfo->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] = pfinfo->dwFlags ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + 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..182b351 100644 --- a/dlls/winex11.drv/winex11.drv.spec +++ b/dlls/winex11.drv/winex11.drv.spec @@ -30,6 +30,7 @@ @ cdecl EmptyClipboard() X11DRV_EmptyClipboard @ cdecl EndClipboardUpdate() X11DRV_EndClipboardUpdate @ cdecl EnumClipboardFormats(long) X11DRV_EnumClipboardFormats +@ cdecl FlashWindowEx(ptr) X11DRV_FlashWindowEx @ cdecl GetClipboardData(long) X11DRV_GetClipboardData @ cdecl GetDC(long long long ptr ptr long) X11DRV_GetDC @ cdecl IsClipboardFormatAvailable(long) X11DRV_IsClipboardFormatAvailable 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",