diff options
author | Andras Becsi <andras.becsi@digia.com> | 2013-10-24 18:06:14 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-25 20:50:57 +0200 |
commit | 44383cc1e34b6fae069af35579c5267221d90ad4 (patch) | |
tree | 547779842f7e83e3412873f3e04c125c3b6c4335 /lib | |
parent | 01d4d6964665957ba1440f763545f6fbde73c2e5 (diff) |
Implement inputMethodQuery
This makes it possible on touch devices to use a simple
virtual keyboard input method that synthesizes key events.
This is the minimal requirement to make the the boot2Qt
Keyboard component functional.
For more advanced input methods and the widget tests we will
need to override inputMethodEvent as well.
Change-Id: If9228ee6b1730d72e7424bdb33a9a9c46654507f
Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/quick/render_widget_host_view_qt_delegate_quick.h | 17 | ||||
-rw-r--r-- | lib/render_widget_host_view_qt.cpp | 91 | ||||
-rw-r--r-- | lib/render_widget_host_view_qt.h | 9 | ||||
-rw-r--r-- | lib/render_widget_host_view_qt_delegate.cpp | 10 | ||||
-rw-r--r-- | lib/render_widget_host_view_qt_delegate.h | 3 | ||||
-rw-r--r-- | lib/widgets/render_widget_host_view_qt_delegate_widget.cpp | 16 | ||||
-rw-r--r-- | lib/widgets/render_widget_host_view_qt_delegate_widget.h | 2 |
7 files changed, 144 insertions, 4 deletions
diff --git a/lib/quick/render_widget_host_view_qt_delegate_quick.h b/lib/quick/render_widget_host_view_qt_delegate_quick.h index ce4d87c3d..f60395802 100644 --- a/lib/quick/render_widget_host_view_qt_delegate_quick.h +++ b/lib/quick/render_widget_host_view_qt_delegate_quick.h @@ -46,8 +46,10 @@ #include "qquickwebengineview_p.h" #include "qquickwebengineview_p_p.h" +#include <QGuiApplication> #include <QQuickPaintedItem> #include <QQuickWindow> +#include <QVariant> #include <QWindow> template<typename ItemBaseT> @@ -169,6 +171,21 @@ public: forwardEvent(event); } + void inputMethodStateChanged(bool editorVisible) + { + if (qApp->inputMethod()->isVisible() == editorVisible) + return; + + this->setFlag(QQuickItem::ItemAcceptsInputMethod, editorVisible); + qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints); + qApp->inputMethod()->setVisible(editorVisible); + } + + QVariant inputMethodQuery(Qt::InputMethodQuery query) const + { + return forwardInputMethodQuery(query); + } + protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { diff --git a/lib/render_widget_host_view_qt.cpp b/lib/render_widget_host_view_qt.cpp index d9f1a48df..5cf7ed232 100644 --- a/lib/render_widget_host_view_qt.cpp +++ b/lib/render_widget_host_view_qt.cpp @@ -51,6 +51,8 @@ #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/ui_events_helper.h" #include "content/common/gpu/gpu_messages.h" +#include "content/common/view_messages.h" +#include "lib/type_conversion.h" #include "third_party/WebKit/public/web/WebCursorInfo.h" #include "ui/base/events/event.h" #include "ui/gfx/size_conversions.h" @@ -63,6 +65,7 @@ #include <QMouseEvent> #include <QScreen> #include <QStyleHints> +#include <QVariant> #include <QWheelEvent> #include <QWindow> @@ -83,6 +86,41 @@ static inline ui::EventType toUIEventType(Qt::TouchPointState state) } } +static inline Qt::InputMethodHints toQtInputMethodHints(ui::TextInputType inputType) +{ + switch (inputType) { + case ui::TEXT_INPUT_TYPE_TEXT: + return Qt::ImhPreferLowercase; + case ui::TEXT_INPUT_TYPE_SEARCH: + return Qt::ImhPreferLowercase | Qt::ImhNoAutoUppercase; + case ui::TEXT_INPUT_TYPE_PASSWORD: + return Qt::ImhSensitiveData | Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase; + case ui::TEXT_INPUT_TYPE_EMAIL: + return Qt::ImhEmailCharactersOnly; + case ui::TEXT_INPUT_TYPE_NUMBER: + return Qt::ImhFormattedNumbersOnly; + case ui::TEXT_INPUT_TYPE_TELEPHONE: + return Qt::ImhDialableCharactersOnly; + case ui::TEXT_INPUT_TYPE_URL: + return Qt::ImhUrlCharactersOnly | Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase; + case ui::TEXT_INPUT_TYPE_DATE_TIME: + case ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL: + case ui::TEXT_INPUT_TYPE_DATE_TIME_FIELD: + return Qt::ImhDate | Qt::ImhTime; + case ui::TEXT_INPUT_TYPE_DATE: + case ui::TEXT_INPUT_TYPE_MONTH: + case ui::TEXT_INPUT_TYPE_WEEK: + return Qt::ImhDate; + case ui::TEXT_INPUT_TYPE_TIME: + return Qt::ImhTime; + case ui::TEXT_INPUT_TYPE_TEXT_AREA: + case ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE: + return Qt::ImhMultiLine | Qt::ImhPreferLowercase; + default: + return Qt::ImhNone; + } +} + static inline gfx::Point toGfxPoint(const QPoint& point) { return gfx::Point(point.x(), point.y()); @@ -102,6 +140,8 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget : m_host(content::RenderWidgetHostImpl::From(widget)) , m_gestureRecognizer(ui::GestureRecognizer::Create(this)) , m_adapterClient(0) + , m_anchorPositionWithinSelection(0) + , m_cursorPositionWithinSelection(0) , m_initPending(false) { m_host->SetView(this); @@ -131,6 +171,7 @@ bool RenderWidgetHostViewQt::handleEvent(QEvent* event) { switch(event->type()) { case QEvent::MouseButtonDblClick: case QEvent::MouseButtonPress: + Focus(); // Fall through. case QEvent::MouseButtonRelease: case QEvent::MouseMove: handleMouseEvent(static_cast<QMouseEvent*>(event)); @@ -143,6 +184,7 @@ bool RenderWidgetHostViewQt::handleEvent(QEvent* event) { handleWheelEvent(static_cast<QWheelEvent*>(event)); break; case QEvent::TouchBegin: + Focus(); // Fall through. case QEvent::TouchUpdate: case QEvent::TouchEnd: handleTouchEvent(static_cast<QTouchEvent*>(event)); @@ -261,7 +303,9 @@ gfx::NativeViewAccessible RenderWidgetHostViewQt::GetNativeViewAccessible() // Set focus to the associated View component. void RenderWidgetHostViewQt::Focus() { + m_host->SetInputMethodActive(true); m_delegate->setKeyboardFocus(); + m_host->Focus(); } bool RenderWidgetHostViewQt::HasFocus() const @@ -352,6 +396,7 @@ void RenderWidgetHostViewQt::MovePluginWindows(const gfx::Vector2d&, const std:: void RenderWidgetHostViewQt::Blur() { + m_host->SetInputMethodActive(false); m_host->Blur(); } @@ -457,9 +502,10 @@ void RenderWidgetHostViewQt::SetIsLoading(bool) // We use WebContentsDelegateQt::LoadingStateChanged to notify about loading state. } -void RenderWidgetHostViewQt::TextInputTypeChanged(ui::TextInputType, bool, ui::TextInputMode) +void RenderWidgetHostViewQt::TextInputTypeChanged(ui::TextInputType type, bool, ui::TextInputMode) { - QT_NOT_YET_IMPLEMENTED + m_currentInputType = type; + m_delegate->inputMethodStateChanged(static_cast<bool>(type)); } void RenderWidgetHostViewQt::ImeCancelComposition() @@ -503,9 +549,20 @@ void RenderWidgetHostViewQt::SetTooltipText(const string16&) // QT_NOT_YET_IMPLEMENTED } -void RenderWidgetHostViewQt::SelectionBoundsChanged(const ViewHostMsg_SelectionBounds_Params&) +void RenderWidgetHostViewQt::SelectionBoundsChanged(const ViewHostMsg_SelectionBounds_Params ¶ms) { - QT_NOT_YET_IMPLEMENTED + if (selection_range_.IsValid()) { + if (params.is_anchor_first) { + m_anchorPositionWithinSelection = selection_range_.GetMin() - selection_text_offset_; + m_cursorPositionWithinSelection = selection_range_.GetMax() - selection_text_offset_; + } else { + m_anchorPositionWithinSelection = selection_range_.GetMax() - selection_text_offset_; + m_cursorPositionWithinSelection = selection_range_.GetMin() - selection_text_offset_; + } + } + + gfx::Rect caretRect = gfx::UnionRects(params.anchor_rect, params.focus_rect); + m_cursorRect = QRect(caretRect.x(), caretRect.y(), caretRect.width(), caretRect.height()); } void RenderWidgetHostViewQt::ScrollOffsetChanged() @@ -697,6 +754,32 @@ bool RenderWidgetHostViewQt::IsPopup() const return popup_type_ != WebKit::WebPopupTypeNone; } +QVariant RenderWidgetHostViewQt::inputMethodQuery(Qt::InputMethodQuery query) const +{ + switch (query) { + case Qt::ImEnabled: + return QVariant(m_currentInputType != ui::TEXT_INPUT_TYPE_NONE); + case Qt::ImCursorRectangle: + return m_cursorRect; + case Qt::ImFont: + return QVariant(); + case Qt::ImCursorPosition: + return static_cast<uint>(m_cursorPositionWithinSelection); + case Qt::ImAnchorPosition: + return static_cast<uint>(m_anchorPositionWithinSelection); + case Qt::ImSurroundingText: + return toQt(selection_text_); + case Qt::ImCurrentSelection: + return toQt(GetSelectedText()); + case Qt::ImMaximumTextLength: + return QVariant(); // No limit. + case Qt::ImHints: + return int(toQtInputMethodHints(m_currentInputType)); + default: + return QVariant(); + } +} + void RenderWidgetHostViewQt::handleMouseEvent(QMouseEvent* event) { int eventType = event->type(); diff --git a/lib/render_widget_host_view_qt.h b/lib/render_widget_host_view_qt.h index 337351b69..12f7d3184 100644 --- a/lib/render_widget_host_view_qt.h +++ b/lib/render_widget_host_view_qt.h @@ -51,6 +51,7 @@ #include "ui/base/gestures/gesture_types.h" #include <QMap> #include <QPoint> +#include <QRect> #include <QtGlobal> class BackingStoreQt; @@ -62,6 +63,7 @@ class QHoverEvent; class QKeyEvent; class QMouseEvent; class QTouchEvent; +class QVariant; class QWheelEvent; QT_END_NAMESPACE @@ -171,6 +173,8 @@ public: void handleHoverEvent(QHoverEvent*); void handleFocusEvent(QFocusEvent*); + QVariant inputMethodQuery(Qt::InputMethodQuery query) const; + #if defined(OS_MACOSX) virtual void SetTakesFocusOnlyOnMouseDown(bool flag) { QT_NOT_YET_IMPLEMENTED } virtual void SetActive(bool active) { QT_NOT_YET_IMPLEMENTED } @@ -206,6 +210,11 @@ private: WebContentsAdapterClient *m_adapterClient; MultipleMouseClickHelper m_clickHelper; + ui::TextInputType m_currentInputType; + QRect m_cursorRect; + size_t m_anchorPositionWithinSelection; + size_t m_cursorPositionWithinSelection; + bool m_initPending; }; diff --git a/lib/render_widget_host_view_qt_delegate.cpp b/lib/render_widget_host_view_qt_delegate.cpp index 3ec9d450a..0c8a5f7ae 100644 --- a/lib/render_widget_host_view_qt_delegate.cpp +++ b/lib/render_widget_host_view_qt_delegate.cpp @@ -47,6 +47,8 @@ #include "content/browser/renderer_host/render_view_host_impl.h" +#include <QVariant> + #if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)) #include "cc/quads/draw_quad.h" #include "cc/quads/render_pass_draw_quad.h" @@ -417,3 +419,11 @@ void RenderWidgetHostViewQtDelegate::setView(RenderWidgetHostViewQt* view) { m_view = view; } + +QVariant RenderWidgetHostViewQtDelegate::forwardInputMethodQuery(Qt::InputMethodQuery query) const +{ + if (!m_view) + return QVariant(); + + return m_view->inputMethodQuery(query); +} diff --git a/lib/render_widget_host_view_qt_delegate.h b/lib/render_widget_host_view_qt_delegate.h index f84d1a085..e80d6fbb5 100644 --- a/lib/render_widget_host_view_qt_delegate.h +++ b/lib/render_widget_host_view_qt_delegate.h @@ -65,6 +65,7 @@ class QEvent; class QPainter; class QQuickWindow; class QSGNode; +class QVariant; class QWindow; QT_END_NAMESPACE @@ -87,6 +88,7 @@ public: virtual void update(const QRect& rect = QRect()) = 0; virtual void updateCursor(const QCursor &) = 0; virtual void resize(int width, int height) = 0; + virtual void inputMethodStateChanged(bool editorVisible) = 0; protected: RenderWidgetHostViewQtDelegate(); @@ -97,6 +99,7 @@ protected: void fetchBackingStore(); void notifyResize(); bool forwardEvent(QEvent*); + QVariant forwardInputMethodQuery(Qt::InputMethodQuery query) const; private: void setView(RenderWidgetHostViewQt*); diff --git a/lib/widgets/render_widget_host_view_qt_delegate_widget.cpp b/lib/widgets/render_widget_host_view_qt_delegate_widget.cpp index 5d0a7960b..d8abd18ff 100644 --- a/lib/widgets/render_widget_host_view_qt_delegate_widget.cpp +++ b/lib/widgets/render_widget_host_view_qt_delegate_widget.cpp @@ -49,6 +49,7 @@ #include <QPainter> #include <QPaintEvent> #include <QWindow> +#include <QtWidgets/QApplication> RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(WebContentsAdapterClient::CompositingMode mode, QWidget *parent) : QWidget(parent) @@ -139,6 +140,21 @@ void RenderWidgetHostViewQtDelegateWidget::resize(int width, int height) QWidget::resize(width, height); } +void RenderWidgetHostViewQtDelegateWidget::inputMethodStateChanged(bool editorVisible) +{ + if (qApp->inputMethod()->isVisible() == editorVisible) + return; + + QWidget::setAttribute(Qt::WA_InputMethodEnabled, editorVisible); + qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints); + qApp->inputMethod()->setVisible(editorVisible); +} + +QVariant RenderWidgetHostViewQtDelegateWidget::inputMethodQuery(Qt::InputMethodQuery query) const +{ + return forwardInputMethodQuery(query); +} + void RenderWidgetHostViewQtDelegateWidget::paintEvent(QPaintEvent * event) { QPainter painter(this); diff --git a/lib/widgets/render_widget_host_view_qt_delegate_widget.h b/lib/widgets/render_widget_host_view_qt_delegate_widget.h index 264f8f4af..29e697d1b 100644 --- a/lib/widgets/render_widget_host_view_qt_delegate_widget.h +++ b/lib/widgets/render_widget_host_view_qt_delegate_widget.h @@ -70,12 +70,14 @@ public: virtual void update(const QRect& rect = QRect()); virtual void updateCursor(const QCursor &); virtual void resize(int width, int height); + virtual void inputMethodStateChanged(bool editorVisible); protected: void paintEvent(QPaintEvent * event); bool event(QEvent *event); void resizeEvent(QResizeEvent *resizeEvent); + QVariant inputMethodQuery(Qt::InputMethodQuery query) const; }; #endif |