зеркало из https://github.com/mozilla/gecko-dev.git
Bug 586656 - Serialize external "pluginEvent" structs in WidgetGUIEvent so that plugin events work in e10s - r=masayuki,jimm
This commit is contained in:
Родитель
192498ad38
Коммит
db65b34b46
|
@ -3605,7 +3605,7 @@ CreateMouseOrPointerWidgetEvent(WidgetMouseEvent* aMouseEvent,
|
|||
aNewEvent->button = aMouseEvent->button;
|
||||
aNewEvent->buttons = aMouseEvent->buttons;
|
||||
aNewEvent->pressure = aMouseEvent->pressure;
|
||||
aNewEvent->pluginEvent = aMouseEvent->pluginEvent;
|
||||
aNewEvent->mPluginEvent = aMouseEvent->mPluginEvent;
|
||||
aNewEvent->inputSource = aMouseEvent->inputSource;
|
||||
}
|
||||
|
||||
|
|
|
@ -1812,7 +1812,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
|
|||
|
||||
// If we have to synthesize an event we'll use one of these.
|
||||
NPCocoaEvent synthCocoaEvent;
|
||||
void* event = anEvent.pluginEvent;
|
||||
const NPCocoaEvent* event = static_cast<const NPCocoaEvent*>(anEvent.mPluginEvent);
|
||||
nsPoint pt =
|
||||
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mObjectFrame) -
|
||||
mObjectFrame->GetContentRectRelativeToSelf().TopLeft();
|
||||
|
@ -1879,7 +1879,9 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
|
|||
int16_t response = kNPEventNotHandled;
|
||||
void* window = FixUpPluginWindow(ePluginPaintEnable);
|
||||
if (window || (eventModel == NPEventModelCocoa)) {
|
||||
mInstance->HandleEvent(event, &response, NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
||||
mInstance->HandleEvent(const_cast<NPCocoaEvent*>(event),
|
||||
&response,
|
||||
NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
||||
}
|
||||
|
||||
if (eventModel == NPEventModelCocoa && response == kNPEventStartIME) {
|
||||
|
@ -1898,7 +1900,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
|
|||
|
||||
#ifdef XP_WIN
|
||||
// this code supports windowless plugins
|
||||
NPEvent *pPluginEvent = (NPEvent*)anEvent.pluginEvent;
|
||||
const NPEvent *pPluginEvent = static_cast<const NPEvent*>(anEvent.mPluginEvent);
|
||||
// we can get synthetic events from the EventStateManager... these
|
||||
// have no pluginEvent
|
||||
NPEvent pluginEvent;
|
||||
|
@ -1967,7 +1969,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
|
|||
nsIntPoint ptPx(presContext->AppUnitsToDevPixels(pt.x),
|
||||
presContext->AppUnitsToDevPixels(pt.y));
|
||||
nsIntPoint widgetPtPx = ptPx + mObjectFrame->GetWindowOriginInPixels(true);
|
||||
pPluginEvent->lParam = MAKELPARAM(widgetPtPx.x, widgetPtPx.y);
|
||||
const_cast<NPEvent*>(pPluginEvent)->lParam = MAKELPARAM(widgetPtPx.x, widgetPtPx.y);
|
||||
}
|
||||
}
|
||||
else if (!pPluginEvent) {
|
||||
|
@ -1995,7 +1997,9 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
|
|||
|
||||
if (pPluginEvent) {
|
||||
int16_t response = kNPEventNotHandled;
|
||||
mInstance->HandleEvent(pPluginEvent, &response, NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
||||
mInstance->HandleEvent(const_cast<NPEvent*>(pPluginEvent),
|
||||
&response,
|
||||
NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
||||
if (response == kNPEventHandled)
|
||||
rv = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
@ -2117,14 +2121,14 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
|
|||
//XXX case NS_MOUSE_SCROLL_EVENT: not received.
|
||||
|
||||
case NS_KEY_EVENT:
|
||||
if (anEvent.pluginEvent)
|
||||
if (anEvent.mPluginEvent)
|
||||
{
|
||||
XKeyEvent &event = pluginEvent.xkey;
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
event.root = GDK_ROOT_WINDOW();
|
||||
event.time = anEvent.time;
|
||||
const GdkEventKey* gdkEvent =
|
||||
static_cast<const GdkEventKey*>(anEvent.pluginEvent);
|
||||
static_cast<const GdkEventKey*>(anEvent.mPluginEvent);
|
||||
event.keycode = gdkEvent->hardware_keycode;
|
||||
event.state = gdkEvent->state;
|
||||
switch (anEvent.message)
|
||||
|
@ -2269,11 +2273,13 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
|
|||
const WidgetKeyboardEvent& keyEvent = *anEvent.AsKeyboardEvent();
|
||||
LOG("Firing NS_KEY_EVENT %d %d\n", keyEvent.keyCode, keyEvent.charCode);
|
||||
// pluginEvent is initialized by nsWindow::InitKeyEvent().
|
||||
ANPEvent* pluginEvent = reinterpret_cast<ANPEvent*>(keyEvent.pluginEvent);
|
||||
const ANPEvent* pluginEvent = static_cast<const ANPEvent*>(keyEvent.mPluginEvent);
|
||||
if (pluginEvent) {
|
||||
MOZ_ASSERT(pluginEvent->inSize == sizeof(ANPEvent));
|
||||
MOZ_ASSERT(pluginEvent->eventType == kKey_ANPEventType);
|
||||
mInstance->HandleEvent(pluginEvent, nullptr, NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
||||
mInstance->HandleEvent(const_cast<ANPEvent*>(pluginEvent),
|
||||
nullptr,
|
||||
NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2987,7 +2993,7 @@ void* nsPluginInstanceOwner::FixUpPluginWindow(int32_t inPaintState)
|
|||
InitializeNPCocoaEvent(&cocoaEvent);
|
||||
cocoaEvent.type = NPCocoaEventWindowFocusChanged;
|
||||
cocoaEvent.data.focus.hasFocus = cocoaTopLevelWindow ? NS_NPAPI_CocoaWindowIsMain(cocoaTopLevelWindow) : true;
|
||||
pluginEvent.pluginEvent = &cocoaEvent;
|
||||
pluginEvent.mPluginEvent.Copy(cocoaEvent);
|
||||
ProcessEvent(pluginEvent);
|
||||
}
|
||||
|
||||
|
|
|
@ -480,6 +480,11 @@ enum nsEventStructType
|
|||
#define NS_EDITOR_EVENT_START 6100
|
||||
#define NS_EDITOR_INPUT (NS_EDITOR_EVENT_START)
|
||||
|
||||
namespace IPC {
|
||||
template<typename T>
|
||||
struct ParamTraits;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -838,12 +843,11 @@ protected:
|
|||
WidgetGUIEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget,
|
||||
nsEventStructType aStructType) :
|
||||
WidgetEvent(aIsTrusted, aMessage, aStructType),
|
||||
widget(aWidget), pluginEvent(nullptr)
|
||||
widget(aWidget)
|
||||
{
|
||||
}
|
||||
|
||||
WidgetGUIEvent() :
|
||||
pluginEvent(nullptr)
|
||||
WidgetGUIEvent()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -852,7 +856,7 @@ public:
|
|||
|
||||
WidgetGUIEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget) :
|
||||
WidgetEvent(aIsTrusted, aMessage, NS_GUI_EVENT),
|
||||
widget(aWidget), pluginEvent(nullptr)
|
||||
widget(aWidget)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -871,8 +875,69 @@ public:
|
|||
/// Originator of the event
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
|
||||
/*
|
||||
* Explanation for this PluginEvent class:
|
||||
*
|
||||
* WidgetGUIEvent's mPluginEvent member used to be a void* pointer,
|
||||
* used to reference external, OS-specific data structures.
|
||||
*
|
||||
* That void* pointer wasn't serializable by itself, causing
|
||||
* certain plugin events not to function in e10s. See bug 586656.
|
||||
*
|
||||
* To make this serializable, we changed this void* pointer into
|
||||
* a proper buffer, and copy these external data structures into this
|
||||
* buffer.
|
||||
*
|
||||
* That buffer is PluginEvent::mBuffer below.
|
||||
*
|
||||
* We wrap this in that PluginEvent class providing operators to
|
||||
* be compatible with existing code that was written around
|
||||
* the old void* field.
|
||||
*
|
||||
* Ideally though, we wouldn't allow arbitrary reinterpret_cast'ing here;
|
||||
* instead, we would at least store type information here so that
|
||||
* this class can't be used to reinterpret one structure type into another.
|
||||
* We can also wonder if it would be possible to properly extend
|
||||
* WidgetGUIEvent and other Event classes to remove the need for this
|
||||
* mPluginEvent field.
|
||||
*/
|
||||
class PluginEvent MOZ_FINAL
|
||||
{
|
||||
nsTArray<uint8_t> mBuffer;
|
||||
|
||||
friend struct IPC::ParamTraits<mozilla::WidgetGUIEvent>;
|
||||
|
||||
public:
|
||||
|
||||
MOZ_EXPLICIT_CONVERSION operator bool() const
|
||||
{
|
||||
return !mBuffer.IsEmpty();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
MOZ_EXPLICIT_CONVERSION operator const T*() const
|
||||
{
|
||||
return mBuffer.IsEmpty()
|
||||
? nullptr
|
||||
: reinterpret_cast<const T*>(mBuffer.Elements());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Copy(const T& other)
|
||||
{
|
||||
static_assert(!mozilla::IsPointer<T>::value, "Don't want a pointer!");
|
||||
mBuffer.SetLength(sizeof(T));
|
||||
memcpy(mBuffer.Elements(), &other, mBuffer.Length());
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
mBuffer.Clear();
|
||||
}
|
||||
};
|
||||
|
||||
/// Event for NPAPI plugin
|
||||
void* pluginEvent;
|
||||
PluginEvent mPluginEvent;
|
||||
|
||||
void AssignGUIEventData(const WidgetGUIEvent& aEvent, bool aCopyTargets)
|
||||
{
|
||||
|
@ -880,9 +945,7 @@ public:
|
|||
|
||||
// widget should be initialized with the constructor.
|
||||
|
||||
// pluginEvent shouldn't be copied because it may be referred after its
|
||||
// instance is destroyed.
|
||||
pluginEvent = nullptr;
|
||||
mPluginEvent = aEvent.mPluginEvent;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1448,7 +1448,7 @@ nsWindow::InitKeyEvent(WidgetKeyboardEvent& event, AndroidGeckoEvent& key,
|
|||
event.isChar = (charCode >= ' ');
|
||||
event.charCode = event.isChar ? charCode : 0;
|
||||
event.keyCode = (event.charCode > 0) ? 0 : domKeyCode;
|
||||
event.pluginEvent = nullptr;
|
||||
event.mPluginEvent.Clear();
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
if (event.message != NS_KEY_DOWN && event.message != NS_KEY_UP) {
|
||||
|
@ -1465,7 +1465,7 @@ nsWindow::InitKeyEvent(WidgetKeyboardEvent& event, AndroidGeckoEvent& key,
|
|||
event.isChar = false;
|
||||
event.charCode = 0;
|
||||
event.keyCode = domKeyCode;
|
||||
event.pluginEvent = pluginEvent;
|
||||
event.mPluginEvent.Copy(*pluginEvent);
|
||||
}
|
||||
|
||||
event.modifiers = key.DOMModifiers();
|
||||
|
|
|
@ -2029,7 +2029,7 @@ TextInputHandler::DispatchKeyEventForFlagsChanged(NSEvent* aNativeEvent,
|
|||
if ([mView isPluginView]) {
|
||||
if ([mView pluginEventModel] == NPEventModelCocoa) {
|
||||
ConvertCocoaKeyEventToNPCocoaEvent(aNativeEvent, cocoaEvent);
|
||||
keyEvent.pluginEvent = &cocoaEvent;
|
||||
keyEvent.mPluginEvent.Copy(cocoaEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3890,7 +3890,7 @@ PluginTextInputHandler::HandleCarbonPluginKeyEvent(EventRef aKeyEvent)
|
|||
uint32_t charCode(charCodes.ElementAt(i));
|
||||
|
||||
keydownEvent.time = PR_IntervalNow();
|
||||
keydownEvent.pluginEvent = &eventRec;
|
||||
keydownEvent.mPluginEvent.Copy(eventRec);
|
||||
if (IsSpecialGeckoKey(macKeyCode)) {
|
||||
keydownEvent.keyCode = keyCode;
|
||||
} else {
|
||||
|
@ -4080,7 +4080,7 @@ PluginTextInputHandler::HandleKeyUpEventForPlugin(NSEvent* aNativeKeyEvent)
|
|||
InitKeyEvent(aNativeKeyEvent, keyupEvent);
|
||||
NPCocoaEvent pluginEvent;
|
||||
ConvertCocoaKeyEventToNPCocoaEvent(aNativeKeyEvent, pluginEvent);
|
||||
keyupEvent.pluginEvent = &pluginEvent;
|
||||
keyupEvent.mPluginEvent.Copy(pluginEvent);
|
||||
DispatchEvent(keyupEvent);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -6634,7 +6634,7 @@ ChildViewMouseTracker::AttachPluginEvent(WidgetMouseEventBase& aMouseEvent,
|
|||
cocoaEvent->data.mouse.deltaX = [aNativeMouseEvent deltaX];
|
||||
cocoaEvent->data.mouse.deltaY = [aNativeMouseEvent deltaY];
|
||||
cocoaEvent->data.mouse.deltaZ = [aNativeMouseEvent deltaZ];
|
||||
aMouseEvent.pluginEvent = cocoaEvent;
|
||||
aMouseEvent.mPluginEvent.Copy(*cocoaEvent);
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
|
|
@ -607,7 +607,7 @@ nsCocoaUtils::InitPluginEvent(WidgetPluginEvent &aPluginEvent,
|
|||
NPCocoaEvent &aCocoaEvent)
|
||||
{
|
||||
aPluginEvent.time = PR_IntervalNow();
|
||||
aPluginEvent.pluginEvent = (void*)&aCocoaEvent;
|
||||
aPluginEvent.mPluginEvent.Copy(aCocoaEvent);
|
||||
aPluginEvent.retargetToFocusedDocument = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1005,7 +1005,7 @@ KeymapWrapper::InitKeyEvent(WidgetKeyboardEvent& aKeyEvent,
|
|||
// so link to the GdkEvent (which will vanish soon after return from the
|
||||
// event callback) to give plugins access to hardware_keycode and state.
|
||||
// (An XEvent would be nice but the GdkEvent is good enough.)
|
||||
aKeyEvent.pluginEvent = (void *)aGdkKeyEvent;
|
||||
aKeyEvent.mPluginEvent.Copy(*aGdkKeyEvent);
|
||||
aKeyEvent.time = aGdkKeyEvent->time;
|
||||
aKeyEvent.mNativeKeyEvent = static_cast<void*>(aGdkKeyEvent);
|
||||
aKeyEvent.mIsRepeat = sRepeatState == REPEATING &&
|
||||
|
|
|
@ -75,11 +75,13 @@ struct ParamTraits<mozilla::WidgetGUIEvent>
|
|||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, static_cast<mozilla::WidgetEvent>(aParam));
|
||||
WriteParam(aMsg, aParam.mPluginEvent.mBuffer);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
return ReadParam(aMsg, aIter, static_cast<mozilla::WidgetEvent*>(aResult));
|
||||
return ReadParam(aMsg, aIter, static_cast<mozilla::WidgetEvent*>(aResult)) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mPluginEvent.mBuffer);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1124,7 +1124,7 @@ InitKeyEvent(WidgetKeyboardEvent& aEvent, QKeyEvent* aQEvent)
|
|||
// so link to the QKeyEvent (which will vanish soon after return from the
|
||||
// event callback) to give plugins access to hardware_keycode and state.
|
||||
// (An XEvent would be nice but the QKeyEvent is good enough.)
|
||||
aEvent.pluginEvent = (void *)aQEvent;
|
||||
aEvent.mPluginEvent.Copy(*aQEvent);
|
||||
}
|
||||
|
||||
nsEventStatus
|
||||
|
|
|
@ -1099,7 +1099,7 @@ NativeKey::DispatchKeyEvent(WidgetKeyboardEvent& aKeyEvent,
|
|||
pluginEvent.event = aMsgSentToPlugin->message;
|
||||
pluginEvent.wParam = aMsgSentToPlugin->wParam;
|
||||
pluginEvent.lParam = aMsgSentToPlugin->lParam;
|
||||
aKeyEvent.pluginEvent = static_cast<void*>(&pluginEvent);
|
||||
aKeyEvent.mPluginEvent.Copy(pluginEvent);
|
||||
}
|
||||
|
||||
return (mWidget->DispatchKeyboardEvent(&aKeyEvent) || mWidget->Destroyed());
|
||||
|
|
|
@ -4000,7 +4000,7 @@ bool nsWindow::DispatchMouseEvent(uint32_t aEventType, WPARAM wParam,
|
|||
pluginEvent.wParam = wParam; // plugins NEED raw OS event flags!
|
||||
pluginEvent.lParam = lParam;
|
||||
|
||||
event.pluginEvent = (void *)&pluginEvent;
|
||||
event.mPluginEvent.Copy(pluginEvent);
|
||||
|
||||
// call the event callback
|
||||
if (mWidgetListener) {
|
||||
|
|
|
@ -30,7 +30,7 @@ nsWindowBase::DispatchPluginEvent(const MSG& aMsg)
|
|||
npEvent.event = aMsg.message;
|
||||
npEvent.wParam = aMsg.wParam;
|
||||
npEvent.lParam = aMsg.lParam;
|
||||
pluginEvent.pluginEvent = &npEvent;
|
||||
pluginEvent.mPluginEvent.Copy(npEvent);
|
||||
pluginEvent.retargetToFocusedDocument = true;
|
||||
return DispatchWindowEvent(&pluginEvent);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче