зеркало из https://github.com/mozilla/pjs.git
Bug 525078 - Make plugin mouse up/down/dragging behavior conform to OS X practice and Cocoa NPAPI spec clarifications. r=josh
This commit is contained in:
Родитель
d17bf9a27b
Коммит
406b239c95
|
@ -1934,6 +1934,19 @@ nsObjectFrame::HandleEvent(nsPresContext* aPresContext,
|
|||
return nsObjectFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus);
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// Needed to make the routing of mouse events while dragging conform to
|
||||
// standard OS X practice, and to the Cocoa NPAPI spec. See bug 525078.
|
||||
NS_IMETHODIMP
|
||||
nsObjectFrame::HandlePress(nsPresContext* aPresContext,
|
||||
nsGUIEvent* anEvent,
|
||||
nsEventStatus* anEventStatus)
|
||||
{
|
||||
nsIPresShell::SetCapturingContent(GetContent(), CAPTURE_IGNOREALLOWED);
|
||||
return nsObjectFrameSuper::HandlePress(aPresContext, anEvent, anEventStatus);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
nsObjectFrame::GetPluginInstance(nsIPluginInstance*& aPluginInstance)
|
||||
{
|
||||
|
@ -4264,6 +4277,16 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
|
|||
}
|
||||
break;
|
||||
case NS_MOUSE_MOVE:
|
||||
{
|
||||
// Ignore mouse-moved events that happen as part of a dragging
|
||||
// operation that started over another frame. See bug 525078.
|
||||
nsCOMPtr<nsFrameSelection> frameselection = mObjectFrame->GetFrameSelection();
|
||||
if (frameselection->GetMouseDownState() &&
|
||||
(nsIPresShell::GetCapturingContent() != mObjectFrame->GetContent())) {
|
||||
pluginWidget->EndDrawPlugin();
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
}
|
||||
#ifndef NP_NO_CARBON
|
||||
if (eventModel == NPEventModelCarbon) {
|
||||
synthCarbonEvent.what = osEvt;
|
||||
|
@ -4288,15 +4311,34 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
|
|||
}
|
||||
break;
|
||||
case NS_MOUSE_BUTTON_UP:
|
||||
// If we're in a dragging operation that started over another frame,
|
||||
// either ignore the mouse-up event (in the Carbon Event Model) or
|
||||
// convert it into a mouse-entered event (in the Cocoa Event Model).
|
||||
// See bug 525078.
|
||||
if ((static_cast<const nsMouseEvent&>(anEvent).button == nsMouseEvent::eLeftButton) &&
|
||||
(nsIPresShell::GetCapturingContent() != mObjectFrame->GetContent())) {
|
||||
#ifndef NP_NO_CARBON
|
||||
if (eventModel == NPEventModelCarbon) {
|
||||
synthCarbonEvent.what = mouseUp;
|
||||
} else
|
||||
if (eventModel == NPEventModelCarbon) {
|
||||
pluginWidget->EndDrawPlugin();
|
||||
return nsEventStatus_eIgnore;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
synthCocoaEvent.type = NPCocoaEventMouseUp;
|
||||
synthCocoaEvent.data.mouse.pluginX = static_cast<double>(ptPx.x);
|
||||
synthCocoaEvent.data.mouse.pluginY = static_cast<double>(ptPx.y);
|
||||
{
|
||||
synthCocoaEvent.type = NPCocoaEventMouseEntered;
|
||||
synthCocoaEvent.data.mouse.pluginX = static_cast<double>(ptPx.x);
|
||||
synthCocoaEvent.data.mouse.pluginY = static_cast<double>(ptPx.y);
|
||||
}
|
||||
} else {
|
||||
#ifndef NP_NO_CARBON
|
||||
if (eventModel == NPEventModelCarbon) {
|
||||
synthCarbonEvent.what = mouseUp;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
synthCocoaEvent.type = NPCocoaEventMouseUp;
|
||||
synthCocoaEvent.data.mouse.pluginX = static_cast<double>(ptPx.x);
|
||||
synthCocoaEvent.data.mouse.pluginY = static_cast<double>(ptPx.y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -90,6 +90,12 @@ public:
|
|||
nsGUIEvent* aEvent,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
NS_IMETHOD HandlePress(nsPresContext* aPresContext,
|
||||
nsGUIEvent* aEvent,
|
||||
nsEventStatus* aEventStatus);
|
||||
#endif
|
||||
|
||||
virtual nsIAtom* GetType() const;
|
||||
|
||||
virtual PRBool IsFrameOfType(PRUint32 aFlags) const
|
||||
|
|
|
@ -284,13 +284,13 @@ public:
|
|||
static void OnDestroyView(ChildView* aView);
|
||||
static BOOL WindowAcceptsEvent(NSWindow* aWindow, NSEvent* aEvent);
|
||||
static void ReEvaluateMouseEnterState(NSEvent* aEvent = nil);
|
||||
static ChildView* ViewForEvent(NSEvent* aEvent);
|
||||
|
||||
static ChildView* sLastMouseEventView;
|
||||
|
||||
private:
|
||||
|
||||
static NSWindow* WindowForEvent(NSEvent* aEvent);
|
||||
static ChildView* ViewForEvent(NSEvent* aEvent);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
|
|
@ -3135,10 +3135,11 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
|
||||
if (!mGeckoChild)
|
||||
return;
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
||||
nsMouseEvent geckoEvent(PR_TRUE, NS_MOUSE_BUTTON_UP, nsnull, nsMouseEvent::eReal);
|
||||
[self convertCocoaMouseEvent:theEvent toGeckoEvent:&geckoEvent];
|
||||
if (nsCocoaUtils::GetCocoaEventModifierFlags(theEvent) & NSControlKeyMask)
|
||||
|
@ -3149,35 +3150,67 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
|||
// Create event for use by plugins.
|
||||
// This is going to our child view so we don't need to look up the destination
|
||||
// event type.
|
||||
if (mIsPluginView) {
|
||||
#ifndef NP_NO_CARBON
|
||||
EventRecord carbonEvent;
|
||||
if (mPluginEventModel == NPEventModelCarbon) {
|
||||
carbonEvent.what = mouseUp;
|
||||
carbonEvent.message = 0;
|
||||
carbonEvent.when = ::TickCount();
|
||||
::GetGlobalMouse(&carbonEvent.where);
|
||||
carbonEvent.modifiers = ::GetCurrentKeyModifiers();
|
||||
geckoEvent.pluginEvent = &carbonEvent;
|
||||
}
|
||||
EventRecord carbonEvent;
|
||||
if (mPluginEventModel == NPEventModelCarbon) {
|
||||
carbonEvent.what = mouseUp;
|
||||
carbonEvent.message = 0;
|
||||
carbonEvent.when = ::TickCount();
|
||||
::GetGlobalMouse(&carbonEvent.where);
|
||||
carbonEvent.modifiers = ::GetCurrentKeyModifiers();
|
||||
geckoEvent.pluginEvent = &carbonEvent;
|
||||
}
|
||||
#endif
|
||||
NPCocoaEvent cocoaEvent;
|
||||
if (mPluginEventModel == NPEventModelCocoa) {
|
||||
InitNPCocoaEvent(&cocoaEvent);
|
||||
NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
cocoaEvent.type = NPCocoaEventMouseUp;
|
||||
cocoaEvent.data.mouse.modifierFlags = [theEvent modifierFlags];
|
||||
cocoaEvent.data.mouse.pluginX = point.x;
|
||||
cocoaEvent.data.mouse.pluginY = point.y;
|
||||
cocoaEvent.data.mouse.buttonNumber = [theEvent buttonNumber];
|
||||
cocoaEvent.data.mouse.clickCount = [theEvent clickCount];
|
||||
cocoaEvent.data.mouse.deltaX = [theEvent deltaX];
|
||||
cocoaEvent.data.mouse.deltaY = [theEvent deltaY];
|
||||
cocoaEvent.data.mouse.deltaZ = [theEvent deltaZ];
|
||||
geckoEvent.pluginEvent = &cocoaEvent;
|
||||
NPCocoaEvent cocoaEvent;
|
||||
if (mPluginEventModel == NPEventModelCocoa) {
|
||||
InitNPCocoaEvent(&cocoaEvent);
|
||||
NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
cocoaEvent.type = NPCocoaEventMouseUp;
|
||||
cocoaEvent.data.mouse.modifierFlags = [theEvent modifierFlags];
|
||||
cocoaEvent.data.mouse.pluginX = point.x;
|
||||
cocoaEvent.data.mouse.pluginY = point.y;
|
||||
cocoaEvent.data.mouse.buttonNumber = [theEvent buttonNumber];
|
||||
cocoaEvent.data.mouse.clickCount = [theEvent clickCount];
|
||||
cocoaEvent.data.mouse.deltaX = [theEvent deltaX];
|
||||
cocoaEvent.data.mouse.deltaY = [theEvent deltaY];
|
||||
cocoaEvent.data.mouse.deltaZ = [theEvent deltaZ];
|
||||
geckoEvent.pluginEvent = &cocoaEvent;
|
||||
}
|
||||
}
|
||||
|
||||
mGeckoChild->DispatchWindowEvent(geckoEvent);
|
||||
|
||||
// If our mouse-up event's location is over some other object (as might
|
||||
// happen if it came at the end of a dragging operation), also send our
|
||||
// Gecko frame a mouse-exit event.
|
||||
if (mIsPluginView) {
|
||||
#ifndef NP_NO_CARBON
|
||||
if (mPluginEventModel == NPEventModelCocoa)
|
||||
#endif
|
||||
{
|
||||
if (ChildViewMouseTracker::ViewForEvent(theEvent) != self) {
|
||||
nsMouseEvent geckoExitEvent(PR_TRUE, NS_MOUSE_EXIT, nsnull, nsMouseEvent::eReal);
|
||||
[self convertCocoaMouseEvent:theEvent toGeckoEvent:&geckoExitEvent];
|
||||
|
||||
NPCocoaEvent cocoaEvent;
|
||||
InitNPCocoaEvent(&cocoaEvent);
|
||||
NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
cocoaEvent.type = NPCocoaEventMouseExited;
|
||||
cocoaEvent.data.mouse.modifierFlags = [theEvent modifierFlags];
|
||||
cocoaEvent.data.mouse.pluginX = point.x;
|
||||
cocoaEvent.data.mouse.pluginY = point.y;
|
||||
cocoaEvent.data.mouse.buttonNumber = [theEvent buttonNumber];
|
||||
cocoaEvent.data.mouse.deltaX = [theEvent deltaX];
|
||||
cocoaEvent.data.mouse.deltaY = [theEvent deltaY];
|
||||
cocoaEvent.data.mouse.deltaZ = [theEvent deltaZ];
|
||||
geckoExitEvent.pluginEvent = &cocoaEvent;
|
||||
|
||||
mGeckoChild->DispatchWindowEvent(geckoExitEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
|
@ -3296,31 +3329,33 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
|||
[self convertCocoaMouseEvent:theEvent toGeckoEvent:&geckoEvent];
|
||||
|
||||
// create event for use by plugins
|
||||
if (mIsPluginView) {
|
||||
#ifndef NP_NO_CARBON
|
||||
EventRecord carbonEvent;
|
||||
if (mPluginEventModel == NPEventModelCarbon) {
|
||||
carbonEvent.what = NPEventType_AdjustCursorEvent;
|
||||
carbonEvent.message = 0;
|
||||
carbonEvent.when = ::TickCount();
|
||||
::GetGlobalMouse(&carbonEvent.where);
|
||||
carbonEvent.modifiers = btnState | ::GetCurrentKeyModifiers();
|
||||
geckoEvent.pluginEvent = &carbonEvent;
|
||||
}
|
||||
EventRecord carbonEvent;
|
||||
if (mPluginEventModel == NPEventModelCarbon) {
|
||||
carbonEvent.what = NPEventType_AdjustCursorEvent;
|
||||
carbonEvent.message = 0;
|
||||
carbonEvent.when = ::TickCount();
|
||||
::GetGlobalMouse(&carbonEvent.where);
|
||||
carbonEvent.modifiers = btnState | ::GetCurrentKeyModifiers();
|
||||
geckoEvent.pluginEvent = &carbonEvent;
|
||||
}
|
||||
#endif
|
||||
NPCocoaEvent cocoaEvent;
|
||||
if (mPluginEventModel == NPEventModelCocoa) {
|
||||
InitNPCocoaEvent(&cocoaEvent);
|
||||
NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
cocoaEvent.type = NPCocoaEventMouseDragged;
|
||||
cocoaEvent.data.mouse.modifierFlags = [theEvent modifierFlags];
|
||||
cocoaEvent.data.mouse.pluginX = point.x;
|
||||
cocoaEvent.data.mouse.pluginY = point.y;
|
||||
cocoaEvent.data.mouse.buttonNumber = [theEvent buttonNumber];
|
||||
cocoaEvent.data.mouse.clickCount = [theEvent clickCount];
|
||||
cocoaEvent.data.mouse.deltaX = [theEvent deltaX];
|
||||
cocoaEvent.data.mouse.deltaY = [theEvent deltaY];
|
||||
cocoaEvent.data.mouse.deltaZ = [theEvent deltaZ];
|
||||
geckoEvent.pluginEvent = &cocoaEvent;
|
||||
NPCocoaEvent cocoaEvent;
|
||||
if (mPluginEventModel == NPEventModelCocoa) {
|
||||
InitNPCocoaEvent(&cocoaEvent);
|
||||
NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
cocoaEvent.type = NPCocoaEventMouseDragged;
|
||||
cocoaEvent.data.mouse.modifierFlags = [theEvent modifierFlags];
|
||||
cocoaEvent.data.mouse.pluginX = point.x;
|
||||
cocoaEvent.data.mouse.pluginY = point.y;
|
||||
cocoaEvent.data.mouse.buttonNumber = [theEvent buttonNumber];
|
||||
cocoaEvent.data.mouse.clickCount = [theEvent clickCount];
|
||||
cocoaEvent.data.mouse.deltaX = [theEvent deltaX];
|
||||
cocoaEvent.data.mouse.deltaY = [theEvent deltaY];
|
||||
cocoaEvent.data.mouse.deltaZ = [theEvent deltaZ];
|
||||
geckoEvent.pluginEvent = &cocoaEvent;
|
||||
}
|
||||
}
|
||||
|
||||
mGeckoChild->DispatchWindowEvent(geckoEvent);
|
||||
|
@ -3401,31 +3436,33 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
|||
geckoEvent.clickCount = [theEvent clickCount];
|
||||
|
||||
// create event for use by plugins
|
||||
if (mIsPluginView) {
|
||||
#ifndef NP_NO_CARBON
|
||||
EventRecord carbonEvent;
|
||||
if (mPluginEventModel == NPEventModelCarbon) {
|
||||
carbonEvent.what = mouseUp;
|
||||
carbonEvent.message = 0;
|
||||
carbonEvent.when = ::TickCount();
|
||||
::GetGlobalMouse(&carbonEvent.where);
|
||||
carbonEvent.modifiers = controlKey; // fake a context menu click
|
||||
geckoEvent.pluginEvent = &carbonEvent;
|
||||
}
|
||||
EventRecord carbonEvent;
|
||||
if (mPluginEventModel == NPEventModelCarbon) {
|
||||
carbonEvent.what = mouseUp;
|
||||
carbonEvent.message = 0;
|
||||
carbonEvent.when = ::TickCount();
|
||||
::GetGlobalMouse(&carbonEvent.where);
|
||||
carbonEvent.modifiers = controlKey; // fake a context menu click
|
||||
geckoEvent.pluginEvent = &carbonEvent;
|
||||
}
|
||||
#endif
|
||||
NPCocoaEvent cocoaEvent;
|
||||
if (mPluginEventModel == NPEventModelCocoa) {
|
||||
InitNPCocoaEvent(&cocoaEvent);
|
||||
NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
cocoaEvent.type = NPCocoaEventMouseUp;
|
||||
cocoaEvent.data.mouse.modifierFlags = [theEvent modifierFlags];
|
||||
cocoaEvent.data.mouse.pluginX = point.x;
|
||||
cocoaEvent.data.mouse.pluginY = point.y;
|
||||
cocoaEvent.data.mouse.buttonNumber = [theEvent buttonNumber];
|
||||
cocoaEvent.data.mouse.clickCount = [theEvent clickCount];
|
||||
cocoaEvent.data.mouse.deltaX = [theEvent deltaX];
|
||||
cocoaEvent.data.mouse.deltaY = [theEvent deltaY];
|
||||
cocoaEvent.data.mouse.deltaZ = [theEvent deltaZ];
|
||||
geckoEvent.pluginEvent = &cocoaEvent;
|
||||
NPCocoaEvent cocoaEvent;
|
||||
if (mPluginEventModel == NPEventModelCocoa) {
|
||||
InitNPCocoaEvent(&cocoaEvent);
|
||||
NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
cocoaEvent.type = NPCocoaEventMouseUp;
|
||||
cocoaEvent.data.mouse.modifierFlags = [theEvent modifierFlags];
|
||||
cocoaEvent.data.mouse.pluginX = point.x;
|
||||
cocoaEvent.data.mouse.pluginY = point.y;
|
||||
cocoaEvent.data.mouse.buttonNumber = [theEvent buttonNumber];
|
||||
cocoaEvent.data.mouse.clickCount = [theEvent clickCount];
|
||||
cocoaEvent.data.mouse.deltaX = [theEvent deltaX];
|
||||
cocoaEvent.data.mouse.deltaY = [theEvent deltaY];
|
||||
cocoaEvent.data.mouse.deltaZ = [theEvent deltaZ];
|
||||
geckoEvent.pluginEvent = &cocoaEvent;
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
|
Загрузка…
Ссылка в новой задаче