diff options
author | Joerg Bornemann <joerg.bornemann@qt.io> | 2017-04-10 13:47:20 +0200 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@qt.io> | 2017-04-25 18:18:30 +0000 |
commit | 3902b27ee40400db6cf596ca0db31b6497f0421b (patch) | |
tree | 774bb6e244482dd308b7488e91cfdba4a3eee665 /src | |
parent | 3e7aab785a22e0bdf96d22e2ed03689c37554baa (diff) |
Override shortcuts in HTML input fields
When users defined a single-letter short cut it was not possible
to type this letter in HTML input fields.
Fix this by accepting ShortcutOverride events whenever the web page
is editing text.
Use QInputControl::isCommonTextEditShortcut for Qt 5.9 and later.
For the case where QtWebEngine is built against an older Qt a duplicated
code path is used.
Also, ensure users do not override web action short cuts.
Task-number: QTBUG-59053
Change-Id: Ic26cf2a040a72b118273c6645c00b2913b995b0b
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/core_chromium.pri | 1 | ||||
-rw-r--r-- | src/core/render_widget_host_view_qt_delegate.cpp | 113 | ||||
-rw-r--r-- | src/core/render_widget_host_view_qt_delegate.h | 2 | ||||
-rw-r--r-- | src/webengine/render_widget_host_view_qt_delegate_quick.cpp | 8 | ||||
-rw-r--r-- | src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp | 21 |
5 files changed, 140 insertions, 5 deletions
diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri index 9c1e9f0db..f13095bfe 100644 --- a/src/core/core_chromium.pri +++ b/src/core/core_chromium.pri @@ -79,6 +79,7 @@ SOURCES = \ qrc_protocol_handler_qt.cpp \ render_view_observer_host_qt.cpp \ render_widget_host_view_qt.cpp \ + render_widget_host_view_qt_delegate.cpp \ renderer/content_renderer_client_qt.cpp \ renderer/render_frame_observer_qt.cpp \ renderer/render_view_observer_qt.cpp \ diff --git a/src/core/render_widget_host_view_qt_delegate.cpp b/src/core/render_widget_host_view_qt_delegate.cpp new file mode 100644 index 000000000..a86900433 --- /dev/null +++ b/src/core/render_widget_host_view_qt_delegate.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "render_widget_host_view_qt_delegate.h" + +#include <QtCore/qvariant.h> +#include <QtGui/qevent.h> + +#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) +#include <QtGui/private/qinputcontrol_p.h> +#endif + +static bool isCommonTextEditShortcut(const QKeyEvent *ke) +{ +#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) + return QInputControl::isCommonTextEditShortcut(ke); +#else + if (ke->modifiers() == Qt::NoModifier + || ke->modifiers() == Qt::ShiftModifier + || ke->modifiers() == Qt::KeypadModifier) { + if (ke->key() < Qt::Key_Escape) { + return true; + } else { + switch (ke->key()) { + case Qt::Key_Return: + case Qt::Key_Enter: + case Qt::Key_Delete: + case Qt::Key_Home: + case Qt::Key_End: + case Qt::Key_Backspace: + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_Tab: + return true; + default: + break; + } + } + } else if (ke->matches(QKeySequence::Copy) + || ke->matches(QKeySequence::Paste) + || ke->matches(QKeySequence::Cut) + || ke->matches(QKeySequence::Redo) + || ke->matches(QKeySequence::Undo) + || ke->matches(QKeySequence::MoveToNextWord) + || ke->matches(QKeySequence::MoveToPreviousWord) + || ke->matches(QKeySequence::MoveToStartOfDocument) + || ke->matches(QKeySequence::MoveToEndOfDocument) + || ke->matches(QKeySequence::SelectNextWord) + || ke->matches(QKeySequence::SelectPreviousWord) + || ke->matches(QKeySequence::SelectStartOfLine) + || ke->matches(QKeySequence::SelectEndOfLine) + || ke->matches(QKeySequence::SelectStartOfBlock) + || ke->matches(QKeySequence::SelectEndOfBlock) + || ke->matches(QKeySequence::SelectStartOfDocument) + || ke->matches(QKeySequence::SelectEndOfDocument) + || ke->matches(QKeySequence::SelectAll) + ) { + return true; + } + return false; +#endif +} + +namespace QtWebEngineCore { + +bool RenderWidgetHostViewQtDelegateClient::handleShortcutOverrideEvent(QKeyEvent *event) +{ + if (inputMethodQuery(Qt::ImEnabled).toBool() && isCommonTextEditShortcut(event)) { + event->accept(); + return true; + } + return false; +} + +} // namespace QtWebEngineCore diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h index 6286596c6..dda59a01a 100644 --- a/src/core/render_widget_host_view_qt_delegate.h +++ b/src/core/render_widget_host_view_qt_delegate.h @@ -48,6 +48,7 @@ QT_BEGIN_NAMESPACE class QCursor; class QEvent; +class QKeyEvent; class QPainter; class QSGLayer; class QSGNode; @@ -85,6 +86,7 @@ public: virtual void windowChanged() = 0; virtual bool forwardEvent(QEvent *) = 0; virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) = 0; + virtual bool handleShortcutOverrideEvent(QKeyEvent *event); }; class QWEBENGINE_EXPORT RenderWidgetHostViewQtDelegate { diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp index b3348b43e..749a2e0d8 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp @@ -241,10 +241,12 @@ void RenderWidgetHostViewQtDelegateQuick::inputMethodStateChanged(bool editorVis bool RenderWidgetHostViewQtDelegateQuick::event(QEvent *event) { if (event->type() == QEvent::ShortcutOverride) { - if (editorActionForKeyEvent(static_cast<QKeyEvent*>(event)) != QQuickWebEngineView::NoWebAction) { - event->accept(); + QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); + if (m_client->handleShortcutOverrideEvent(keyEvent)) return true; - } + if (editorActionForKeyEvent(keyEvent) != QQuickWebEngineView::NoWebAction) + event->accept(); + return true; } if (event->type() == QEvent::NativeGesture) diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp index fd58a0708..c608ba2aa 100644 --- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp +++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp @@ -59,6 +59,15 @@ namespace QtWebEngineCore { +static bool handleShortcutOverrideEvent(RenderWidgetHostViewQtDelegateClient *client, QKeyEvent *ke) +{ + if (client->handleShortcutOverrideEvent(ke)) + return true; + if (editorActionForKeyEvent(ke) != QWebEnginePage::NoWebAction) + ke->accept(); + return true; +} + class RenderWidgetHostViewQuickItem : public QQuickItem { public: RenderWidgetHostViewQuickItem(RenderWidgetHostViewQtDelegateClient *client) : m_client(client) @@ -68,6 +77,14 @@ public: setFocus(true); } protected: + bool event(QEvent *event) override + { + if (event->type() == QEvent::ShortcutOverride) { + handleShortcutOverrideEvent(m_client, static_cast<QKeyEvent *>(event)); + return true; + } + return QQuickItem::event(event); + } void focusInEvent(QFocusEvent *event) override { m_client->forwardEvent(event); @@ -437,8 +454,8 @@ bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event) // We forward focus events later, once they have made it to the m_rootItem. return QQuickWidget::event(event); case QEvent::ShortcutOverride: - if (editorActionForKeyEvent(static_cast<QKeyEvent*>(event)) != QWebEnginePage::NoWebAction) { - event->accept(); + if (event->type() == QEvent::ShortcutOverride) { + handleShortcutOverrideEvent(m_client, static_cast<QKeyEvent *>(event)); return true; } break; |