From f7e789710568d263816f50bd5782cc7adec41249 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Tue, 8 Feb 2011 13:43:19 +1000 Subject: Don't clear pre-edit text when a graphics items loses focus. Don't forceably reset the input method state when a graphics item loses focus, reset the input context and let it handle sending the appropriate events itself. That way behavior is consistent with QWidget and the input context can opt to commit its current pre-edit text instead of discarding it. And don't change the focus until after the input context has been reset or the input method events won't be delivered. Change-Id: Ic545bccab6bf671709c1d06d499217baf614e6f9 Task-number: QTBUG-16997 Reviewed-by: axis --- src/gui/graphicsview/qgraphicsscene.cpp | 19 ++++++-------- tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 32 ++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 5e5077b..c395a54 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -806,28 +806,23 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item, } if (focusItem) { - QFocusEvent event(QEvent::FocusOut, focusReason); lastFocusItem = focusItem; - focusItem = 0; - sendEvent(lastFocusItem, &event); #ifndef QT_NO_IM if (lastFocusItem && (lastFocusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { - // Reset any visible preedit text - QInputMethodEvent imEvent; - sendEvent(lastFocusItem, &imEvent); - // Close any external input method panel. This happens // automatically by removing WA_InputMethodEnabled on // the views, but if we are changing focus, we have to // do it ourselves. - if (item) { - for (int i = 0; i < views.size(); ++i) - if (views.at(i)->inputContext()) - views.at(i)->inputContext()->reset(); - } + for (int i = 0; i < views.size(); ++i) + if (views.at(i)->inputContext()) + views.at(i)->inputContext()->reset(); } + + focusItem = 0; + QFocusEvent event(QEvent::FocusOut, focusReason); + sendEvent(lastFocusItem, &event); #endif //QT_NO_IM } diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index b221cd9..d446ca7 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -3838,6 +3838,23 @@ public: mutable int queryCalls; }; +class TestInputContext : public QInputContext +{ +public: + TestInputContext() {} + + QString identifierName() { return QString(); } + QString language() { return QString(); } + + void reset() { + ++resetCalls; + sendEvent(QInputMethodEvent()); } + + bool isComposing() const { return false; } + + int resetCalls; +}; + void tst_QGraphicsScene::inputMethod() { QFETCH(int, flags); @@ -3847,14 +3864,22 @@ void tst_QGraphicsScene::inputMethod() item->setFlags((QGraphicsItem::GraphicsItemFlags)flags); QGraphicsScene scene; - QEvent activate(QEvent::WindowActivate); - QApplication::sendEvent(&scene, &activate); + QGraphicsView view(&scene); + TestInputContext inputContext; + view.setInputContext(&inputContext); + view.show(); + QApplication::setActiveWindow(&view); + view.setFocus(); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&view)); + inputContext.resetCalls = 0; scene.addItem(item); QInputMethodEvent event; scene.setFocusItem(item); QCOMPARE(!!(item->flags() & QGraphicsItem::ItemIsFocusable), scene.focusItem() == item); + QCOMPARE(inputContext.resetCalls, 0); item->eventCalls = 0; qApp->sendEvent(&scene, &event); @@ -3865,6 +3890,9 @@ void tst_QGraphicsScene::inputMethod() QCOMPARE(item->queryCalls, callFocusItem ? 1 : 0); scene.setFocusItem(0); + // the input context is reset twice, once because an item has lost focus and again because + // the Qt::WA_InputMethodEnabled flag is cleared because no item has focus. + QCOMPARE(inputContext.resetCalls, callFocusItem ? 2 : 0); QCOMPARE(item->eventCalls, callFocusItem ? 2 : 0); // verify correct delivery of "reset" event QCOMPARE(item->queryCalls, callFocusItem ? 1 : 0); // verify that value is unaffected -- cgit v0.12