From 4e3537e998be71c735065d98029eb7cc9ab4884e Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Thu, 24 Jun 2010 21:01:07 -0500 Subject: [PATCH] Bug 513162 - Win support for custom chrome margins on windows. r=tellrob. --- widget/src/windows/nsUXThemeData.cpp | 2 + widget/src/windows/nsUXThemeData.h | 2 + widget/src/windows/nsWindow.cpp | 370 ++++++++++++++++++++++++--- widget/src/windows/nsWindow.h | 20 ++ 4 files changed, 364 insertions(+), 30 deletions(-) diff --git a/widget/src/windows/nsUXThemeData.cpp b/widget/src/windows/nsUXThemeData.cpp index 4df110ebf6f..4f32f8c1053 100644 --- a/widget/src/windows/nsUXThemeData.cpp +++ b/widget/src/windows/nsUXThemeData.cpp @@ -92,6 +92,7 @@ nsUXThemeData::DwmSetIconicThumbnailProc nsUXThemeData::dwmSetIconicThumbnailPtr nsUXThemeData::DwmSetIconicLivePreviewBitmapProc nsUXThemeData::dwmSetIconicLivePreviewBitmapPtr = NULL; nsUXThemeData::DwmSetWindowAttributeProc nsUXThemeData::dwmSetWindowAttributePtr = NULL; nsUXThemeData::DwmInvalidateIconicBitmapsProc nsUXThemeData::dwmInvalidateIconicBitmapsPtr = NULL; +nsUXThemeData::DwmDefWindowProcProc nsUXThemeData::dwmDwmDefWindowProcPtr = NULL; #endif void @@ -136,6 +137,7 @@ nsUXThemeData::Initialize() dwmSetIconicLivePreviewBitmapPtr = (DwmSetIconicLivePreviewBitmapProc)::GetProcAddress(sDwmDLL, "DwmSetIconicLivePreviewBitmap"); dwmSetWindowAttributePtr = (DwmSetWindowAttributeProc)::GetProcAddress(sDwmDLL, "DwmSetWindowAttribute"); dwmInvalidateIconicBitmapsPtr = (DwmInvalidateIconicBitmapsProc)::GetProcAddress(sDwmDLL, "DwmInvalidateIconicBitmaps"); + dwmDwmDefWindowProcPtr = (DwmDefWindowProcProc)::GetProcAddress(sDwmDLL, "DwmDefWindowProc"); CheckForCompositor(); } #endif diff --git a/widget/src/windows/nsUXThemeData.h b/widget/src/windows/nsUXThemeData.h index 620a0dbef6c..effeea8dec7 100644 --- a/widget/src/windows/nsUXThemeData.h +++ b/widget/src/windows/nsUXThemeData.h @@ -178,6 +178,7 @@ public: typedef HRESULT (WINAPI*DwmSetIconicLivePreviewBitmapProc)(HWND hWnd, HBITMAP hBitmap, POINT *pptClient, DWORD dwSITFlags); typedef HRESULT (WINAPI*DwmSetWindowAttributeProc)(HWND hWnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); typedef HRESULT (WINAPI*DwmInvalidateIconicBitmapsProc)(HWND hWnd); + typedef HRESULT (WINAPI*DwmDefWindowProcProc)(HWND hWnd, UINT msg, LPARAM lParam, WPARAM wParam, LRESULT *aRetValue); static DwmExtendFrameIntoClientAreaProc dwmExtendFrameIntoClientAreaPtr; static DwmIsCompositionEnabledProc dwmIsCompositionEnabledPtr; @@ -185,6 +186,7 @@ public: static DwmSetIconicLivePreviewBitmapProc dwmSetIconicLivePreviewBitmapPtr; static DwmSetWindowAttributeProc dwmSetWindowAttributePtr; static DwmInvalidateIconicBitmapsProc dwmInvalidateIconicBitmapsPtr; + static DwmDefWindowProcProc dwmDwmDefWindowProcPtr; static PRBool CheckForCompositor() { BOOL compositionIsEnabled = FALSE; diff --git a/widget/src/windows/nsWindow.cpp b/widget/src/windows/nsWindow.cpp index 44c2c36f4e4..6b7a7a1db9e 100644 --- a/widget/src/windows/nsWindow.cpp +++ b/widget/src/windows/nsWindow.cpp @@ -141,6 +141,7 @@ #include "nsIFontMetrics.h" #include "nsIFontEnumerator.h" #include "nsIDeviceContext.h" +#include "nsILookAndFeel.h" #include "nsGUIEvent.h" #include "nsFont.h" #include "nsRect.h" @@ -370,10 +371,13 @@ nsWindow::nsWindow() : nsBaseWidget() mIsInMouseCapture = PR_FALSE; mIsTopWidgetWindow = PR_FALSE; mUnicodeWidget = PR_TRUE; + mDisplayPanFeedback = PR_FALSE; + mCustomNonClient = PR_FALSE; + mCompositorFlag = PR_FALSE; + mHideChrome = PR_FALSE; mWindowType = eWindowType_child; mBorderStyle = eBorderStyle_default; mPopupType = ePopupTypeAny; - mDisplayPanFeedback = PR_FALSE; mLastPoint.x = 0; mLastPoint.y = 0; mLastSize.width = 0; @@ -1719,8 +1723,8 @@ NS_METHOD nsWindow::SetFocus(PRBool aRaise) * * SECTION: Bounds * - * nsIWidget::GetBounds, nsIWidget::GetScreenBounds, - * nsIWidget::GetClientBounds + * GetBounds, GetClientBounds, GetScreenBounds, GetClientOffset + * SetDrawsInTitlebar, GetNonClientMargins, SetNonClientMargins * * Bound calculations. * @@ -1843,6 +1847,166 @@ NS_METHOD nsWindow::GetClientOffset(nsIntPoint &aPt) return NS_OK; } +void +nsWindow::SetDrawsInTitlebar(PRBool aState) +{ + nsWindow * window = GetTopLevelWindow(PR_TRUE); + if (window && window != this) { + return window->SetDrawsInTitlebar(aState); + } + + if (aState) { + // left, top, right, bottom for nsIntMargin + nsIntMargin margins(-1, 0, -1, -1); + SetNonClientMargins(margins); + } + else { + nsIntMargin margins(-1, -1, -1, -1); + SetNonClientMargins(margins); + } +} + +NS_IMETHODIMP +nsWindow::GetNonClientMargins(nsIntMargin &margins) +{ + nsWindow * window = GetTopLevelWindow(PR_TRUE); + if (window && window != this) { + return window->GetNonClientMargins(margins); + } + + if (mCustomNonClient) { + margins = mNonClientMargins; + return NS_OK; + } + + nsCOMPtr lookAndFeel = + do_GetService("@mozilla.org/widget/lookandfeel;1"); + if (!lookAndFeel) { + NS_WARNING("We need nsILookAndFeel for GetNonClientMargins!"); + return NS_ERROR_FAILURE; + } + + PRInt32 val; + lookAndFeel->GetMetric(nsILookAndFeel::eMetric_WindowTitleHeight, val); + margins.top = val; + lookAndFeel->GetMetric(nsILookAndFeel::eMetric_WindowBorderHeight, val); + margins.top += val; + margins.bottom = val; + lookAndFeel->GetMetric(nsILookAndFeel::eMetric_WindowBorderWidth, val); + margins.left = margins.right = val; + + return NS_OK; +} + +PRBool +nsWindow::UpdateNonClientMargins() +{ + if (!mCustomNonClient) + return PR_FALSE; + + // XXX Temp disable margins until frame rendering is supported + mCompositorFlag = PR_TRUE; + if(!nsUXThemeData::CheckForCompositor()) { + mCompositorFlag = PR_FALSE; + return PR_FALSE; + } + + mNonClientOffset.top = mNonClientOffset.bottom = + mNonClientOffset.left = mNonClientOffset.right = 0; + + nsCOMPtr lookAndFeel = + do_GetService("@mozilla.org/widget/lookandfeel;1"); + if (!lookAndFeel) { + NS_WARNING("We need nsILookAndFeel for UpdateNonClientMargins!"); + return PR_FALSE; + } + + // Used in hit testing, provides the resize cursor margin + lookAndFeel->GetMetric(nsILookAndFeel::eMetric_WindowBorderWidth, mResizeMargin); + lookAndFeel->GetMetric(nsILookAndFeel::eMetric_WindowTitleHeight, mCaptionHeight); + mCaptionHeight += mResizeMargin; + + // If a margin value is 0, set the offset to the default size of the frame. + // If a margin is -1, leave as default, and if a margin > 0, set the offset + // so that the frame size is equal to the margin value. + if (!mNonClientMargins.top) + mNonClientOffset.top = mCaptionHeight; + else if (mNonClientMargins.top > 0) + mNonClientOffset.top = mCaptionHeight - mNonClientMargins.top; + + if (!mNonClientMargins.left) + mNonClientOffset.left = mResizeMargin; + else if (mNonClientMargins.left > 0) + mNonClientOffset.left = mResizeMargin - mNonClientMargins.left; + + if (!mNonClientMargins.right) + mNonClientOffset.right = mResizeMargin; + else if (mNonClientMargins.right > 0) + mNonClientOffset.right = mResizeMargin - mNonClientMargins.right; + + PRInt32 val; + lookAndFeel->GetMetric(nsILookAndFeel::eMetric_WindowBorderHeight, val); + if (!mNonClientMargins.bottom) + mNonClientOffset.bottom = val; + else if (mNonClientMargins.bottom > 0) + mNonClientOffset.bottom = val - mNonClientMargins.bottom; + + NS_ASSERTION(mNonClientOffset.top >= 0, "non-client top margin is negative!"); + NS_ASSERTION(mNonClientOffset.left >= 0, "non-client left margin is negative!"); + NS_ASSERTION(mNonClientOffset.right >= 0, "non-client right margin is negative!"); + NS_ASSERTION(mNonClientOffset.bottom >= 0, "non-client bottom margin is negative!"); + + if (mNonClientOffset.top < 0) + mNonClientOffset.top = 0; + if (mNonClientOffset.left < 0) + mNonClientOffset.left = 0; + if (mNonClientOffset.right < 0) + mNonClientOffset.right = 0; + if (mNonClientOffset.bottom < 0) + mNonClientOffset.bottom = 0; + + SetWindowPos(mWnd, 0, 0, 0, 0, 0, + SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOMOVE| + SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER); + UpdateWindow(mWnd); + + return PR_TRUE; +} + +NS_IMETHODIMP +nsWindow::SetNonClientMargins(nsIntMargin &margins) +{ + if (!mIsTopWidgetWindow || + mBorderStyle & eBorderStyle_none || + mHideChrome) + return NS_ERROR_INVALID_ARG; + + // Request for a reset + if (margins.top == -1 && margins.left == -1 && + margins.right == -1 && margins.bottom == -1) { + mCustomNonClient = PR_FALSE; + mNonClientMargins = margins; + SetWindowPos(mWnd, 0, 0, 0, 0, 0, + SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOMOVE| + SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER); + UpdateWindow(mWnd); + return NS_OK; + } + + if (margins.top < -1 || margins.bottom < -1 || + margins.left < -1 || margins.right < -1) + return NS_ERROR_INVALID_ARG; + + mNonClientMargins = margins; + mCustomNonClient = PR_TRUE; + if (!UpdateNonClientMargins()) { + NS_WARNING("UpdateNonClientMargins failed!"); + return PR_FALSE; + } + + return NS_OK; +} + /************************************************************** * * SECTION: nsIWidget::SetBackgroundColor @@ -2145,11 +2309,16 @@ void nsWindow::UpdatePossiblyTransparentRegion(const nsIntRegion &aDirtyRegion, opaqueRegion.Or(opaqueRegion, childWindowRegion); // Sometimes child windows overlap our bounds opaqueRegion.And(opaqueRegion, clientBounds); + MARGINS margins = { 0, 0, 0, 0 }; DWORD_PTR dwStyle = ::GetWindowLongPtrW(hWnd, GWL_STYLE); - // If there is no opaque region or hidechrome=true then full glass - if (opaqueRegion.IsEmpty() || !(dwStyle & WS_CAPTION)) { - margins.cxLeftWidth = -1; + + // If there is no opaque region or hidechrome=true, set margins + // to support a full sheet of glass. + if (opaqueRegion.IsEmpty() || mHideChrome) { + // Comments in MSDN indicate all values must be set to -1 + margins.cxLeftWidth = margins.cxRightWidth = + margins.cyTopHeight = margins.cyBottomHeight = -1; } else { // Find the largest rectangle and use that to calculate the inset nsIntRect largest = opaqueRegion.GetLargestRectangle(); @@ -2158,6 +2327,8 @@ void nsWindow::UpdatePossiblyTransparentRegion(const nsIntRegion &aDirtyRegion, margins.cyTopHeight = largest.y; margins.cyBottomHeight = clientBounds.height - largest.YMost(); } + + // Only update glass area if there are changes if (memcmp(&mGlassMargins, &margins, sizeof mGlassMargins)) { mGlassMargins = margins; UpdateGlass(); @@ -2165,13 +2336,21 @@ void nsWindow::UpdatePossiblyTransparentRegion(const nsIntRegion &aDirtyRegion, #endif // #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN } -void nsWindow::UpdateGlass() { +void nsWindow::UpdateGlass() +{ #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN HWND hWnd = GetTopLevelHWND(mWnd, PR_TRUE); + + // DWMNCRP_USEWINDOWSTYLE - The non-client rendering area is + // rendered based on the window style. + // DWMNCRP_ENABLED - The non-client area rendering is + // enabled; the window style is ignored. DWMNCRENDERINGPOLICY policy = DWMNCRP_USEWINDOWSTYLE; - if(eTransparencyGlass == mTransparencyMode) { + if (mTransparencyMode == eTransparencyGlass) { policy = DWMNCRP_ENABLED; } + + // Extends the window frame behind the client area if(nsUXThemeData::CheckForCompositor()) { nsUXThemeData::dwmExtendFrameIntoClientAreaPtr(hWnd, &mGlassMargins); nsUXThemeData::dwmSetWindowAttributePtr(hWnd, DWMWA_NCRENDERING_POLICY, &policy, sizeof policy); @@ -2198,11 +2377,13 @@ NS_IMETHODIMP nsWindow::HideWindowChrome(PRBool aShouldHide) } DWORD_PTR style, exStyle; + mHideChrome = aShouldHide; if (aShouldHide) { DWORD_PTR tempStyle = ::GetWindowLongPtrW(hwnd, GWL_STYLE); DWORD_PTR tempExStyle = ::GetWindowLongPtrW(hwnd, GWL_EXSTYLE); - style = tempStyle & ~(WS_CAPTION | WS_THICKFRAME); + style = tempStyle & ~(WS_CAPTION | WS_THICKFRAME | WS_SYSMENU | + WS_MINIMIZEBOX | WS_MAXIMIZEBOX); exStyle = tempExStyle & ~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE); @@ -2210,10 +2391,17 @@ NS_IMETHODIMP nsWindow::HideWindowChrome(PRBool aShouldHide) mOldExStyle = tempExStyle; } else { - if (!mOldStyle || !mOldExStyle) { + if (!mOldStyle) mOldStyle = ::GetWindowLongPtrW(hwnd, GWL_STYLE); + if (!mOldExStyle) mOldExStyle = ::GetWindowLongPtrW(hwnd, GWL_EXSTYLE); - } + + if (mIsVisible) + mOldStyle |= WS_VISIBLE; + if (mSizeMode == nsSizeMode_Maximized) + mOldStyle |= WS_MAXIMIZE; + else if (mSizeMode == nsSizeMode_Minimized) + mOldStyle |= WS_MINIMIZE; style = mOldStyle; exStyle = mOldExStyle; @@ -4186,6 +4374,16 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam, static PRBool getWheelInfo = PR_TRUE; + // Glass hit testing w/custom transparent margins + LRESULT dwmHitResult; + if (mCustomNonClient && + mCompositorFlag && + nsUXThemeData::CheckForCompositor() && + nsUXThemeData::dwmDwmDefWindowProcPtr(mWnd, msg, wParam, lParam, &dwmHitResult)) { + *aRetValue = dwmHitResult; + return PR_TRUE; + } + switch (msg) { #ifndef WINCE // WM_QUERYENDSESSION must be handled by all windows. @@ -4270,6 +4468,9 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam, case WM_XP_THEMECHANGED: { + // Update non-client margin offsets + UpdateNonClientMargins(); + DispatchStandardEvent(NS_THEMECHANGED); // Invalidate the window so that the repaint will @@ -4309,6 +4510,62 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam, } break; + case WM_NCCALCSIZE: + { + // If wParam is TRUE, it specifies that the application should indicate + // which part of the client area contains valid information. The system + // copies the valid information to the specified area within the new + // client area. If the wParam parameter is FALSE, the application should + // return zero. + if (mCustomNonClient && mCompositorFlag) { + if (!wParam) { + result = PR_TRUE; + *aRetValue = 0; + break; + } + + // before: + // rgrc[0]: the proposed window + // rgrc[1]: the current window + // rgrc[2]: the source client area + // pncsp->lppos: move/size data + // after: + // rgrc[0]: the new client area + // rgrc[1]: the destination window + // rgrc[2]: the source client area + // (all values in screen coordiantes) + NCCALCSIZE_PARAMS *pncsp = reinterpret_cast(lParam); + LRESULT res = CallWindowProcW(GetPrevWindowProc(), mWnd, msg, wParam, lParam); + pncsp->rgrc[0].top -= mNonClientOffset.top; + pncsp->rgrc[0].left -= mNonClientOffset.left; + pncsp->rgrc[0].right += mNonClientOffset.right; + pncsp->rgrc[0].bottom += mNonClientOffset.bottom; + + result = PR_TRUE; + *aRetValue = res; + } + break; + } + + case WM_NCHITTEST: + { + /* + * If an nc client area margin has been moved, we are responsible + * for calculating where the resize margins are and returning the + * appropriate set of hit test constants. DwmDefWindowProc (above) + * will handle hit testing on it's command buttons if we are on a + * composited desktop. + */ + + if (!mCustomNonClient || !mCompositorFlag) + break; + + *aRetValue = + ClientMarginHitTestPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + result = PR_TRUE; + break; + } + #ifndef WINCE case WM_POWERBROADCAST: // only hidden window handle this @@ -4813,6 +5070,7 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam, #ifndef WINCE #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN case WM_DWMCOMPOSITIONCHANGED: + UpdateNonClientMargins(); BroadcastMsg(mWnd, WM_DWMCOMPOSITIONCHANGED); DispatchStandardEvent(NS_THEMECHANGED); UpdateGlass(); @@ -5094,6 +5352,71 @@ void nsWindow::GlobalMsgWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP * **************************************************************/ +PRInt32 +nsWindow::ClientMarginHitTestPoint(PRInt32 mx, PRInt32 my) +{ + // Calculations are done in screen coords + RECT winRect; + GetWindowRect(mWnd, &winRect); + + // hit return constants: + // HTBORDER - non-resizable border + // HTBOTTOM, HTLEFT, HTRIGHT, HTTOP - resizable border + // HTBOTTOMLEFT, HTBOTTOMRIGHT - resizable corner + // HTTOPLEFT, HTTOPRIGHT - resizable corner + // HTCAPTION - general title bar area + // HTCLIENT - area considered the client + // HTCLOSE - hovering over the close button + // HTMAXBUTTON - maximize button + // HTMINBUTTON - minimize button + + PRInt32 testResult = HTCLIENT; + + PRBool top = PR_FALSE; + PRBool bottom = PR_FALSE; + PRBool left = PR_FALSE; + PRBool right = PR_FALSE; + + if (my >= winRect.top && my <= + (winRect.top + (mCaptionHeight - mNonClientOffset.top))) + top = PR_TRUE; + else if (my <= winRect.bottom && my >= (winRect.bottom - mResizeMargin)) + bottom = PR_TRUE; + + if (mx >= winRect.left && mx <= (winRect.left + mResizeMargin)) + left = PR_TRUE; + else if (mx <= winRect.right && mx >= (winRect.right - mResizeMargin)) + right = PR_TRUE; + + if (top) { + testResult = HTTOP; + if (left) + testResult = HTTOPLEFT; + else if (right) + testResult = HTTOPRIGHT; + } else if (bottom) { + testResult = HTBOTTOM; + if (left) + testResult = HTBOTTOMLEFT; + else if (right) + testResult = HTBOTTOMRIGHT; + } else { + if (left) + testResult = HTLEFT; + if (right) + testResult = HTRIGHT; + } + + if (testResult == HTCLIENT && + my > (winRect.top + mResizeMargin) && + my <= (winRect.top + mCaptionHeight) && + my <= (winRect.top + (mCaptionHeight - mNonClientOffset.top))) + testResult = HTCAPTION; + + return testResult; +} + + #ifndef WINCE void nsWindow::PostSleepWakeNotification(const char* aNotification) { @@ -7027,34 +7350,21 @@ void nsWindow::SetWindowTranslucencyInner(nsTransparencyMode aMode) return; } - LONG_PTR style = 0, exStyle = 0; switch(aMode) { case eTransparencyTransparent: + { + LONG_PTR exStyle = topWindow->WindowStyle(); exStyle |= WS_EX_LAYERED; + ::SetWindowLongPtrW(hWnd, GWL_EXSTYLE, exStyle); + } case eTransparencyOpaque: case eTransparencyGlass: topWindow->mTransparencyMode = aMode; break; } - style |= topWindow->WindowStyle(); - exStyle |= topWindow->WindowExStyle(); - - if (aMode == eTransparencyTransparent) { - style &= ~(WS_CAPTION | WS_THICKFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX); - exStyle &= ~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE); - } - - if (topWindow->mIsVisible) - style |= WS_VISIBLE; - if (topWindow->mSizeMode == nsSizeMode_Maximized) - style |= WS_MAXIMIZE; - else if (topWindow->mSizeMode == nsSizeMode_Minimized) - style |= WS_MINIMIZE; - - VERIFY_WINDOW_STYLE(style); - ::SetWindowLongPtrW(hWnd, GWL_STYLE, style); - ::SetWindowLongPtrW(hWnd, GWL_EXSTYLE, exStyle); + // Hide chrome supports caching old styles, so this can be flipped back and forth + topWindow->HideWindowChrome(aMode == eTransparencyTransparent); #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN if (mTransparencyMode == eTransparencyGlass) diff --git a/widget/src/windows/nsWindow.h b/widget/src/windows/nsWindow.h index 856aed63812..fbee5c0b270 100644 --- a/widget/src/windows/nsWindow.h +++ b/widget/src/windows/nsWindow.h @@ -197,6 +197,9 @@ public: NS_IMETHOD OnIMETextChange(PRUint32 aStart, PRUint32 aOldEnd, PRUint32 aNewEnd); NS_IMETHOD OnIMESelectionChange(void); #endif // NS_ENABLE_TSF + NS_IMETHOD GetNonClientMargins(nsIntMargin &margins); + NS_IMETHOD SetNonClientMargins(nsIntMargin &margins); + void SetDrawsInTitlebar(PRBool aState); /** * Statics used in other classes @@ -284,6 +287,7 @@ protected: nsWindow* GetParentWindow(PRBool aIncludeOwner); virtual void SubclassWindow(BOOL bState); PRBool CanTakeFocus(); + PRBool UpdateNonClientMargins(); #if !defined(WINCE) static void InitTrackPointHack(); #endif @@ -319,6 +323,7 @@ protected: PRBool& aResult, LRESULT* aRetValue, PRBool& aQuitProcessing); + PRInt32 ClientMarginHitTestPoint(PRInt32 mx, PRInt32 my); /** * Event handlers @@ -449,6 +454,7 @@ protected: HKL mLastKeyboardLayout; nsPopupType mPopupType; PRPackedBool mDisplayPanFeedback; + PRPackedBool mHideChrome; WindowHook mWindowHook; static PRUint32 sInstanceCount; static TriStateBool sCanQuit; @@ -467,6 +473,20 @@ protected: static PRUint32 sOOPPPluginFocusEvent; #endif + // Non-client margin settings + // Pre-calculated outward offset applied to default frames + nsIntMargin mNonClientOffset; + // Margins set by the owner + nsIntMargin mNonClientMargins; + // Indicates custom frames are enabled + PRPackedBool mCustomNonClient; + // Disable non client margins on non-comsitor desktops + PRPackedBool mCompositorFlag; + // Cached copy of L&F's resize border + PRInt32 mResizeMargin; + // Height of the caption plus border + PRInt32 mCaptionHeight; + nsCOMPtr mIdleService; // Hook Data Memebers for Dropdowns. sProcessHook Tells the