Adding extra event call (WM_WINDOWPOSCHANGED) for windowless plugins on Windows so that they are updated with their position and bounds. Bug 135737, r=av, sr=attinasi

git-svn-id: svn://10.0.0.236/trunk@120569 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
peterlubczynski%netscape.com
2002-05-02 20:46:22 +00:00
parent 081f08f038
commit db0df3ee8d
4 changed files with 184 additions and 14 deletions

View File

@@ -786,8 +786,6 @@ nsObjectFrame::CreateWidget(nsIPresContext* aPresContext,
view->GetWidget(*getter_AddRefs(win));
if (win)
win->SetBackgroundColor(color->mBackgroundColor);
else
NS_ASSERTION(win, "failed to get widget to set background color on");
break;
}
}
@@ -1400,7 +1398,7 @@ nsObjectFrame::ContentChanged(nsIPresContext* aPresContext,
return rv;
}
nsresult nsObjectFrame::GetWindowOriginInPixels(nsIPresContext * aPresContext, nsPoint * aOrigin)
nsresult nsObjectFrame::GetWindowOriginInPixels(nsIPresContext * aPresContext, PRBool aWindowless, nsPoint * aOrigin)
{
NS_ENSURE_ARG_POINTER(aPresContext);
NS_ENSURE_ARG_POINTER(aOrigin);
@@ -1411,6 +1409,29 @@ nsresult nsObjectFrame::GetWindowOriginInPixels(nsIPresContext * aPresContext, n
GetOffsetFromView(aPresContext, origin, &parentWithView);
// if it's windowless, let's make sure we have our origin set right
// it may need to be corrected, like after scrolling
if (aWindowless && parentWithView) {
nsPoint correction(0,0);
nsCOMPtr<nsIViewManager> parentVM;
parentWithView->GetViewManager(*getter_AddRefs(parentVM));
// Walk up all the views and add up their positions. This will give us our
// absolute position which is what we want to give the plugin
nsIView* theView = parentWithView;
while (theView) {
nsCOMPtr<nsIViewManager> vm;
theView->GetViewManager(*getter_AddRefs(vm));
if (vm != parentVM)
break;
theView->GetPosition(&correction.x, &correction.y);
origin += correction;
theView->GetParent(theView);
}
}
float t2p;
aPresContext->GetTwipsToPixels(&t2p);
aOrigin->x = NSTwipsToIntPixels(origin.x, t2p);
@@ -1466,7 +1487,7 @@ nsObjectFrame::DidReflow(nsIPresContext* aPresContext,
return rv;
nsPoint origin;
GetWindowOriginInPixels(aPresContext, &origin);
GetWindowOriginInPixels(aPresContext, windowless, &origin);
window->x = origin.x;
window->y = origin.y;
@@ -1688,6 +1709,15 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext,
doupdatewindow = PR_TRUE;
}
/*
* Layout now has an optimized way of painting. Now we always get
* a new drawing surface, sized to be just what's needed. Windowsless
* plugins need a transform applied to their origin so they paint
* in the right place. Since |SetWindow| is no longer being used
* to tell the plugin where it is, we dispatch a NPWindow through
* |HandleEvent| to tell the plugin when its window moved
*/
// Get the offset of the DC
nsTransform2D* rcTransform;
aRenderingContext.GetCurrentTransform(rcTransform);
@@ -1700,8 +1730,62 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext,
doupdatewindow = PR_TRUE;
}
if(doupdatewindow)
inst->SetWindow(window);
// if our location or visible area has changed, we need to tell the plugin
if(doupdatewindow) {
#ifdef XP_WIN // Windowless plugins on windows need a special event to update their location, see bug 135737
// first, lets find out how big the window is, in pixels
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIViewManager> vm;
aPresContext->GetShell(getter_AddRefs(shell));
if (shell) {
shell->GetViewManager(getter_AddRefs(vm));
if (vm) {
nsIView* view;
vm->GetRootView(view);
if (view) {
nsCOMPtr<nsIWidget> win;
view->GetWidget(*getter_AddRefs(win));
if (win) {
nsRect visibleRect;
win->GetBounds(visibleRect);
// next, get our plugin's rect so we can intersect it with the visible rect so we
// can tell the plugin where and how much to paint
GetWindowOriginInPixels(aPresContext, window->type, &origin);
nsRect winlessRect = nsRect(origin, nsSize(window->width, window->height));
winlessRect.IntersectRect(winlessRect, visibleRect);
// now check our cached window and only update plugin if something has changed
if (mWindowlessRect != winlessRect) {
mWindowlessRect = winlessRect;
WINDOWPOS winpos;
memset(&winpos, 0, sizeof(winpos));
winpos.x = mWindowlessRect.x;
winpos.y = mWindowlessRect.y;
winpos.cx = mWindowlessRect.width;
winpos.cy = mWindowlessRect.height;
// finally, update the plugin by sending it a WM_WINDOWPOSCHANGED event
nsPluginEvent pluginEvent;
pluginEvent.event = 0x0047;
pluginEvent.wParam = 0;
pluginEvent.lParam = (uint32)&winpos;
PRBool eventHandled = PR_FALSE;
inst->HandleEvent(&pluginEvent, &eventHandled);
mInstanceOwner->ReleasePluginPort((nsPluginPort *)winpos.hwnd);
}
}
}
}
}
#endif
inst->SetWindow(window);
}
mInstanceOwner->Paint(aDirtyRect, hdc);
}

