Better implementation of [GS]etForegroundWindow. Fixed focus handling on inter-thread activation. Adapted FocusIn/Out event handling to per-queue focus.
diff --git a/windows/winpos.c b/windows/winpos.c index 11d365e..5954f18 100644 --- a/windows/winpos.c +++ b/windows/winpos.c
@@ -899,17 +899,27 @@ */ HWND WINAPI GetForegroundWindow(void) { - return GetActiveWindow(); -} + HWND hwndActive = 0; + /* Get the foreground window (active window of hActiveQueue) */ + if ( hActiveQueue ) + { + MESSAGEQUEUE *pActiveQueue = QUEUE_Lock( hActiveQueue ); + if ( pActiveQueue ) + hwndActive = PERQDATA_GetActiveWnd( pActiveQueue->pQData ); + + QUEUE_Unlock( pActiveQueue ); + } + + return hwndActive; +} /******************************************************************* * SetForegroundWindow (USER32.482) */ BOOL WINAPI SetForegroundWindow( HWND hwnd ) { - SetActiveWindow( hwnd ); - return TRUE; + return WINPOS_ChangeActiveWindow( hwnd, FALSE ); } @@ -1643,6 +1653,8 @@ HWND hwndActive = 0; BOOL bRet = 0; + TRACE( win, "(%04x, %d, %d)\n", hWnd, fMouse, fChangeFocus ); + /* Get current active window from the active queue */ if ( hActiveQueue ) { @@ -1784,7 +1796,7 @@ } WIN_ReleaseDesktop(); - if (!IsWindow(hWnd)) goto CLEANUP; + if (hWnd && !IsWindow(hWnd)) goto CLEANUP; } if (hWnd) @@ -1808,13 +1820,27 @@ } /* change focus if possible */ - if( fChangeFocus && GetFocus() ) - if( WIN_GetTopParent(GetFocus()) != hwndActive ) - FOCUS_SwitchFocus( pNewActiveQueue, GetFocus(), - (wndPtr && (wndPtr->dwStyle & WS_MINIMIZE))? - 0: - hwndActive - ); + if ( fChangeFocus ) + { + if ( pNewActiveQueue ) + { + HWND hOldFocus = PERQDATA_GetFocusWnd( pNewActiveQueue->pQData ); + + if ( WIN_GetTopParent( hOldFocus ) != hwndActive ) + FOCUS_SwitchFocus( pNewActiveQueue, hOldFocus, + (wndPtr && (wndPtr->dwStyle & WS_MINIMIZE))? + 0 : hwndActive ); + } + + if ( pOldActiveQueue && + ( !pNewActiveQueue || + pNewActiveQueue->pQData != pOldActiveQueue->pQData ) ) + { + HWND hOldFocus = PERQDATA_GetFocusWnd( pOldActiveQueue->pQData ); + if ( hOldFocus ) + FOCUS_SwitchFocus( pOldActiveQueue, hOldFocus, 0 ); + } + } if( !hwndPrevActive && wndPtr ) (*wndPtr->pDriver->pForceWindowRaise)(wndPtr);
diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c index 15bed2a..bde0155 100644 --- a/windows/x11drv/event.c +++ b/windows/x11drv/event.c
@@ -660,18 +660,12 @@ */ static void EVENT_FocusIn( HWND hWnd, XFocusChangeEvent *event ) { - if (Options.managed) EVENT_QueryZOrder( hWnd ); - - if (event->detail != NotifyPointer) - { - if (hWnd != GetActiveWindow()) + if (event->detail != NotifyPointer) + if (hWnd != GetForegroundWindow()) { - WINPOS_ChangeActiveWindow( hWnd, FALSE ); - X11DRV_KEYBOARD_UpdateState(); + SetForegroundWindow( hWnd ); + X11DRV_KEYBOARD_UpdateState(); } - if ((hWnd != GetFocus()) && !IsChild( hWnd, GetFocus())) - SetFocus( hWnd ); - } } @@ -683,15 +677,11 @@ static void EVENT_FocusOut( HWND hWnd, XFocusChangeEvent *event ) { if (event->detail != NotifyPointer) - { - if (hWnd == GetActiveWindow()) + if (hWnd == GetForegroundWindow()) { SendMessageA( hWnd, WM_CANCELMODE, 0, 0 ); - WINPOS_ChangeActiveWindow( 0, FALSE ); + SetForegroundWindow( 0 ); } - if ((hWnd == GetFocus()) || IsChild( hWnd, GetFocus())) - SetFocus( 0 ); - } } /********************************************************************** @@ -699,13 +689,13 @@ */ BOOL X11DRV_EVENT_CheckFocus(void) { - WND* pWnd; + HWND hWnd; Window xW; int state; TSXGetInputFocus(display, &xW, &state); if( xW == None || - TSXFindContext(display, xW, winContext, (char **)&pWnd) ) + TSXFindContext(display, xW, winContext, (char **)&hWnd) ) return FALSE; return TRUE; }