From b3362334e8c44e50131a9dfdef964526fe9dc5ff Mon Sep 17 00:00:00 2001 From: "peterlubczynski%netscape.com" Date: Tue, 11 Jun 2002 03:55:03 +0000 Subject: [PATCH] Fixing bug 120875, flash repsonds to mouse events in other tab and can't hide plugins, r=bnesse sr=beard a=valeski git-svn-id: svn://10.0.0.236/branches/MOZILLA_1_0_BRANCH@123022 18797224-902f-48f8-a5cc-f745e15eee43 --- .../layout/html/base/src/nsObjectFrame.cpp | 82 ++++++++++++------- .../plugin/base/src/nsPluginViewer.cpp | 37 +++++++-- 2 files changed, 83 insertions(+), 36 deletions(-) diff --git a/mozilla/layout/html/base/src/nsObjectFrame.cpp b/mozilla/layout/html/base/src/nsObjectFrame.cpp index 82c35662653..63a7ff3e997 100644 --- a/mozilla/layout/html/base/src/nsObjectFrame.cpp +++ b/mozilla/layout/html/base/src/nsObjectFrame.cpp @@ -325,6 +325,7 @@ private: nsCOMPtr mPluginTimer; nsIPluginHost *mPluginHost; PRPackedBool mContentFocused; + PRPackedBool mWidgetVisible; // used on Mac to store our widget's visible state PRUint16 mNumCachedAttrs; PRUint16 mNumCachedParams; char **mCachedAttrParamNames; @@ -344,7 +345,7 @@ static void ConvertTwipsToPixels(nsIPresContext& aPresContext, nsRect& aTwipsRec // Mac specific code to fix up port position and clip during paint #ifdef XP_MAC // get the absolute widget position and clip - static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY, nsRect& aClipRect); + static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY, nsRect& aClipRect, PRBool& aIsVisible); // convert relative coordinates to absolute static void ConvertRelativeToWindowAbsolute(nsIFrame* aFrame, nsIPresContext* aPresContext, nsPoint& aRel, nsPoint& aAbs, nsIWidget *&aContainerWidget); #endif // XP_MAC @@ -1463,26 +1464,25 @@ nsObjectFrame::DidReflow(nsIPresContext* aPresContext, vm->SetViewVisibility(view, bHidden ? nsViewVisibility_kHide : nsViewVisibility_kShow); } - if (bHidden) - return rv; - nsPluginWindow *window; - - if (!mInstanceOwner || NS_FAILED(mInstanceOwner->GetWindow(window))) + + nsCOMPtr pi; + if (!mInstanceOwner || + NS_FAILED(rv = mInstanceOwner->GetWindow(window)) || + NS_FAILED(rv = mInstanceOwner->GetInstance(*getter_AddRefs(pi))) || + !pi || + !window) return rv; - PRBool windowless = (window->type == nsPluginWindowType_Drawable); - - // if we are on Mac or windowless on Windows we will get Paint - // event anyway so there is no need to update plugin window - // and call NPP_SetWindow here, it'll be done in Paint. - // Windowed plugins thought need it to be done here, there will - // no chance to do it later because they will get paint event - // from the OS itself #ifdef XP_MAC + mInstanceOwner->FixUpPluginWindow(); return rv; #endif // XP_MAC + if (bHidden) + return rv; + + PRBool windowless = (window->type == nsPluginWindowType_Drawable); if(windowless) return rv; @@ -1494,14 +1494,7 @@ nsObjectFrame::DidReflow(nsIPresContext* aPresContext, // refresh the plugin port as well window->window = mInstanceOwner->GetPluginPort(); - - nsIPluginInstance *inst; - - if (NS_OK == mInstanceOwner->GetInstance(inst)) { - inst->SetWindow(window); - NS_RELEASE(inst); - } - + pi->SetWindow(window); mInstanceOwner->ReleasePluginPort((nsPluginPort *)window->window); if (mWidget) { @@ -2043,6 +2036,7 @@ nsPluginInstanceOwner::nsPluginInstanceOwner() mTagText = nsnull; mPluginHost = nsnull; mContentFocused = PR_FALSE; + mWidgetVisible = PR_TRUE; mNumCachedAttrs = 0; mNumCachedParams = 0; mCachedAttrParamNames = nsnull; @@ -3212,6 +3206,10 @@ nsPluginInstanceOwner::MouseMove(nsIDOMEvent* aMouseEvent) // continue only for cases without child window #endif + // don't send mouse events if we are hiddden + if (!mWidgetVisible) + return NS_OK; + nsCOMPtr privateEvent(do_QueryInterface(aMouseEvent)); if (privateEvent) { nsMouseEvent* mouseEvent = nsnull; @@ -3304,6 +3302,10 @@ nsresult nsPluginInstanceOwner::DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent) // continue only for cases without child window #endif + // don't send mouse events if we are hiddden + if (!mWidgetVisible) + return NS_OK; + nsCOMPtr privateEvent(do_QueryInterface(aMouseEvent)); if (privateEvent) { nsMouseEvent* mouseEvent = nsnull; @@ -3542,6 +3544,11 @@ NS_IMETHODIMP_(void) nsPluginInstanceOwner::Notify(nsITimer* /* timer */) EventRecord idleEvent; InitializeEventRecord(&idleEvent); idleEvent.what = nullEvent; + + // give a bogus 'where' field of our null event when hidden, so Flash + // won't respond to mouse moves in other tabs, see bug 120875 + if (!mWidgetVisible) + idleEvent.where.h = idleEvent.where.v = 20000; nsPluginPort* pluginPort = GetPluginPort(); nsPluginEvent pluginEvent = { &idleEvent, nsPluginPlatformWindowRef(pluginPort->port) }; @@ -3788,9 +3795,12 @@ static void ConvertTwipsToPixels(nsIPresContext& aPresContext, nsRect& aTwipsRec #ifdef XP_MAC // calculate the absolute position and clip for a widget // and use other windows in calculating the clip -static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY, - nsRect& aClipRect) +static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY, + nsRect& aClipRect, PRBool& aIsVisible) { + if (aIsVisible) + aWidget->IsVisible(aIsVisible); + aWidget->GetBounds(aClipRect); aAbsX = aClipRect.x; aAbsY = aClipRect.y; @@ -3800,10 +3810,12 @@ static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbs aClipRect.x = 0; aClipRect.y = 0; - // Gather up the absolute position of the widget - // + clip window + // Gather up the absolute position of the widget, clip window, and visibilty nsCOMPtr widget = getter_AddRefs(aWidget->GetParent()); while (widget != nsnull) { + if (aIsVisible) + widget->IsVisible(aIsVisible); + nsRect wrect; widget->GetClientBounds(wrect); nscoord wx, wy; @@ -3828,6 +3840,10 @@ static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbs aClipRect.x += aAbsX; aClipRect.y += aAbsY; + // if we are not visible, clear out the plugin's clip so it won't paint + if (!aIsVisible) + aClipRect.Empty(); + //printf("--------------\n"); //printf("Widget clip X %d Y %d rect %d %d %d %d\n", aAbsX, aAbsY, aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height ); //printf("--------------\n"); @@ -3900,7 +3916,18 @@ void nsPluginInstanceOwner::FixUpPluginWindow() nscoord absWidgetX = 0; nscoord absWidgetY = 0; nsRect widgetClip(0,0,0,0); - GetWidgetPosAndClip(mWidget,absWidgetX,absWidgetY,widgetClip); + + // first, check our view for CSS visibility style + nsIView *view; + mOwner->GetView(mContext, &view); + nsViewVisibility vis; + view->GetVisibility(vis); + PRBool isVisible = (vis == nsViewVisibility_kShow) ? PR_TRUE : PR_FALSE; + + GetWidgetPosClipAndVis(mWidget,absWidgetX,absWidgetY,widgetClip,isVisible); + + if (mWidgetVisible != isVisible) + mWidgetVisible = isVisible; // set the port coordinates mPluginWindow.x = absWidgetX; @@ -3929,5 +3956,4 @@ void nsPluginInstanceOwner::FixUpPluginWindow() } } - #endif // XP_MAC diff --git a/mozilla/modules/plugin/base/src/nsPluginViewer.cpp b/mozilla/modules/plugin/base/src/nsPluginViewer.cpp index 2b0dadfa601..2579e5f16cd 100644 --- a/mozilla/modules/plugin/base/src/nsPluginViewer.cpp +++ b/mozilla/modules/plugin/base/src/nsPluginViewer.cpp @@ -167,11 +167,12 @@ private: nsIWidget *mWindow; //we do not addref this... PluginViewerImpl *mViewer; //we do not addref this... nsCOMPtr mPluginTimer; + PRPackedBool mWidgetVisible; // used on Mac to store our widget's visible state }; #ifdef XP_MAC - static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY, - nsRect& aClipRect); + static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY, + nsRect& aClipRect, PRBool& aIsVisible); #endif class PluginViewerImpl : public nsIPluginViewer, @@ -1025,6 +1026,7 @@ pluginInstanceOwner :: pluginInstanceOwner() mInstance = nsnull; mWindow = nsnull; mViewer = nsnull; + mWidgetVisible = PR_TRUE; } pluginInstanceOwner :: ~pluginInstanceOwner() @@ -1339,6 +1341,11 @@ NS_IMETHODIMP_(void) pluginInstanceOwner::Notify(nsITimer* /* timer */) EventRecord idleEvent; InitializeEventRecord(&idleEvent); idleEvent.what = nullEvent; + + // give a bogus 'where' field of our null event when hidden, so Flash + // won't respond to mouse moves in other tabs, see bug 120875 + if (!mWidgetVisible) + idleEvent.where.h = idleEvent.where.v = 20000; nsPluginPort* pluginPort = GetPluginPort(); nsPluginEvent pluginEvent = { &idleEvent, nsPluginPlatformWindowRef(pluginPort->port) }; @@ -1380,9 +1387,13 @@ nsPluginPort* pluginInstanceOwner::GetPluginPort() // calculate the absolute position and clip for a widget // and use other windows in calculating the clip -static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY, - nsRect& aClipRect) + // also find out if we are visible or not +static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY, + nsRect& aClipRect, PRBool& aIsVisible) { + if (aIsVisible) + aWidget->IsVisible(aIsVisible); + aWidget->GetBounds(aClipRect); aAbsX = aClipRect.x; aAbsY = aClipRect.y; @@ -1392,10 +1403,12 @@ static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbs aClipRect.x = 0; aClipRect.y = 0; - // Gather up the absolute position of the widget - // + clip window + // Gather up the absolute position of the widget, clip window, and visibilty nsCOMPtr widget = getter_AddRefs(aWidget->GetParent()); while (widget != nsnull) { + if (aIsVisible) + widget->IsVisible(aIsVisible); + nsRect wrect; widget->GetClientBounds(wrect); nscoord wx, wy; @@ -1420,6 +1433,10 @@ static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbs aClipRect.x += aAbsX; aClipRect.y += aAbsY; + // if we are not visible, clear out the plugin's clip so it won't paint + if (!aIsVisible) + aClipRect.Empty(); + //printf("--------------\n"); //printf("Widget clip X %d Y %d rect %d %d %d %d\n", aAbsX, aAbsY, aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height ); //printf("--------------\n"); @@ -1432,7 +1449,11 @@ void pluginInstanceOwner::FixUpPluginWindow() nscoord absWidgetX = 0; nscoord absWidgetY = 0; nsRect widgetClip(0,0,0,0); - GetWidgetPosAndClip(mWindow,absWidgetX,absWidgetY,widgetClip); + PRBool isVisible = PR_TRUE; + GetWidgetPosClipAndVis(mWindow,absWidgetX,absWidgetY,widgetClip,isVisible); + + if (mWidgetVisible != isVisible) + mWidgetVisible = isVisible; // set the port coordinates mPluginWindow.x = absWidgetX; @@ -1442,7 +1463,7 @@ void pluginInstanceOwner::FixUpPluginWindow() mPluginWindow.clipRect.top = widgetClip.y; mPluginWindow.clipRect.left = widgetClip.x; mPluginWindow.clipRect.bottom = mPluginWindow.clipRect.top + widgetClip.height; - mPluginWindow.clipRect.right = mPluginWindow.clipRect.left + widgetClip.width; + mPluginWindow.clipRect.right = mPluginWindow.clipRect.left + widgetClip.width; } }