- 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
* PROJECT: ReactOS Win32k subsystem
* PURPOSE: Miscellaneous User functions
* FILE: subsystems/win32/win32k/ntuser/defwnd.c
* FILE: win32ss/user/ntuser/defwnd.c
* PROGRAMER:
*/
@ -638,6 +638,7 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
}
if ( IntIsWindow(UserHMGetHandle(pwnd)) )
{
if ( iconic )
{
/* 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));
}
}
}
}
//
@ -773,7 +775,7 @@ DefWndHandleSetCursor(PWND pWnd, WPARAM wParam, LPARAM lParam)
{
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;
if (Msg == WM_LBUTTONDOWN)
@ -1107,19 +1109,21 @@ IntDefWindowProc(
case WM_SYNCPAINT:
{
PREGION Rgn;
HRGN hRgn;
Wnd->state &= ~WNDS_SYNCPAINTPENDING;
ERR("WM_SYNCPAINT\n");
Rgn = IntSysCreateRectpRgn(0, 0, 0, 0);
if (Rgn)
TRACE("WM_SYNCPAINT\n");
hRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
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)
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;
}

View file

@ -763,14 +763,14 @@ IntDispatchMessage(PMSG pMsg)
pMsg->lParam,
-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;
/* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
Rgn = IntSysCreateRectpRgn( 0, 0, 0, 0 );
co_UserGetUpdateRgn( Window, Rgn, TRUE );
REGION_Delete(Rgn);
/* send a WM_ERASEBKGND if the non-client area is still invalid */
ERR("Message WM_PAINT\n");
co_IntPaintWindows( Window, RDW_NOCHILDREN, FALSE );
}
return retval;
@ -1076,7 +1076,7 @@ co_IntGetPeekMessage( PMSG 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 )

File diff suppressed because it is too large Load diff

View file

@ -8,13 +8,25 @@
#define FLASHW_KILLSYSTIMER 0x00004000
#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);
VOID FASTCALL IntInvalidateWindows(PWND Window, PREGION Rgn, ULONG Flags);
BOOL FASTCALL IntGetPaintMessage(PWND Window, UINT MsgFilterMin, UINT MsgFilterMax, PTHREADINFO Thread, MSG *Message, BOOL Remove);
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);
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 IntEndPaint(PWND,PPAINTSTRUCT);
HDC FASTCALL IntBeginPaint(PWND,PPAINTSTRUCT);

View file

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

View file

@ -2,7 +2,7 @@
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Win32k subsystem
* PURPOSE: Windows
* FILE: subsystems/win32/win32k/ntuser/window.c
* FILE: win32ss/user/ntuser/window.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
@ -572,6 +572,23 @@ LRESULT co_UserFreeWindow(PWND Window,
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) &&
Window->IDMenu &&
(Menu = UserGetMenuObject((HMENU)Window->IDMenu)))

View file

@ -2,7 +2,7 @@
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Windows
* FILE: subsystems/win32/win32k/ntuser/window.c
* FILE: win32ss/user/ntuser/window.c
* 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
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?
}
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
VOID FASTCALL
FixClientRect(PRECTL ClientRect, PRECTL WindowRect)
@ -1320,8 +1375,6 @@ co_WinPosDoWinPosChanging(PWND Window,
}
}
WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
if (!(WinPos->flags & SWP_NOMOVE))
{
INT X, Y;
@ -1331,9 +1384,6 @@ co_WinPosDoWinPosChanging(PWND Window,
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.
if (//((Window->style & WS_CHILD) != 0) && <- Fixes wine msg test_SetParent: "rects do not match", the last test.
Parent &&
@ -1353,6 +1403,7 @@ co_WinPosDoWinPosChanging(PWND Window,
RECTL_vOffsetRect(ClientRect, X - Window->rcWindow.left,
Y - Window->rcWindow.top);
}
WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n",
WinPos->hwnd, WinPos->hwndInsertAfter, WinPos->x, WinPos->y,
@ -1387,7 +1438,6 @@ WinPosDoOwnedPopups(PWND Window, HWND hWndInsertAfter)
TRACE("(%p) hInsertAfter = %p\n", Window, hWndInsertAfter );
Owner = Window->spwndOwner ? Window->spwndOwner->head.h : NULL;
Style = Window->style;
if (Style & WS_CHILD)
@ -1396,6 +1446,8 @@ WinPosDoOwnedPopups(PWND Window, HWND hWndInsertAfter)
return hWndInsertAfter;
}
Owner = Window->spwndOwner ? Window->spwndOwner->head.h : NULL;
if (Owner)
{
/* Make sure this popup stays above the owner */
@ -1438,7 +1490,7 @@ WinPosDoOwnedPopups(PWND Window, HWND hWndInsertAfter)
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);
goto done;
}
@ -1981,7 +2033,7 @@ co_WinPosSetWindowPos(
0);
UserReleaseDC(Window, Dc, FALSE);
IntValidateParent(Window, CopyRgn, FALSE);
IntValidateParent(Window, CopyRgn);
GreDeleteObject(DcRgn);
}
}
@ -2004,6 +2056,7 @@ co_WinPosSetWindowPos(
{
RgnType = IntGdiCombineRgn(DirtyRgn, VisAfter, 0, RGN_COPY);
}
if (RgnType != ERROR && RgnType != NULLREGION)
{
/* old code
@ -2017,23 +2070,16 @@ co_WinPosSetWindowPos(
PWND Parent = Window->spwndParent;
REGION_bOffsetRgn( DirtyRgn,
Window->rcWindow.left,
Window->rcWindow.top);
if ( (Window->style & WS_CHILD) &&
(Parent) &&
!(Parent->style & WS_CLIPCHILDREN))
REGION_bOffsetRgn( DirtyRgn, Window->rcWindow.left, Window->rcWindow.top);
if ( (Window->style & WS_CHILD) && (Parent) && !(Parent->style & WS_CLIPCHILDREN))
{
IntInvalidateWindows( Parent,
DirtyRgn,
RDW_ERASE | RDW_INVALIDATE);
co_IntPaintWindows(Parent, RDW_ERASENOW, FALSE);
IntInvalidateWindows( Parent, DirtyRgn, RDW_ERASE | RDW_INVALIDATE);
co_IntPaintWindows(Parent, RDW_NOCHILDREN, FALSE);
}
else
{
IntInvalidateWindows( Window,
DirtyRgn,
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
IntInvalidateWindows( Window, DirtyRgn, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
}
REGION_Delete(DirtyRgn);

View file

@ -44,6 +44,16 @@ FORCEINLINE BOOL IntPtInWindow(PWND pwnd, INT x, INT y)
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);
UINT FASTCALL co_WinPosArrangeIconicWindows(PWND parent);
BOOL FASTCALL IntGetClientOrigin(PWND Window, LPPOINT Point);
@ -58,3 +68,4 @@ VOID FASTCALL co_WinPosActivateOtherWindow(PWND);
PWND FASTCALL IntRealChildWindowFromPoint(PWND,LONG,LONG);
BOOL FASTCALL IntScreenToClient(PWND,LPPOINT);
BOOL FASTCALL IntClientToScreen(PWND,LPPOINT);
BOOL FASTCALL IntGetWindowRect(PWND,RECTL*);