[0.4.9][WIN32K:NTUSER] Properly fix IntSendChildNCPaint() & IntLinkWindow()

Hack has been introduced in IntSendChildNCPaint() in r73532 == 6d7fcc4
to attempt to pseudo-fix CORE-12071 and CORE-12085 while breaking other stuff,
amongst which CORE-14763 is one of the latest manifestations, and re-enable the correct original code.

This fixes painting hangs under diverse situations,
while CORE-12071 and CORE-12085 remain fixed.

When it was hanging like CORE-14763, we could not even ACPI shutdown anymore.

by porting back:
0.4.10-dev-324-g 25004bb5b4
0.4.10-dev-323-g ee0511b49d
0.4.10-dev-322-g 4d057cf626
This commit is contained in:
Joachim Henze 2020-12-23 02:21:19 +01:00
parent 1c107f80cf
commit 743f12cdc8
3 changed files with 63 additions and 70 deletions

View file

@ -366,38 +366,16 @@ IntSendNCPaint(PWND pWnd, HRGN hRgn)
VOID FASTCALL VOID FASTCALL
IntSendChildNCPaint(PWND pWnd) IntSendChildNCPaint(PWND pWnd)
{ {
PWND Child; for (pWnd = pWnd->spwndChild; pWnd; pWnd = pWnd->spwndNext)
HWND *List, *phWnd; {
if ((pWnd->hrgnUpdate == NULL) && (pWnd->state & WNDS_SENDNCPAINT))
List = IntWinListChildren(UserGetDesktopWindow()); {
if ( List ) USER_REFERENCE_ENTRY Ref;
{ UserRefObjectCo(pWnd, &Ref);
for (phWnd = List; *phWnd; ++phWnd) IntSendNCPaint(pWnd, HRGN_WINDOW);
{ UserDerefObjectCo(pWnd);
Child = ValidateHwndNoErr(*phWnd); }
if ( Child && Child->hrgnUpdate == NULL && Child->state & WNDS_SENDNCPAINT) }
{
USER_REFERENCE_ENTRY Ref;
UserRefObjectCo(Child, &Ref);
IntSendNCPaint(Child, HRGN_WINDOW);
UserDerefObjectCo(Child);
}
}
ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
}
/* FIXME : Use snap shot mode until window death is fixed while surfing menus! Fix CORE-12085 and CORE-12071.
pWnd = pWnd->spwndChild;
while(pWnd)
{
if (pWnd->hrgnUpdate == NULL && pWnd->state & WNDS_SENDNCPAINT)
{
USER_REFERENCE_ENTRY Ref;
UserRefObjectCo(pWnd, &Ref);
IntSendNCPaint(pWnd, HRGN_WINDOW);
UserDerefObjectCo(pWnd);
}
pWnd = pWnd->spwndNext;
}*/
} }
/* /*

View file

@ -894,32 +894,41 @@ IntIsChildWindow(PWND Parent, PWND BaseWindow)
} }
//// ////
/* /* Link the window into siblings list. Children and parent are kept in place. */
Link the window into siblings list
children and parent are kept in place.
*/
VOID FASTCALL VOID FASTCALL
IntLinkWindow( IntLinkWindow(
PWND Wnd, PWND Wnd,
PWND WndInsertAfter /* set to NULL if top sibling */ PWND WndInsertAfter /* Set to NULL if top sibling */
) )
{ {
if ((Wnd->spwndPrev = WndInsertAfter)) if (Wnd == WndInsertAfter)
{ {
/* link after WndInsertAfter */ ERR("IntLinkWindow -- Trying to link window 0x%p to itself!!\n", Wnd);
if ((Wnd->spwndNext = WndInsertAfter->spwndNext)) return;
Wnd->spwndNext->spwndPrev = Wnd; }
Wnd->spwndPrev->spwndNext = Wnd; Wnd->spwndPrev = WndInsertAfter;
} if (Wnd->spwndPrev)
else {
{ /* Link after WndInsertAfter */
/* link at top */ ASSERT(Wnd != WndInsertAfter->spwndNext);
if ((Wnd->spwndNext = Wnd->spwndParent->spwndChild)) Wnd->spwndNext = WndInsertAfter->spwndNext;
Wnd->spwndNext->spwndPrev = Wnd; if (Wnd->spwndNext)
Wnd->spwndNext->spwndPrev = Wnd;
Wnd->spwndParent->spwndChild = Wnd; ASSERT(Wnd != Wnd->spwndPrev);
} Wnd->spwndPrev->spwndNext = Wnd;
}
else
{
/* Link at the top */
ASSERT(Wnd != Wnd->spwndParent->spwndChild);
Wnd->spwndNext = Wnd->spwndParent->spwndChild;
if (Wnd->spwndNext)
Wnd->spwndNext->spwndPrev = Wnd;
Wnd->spwndParent->spwndChild = Wnd;
}
} }
/* /*
@ -929,8 +938,8 @@ VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
{ {
if (hWndPrev == HWND_NOTOPMOST) if (hWndPrev == HWND_NOTOPMOST)
{ {
if (!(Wnd->ExStyle & WS_EX_TOPMOST) && if (!(Wnd->ExStyle & WS_EX_TOPMOST) && (Wnd->ExStyle2 & WS_EX2_LINKED))
(Wnd->ExStyle2 & WS_EX2_LINKED)) return; /* nothing to do */ return; /* nothing to do */
Wnd->ExStyle &= ~WS_EX_TOPMOST; Wnd->ExStyle &= ~WS_EX_TOPMOST;
hWndPrev = HWND_TOP; /* fallback to the HWND_TOP case */ hWndPrev = HWND_TOP; /* fallback to the HWND_TOP case */
} }
@ -943,8 +952,10 @@ VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
PWND WndInsertAfter; PWND WndInsertAfter;
WndInsertAfter = Wnd->spwndParent->spwndChild; WndInsertAfter = Wnd->spwndParent->spwndChild;
while( WndInsertAfter && WndInsertAfter->spwndNext) while (WndInsertAfter && WndInsertAfter->spwndNext)
{
WndInsertAfter = WndInsertAfter->spwndNext; WndInsertAfter = WndInsertAfter->spwndNext;
}
IntLinkWindow(Wnd, WndInsertAfter); IntLinkWindow(Wnd, WndInsertAfter);
Wnd->ExStyle &= ~WS_EX_TOPMOST; Wnd->ExStyle &= ~WS_EX_TOPMOST;
@ -953,7 +964,6 @@ VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
{ {
/* Link in the top of the list */ /* Link in the top of the list */
IntLinkWindow(Wnd, NULL); IntLinkWindow(Wnd, NULL);
Wnd->ExStyle |= WS_EX_TOPMOST; Wnd->ExStyle |= WS_EX_TOPMOST;
} }
else if (hWndPrev == HWND_TOP) else if (hWndPrev == HWND_TOP)
@ -967,7 +977,9 @@ VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
{ {
while (WndInsertBefore != NULL && WndInsertBefore->spwndNext != NULL) while (WndInsertBefore != NULL && WndInsertBefore->spwndNext != NULL)
{ {
if (!(WndInsertBefore->ExStyle & WS_EX_TOPMOST)) break; if (!(WndInsertBefore->ExStyle & WS_EX_TOPMOST))
break;
if (WndInsertBefore == Wnd->spwndOwner) /* keep it above owner */ if (WndInsertBefore == Wnd->spwndOwner) /* keep it above owner */
{ {
Wnd->ExStyle |= WS_EX_TOPMOST; Wnd->ExStyle |= WS_EX_TOPMOST;
@ -986,13 +998,15 @@ VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
WndInsertAfter = UserGetWindowObject(hWndPrev); WndInsertAfter = UserGetWindowObject(hWndPrev);
/* Are we called with an erroneous handle */ /* Are we called with an erroneous handle */
if(WndInsertAfter == NULL) if (WndInsertAfter == NULL)
{ {
/* Link in a default position */ /* Link in a default position */
IntLinkHwnd(Wnd, HWND_TOP); IntLinkHwnd(Wnd, HWND_TOP);
return; return;
} }
if (Wnd == WndInsertAfter)
ERR("IntLinkHwnd -- Trying to link window 0x%p to itself!!\n", Wnd);
IntLinkWindow(Wnd, WndInsertAfter); IntLinkWindow(Wnd, WndInsertAfter);
/* Fix the WS_EX_TOPMOST flag */ /* Fix the WS_EX_TOPMOST flag */
@ -1002,8 +1016,8 @@ VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
} }
else else
{ {
if(WndInsertAfter->spwndNext && if (WndInsertAfter->spwndNext &&
WndInsertAfter->spwndNext->ExStyle & WS_EX_TOPMOST) (WndInsertAfter->spwndNext->ExStyle & WS_EX_TOPMOST))
{ {
Wnd->ExStyle |= WS_EX_TOPMOST; Wnd->ExStyle |= WS_EX_TOPMOST;
} }
@ -1287,20 +1301,23 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
return( hWndOldParent); return( hWndOldParent);
} }
/* Unlink the window from siblings. children and parent are kept in place. */ /* Unlink the window from siblings. Children and parent are kept in place. */
VOID FASTCALL VOID FASTCALL
IntUnlinkWindow(PWND Wnd) IntUnlinkWindow(PWND Wnd)
{ {
if (Wnd->spwndNext) ASSERT(Wnd != Wnd->spwndNext);
Wnd->spwndNext->spwndPrev = Wnd->spwndPrev; ASSERT(Wnd != Wnd->spwndPrev);
if (Wnd->spwndPrev) if (Wnd->spwndNext)
Wnd->spwndPrev->spwndNext = Wnd->spwndNext; Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd) if (Wnd->spwndPrev)
Wnd->spwndParent->spwndChild = Wnd->spwndNext; Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
Wnd->spwndPrev = Wnd->spwndNext = NULL; if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd)
Wnd->spwndParent->spwndChild = Wnd->spwndNext;
Wnd->spwndPrev = Wnd->spwndNext = NULL;
} }
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/

View file

@ -30,8 +30,6 @@ DBG_DEFAULT_CHANNEL(UserWinpos);
#define PLACE_MAX 0x0002 #define PLACE_MAX 0x0002
#define PLACE_RECT 0x0004 #define PLACE_RECT 0x0004
VOID FASTCALL IntLinkWindow(PWND Wnd,PWND WndInsertAfter);
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
#if DBG #if DBG