Bug 1147521 - Cannot type into comment area of plugin crash UI. r=smaug
authorSteven Michaud <smichaud@pobox.com>
Thu, 26 Mar 2015 19:38:13 -0500
changeset 266375 9ea27ee1d96d779ceffb8cecbfb3a924b83b5546
parent 266374 e99d72e0a529bd7b95e56fe39cad2e42ee1d1445
child 266376 1a049b3a7e08573571d04e4ce49e632aaa513c18
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1147521
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1147521 - Cannot type into comment area of plugin crash UI. r=smaug
dom/base/nsObjectLoadingContent.cpp
dom/html/HTMLObjectElement.cpp
dom/html/HTMLObjectElement.h
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -86,16 +86,23 @@
 
 #ifdef XP_WIN
 // Thanks so much, Microsoft! :(
 #ifdef CreateEvent
 #undef CreateEvent
 #endif
 #endif // XP_WIN
 
+#ifdef XP_MACOSX
+// HandlePluginCrashed() and HandlePluginInstantiated() needed from here to
+// fix bug 1147521.  Should later be replaced by proper interface methods,
+// maybe on nsIObjectLoadingContext.
+#include "mozilla/dom/HTMLObjectElement.h"
+#endif
+
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 static const char *kPrefJavaMIME = "plugin.java.mime";
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 #ifdef PR_LOGGING
@@ -862,16 +869,20 @@ nsObjectLoadingContent::InstantiatePlugi
   }
 
   nsCOMPtr<nsIRunnable> ev = \
     new nsSimplePluginEvent(thisContent,
                             doc,
                             NS_LITERAL_STRING("PluginInstantiated"));
   NS_DispatchToCurrentThread(ev);
 
+#ifdef XP_MACOSX
+  HTMLObjectElement::HandlePluginInstantiated(thisContent->AsElement());
+#endif
+
   return NS_OK;
 }
 
 void
 nsObjectLoadingContent::GetPluginAttributes(nsTArray<MozPluginParameter>& aAttributes)
 {
   aAttributes = mCachedAttributes;
 }
@@ -2718,24 +2729,29 @@ NS_IMETHODIMP
 nsObjectLoadingContent::PluginCrashed(nsIPluginTag* aPluginTag,
                                       const nsAString& pluginDumpID,
                                       const nsAString& browserDumpID,
                                       bool submittedCrashReport)
 {
   LOG(("OBJLC [%p]: Plugin Crashed, queuing crash event", this));
   NS_ASSERTION(mType == eType_Plugin, "PluginCrashed at non-plugin type");
 
+  nsCOMPtr<nsIContent> thisContent =
+    do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
+
+#ifdef XP_MACOSX
+  HTMLObjectElement::HandlePluginCrashed(thisContent->AsElement());
+#endif
+
   PluginDestroyed();
 
   // Switch to fallback/crashed state, notify
   LoadFallback(eFallbackCrashed, true);
 
   // send nsPluginCrashedEvent
-  nsCOMPtr<nsIContent> thisContent =
-    do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
 
   // Note that aPluginTag in invalidated after we're called, so copy 
   // out any data we need now.
   nsAutoCString pluginName;
   aPluginTag->GetName(pluginName);
   nsAutoCString pluginFilename;
   aPluginTag->GetFilename(pluginFilename);
 
--- a/dom/html/HTMLObjectElement.cpp
+++ b/dom/html/HTMLObjectElement.cpp
@@ -18,16 +18,17 @@
 #include "nsFormSubmission.h"
 #include "nsIObjectFrame.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsIWidget.h"
 #include "nsContentUtils.h"
 #ifdef XP_MACOSX
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/dom/Event.h"
+#include "nsFocusManager.h"
 #endif
 
 namespace mozilla {
 namespace dom {
 
 HTMLObjectElement::HTMLObjectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                                      FromParser aFromParser)
   : nsGenericHTMLFormElement(aNodeInfo),
@@ -146,29 +147,68 @@ public:
 private:
   nsCOMPtr<nsIWidget> mWidget;
   nsCOMPtr<Element> mElement;
 };
 
 void
 HTMLObjectElement::OnFocusBlurPlugin(Element* aElement, bool aFocus)
 {
+  // In general we don't want to call nsIWidget::SetPluginFocused() for any
+  // Element that doesn't have a plugin running.  But if SetPluginFocused(true)
+  // was just called for aElement while it had a plugin running, we want to
+  // make sure nsIWidget::SetPluginFocused(false) gets called for it now, even
+  // if aFocus is true.
+  if (aFocus) {
+    nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(aElement);
+    bool hasRunningPlugin = false;
+    if (olc) {
+      olc->GetHasRunningPlugin(&hasRunningPlugin);
+    }
+    if (!hasRunningPlugin) {
+      aFocus = false;
+    }
+  }
+
   if (aFocus || aElement == sLastFocused) {
     if (!aFocus) {
       sLastFocused = nullptr;
     }
     nsIWidget* widget = GetWidget(aElement);
     if (widget) {
       nsContentUtils::AddScriptRunner(
         new PluginFocusSetter(widget, aFocus ? aElement : nullptr));
     }
   }
 }
 
 void
+HTMLObjectElement::HandlePluginCrashed(Element* aElement)
+{
+  OnFocusBlurPlugin(aElement, false);
+}
+
+void
+HTMLObjectElement::HandlePluginInstantiated(Element* aElement)
+{
+  // If aElement is already focused when a plugin is instantiated, we need
+  // to initiate a call to nsIWidget::SetPluginFocused(true).  Otherwise
+  // keyboard input won't work in a click-to-play plugin until aElement
+  // loses focus and regains it.
+  nsIContent* focusedContent = nullptr;
+  nsFocusManager *fm = nsFocusManager::GetFocusManager();
+  if (fm) {
+    focusedContent = fm->GetFocusedContent();
+  }
+  if (SameCOMIdentity(focusedContent, aElement)) {
+    OnFocusBlurPlugin(aElement, true);
+  }
+}
+
+void
 HTMLObjectElement::HandleFocusBlurPlugin(Element* aElement,
                                          WidgetEvent* aEvent)
 {
   if (!aEvent->mFlags.mIsTrusted) {
     return;
   }
   switch (aEvent->message) {
     case NS_FOCUS_CONTENT: {
--- a/dom/html/HTMLObjectElement.h
+++ b/dom/html/HTMLObjectElement.h
@@ -31,16 +31,18 @@ public:
   virtual int32_t TabIndexDefault() override;
 
 #ifdef XP_MACOSX
   // nsIDOMEventTarget
   NS_IMETHOD PostHandleEvent(EventChainPostVisitor& aVisitor) override;
   // Helper methods
   static void OnFocusBlurPlugin(Element* aElement, bool aFocus);
   static void HandleFocusBlurPlugin(Element* aElement, WidgetEvent* aEvent);
+  static void HandlePluginCrashed(Element* aElement);
+  static void HandlePluginInstantiated(Element* aElement);
   // Weak pointer. Null if last action was blur.
   static Element* sLastFocused;
 #endif
 
   // Element
   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
 
   // nsIDOMHTMLObjectElement