summaryrefslogtreecommitdiffstats
path: root/src/widgets/kernel/qwidgetwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/kernel/qwidgetwindow.cpp')
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp63
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