QMdiArea: Store focus widget when new QMdiSubWindow is added.
Introduce function QMdiSubWindowPrivate::storeFocusWidget() to store focus widget and call this when de-activating a sub window. Change restoreFocus() to return a bool and call it from QMdiSubWindowPrivate::setActive(). Task-number: QTBUG-38378 Change-Id: I18dbe66ce85213ca5b4907b5a09126544415351a Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
parent
cd89ec830d
commit
0240110c58
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
** Contact: http://www.qt-project.org/legal
|
** Contact: http://www.qt-project.org/legal
|
||||||
**
|
**
|
||||||
** This file is part of the QtWidgets module of the Qt Toolkit.
|
** This file is part of the QtWidgets module of the Qt Toolkit.
|
||||||
@ -1321,6 +1321,14 @@ void QMdiSubWindowPrivate::setNormalMode()
|
|||||||
updateMask();
|
updateMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void QMdiSubWindowPrivate::storeFocusWidget()
|
||||||
|
{
|
||||||
|
if (QWidget *focus = QApplication::focusWidget()) {
|
||||||
|
if (!restoreFocusWidget && q_func()->isAncestorOf(focus))
|
||||||
|
restoreFocusWidget = focus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
*/
|
*/
|
||||||
@ -1333,8 +1341,7 @@ void QMdiSubWindowPrivate::setMaximizeMode()
|
|||||||
isShadeMode = false;
|
isShadeMode = false;
|
||||||
isMaximizeMode = true;
|
isMaximizeMode = true;
|
||||||
|
|
||||||
if (!restoreFocusWidget && q->isAncestorOf(QApplication::focusWidget()))
|
storeFocusWidget();
|
||||||
restoreFocusWidget = QApplication::focusWidget();
|
|
||||||
|
|
||||||
#ifndef QT_NO_SIZEGRIP
|
#ifndef QT_NO_SIZEGRIP
|
||||||
setSizeGripVisible(false);
|
setSizeGripVisible(false);
|
||||||
@ -1436,6 +1443,7 @@ void QMdiSubWindowPrivate::setActive(bool activate, bool changeFocus)
|
|||||||
Qt::WindowStates oldWindowState = q->windowState();
|
Qt::WindowStates oldWindowState = q->windowState();
|
||||||
q->overrideWindowState(q->windowState() & ~Qt::WindowActive);
|
q->overrideWindowState(q->windowState() & ~Qt::WindowActive);
|
||||||
if (changeFocus) {
|
if (changeFocus) {
|
||||||
|
storeFocusWidget();
|
||||||
QWidget *focusWidget = QApplication::focusWidget();
|
QWidget *focusWidget = QApplication::focusWidget();
|
||||||
if (focusWidget && (focusWidget == q || q->isAncestorOf(focusWidget)))
|
if (focusWidget && (focusWidget == q || q->isAncestorOf(focusWidget)))
|
||||||
focusWidget->clearFocus();
|
focusWidget->clearFocus();
|
||||||
@ -2026,6 +2034,9 @@ void QMdiSubWindowPrivate::setFocusWidget()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(q->windowState() & Qt::WindowMinimized) && restoreFocus())
|
||||||
|
return;
|
||||||
|
|
||||||
if (QWidget *focusWidget = baseWidget->focusWidget()) {
|
if (QWidget *focusWidget = baseWidget->focusWidget()) {
|
||||||
if (!focusWidget->hasFocus() && q->isAncestorOf(focusWidget)
|
if (!focusWidget->hasFocus() && q->isAncestorOf(focusWidget)
|
||||||
&& focusWidget->isVisible() && !q->isMinimized()
|
&& focusWidget->isVisible() && !q->isMinimized()
|
||||||
@ -2048,16 +2059,19 @@ void QMdiSubWindowPrivate::setFocusWidget()
|
|||||||
q->setFocus();
|
q->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QMdiSubWindowPrivate::restoreFocus()
|
bool QMdiSubWindowPrivate::restoreFocus()
|
||||||
{
|
{
|
||||||
if (!restoreFocusWidget)
|
if (restoreFocusWidget.isNull())
|
||||||
return;
|
return false;
|
||||||
if (!restoreFocusWidget->hasFocus() && q_func()->isAncestorOf(restoreFocusWidget)
|
QWidget *candidate = restoreFocusWidget;
|
||||||
&& restoreFocusWidget->isVisible()
|
restoreFocusWidget.clear();
|
||||||
&& restoreFocusWidget->focusPolicy() != Qt::NoFocus) {
|
if (!candidate->hasFocus() && q_func()->isAncestorOf(candidate)
|
||||||
restoreFocusWidget->setFocus();
|
&& candidate->isVisible()
|
||||||
|
&& candidate->focusPolicy() != Qt::NoFocus) {
|
||||||
|
candidate->setFocus();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
restoreFocusWidget = 0;
|
return candidate->hasFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -2605,9 +2619,7 @@ void QMdiSubWindow::showShaded()
|
|||||||
|
|
||||||
d->isMaximizeMode = false;
|
d->isMaximizeMode = false;
|
||||||
|
|
||||||
QWidget *currentFocusWidget = QApplication::focusWidget();
|
d->storeFocusWidget();
|
||||||
if (!d->restoreFocusWidget && isAncestorOf(currentFocusWidget))
|
|
||||||
d->restoreFocusWidget = currentFocusWidget;
|
|
||||||
|
|
||||||
if (!d->isShadeRequestFromMinimizeMode) {
|
if (!d->isShadeRequestFromMinimizeMode) {
|
||||||
d->isShadeMode = true;
|
d->isShadeMode = true;
|
||||||
@ -2621,7 +2633,7 @@ void QMdiSubWindow::showShaded()
|
|||||||
// showMinimized() will reset Qt::WindowActive, which makes sense
|
// showMinimized() will reset Qt::WindowActive, which makes sense
|
||||||
// for top level widgets, but in MDI it makes sense to have an
|
// for top level widgets, but in MDI it makes sense to have an
|
||||||
// active window which is minimized.
|
// active window which is minimized.
|
||||||
if (hasFocus() || isAncestorOf(currentFocusWidget))
|
if (hasFocus() || isAncestorOf(QApplication::focusWidget()))
|
||||||
d->ensureWindowState(Qt::WindowActive);
|
d->ensureWindowState(Qt::WindowActive);
|
||||||
|
|
||||||
#ifndef QT_NO_SIZEGRIP
|
#ifndef QT_NO_SIZEGRIP
|
||||||
|
@ -266,7 +266,8 @@ public:
|
|||||||
QPalette desktopPalette() const;
|
QPalette desktopPalette() const;
|
||||||
void updateActions();
|
void updateActions();
|
||||||
void setFocusWidget();
|
void setFocusWidget();
|
||||||
void restoreFocus();
|
bool restoreFocus();
|
||||||
|
void storeFocusWidget();
|
||||||
void setWindowFlags(Qt::WindowFlags windowFlags);
|
void setWindowFlags(Qt::WindowFlags windowFlags);
|
||||||
void setVisible(WindowStateAction, bool visible = true);
|
void setVisible(WindowStateAction, bool visible = true);
|
||||||
#ifndef QT_NO_ACTION
|
#ifndef QT_NO_ACTION
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
** Contact: http://www.qt-project.org/legal
|
** Contact: http://www.qt-project.org/legal
|
||||||
**
|
**
|
||||||
** This file is part of the test suite of the Qt Toolkit.
|
** This file is part of the test suite of the Qt Toolkit.
|
||||||
@ -58,6 +58,7 @@
|
|||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
#include <QStyleOptionTitleBar>
|
#include <QStyleOptionTitleBar>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QScreen>
|
||||||
#include <QSizeGrip>
|
#include <QSizeGrip>
|
||||||
|
|
||||||
#include "../../../qtest-config.h"
|
#include "../../../qtest-config.h"
|
||||||
@ -182,6 +183,7 @@ private slots:
|
|||||||
void mouseDoubleClick();
|
void mouseDoubleClick();
|
||||||
void setSystemMenu();
|
void setSystemMenu();
|
||||||
void restoreFocus();
|
void restoreFocus();
|
||||||
|
void restoreFocusOverCreation();
|
||||||
void changeFocusWithTab();
|
void changeFocusWithTab();
|
||||||
void closeEvent();
|
void closeEvent();
|
||||||
void setWindowTitle();
|
void setWindowTitle();
|
||||||
@ -1126,6 +1128,7 @@ void tst_QMdiSubWindow::restoreFocus()
|
|||||||
expectedFocusWindow->showMinimized();
|
expectedFocusWindow->showMinimized();
|
||||||
qApp->processEvents();
|
qApp->processEvents();
|
||||||
QVERIFY(expectedFocusWindow->isMinimized());
|
QVERIFY(expectedFocusWindow->isMinimized());
|
||||||
|
qDebug() << expectedFocusWindow<< qApp->focusWidget();
|
||||||
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(expectedFocusWindow));
|
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(expectedFocusWindow));
|
||||||
|
|
||||||
// Minimized -> normal
|
// Minimized -> normal
|
||||||
@ -1178,6 +1181,48 @@ void tst_QMdiSubWindow::restoreFocus()
|
|||||||
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(expectedFocusWindow));
|
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(expectedFocusWindow));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MultiWidget : public QWidget {
|
||||||
|
public:
|
||||||
|
explicit MultiWidget(QWidget *parent = 0) : QWidget(parent)
|
||||||
|
, m_lineEdit1(new QLineEdit(this)), m_lineEdit2(new QLineEdit(this))
|
||||||
|
{
|
||||||
|
QVBoxLayout *lt = new QVBoxLayout(this);
|
||||||
|
lt->addWidget(m_lineEdit1);
|
||||||
|
lt->addWidget(m_lineEdit2);
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineEdit *m_lineEdit1;
|
||||||
|
QLineEdit *m_lineEdit2;
|
||||||
|
};
|
||||||
|
|
||||||
|
void tst_QMdiSubWindow::restoreFocusOverCreation()
|
||||||
|
{
|
||||||
|
// QTBUG-38378, verify that the focus child of a subwindow
|
||||||
|
// is not "forgotten" when adding yet another subwindow.
|
||||||
|
QMdiArea mdiArea;
|
||||||
|
mdiArea.resize(800, 800);
|
||||||
|
mdiArea.move(QGuiApplication::primaryScreen()->availableGeometry().center() - QPoint(400, 400));
|
||||||
|
mdiArea.setWindowTitle(QStringLiteral("restoreFocusOverCreation"));
|
||||||
|
|
||||||
|
MultiWidget *subWidget1 = new MultiWidget;
|
||||||
|
MultiWidget *subWidget2 = new MultiWidget;
|
||||||
|
|
||||||
|
QMdiSubWindow *subWindow1 = mdiArea.addSubWindow(subWidget1);
|
||||||
|
subWidget1->m_lineEdit2->setFocus();
|
||||||
|
subWindow1->show();
|
||||||
|
mdiArea.show();
|
||||||
|
QApplication::setActiveWindow(&mdiArea);
|
||||||
|
QVERIFY(QTest::qWaitForWindowActive(&mdiArea));
|
||||||
|
QCOMPARE(QApplication::focusWidget(), subWidget1->m_lineEdit2);
|
||||||
|
|
||||||
|
QMdiSubWindow *subWindow2 = mdiArea.addSubWindow(subWidget2);
|
||||||
|
subWindow2->show();
|
||||||
|
QTRY_COMPARE(QApplication::focusWidget(), subWidget2->m_lineEdit1);
|
||||||
|
|
||||||
|
mdiArea.setActiveSubWindow(subWindow1);
|
||||||
|
QTRY_COMPARE(QApplication::focusWidget(), subWidget1->m_lineEdit2);
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QMdiSubWindow::changeFocusWithTab()
|
void tst_QMdiSubWindow::changeFocusWithTab()
|
||||||
{
|
{
|
||||||
QWidget *widget = new QWidget;
|
QWidget *widget = new QWidget;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user