- Improve painting messages, separated functions and dual functions for isolating drawing issues. Next thing to do is fix Set Window Position; Still no SWP_FRAMECHANGED support.
- See CORE-7447 for test results.

svn path=/trunk/; revision=68474
This commit is contained in:
James Tabor 2015-07-20 19:34:35 +00:00
parent 062fc062d2
commit 4cb15718ab
8 changed files with 863 additions and 394 deletions

View file

@ -2,7 +2,7 @@
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Win32k subsystem * PROJECT: ReactOS Win32k subsystem
* PURPOSE: Miscellaneous User functions * PURPOSE: Miscellaneous User functions
* FILE: subsystems/win32/win32k/ntuser/defwnd.c * FILE: win32ss/user/ntuser/defwnd.c
* PROGRAMER: * PROGRAMER:
*/ */
@ -638,6 +638,7 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
} }
if ( IntIsWindow(UserHMGetHandle(pwnd)) ) if ( IntIsWindow(UserHMGetHandle(pwnd)) )
{
if ( iconic ) if ( iconic )
{ {
/* Single click brings up the system menu when iconized */ /* Single click brings up the system menu when iconized */
@ -647,6 +648,7 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
co_IntSendMessage( UserHMGetHandle(pwnd), WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y)); co_IntSendMessage( UserHMGetHandle(pwnd), WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y));
} }
} }
}
} }
// //
@ -773,7 +775,7 @@ DefWndHandleSetCursor(PWND pWnd, WPARAM wParam, LPARAM lParam)
{ {
case HTERROR: case HTERROR:
{ {
//// This is the real fix for CORE-6129! This was a "Code Whole". //// This is the real fix for CORE-6129! This was a "Code hole".
USER_REFERENCE_ENTRY Ref; USER_REFERENCE_ENTRY Ref;
if (Msg == WM_LBUTTONDOWN) if (Msg == WM_LBUTTONDOWN)
@ -1107,19 +1109,21 @@ IntDefWindowProc(
case WM_SYNCPAINT: case WM_SYNCPAINT:
{ {
PREGION Rgn; HRGN hRgn;
Wnd->state &= ~WNDS_SYNCPAINTPENDING; Wnd->state &= ~WNDS_SYNCPAINTPENDING;
ERR("WM_SYNCPAINT\n"); TRACE("WM_SYNCPAINT\n");
Rgn = IntSysCreateRectpRgn(0, 0, 0, 0); hRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
if (Rgn) if (hRgn)
{ {
if (co_UserGetUpdateRgn(Wnd, Rgn, FALSE) != NULLREGION) if (co_UserGetUpdateRgn(Wnd, hRgn, FALSE) != NULLREGION)
{ {
PREGION pRgn = REGION_LockRgn(hRgn);
if (pRgn) REGION_UnlockRgn(pRgn);
if (!wParam) if (!wParam)
wParam = (RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN); wParam = (RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN);
co_UserRedrawWindow(Wnd, NULL, Rgn, wParam); co_UserRedrawWindow(Wnd, NULL, pRgn, wParam);
} }
REGION_Delete(Rgn); GreDeleteObject(hRgn);
} }
return 0; return 0;
} }

View file

@ -763,14 +763,14 @@ IntDispatchMessage(PMSG pMsg)
pMsg->lParam, pMsg->lParam,
-1); -1);
if (pMsg->message == WM_PAINT) if ( pMsg->message == WM_PAINT &&
VerifyWnd(Window) &&
Window->state & WNDS_PAINTNOTPROCESSED ) // <--- Cleared, paint was already processed!
{ {
PREGION Rgn;
Window->state2 &= ~WNDS2_WMPAINTSENT; Window->state2 &= ~WNDS2_WMPAINTSENT;
/* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */ /* send a WM_ERASEBKGND if the non-client area is still invalid */
Rgn = IntSysCreateRectpRgn( 0, 0, 0, 0 ); ERR("Message WM_PAINT\n");
co_UserGetUpdateRgn( Window, Rgn, TRUE ); co_IntPaintWindows( Window, RDW_NOCHILDREN, FALSE );
REGION_Delete(Rgn);
} }
return retval; return retval;
@ -1076,7 +1076,7 @@ co_IntGetPeekMessage( PMSG pMsg,
co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)pMsg); co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)pMsg);
if ( bGMSG ) break; if ( bGMSG || pMsg->message == WM_PAINT) break;
} }
if ( bGMSG ) if ( bGMSG )

File diff suppressed because it is too large Load diff

View file

