USER_REFERENCE_ENTRY Ref, RefPrev;
PWND Window, WindowPrev = NULL;
HANDLE OldTID, NewTID;
+ PTHREADINFO ptiOld, ptiNew;
if ((Window = UserGetWindowObject(hWnd)))
{
OldTID = WindowPrev ? IntGetWndThreadId(WindowPrev) : NULL;
NewTID = Window ? IntGetWndThreadId(Window) : NULL;
+ ptiOld = WindowPrev ? WindowPrev->head.pti : NULL;
+ ptiNew = Window ? Window->head.pti : NULL;
TRACE("SendActiveMessage Old -> %x, New -> %x\n", OldTID, NewTID);
HWND *List, *phWnd;
List = IntWinListChildren(UserGetWindowObject(IntGetDesktopWindow()));
- if (List)
+ if ( List )
{
- if (OldTID)
+ if ( OldTID )
{
for (phWnd = List; *phWnd; ++phWnd)
{
cWindow = UserGetWindowObject(*phWnd);
-
- if (cWindow && (IntGetWndThreadId(cWindow) == OldTID))
+ if (cWindow && cWindow->head.pti == ptiOld)
{ // FALSE if the window is being deactivated,
// ThreadId that owns the window being activated.
co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID);
}
}
}
- if (NewTID)
+ if ( NewTID )
{
for (phWnd = List; *phWnd; ++phWnd)
{
cWindow = UserGetWindowObject(*phWnd);
- if (cWindow && (IntGetWndThreadId(cWindow) == NewTID))
+ if (cWindow && cWindow->head.pti == ptiNew)
{ // TRUE if the window is being activated,
// ThreadId that owns the window being deactivated.
co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, TRUE, (LPARAM)OldTID);
return NULL;
}
+VOID FASTCALL
+FindRemoveAsyncMsg(PWND Wnd)
+{
+ PUSER_MESSAGE_QUEUE MessageQueue;
+ PUSER_SENT_MESSAGE Message;
+ PLIST_ENTRY Entry;
+
+ if (!Wnd) return;
+
+ MessageQueue = Wnd->head.pti->MessageQueue;
+
+ if (!IsListEmpty(&MessageQueue->SentMessagesListHead))
+ {
+ // Scan sent queue messages to see if we received async messages.
+ Entry = MessageQueue->SentMessagesListHead.Flink;
+ Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
+ do
+ {
+ if (Message->Msg.message == WM_ASYNC_SETACTIVEWINDOW &&
+ Message->Msg.hwnd == UserHMGetHandle(Wnd) &&
+ Message->Msg.wParam == 0 )
+ {
+ TRACE("ASYNC SAW: Found one in the Sent Msg Queue! %p\n", Message->Msg.hwnd);
+ RemoveEntryList(Entry); // Purge the entry.
+ }
+ Entry = Message->ListEntry.Flink;
+ Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
+ }
+ while (Entry != &MessageQueue->SentMessagesListHead);
+ }
+}
+
/*
Can the system force foreground from one or more conditions.
*/
{
IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue);
gptiForeground = Wnd->head.pti;
+/*
+ Henri Verbeet,
+ What happens is that we get the WM_WINE_SETACTIVEWINDOW message sent by the
+ other thread after we already changed the foreground window back to our own
+ window.
+ */
+ FindRemoveAsyncMsg(Wnd); // Do this to fix test_SFW todos!
fgRet = TRUE;
- }
+ }
-//// Fix FG Bounce with regedit but breaks test_SFW todos
+ // Fix FG Bounce with regedit.
if (hWndPrev != hWnd )
{
if (PrevForegroundQueue &&
Wnd->head.pti->MessageQueue != PrevForegroundQueue &&
PrevForegroundQueue->spwndActive)
{
+ //ERR("SFGW: Send NULL to 0x%x\n",hWndPrev);
+ if (pti->MessageQueue == PrevForegroundQueue)
+ {
+ //ERR("SFGW: TI same as Prev TI\n");
+ co_IntSetActiveWindow(NULL, NULL, FALSE, TRUE);
+ }
+ else
co_IntSendMessageNoWait(hWndPrev, WM_ASYNC_SETACTIVEWINDOW, 0, 0 );
}
}
}
}
+ // Check again! SetActiveWindow could have set the focus via WM_ACTIVATE.
+ hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
+
/* check if the specified window can be set in the input data of a given queue */
- if ( !Window || ThreadQueue == Window->head.pti->MessageQueue)
+ if (ThreadQueue == Window->head.pti->MessageQueue)
/* set the current thread focus window */
ThreadQueue->spwndFocus = Window;