Bug 1362382 - Move RegisterDragDrop to be called during idle time, if possible
Additionally, do not call RegisterDragDrop for hidden windows.
MozReview-Commit-ID: Fv8j9FntGGT
--- 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);