@ -8,13 +8,25 @@
#define FLASHW_KILLSYSTIMER 0x00004000 #define FLASHW_KILLSYSTIMER 0x00004000
#define FLASHW_ACTIVE 0x00008000 #define FLASHW_ACTIVE 0x00008000
#define PRGN_NULL ((PREGION)0) /* NULL empty region */
#define PRGN_WINDOW ((PREGION)1) /* region from window rcWindow */
#define PRGN_MONITOR ((PREGION)2) /* region from monitor region. */
#define GreCreateRectRgnIndirect(prc) \
NtGdiCreateRectRgn((prc)->left, (prc)->top, (prc)->right, (prc)->bottom)
#define GreSetRectRgnIndirect(hRgn, prc) \
NtGdiSetRectRgn(hRgn, (prc)->left, (prc)->top, (prc)->right, (prc)->bottom);
BOOL FASTCALL co_UserRedrawWindow(PWND Wnd, const RECTL* UpdateRect, PREGION UpdateRgn, ULONG Flags); BOOL FASTCALL co_UserRedrawWindow(PWND Wnd, const RECTL* UpdateRect, PREGION UpdateRgn, ULONG Flags);
VOID FASTCALL IntInvalidateWindows(PWND Window, PREGION Rgn, ULONG Flags); VOID FASTCALL IntInvalidateWindows(PWND Window, PREGION Rgn, ULONG Flags);
BOOL FASTCALL IntGetPaintMessage(PWND Window, UINT MsgFilterMin, UINT MsgFilterMax, PTHREADINFO Thread, MSG *Message, BOOL Remove); BOOL FASTCALL IntGetPaintMessage(PWND Window, UINT MsgFilterMin, UINT MsgFilterMax, PTHREADINFO Thread, MSG *Message, BOOL Remove);
INT FASTCALL UserRealizePalette(HDC); INT FASTCALL UserRealizePalette(HDC);
INT FASTCALL co_UserGetUpdateRgn(PWND, PREGION, BOOL); INT FASTCALL co_UserGetUpdateRgn(PWND, HRGN, BOOL);
BOOL FASTCALL co_UserGetUpdateRect(PWND, PRECT, BOOL);
VOID FASTCALL co_IntPaintWindows(PWND Window, ULONG Flags, BOOL Recurse); VOID FASTCALL co_IntPaintWindows(PWND Window, ULONG Flags, BOOL Recurse);
BOOL FASTCALL IntValidateParent(PWND Child, PREGION ValidateRgn, BOOL Recurse); VOID FASTCALL IntSendSyncPaint(PWND, ULONG);
VOID FASTCALL co_IntUpdateWindows(PWND, ULONG, BOOL);
BOOL FASTCALL IntIsWindowDirty(PWND); BOOL FASTCALL IntIsWindowDirty(PWND);
BOOL FASTCALL IntEndPaint(PWND,PPAINTSTRUCT); BOOL FASTCALL IntEndPaint(PWND,PPAINTSTRUCT);
HDC FASTCALL IntBeginPaint(PWND,PPAINTSTRUCT); HDC FASTCALL IntBeginPaint(PWND,PPAINTSTRUCT);

View file

@ -544,7 +544,8 @@ NtUserCallHwndLock(
break; break;
case HWNDLOCK_ROUTINE_UPDATEWINDOW: case HWNDLOCK_ROUTINE_UPDATEWINDOW:
Ret = co_UserRedrawWindow( Window, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN); co_IntUpdateWindows(Window, RDW_ALLCHILDREN, FALSE);
Ret = TRUE;
break; break;
} }

View file

@ -2,7 +2,7 @@
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Win32k subsystem * PROJECT: ReactOS Win32k subsystem
* PURPOSE: Windows * PURPOSE: Windows
* FILE: subsystems/win32/win32k/ntuser/window.c * FILE: win32ss/user/ntuser/window.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
*/ */
@ -572,6 +572,23 @@ LRESULT co_UserFreeWindow(PWND Window,
IntReleaseCapture(); IntReleaseCapture();
} }
//// Now kill those remaining "PAINTING BUG: Thread marked as containing dirty windows" spam!!!
if ( Window->hrgnUpdate != NULL || Window->state & WNDS_INTERNALPAINT )
{
MsqDecPaintCountQueue(Window->head.pti);
if (Window->hrgnUpdate > HRGN_WINDOW && GreIsHandleValid(Window->hrgnUpdate))
{
GreDeleteObject(Window->hrgnUpdate);
}
Window->hrgnUpdate = NULL;
Window->state &= ~WNDS_INTERNALPAINT;
}
if (Window->state & (WNDS_SENDERASEBACKGROUND|WNDS_SENDNCPAINT))
{
Window->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_SENDNCPAINT);
}
if ( ((Window->style & (WS_CHILD|WS_POPUP)) != WS_CHILD) && if ( ((Window->style & (WS_CHILD|WS_POPUP)) != WS_CHILD) &&
Window->IDMenu && Window->IDMenu &&
(Menu = UserGetMenuObject((HMENU)Window->IDMenu))) (Menu = UserGetMenuObject((HMENU)Window->IDMenu)))

