Skip to content

Commit 659490b

Browse files
committed
Fix MouseMove event handling when opening a new tab with middle click.
When opening a new tab by middle clicking on a link in a web page, two MouseMove events are sent to Chromium consecutively, without getting proper acknowledgment events, which causes further move events not to be handled properly. Fix consists in preventing the second move event from being sent. Change-Id: Ia0a64698476226e472faa53f75b51dfb6ed477c9 Task-number: QTBUG-50031 Reviewed-by: Joerg Bornemann <[email protected]>
1 parent 7c5f2a9 commit 659490b

File tree

6 files changed

+35
-0
lines changed

6 files changed

+35
-0
lines changed

src/core/render_widget_host_view_qt.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,10 @@ bool RenderWidgetHostViewQt::forwardEvent(QEvent *event)
747747
Focus(); // Fall through.
748748
case QEvent::MouseButtonRelease:
749749
case QEvent::MouseMove:
750+
// Skip second MouseMove event when a window is being adopted, so that Chromium
751+
// can properly handle further move events.
752+
if (m_adapterClient->isBeingAdopted())
753+
return false;
750754
handleMouseEvent(static_cast<QMouseEvent*>(event));
751755
break;
752756
case QEvent::KeyPress:

src/core/web_contents_adapter_client.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ class QWEBENGINE_EXPORT WebContentsAdapterClient {
159159
virtual void focusContainer() = 0;
160160
virtual void unhandledKeyEvent(QKeyEvent *event) = 0;
161161
virtual void adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect & initialGeometry) = 0;
162+
virtual bool isBeingAdopted() = 0;
162163
virtual void close() = 0;
163164
virtual bool contextMenuRequested(const WebEngineContextMenuData&) = 0;
164165
virtual void navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) = 0;

src/webengine/api/qquickwebengineview.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,11 @@ void QQuickWebEngineViewPrivate::adoptNewWindow(WebContentsAdapter *newWebConten
421421
Q_EMIT q->newViewRequested(&request);
422422
}
423423

424+
bool QQuickWebEngineViewPrivate::isBeingAdopted()
425+
{
426+
return false;
427+
}
428+
424429
void QQuickWebEngineViewPrivate::close()
425430
{
426431
// Not implemented yet.

src/webengine/api/qquickwebengineview_p_p.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineViewPrivate : public QtWebEngine
141141
virtual void focusContainer() Q_DECL_OVERRIDE;
142142
virtual void unhandledKeyEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
143143
virtual void adoptNewWindow(QtWebEngineCore::WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &) Q_DECL_OVERRIDE;
144+
virtual bool isBeingAdopted() Q_DECL_OVERRIDE;
144145
virtual void close() Q_DECL_OVERRIDE;
145146
virtual void requestFullScreen(bool) Q_DECL_OVERRIDE;
146147
virtual bool isFullScreen() const Q_DECL_OVERRIDE;

src/webenginewidgets/api/qwebenginepage.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
185185
, view(0)
186186
, isLoading(false)
187187
, scriptCollection(new QWebEngineScriptCollectionPrivate(browserContextAdapter()->userScriptController(), adapter.data()))
188+
, m_isBeingAdopted(false)
188189
{
189190
memset(actions, 0, sizeof(actions));
190191
}
@@ -298,14 +299,35 @@ void QWebEnginePagePrivate::adoptNewWindow(WebContentsAdapter *newWebContents, W
298299
{
299300
Q_Q(QWebEnginePage);
300301
Q_UNUSED(userGesture);
302+
301303
QWebEnginePage *newPage = q->createWindow(toWindowType(disposition));
304+
305+
// Mark the new page as being in the process of being adopted, so that a second mouse move event
306+
// sent by newWebContents->initialize() gets filtered in RenderWidgetHostViewQt::forwardEvent.
307+
// The first mouse move event is being sent by q->createWindow(). This is necessary because
308+
// Chromium does not get a mouse move acknowledgment message between the two events, and
309+
// InputRouterImpl::ProcessMouseAck is not executed, thus all subsequent mouse move events
310+
// get coalesced together, and don't get processed at all.
311+
// The mouse move events are actually sent as a result of show() being called on
312+
// RenderWidgetHostViewQtDelegateWidget, both when creating the window and when initialize is
313+
// called.
314+
newPage->d_func()->m_isBeingAdopted = true;
315+
302316
// Overwrite the new page's WebContents with ours.
303317
if (newPage && newPage->d_func() != this) {
304318
newPage->d_func()->adapter = newWebContents;
305319
newWebContents->initialize(newPage->d_func());
306320
if (!initialGeometry.isEmpty())
307321
emit newPage->geometryChangeRequested(initialGeometry);
308322
}
323+
324+
// Page has finished the adoption process.
325+
newPage->d_func()->m_isBeingAdopted = false;
326+
}
327+
328+
bool QWebEnginePagePrivate::isBeingAdopted()
329+
{
330+
return m_isBeingAdopted;
309331
}
310332

311333
void QWebEnginePagePrivate::close()

src/webenginewidgets/api/qwebenginepage_p.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ class QWebEnginePagePrivate : public QtWebEngineCore::WebContentsAdapterClient
136136
virtual void focusContainer() Q_DECL_OVERRIDE;
137137
virtual void unhandledKeyEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
138138
virtual void adoptNewWindow(QtWebEngineCore::WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &initialGeometry) Q_DECL_OVERRIDE;
139+
virtual bool isBeingAdopted() Q_DECL_OVERRIDE;
139140
virtual void close() Q_DECL_OVERRIDE;
140141
virtual bool contextMenuRequested(const QtWebEngineCore::WebEngineContextMenuData &data) Q_DECL_OVERRIDE;
141142
virtual void navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) Q_DECL_OVERRIDE;
@@ -181,6 +182,7 @@ class QWebEnginePagePrivate : public QtWebEngineCore::WebContentsAdapterClient
181182
QtWebEngineCore::WebEngineContextMenuData m_menuData;
182183
bool isLoading;
183184
QWebEngineScriptCollection scriptCollection;
185+
bool m_isBeingAdopted;
184186

185187
mutable CallbackDirectory m_callbacks;
186188
mutable QAction *actions[QWebEnginePage::WebActionCount];

0 commit comments

Comments
 (0)