From a30d4162ddb30b62b8d003b099d3ca8ae0b0ed0b Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 5 Sep 2011 12:53:33 +0200 Subject: [PATCH] Refactor the input framework Results of the ongoing workshop in Oslo: QInputPanel will be the application facing interface for controlling the input context as well as querying things like the position of the virtual keyboard. QInputContext is significantly cleaned up and only there as a compatibility API for existing code. Change-Id: Ie8e2ee480930763f414bfaae63247b1fb6500c82 Reviewed-on: http://codereview.qt.nokia.com/4357 Reviewed-by: Qt Sanity Bot Reviewed-by: Vesa Rantanen Reviewed-by: Joona Petrell Reviewed-by: Lars Knoll --- src/corelib/global/qnamespace.h | 38 ++-- src/gui/kernel/kernel.pri | 3 + src/gui/kernel/qguiapplication.cpp | 24 ++- src/gui/kernel/qguiapplication.h | 3 + src/gui/kernel/qguiapplication_p.h | 1 + src/gui/kernel/qinputpanel.cpp | 172 ++++++++++++++++++ src/gui/kernel/qinputpanel.h | 121 ++++++++++++ src/gui/kernel/qinputpanel_p.h | 68 +++++++ src/gui/kernel/qplatforminputcontext_qpa.cpp | 28 ++- src/gui/kernel/qplatforminputcontext_qpa.h | 17 +- .../ibus/qibusplatforminputcontext.cpp | 33 ++-- .../ibus/qibusplatforminputcontext.h | 6 +- src/widgets/kernel/qapplication.cpp | 22 +-- src/widgets/kernel/qinputcontext.cpp | 135 +------------- src/widgets/kernel/qinputcontext.h | 8 - 15 files changed, 480 insertions(+), 199 deletions(-) create mode 100644 src/gui/kernel/qinputpanel.cpp create mode 100644 src/gui/kernel/qinputpanel.h create mode 100644 src/gui/kernel/qinputpanel_p.h diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 2fc82c55ca..740579b11d 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1234,24 +1234,36 @@ public: }; enum InputMethodQuery { - ImMicroFocus, - ImFont, - ImCursorPosition, - ImSurroundingText, - ImCurrentSelection, - ImMaximumTextLength, - ImAnchorPosition, - ImHints + ImEnabled = 0x1, + ImMicroFocus = 0x2, + ImFont = 0x4, + ImCursorPosition = 0x8, + ImSurroundingText = 0x10, + ImCurrentSelection = 0x20, + ImMaximumTextLength = 0x40, + ImAnchorPosition = 0x80, + ImHints = 0x100, + ImPreferredLanguage = 0x200, + + ImPlatformData = 0x80000000, + ImQueryAll = 0xffffffff }; + Q_DECLARE_FLAGS(InputMethodQueries, InputMethodQuery) enum InputMethodHint { ImhNone = 0x0, + ImhHiddenText = 0x1, - ImhNoAutoUppercase = 0x2, - ImhPreferNumbers = 0x4, - ImhPreferUppercase = 0x8, - ImhPreferLowercase = 0x10, - ImhNoPredictiveText = 0x20, + ImhSensitiveData = 0x2, + ImhNoAutoUppercase = 0x4, + ImhPreferNumbers = 0x8, + ImhPreferUppercase = 0x10, + ImhPreferLowercase = 0x20, + ImhNoPredictiveText = 0x40, + + ImhDate = 0x80, + ImhTime = 0x100, + ImhMultiLine = 0x200, ImhDigitsOnly = 0x10000, ImhFormattedNumbersOnly = 0x20000, diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 2167510c4d..5195b2e3f5 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -13,6 +13,8 @@ HEADERS += \ kernel/qdnd_p.h \ kernel/qevent.h \ kernel/qevent_p.h \ + kernel/qinputpanel.h \ + kernel/qinputpanel_p.h \ kernel/qkeysequence.h \ kernel/qkeysequence_p.h \ kernel/qkeymapper_p.h \ @@ -29,6 +31,7 @@ SOURCES += \ kernel/qdrag.cpp \ kernel/qdnd.cpp \ kernel/qevent.cpp \ + kernel/qinputpanel.cpp \ kernel/qkeysequence.cpp \ kernel/qkeymapper.cpp \ kernel/qkeymapper_qpa.cpp \ diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 6cddf3ab73..e9edeb9247 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -60,6 +60,7 @@ #include #include #include +#include #include #include "private/qwindowsysteminterface_qpa_p.h" @@ -174,7 +175,8 @@ QGuiApplication::~QGuiApplication() QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv, int flags) : QCoreApplicationPrivate(argc, argv, flags), - styleHints(0) + styleHints(0), + inputPanel(0) { self = this; } @@ -403,6 +405,7 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate() cleanupThreadData(); delete styleHints; + delete inputPanel; delete platform_integration; platform_integration = 0; @@ -1186,6 +1189,25 @@ QStyleHints *QGuiApplication::styleHints() const } +/*! + \since 5.0 + + returns the input panel. + + The input panel returns properties about the state and position of + the virtual keyboard. It also provides information about the position of the + current focused input element. + + \sa QInputPanel + */ +QInputPanel *QGuiApplication::inputPanel() const +{ + Q_D(const QGuiApplication); + if (!d->inputPanel) + const_cast(d)->inputPanel = new QInputPanel(); + return d->inputPanel; +} + // Returns the current platform used by keyBindings uint QGuiApplicationPrivate::currentKeyPlatform() diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h index c402b9b9dc..0649b5de31 100644 --- a/src/gui/kernel/qguiapplication.h +++ b/src/gui/kernel/qguiapplication.h @@ -59,6 +59,7 @@ class QPlatformNativeInterface; class QPalette; class QScreen; class QStyleHints; +class QInputPanel; #if defined(qApp) #undef qApp @@ -113,10 +114,12 @@ public: static inline bool isRightToLeft() { return layoutDirection() == Qt::RightToLeft; } static inline bool isLeftToRight() { return layoutDirection() == Qt::LeftToRight; } + // ### move to QInputPanel static QLocale keyboardInputLocale(); static Qt::LayoutDirection keyboardInputDirection(); QStyleHints *styleHints() const; + QInputPanel *inputPanel() const; static QPlatformNativeInterface *platformNativeInterface(); diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index bdf79d4394..9f64911399 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -173,6 +173,7 @@ public: static QFont *app_font; QStyleHints *styleHints; + QInputPanel *inputPanel; static bool quitOnLastWindowClosed; diff --git a/src/gui/kernel/qinputpanel.cpp b/src/gui/kernel/qinputpanel.cpp new file mode 100644 index 0000000000..36104f3816 --- /dev/null +++ b/src/gui/kernel/qinputpanel.cpp @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +QInputPanel::QInputPanel() + : QObject(*new QInputPanelPrivate) +{ +} + +QInputPanel::~QInputPanel() +{ +} + + +QObject *QInputPanel::inputItem() const +{ + Q_D(const QInputPanel); + return d->inputItem.data(); +} + +void QInputPanel::setInputItem(QObject *inputItem) +{ + Q_D(QInputPanel); + + if (d->inputItem.data() == inputItem) + return; + + d->inputItem = inputItem; + emit inputItemChanged(); +} + +QWindow *QInputPanel::inputWindow() const +{ + return qApp->activeWindow(); +} + +QTransform QInputPanel::inputItemTransform() const +{ + Q_D(const QInputPanel); + return d->inputItemTransform; +} + +void QInputPanel::setInputItemTranform(const QTransform &transform) +{ + Q_D(QInputPanel); + d->inputItemTransform = transform; + emit cursorRectChanged(); +} + +QRectF QInputPanel::cursorRect() const +{ + QInputMethodQueryEvent query(Qt::ImMicroFocus); + QGuiApplication::sendEvent(inputItem(), &query); + QRect r = query.value().toRect(); + if (!r.isValid()) + return QRect(); + + Q_D(const QInputPanel); + return d->inputItemTransform.mapRect(r); +} + +QRectF QInputPanel::keyboardRect() +{ + QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext(); + if (ic) + return ic->keyboardRect(); + return QRectF(); +} + +void QInputPanel::open() +{ + setOpen(true); +} + +void QInputPanel::close() +{ + setOpen(false); +} + +bool QInputPanel::isOpen() const +{ + Q_D(const QInputPanel); + + return d->open; +} + +void QInputPanel::setOpen(bool open) +{ + Q_D(QInputPanel); + if (d->open == open) + return; + + d->open = open; + emit openChanged(); +} + +bool QInputPanel::isAnimating() const +{ + QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext(); + if (ic) + return ic->isAnimating(); + return false; +} + + +void QInputPanel::update(Qt::InputMethodQueries queries) +{ + QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext(); + if (ic) + ic->update(queries); + + if (queries & Qt::ImMicroFocus) + emit cursorRectChanged(); +} + +void QInputPanel::reset() +{ + QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext(); + if (ic) + ic->reset(); +} + +void QInputPanel::invokeAction(Action a, int cursorPosition) +{ + QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext(); + if (ic) + ic->invokeAction(a, cursorPosition); +} + +#include "moc_qinputpanel.cpp" diff --git a/src/gui/kernel/qinputpanel.h b/src/gui/kernel/qinputpanel.h new file mode 100644 index 0000000000..2348fbd62f --- /dev/null +++ b/src/gui/kernel/qinputpanel.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QINPUTPANEL_H +#define QINPUTPANEL_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QInputPanelPrivate; +class QWindow; +class QRectF; + +class Q_GUI_EXPORT QInputPanel : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QInputPanel) + Q_PROPERTY(QObject *inputItem READ inputItem WRITE setInputItem NOTIFY inputItemChanged) + Q_PROPERTY(QRectF cursorRect READ cursorRect NOTIFY cursorRectChanged) + Q_PROPERTY(QRectF keyboardRect READ keyboardRect NOTIFY keyboardRectChanged) + Q_PROPERTY(bool open READ isOpen WRITE setOpen NOTIFY openChanged) + Q_PROPERTY(bool animating READ isAnimating NOTIFY animatingChanged) + +public: + QObject *inputItem() const; + void setInputItem(QObject *inputItemChanged); + + // the window containing the editor + QWindow *inputWindow() const; + + QTransform inputItemTransform() const; + void setInputItemTranform(const QTransform &transform); + + // in window coordinates + QRectF cursorRect() const; // ### what if we have rotations for the item? + + // keyboard geometry in window coords + QRectF keyboardRect(); + + enum Action { + Click, + ContextMenu + }; + + bool isOpen() const; + void setOpen(bool open); + + bool isAnimating() const; + +public Q_SLOTS: + void open(); + void close(); + + void update(Qt::InputMethodQueries queries); + void reset(); + + void invokeAction(Action a, int cursorPosition); + +Q_SIGNALS: + void inputItemChanged(); + void cursorRectChanged(); + void keyboardRectChanged(); + void openChanged(); + void animatingChanged(); + +private: + friend class QGuiApplication; + friend class QGuiApplicationPrivate; + friend class QPlatformInputContext; + QInputPanel(); + ~QInputPanel(); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/gui/kernel/qinputpanel_p.h b/src/gui/kernel/qinputpanel_p.h new file mode 100644 index 0000000000..567459c79e --- /dev/null +++ b/src/gui/kernel/qinputpanel_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QINPUTPANEL_P_H +#define QINPUTPANEL_P_H + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QInputPanelPrivate : public QObjectPrivate +{ +public: + inline QInputPanelPrivate() + : open(false) + {} + QTransform inputItemTransform; + QWeakPointer inputItem; + bool open; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/gui/kernel/qplatforminputcontext_qpa.cpp b/src/gui/kernel/qplatforminputcontext_qpa.cpp index 4ef25ddbe5..8c08c13180 100644 --- a/src/gui/kernel/qplatforminputcontext_qpa.cpp +++ b/src/gui/kernel/qplatforminputcontext_qpa.cpp @@ -40,8 +40,7 @@ ****************************************************************************/ #include - -#include +#include QT_BEGIN_NAMESPACE @@ -57,26 +56,37 @@ void QPlatformInputContext::reset() { } -void QPlatformInputContext::update() +void QPlatformInputContext::update(Qt::InputMethodQueries) { } -void QPlatformInputContext::mouseHandler(int, QMouseEvent *event) +void QPlatformInputContext::invokeAction(QInputPanel::Action action, int cursorPosition) { // Default behavior for simple ephemeral input contexts. Some // complex input contexts should not be reset here. - if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) + if (action == QInputPanel::Click) reset(); } -QObject *QPlatformInputContext::focusObject() const +QRectF QPlatformInputContext::keyboardRect() const { - return m_focusObject.data(); + return QRectF(); } -void QPlatformInputContext::setFocusObject(QObject *object) +void QPlatformInputContext::emitKeyboardRectChanged() const { - m_focusObject = object; + emit qApp->inputPanel()->keyboardRectChanged(); } +bool QPlatformInputContext::isAnimating() +{ + return false; +} + +void QPlatformInputContext::emitAnimatingChanged() +{ + emit qApp->inputPanel()->animatingChanged(); +} + + QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatforminputcontext_qpa.h b/src/gui/kernel/qplatforminputcontext_qpa.h index 57694fe9d9..3bdce73019 100644 --- a/src/gui/kernel/qplatforminputcontext_qpa.h +++ b/src/gui/kernel/qplatforminputcontext_qpa.h @@ -42,7 +42,7 @@ #ifndef QPLATFORMINPUTCONTEXT_H #define QPLATFORMINPUTCONTEXT_H -#include +#include QT_BEGIN_HEADER @@ -60,17 +60,14 @@ public: virtual ~QPlatformInputContext(); virtual void reset(); - virtual void update(); + virtual void update(Qt::InputMethodQueries); + virtual void invokeAction(QInputPanel::Action, int cursorPosition); - virtual void mouseHandler(int x, QMouseEvent *event); + virtual QRectF keyboardRect() const; + void emitKeyboardRectChanged() const; - QObject *focusObject() const; - virtual void setFocusObject(QObject *object); - -// virtual QList actions(); -private: - QWeakPointer m_focusObject; - QWeakPointer m_focusWindow; + virtual bool isAnimating(); + void emitAnimatingChanged(); }; QT_END_NAMESPACE diff --git a/src/platformsupport/inputmethods/ibus/qibusplatforminputcontext.cpp b/src/platformsupport/inputmethods/ibus/qibusplatforminputcontext.cpp index 34838ff490..fba9116ca8 100644 --- a/src/platformsupport/inputmethods/ibus/qibusplatforminputcontext.cpp +++ b/src/platformsupport/inputmethods/ibus/qibusplatforminputcontext.cpp @@ -84,6 +84,8 @@ QIBusPlatformInputContext::QIBusPlatformInputContext () connect(d->context, SIGNAL(CommitText(QDBusVariant)), SLOT(commitText(QDBusVariant))); connect(d->context, SIGNAL(UpdatePreeditText(QDBusVariant,uint,bool)), this, SLOT(updatePreeditText(QDBusVariant,uint,bool))); } + QInputPanel *p = qApp->inputPanel(); + connect(p, SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged())); } QIBusPlatformInputContext::~QIBusPlatformInputContext (void) @@ -96,9 +98,9 @@ bool QIBusPlatformInputContext::isValid() const return d->valid; } -void QIBusPlatformInputContext::mouseHandler (int x, QMouseEvent *event) +void QIBusPlatformInputContext::invokeAction(QInputPanel::Action a, int x) { - QPlatformInputContext::mouseHandler (x, event); + QPlatformInputContext::invokeAction(a, x); if (!d->valid) return; @@ -114,14 +116,14 @@ void QIBusPlatformInputContext::reset() d->context->Reset(); } -void QIBusPlatformInputContext::update() +void QIBusPlatformInputContext::update(Qt::InputMethodQueries q) { - QPlatformInputContext::update(); + QPlatformInputContext::update(q); if (!d->valid) return; - QObject *o = focusObject(); + QObject *o = qApp->inputPanel()->inputItem(); if (!o) return; @@ -135,16 +137,15 @@ void QIBusPlatformInputContext::update() } } -void QIBusPlatformInputContext::setFocusObject(QObject *object) +void QIBusPlatformInputContext::inputItemChanged() { - QPlatformInputContext::setFocusObject(object); - if (!d->valid) return; + QObject *input = qApp->inputPanel()->inputItem(); if (debug) - qDebug() << "setFocusObject" << object; - if (object) + qDebug() << "setFocusObject" << input; + if (input) d->context->FocusIn(); else d->context->FocusOut(); @@ -153,6 +154,10 @@ void QIBusPlatformInputContext::setFocusObject(QObject *object) void QIBusPlatformInputContext::commitText(const QDBusVariant &text) { + QObject *input = qApp->inputPanel()->inputItem(); + if (!input) + return; + const QDBusArgument arg = text.variant().value(); QIBusText t; @@ -164,11 +169,15 @@ void QIBusPlatformInputContext::commitText(const QDBusVariant &text) QInputMethodEvent event; event.setCommitString(t.text); - QCoreApplication::sendEvent(focusObject(), &event); + QCoreApplication::sendEvent(input, &event); } void QIBusPlatformInputContext::updatePreeditText(const QDBusVariant &text, uint cursorPos, bool visible) { + QObject *input = qApp->inputPanel()->inputItem(); + if (!input) + return; + const QDBusArgument arg = text.variant().value(); QIBusText t; @@ -180,7 +189,7 @@ void QIBusPlatformInputContext::updatePreeditText(const QDBusVariant &text, uint attributes += QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursorPos, visible ? 1 : 0, QVariant()); QInputMethodEvent event(t.text, attributes); - QCoreApplication::sendEvent(focusObject(), &event); + QCoreApplication::sendEvent(input, &event); } diff --git a/src/platformsupport/inputmethods/ibus/qibusplatforminputcontext.h b/src/platformsupport/inputmethods/ibus/qibusplatforminputcontext.h index 74f7da8d41..66c3aeecc6 100644 --- a/src/platformsupport/inputmethods/ibus/qibusplatforminputcontext.h +++ b/src/platformsupport/inputmethods/ibus/qibusplatforminputcontext.h @@ -55,16 +55,16 @@ public: bool isValid() const; - void mouseHandler(int x, QMouseEvent *event); + void invokeAction(QInputPanel::Action a, int x); void reset(void); - void update(void); - void setFocusObject(QObject *object); + void update(Qt::InputMethodQueries); bool x11FilterEvent(uint keyval, uint keycode, uint state, bool press); public Q_SLOTS: void commitText(const QDBusVariant &text); void updatePreeditText(const QDBusVariant &text, uint cursor_pos, bool visible); + void inputItemChanged(); private: QIBusPlatformInputContextPrivate *d; diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 043b114c64..c9ef2e79d8 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -69,7 +69,7 @@ #include "qmessagebox.h" #include #include - +#include #include "qinputcontext.h" #include "private/qkeymapper_p.h" @@ -3754,13 +3754,6 @@ bool QApplication::notify(QObject *receiver, QEvent *e) QPoint relpos = mouse->pos(); if (e->spontaneous()) { -#ifndef QT_NO_IM - QInputContext *ic = w->inputContext(); - if (ic - && w->testAttribute(Qt::WA_InputMethodEnabled) - && ic->filterEvent(mouse)) - return true; -#endif if (e->type() == QEvent::MouseButtonPress) { QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, @@ -4117,17 +4110,10 @@ bool QApplication::notify(QObject *receiver, QEvent *e) break; } case QEvent::RequestSoftwareInputPanel: + inputPanel()->open(); + break; case QEvent::CloseSoftwareInputPanel: -#ifndef QT_NO_IM - if (receiver->isWidgetType()) { - QWidget *w = static_cast(receiver); - QInputContext *ic = w->inputContext(); - if (ic && ic->filterEvent(e)) { - break; - } - } -#endif - res = d->notify_helper(receiver, e); + inputPanel()->close(); break; #ifndef QT_NO_GESTURES diff --git a/src/widgets/kernel/qinputcontext.cpp b/src/widgets/kernel/qinputcontext.cpp index a3e73eb288..05ed9369f6 100644 --- a/src/widgets/kernel/qinputcontext.cpp +++ b/src/widgets/kernel/qinputcontext.cpp @@ -62,12 +62,11 @@ #include "qplatformdefs.h" #include "qapplication.h" -#include "private/qguiapplication_p.h" -#include "qplatformintegration_qpa.h" -#include "qplatforminputcontext_qpa.h" #include "qmenu.h" #include "qtextformat.h" #include "qpalette.h" +#include +#include #include #include @@ -172,10 +171,7 @@ QInputContext::~QInputContext() */ QWidget *QInputContext::focusWidget() const { - QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext(); - if (ic) - return qobject_cast(ic->focusObject()); - return 0; + return qobject_cast(qApp->inputPanel()->inputItem()); } @@ -189,10 +185,7 @@ QWidget *QInputContext::focusWidget() const */ void QInputContext::setFocusWidget(QWidget *widget) { - Q_ASSERT(!widget || widget->testAttribute(Qt::WA_InputMethodEnabled)); - QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext(); - if (ic) - ic->setFocusObject(widget); + qApp->inputPanel()->setInputItem(widget); } /*! @@ -209,50 +202,6 @@ void QInputContext::setFocusWidget(QWidget *widget) \sa sendEvent() */ -/*! - This function can be reimplemented in a subclass to filter input - events. - - Return true if the \a event has been consumed. Otherwise, the - unfiltered \a event will be forwarded to widgets as ordinary - way. Although the input events have accept() and ignore() - methods, leave it untouched. - - \a event is currently restricted to events of these types: - - \list - \i CloseSoftwareInputPanel - \i KeyPress - \i KeyRelease - \i MouseButtonDblClick - \i MouseButtonPress - \i MouseButtonRelease - \i MouseMove - \i RequestSoftwareInputPanel - \endlist - - But some input method related events such as QWheelEvent or - QTabletEvent may be added in future. - - The filtering opportunity is always given to the input context as - soon as possible. It has to be taken place before any other key - event consumers such as eventfilters and accelerators because some - input methods require quite various key combination and - sequences. It often conflicts with accelerators and so on, so we - must give the input context the filtering opportunity first to - ensure all input methods work properly regardless of application - design. - - Ordinary input methods require discrete key events to work - properly, so Qt's key compression is always disabled for any input - contexts. - - \sa QKeyEvent, x11FilterEvent() -*/ -bool QInputContext::filterEvent(const QEvent * /*event*/) -{ - return false; -} /*! Sends an input method event specified by \a event to the current focus @@ -271,14 +220,8 @@ bool QInputContext::filterEvent(const QEvent * /*event*/) */ void QInputContext::sendEvent(const QInputMethodEvent &event) { - // route events over input context parents to make chaining possible. - QInputContext *p = qobject_cast(parent()); - if (p) { - p->sendEvent(event); - return; - } - QWidget *focus = focusWidget(); + QObject *focus = qApp->inputPanel()->inputItem(); if (!focus) return; @@ -306,9 +249,8 @@ void QInputContext::sendEvent(const QInputMethodEvent &event) */ void QInputContext::mouseHandler(int x, QMouseEvent *event) { - QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext(); - if (ic) - ic->mouseHandler(x, event); + if (event->type() == QEvent::MouseButtonRelease) + qApp->inputPanel()->invokeAction(QInputPanel::Click, x); } @@ -331,9 +273,7 @@ QFont QInputContext::font() const */ void QInputContext::update() { - QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext(); - if (ic) - ic->update(); + qApp->inputPanel()->update(Qt::ImQueryAll); } /*! @@ -343,8 +283,7 @@ void QInputContext::update() */ void QInputContext::widgetDestroyed(QWidget *widget) { - if (widget == focusWidget()) - setFocusWidget(0); + // nothing to be done here, as we use a weak pointer in the input panel } /*! @@ -369,9 +308,7 @@ void QInputContext::widgetDestroyed(QWidget *widget) */ void QInputContext::reset() { - QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext(); - if (ic) - ic->reset(); + qApp->inputPanel()->reset(); } @@ -464,58 +401,6 @@ QTextFormat QInputContext::standardFormat(StandardFormat s) const return fmt; } -#ifdef Q_WS_X11 -/*! - This function may be overridden only if input method is depending - on X11 and you need raw XEvent. Otherwise, this function must not. - - This function is designed to filter raw key events for XIM, but - other input methods may use this to implement some special - features such as distinguishing Shift_L and Shift_R. - - Return true if the \a event has been consumed. Otherwise, the - unfiltered \a event will be translated into QEvent and forwarded - to filterEvent(). Filtering at both x11FilterEvent() and - filterEvent() in single input method is allowed. - - \a keywidget is a client widget into which a text is inputted. \a - event is inputted XEvent. - - \sa filterEvent() -*/ -bool QInputContext::x11FilterEvent(QWidget * /*keywidget*/, XEvent * /*event*/) -{ - return false; -} -#endif // Q_WS_X11 - -#ifdef Q_OS_SYMBIAN -/*! - \since 4.6 - - This function may be overridden only if input method is depending - on Symbian and you need raw Symbian events. Otherwise, this function must not. - - This function is designed to filter raw key events on Symbian, but - other input methods may use this to implement some special - features. - - Return true if the \a event has been consumed. Otherwise, the - unfiltered \a event will be translated into QEvent and forwarded - to filterEvent(). Filtering at both symbianFilterEvent() and - filterEvent() in single input method is allowed. - - \a keywidget is a client widget into which a text is inputted. \a - event is inputted QSymbianEvent. - - \sa filterEvent() -*/ -bool QInputContext::symbianFilterEvent(QWidget * /*keywidget*/, const QSymbianEvent * /*event*/) -{ - return false; -} -#endif // Q_OS_SYMBIAN - QT_END_NAMESPACE #endif //Q_NO_IM diff --git a/src/widgets/kernel/qinputcontext.h b/src/widgets/kernel/qinputcontext.h index ac5f07549c..4864c5aea6 100644 --- a/src/widgets/kernel/qinputcontext.h +++ b/src/widgets/kernel/qinputcontext.h @@ -102,14 +102,6 @@ public: virtual QList actions(); -#if defined(Q_WS_X11) - virtual bool x11FilterEvent( QWidget *keywidget, XEvent *event ); -#endif // Q_WS_X11 -#if defined(Q_OS_SYMBIAN) - virtual bool symbianFilterEvent( QWidget *keywidget, const QSymbianEvent *event ); -#endif // Q_OS_SYMBIAN - virtual bool filterEvent( const QEvent *event ); - void sendEvent(const QInputMethodEvent &event); virtual bool isComposing() const { return false; }