View file

@ -2,7 +2,7 @@
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* PURPOSE: Windows * PURPOSE: Windows
* FILE: subsystems/win32/win32k/ntuser/window.c * FILE: win32ss/user/ntuser/window.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
*/ */
@ -82,6 +82,29 @@ IntGetClientRect(PWND Wnd, RECTL *Rect)
} }
} }
BOOL FASTCALL
IntGetWindowRect(PWND Wnd, RECTL *Rect)
{
ASSERT( Wnd );
ASSERT( Rect );
if (!Wnd) return FALSE;
if ( Wnd != UserGetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
{
*Rect = Wnd->rcWindow;
}
else
{
Rect->left = Rect->top = 0;
Rect->right = Wnd->rcWindow.right;
Rect->bottom = Wnd->rcWindow.bottom;
/* Do this until Init bug is fixed. This sets 640x480, see InitMetrics.
Rect->right = GetSystemMetrics(SM_CXSCREEN);
Rect->bottom = GetSystemMetrics(SM_CYSCREEN);
*/ }
return TRUE;
}
INT FASTCALL INT FASTCALL
IntMapWindowPoints(PWND FromWnd, PWND ToWnd, LPPOINT lpPoints, UINT cPoints) IntMapWindowPoints(PWND FromWnd, PWND ToWnd, LPPOINT lpPoints, UINT cPoints)
{ {
@ -1098,6 +1121,38 @@ co_WinPosGetMinMaxInfo(PWND Window, POINT* MaxSize, POINT* MaxPos,
return 0; // FIXME: What does it return? return 0; // FIXME: What does it return?
} }
static
BOOL
IntValidateParent(PWND Child, PREGION ValidateRgn)
{
PWND ParentWnd = Child;
if (ParentWnd->style & WS_CHILD)
{
do
ParentWnd = ParentWnd->spwndParent;
while (ParentWnd->style & WS_CHILD);
}
ParentWnd = Child->spwndParent;
while (ParentWnd)
{
if (ParentWnd->style & WS_CLIPCHILDREN)
break;
if (ParentWnd->hrgnUpdate != 0)
{
IntInvalidateWindows( ParentWnd,
ValidateRgn,
RDW_VALIDATE | RDW_NOCHILDREN);
}
ParentWnd = ParentWnd->spwndParent;
}
return TRUE;
}
static static
VOID FASTCALL VOID FASTCALL
FixClientRect(PRECTL ClientRect, PRECTL WindowRect) FixClientRect(PRECTL ClientRect, PRECTL WindowRect)
@ -1320,8 +1375,6 @@ co_WinPosDoWinPosChanging(PWND Window,
} }
} }
WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
if (!(WinPos->flags & SWP_NOMOVE)) if (!(WinPos->flags & SWP_NOMOVE))
{ {
INT X, Y; INT X, Y;
@ -1331,9 +1384,6 @@ co_WinPosDoWinPosChanging(PWND Window,
Parent = Window->spwndParent; Parent = Window->spwndParent;
// Fix wine msg test_SetParent:WmSetParentSeq_2:19 wParam bits.
WinPos->flags &= ~SWP_NOCLIENTMOVE;
// Parent child position issue is in here. SetParent_W7 test CORE-6651. // Parent child position issue is in here. SetParent_W7 test CORE-6651.
if (//((Window->style & WS_CHILD) != 0) && <- Fixes wine msg test_SetParent: "rects do not match", the last test. if (//((Window->style & WS_CHILD) != 0) && <- Fixes wine msg test_SetParent: "rects do not match", the last test.
Parent && Parent &&
@ -1353,6 +1403,7 @@ co_WinPosDoWinPosChanging(PWND Window,
RECTL_vOffsetRect(ClientRect, X - Window->rcWindow.left, RECTL_vOffsetRect(ClientRect, X - Window->rcWindow.left,
Y - Window->rcWindow.top); Y - Window->rcWindow.top);
} }
WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n", TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n",
WinPos->hwnd, WinPos->hwndInsertAfter, WinPos->x, WinPos->y, WinPos->hwnd, WinPos->hwndInsertAfter, WinPos->x, WinPos->y,
@ -1387,7 +1438,6 @@ WinPosDoOwnedPopups(PWND Window, HWND hWndInsertAfter)
TRACE("(%p) hInsertAfter = %p\n", Window, hWndInsertAfter ); TRACE("(%p) hInsertAfter = %p\n", Window, hWndInsertAfter );
Owner = Window->spwndOwner ? Window->spwndOwner->head.h : NULL;
Style = Window->style; Style = Window->style;
if (Style & WS_CHILD) if (Style & WS_CHILD)
@ -1396,6 +1446,8 @@ WinPosDoOwnedPopups(PWND Window, HWND hWndInsertAfter)
return hWndInsertAfter; return hWndInsertAfter;
} }
Owner = Window->spwndOwner ? Window->spwndOwner->head.h : NULL;
if (Owner) if (Owner)
{ {
/* Make sure this popup stays above the owner */ /* Make sure this popup stays above the owner */
@ -1438,7 +1490,7 @@ WinPosDoOwnedPopups(PWND Window, HWND hWndInsertAfter)
if (hWndInsertAfter == HWND_BOTTOM) if (hWndInsertAfter == HWND_BOTTOM)
{ {
ERR("Window is HWND_BOTTOM\n"); ERR("Window is HWND_BOTTOM hwnd %p\n",hWndInsertAfter);
if (List) ExFreePoolWithTag(List, USERTAG_WINDOWLIST); if (List) ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
goto done; goto done;
} }
@ -1981,7 +2033,7 @@ co_WinPosSetWindowPos(
0); 0);
UserReleaseDC(Window, Dc, FALSE); UserReleaseDC(Window, Dc, FALSE);
IntValidateParent(Window, CopyRgn, FALSE); IntValidateParent(Window, CopyRgn);
GreDeleteObject(DcRgn); GreDeleteObject(DcRgn);
} }
} }
@ -2004,6 +2056,7 @@ co_WinPosSetWindowPos(
{ {
RgnType = IntGdiCombineRgn(DirtyRgn, VisAfter, 0, RGN_COPY); RgnType = IntGdiCombineRgn(DirtyRgn, VisAfter, 0, RGN_COPY);
} }
if (RgnType != ERROR && RgnType != NULLREGION) if (RgnType != ERROR && RgnType != NULLREGION)
{ {
/* old code /* old code
@ -2017,23 +2070,16 @@ co_WinPosSetWindowPos(
PWND Parent = Window->spwndParent; PWND Parent = Window->spwndParent;
REGION_bOffsetRgn( DirtyRgn, REGION_bOffsetRgn( DirtyRgn, Window->rcWindow.left, Window->rcWindow.top);
Window->rcWindow.left,
Window->rcWindow.top); if ( (Window->style & WS_CHILD) && (Parent) && !(Parent->style & WS_CLIPCHILDREN))
if ( (Window->style & WS_CHILD) &&
(Parent) &&
!(Parent->style & WS_CLIPCHILDREN))
{ {
IntInvalidateWindows( Parent, IntInvalidateWindows( Parent, DirtyRgn, RDW_ERASE | RDW_INVALIDATE);
DirtyRgn, co_IntPaintWindows(Parent, RDW_NOCHILDREN, FALSE);
RDW_ERASE | RDW_INVALIDATE);
co_IntPaintWindows(Parent, RDW_ERASENOW, FALSE);
} }
else else
{ {
IntInvalidateWindows( Window, IntInvalidateWindows( Window, DirtyRgn, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
DirtyRgn,
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
} }
} }
REGION_Delete(DirtyRgn); REGION_Delete(DirtyRgn);

View file

@ -44,6 +44,16 @@ FORCEINLINE BOOL IntPtInWindow(PWND pwnd, INT x, INT y)
y - pwnd->rcWindow.top); y - pwnd->rcWindow.top);
} }
FORCEINLINE BOOL
IntEqualRect(RECTL *lprc1, RECTL *lprc2)
{
if (lprc1 == NULL || lprc2 == NULL)
return FALSE;
return (lprc1->left == lprc2->left) && (lprc1->top == lprc2->top) &&
(lprc1->right == lprc2->right) && (lprc1->bottom == lprc2->bottom);
}
BOOL FASTCALL ActivateOtherWindowMin(PWND); BOOL FASTCALL ActivateOtherWindowMin(PWND);
UINT FASTCALL co_WinPosArrangeIconicWindows(PWND parent); UINT FASTCALL co_WinPosArrangeIconicWindows(PWND parent);
BOOL FASTCALL IntGetClientOrigin(PWND Window, LPPOINT Point); BOOL FASTCALL IntGetClientOrigin(PWND Window, LPPOINT Point);
@ -58,3 +68,4 @@ VOID FASTCALL co_WinPosActivateOtherWindow(PWND);
PWND FASTCALL IntRealChildWindowFromPoint(PWND,LONG,LONG); PWND FASTCALL IntRealChildWindowFromPoint(PWND,LONG,LONG);
BOOL FASTCALL IntScreenToClient(PWND,LPPOINT); BOOL FASTCALL IntScreenToClient(PWND,LPPOINT);
BOOL FASTCALL IntClientToScreen(PWND,LPPOINT); BOOL FASTCALL IntClientToScreen(PWND,LPPOINT);
BOOL FASTCALL IntGetWindowRect(PWND,RECTL*);