mirror of
https://github.com/reactos/reactos.git
synced 2024-07-05 12:15:46 +00:00
[NtUser]
- Defer the changing of the window region while setting the window position. - Patch based on Stefano Toncich work. See CORE-6897 and possibly CORE-7229. svn path=/trunk/; revision=72429
This commit is contained in:
parent
f5b4891559
commit
f7b2e13609
|
@ -32,6 +32,40 @@ VOID FASTCALL IntLinkWindow(PWND Wnd,PWND WndInsertAfter);
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
#if DBG
|
||||||
|
/***********************************************************************
|
||||||
|
* dump_winpos_flags
|
||||||
|
*/
|
||||||
|
static void dump_winpos_flags(UINT flags)
|
||||||
|
{
|
||||||
|
static const DWORD dumped_flags = (SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW |
|
||||||
|
SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_SHOWWINDOW |
|
||||||
|
SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOOWNERZORDER |
|
||||||
|
SWP_NOSENDCHANGING | SWP_DEFERERASE | SWP_ASYNCWINDOWPOS |
|
||||||
|
SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE | SWP_STATECHANGED);
|
||||||
|
TRACE("flags:");
|
||||||
|
if(flags & SWP_NOSIZE) TRACE(" SWP_NOSIZE");
|
||||||
|
if(flags & SWP_NOMOVE) TRACE(" SWP_NOMOVE");
|
||||||
|
if(flags & SWP_NOZORDER) TRACE(" SWP_NOZORDER");
|
||||||
|
if(flags & SWP_NOREDRAW) TRACE(" SWP_NOREDRAW");
|
||||||
|
if(flags & SWP_NOACTIVATE) TRACE(" SWP_NOACTIVATE");
|
||||||
|
if(flags & SWP_FRAMECHANGED) TRACE(" SWP_FRAMECHANGED");
|
||||||
|
if(flags & SWP_SHOWWINDOW) TRACE(" SWP_SHOWWINDOW");
|
||||||
|
if(flags & SWP_HIDEWINDOW) TRACE(" SWP_HIDEWINDOW");
|
||||||
|
if(flags & SWP_NOCOPYBITS) TRACE(" SWP_NOCOPYBITS");
|
||||||
|
if(flags & SWP_NOOWNERZORDER) TRACE(" SWP_NOOWNERZORDER");
|
||||||
|
if(flags & SWP_NOSENDCHANGING) TRACE(" SWP_NOSENDCHANGING");
|
||||||
|
if(flags & SWP_DEFERERASE) TRACE(" SWP_DEFERERASE");
|
||||||
|
if(flags & SWP_ASYNCWINDOWPOS) TRACE(" SWP_ASYNCWINDOWPOS");
|
||||||
|
if(flags & SWP_NOCLIENTSIZE) TRACE(" SWP_NOCLIENTSIZE");
|
||||||
|
if(flags & SWP_NOCLIENTMOVE) TRACE(" SWP_NOCLIENTMOVE");
|
||||||
|
if(flags & SWP_STATECHANGED) TRACE(" SWP_STATECHANGED");
|
||||||
|
|
||||||
|
if(flags & ~dumped_flags) TRACE(" %08x", flags & ~dumped_flags);
|
||||||
|
TRACE("\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
IntGetClientOrigin(PWND Window OPTIONAL, LPPOINT Point)
|
IntGetClientOrigin(PWND Window OPTIONAL, LPPOINT Point)
|
||||||
{
|
{
|
||||||
|
@ -220,6 +254,30 @@ PWND FASTCALL IntGetLastTopMostWindow(VOID)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SelectWindowRgn( PWND Window, HRGN hRgnClip)
|
||||||
|
{
|
||||||
|
if (Window->hrgnClip)
|
||||||
|
{
|
||||||
|
/* Delete no longer needed region handle */
|
||||||
|
IntGdiSetRegionOwner(Window->hrgnClip, GDI_OBJ_HMGR_POWNED);
|
||||||
|
GreDeleteObject(Window->hrgnClip);
|
||||||
|
Window->hrgnClip = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hRgnClip > HRGN_WINDOW)
|
||||||
|
{
|
||||||
|
/*if (Window != UserGetDesktopWindow()) // Window->fnid != FNID_DESKTOP)
|
||||||
|
{
|
||||||
|
NtGdiOffsetRgn(hRgnClip, Window->rcWindow.left, Window->rcWindow.top);
|
||||||
|
}*/
|
||||||
|
/* Set public ownership */
|
||||||
|
IntGdiSetRegionOwner(hRgnClip, GDI_OBJ_HMGR_PUBLIC);
|
||||||
|
|
||||||
|
Window->hrgnClip = hRgnClip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// This helps with CORE-6129 forcing modal dialog active when another app is minimized or closed.
|
// This helps with CORE-6129 forcing modal dialog active when another app is minimized or closed.
|
||||||
//
|
//
|
||||||
|
@ -1758,11 +1816,17 @@ co_WinPosSetWindowPos(
|
||||||
HDC Dc;
|
HDC Dc;
|
||||||
RECTL CopyRect;
|
RECTL CopyRect;
|
||||||
PWND Ancestor;
|
PWND Ancestor;
|
||||||
BOOL bPointerInWindow;
|
BOOL bPointerInWindow, PosChanged = FALSE;
|
||||||
//PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
|
//PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
|
||||||
|
|
||||||
ASSERT_REFS_CO(Window);
|
ASSERT_REFS_CO(Window);
|
||||||
|
|
||||||
|
TRACE("pwnd %p, after %p, %d,%d (%dx%d), flags %s",
|
||||||
|
Window, WndInsertAfter, x, y, cx, cy, flags);
|
||||||
|
#if DBG
|
||||||
|
dump_winpos_flags(flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* FIXME: Get current active window from active queue. Why? since r2915. */
|
/* FIXME: Get current active window from active queue. Why? since r2915. */
|
||||||
|
|
||||||
bPointerInWindow = IntPtInWindow(Window, gpsi->ptCursor.x, gpsi->ptCursor.y);
|
bPointerInWindow = IntPtInWindow(Window, gpsi->ptCursor.x, gpsi->ptCursor.y);
|
||||||
|
@ -1862,6 +1926,13 @@ co_WinPosSetWindowPos(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//// HACK 3
|
||||||
|
if (Window->hrgnNewFrame)
|
||||||
|
{
|
||||||
|
SelectWindowRgn( Window, Window->hrgnNewFrame ); // Should be PSMWP->acvr->hrgnClip
|
||||||
|
Window->hrgnNewFrame = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect, valid_rects);
|
WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect, valid_rects);
|
||||||
|
|
||||||
// ERR("co_WinPosDoNCCALCSize returned 0x%x\n valid dest: %d %d %d %d\n valid src : %d %d %d %d\n", WvrFlags,
|
// ERR("co_WinPosDoNCCALCSize returned 0x%x\n valid dest: %d %d %d %d\n valid src : %d %d %d %d\n", WvrFlags,
|
||||||
|
@ -1884,6 +1955,7 @@ co_WinPosSetWindowPos(
|
||||||
WinPosInternalMoveWindow(Window,
|
WinPosInternalMoveWindow(Window,
|
||||||
NewClientRect.left - OldClientRect.left,
|
NewClientRect.left - OldClientRect.left,
|
||||||
NewClientRect.top - OldClientRect.top);
|
NewClientRect.top - OldClientRect.top);
|
||||||
|
PosChanged = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window->rcWindow = NewWindowRect;
|
Window->rcWindow = NewWindowRect;
|
||||||
|
@ -1951,11 +2023,12 @@ co_WinPosSetWindowPos(
|
||||||
* class need to be completely repainted on (horizontal/vertical) size
|
* class need to be completely repainted on (horizontal/vertical) size
|
||||||
* change.
|
* change.
|
||||||
*/
|
*/
|
||||||
if ( VisBefore != NULL &&
|
if ( ( VisBefore != NULL &&
|
||||||
VisAfter != NULL &&
|
VisAfter != NULL &&
|
||||||
!(WinPos.flags & SWP_NOCOPYBITS) &&
|
!(WinPos.flags & SWP_NOCOPYBITS) &&
|
||||||
((WinPos.flags & SWP_NOSIZE) || !(WvrFlags & WVR_REDRAW)) &&
|
((WinPos.flags & SWP_NOSIZE) || !(WvrFlags & WVR_REDRAW)) &&
|
||||||
!(Window->ExStyle & WS_EX_TRANSPARENT) )
|
!(Window->ExStyle & WS_EX_TRANSPARENT) ) ||
|
||||||
|
( !PosChanged && (WinPos.flags & SWP_FRAMECHANGED) && VisBefore) )
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2000,8 +2073,9 @@ co_WinPosSetWindowPos(
|
||||||
REGION_Delete(CopyRgn);
|
REGION_Delete(CopyRgn);
|
||||||
CopyRgn = NULL;
|
CopyRgn = NULL;
|
||||||
}
|
}
|
||||||
else if (OldWindowRect.left != NewWindowRect.left ||
|
else if ( OldWindowRect.left != NewWindowRect.left ||
|
||||||
OldWindowRect.top != NewWindowRect.top)
|
OldWindowRect.top != NewWindowRect.top ||
|
||||||
|
(WinPos.flags & SWP_FRAMECHANGED) )
|
||||||
{
|
{
|
||||||
HRGN DcRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
|
HRGN DcRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
|
||||||
PREGION DcRgnObj = REGION_LockRgn(DcRgn);
|
PREGION DcRgnObj = REGION_LockRgn(DcRgn);
|
||||||
|
@ -2041,7 +2115,19 @@ co_WinPosSetWindowPos(
|
||||||
{
|
{
|
||||||
CopyRgn = NULL;
|
CopyRgn = NULL;
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
/////// Fixes NoPopup tests but breaks msg_paint tests.
|
||||||
|
if ( !PosChanged && (WinPos.flags & SWP_FRAMECHANGED) && VisBefore)
|
||||||
|
{
|
||||||
|
PWND Parent = Window->spwndParent;
|
||||||
|
ERR("SWP_FRAMECHANGED no chg\n");
|
||||||
|
if ( !(Window->style & WS_CHILD) && (Parent) && (Parent->style & WS_CLIPCHILDREN))
|
||||||
|
{
|
||||||
|
ERR("SWP_FRAMECHANGED Parent WS_CLIPCHILDREN\n");
|
||||||
|
//IntInvalidateWindows( Window, VisBefore, /*RDW_ERASE |*/ RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* We need to redraw what wasn't visible before */
|
/* We need to redraw what wasn't visible before */
|
||||||
if (VisAfter != NULL)
|
if (VisAfter != NULL)
|
||||||
{
|
{
|
||||||
|
@ -3303,20 +3389,16 @@ NtUserSetWindowRgn(
|
||||||
RETURN( 0);
|
RETURN( 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Window->hrgnClip)
|
//// HACK 1 : Work around the lack of supporting DeferWindowPos.
|
||||||
{
|
|
||||||
/* Delete no longer needed region handle */
|
|
||||||
IntGdiSetRegionOwner(Window->hrgnClip, GDI_OBJ_HMGR_POWNED);
|
|
||||||
GreDeleteObject(Window->hrgnClip);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hrgnCopy)
|
if (hrgnCopy)
|
||||||
{
|
{
|
||||||
/* Set public ownership */
|
Window->hrgnNewFrame = hrgnCopy; // Should be PSMWP->acvr->hrgnClip
|
||||||
IntGdiSetRegionOwner(hrgnCopy, GDI_OBJ_HMGR_PUBLIC);
|
|
||||||
}
|
}
|
||||||
Window->hrgnClip = hrgnCopy;
|
else
|
||||||
|
{
|
||||||
|
Window->hrgnNewFrame = (HRGN) 1;
|
||||||
|
}
|
||||||
|
//// HACK 2
|
||||||
Ret = co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, bRedraw ? flags : (flags|SWP_NOREDRAW) );
|
Ret = co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, bRedraw ? flags : (flags|SWP_NOREDRAW) );
|
||||||
|
|
||||||
RETURN( (INT)Ret);
|
RETURN( (INT)Ret);
|
||||||
|
|
Loading…
Reference in a new issue