summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAndras Becsi <andras.becsi@digia.com>2013-10-24 18:06:14 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-25 20:50:57 +0200
commit44383cc1e34b6fae069af35579c5267221d90ad4 (patch)
tree547779842f7e83e3412873f3e04c125c3b6c4335 /lib
parent01d4d6964665957ba1440f763545f6fbde73c2e5 (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.h17
-rw-r--r--lib/render_widget_host_view_qt.cpp91
-rw-r--r--lib/render_widget_host_view_qt.h9
-rw-r--r--lib/render_widget_host_view_qt_delegate.cpp10
-rw-r--r--lib/render_widget_host_view_qt_delegate.h3
-rw-r--r--lib/widgets/render_widget_host_view_qt_delegate_widget.cpp16
-rw-r--r--lib/widgets/render_widget_host_view_qt_delegate_widget.h2
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 &params)
{
- 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