Bug 611206 - Send the plugin information about mouse position changes when we scroll, even when we don't need to repaint the plugin, r=karlt

This commit is contained in:
Benjamin Smedberg 2010-11-15 09:41:18 -05:00
Родитель 4512100555
Коммит 4b1e537953
5 изменённых файлов: 127 добавлений и 12 удалений

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

@ -2166,7 +2166,9 @@ PluginInstanceChild::RecvAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
{
AssertPluginThread();
mWindow.window = reinterpret_cast<void*>(aWindow.window);
NS_ASSERTION(!aWindow.window, "Remote window should be null.");
mWindow.window = NULL;
if (mWindow.width != aWindow.width || mWindow.height != aWindow.height) {
mCurrentSurface = nsnull;
mHelperSurface = nsnull;

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

@ -385,7 +385,7 @@ public:
void BeginCGPaint();
void EndCGPaint();
#else // XP_MACOSX
void UpdateWindowClipRect(PRBool aSetWindow);
void UpdateWindowPositionAndClipRect(PRBool aSetWindow);
void SetWindow();
void UpdateWindowVisibility(PRBool aVisible);
#endif // XP_MACOSX
@ -1084,7 +1084,7 @@ nsObjectFrame::FixupWindow(const nsSize& aSize)
window->clipRect.bottom = 0;
window->clipRect.right = 0;
#else
mInstanceOwner->UpdateWindowClipRect(PR_FALSE);
mInstanceOwner->UpdateWindowPositionAndClipRect(PR_FALSE);
#endif
NotifyPluginReflowObservers();
@ -1319,6 +1319,8 @@ nsObjectFrame::ComputeWidgetGeometry(const nsRegion& aRegion,
if (!mWidget) {
#ifndef XP_MACOSX
if (mInstanceOwner) {
// UpdateWindowVisibility will notify the plugin of position changes
// by updating the NPWindow and calling NPP_SetWindow/AsyncSetWindow.
mInstanceOwner->UpdateWindowVisibility(!aRegion.IsEmpty());
}
#endif
@ -6444,7 +6446,7 @@ nsPluginInstanceOwner::HidePluginWindow()
#else // XP_MACOSX
void nsPluginInstanceOwner::UpdateWindowClipRect(PRBool aSetWindow)
void nsPluginInstanceOwner::UpdateWindowPositionAndClipRect(PRBool aSetWindow)
{
if (!mPluginWindow)
return;
@ -6455,7 +6457,13 @@ void nsPluginInstanceOwner::UpdateWindowClipRect(PRBool aSetWindow)
if (aSetWindow && !mWidget && mPluginWindowVisible && !UseLayers())
return;
const NPRect oldClipRect = mPluginWindow->clipRect;
const NPWindow oldWindow = *mPluginWindow;
PRBool windowless = (mPluginWindow->type == NPWindowTypeDrawable);
nsIntPoint origin = mObjectFrame->GetWindowOriginInPixels(windowless);
mPluginWindow->x = origin.x;
mPluginWindow->y = origin.y;
mPluginWindow->clipRect.left = 0;
mPluginWindow->clipRect.top = 0;
@ -6471,10 +6479,12 @@ void nsPluginInstanceOwner::UpdateWindowClipRect(PRBool aSetWindow)
if (!aSetWindow)
return;
if ((mPluginWindow->clipRect.left != oldClipRect.left ||
mPluginWindow->clipRect.top != oldClipRect.top ||
mPluginWindow->clipRect.right != oldClipRect.right ||
mPluginWindow->clipRect.bottom != oldClipRect.bottom)) {
if (mPluginWindow->x != oldWindow.x ||
mPluginWindow->y != oldWindow.y ||
mPluginWindow->clipRect.left != oldWindow.clipRect.left ||
mPluginWindow->clipRect.top != oldWindow.clipRect.top ||
mPluginWindow->clipRect.right != oldWindow.clipRect.right ||
mPluginWindow->clipRect.bottom != oldWindow.clipRect.bottom) {
SetWindow();
}
}
@ -6496,7 +6506,7 @@ void
nsPluginInstanceOwner::UpdateWindowVisibility(PRBool aVisible)
{
mPluginWindowVisible = aVisible;
UpdateWindowClipRect(PR_TRUE);
UpdateWindowPositionAndClipRect(PR_TRUE);
}
#endif // XP_MACOSX

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

@ -101,6 +101,7 @@ _MOCHITEST_FILES = \
ifeq ($(OS_ARCH),WINNT)
_MOCHITEST_FILES += \
test_windowed_invalidate.html \
test_positioning.html \
$(NULL)
endif

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

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html>
<head>
<title>Test whether windowless plugins receive correct visible/invisible notifications.</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<style type="text/css">
body {
height: 10000px;
}
</style>
<body onload="startTest()">
<p id="display"></p>
<embed id="theplugin" type="application/x-test" width="200" height="200"></embed>
<script type="application/javascript;version=1.8">
SimpleTest.waitForExplicitFinish();
var p = document.getElementById('theplugin');
function startTest() {
// Wait for the plugin to have painted once
var interval = setInterval(function() {
if (!p.getPaintCount())
return;
clearInterval(interval);
doScroll();
}, 100);
}
const kScrollAmount = 1000;
var startY;
function doScroll() {
let [x, y, w, h] = p.getWindowPosition();
startY = y;
scrollBy(0, kScrollAmount);
setTimeout(checkScroll, 500);
}
function checkScroll() {
let [x, y, w, h] = p.getWindowPosition();
is(y, startY - kScrollAmount, "Window should be informed of its new position.");
SimpleTest.finish();
}
</script>

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

@ -178,6 +178,7 @@ static bool getFocusEventCount(NPObject* npobj, const NPVariant* args, uint32_t
static bool getEventModel(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool getReflector(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool isVisible(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool getWindowPosition(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static const NPUTF8* sPluginMethodIdentifierNames[] = {
"npnEvaluateTest",
@ -230,7 +231,8 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = {
"getFocusEventCount",
"getEventModel",
"getReflector",
"isVisible"
"isVisible",
"getWindowPosition"
};
static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)];
static const ScriptableFunction sPluginMethodFunctions[] = {
@ -284,7 +286,8 @@ static const ScriptableFunction sPluginMethodFunctions[] = {
getFocusEventCount,
getEventModel,
getReflector,
isVisible
isVisible,
getWindowPosition
};
STATIC_ASSERT(ARRAY_LENGTH(sPluginMethodIdentifierNames) ==
@ -1389,6 +1392,13 @@ NPN_InvokeDefault(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCou
return sBrowserFuncs->invokeDefault(npp, obj, args, argCount, result);
}
bool
NPN_Construct(NPP npp, NPObject* npobj, const NPVariant* args,
uint32_t argCount, NPVariant* result)
{
return sBrowserFuncs->construct(npp, npobj, args, argCount, result);
}
const char*
NPN_UserAgent(NPP instance)
{
@ -3124,3 +3134,42 @@ bool isVisible(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVari
id->window.clipRect.right != 0, *result);
return true;
}
bool getWindowPosition(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
{
NPP npp = static_cast<TestNPObject*>(npobj)->npp;
InstanceData* id = static_cast<InstanceData*>(npp->pdata);
NPObject* window = NULL;
NPError err = NPN_GetValue(npp, NPNVWindowNPObject, &window);
if (NPERR_NO_ERROR != err || !window)
return false;
NPIdentifier arrayID = NPN_GetStringIdentifier("Array");
NPVariant arrayFunctionV;
bool ok = NPN_GetProperty(npp, window, arrayID, &arrayFunctionV);
NPN_ReleaseObject(window);
if (!ok)
return false;
if (!NPVARIANT_IS_OBJECT(arrayFunctionV)) {
NPN_ReleaseVariantValue(&arrayFunctionV);
return false;
}
NPObject* arrayFunction = NPVARIANT_TO_OBJECT(arrayFunctionV);
NPVariant elements[4];
INT32_TO_NPVARIANT(id->window.x, elements[0]);
INT32_TO_NPVARIANT(id->window.y, elements[1]);
INT32_TO_NPVARIANT(id->window.width, elements[2]);
INT32_TO_NPVARIANT(id->window.height, elements[3]);
NPObject* resultArray = NULL;
ok = NPN_InvokeDefault(npp, arrayFunction, elements, 4, result);
NPN_ReleaseObject(arrayFunction);
return ok;
}