diff options
Diffstat (limited to 'src/widgets/kernel/qwidgetwindow.cpp')
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 50b61beb05..ddb570d6c7 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtWidgets module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage @@ -52,6 +52,8 @@ QT_BEGIN_NAMESPACE +Q_WIDGETS_EXPORT extern bool qt_tab_all_widgets(); + QWidget *qt_button_down = 0; // widget got last button-down static QWidget *qt_tablet_target = 0; @@ -123,6 +125,8 @@ bool QWidgetWindow::event(QEvent *event) // these should not be sent to QWidget, the corresponding events // are sent by QApplicationPrivate::notifyActiveWindowChange() case QEvent::FocusIn: + handleFocusInEvent(static_cast<QFocusEvent *>(event)); + // Fallthrough case QEvent::FocusOut: { #ifndef QT_NO_ACCESSIBILITY QAccessible::State state; @@ -284,6 +288,42 @@ void QWidgetWindow::handleEnterLeaveEvent(QEvent *event) } } +QWidget *QWidgetWindow::getFocusWidget(FocusWidgets fw) +{ + QWidget *tlw = m_widget; + QWidget *w = tlw->nextInFocusChain(); + + QWidget *last = tlw; + + uint focus_flag = qt_tab_all_widgets() ? Qt::TabFocus : Qt::StrongFocus; + + while (w != tlw) + { + if (((w->focusPolicy() & focus_flag) == focus_flag) + && w->isVisibleTo(m_widget) && w->isEnabled()) + { + last = w; + if (fw == FirstFocusWidget) + break; + } + w = w->nextInFocusChain(); + } + + return last; +} + +void QWidgetWindow::handleFocusInEvent(QFocusEvent *e) +{ + QWidget *focusWidget = 0; + if (e->reason() == Qt::BacktabFocusReason) + focusWidget = getFocusWidget(LastFocusWidget); + else if (e->reason() == Qt::TabFocusReason) + focusWidget = getFocusWidget(FirstFocusWidget); + + if (focusWidget != 0) + focusWidget->setFocus(); +} + void QWidgetWindow::handleNonClientAreaMouseEvent(QMouseEvent *e) { QApplication::sendSpontaneousEvent(m_widget, e); @@ -352,6 +392,27 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) && qt_replay_popup_mouse_event) { if (m_widget->windowType() != Qt::Popup) qt_button_down = 0; + if (event->type() == QEvent::MouseButtonPress) { + // the popup disappeared, replay the mouse press event + QWidget *w = QApplication::widgetAt(event->globalPos()); + if (w && !QApplicationPrivate::isBlockedByModal(w)) { + // activate window of the widget under mouse pointer + if (!w->isActiveWindow()) { + w->activateWindow(); + w->raise(); + } + + QWindow *win = w->windowHandle(); + if (!win) + win = w->nativeParentWidget()->windowHandle(); + if (win && win->geometry().contains(event->globalPos())) { + const QPoint localPos = win->mapFromGlobal(event->globalPos()); + QMouseEvent e(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), event->button(), event->buttons(), event->modifiers()); + e.setTimestamp(event->timestamp()); + QApplication::sendSpontaneousEvent(win, &e); + } + } + } qt_replay_popup_mouse_event = false; #ifndef QT_NO_CONTEXTMENU } else if (event->type() == QEvent::MouseButtonPress |