зеркало из https://github.com/mozilla/gecko-dev.git
Bug 574454 - Implement non-client frame rendering for windows. r=neil.
This commit is contained in:
Родитель
3f96770976
Коммит
43bcab02a9
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче