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;
}