diff options
author | Joerg Bornemann <joerg.bornemann@qt.io> | 2016-10-26 11:18:36 +0200 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@qt.io> | 2016-10-26 11:10:29 +0000 |
commit | 8caf750d57e9ebf7507f61951c45d3f31b5f5139 (patch) | |
tree | aa77fb9a37fecf393aab369e799433ba79aa3a40 /src/core | |
parent | 37c8b107743465053182d4e0169f42bbd804dafe (diff) |
Fix hang when dragging files from file picker onto QWebEngineView
The method WebContentsAdapter::updateDragPosition actively waits for the
UpdateDragCursor message, sent by the renderer. This active wait does
not work whenever we're currently in a base::MessageLoop::RunTask call,
because of its internal recursion guard nestable_tasks_allowed. Add a
check for nestable_tasks_allowed and bail out if we know that the active
wait will fail. This fixes the hang.
Ensure that the modal file picker dialog is shown outside of
base::MessageLoop::RunTask. This enables drag 'n drop updates from the
file picker to QWebEngineView.
Task-number: QTBUG-56488
Change-Id: Ia13ada9c19e7780e12ca633ab1caeac352aca2a9
Reviewed-by: Viktor Engelmann <viktor.engelmann@qt.io>
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/web_contents_adapter.cpp | 10 | ||||
-rw-r--r-- | src/core/web_contents_delegate_qt.cpp | 7 |
2 files changed, 16 insertions, 1 deletions
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 7285648fd..fc54c98ed 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -1159,6 +1159,16 @@ Qt::DropAction WebContentsAdapter::updateDragPosition(QDragMoveEvent *e, const Q rvh->DragTargetDragOver(toGfx(e->pos()), toGfx(screenPos), toWeb(e->possibleActions()), blink::WebInputEvent::LeftButtonDown); + base::MessageLoop *currentMessageLoop = base::MessageLoop::current(); + DCHECK(currentMessageLoop); + if (!currentMessageLoop->NestableTasksAllowed()) { + // We're already inside a MessageLoop::RunTask call, and scheduled tasks will not be + // executed. That means, updateDragAction will never be called, and the RunLoop below will + // remain blocked forever. + qWarning("WebContentsAdapter::updateDragPosition called from MessageLoop::RunTask."); + return Qt::IgnoreAction; + } + // Wait until we get notified via RenderViewHostDelegateView::UpdateDragCursor. This calls // WebContentsAdapter::updateDragAction that will eventually quit the nested loop. base::RunLoop loop; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index 06ae9c6da..757ae853c 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -74,6 +74,7 @@ #include "ui/events/latency_info.h" #include <QDesktopServices> +#include <QTimer> namespace QtWebEngineCore { @@ -325,7 +326,11 @@ void WebContentsDelegateQt::RunFileChooser(content::WebContents *web_contents, c acceptedMimeTypes.append(toQt(*it)); FilePickerController *controller = new FilePickerController(static_cast<FilePickerController::FileChooserMode>(params.mode), web_contents, toQt(params.default_file_name.value()), acceptedMimeTypes); - m_viewClient->runFileChooser(controller); + + // Defer the call to not block base::MessageLoop::RunTask with modal dialogs. + QTimer::singleShot(0, [this, controller] () { + m_viewClient->runFileChooser(controller); + }); } bool WebContentsDelegateQt::AddMessageToConsole(content::WebContents *source, int32_t level, const base::string16 &message, int32_t line_no, const base::string16 &source_id) |