Bug 450944 - Implement -moz-window-shadow functionality on Mac OS X, r=hwaara sr=roc.

This patch turns on window shadows for transparent windows by default, so the identity popup and the "edit bookmarks" popup will get a shadow, too. ui-r=faaborg
This commit is contained in:
Markus Stange 2008-10-14 17:33:40 +02:00
parent 0116ce7b3a
commit e00fee0e90
10 changed files with 115 additions and 10 deletions

View File

@ -42,6 +42,7 @@
#define nsStyleConsts_h___
#include "nsFont.h"
#include "nsIWidget.h"
// cairo doesn't support invert
// #define GFX_HAS_INVERT
@ -710,10 +711,6 @@
#define NS_STYLE_IME_MODE_DISABLED 3
#define NS_STYLE_IME_MODE_INACTIVE 4
// See nsStyleUIReset
#define NS_STYLE_WINDOW_SHADOW_NONE 0
#define NS_STYLE_WINDOW_SHADOW_DEFAULT 1
#ifdef MOZ_SVG
// See nsStyleSVG

View File

@ -508,7 +508,10 @@ SyncFrameViewGeometryDependentProperties(nsPresContext* aPresContext,
nsIFrame *rootFrame = aPresContext->PresShell()->FrameConstructor()->GetRootElementStyleFrame();
if(rootFrame && NS_THEME_WIN_GLASS == rootFrame->GetStyleDisplay()->mAppearance)
mode = eTransparencyGlass;
aView->GetWidget()->SetTransparencyMode(mode);
nsIWidget* widget = aView->GetWidget();
widget->SetTransparencyMode(mode);
if (rootFrame)
widget->SetWindowShadowStyle(rootFrame->GetStyleUIReset()->mWindowShadow);
}
}
}

View File

@ -280,7 +280,10 @@ nsMenuPopupFrame::CreateWidgetForView(nsIView* aView)
aView->CreateWidget(kCChildCID, &widgetData, nsnull, PR_TRUE, PR_TRUE,
eContentTypeInherit, parentWidget);
#endif
aView->GetWidget()->SetTransparencyMode(mode);
nsIWidget* widget = aView->GetWidget();
widget->SetTransparencyMode(viewHasTransparentContent ?
eTransparencyTransparent : eTransparencyOpaque);
widget->SetWindowShadowStyle(GetStyleUIReset()->mWindowShadow);
return NS_OK;
}

View File

