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(); 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) { if (mWindow.width != aWindow.width || mWindow.height != aWindow.height) {
mCurrentSurface = nsnull; mCurrentSurface = nsnull;
mHelperSurface = nsnull; mHelperSurface = nsnull;

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

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

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

@ -101,6 +101,7 @@ _MOCHITEST_FILES = \
ifeq ($(OS_ARCH),WINNT) ifeq ($(OS_ARCH),WINNT)
_MOCHITEST_FILES += \ _MOCHITEST_FILES += \
test_windowed_invalidate.html \ test_windowed_invalidate.html \
test_positioning.html \
$(NULL) $(NULL)
endif 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 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 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 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[] = { static const NPUTF8* sPluginMethodIdentifierNames[] = {
"npnEvaluateTest", "npnEvaluateTest",
@ -230,7 +231,8 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = {
"getFocusEventCount", "getFocusEventCount",
"getEventModel", "getEventModel",
"getReflector", "getReflector",
"isVisible" "isVisible",
"getWindowPosition"
}; };
static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)]; static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)];
static const ScriptableFunction sPluginMethodFunctions[] = { static const ScriptableFunction sPluginMethodFunctions[] = {
@ -284,7 +286,8 @@ static const ScriptableFunction sPluginMethodFunctions[] = {
getFocusEventCount, getFocusEventCount,
getEventModel, getEventModel,
getReflector, getReflector,
isVisible isVisible,
getWindowPosition
}; };
STATIC_ASSERT(ARRAY_LENGTH(sPluginMethodIdentifierNames) == 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); 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* const char*
NPN_UserAgent(NPP instance) 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); id->window.clipRect.right != 0, *result);
return true; 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;
}