[tbb-commits] [tor-browser/esr24] Backed out changeset 6402fb9a21cb (bug 995603) for causing bug 1021815. a=abillings

mikeperry at torproject.org mikeperry at torproject.org
Fri Aug 29 05:26:41 UTC 2014


commit 1b9259cf6ad5f15be9f3ae54e54205743bab6bc1
Author: Ryan VanderMeulen <ryanvm at gmail.com>
Date:   Mon Jun 9 14:42:40 2014 -0400

    Backed out changeset 6402fb9a21cb (bug 995603) for causing bug 1021815. a=abillings
---
 content/events/src/nsContentEventHandler.cpp |   25 ++------
 content/events/src/nsContentEventHandler.h   |    2 +-
 widget/cocoa/nsChildView.mm                  |   79 +++++++++++++++++---------
 widget/cocoa/nsCocoaWindow.h                 |    3 +
 widget/cocoa/nsCocoaWindow.mm                |   30 ++++++++++
 5 files changed, 93 insertions(+), 46 deletions(-)

diff --git a/content/events/src/nsContentEventHandler.cpp b/content/events/src/nsContentEventHandler.cpp
index e989535..8b151cb 100644
--- a/content/events/src/nsContentEventHandler.cpp
+++ b/content/events/src/nsContentEventHandler.cpp
@@ -44,8 +44,11 @@ nsContentEventHandler::nsContentEventHandler(
 }
 
 nsresult
-nsContentEventHandler::InitBasic()
+nsContentEventHandler::InitCommon()
 {
+  if (mSelection)
+    return NS_OK;
+
   NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
 
   // If text frame which has overflowing selection underline is dirty,
@@ -55,24 +58,11 @@ nsContentEventHandler::InitBasic()
   // Flushing notifications can cause mPresShell to be destroyed (bug 577963).
   NS_ENSURE_TRUE(!mPresShell->IsDestroying(), NS_ERROR_FAILURE);
 
-  return NS_OK;
-}
-
-nsresult
-nsContentEventHandler::InitCommon()
-{
-  if (mSelection) {
-    return NS_OK;
-  }
-
-  nsresult rv = InitBasic();
-  NS_ENSURE_SUCCESS(rv, rv);
-
   nsCopySupport::GetSelectionForCopy(mPresShell->GetDocument(),
                                      getter_AddRefs(mSelection));
 
   nsCOMPtr<nsIDOMRange> firstRange;
-  rv = mSelection->GetRangeAt(0, getter_AddRefs(firstRange));
+  nsresult rv = mSelection->GetRangeAt(0, getter_AddRefs(firstRange));
   // This shell doesn't support selection.
   if (NS_FAILED(rv))
     return NS_ERROR_NOT_AVAILABLE;
@@ -870,13 +860,10 @@ nsContentEventHandler::OnQueryCharacterAtPoint(nsQueryContentEvent* aEvent)
 nsresult
 nsContentEventHandler::OnQueryDOMWidgetHittest(nsQueryContentEvent* aEvent)
 {
-  NS_ASSERTION(aEvent, "aEvent must not be null");
-
-  nsresult rv = InitBasic();
+  nsresult rv = Init(aEvent);
   if (NS_FAILED(rv))
     return rv;
 
-  aEvent->mSucceeded = false;
   aEvent->mReply.mWidgetIsHit = false;
 
   NS_ENSURE_TRUE(aEvent->widget, NS_ERROR_FAILURE);
diff --git a/content/events/src/nsContentEventHandler.h b/content/events/src/nsContentEventHandler.h
index 1624d35..4c4f492 100644
--- a/content/events/src/nsContentEventHandler.h
+++ b/content/events/src/nsContentEventHandler.h
@@ -66,7 +66,7 @@ protected:
   nsresult Init(nsQueryContentEvent* aEvent);
   nsresult Init(nsSelectionEvent* aEvent);
 
-  nsresult InitBasic();
+  // InitCommon() is called from each Init().
   nsresult InitCommon();
 
 public:
diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm
index 6ced313..aef01c7 100644
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -2790,32 +2790,6 @@ 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];
-    cocoaLoc.y = nsCocoaUtils::FlippedScreenY(cocoaLoc.y);
-    nsIntPoint widgetLoc = mGeckoChild->CocoaPointsToDevPixels(cocoaLoc) -
-      mGeckoChild->WidgetToScreenOffset();
-
-    nsQueryContentEvent 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
@@ -4939,12 +4913,65 @@ 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);
+  nsIntPoint widgetLoc = mGeckoChild->CocoaPointsToDevPixels(eventLoc) -
+    mGeckoChild->WidgetToScreenOffset();
+
+  nsQueryContentEvent 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) {
     nsPluginEvent pluginEvent(true, NS_PLUGIN_FOCUS_EVENT, mGeckoChild);
     NPCocoaEvent cocoaEvent;
diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h
index dc5994671..ac434e0 100644
--- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h
@@ -316,6 +316,9 @@ public:
 
     void SetPopupWindowLevel();
 
+    bool IsChildInFailingLeftClickThrough(NSView *aChild);
+    bool ShouldFocusPlugin();
+
     NS_IMETHOD         ReparentNativeWidget(nsIWidget* aNewParent);
 protected:
 
diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
index b435155..b95c072 100644
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -2051,6 +2051,36 @@ 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(NotificationToIME aNotification)
 {





More information about the tbb-commits mailing list