@ -93,16 +93,24 @@ typedef nsEventStatus (* EVENT_CALLBACK)(nsGUIEvent *event);
#define NS_NATIVE_PLUGIN_PORT_CG 101
#endif
// 0e64821f-00a2-4adc-ac3b-3439d61f4491
// 8c91457a-ef86-4da1-b4f9-36022dcc6c7e
#define NS_IWIDGET_IID \
{ 0x0e64821f, 0x00a2, 0x4adc, \
{ 0xac, 0x3b, 0x34, 0x39, 0xd6, 0x1f, 0x44, 0x91 } }
{ 0x8c91457a, 0xef86, 0x4da1, \
{ 0xb4, 0xf9, 0x36, 0x02, 0x2d, 0xcc, 0x6c, 0x7e } }
// Hide the native window systems real window type so as to avoid
// including native window system types and APIs. This is necessary
// to ensure cross-platform code.
typedef void* nsNativeWidget;
/*
* Window shadow styles
* Also used for the -moz-window-shadow CSS property
*/
#define NS_STYLE_WINDOW_SHADOW_NONE 0
#define NS_STYLE_WINDOW_SHADOW_DEFAULT 1
/**
* Border styles
*/
@ -711,6 +719,11 @@ class nsIWidget : public nsISupports {
*/
virtual nsTransparencyMode GetTransparencyMode() = 0;
/**
* Set the shadow style of the window.
*/
NS_IMETHOD SetWindowShadowStyle(PRInt32 aStyle) = 0;
/**
* Hide window chrome (borders, buttons) for this widget.
*

View File

@ -166,6 +166,8 @@ enum {
// All views are always opaque (non-transparent). The only exception is when we're
// the content view in a transparent XUL window.
BOOL mIsTransparent;
PRIntervalTime mLastShadowInvalidation;
BOOL mNeedsShadowInvalidation;
// Holds our drag service across multiple drag calls. The reference to the
// service is obtained when the mouse enters the view and is released when
@ -366,6 +368,7 @@ public:
virtual nsTransparencyMode GetTransparencyMode();
virtual void SetTransparencyMode(nsTransparencyMode aMode);
NS_IMETHOD SetWindowShadowStyle(PRInt32 aStyle);
// Mac specific methods
virtual PRBool PointInWidget(Point aThePoint);

View File

@ -179,6 +179,9 @@ nsIWidget * gRollupWidget = nsnull;
- (BOOL)isPaintingSuppressed;
- (void)maybeInvalidateShadow;
- (void)invalidateShadow;
#if USE_CLICK_HOLD_CONTEXTMENU
// called on a timer two seconds after a mouse down to see if we should display
// a context menu (click-hold)
@ -777,6 +780,28 @@ void nsChildView::SetTransparencyMode(nsTransparencyMode aMode)
}
// This is called by nsContainerFrame on the root widget for all window types
// except popup windows (when nsCocoaWindow::SetWindowShadowStyle is used instead).
NS_IMETHODIMP nsChildView::SetWindowShadowStyle(PRInt32 aStyle)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
// Find out if this is a window we created by seeing if the delegate is WindowDelegate. If it is,
// tell the nsCocoaWindow to set the shadow style.
id windowDelegate = [[mView nativeWindow] delegate];
if (windowDelegate && [windowDelegate isKindOfClass:[WindowDelegate class]]) {
nsCocoaWindow *widget = [(WindowDelegate *)windowDelegate geckoWidget];
if (widget) {
widget->SetWindowShadowStyle(aStyle);
}
}
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
NS_IMETHODIMP nsChildView::IsVisible(PRBool& outState)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
@ -2733,6 +2758,38 @@ NSEvent* gLastDragEvent = nil;
}
// Limit shadow invalidation to 10 times per second.
static const PRInt32 sShadowInvalidationInterval = 100;
- (void)maybeInvalidateShadow
{
if (!mIsTransparent || ![mWindow hasShadow])
return;
PRIntervalTime now = PR_IntervalNow();
PRInt32 elapsed = PR_IntervalToMilliseconds(now - mLastShadowInvalidation);
if (!mLastShadowInvalidation ||
elapsed >= sShadowInvalidationInterval) {
[mWindow invalidateShadow];
mLastShadowInvalidation = now;
mNeedsShadowInvalidation = NO;
} else if (!mNeedsShadowInvalidation) {
mNeedsShadowInvalidation = YES;
[self performSelector:@selector(invalidateShadow)
withObject:nil
afterDelay:(sShadowInvalidationInterval - elapsed) / 1000.0];
}
}
- (void)invalidateShadow
{
if (!mNeedsShadowInvalidation)
return;
[mWindow invalidateShadow];
mNeedsShadowInvalidation = NO;
}
- (BOOL)isPaintingSuppressed
{
NSWindow* win = [self window];
@ -2811,6 +2868,10 @@ NSEvent* gLastDragEvent = nil;
if (!mGeckoChild)
return;
// If we're a transparent window, and our contents have changed, we need
// to make sure the shadow is updated to the new contents.
[self maybeInvalidateShadow];
paintEvent.renderingContext = nsnull;
paintEvent.region = nsnull;

View File

@ -276,6 +276,7 @@ public:
NS_IMETHOD GetAttention(PRInt32 aCycleCount);
virtual nsTransparencyMode GetTransparencyMode();
virtual void SetTransparencyMode(nsTransparencyMode aMode);
NS_IMETHOD SetWindowShadowStyle(PRInt32 aStyle);
NS_IMETHOD SetWindowTitlebarColor(nscolor aColor, PRBool aActive);
// dispatch an NS_SIZEMODE event on miniaturize or deminiaturize

View File

@ -65,6 +65,7 @@
#include "nsIDOMElement.h"
#include "nsMenuBarX.h"
#include "nsMenuUtilsX.h"
#include "nsStyleConsts.h"
#include "gfxPlatform.h"
#include "lcms.h"
@ -800,7 +801,6 @@ void nsCocoaWindow::MakeBackgroundTransparent(PRBool aTransparent)
}
[mWindow setOpaque:!aTransparent];
[mWindow setBackgroundColor:(aTransparent ? [NSColor clearColor] : [NSColor whiteColor])];
[mWindow setHasShadow:!aTransparent];
}
NS_OBJC_END_TRY_ABORT_BLOCK;
@ -1317,6 +1317,18 @@ NS_IMETHODIMP nsCocoaWindow::GetAttention(PRInt32 aCycleCount)
}
NS_IMETHODIMP nsCocoaWindow::SetWindowShadowStyle(PRInt32 aStyle)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
if ([mWindow hasShadow] != (aStyle != NS_STYLE_WINDOW_SHADOW_NONE))
[mWindow setHasShadow:(aStyle != NS_STYLE_WINDOW_SHADOW_NONE)];
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
NS_IMETHODIMP nsCocoaWindow::SetWindowTitlebarColor(nscolor aColor, PRBool aActive)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;

View File

@ -568,6 +568,17 @@ nsTransparencyMode nsBaseWidget::GetTransparencyMode() {
return eTransparencyOpaque;
}
//-------------------------------------------------------------------------
//
// Set window shadow style
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsBaseWidget::SetWindowShadowStyle(PRInt32 aMode)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//-------------------------------------------------------------------------
//
// Hide window borders/decorations for this widget

View File

@ -106,6 +106,7 @@ public:
NS_IMETHOD SetWindowType(nsWindowType aWindowType);
virtual void SetTransparencyMode(nsTransparencyMode aMode);
virtual nsTransparencyMode GetTransparencyMode();
NS_IMETHOD SetWindowShadowStyle(PRInt32 aStyle);
NS_IMETHOD HideWindowChrome(PRBool aShouldHide);
NS_IMETHOD MakeFullScreen(PRBool aFullScreen);
virtual nsIRenderingContext* GetRenderingContext();