mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Bug 534027 - input event coords incorrect for oop windowless plugins. r=jmuizelaar.
This commit is contained in:
parent
8334063adb
commit
3c68e53543
@ -47,6 +47,10 @@
|
||||
#include "npfunctions.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <windowsx.h>
|
||||
#endif
|
||||
|
||||
using namespace mozilla::plugins;
|
||||
|
||||
PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent,
|
||||
@ -452,12 +456,57 @@ PluginInstanceParent::NPP_HandleEvent(void* event)
|
||||
NPEvent* npevent = reinterpret_cast<NPEvent*>(event);
|
||||
NPRemoteEvent npremoteevent;
|
||||
npremoteevent.event = *npevent;
|
||||
int16_t handled;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
RECT rect;
|
||||
if (mWindowType == NPWindowTypeDrawable &&
|
||||
npevent->event == WM_PAINT) {
|
||||
SharedSurfaceBeforePaint(rect, npremoteevent);
|
||||
if (mWindowType == NPWindowTypeDrawable) {
|
||||
switch(npevent->event) {
|
||||
case WM_PAINT:
|
||||
{
|
||||
RECT rect;
|
||||
SharedSurfaceBeforePaint(rect, npremoteevent);
|
||||
if (!CallNPP_HandleEvent(npremoteevent, &handled))
|
||||
return 0;
|
||||
if (handled)
|
||||
SharedSurfaceAfterPaint(npevent);
|
||||
}
|
||||
break;
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
SharedSurfaceSetOrigin(npremoteevent);
|
||||
if (!CallNPP_HandleEvent(npremoteevent, &handled))
|
||||
return 0;
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_MBUTTONDBLCLK:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
{
|
||||
// Received mouse events have an origin at the position of the plugin rect
|
||||
// in the page. However, when rendering to the shared dib, the rect origin
|
||||
// changes to 0,0 via the WM_WINDOWPOSCHANGED event. In this case we need to
|
||||
// translate these coords to the proper location.
|
||||
nsPoint pt(GET_X_LPARAM(npremoteevent.event.lParam), GET_Y_LPARAM(npremoteevent.event.lParam));
|
||||
pt.MoveBy(-mPluginPosOrigin.x, -mPluginPosOrigin.y);
|
||||
npremoteevent.event.lParam = MAKELPARAM(pt.x, pt.y);
|
||||
if (!CallNPP_HandleEvent(npremoteevent, &handled))
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
if (!CallNPP_HandleEvent(npremoteevent, &handled))
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!CallNPP_HandleEvent(npremoteevent, &handled))
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -476,16 +525,9 @@ PluginInstanceParent::NPP_HandleEvent(void* event)
|
||||
XSync(GDK_DISPLAY(), False);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
int16_t handled;
|
||||
if (!CallNPP_HandleEvent(npremoteevent, &handled)) {
|
||||
return 0; // no good way to handle errors here...
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
if (handled && mWindowType == NPWindowTypeDrawable && npevent->event == WM_PAINT)
|
||||
SharedSurfaceAfterPaint(npevent);
|
||||
if (!CallNPP_HandleEvent(npremoteevent, &handled))
|
||||
return 0; // no good way to handle errors here...
|
||||
#endif
|
||||
|
||||
return handled;
|
||||
@ -661,6 +703,41 @@ PluginInstanceParent::AnswerNPN_PopPopupsEnabledState(bool* aSuccess)
|
||||
|
||||
/* windowless drawing helpers */
|
||||
|
||||
/*
|
||||
* Origin info:
|
||||
*
|
||||
* windowless, offscreen:
|
||||
*
|
||||
* WM_WINDOWPOSCHANGED: origin is relative to container
|
||||
* setwindow: origin is 0,0
|
||||
* WM_PAINT: origin is 0,0
|
||||
*
|
||||
* windowless, native:
|
||||
*
|
||||
* WM_WINDOWPOSCHANGED: origin is relative to container
|
||||
* setwindow: origin is relative to container
|
||||
* WM_PAINT: origin is relative to container
|
||||
*
|
||||
* PluginInstanceParent:
|
||||
*
|
||||
* painting: mPluginPort (nsIntRect, saved in SetWindow)
|
||||
* event translation: mPluginPosOrigin (nsIntPoint, saved in SetOrigin)
|
||||
*/
|
||||
|
||||
void
|
||||
PluginInstanceParent::SharedSurfaceSetOrigin(NPRemoteEvent& npremoteevent)
|
||||
{
|
||||
WINDOWPOS* winpos = (WINDOWPOS*)npremoteevent.event.lParam;
|
||||
|
||||
// save the origin, we'll use this to translate input coordinates
|
||||
mPluginPosOrigin.x = winpos->x;
|
||||
mPluginPosOrigin.y = winpos->y;
|
||||
|
||||
// Reset to the offscreen dib origin
|
||||
winpos->x = 0;
|
||||
winpos->y = 0;
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceParent::SharedSurfaceRelease()
|
||||
{
|
||||
|
@ -219,12 +219,14 @@ private:
|
||||
bool SharedSurfaceSetWindow(const NPWindow* aWindow, NPRemoteWindow& aRemoteWindow);
|
||||
void SharedSurfaceBeforePaint(RECT &rect, NPRemoteEvent& npremoteevent);
|
||||
void SharedSurfaceAfterPaint(NPEvent* npevent);
|
||||
void SharedSurfaceSetOrigin(NPRemoteEvent& npremoteevent);
|
||||
void SharedSurfaceRelease();
|
||||
|
||||
private:
|
||||
gfx::SharedDIBWin mSharedSurfaceDib;
|
||||
nsIntRect mPluginPort;
|
||||
nsIntRect mSharedSize;
|
||||
nsIntPoint mPluginPosOrigin;
|
||||
#endif // defined(XP_WIN)
|
||||
};
|
||||
|
||||
|
@ -1713,17 +1713,22 @@ nsObjectFrame::PaintPlugin(nsIRenderingContext& aRenderingContext,
|
||||
window->x = dest.left;
|
||||
window->y = dest.top;
|
||||
|
||||
// Windowless plugins on windows need a special event to update their location, see bug 135737
|
||||
// Windowless plugins on windows need a special event to update their location,
|
||||
// see bug 135737.
|
||||
//
|
||||
// bug 271442: note, the rectangle we send is now purely the bounds of the plugin
|
||||
// relative to the window it is contained in, which is useful for the plugin to correctly translate mouse coordinates
|
||||
// relative to the window it is contained in, which is useful for the plugin to
|
||||
// correctly translate mouse coordinates.
|
||||
//
|
||||
// this does not mesh with the comments for bug 135737 which imply that the rectangle
|
||||
// must be clipped in some way to prevent the plugin attempting to paint over areas it shouldn't;
|
||||
// must be clipped in some way to prevent the plugin attempting to paint over areas
|
||||
// it shouldn't.
|
||||
//
|
||||
// since the two uses of the rectangle are mutually exclusive in some cases,
|
||||
// and since I don't see any incorrect painting (at least with Flash and ViewPoint - the originator of 135737),
|
||||
// it seems that windowless plugins are not relying on information here for clipping their drawing,
|
||||
// and we can safely use this message to tell the plugin exactly where it is in all cases.
|
||||
// since the two uses of the rectangle are mutually exclusive in some cases, and
|
||||
// since I don't see any incorrect painting (at least with Flash and ViewPoint -
|
||||
// the originator of bug 135737), it seems that windowless plugins are not relying
|
||||
// on information here for clipping their drawing, and we can safely use this message
|
||||
// to tell the plugin exactly where it is in all cases.
|
||||
|
||||
nsIntPoint origin = GetWindowOriginInPixels(PR_TRUE);
|
||||
nsIntRect winlessRect = nsIntRect(origin, nsIntSize(window->width, window->height));
|
||||
|
Loading…
Reference in New Issue
Block a user