View File

@@ -161,13 +161,14 @@ protected:
nsresult NotifyContentObjectWrapper();
nsresult GetWindowOriginInPixels(nsIPresContext * aPresContext, nsPoint* aOrigin);
nsresult GetWindowOriginInPixels(nsIPresContext * aPresContext, PRBool aWindoless, nsPoint* aOrigin);
private:
nsPluginInstanceOwner *mInstanceOwner;
nsIURI *mFullURL;
nsIFrame *mFirstChild;
nsIWidget *mWidget;
nsRect mWindowlessRect;
};

View File

@@ -786,8 +786,6 @@ nsObjectFrame::CreateWidget(nsIPresContext* aPresContext,
view->GetWidget(*getter_AddRefs(win));
if (win)
win->SetBackgroundColor(color->mBackgroundColor);
else
NS_ASSERTION(win, "failed to get widget to set background color on");
break;
}
}
@@ -1400,7 +1398,7 @@ nsObjectFrame::ContentChanged(nsIPresContext* aPresContext,
return rv;
}
nsresult nsObjectFrame::GetWindowOriginInPixels(nsIPresContext * aPresContext, nsPoint * aOrigin)
nsresult nsObjectFrame::GetWindowOriginInPixels(nsIPresContext * aPresContext, PRBool aWindowless, nsPoint * aOrigin)
{
NS_ENSURE_ARG_POINTER(aPresContext);
NS_ENSURE_ARG_POINTER(aOrigin);
@@ -1411,6 +1409,29 @@ nsresult nsObjectFrame::GetWindowOriginInPixels(nsIPresContext * aPresContext, n
GetOffsetFromView(aPresContext, origin, &parentWithView);
// if it's windowless, let's make sure we have our origin set right
// it may need to be corrected, like after scrolling
if (aWindowless && parentWithView) {
nsPoint correction(0,0);
nsCOMPtr<nsIViewManager> parentVM;
parentWithView->GetViewManager(*getter_AddRefs(parentVM));
// Walk up all the views and add up their positions. This will give us our
// absolute position which is what we want to give the plugin
nsIView* theView = parentWithView;
while (theView) {
nsCOMPtr<nsIViewManager> vm;
theView->GetViewManager(*getter_AddRefs(vm));
if (vm != parentVM)
break;
theView->GetPosition(&correction.x, &correction.y);
origin += correction;
theView->GetParent(theView);
}
}
float t2p;
aPresContext->GetTwipsToPixels(&t2p);
aOrigin->x = NSTwipsToIntPixels(origin.x, t2p);
@@ -1466,7 +1487,7 @@ nsObjectFrame::DidReflow(nsIPresContext* aPresContext,
return rv;
nsPoint origin;
GetWindowOriginInPixels(aPresContext, &origin);
GetWindowOriginInPixels(aPresContext, windowless, &origin);
window->x = origin.x;
window->y = origin.y;
@@ -1688,6 +1709,15 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext,
doupdatewindow = PR_TRUE;
}
/*
* Layout now has an optimized way of painting. Now we always get
* a new drawing surface, sized to be just what's needed. Windowsless
* plugins need a transform applied to their origin so they paint
* in the right place. Since |SetWindow| is no longer being used
* to tell the plugin where it is, we dispatch a NPWindow through
* |HandleEvent| to tell the plugin when its window moved
*/
// Get the offset of the DC
nsTransform2D* rcTransform;
aRenderingContext.GetCurrentTransform(rcTransform);
@@ -1700,8 +1730,62 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext,
doupdatewindow = PR_TRUE;
}
if(doupdatewindow)
inst->SetWindow(window);
// if our location or visible area has changed, we need to tell the plugin
if(doupdatewindow) {
#ifdef XP_WIN // Windowless plugins on windows need a special event to update their location, see bug 135737
// first, lets find out how big the window is, in pixels
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIViewManager> vm;
aPresContext->GetShell(getter_AddRefs(shell));
if (shell) {
shell->GetViewManager(getter_AddRefs(vm));
if (vm) {
nsIView* view;
vm->GetRootView(view);
if (view) {
nsCOMPtr<nsIWidget> win;
view->GetWidget(*getter_AddRefs(win));
if (win) {
nsRect visibleRect;
win->GetBounds(visibleRect);
// next, get our plugin's rect so we can intersect it with the visible rect so we
// can tell the plugin where and how much to paint
GetWindowOriginInPixels(aPresContext, window->type, &origin);
nsRect winlessRect = nsRect(origin, nsSize(window->width, window->height));
winlessRect.IntersectRect(winlessRect, visibleRect);
// now check our cached window and only update plugin if something has changed
if (mWindowlessRect != winlessRect) {
mWindowlessRect = winlessRect;
WINDOWPOS winpos;
memset(&winpos, 0, sizeof(winpos));
winpos.x = mWindowlessRect.x;
winpos.y = mWindowlessRect.y;
winpos.cx = mWindowlessRect.width;
winpos.cy = mWindowlessRect.height;
// finally, update the plugin by sending it a WM_WINDOWPOSCHANGED event
nsPluginEvent pluginEvent;
pluginEvent.event = 0x0047;
pluginEvent.wParam = 0;
pluginEvent.lParam = (uint32)&winpos;
PRBool eventHandled = PR_FALSE;
inst->HandleEvent(&pluginEvent, &eventHandled);
mInstanceOwner->ReleasePluginPort((nsPluginPort *)winpos.hwnd);
}
}
}
}
}
#endif
inst->SetWindow(window);
}
mInstanceOwner->Paint(aDirtyRect, hdc);
}

View File

@@ -161,13 +161,14 @@ protected:
nsresult NotifyContentObjectWrapper();
nsresult GetWindowOriginInPixels(nsIPresContext * aPresContext, nsPoint* aOrigin);
nsresult GetWindowOriginInPixels(nsIPresContext * aPresContext, PRBool aWindoless, nsPoint* aOrigin);
private:
nsPluginInstanceOwner *mInstanceOwner;
nsIURI *mFullURL;
nsIFrame *mFirstChild;
nsIWidget *mWidget;
nsRect mWindowlessRect;
};