Bug 574454 - Implement non-client frame rendering for windows. r=neil.

This commit is contained in:
Jim Mathies 2010-08-09 20:49:35 -05:00
Родитель 3f96770976
Коммит 43bcab02a9
2 изменённых файлов: 140 добавлений и 0 удалений

Просмотреть файл

@ -2108,6 +2108,63 @@ nsWindow::SetNonClientMargins(nsIntMargin &margins)
return NS_OK;
}
void
nsWindow::InvalidateNonClientRegion()
{
// +-+-----------------------+-+
// | | app non-client chrome | |
// | +-----------------------+ |
// | | app client chrome | | }
// | +-----------------------+ | }
// | | app content | | } area we don't want to invalidate
// | +-----------------------+ | }
// | | app client chrome | | }
// | +-----------------------+ |
// +---------------------------+ <
// ^ ^ windows non-client chrome
// client area = app *
RECT rect;
GetWindowRect(mWnd, &rect);
MapWindowPoints(NULL, mWnd, (LPPOINT)&rect, 2);
HRGN winRgn = CreateRectRgnIndirect(&rect);
// Subtract app client chrome and app content leaving
// windows non-client chrome and app non-client chrome
// in winRgn.
GetWindowRect(mWnd, &rect);
rect.top += mCaptionHeight;
rect.right -= mHorResizeMargin;
rect.bottom -= mHorResizeMargin;
rect.left += mVertResizeMargin;
MapWindowPoints(NULL, mWnd, (LPPOINT)&rect, 2);
HRGN clientRgn = CreateRectRgnIndirect(&rect);
CombineRgn(winRgn, winRgn, clientRgn, RGN_DIFF);
DeleteObject(clientRgn);
// triggers ncpaint and paint events for the two areas
RedrawWindow(mWnd, NULL, winRgn, RDW_FRAME|RDW_INVALIDATE);
DeleteObject(winRgn);
}
HRGN
nsWindow::ExcludeNonClientFromPaintRegion(HRGN aRegion)
{
RECT rect;
HRGN rgn = NULL;
if (aRegion == (HRGN)1) { // undocumented value indicating a full refresh
GetWindowRect(mWnd, &rect);
rgn = CreateRectRgnIndirect(&rect);
} else {
rgn = aRegion;
}
GetClientRect(mWnd, &rect);
MapWindowPoints(mWnd, NULL, (LPPOINT)&rect, 2);
HRGN nonClientRgn = CreateRectRgnIndirect(&rect);
CombineRgn(rgn, rgn, nonClientRgn, RGN_DIFF);
DeleteObject(nonClientRgn);
return rgn;
}
/**************************************************************
*
* SECTION: nsIWidget::SetBackgroundColor
@ -4705,6 +4762,87 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam,
break;
}
case WM_SETTEXT:
/*
* WM_SETTEXT paints the titlebar area. Avoid this if we have a
* custom titlebar we paint ourselves.
*/
if (mNonClientMargins.top == -1)
break;
{
// From msdn, the way around this is to disable the visible state
// temporarily. We need the text to be set but we don't want the
// redraw to occur.
DWORD style = GetWindowLong(mWnd, GWL_STYLE);
SetWindowLong(mWnd, GWL_STYLE, style & ~WS_VISIBLE);
*aRetValue = CallWindowProcW(GetPrevWindowProc(), mWnd,
msg, wParam, lParam);
SetWindowLong(mWnd, GWL_STYLE, style);
return PR_TRUE;
}
case WM_NCACTIVATE:
{
/*
* WM_NCACTIVATE paints nc areas. Avoid this and re-route painting
* through WM_NCPAINT via InvalidateNonClientRegion.
*/
if (!mCustomNonClient)
break;
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
// let the dwm handle nc painting on glass
if(nsUXThemeData::CheckForCompositor())
break;
#endif
if (wParam == TRUE) {
// going active
*aRetValue = FALSE; // ignored
result = PR_TRUE;
// invalidate to trigger a paint
InvalidateNonClientRegion();
break;
} else {
// going inactive
*aRetValue = TRUE; // go ahead and deactive
result = PR_TRUE;
// invalidate to trigger a paint
InvalidateNonClientRegion();
break;
}
}
case WM_NCPAINT:
{
/*
* Reset the non-client paint region so that it excludes the
* non-client areas we paint manually. Then call defwndproc
* to do the actual painting.
*/
if (!mCustomNonClient)
break;
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
// let the dwm handle nc painting on glass
if(nsUXThemeData::CheckForCompositor())
break;
#endif
HRGN paintRgn = ExcludeNonClientFromPaintRegion((HRGN)wParam);
LRESULT res = CallWindowProcW(GetPrevWindowProc(), mWnd,
msg, (WPARAM)paintRgn, lParam);
if (paintRgn != (HRGN)wParam)
DeleteObject(paintRgn);
*aRetValue = res;
result = PR_TRUE;
}
break;
#ifndef WINCE
case WM_POWERBROADCAST:
// only hidden window handle this

Просмотреть файл

@ -302,6 +302,8 @@ protected:
PRBool CanTakeFocus();
PRBool UpdateNonClientMargins(PRInt32 aSizeMode = -1, PRBool aReflowWindow = PR_TRUE);
void ResetLayout();
void InvalidateNonClientRegion();
HRGN ExcludeNonClientFromPaintRegion(HRGN aRegion);
#if !defined(WINCE)
static void InitTrackPointHack();
#endif