Bug 489258 - Firefox window doesn't maintain win7 docked position when minimized and restored. r=emaijala.

This commit is contained in:
Jim Mathies 2009-08-11 12:29:53 -05:00
parent 66d0dc5c56
commit 815021b6af
2 changed files with 113 additions and 113 deletions

View File

@ -4031,119 +4031,7 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam,
case WM_WINDOWPOSCHANGED:
{
WINDOWPOS *wp = (LPWINDOWPOS)lParam;
// We only care about a resize, so filter out things like z-order
// changes. Note: there's a WM_MOVE handler above which is why we're
// not handling them here...
if (0 == (wp->flags & SWP_NOSIZE)) {
// XXX Why are we using the client size area? If the size notification
// is for the client area then the origin should be (0,0) and not
// the window origin in screen coordinates...
RECT r;
::GetWindowRect(mWnd, &r);
PRInt32 newWidth, newHeight;
newWidth = PRInt32(r.right - r.left);
newHeight = PRInt32(r.bottom - r.top);
nsIntRect rect(wp->x, wp->y, newWidth, newHeight);
#ifdef MOZ_XUL
if (eTransparencyTransparent == mTransparencyMode)
ResizeTranslucentWindow(newWidth, newHeight);
#endif
if (newWidth > mLastSize.width)
{
RECT drect;
//getting wider
drect.left = wp->x + mLastSize.width;
drect.top = wp->y;
drect.right = drect.left + (newWidth - mLastSize.width);
drect.bottom = drect.top + newHeight;
::RedrawWindow(mWnd, &drect, NULL,
RDW_INVALIDATE | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ERASENOW | RDW_ALLCHILDREN);
}
if (newHeight > mLastSize.height)
{
RECT drect;
//getting taller
drect.left = wp->x;
drect.top = wp->y + mLastSize.height;
drect.right = drect.left + newWidth;
drect.bottom = drect.top + (newHeight - mLastSize.height);
::RedrawWindow(mWnd, &drect, NULL,
RDW_INVALIDATE | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ERASENOW | RDW_ALLCHILDREN);
}
mBounds.width = newWidth;
mBounds.height = newHeight;
mLastSize.width = newWidth;
mLastSize.height = newHeight;
///nsRect rect(wp->x, wp->y, wp->cx, wp->cy);
// If we're being minimized, don't send the resize event to Gecko because
// it will cause the scrollbar in the content area to go away and we'll
// forget the scroll position of the page. Note that we need to check the
// toplevel window, because child windows seem to go to 0x0 on minimize.
HWND toplevelWnd = GetTopLevelHWND(mWnd);
if (mWnd == toplevelWnd && IsIconic(toplevelWnd)) {
result = PR_FALSE;
break;
}
// recalculate the width and height
// this time based on the client area
if (::GetClientRect(mWnd, &r)) {
rect.width = PRInt32(r.right - r.left);
rect.height = PRInt32(r.bottom - r.top);
}
result = OnResize(rect);
}
/* handle size mode changes
(the framechanged message seems a handy place to hook in,
because it happens early enough (WM_SIZE is too late) and
because in testing it seems an accurate harbinger of
an impending min/max/restore change (WM_NCCALCSIZE would
also work, but it's also sent when merely resizing.)) */
if (wp->flags & SWP_FRAMECHANGED && ::IsWindowVisible(mWnd)) {
nsSizeModeEvent event(PR_TRUE, NS_SIZEMODE, this);
#ifndef WINCE
WINDOWPLACEMENT pl;
pl.length = sizeof(pl);
::GetWindowPlacement(mWnd, &pl);
if (pl.showCmd == SW_SHOWMAXIMIZED)
event.mSizeMode = nsSizeMode_Maximized;
else if (pl.showCmd == SW_SHOWMINIMIZED)
event.mSizeMode = nsSizeMode_Minimized;
else
event.mSizeMode = nsSizeMode_Normal;
#else
// Bug 504499 - Can't find a way to query if the window is maximized
// on Windows CE. So as a hacky workaround, we'll assume that if the
// window size exactly fills the screen, then it must be maximized.
RECT wr;
::GetWindowRect(mWnd, &wr);
if (::IsIconic(mWnd))
event.mSizeMode = nsSizeMode_Minimized;
else if (wr.left == 0 &&
wr.top == 0 &&
wr.right == ::GetSystemMetrics(SM_CXSCREEN) &&
wr.bottom == ::GetSystemMetrics(SM_CYSCREEN))
event.mSizeMode = nsSizeMode_Maximized;
else
event.mSizeMode = nsSizeMode_Normal;
#endif
InitEvent(event);
result = DispatchWindowEvent(&event);
}
}
OnWindowPosChanged(wp, result);
break;
case WM_SETTINGCHANGE:
@ -4646,6 +4534,117 @@ BOOL nsWindow::OnInputLangChange(HKL aHKL)
return PR_FALSE; // always pass to child window
}
void nsWindow::OnWindowPosChanged(WINDOWPOS *wp, PRBool& result)
{
if (wp == nsnull)
return;
// We only care about a resize, so filter out things like z-order
// changes. Note: there's a WM_MOVE handler above which is why we're
// not handling them here...
if (0 == (wp->flags & SWP_NOSIZE)) {
// XXX Why are we using the client size area? If the size notification
// is for the client area then the origin should be (0,0) and not
// the window origin in screen coordinates...
RECT r;
::GetWindowRect(mWnd, &r);
PRInt32 newWidth, newHeight;
newWidth = PRInt32(r.right - r.left);
newHeight = PRInt32(r.bottom - r.top);
nsIntRect rect(wp->x, wp->y, newWidth, newHeight);
#ifdef MOZ_XUL
if (eTransparencyTransparent == mTransparencyMode)
ResizeTranslucentWindow(newWidth, newHeight);
#endif
if (newWidth > mLastSize.width)
{
RECT drect;
//getting wider
drect.left = wp->x + mLastSize.width;
drect.top = wp->y;
drect.right = drect.left + (newWidth - mLastSize.width);
drect.bottom = drect.top + newHeight;
::RedrawWindow(mWnd, &drect, NULL,
RDW_INVALIDATE | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ERASENOW | RDW_ALLCHILDREN);
}
if (newHeight > mLastSize.height)
{
RECT drect;
//getting taller
drect.left = wp->x;
drect.top = wp->y + mLastSize.height;
drect.right = drect.left + newWidth;
drect.bottom = drect.top + (newHeight - mLastSize.height);
::RedrawWindow(mWnd, &drect, NULL,
RDW_INVALIDATE | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ERASENOW | RDW_ALLCHILDREN);
}
mBounds.width = newWidth;
mBounds.height = newHeight;
mLastSize.width = newWidth;
mLastSize.height = newHeight;
// If we're being minimized, don't send the resize event to Gecko because
// it will cause the scrollbar in the content area to go away and we'll
// forget the scroll position of the page. Note that we need to check the
// toplevel window, because child windows seem to go to 0x0 on minimize.
HWND toplevelWnd = GetTopLevelHWND(mWnd);
if (mWnd == toplevelWnd && IsIconic(toplevelWnd)) {
result = PR_FALSE;
return;
}
// recalculate the width and height
// this time based on the client area
if (::GetClientRect(mWnd, &r)) {
rect.width = PRInt32(r.right - r.left);
rect.height = PRInt32(r.bottom - r.top);
}
result = OnResize(rect);
}
// handle size mode changes - (the framechanged message seems a handy
// place to hook in, because it happens early enough (WM_SIZE is too
// late) and because in testing it seems an accurate harbinger of an
// impending min/max/restore change (WM_NCCALCSIZE would also work,
// but it's also sent when merely resizing.))
if (wp->flags & SWP_FRAMECHANGED && ::IsWindowVisible(mWnd)) {
nsSizeModeEvent event(PR_TRUE, NS_SIZEMODE, this);
#ifndef WINCE
WINDOWPLACEMENT pl;
pl.length = sizeof(pl);
::GetWindowPlacement(mWnd, &pl);
if (pl.showCmd == SW_SHOWMAXIMIZED)
event.mSizeMode = nsSizeMode_Maximized;
else if (pl.showCmd == SW_SHOWMINIMIZED)
event.mSizeMode = nsSizeMode_Minimized;
else
event.mSizeMode = nsSizeMode_Normal;
#else
event.mSizeMode = mSizeMode;
#endif
// Windows has just changed the size mode of this window. The following
// NS_SIZEMODE event will trigger a call into SetSizeMode where we will
// set the min/max window state again or for nsSizeMode_Normal, call
// SetWindow with a parameter of SW_RESTORE. There's no need however as
// this window's mode has already changed. Updating mSizeMode here
// insures the SetSizeMode call is a no-op. Addresses a bug on Win7 related
// to window docking. (bug 489258)
mSizeMode = event.mSizeMode;
InitEvent(event);
result = DispatchWindowEvent(&event);
}
}
#if !defined(WINCE)
void nsWindow::OnWindowPosChanging(LPWINDOWPOS& info)
{

View File

@ -311,6 +311,7 @@ protected:
BOOL OnInputLangChange(HKL aHKL);
void OnSettingsChange(WPARAM wParam, LPARAM lParam);
virtual PRBool OnPaint(HDC aDC = nsnull);
void OnWindowPosChanged(WINDOWPOS *wp, PRBool& aResult);
#if defined(CAIRO_HAS_DDRAW_SURFACE)
PRBool OnPaintImageDDraw16();
#endif // defined(CAIRO_HAS_DDRAW_SURFACE)