summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Dzyubenko <denis.dzyubenko@nokia.com>2010-01-06 14:27:42 (GMT)
committerDenis Dzyubenko <denis.dzyubenko@nokia.com>2010-01-06 14:46:14 (GMT)
commit70496884450d3989829a63baac8db48d36190a25 (patch)
tree50c584b0dc465772b8968f34a6b1f6ea2c29ded8
parenta24d87f6469fa491624590383617b43c2b3dda32 (diff)
downloadQt-70496884450d3989829a63baac8db48d36190a25.zip
Qt-70496884450d3989829a63baac8db48d36190a25.tar.gz
Qt-70496884450d3989829a63baac8db48d36190a25.tar.bz2
Fixes a crash when setting focus on a widget with a focus proxy.
When the focus proxy widget doesn't have InputMethodEnabled attribute set we shouldn't try to set an input context on it. Reviewed-by: Simon Hausmann
-rw-r--r--src/gui/kernel/qwidget.cpp19
-rw-r--r--tests/auto/qinputcontext/tst_qinputcontext.cpp37
2 files changed, 50 insertions, 6 deletions
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 1cb3883..81a9a80 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -3088,7 +3088,8 @@ void QWidgetPrivate::setEnabled_helper(bool enable)
QWidget *focusWidget = effectiveFocusWidget();
QInputContext *qic = focusWidget->d_func()->inputContext();
if (enable) {
- qic->setFocusWidget(focusWidget);
+ if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled))
+ qic->setFocusWidget(focusWidget);
} else {
qic->reset();
qic->setFocusWidget(0);
@@ -10357,17 +10358,22 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
#ifndef QT_NO_IM
QWidget *focusWidget = d->effectiveFocusWidget();
QInputContext *ic = 0;
- if (on && !internalWinId() && testAttribute(Qt::WA_InputMethodEnabled) && hasFocus()) {
+ if (on && !internalWinId() && hasFocus()
+ && focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) {
ic = focusWidget->d_func()->inputContext();
- ic->reset();
- ic->setFocusWidget(0);
+ if (ic) {
+ ic->reset();
+ ic->setFocusWidget(0);
+ }
}
if (!qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings) && parentWidget())
parentWidget()->d_func()->enforceNativeChildren();
if (on && !internalWinId() && testAttribute(Qt::WA_WState_Created))
d->createWinId();
- if (ic && isEnabled())
+ if (ic && isEnabled() && focusWidget->isEnabled()
+ && focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) {
ic->setFocusWidget(focusWidget);
+ }
#endif //QT_NO_IM
break;
}
@@ -10404,7 +10410,8 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
if (!ic && (!on || hasFocus()))
ic = focusWidget->d_func()->inputContext();
if (ic) {
- if (on && hasFocus() && ic->focusWidget() != focusWidget && isEnabled()) {
+ if (on && hasFocus() && ic->focusWidget() != focusWidget && isEnabled()
+ && focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) {
ic->setFocusWidget(focusWidget);
} else if (!on && ic->focusWidget() == focusWidget) {
ic->reset();
diff --git a/tests/auto/qinputcontext/tst_qinputcontext.cpp b/tests/auto/qinputcontext/tst_qinputcontext.cpp
index 50f9140..644b463 100644
--- a/tests/auto/qinputcontext/tst_qinputcontext.cpp
+++ b/tests/auto/qinputcontext/tst_qinputcontext.cpp
@@ -68,6 +68,7 @@ private slots:
void requestSoftwareInputPanel();
void closeSoftwareInputPanel();
void selections();
+ void focusProxy();
};
void tst_QInputContext::maximumTextLength()
@@ -248,5 +249,41 @@ void tst_QInputContext::selections()
QCOMPARE(le.inputMethodQuery(Qt::ImAnchorPosition).toInt(), 5);
}
+void tst_QInputContext::focusProxy()
+{
+ QWidget toplevel(0, Qt::X11BypassWindowManagerHint); toplevel.setObjectName("toplevel");
+ QWidget w(&toplevel); w.setObjectName("w");
+ QWidget proxy(&w); proxy.setObjectName("proxy");
+ QWidget proxy2(&w); proxy2.setObjectName("proxy2");
+ w.setFocusProxy(&proxy);
+ w.setAttribute(Qt::WA_InputMethodEnabled);
+ toplevel.show();
+ QApplication::setActiveWindow(&toplevel);
+ QTest::qWaitForWindowShown(&toplevel);
+ w.setFocus();
+ w.setAttribute(Qt::WA_NativeWindow); // we shouldn't crash!
+
+ proxy.setAttribute(Qt::WA_InputMethodEnabled);
+ proxy2.setAttribute(Qt::WA_InputMethodEnabled);
+
+ proxy2.setFocus();
+ w.setFocus();
+
+ QInputContext *gic = qApp->inputContext();
+ QVERIFY(gic);
+ qDebug() << gic->focusWidget() << &proxy;
+ QCOMPARE(gic->focusWidget(), &proxy);
+
+ // then change the focus proxy and check that input context is valid
+ QVERIFY(w.hasFocus());
+ QVERIFY(proxy.hasFocus());
+ QVERIFY(!proxy2.hasFocus());
+ w.setFocusProxy(&proxy2);
+ QVERIFY(!w.hasFocus());
+ QVERIFY(proxy.hasFocus());
+ QVERIFY(!proxy2.hasFocus());
+ QCOMPARE(gic->focusWidget(), &proxy);
+}
+
QTEST_MAIN(tst_QInputContext)
#include "tst_qinputcontext.moc"