From 331b7fa11c84107e3300b14ece5fc5991cfc35e9 Mon Sep 17 00:00:00 2001 From: Zeno Albisser <zeno.albisser@digia.com> Date: Fri, 31 Jan 2014 17:24:40 +0100 Subject: [PATCH] Add TakeFocus in WebContentsViewQt for passing on tab focus. Chromium calls RenderViewHostDelegate::TakeFocus when the last focusable item within the page was reached. We then have to move the focus on to the next/previous QQuickItem. Change-Id: Id0128053602ff1220c1bced1b218050b66fef659 Reviewed-by: Andras Becsi <andras.becsi@digia.com> --- examples/quick/quicknanobrowser/quickwindow.qml | 10 ++++++++++ src/core/web_contents_adapter_client.h | 1 + src/core/web_contents_view_qt.cpp | 5 +++++ src/core/web_contents_view_qt.h | 2 ++ src/webengine/api/qquickwebengineview.cpp | 12 ++++++++++++ src/webengine/api/qquickwebengineview_p_p.h | 1 + .../render_widget_host_view_qt_delegate_quick.h | 6 +++++- src/webenginewidgets/api/qwebenginepage_p.h | 2 ++ 8 files changed, 38 insertions(+), 1 deletion(-) diff --git a/examples/quick/quicknanobrowser/quickwindow.qml b/examples/quick/quicknanobrowser/quickwindow.qml index 63f86458e..88fc9f8a0 100644 --- a/examples/quick/quicknanobrowser/quickwindow.qml +++ b/examples/quick/quicknanobrowser/quickwindow.qml @@ -44,6 +44,7 @@ import QtWebEngine.experimental 1.0 import QtQuick.Controls 1.0 import QtQuick.Controls.Styles 1.0 import QtQuick.Layouts 1.0 +import QtQuick.Controls.Private 1.0 ApplicationWindow { id: browserWindow @@ -55,6 +56,12 @@ ApplicationWindow { visible: true title: tabs.currentView && tabs.currentView.title + // Create a styleItem to determine the platform. + // When using style "mac", ToolButtons are not supposed to accept focus. + StyleItem { id: styleItem } + property bool platformIsMac: styleItem.style == "mac" + + Action { id: focus shortcut: "Ctrl+L" @@ -94,17 +101,20 @@ ApplicationWindow { iconSource: "icons/go-previous.png" onClicked: tabs.currentView.goBack() enabled: tabs.currentView && tabs.currentView.canGoBack + activeFocusOnTab: !browserWindow.platformIsMac } ToolButton { id: forwardButton iconSource: "icons/go-next.png" onClicked: tabs.currentView.goForward() enabled: tabs.currentView && tabs.currentView.canGoForward + activeFocusOnTab: !browserWindow.platformIsMac } ToolButton { id: reloadButton iconSource: tabs.currentView && tabs.currentView.loading ? "icons/process-stop.png" : "icons/view-refresh.png" onClicked: tabs.currentView && tabs.currentView.loading ? tabs.currentView.stop() : tabs.currentView.reload() + activeFocusOnTab: !browserWindow.platformIsMac } TextField { id: addressBar diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 598840f1d..077e21500 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -132,6 +132,7 @@ public: virtual void didRunJavaScript(const QVariant& result, quint64 requestId) = 0; virtual void didFetchDocumentMarkup(const QString& result, quint64 requestId) = 0; virtual void didFetchDocumentInnerText(const QString& result, quint64 requestId) = 0; + virtual void passOnFocus(bool reverse) = 0; virtual void javaScriptConsoleMessage(int level, const QString& message, int lineNumber, const QString& sourceID) = 0; }; diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp index 65b8e5f3a..a4cb3556e 100644 --- a/src/core/web_contents_view_qt.cpp +++ b/src/core/web_contents_view_qt.cpp @@ -130,3 +130,8 @@ void WebContentsViewQt::ShowContextMenu(const content::ContextMenuParams ¶ms WebEngineContextMenuData contextMenuData(fromParams(params)); m_client->contextMenuRequested(contextMenuData); } + +void WebContentsViewQt::TakeFocus(bool reverse) +{ + m_client->passOnFocus(reverse); +} diff --git a/src/core/web_contents_view_qt.h b/src/core/web_contents_view_qt.h index ee81ccc81..1c9da487b 100644 --- a/src/core/web_contents_view_qt.h +++ b/src/core/web_contents_view_qt.h @@ -112,6 +112,8 @@ public: virtual void ShowContextMenu(const content::ContextMenuParams ¶ms) Q_DECL_OVERRIDE; + virtual void TakeFocus(bool reverse) Q_DECL_OVERRIDE; + #if defined(OS_MACOSX) virtual void SetAllowOverlappingViews(bool overlapping) Q_DECL_OVERRIDE { QT_NOT_YET_IMPLEMENTED } virtual void CloseTabAfterEventTracking() Q_DECL_OVERRIDE { QT_NOT_YET_IMPLEMENTED } diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 049e353b6..2f5d868ea 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -180,6 +180,18 @@ void QQuickWebEngineViewPrivate::runFileChooser(FileChooserMode mode, const QStr ui()->showFilePicker(mode, defaultFileName, acceptedMimeTypes, adapter); } +void QQuickWebEngineViewPrivate::passOnFocus(bool reverse) +{ + Q_Q(QQuickWebEngineView); + // In one direction we would pass forward the focus to RenderWidgetHostViewQtDelegateQuick(Painted), + // which in return would forward the tab key event and therefore the focus back to the QQuickWebEngineView. + // This is why we skip RenderWidgetHostViewQtDelegateQuick in the focus chain. + QQuickItem* current = QQuickItemPrivate::nextPrevItemInTabFocusChain(q, !reverse); + if (!qobject_cast<RenderWidgetHostViewQtDelegateQuick*>(current) && !qobject_cast<RenderWidgetHostViewQtDelegateQuickPainted*>(current)) + current = q; + focusNextPrev(current, !reverse); +} + void QQuickWebEngineViewPrivate::titleChanged(const QString &title) { Q_Q(QQuickWebEngineView); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 37ac9edf0..3de597469 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -141,6 +141,7 @@ public: virtual void didRunJavaScript(const QVariant&, quint64) Q_DECL_OVERRIDE { } virtual void didFetchDocumentMarkup(const QString&, quint64) Q_DECL_OVERRIDE { } virtual void didFetchDocumentInnerText(const QString&, quint64) Q_DECL_OVERRIDE { } + virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE; virtual void javaScriptConsoleMessage(int level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE; void setDevicePixelRatio(qreal); diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.h b/src/webengine/render_widget_host_view_qt_delegate_quick.h index 9dbe79941..8f32689d0 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.h +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h @@ -60,6 +60,10 @@ public: : ItemBaseT(parent) , m_client(client) { + this->setFocus(true); + this->setActiveFocusOnTab(true); + this->setFlag(QQuickItem::ItemIsFocusScope); + this->setAcceptedMouseButtons(Qt::AllButtons); this->setAcceptHoverEvents(true); } @@ -143,7 +147,7 @@ public: void mousePressEvent(QMouseEvent *event) { - this->setFocus(true); + this->forceActiveFocus(); m_client->forwardEvent(event); } diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index 595318ffc..0a90eda07 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -83,6 +83,8 @@ public: virtual void didRunJavaScript(const QVariant& result, quint64 requestId) Q_DECL_OVERRIDE; virtual void didFetchDocumentMarkup(const QString& result, quint64 requestId) Q_DECL_OVERRIDE; virtual void didFetchDocumentInnerText(const QString& result, quint64 requestId) Q_DECL_OVERRIDE; + virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE { }; + virtual void javaScriptConsoleMessage(int level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE; void updateAction(QWebEnginePage::WebAction) const; -- GitLab