Fix the infamous 'dialogs show up on the Task Manager' bug once more.
- Initially set state (and type, and flags) in response to PlatformSurfaceCreated. We know reliably this will run before the window is mapped. - Drop the comment about removing setState() form showEvent handler, as we need it to avoid state loss in this scenario: <mgraesslin> the window gets mapped first time: everything is fine <mgraesslin> window gets unmapped: kwin removes the state as per spec <mgraesslin> qt gets change event and removes the states it doesn't care about <mgraesslin> qt maps window again and sets states <mgraesslin> we lost the state <mgraesslin> which means we need to set the state again from our side before(!) Qt sets it <mgraesslin> and before Qt maps the window
This commit is contained in:
parent
b6b26850fd
commit
2c6dacea38
@ -40,6 +40,7 @@ ENDMACRO(PLASMA_UNIT_TESTS)
|
|||||||
|
|
||||||
PLASMA_UNIT_TESTS(
|
PLASMA_UNIT_TESTS(
|
||||||
dialogqmltest
|
dialogqmltest
|
||||||
|
dialogstatetest
|
||||||
fallbackpackagetest
|
fallbackpackagetest
|
||||||
packagestructuretest
|
packagestructuretest
|
||||||
packageurlinterceptortest
|
packageurlinterceptortest
|
||||||
|
98
autotests/dialogstatetest.cpp
Normal file
98
autotests/dialogstatetest.cpp
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/********************************************************************************
|
||||||
|
* Copyright 2016 Eike Hein <hein@kde.org> *
|
||||||
|
* *
|
||||||
|
* This library is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU Library General Public *
|
||||||
|
* License as published by the Free Software Foundation; either *
|
||||||
|
* version 2 of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This library is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||||
|
* Library General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Library General Public License *
|
||||||
|
* along with this library; see the file COPYING.LIB. If not, write to *
|
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
||||||
|
* Boston, MA 02110-1301, USA. *
|
||||||
|
*********************************************************************************/
|
||||||
|
|
||||||
|
#include "dialogstatetest.h"
|
||||||
|
|
||||||
|
#include <KWindowSystem>
|
||||||
|
|
||||||
|
void DialogStateTest::initTestCase()
|
||||||
|
{
|
||||||
|
m_dialog = new PlasmaQuick::Dialog;
|
||||||
|
m_dialog->setLocation(Plasma::Types::TopEdge);
|
||||||
|
m_dialog->setGeometry(0, 0, 50, 50);
|
||||||
|
|
||||||
|
qRegisterMetaType<WId>("WId");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogStateTest::cleanupTestCase()
|
||||||
|
{
|
||||||
|
delete m_dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogStateTest::windowState()
|
||||||
|
{
|
||||||
|
for (int i = 0; i <= 100; ++i) {
|
||||||
|
m_dialog->show();
|
||||||
|
|
||||||
|
QSignalSpy windowAddedSpy(KWindowSystem::self(), &KWindowSystem::windowAdded);
|
||||||
|
QVERIFY(windowAddedSpy.isValid());
|
||||||
|
QVERIFY(windowAddedSpy.wait());
|
||||||
|
|
||||||
|
bool windowAdded = false;
|
||||||
|
|
||||||
|
while (windowAddedSpy.count()) {
|
||||||
|
const QVariantList &arguments = windowAddedSpy.takeFirst();
|
||||||
|
|
||||||
|
if (arguments.at(0).value<WId>() == m_dialog->winId()) {
|
||||||
|
windowAdded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVERIFY(windowAdded);
|
||||||
|
|
||||||
|
QVERIFY(verifyState(m_dialog));
|
||||||
|
|
||||||
|
m_dialog->hide();
|
||||||
|
|
||||||
|
QSignalSpy windowRemovedSpy(KWindowSystem::self(), &KWindowSystem::windowRemoved);
|
||||||
|
QVERIFY(windowRemovedSpy.isValid());
|
||||||
|
QVERIFY(windowRemovedSpy.wait());
|
||||||
|
|
||||||
|
bool windowRemoved = false;
|
||||||
|
|
||||||
|
while (windowRemovedSpy.count()) {
|
||||||
|
const QVariantList &arguments = windowRemovedSpy.takeFirst();
|
||||||
|
|
||||||
|
if (arguments.at(0).value<WId>() == m_dialog->winId()) {
|
||||||
|
windowRemoved = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVERIFY(windowRemoved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DialogStateTest::verifyState(PlasmaQuick::Dialog *dialog) const
|
||||||
|
{
|
||||||
|
KWindowInfo info(dialog->winId(), NET::WMState);
|
||||||
|
|
||||||
|
if (!(info.state() & NET::SkipTaskbar)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!info.hasState(NET::SkipPager)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(DialogStateTest)
|
44
autotests/dialogstatetest.h
Normal file
44
autotests/dialogstatetest.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright 2016 Eike Hein <hein@kde.org> *
|
||||||
|
* *
|
||||||
|
* This library is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU Library General Public *
|
||||||
|
* License as published by the Free Software Foundation; either *
|
||||||
|
* version 2 of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This library is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||||
|
* Library General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Library General Public License *
|
||||||
|
* along with this library; see the file COPYING.LIB. If not, write to *
|
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
||||||
|
* Boston, MA 02110-1301, USA. *
|
||||||
|
*******************************************************************************/
|
||||||
|
#ifndef DIALOGTEST_H
|
||||||
|
#define DIALOGTEST_H
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
#include "plasmaquick/dialog.h"
|
||||||
|
|
||||||
|
class DialogStateTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void initTestCase();
|
||||||
|
void cleanupTestCase();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void windowState();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool verifyState(PlasmaQuick::Dialog *dialog) const;
|
||||||
|
|
||||||
|
PlasmaQuick::Dialog *m_dialog;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -32,6 +32,10 @@
|
|||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
|
||||||
|
#if (QT_VERSION > QT_VERSION_CHECK(5, 5, 0))
|
||||||
|
#include <QPlatformSurfaceEvent>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <kwindowsystem.h>
|
#include <kwindowsystem.h>
|
||||||
#include <KWindowSystem/KWindowInfo>
|
#include <KWindowSystem/KWindowInfo>
|
||||||
|
|
||||||
@ -317,6 +321,7 @@ void DialogPrivate::updateVisibility(bool visible)
|
|||||||
} else {
|
} else {
|
||||||
q->setFlags(Qt::FramelessWindowHint | q->flags());
|
q->setFlags(Qt::FramelessWindowHint | q->flags());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == Dialog::Dock || type == Dialog::Notification || type == Dialog::OnScreenDisplay) {
|
if (type == Dialog::Dock || type == Dialog::Notification || type == Dialog::OnScreenDisplay) {
|
||||||
KWindowSystem::setOnAllDesktops(q->winId(), true);
|
KWindowSystem::setOnAllDesktops(q->winId(), true);
|
||||||
} else {
|
} else {
|
||||||
@ -1067,7 +1072,6 @@ void Dialog::showEvent(QShowEvent *event)
|
|||||||
DialogShadows::self()->addWindow(this, d->frameSvgItem->enabledBorders());
|
DialogShadows::self()->addWindow(this, d->frameSvgItem->enabledBorders());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove this call from other places once we can depend on Qt >= 5.6.1
|
|
||||||
KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
|
KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
|
||||||
|
|
||||||
QQuickWindow::showEvent(event);
|
QQuickWindow::showEvent(event);
|
||||||
@ -1076,7 +1080,17 @@ void Dialog::showEvent(QShowEvent *event)
|
|||||||
bool Dialog::event(QEvent *event)
|
bool Dialog::event(QEvent *event)
|
||||||
{
|
{
|
||||||
if (event->type() == QEvent::Expose) {
|
if (event->type() == QEvent::Expose) {
|
||||||
|
// FIXME TODO: We can remove this once we depend on Qt 5.6.1+.
|
||||||
|
// See: https://bugreports.qt.io/browse/QTBUG-26978
|
||||||
KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
|
KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
|
||||||
|
#if (QT_VERSION > QT_VERSION_CHECK(5, 5, 0))
|
||||||
|
} else if (event->type() == QEvent::PlatformSurface) {
|
||||||
|
const QPlatformSurfaceEvent *pSEvent = static_cast<QPlatformSurfaceEvent *>(event);
|
||||||
|
|
||||||
|
if (pSEvent->surfaceEventType() == QPlatformSurfaceEvent::SurfaceCreated) {
|
||||||
|
KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} else if (event->type() == QEvent::Show) {
|
} else if (event->type() == QEvent::Show) {
|
||||||
d->updateVisibility(true);
|
d->updateVisibility(true);
|
||||||
} else if (event->type() == QEvent::Hide) {
|
} else if (event->type() == QEvent::Hide) {
|
||||||
@ -1193,9 +1207,10 @@ void Dialog::componentComplete()
|
|||||||
d->componentComplete = true;
|
d->componentComplete = true;
|
||||||
QQuickWindow::setVisible(d->visible);
|
QQuickWindow::setVisible(d->visible);
|
||||||
if (d->visible) {
|
if (d->visible) {
|
||||||
|
// FIXME TODO: We can remove this once we depend on Qt 5.6.1+.
|
||||||
|
// See: https://bugreports.qt.io/browse/QTBUG-26978
|
||||||
KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
|
KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
|
||||||
}
|
}
|
||||||
|
|
||||||
d->updateTheme();
|
d->updateTheme();
|
||||||
|
|
||||||
if (d->mainItem) {
|
if (d->mainItem) {
|
||||||
@ -1247,6 +1262,8 @@ void Dialog::setVisible(bool visible)
|
|||||||
}
|
}
|
||||||
QQuickWindow::setVisible(visible);
|
QQuickWindow::setVisible(visible);
|
||||||
if (visible) {
|
if (visible) {
|
||||||
|
// FIXME TODO: We can remove this once we depend on Qt 5.6.1+.
|
||||||
|
// See: https://bugreports.qt.io/browse/QTBUG-26978
|
||||||
KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
|
KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
|
||||||
}
|
}
|
||||||
//signal will be emitted and proxied from the QQuickWindow code
|
//signal will be emitted and proxied from the QQuickWindow code
|
||||||
|
Loading…
Reference in New Issue
Block a user