Fixing problems with showing/hiding Mac plugins. Specifically, these problems:

* Mouse events "bleeding through" tabs so that a plugin in one tab responds to mouse movements in another (bug 120875)
* dynamic control of CSS visiblity property with plugins on mac (can hide/show plugins) (bug 137230)
* Plugins incorrectly show up on top of documents and in the wrong place in print preview. This fix will also them to be hidden like they are on other platforms. (bug 133992)
r=av sr=beard
This commit is contained in:
peterlubczynski%netscape.com 2002-05-02 22:47:49 +00:00
Родитель 1452527607
Коммит 9404e003ab
3 изменённых файлов: 123 добавлений и 63 удалений

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

@ -325,6 +325,7 @@ private:
nsCOMPtr<nsITimer> mPluginTimer; nsCOMPtr<nsITimer> mPluginTimer;
nsIPluginHost *mPluginHost; nsIPluginHost *mPluginHost;
PRPackedBool mContentFocused; PRPackedBool mContentFocused;
PRPackedBool mWidgetVisible; // used on Mac to store our widget's visible state
PRUint16 mNumCachedAttrs; PRUint16 mNumCachedAttrs;
PRUint16 mNumCachedParams; PRUint16 mNumCachedParams;
char **mCachedAttrParamNames; 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 // Mac specific code to fix up port position and clip during paint
#ifdef XP_MAC #ifdef XP_MAC
// get the absolute widget position and clip // 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 // convert relative coordinates to absolute
static void ConvertRelativeToWindowAbsolute(nsIFrame* aFrame, nsIPresContext* aPresContext, nsPoint& aRel, nsPoint& aAbs, nsIWidget *&aContainerWidget); static void ConvertRelativeToWindowAbsolute(nsIFrame* aFrame, nsIPresContext* aPresContext, nsPoint& aRel, nsPoint& aAbs, nsIWidget *&aContainerWidget);
#endif // XP_MAC #endif // XP_MAC
@ -1463,26 +1464,25 @@ nsObjectFrame::DidReflow(nsIPresContext* aPresContext,
vm->SetViewVisibility(view, bHidden ? nsViewVisibility_kHide : nsViewVisibility_kShow); vm->SetViewVisibility(view, bHidden ? nsViewVisibility_kHide : nsViewVisibility_kShow);
} }
if (bHidden)
return rv;
nsPluginWindow *window; nsPluginWindow *window;
if (!mInstanceOwner || NS_FAILED(mInstanceOwner->GetWindow(window))) nsCOMPtr<nsIPluginInstance> pi;
if (!mInstanceOwner ||
NS_FAILED(rv = mInstanceOwner->GetWindow(window)) ||
NS_FAILED(rv = mInstanceOwner->GetInstance(*getter_AddRefs(pi))) ||
!pi ||
!window)
return rv; 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 #ifdef XP_MAC
mInstanceOwner->FixUpPluginWindow();
return rv; return rv;
#endif // XP_MAC #endif // XP_MAC
if (bHidden)
return rv;
PRBool windowless = (window->type == nsPluginWindowType_Drawable);
if(windowless) if(windowless)
return rv; return rv;
@ -1494,14 +1494,7 @@ nsObjectFrame::DidReflow(nsIPresContext* aPresContext,
// refresh the plugin port as well // refresh the plugin port as well
window->window = mInstanceOwner->GetPluginPort(); window->window = mInstanceOwner->GetPluginPort();
pi->SetWindow(window);
nsIPluginInstance *inst;
if (NS_OK == mInstanceOwner->GetInstance(inst)) {
inst->SetWindow(window);
NS_RELEASE(inst);
}
mInstanceOwner->ReleasePluginPort((nsPluginPort *)window->window); mInstanceOwner->ReleasePluginPort((nsPluginPort *)window->window);
if (mWidget) { if (mWidget) {
@ -2045,6 +2038,7 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
mTagText = nsnull; mTagText = nsnull;
mPluginHost = nsnull; mPluginHost = nsnull;
mContentFocused = PR_FALSE; mContentFocused = PR_FALSE;
mWidgetVisible = PR_TRUE;
mNumCachedAttrs = 0; mNumCachedAttrs = 0;
mNumCachedParams = 0; mNumCachedParams = 0;
mCachedAttrParamNames = nsnull; mCachedAttrParamNames = nsnull;
@ -3790,9 +3784,12 @@ static void ConvertTwipsToPixels(nsIPresContext& aPresContext, nsRect& aTwipsRec
#ifdef XP_MAC #ifdef XP_MAC
// calculate the absolute position and clip for a widget // calculate the absolute position and clip for a widget
// and use other windows in calculating the clip // and use other windows in calculating the clip
static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY, static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY,
nsRect& aClipRect) nsRect& aClipRect, PRBool& aIsVisible)
{ {
if (aIsVisible)
aWidget->IsVisible(aIsVisible);
aWidget->GetBounds(aClipRect); aWidget->GetBounds(aClipRect);
aAbsX = aClipRect.x; aAbsX = aClipRect.x;
aAbsY = aClipRect.y; aAbsY = aClipRect.y;
@ -3802,10 +3799,12 @@ static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbs
aClipRect.x = 0; aClipRect.x = 0;
aClipRect.y = 0; aClipRect.y = 0;
// Gather up the absolute position of the widget // Gather up the absolute position of the widget, clip window, and visibilty
// + clip window
nsCOMPtr<nsIWidget> widget = getter_AddRefs(aWidget->GetParent()); nsCOMPtr<nsIWidget> widget = getter_AddRefs(aWidget->GetParent());
while (widget != nsnull) { while (widget != nsnull) {
if (aIsVisible)
widget->IsVisible(aIsVisible);
nsRect wrect; nsRect wrect;
widget->GetClientBounds(wrect); widget->GetClientBounds(wrect);
nscoord wx, wy; nscoord wx, wy;
@ -3902,7 +3901,15 @@ void nsPluginInstanceOwner::FixUpPluginWindow()
nscoord absWidgetX = 0; nscoord absWidgetX = 0;
nscoord absWidgetY = 0; nscoord absWidgetY = 0;
nsRect widgetClip(0,0,0,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);
// set the port coordinates // set the port coordinates
mPluginWindow.x = absWidgetX; mPluginWindow.x = absWidgetX;
@ -3928,8 +3935,20 @@ void nsPluginInstanceOwner::FixUpPluginWindow()
macColor.blue = COLOR8TOCOLOR16(NS_GET_B(color)); macColor.blue = COLOR8TOCOLOR16(NS_GET_B(color));
::RGBBackColor(&macColor); ::RGBBackColor(&macColor);
::SetPort(savePort); // restore port ::SetPort(savePort); // restore port
// now we need to check if we've been hidden or made visible and then update the plugin
// with the correct port if visible or null if hidden,
// if visiblity has changed, then update the plugin
if (isVisible != mWidgetVisible) {
mWidgetVisible = isVisible;
nsPluginWindow *window;
GetWindow(window);
if (window && mInstance) {
window->window = mWidgetVisible ? GetPluginPort() : nsnull;
mInstance->SetWindow(window);
}
}
} }
} }
#endif // XP_MAC #endif // XP_MAC

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

@ -325,6 +325,7 @@ private:
nsCOMPtr<nsITimer> mPluginTimer; nsCOMPtr<nsITimer> mPluginTimer;
nsIPluginHost *mPluginHost; nsIPluginHost *mPluginHost;
PRPackedBool mContentFocused; PRPackedBool mContentFocused;
PRPackedBool mWidgetVisible; // used on Mac to store our widget's visible state
PRUint16 mNumCachedAttrs; PRUint16 mNumCachedAttrs;
PRUint16 mNumCachedParams; PRUint16 mNumCachedParams;
char **mCachedAttrParamNames; 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 // Mac specific code to fix up port position and clip during paint
#ifdef XP_MAC #ifdef XP_MAC
// get the absolute widget position and clip // 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 // convert relative coordinates to absolute
static void ConvertRelativeToWindowAbsolute(nsIFrame* aFrame, nsIPresContext* aPresContext, nsPoint& aRel, nsPoint& aAbs, nsIWidget *&aContainerWidget); static void ConvertRelativeToWindowAbsolute(nsIFrame* aFrame, nsIPresContext* aPresContext, nsPoint& aRel, nsPoint& aAbs, nsIWidget *&aContainerWidget);
#endif // XP_MAC #endif // XP_MAC
@ -1463,26 +1464,25 @@ nsObjectFrame::DidReflow(nsIPresContext* aPresContext,
vm->SetViewVisibility(view, bHidden ? nsViewVisibility_kHide : nsViewVisibility_kShow); vm->SetViewVisibility(view, bHidden ? nsViewVisibility_kHide : nsViewVisibility_kShow);
} }
if (bHidden)
return rv;
nsPluginWindow *window; nsPluginWindow *window;
if (!mInstanceOwner || NS_FAILED(mInstanceOwner->GetWindow(window))) nsCOMPtr<nsIPluginInstance> pi;
if (!mInstanceOwner ||
NS_FAILED(rv = mInstanceOwner->GetWindow(window)) ||
NS_FAILED(rv = mInstanceOwner->GetInstance(*getter_AddRefs(pi))) ||
!pi ||
!window)
return rv; 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 #ifdef XP_MAC
mInstanceOwner->FixUpPluginWindow();
return rv; return rv;
#endif // XP_MAC #endif // XP_MAC
if (bHidden)
return rv;
PRBool windowless = (window->type == nsPluginWindowType_Drawable);
if(windowless) if(windowless)
return rv; return rv;
@ -1494,14 +1494,7 @@ nsObjectFrame::DidReflow(nsIPresContext* aPresContext,
// refresh the plugin port as well // refresh the plugin port as well
window->window = mInstanceOwner->GetPluginPort(); window->window = mInstanceOwner->GetPluginPort();
pi->SetWindow(window);
nsIPluginInstance *inst;
if (NS_OK == mInstanceOwner->GetInstance(inst)) {
inst->SetWindow(window);
NS_RELEASE(inst);
}
mInstanceOwner->ReleasePluginPort((nsPluginPort *)window->window); mInstanceOwner->ReleasePluginPort((nsPluginPort *)window->window);
if (mWidget) { if (mWidget) {
@ -2045,6 +2038,7 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
mTagText = nsnull; mTagText = nsnull;
mPluginHost = nsnull; mPluginHost = nsnull;
mContentFocused = PR_FALSE; mContentFocused = PR_FALSE;
mWidgetVisible = PR_TRUE;
mNumCachedAttrs = 0; mNumCachedAttrs = 0;
mNumCachedParams = 0; mNumCachedParams = 0;
mCachedAttrParamNames = nsnull; mCachedAttrParamNames = nsnull;
@ -3790,9 +3784,12 @@ static void ConvertTwipsToPixels(nsIPresContext& aPresContext, nsRect& aTwipsRec
#ifdef XP_MAC #ifdef XP_MAC
// calculate the absolute position and clip for a widget // calculate the absolute position and clip for a widget
// and use other windows in calculating the clip // and use other windows in calculating the clip
static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY, static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY,
nsRect& aClipRect) nsRect& aClipRect, PRBool& aIsVisible)
{ {
if (aIsVisible)
aWidget->IsVisible(aIsVisible);
aWidget->GetBounds(aClipRect); aWidget->GetBounds(aClipRect);
aAbsX = aClipRect.x; aAbsX = aClipRect.x;
aAbsY = aClipRect.y; aAbsY = aClipRect.y;
@ -3802,10 +3799,12 @@ static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbs
aClipRect.x = 0; aClipRect.x = 0;
aClipRect.y = 0; aClipRect.y = 0;
// Gather up the absolute position of the widget // Gather up the absolute position of the widget, clip window, and visibilty
// + clip window
nsCOMPtr<nsIWidget> widget = getter_AddRefs(aWidget->GetParent()); nsCOMPtr<nsIWidget> widget = getter_AddRefs(aWidget->GetParent());
while (widget != nsnull) { while (widget != nsnull) {
if (aIsVisible)
widget->IsVisible(aIsVisible);
nsRect wrect; nsRect wrect;
widget->GetClientBounds(wrect); widget->GetClientBounds(wrect);
nscoord wx, wy; nscoord wx, wy;
@ -3902,7 +3901,15 @@ void nsPluginInstanceOwner::FixUpPluginWindow()
nscoord absWidgetX = 0; nscoord absWidgetX = 0;
nscoord absWidgetY = 0; nscoord absWidgetY = 0;
nsRect widgetClip(0,0,0,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);
// set the port coordinates // set the port coordinates
mPluginWindow.x = absWidgetX; mPluginWindow.x = absWidgetX;
@ -3928,8 +3935,20 @@ void nsPluginInstanceOwner::FixUpPluginWindow()
macColor.blue = COLOR8TOCOLOR16(NS_GET_B(color)); macColor.blue = COLOR8TOCOLOR16(NS_GET_B(color));
::RGBBackColor(&macColor); ::RGBBackColor(&macColor);
::SetPort(savePort); // restore port ::SetPort(savePort); // restore port
// now we need to check if we've been hidden or made visible and then update the plugin
// with the correct port if visible or null if hidden,
// if visiblity has changed, then update the plugin
if (isVisible != mWidgetVisible) {
mWidgetVisible = isVisible;
nsPluginWindow *window;
GetWindow(window);
if (window && mInstance) {
window->window = mWidgetVisible ? GetPluginPort() : nsnull;
mInstance->SetWindow(window);
}
}
} }
} }
#endif // XP_MAC #endif // XP_MAC

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

@ -167,11 +167,12 @@ private:
nsIWidget *mWindow; //we do not addref this... nsIWidget *mWindow; //we do not addref this...
PluginViewerImpl *mViewer; //we do not addref this... PluginViewerImpl *mViewer; //we do not addref this...
nsCOMPtr<nsITimer> mPluginTimer; nsCOMPtr<nsITimer> mPluginTimer;
PRPackedBool mWidgetVisible; // used on Mac to store our widget's visible state
}; };
#ifdef XP_MAC #ifdef XP_MAC
static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY, static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY,
nsRect& aClipRect); nsRect& aClipRect, PRBool& aIsVisible);
#endif #endif
class PluginViewerImpl : public nsIPluginViewer, class PluginViewerImpl : public nsIPluginViewer,
@ -1070,6 +1071,7 @@ pluginInstanceOwner :: pluginInstanceOwner()
mInstance = nsnull; mInstance = nsnull;
mWindow = nsnull; mWindow = nsnull;
mViewer = nsnull; mViewer = nsnull;
mWidgetVisible = PR_TRUE;
} }
pluginInstanceOwner :: ~pluginInstanceOwner() pluginInstanceOwner :: ~pluginInstanceOwner()
@ -1426,9 +1428,13 @@ nsPluginPort* pluginInstanceOwner::GetPluginPort()
// calculate the absolute position and clip for a widget // calculate the absolute position and clip for a widget
// and use other windows in calculating the clip // and use other windows in calculating the clip
static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY, // also find out if we are visible or not
nsRect& aClipRect) static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY,
nsRect& aClipRect, PRBool& aIsVisible)
{ {
if (aIsVisible)
aWidget->IsVisible(aIsVisible);
aWidget->GetBounds(aClipRect); aWidget->GetBounds(aClipRect);
aAbsX = aClipRect.x; aAbsX = aClipRect.x;
aAbsY = aClipRect.y; aAbsY = aClipRect.y;
@ -1438,10 +1444,12 @@ static void GetWidgetPosAndClip(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbs
aClipRect.x = 0; aClipRect.x = 0;
aClipRect.y = 0; aClipRect.y = 0;
// Gather up the absolute position of the widget // Gather up the absolute position of the widget, clip window, and visibilty
// + clip window
nsCOMPtr<nsIWidget> widget = getter_AddRefs(aWidget->GetParent()); nsCOMPtr<nsIWidget> widget = getter_AddRefs(aWidget->GetParent());
while (widget != nsnull) { while (widget != nsnull) {
if (aIsVisible)
widget->IsVisible(aIsVisible);
nsRect wrect; nsRect wrect;
widget->GetClientBounds(wrect); widget->GetClientBounds(wrect);
nscoord wx, wy; nscoord wx, wy;
@ -1478,7 +1486,8 @@ void pluginInstanceOwner::FixUpPluginWindow()
nscoord absWidgetX = 0; nscoord absWidgetX = 0;
nscoord absWidgetY = 0; nscoord absWidgetY = 0;
nsRect widgetClip(0,0,0,0); nsRect widgetClip(0,0,0,0);
GetWidgetPosAndClip(mWindow,absWidgetX,absWidgetY,widgetClip); PRBool isVisible = PR_TRUE;
GetWidgetPosClipAndVis(mWindow,absWidgetX,absWidgetY,widgetClip,isVisible);
// set the port coordinates // set the port coordinates
mPluginWindow.x = absWidgetX; mPluginWindow.x = absWidgetX;
@ -1489,6 +1498,19 @@ void pluginInstanceOwner::FixUpPluginWindow()
mPluginWindow.clipRect.left = widgetClip.x; mPluginWindow.clipRect.left = widgetClip.x;
mPluginWindow.clipRect.bottom = mPluginWindow.clipRect.top + widgetClip.height; mPluginWindow.clipRect.bottom = mPluginWindow.clipRect.top + widgetClip.height;
mPluginWindow.clipRect.right = mPluginWindow.clipRect.left + widgetClip.width; mPluginWindow.clipRect.right = mPluginWindow.clipRect.left + widgetClip.width;
// now we need to check if we've been hidden or made visible and then update the plugin
// with the correct port if visible or null if hidden,
// if visiblity has changed, then update the plugin
if (isVisible != mWidgetVisible) {
mWidgetVisible = isVisible;
nsPluginWindow *window;
GetWindow(window);
if (window && mInstance) {
window->window = mWidgetVisible ? GetPluginPort() : nsnull;
mInstance->SetWindow(window);
}
}
} }
} }