mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 995603 - Ensure mouse-enter/exit events are sent to plugins as appropriate. r=mstange,masayuki
This commit is contained in:
parent
115813e446
commit
b9f66f47e7
@ -50,12 +50,8 @@ ContentEventHandler::ContentEventHandler(nsPresContext* aPresContext)
|
||||
}
|
||||
|
||||
nsresult
|
||||
ContentEventHandler::InitCommon()
|
||||
ContentEventHandler::InitBasic()
|
||||
{
|
||||
if (mSelection) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// If text frame which has overflowing selection underline is dirty,
|
||||
@ -65,11 +61,24 @@ ContentEventHandler::InitCommon()
|
||||
// Flushing notifications can cause mPresShell to be destroyed (bug 577963).
|
||||
NS_ENSURE_TRUE(!mPresShell->IsDestroying(), NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
ContentEventHandler::InitCommon()
|
||||
{
|
||||
if (mSelection) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = InitBasic();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCopySupport::GetSelectionForCopy(mPresShell->GetDocument(),
|
||||
getter_AddRefs(mSelection));
|
||||
|
||||
nsCOMPtr<nsIDOMRange> firstRange;
|
||||
nsresult rv = mSelection->GetRangeAt(0, getter_AddRefs(firstRange));
|
||||
rv = mSelection->GetRangeAt(0, getter_AddRefs(firstRange));
|
||||
// This shell doesn't support selection.
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
@ -996,11 +1005,14 @@ ContentEventHandler::OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent)
|
||||
nsresult
|
||||
ContentEventHandler::OnQueryDOMWidgetHittest(WidgetQueryContentEvent* aEvent)
|
||||
{
|
||||
nsresult rv = Init(aEvent);
|
||||
NS_ASSERTION(aEvent, "aEvent must not be null");
|
||||
|
||||
nsresult rv = InitBasic();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
aEvent->mSucceeded = false;
|
||||
aEvent->mReply.mWidgetIsHit = false;
|
||||
|
||||
NS_ENSURE_TRUE(aEvent->widget, NS_ERROR_FAILURE);
|
||||
|
@ -68,7 +68,7 @@ protected:
|
||||
nsresult Init(WidgetQueryContentEvent* aEvent);
|
||||
nsresult Init(WidgetSelectionEvent* aEvent);
|
||||
|
||||
// InitCommon() is called from each Init().
|
||||
nsresult InitBasic();
|
||||
nsresult InitCommon();
|
||||
|
||||
public:
|
||||
|
@ -3272,6 +3272,31 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
||||
return mIsPluginView;
|
||||
}
|
||||
|
||||
- (NSView *)hitTest:(NSPoint)aPoint
|
||||
{
|
||||
NSView* target = [super hitTest:aPoint];
|
||||
if ((target == self) && [self isPluginView] && mGeckoChild) {
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
||||
NSPoint cocoaLoc = [[self superview] convertPoint:aPoint toView:self];
|
||||
LayoutDeviceIntPoint widgetLoc = LayoutDeviceIntPoint::FromUntyped(
|
||||
mGeckoChild->CocoaPointsToDevPixels(cocoaLoc));
|
||||
|
||||
WidgetQueryContentEvent hitTest(true, NS_QUERY_DOM_WIDGET_HITTEST,
|
||||
mGeckoChild);
|
||||
hitTest.InitForQueryDOMWidgetHittest(widgetLoc);
|
||||
// This might destroy our widget.
|
||||
mGeckoChild->DispatchWindowEvent(hitTest);
|
||||
if (!mGeckoChild) {
|
||||
return nil;
|
||||
}
|
||||
if (hitTest.mSucceeded && !hitTest.mReply.mWidgetIsHit) {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
// Are we processing an NSLeftMouseDown event that will fail to click through?
|
||||
// If so, we shouldn't focus or unfocus a plugin.
|
||||
- (BOOL)isInFailingLeftClickThrough
|
||||
@ -5528,67 +5553,12 @@ static int32_t RoundUp(double aDouble)
|
||||
return !mGeckoChild->DispatchWindowEvent(geckoEvent);
|
||||
}
|
||||
|
||||
// Don't focus a plugin if the user has clicked on a DOM element above it.
|
||||
// In this case the user has actually clicked on the plugin's ChildView
|
||||
// (underneath the non-plugin DOM element). But we shouldn't allow the
|
||||
// ChildView to be focused. See bug 627649.
|
||||
- (BOOL)currentEventShouldFocusPlugin
|
||||
{
|
||||
if (!mGeckoChild)
|
||||
return NO;
|
||||
|
||||
NSEvent* currentEvent = [NSApp currentEvent];
|
||||
if ([currentEvent type] != NSLeftMouseDown)
|
||||
return YES;
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
||||
// hitTest needs coordinates in device pixels
|
||||
NSPoint eventLoc = nsCocoaUtils::ScreenLocationForEvent(currentEvent);
|
||||
eventLoc.y = nsCocoaUtils::FlippedScreenY(eventLoc.y);
|
||||
LayoutDeviceIntPoint widgetLoc = LayoutDeviceIntPoint::FromUntyped(
|
||||
mGeckoChild->CocoaPointsToDevPixels(eventLoc) -
|
||||
mGeckoChild->WidgetToScreenOffset());
|
||||
|
||||
WidgetQueryContentEvent hitTest(true, NS_QUERY_DOM_WIDGET_HITTEST,
|
||||
mGeckoChild);
|
||||
hitTest.InitForQueryDOMWidgetHittest(widgetLoc);
|
||||
// This might destroy our widget (and null out mGeckoChild).
|
||||
mGeckoChild->DispatchWindowEvent(hitTest);
|
||||
if (!mGeckoChild)
|
||||
return NO;
|
||||
if (hitTest.mSucceeded && !hitTest.mReply.mWidgetIsHit)
|
||||
return NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Don't focus a plugin if we're in a left click-through that will fail (see
|
||||
// [ChildView isInFailingLeftClickThrough] above).
|
||||
- (BOOL)shouldFocusPlugin:(BOOL)getFocus
|
||||
{
|
||||
if (!mGeckoChild)
|
||||
return NO;
|
||||
|
||||
nsCocoaWindow* windowWidget = mGeckoChild->GetXULWindowWidget();
|
||||
if (windowWidget && !windowWidget->ShouldFocusPlugin())
|
||||
return NO;
|
||||
|
||||
if (getFocus && ![self currentEventShouldFocusPlugin])
|
||||
return NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Returns NO if the plugin shouldn't be focused/unfocused.
|
||||
- (BOOL)updatePluginFocusStatus:(BOOL)getFocus
|
||||
{
|
||||
if (!mGeckoChild)
|
||||
return NO;
|
||||
|
||||
if (![self shouldFocusPlugin:getFocus])
|
||||
return NO;
|
||||
|
||||
if (mPluginEventModel == NPEventModelCocoa) {
|
||||
WidgetPluginEvent pluginEvent(true, NS_PLUGIN_FOCUS_EVENT, mGeckoChild);
|
||||
NPCocoaEvent cocoaEvent;
|
||||
|
@ -352,9 +352,6 @@ public:
|
||||
|
||||
void SetPopupWindowLevel();
|
||||
|
||||
bool IsChildInFailingLeftClickThrough(NSView *aChild);
|
||||
bool ShouldFocusPlugin();
|
||||
|
||||
NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent);
|
||||
protected:
|
||||
|
||||
|
@ -2090,36 +2090,6 @@ void nsCocoaWindow::SetPopupWindowLevel()
|
||||
}
|
||||
}
|
||||
|
||||
bool nsCocoaWindow::IsChildInFailingLeftClickThrough(NSView *aChild)
|
||||
{
|
||||
if ([aChild isKindOfClass:[ChildView class]]) {
|
||||
ChildView* childView = (ChildView*) aChild;
|
||||
if ([childView isInFailingLeftClickThrough])
|
||||
return true;
|
||||
}
|
||||
NSArray* subviews = [aChild subviews];
|
||||
if (subviews) {
|
||||
NSUInteger count = [subviews count];
|
||||
for (NSUInteger i = 0; i < count; ++i) {
|
||||
NSView* aView = (NSView*) [subviews objectAtIndex:i];
|
||||
if (IsChildInFailingLeftClickThrough(aView))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't focus a plugin if we're in a left click-through that will
|
||||
// fail (see [ChildView isInFailingLeftClickThrough]). Called from
|
||||
// [ChildView shouldFocusPlugin].
|
||||
bool nsCocoaWindow::ShouldFocusPlugin()
|
||||
{
|
||||
if (!mWindow || IsChildInFailingLeftClickThrough([mWindow contentView]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaWindow::NotifyIME(const IMENotification& aIMENotification)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user