summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPekka Vuorela <[email protected]>2012-02-23 15:57:14 +0200
committerQt by Nokia <[email protected]>2012-04-01 20:13:51 +0200
commit6a4bf73c07b034a0f9d07cb617d23e92ca778dd1 (patch)
tree818497855c1ad073919c214fa52ba3fd5b50d7d7 /src
parent1f5e058f79f95e869d8de300596137463492056c (diff)
Added some convenience API for platform input contexts
QPlatformInputContext now gets notified on changed focus and has inputMethodAccepted() telling whether current focus object accepts input method events. Also adapted IBus plugin to use this. Key event filtering for focused objects without input method support got fixed by the change. Change-Id: I6910aa6af2459d752a5763f0ae88fa8c34e5b165 Reviewed-by: Joona Petrell <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gui/kernel/kernel.pri1
-rw-r--r--src/gui/kernel/qguiapplication.cpp34
-rw-r--r--src/gui/kernel/qguiapplication.h2
-rw-r--r--src/gui/kernel/qguiapplication_p.h2
-rw-r--r--src/gui/kernel/qinputmethod.cpp17
-rw-r--r--src/gui/kernel/qinputmethod_p.h1
-rw-r--r--src/gui/kernel/qplatforminputcontext_qpa.cpp27
-rw-r--r--src/gui/kernel/qplatforminputcontext_qpa.h14
-rw-r--r--src/gui/kernel/qplatforminputcontext_qpa_p.h67
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp19
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h2
11 files changed, 164 insertions, 22 deletions
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 06773f58b57..b0fe871741a 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -15,6 +15,7 @@ HEADERS += \
kernel/qplatformscreen_qpa.h \
kernel/qplatformscreen_qpa_p.h \
kernel/qplatforminputcontext_qpa.h \
+ kernel/qplatforminputcontext_qpa_p.h \
kernel/qplatformintegrationfactory_qpa_p.h \
kernel/qplatformintegrationplugin_qpa.h \
kernel/qplatformtheme_qpa.h\
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index f5856918af1..0f5c218e52c 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -69,7 +69,8 @@
#include <QtGui/qstylehints.h>
#include <QtGui/qinputpanel.h>
#include <QtGui/qplatformtheme_qpa.h>
-
+#include <QtGui/qplatforminputcontext_qpa.h>
+#include <private/qplatforminputcontext_qpa_p.h>
#include <QWindowSystemInterface>
#include "private/qwindowsysteminterface_qpa_p.h"
@@ -1180,7 +1181,7 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate
QFocusEvent focusOut(QEvent::FocusOut);
QCoreApplication::sendSpontaneousEvent(previous, &focusOut);
QObject::disconnect(previous, SIGNAL(focusObjectChanged(QObject*)),
- qApp, SIGNAL(focusObjectChanged(QObject*)));
+ qApp, SLOT(q_updateFocusObject(QObject*)));
} else {
QEvent appActivate(QEvent::ApplicationActivate);
qApp->sendSpontaneousEvent(qApp, &appActivate);
@@ -1190,17 +1191,18 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate
QFocusEvent focusIn(QEvent::FocusIn);
QCoreApplication::sendSpontaneousEvent(QGuiApplicationPrivate::focus_window, &focusIn);
QObject::connect(QGuiApplicationPrivate::focus_window, SIGNAL(focusObjectChanged(QObject*)),
- qApp, SIGNAL(focusObjectChanged(QObject*)));
+ qApp, SLOT(q_updateFocusObject(QObject*)));
} else {
QEvent appActivate(QEvent::ApplicationDeactivate);
qApp->sendSpontaneousEvent(qApp, &appActivate);
}
- if (self)
+ if (self) {
self->notifyActiveWindowChange(previous);
- if (previousFocusObject != qApp->focusObject())
- emit qApp->focusObjectChanged(qApp->focusObject());
+ if (previousFocusObject != qApp->focusObject())
+ self->q_updateFocusObject(qApp->focusObject());
+ }
}
void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *wse)
@@ -2186,4 +2188,24 @@ const QDrawHelperGammaTables *QGuiApplicationPrivate::gammaTables()
return result;
}
+void QGuiApplicationPrivate::q_updateFocusObject(QObject *object)
+{
+ Q_Q(QGuiApplication);
+
+ bool enabled = false;
+ if (object) {
+ QInputMethodQueryEvent query(Qt::ImEnabled);
+ QGuiApplication::sendEvent(object, &query);
+ enabled = query.value(Qt::ImEnabled).toBool();
+ }
+
+ QPlatformInputContextPrivate::setInputMethodAccepted(enabled);
+ QPlatformInputContext *inputContext = platformIntegration()->inputContext();
+ if (inputContext)
+ inputContext->setFocusObject(object);
+ emit q->focusObjectChanged(object);
+}
+
+#include "moc_qguiapplication.cpp"
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h
index cc7dea422f0..b58720db133 100644
--- a/src/gui/kernel/qguiapplication.h
+++ b/src/gui/kernel/qguiapplication.h
@@ -155,6 +155,8 @@ private:
Q_DISABLE_COPY(QGuiApplication)
Q_DECLARE_PRIVATE(QGuiApplication)
+ Q_PRIVATE_SLOT(d_func(), void q_updateFocusObject(QObject *object))
+
#ifndef QT_NO_GESTURES
friend class QGestureManager;
#endif
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 4d8ef6fadd8..a686b4fd66d 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -145,6 +145,8 @@ public:
QPixmap getPixmapCursor(Qt::CursorShape cshape);
+ void q_updateFocusObject(QObject *object);
+
static QGuiApplicationPrivate *instance() { return self; }
static QString *platform_name;
diff --git a/src/gui/kernel/qinputmethod.cpp b/src/gui/kernel/qinputmethod.cpp
index b9ba7310d51..c443a47cacb 100644
--- a/src/gui/kernel/qinputmethod.cpp
+++ b/src/gui/kernel/qinputmethod.cpp
@@ -43,6 +43,7 @@
#include <private/qinputmethod_p.h>
#include <qguiapplication.h>
#include <qtimer.h>
+#include <private/qplatforminputcontext_qpa_p.h>
QT_BEGIN_NAMESPACE
@@ -295,8 +296,12 @@ void QInputMethod::update(Qt::InputMethodQueries queries)
{
Q_D(QInputMethod);
- if (queries & Qt::ImEnabled)
- d->q_checkFocusObject(qApp->focusObject());
+ if (queries & Qt::ImEnabled) {
+ QObject *focus = qApp->focusObject();
+ bool enabled = d->objectAcceptsInputMethod(focus);
+ setInputItem(enabled ? focus : 0);
+ QPlatformInputContextPrivate::setInputMethodAccepted(enabled);
+ }
QPlatformInputContext *ic = d->platformInputContext();
if (ic)
@@ -361,14 +366,20 @@ void QInputMethodPrivate::q_connectFocusObject()
void QInputMethodPrivate::q_checkFocusObject(QObject *object)
{
Q_Q(QInputMethod);
+ bool enabled = objectAcceptsInputMethod(object);
+ q->setInputItem(enabled ? object : 0);
+}
+bool QInputMethodPrivate::objectAcceptsInputMethod(QObject *object)
+{
bool enabled = false;
if (object) {
QInputMethodQueryEvent query(Qt::ImEnabled);
QGuiApplication::sendEvent(object, &query);
enabled = query.value(Qt::ImEnabled).toBool();
}
- q->setInputItem(enabled ? object : 0);
+
+ return enabled;
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qinputmethod_p.h b/src/gui/kernel/qinputmethod_p.h
index 8a17c859902..34a0430f10e 100644
--- a/src/gui/kernel/qinputmethod_p.h
+++ b/src/gui/kernel/qinputmethod_p.h
@@ -71,6 +71,7 @@ public:
}
void q_connectFocusObject();
void q_checkFocusObject(QObject *object);
+ bool objectAcceptsInputMethod(QObject *object);
QTransform inputItemTransform;
QWeakPointer<QObject> inputItem;
diff --git a/src/gui/kernel/qplatforminputcontext_qpa.cpp b/src/gui/kernel/qplatforminputcontext_qpa.cpp
index ee18f3ebd13..04610890dce 100644
--- a/src/gui/kernel/qplatforminputcontext_qpa.cpp
+++ b/src/gui/kernel/qplatforminputcontext_qpa.cpp
@@ -43,6 +43,7 @@
#include <qguiapplication.h>
#include <QRect>
#include "private/qkeymapper_p.h"
+#include "private/qplatforminputcontext_qpa_p.h"
QT_BEGIN_NAMESPACE
@@ -75,6 +76,7 @@ QT_BEGIN_NAMESPACE
\internal
*/
QPlatformInputContext::QPlatformInputContext()
+ : QObject(*(new QPlatformInputContextPrivate))
{
}
@@ -228,5 +230,30 @@ void QPlatformInputContext::emitInputDirectionChanged(Qt::LayoutDirection newDir
emit qApp->inputMethod()->inputDirectionChanged(newDirection);
}
+/*!
+ This virtual method gets called to notify updated focus to \a object.
+ \warning Input methods must not call this function directly.
+ */
+void QPlatformInputContext::setFocusObject(QObject *object)
+{
+ Q_UNUSED(object)
+}
+
+/*!
+ Returns true if current focus object supports input method events.
+ */
+bool QPlatformInputContext::inputMethodAccepted() const
+{
+ Q_D(const QPlatformInputContext);
+ return d->s_inputMethodAccepted;
+}
+
+bool QPlatformInputContextPrivate::s_inputMethodAccepted = false;
+
+void QPlatformInputContextPrivate::setInputMethodAccepted(bool accepted)
+{
+ s_inputMethodAccepted = accepted;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatforminputcontext_qpa.h b/src/gui/kernel/qplatforminputcontext_qpa.h
index c7d823d662c..5e8060c6e0c 100644
--- a/src/gui/kernel/qplatforminputcontext_qpa.h
+++ b/src/gui/kernel/qplatforminputcontext_qpa.h
@@ -48,13 +48,13 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-
-class QWindow;
-class QMouseEvent;
+class QPlatformInputContextPrivate;
class Q_GUI_EXPORT QPlatformInputContext : public QObject
{
Q_OBJECT
+ Q_DECLARE_PRIVATE(QPlatformInputContext)
+
public:
QPlatformInputContext();
virtual ~QPlatformInputContext();
@@ -81,6 +81,14 @@ public:
void emitLocaleChanged();
virtual Qt::LayoutDirection inputDirection() const;
void emitInputDirectionChanged(Qt::LayoutDirection newDirection);
+
+ virtual void setFocusObject(QObject *object);
+ bool inputMethodAccepted() const;
+
+private:
+ friend class QGuiApplication;
+ friend class QGuiApplicationPrivate;
+ friend class QInputMethod;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatforminputcontext_qpa_p.h b/src/gui/kernel/qplatforminputcontext_qpa_p.h
new file mode 100644
index 00000000000..dc12d26ffc1
--- /dev/null
+++ b/src/gui/kernel/qplatforminputcontext_qpa_p.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMINPUTCONTEXT_P_H
+#define QPLATFORMINPUTCONTEXT_P_H
+
+#include <private/qobject_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QPlatformInputContextPrivate: public QObjectPrivate
+{
+public:
+ QPlatformInputContextPrivate() {}
+ ~QPlatformInputContextPrivate() {}
+
+ static void setInputMethodAccepted(bool accepted);
+ static bool inputMethodAccepted();
+
+ static bool s_inputMethodAccepted;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
index 5579b4cd26e..38fe0cce516 100644
--- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
@@ -89,7 +89,6 @@ QIBusPlatformInputContext::QIBusPlatformInputContext ()
connect(d->context, SIGNAL(UpdatePreeditText(QDBusVariant,uint,bool)), this, SLOT(updatePreeditText(QDBusVariant,uint,bool)));
}
QInputMethod *p = qApp->inputMethod();
- connect(p, SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged()));
connect(p, SIGNAL(cursorRectangleChanged()), this, SLOT(cursorRectChanged()));
}
@@ -130,7 +129,7 @@ void QIBusPlatformInputContext::commit()
if (!d->valid)
return;
- QObject *input = qApp->inputMethod()->inputItem();
+ QObject *input = qApp->focusObject();
if (!input) {
d->predit = QString();
return;
@@ -159,7 +158,7 @@ void QIBusPlatformInputContext::cursorRectChanged()
if(!r.isValid())
return;
- QWindow *inputWindow = qApp->inputMethod()->inputWindow();
+ QWindow *inputWindow = qApp->focusWindow();
if (!inputWindow)
return;
r.moveTopLeft(inputWindow->mapToGlobal(r.topLeft()));
@@ -168,15 +167,14 @@ void QIBusPlatformInputContext::cursorRectChanged()
d->context->SetCursorLocation(r.x(), r.y(), r.width(), r.height());
}
-void QIBusPlatformInputContext::inputItemChanged()
+void QIBusPlatformInputContext::setFocusObject(QObject *object)
{
if (!d->valid)
return;
- QObject *input = qApp->inputMethod()->inputItem();
if (debug)
- qDebug() << "setFocusObject" << input;
- if (input)
+ qDebug() << "setFocusObject" << object;
+ if (object)
d->context->FocusIn();
else
d->context->FocusOut();
@@ -184,7 +182,7 @@ void QIBusPlatformInputContext::inputItemChanged()
void QIBusPlatformInputContext::commitText(const QDBusVariant &text)
{
- QObject *input = qApp->inputMethod()->inputItem();
+ QObject *input = qApp->focusObject();
if (!input)
return;
@@ -206,7 +204,7 @@ void QIBusPlatformInputContext::commitText(const QDBusVariant &text)
void QIBusPlatformInputContext::updatePreeditText(const QDBusVariant &text, uint cursorPos, bool visible)
{
- QObject *input = qApp->inputMethod()->inputItem();
+ QObject *input = qApp->focusObject();
if (!input)
return;
@@ -254,6 +252,9 @@ QIBusPlatformInputContext::x11FilterEvent(uint keyval, uint keycode, uint state,
if (!d->valid)
return false;
+ if (!inputMethodAccepted())
+ return false;
+
if (!press)
return false;
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
index ca8f492c5db..1ed4262ef65 100644
--- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
@@ -56,6 +56,7 @@ public:
~QIBusPlatformInputContext();
bool isValid() const;
+ void setFocusObject(QObject *object);
void invokeAction(QInputMethod::Action a, int x);
void reset();
@@ -67,7 +68,6 @@ public:
public Q_SLOTS:
void commitText(const QDBusVariant &text);
void updatePreeditText(const QDBusVariant &text, uint cursor_pos, bool visible);
- void inputItemChanged();
void cursorRectChanged();
private: