Bug 1362382 - Move RegisterDragDrop to be called during idle time, if possible draft
authorKirk Steuber <ksteuber@mozilla.com>
Wed, 30 Aug 2017 11:18:25 -0700
changeset 660177 7b01a1a7c2613646142b68240da02c602317cc09
parent 656783 4984da22242841a5d84c4e5fd866e93a450d9723
child 730144 76f6914066b280c4a49757cee78997e4e62b028d
push id78300
push userksteuber@mozilla.com
push dateWed, 06 Sep 2017 16:48:07 +0000
bugs1362382
milestone57.0a1
Bug 1362382 - Move RegisterDragDrop to be called during idle time, if possible Additionally, do not call RegisterDragDrop for hidden windows. MozReview-Commit-ID: Fv8j9FntGGT
view/nsView.cpp
widget/nsBaseWidget.cpp
widget/nsBaseWidget.h
widget/nsIWidget.h
widget/windows/nsWindow.cpp
--- a/view/nsView.cpp
+++ b/view/nsView.cpp
@@ -711,17 +711,20 @@ nsresult nsView::AttachToTopLevelWidget(
 
   // Note, the previous device context will be released. Detaching
   // will not restore the old one.
   aWidget->AttachViewToTopLevel(!nsIWidget::UsePuppetWidgets());
 
   mWindow = aWidget;
 
   mWindow->SetAttachedWidgetListener(this);
-  mWindow->EnableDragDrop(true);
+  if (mWindow->WindowType() != eWindowType_invisible) {
+    nsresult rv = mWindow->AsyncEnableDragDrop(true);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
   mWidgetIsTopLevel = true;
 
   // Refresh the view bounds
   CalcWidgetBounds(mWindow->WindowType());
 
   return NS_OK;
 }
 
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -2224,16 +2224,27 @@ nsBaseWidget::UnregisterPluginWindowForR
     NS_WARNING("This is not a valid native widget!");
     return;
   }
   MOZ_ASSERT(sPluginWidgetList);
   sPluginWidgetList->Remove(id);
 #endif
 }
 
+nsresult
+nsBaseWidget::AsyncEnableDragDrop(bool aEnable)
+{
+  return NS_IdleDispatchToCurrentThread(
+    NS_NewRunnableFunction("AsyncEnableDragDropFn",
+                           [this, aEnable]() {
+                             EnableDragDrop(aEnable);
+                           }),
+    1000);
+}
+
 // static
 nsIWidget*
 nsIWidget::LookupRegisteredPluginWindow(uintptr_t aWindowID)
 {
 #if !defined(XP_WIN) && !defined(MOZ_WIDGET_GTK)
   NS_NOTREACHED("nsBaseWidget::LookupRegisteredPluginWindow not implemented!");
   return nullptr;
 #else
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -245,16 +245,17 @@ public:
   virtual void            ResizeClient(double aX, double aY, double aWidth, double aHeight, bool aRepaint) override;
   virtual LayoutDeviceIntRect GetBounds() override;
   virtual LayoutDeviceIntRect GetClientBounds() override;
   virtual LayoutDeviceIntRect GetScreenBounds() override;
   virtual MOZ_MUST_USE nsresult GetRestoredBounds(LayoutDeviceIntRect& aRect) override;
   virtual nsresult        SetNonClientMargins(LayoutDeviceIntMargin& aMargins) override;
   virtual LayoutDeviceIntPoint GetClientOffset() override;
   virtual void            EnableDragDrop(bool aEnable) override {};
+  virtual nsresult        AsyncEnableDragDrop(bool aEnable);
   virtual MOZ_MUST_USE nsresult
                           GetAttention(int32_t aCycleCount) override
                           { return NS_OK; }
   virtual bool            HasPendingInputEvent() override;
   virtual void            SetIcon(const nsAString &aIconSpec) override {}
   virtual void            SetWindowTitlebarColor(nscolor aColor, bool aActive)
                             override {}
   virtual void            SetDrawsInTitlebar(bool aState) override {}
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -1410,16 +1410,17 @@ class nsIWidget : public nsISupports
      * Returns true if APZ is in use, false otherwise.
      */
     virtual bool AsyncPanZoomEnabled() const = 0;
 
     /**
      * Enables the dropping of files to a widget.
      */
     virtual void EnableDragDrop(bool aEnable) = 0;
+    virtual nsresult AsyncEnableDragDrop(bool aEnable) = 0;
 
     /**
      * Enables/Disables system mouse capture.
      * @param aCapture true enables mouse capture, false disables mouse capture
      *
      */
     virtual void CaptureMouse(bool aCapture) = 0;
 
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -3767,17 +3767,20 @@ nsWindow::ClientToWindowSize(const Layou
  *
  * Enables/Disables drag and drop of files on this widget.
  *
  **************************************************************/
 
 void
 nsWindow::EnableDragDrop(bool aEnable)
 {
-  NS_ASSERTION(mWnd, "nsWindow::EnableDragDrop() called after Destroy()");
+  if (!mWnd) {
+    // Return early if the window already closed
+    return;
+  }
 
   if (aEnable) {
     if (!mNativeDragTarget) {
       mNativeDragTarget = new nsNativeDragTarget(this);
       mNativeDragTarget->AddRef();
       if (SUCCEEDED(::CoLockObjectExternal((LPUNKNOWN)mNativeDragTarget,
                                            TRUE, FALSE))) {
         ::RegisterDragDrop(mWnd, (LPDROPTARGET)mNativeDragTarget);