diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qcoreevent.h | 1 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 11 | ||||
-rw-r--r-- | src/widgets/kernel/qapplication.cpp | 19 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 72 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_p.h | 1 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow_qpa.cpp | 9 |
6 files changed, 82 insertions, 31 deletions
diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index 1d54b32dfa..bfd99208cc 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -75,6 +75,7 @@ public: KeyRelease = 7, // key released FocusIn = 8, // keyboard focus received FocusOut = 9, // keyboard focus lost + FocusAboutToChange = 23, // keyboard focus is about to be lost Enter = 10, // mouse enters widget Leave = 11, // mouse leaves widget Paint = 12, // paint widget diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 5611296385..e12183869a 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1155,14 +1155,21 @@ void QGuiApplicationPrivate::processLeaveEvent(QWindowSystemInterfacePrivate::Le void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e) { QWindow *previous = QGuiApplicationPrivate::focus_window; - QGuiApplicationPrivate::focus_window = e->activated.data(); + QWindow *newFocus = e->activated.data(); - if (previous == QGuiApplicationPrivate::focus_window) + if (previous == newFocus) return; QObject *previousFocusObject = previous ? previous->focusObject() : 0; if (previous) { + QFocusEvent focusAboutToChange(QEvent::FocusAboutToChange); + QCoreApplication::sendSpontaneousEvent(previous, &focusAboutToChange); + } + + QGuiApplicationPrivate::focus_window = newFocus; + + if (previous) { QFocusEvent focusOut(QEvent::FocusOut); QCoreApplication::sendSpontaneousEvent(previous, &focusOut); QObject::disconnect(previous, SIGNAL(focusObjectChanged(QObject*)), diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 7441d55865..ce57e2868d 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1760,16 +1760,6 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason) } QWidget *prev = focus_widget; focus_widget = focus; -#ifndef QT_NO_IM - if (prev && ((reason != Qt::PopupFocusReason && reason != Qt::MenuBarFocusReason - && prev->testAttribute(Qt::WA_InputMethodEnabled)) - // Do reset the input context, in case the new focus widget won't accept keyboard input - // or it is not created fully yet. - || (focus_widget && (!focus_widget->testAttribute(Qt::WA_InputMethodEnabled) - || !focus_widget->testAttribute(Qt::WA_WState_Created))))) { - qApp->inputMethod()->reset(); - } -#endif //QT_NO_IM if(focus_widget) focus_widget->d_func()->setFocus_sys(); @@ -1798,7 +1788,6 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason) QApplication::sendEvent(that->style(), &in); } emit qApp->focusChanged(prev, focus_widget); - emit qApp->focusObjectChanged(focus_widget); } } } @@ -2051,6 +2040,14 @@ void QApplication::setActiveWindow(QWidget* act) } } + if (QApplicationPrivate::focus_widget) { + if (QApplicationPrivate::focus_widget->testAttribute(Qt::WA_InputMethodEnabled)) + qApp->inputMethod()->reset(); + + QFocusEvent focusAboutToChange(QEvent::FocusAboutToChange, Qt::ActiveWindowFocusReason); + QApplication::sendEvent(QApplicationPrivate::focus_widget, &focusAboutToChange); + } + QApplicationPrivate::active_window = window; if (QApplicationPrivate::active_window) { diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 6418ba63e1..63eb2540ff 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -5875,9 +5875,10 @@ bool QWidget::hasFocus() const If the window is not active, the widget will be given the focus when the window becomes active. - First, a focus out event is sent to the focus widget (if any) to - tell it that it is about to lose the focus. Then a focus in event - is sent to this widget to tell it that it just received the focus. + First, a focus about to change event is sent to the focus widget (if any) to + tell it that it is about to lose the focus. Then focus is changed, a + focus out event is sent to the previous focus item and a focus in event is sent + to the new item to tell it that it just received the focus. (Nothing happens if the focus in and focus out widgets are the same.) @@ -5930,23 +5931,11 @@ void QWidget::setFocus(Qt::FocusReason reason) } #endif - QWidget *w = f; - if (isHidden()) { - while (w && w->isHidden()) { - w->d_func()->focus_child = f; - w = w->isWindow() ? 0 : w->parentWidget(); - } - } else { - while (w) { - w->d_func()->focus_child = f; - w = w->isWindow() ? 0 : w->parentWidget(); - } - } - #ifndef QT_NO_GRAPHICSVIEW // Update proxy state if (QWExtra *topData = window()->d_func()->extra) { if (topData->proxyWidget && !topData->proxyWidget->hasFocus()) { + f->d_func()->updateFocusChild(); topData->proxyWidget->d_func()->focusFromWidgetToProxy = 1; topData->proxyWidget->setFocus(reason); topData->proxyWidget->d_func()->focusFromWidgetToProxy = 0; @@ -5955,6 +5944,21 @@ void QWidget::setFocus(Qt::FocusReason reason) #endif if (f->isActiveWindow()) { + QWidget *prev = QApplicationPrivate::focus_widget; + if (prev) { + if (reason != Qt::PopupFocusReason && reason != Qt::MenuBarFocusReason + && prev->testAttribute(Qt::WA_InputMethodEnabled)) { + qApp->inputMethod()->reset(); + } + + if (reason != Qt::NoFocusReason) { + QFocusEvent focusAboutToChange(QEvent::FocusAboutToChange, reason); + QApplication::sendEvent(prev, &focusAboutToChange); + } + } + + f->d_func()->updateFocusChild(); + QApplicationPrivate::setFocusWidget(f, reason); #ifndef QT_NO_ACCESSIBILITY # ifdef Q_OS_WIN @@ -5999,6 +6003,30 @@ void QWidget::setFocus(Qt::FocusReason reason) } } #endif + } else { + f->d_func()->updateFocusChild(); + } + + if (QTLWExtra *extra = f->window()->d_func()->maybeTopData()) + emit extra->window->focusObjectChanged(f); +} + +// updates focus_child on parent widgets to point into this widget +void QWidgetPrivate::updateFocusChild() +{ + Q_Q(QWidget); + + QWidget *w = q; + if (q->isHidden()) { + while (w && w->isHidden()) { + w->d_func()->focus_child = q; + w = w->isWindow() ? 0 : w->parentWidget(); + } + } else { + while (w) { + w->d_func()->focus_child = q; + w = w->isWindow() ? 0 : w->parentWidget(); + } } } @@ -6015,8 +6043,8 @@ void QWidget::setFocus(Qt::FocusReason reason) Takes keyboard input focus from the widget. If the widget has active focus, a \link focusOutEvent() focus out - event\endlink is sent to this widget to tell it that it is about - to lose the focus. + event\endlink is sent to this widget to tell it that it has + lost the focus. This widget must enable focus setting in order to get the keyboard input focus, i.e. it must call setFocusPolicy(). @@ -6027,6 +6055,14 @@ void QWidget::setFocus(Qt::FocusReason reason) void QWidget::clearFocus() { + if (hasFocus()) { + if (testAttribute(Qt::WA_InputMethodEnabled)) + qApp->inputMethod()->reset(); + + QFocusEvent focusAboutToChange(QEvent::FocusAboutToChange); + QApplication::sendEvent(this, &focusAboutToChange); + } + QWidget *w = this; while (w) { if (w->d_func()->focus_child == this) diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 38314c234b..8107b6ca74 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -336,6 +336,7 @@ public: void stackUnder_sys(QWidget *); void setFocus_sys(); + void updateFocusChild(); void updateFont(const QFont &); inline void setFont_helper(const QFont &font) { diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp index f58dddb70f..7a13e2032e 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa.cpp +++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp @@ -99,6 +99,15 @@ bool QWidgetWindow::event(QEvent *event) case QEvent::FocusOut: return false; + case QEvent::FocusAboutToChange: + if (QApplicationPrivate::focus_widget) { + if (QApplicationPrivate::focus_widget->testAttribute(Qt::WA_InputMethodEnabled)) + qApp->inputMethod()->commit(); + + QGuiApplication::sendSpontaneousEvent(QApplicationPrivate::focus_widget, event); + } + return true; + case QEvent::KeyPress: case QEvent::KeyRelease: handleKeyEvent(static_cast<QKeyEvent *>(event)); |