2018-10-02 05:39:31 +00:00
|
|
|
/********************************************************************
|
|
|
|
KWin - the KDE window manager
|
|
|
|
This file is part of the KDE project.
|
|
|
|
|
2020-01-14 16:17:18 +00:00
|
|
|
Copyright (C) 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program 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 General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
#include "kwin_wayland_test.h"
|
|
|
|
|
|
|
|
#include "abstract_client.h"
|
|
|
|
#include "atoms.h"
|
2019-09-24 08:48:08 +00:00
|
|
|
#include "x11client.h"
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
#include "deleted.h"
|
2018-10-02 05:39:31 +00:00
|
|
|
#include "main.h"
|
|
|
|
#include "platform.h"
|
|
|
|
#include "wayland_server.h"
|
|
|
|
#include "workspace.h"
|
|
|
|
|
|
|
|
#include <KWayland/Client/compositor.h>
|
|
|
|
#include <KWayland/Client/surface.h>
|
|
|
|
|
|
|
|
#include <xcb/xcb.h>
|
|
|
|
#include <xcb/xcb_icccm.h>
|
|
|
|
|
|
|
|
using namespace KWin;
|
|
|
|
|
|
|
|
static const QString s_socketName = QStringLiteral("wayland_test_kwin_stacking_order-0");
|
|
|
|
|
|
|
|
class StackingOrderTest : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
private Q_SLOTS:
|
|
|
|
void initTestCase();
|
|
|
|
void init();
|
|
|
|
void cleanup();
|
|
|
|
|
|
|
|
void testTransientIsAboveParent();
|
|
|
|
void testRaiseTransient();
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
void testDeletedTransient();
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
void testGroupTransientIsAboveWindowGroup();
|
|
|
|
void testRaiseGroupTransient();
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
void testDeletedGroupTransient();
|
2018-10-02 05:39:31 +00:00
|
|
|
void testDontKeepAboveNonModalDialogGroupTransients();
|
|
|
|
|
2018-10-16 16:19:17 +00:00
|
|
|
void testKeepAbove();
|
|
|
|
void testKeepBelow();
|
|
|
|
|
2018-10-02 05:39:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
void StackingOrderTest::initTestCase()
|
|
|
|
{
|
|
|
|
qRegisterMetaType<KWin::AbstractClient *>();
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
qRegisterMetaType<KWin::Deleted *>();
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated);
|
|
|
|
QVERIFY(workspaceCreatedSpy.isValid());
|
|
|
|
kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024));
|
|
|
|
QVERIFY(waylandServer()->init(s_socketName.toLocal8Bit()));
|
|
|
|
|
|
|
|
kwinApp()->setConfig(KSharedConfig::openConfig(QString(), KConfig::SimpleConfig));
|
|
|
|
|
|
|
|
kwinApp()->start();
|
|
|
|
QVERIFY(workspaceCreatedSpy.wait());
|
|
|
|
waylandServer()->initWorkspace();
|
|
|
|
}
|
|
|
|
|
|
|
|
void StackingOrderTest::init()
|
|
|
|
{
|
|
|
|
QVERIFY(Test::setupWaylandConnection());
|
|
|
|
}
|
|
|
|
|
|
|
|
void StackingOrderTest::cleanup()
|
|
|
|
{
|
|
|
|
Test::destroyWaylandConnection();
|
|
|
|
}
|
|
|
|
|
|
|
|
void StackingOrderTest::testTransientIsAboveParent()
|
|
|
|
{
|
|
|
|
// This test verifies that transients are always above their parents.
|
|
|
|
|
|
|
|
// Create the parent.
|
|
|
|
KWayland::Client::Surface *parentSurface =
|
|
|
|
Test::createSurface(Test::waylandCompositor());
|
|
|
|
QVERIFY(parentSurface);
|
2019-08-27 15:01:14 +00:00
|
|
|
KWayland::Client::XdgShellSurface *parentShellSurface =
|
|
|
|
Test::createXdgShellStableSurface(parentSurface, parentSurface);
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(parentShellSurface);
|
2020-03-04 07:55:26 +00:00
|
|
|
AbstractClient *parent = Test::renderAndWaitForShown(parentSurface, QSize(256, 256), Qt::blue);
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(parent);
|
|
|
|
QVERIFY(parent->isActive());
|
|
|
|
QVERIFY(!parent->isTransient());
|
|
|
|
|
|
|
|
// Initially, the stacking order should contain only the parent window.
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// Create the transient.
|
|
|
|
KWayland::Client::Surface *transientSurface =
|
|
|
|
Test::createSurface(Test::waylandCompositor());
|
|
|
|
QVERIFY(transientSurface);
|
2019-08-27 15:01:14 +00:00
|
|
|
KWayland::Client::XdgShellSurface *transientShellSurface =
|
|
|
|
Test::createXdgShellStableSurface(transientSurface, transientSurface);
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(transientShellSurface);
|
2019-08-27 15:01:14 +00:00
|
|
|
transientShellSurface->setTransientFor(parentShellSurface);
|
2020-03-04 07:55:26 +00:00
|
|
|
AbstractClient *transient = Test::renderAndWaitForShown(
|
2018-10-02 05:39:31 +00:00
|
|
|
transientSurface, QSize(128, 128), Qt::red);
|
|
|
|
QVERIFY(transient);
|
|
|
|
QVERIFY(transient->isActive());
|
|
|
|
QVERIFY(transient->isTransient());
|
|
|
|
|
|
|
|
// The transient should be above the parent.
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// The transient still stays above the parent if we activate the latter.
|
|
|
|
workspace()->activateClient(parent);
|
|
|
|
QTRY_VERIFY(parent->isActive());
|
|
|
|
QTRY_VERIFY(!transient->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void StackingOrderTest::testRaiseTransient()
|
|
|
|
{
|
|
|
|
// This test verifies that both the parent and the transient will be
|
|
|
|
// raised if either one of them is activated.
|
|
|
|
|
|
|
|
// Create the parent.
|
|
|
|
KWayland::Client::Surface *parentSurface =
|
|
|
|
Test::createSurface(Test::waylandCompositor());
|
|
|
|
QVERIFY(parentSurface);
|
2019-08-27 15:01:14 +00:00
|
|
|
KWayland::Client::XdgShellSurface *parentShellSurface =
|
|
|
|
Test::createXdgShellStableSurface(parentSurface, parentSurface);
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(parentShellSurface);
|
2020-03-04 07:55:26 +00:00
|
|
|
AbstractClient *parent = Test::renderAndWaitForShown(parentSurface, QSize(256, 256), Qt::blue);
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(parent);
|
|
|
|
QVERIFY(parent->isActive());
|
|
|
|
QVERIFY(!parent->isTransient());
|
|
|
|
|
|
|
|
// Initially, the stacking order should contain only the parent window.
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// Create the transient.
|
|
|
|
KWayland::Client::Surface *transientSurface =
|
|
|
|
Test::createSurface(Test::waylandCompositor());
|
|
|
|
QVERIFY(transientSurface);
|
2019-08-27 15:01:14 +00:00
|
|
|
KWayland::Client::XdgShellSurface *transientShellSurface =
|
|
|
|
Test::createXdgShellStableSurface(transientSurface, transientSurface);
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(transientShellSurface);
|
2019-08-27 15:01:14 +00:00
|
|
|
transientShellSurface->setTransientFor(parentShellSurface);
|
2020-03-04 07:55:26 +00:00
|
|
|
AbstractClient *transient = Test::renderAndWaitForShown(
|
2018-10-02 05:39:31 +00:00
|
|
|
transientSurface, QSize(128, 128), Qt::red);
|
|
|
|
QVERIFY(transient);
|
|
|
|
QTRY_VERIFY(transient->isActive());
|
|
|
|
QVERIFY(transient->isTransient());
|
|
|
|
|
|
|
|
// The transient should be above the parent.
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// Create a window that doesn't have any relationship to the parent or the transient.
|
|
|
|
KWayland::Client::Surface *anotherSurface =
|
|
|
|
Test::createSurface(Test::waylandCompositor());
|
|
|
|
QVERIFY(anotherSurface);
|
2019-08-27 15:01:14 +00:00
|
|
|
KWayland::Client::XdgShellSurface *anotherShellSurface =
|
|
|
|
Test::createXdgShellStableSurface(anotherSurface, anotherSurface);
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(anotherShellSurface);
|
2020-03-04 07:55:26 +00:00
|
|
|
AbstractClient *anotherClient = Test::renderAndWaitForShown(anotherSurface, QSize(128, 128), Qt::green);
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(anotherClient);
|
|
|
|
QVERIFY(anotherClient->isActive());
|
|
|
|
QVERIFY(!anotherClient->isTransient());
|
|
|
|
|
|
|
|
// The newly created surface has to be above both the parent and the transient.
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient, anotherClient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// If we activate the parent, the transient should be raised too.
|
|
|
|
workspace()->activateClient(parent);
|
|
|
|
QTRY_VERIFY(parent->isActive());
|
|
|
|
QTRY_VERIFY(!transient->isActive());
|
|
|
|
QTRY_VERIFY(!anotherClient->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{anotherClient, parent, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// Go back to the initial setup.
|
|
|
|
workspace()->activateClient(anotherClient);
|
|
|
|
QTRY_VERIFY(!parent->isActive());
|
|
|
|
QTRY_VERIFY(!transient->isActive());
|
|
|
|
QTRY_VERIFY(anotherClient->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient, anotherClient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// If we activate the transient, the parent should be raised too.
|
|
|
|
workspace()->activateClient(transient);
|
|
|
|
QTRY_VERIFY(!parent->isActive());
|
|
|
|
QTRY_VERIFY(transient->isActive());
|
|
|
|
QTRY_VERIFY(!anotherClient->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{anotherClient, parent, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
}
|
|
|
|
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
struct WindowUnrefDeleter
|
|
|
|
{
|
|
|
|
static inline void cleanup(Deleted *d) {
|
|
|
|
if (d != nullptr) {
|
|
|
|
d->unrefWindow();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void StackingOrderTest::testDeletedTransient()
|
|
|
|
{
|
|
|
|
// This test verifies that deleted transients are kept above their
|
|
|
|
// old parents.
|
|
|
|
|
|
|
|
// Create the parent.
|
|
|
|
KWayland::Client::Surface *parentSurface =
|
|
|
|
Test::createSurface(Test::waylandCompositor());
|
|
|
|
QVERIFY(parentSurface);
|
2019-08-27 15:01:14 +00:00
|
|
|
KWayland::Client::XdgShellSurface *parentShellSurface =
|
|
|
|
Test::createXdgShellStableSurface(parentSurface, parentSurface);
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
QVERIFY(parentShellSurface);
|
2020-03-04 07:55:26 +00:00
|
|
|
AbstractClient *parent = Test::renderAndWaitForShown(parentSurface, QSize(256, 256), Qt::blue);
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
QVERIFY(parent);
|
|
|
|
QVERIFY(parent->isActive());
|
|
|
|
QVERIFY(!parent->isTransient());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent}));
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
|
|
|
|
// Create the first transient.
|
|
|
|
KWayland::Client::Surface *transient1Surface =
|
|
|
|
Test::createSurface(Test::waylandCompositor());
|
|
|
|
QVERIFY(transient1Surface);
|
2019-08-27 15:01:14 +00:00
|
|
|
KWayland::Client::XdgShellSurface *transient1ShellSurface =
|
|
|
|
Test::createXdgShellStableSurface(transient1Surface, transient1Surface);
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
QVERIFY(transient1ShellSurface);
|
2019-08-27 15:01:14 +00:00
|
|
|
transient1ShellSurface->setTransientFor(parentShellSurface);
|
2020-03-04 07:55:26 +00:00
|
|
|
AbstractClient *transient1 = Test::renderAndWaitForShown(
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
transient1Surface, QSize(128, 128), Qt::red);
|
|
|
|
QVERIFY(transient1);
|
|
|
|
QTRY_VERIFY(transient1->isActive());
|
|
|
|
QVERIFY(transient1->isTransient());
|
|
|
|
QCOMPARE(transient1->transientFor(), parent);
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient1}));
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
|
|
|
|
// Create the second transient.
|
|
|
|
KWayland::Client::Surface *transient2Surface =
|
|
|
|
Test::createSurface(Test::waylandCompositor());
|
|
|
|
QVERIFY(transient2Surface);
|
2019-08-27 15:01:14 +00:00
|
|
|
KWayland::Client::XdgShellSurface *transient2ShellSurface =
|
|
|
|
Test::createXdgShellStableSurface(transient2Surface, transient2Surface);
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
QVERIFY(transient2ShellSurface);
|
2019-08-27 15:01:14 +00:00
|
|
|
transient2ShellSurface->setTransientFor(transient1ShellSurface);
|
2020-03-04 07:55:26 +00:00
|
|
|
AbstractClient *transient2 = Test::renderAndWaitForShown(
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
transient2Surface, QSize(128, 128), Qt::red);
|
|
|
|
QVERIFY(transient2);
|
|
|
|
QTRY_VERIFY(transient2->isActive());
|
|
|
|
QVERIFY(transient2->isTransient());
|
|
|
|
QCOMPARE(transient2->transientFor(), transient1);
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient1, transient2}));
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
|
|
|
|
// Activate the parent, both transients have to be above it.
|
|
|
|
workspace()->activateClient(parent);
|
|
|
|
QTRY_VERIFY(parent->isActive());
|
|
|
|
QTRY_VERIFY(!transient1->isActive());
|
|
|
|
QTRY_VERIFY(!transient2->isActive());
|
|
|
|
|
|
|
|
// Close the top-most transient.
|
2020-03-04 07:55:26 +00:00
|
|
|
connect(transient2, &AbstractClient::windowClosed, this,
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
[](Toplevel *toplevel, Deleted *deleted) {
|
|
|
|
Q_UNUSED(toplevel)
|
|
|
|
deleted->refWindow();
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2020-03-04 07:55:26 +00:00
|
|
|
QSignalSpy windowClosedSpy(transient2, &AbstractClient::windowClosed);
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
QVERIFY(windowClosedSpy.isValid());
|
|
|
|
delete transient2ShellSurface;
|
|
|
|
delete transient2Surface;
|
|
|
|
QVERIFY(windowClosedSpy.wait());
|
|
|
|
|
|
|
|
QScopedPointer<Deleted, WindowUnrefDeleter> deletedTransient(
|
|
|
|
windowClosedSpy.first().at(1).value<Deleted *>());
|
|
|
|
QVERIFY(deletedTransient.data());
|
|
|
|
|
|
|
|
// The deleted transient still has to be above its old parent (transient1).
|
|
|
|
QTRY_VERIFY(parent->isActive());
|
|
|
|
QTRY_VERIFY(!transient1->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{parent, transient1, deletedTransient.data()}));
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
}
|
|
|
|
|
2018-10-02 05:39:31 +00:00
|
|
|
static xcb_window_t createGroupWindow(xcb_connection_t *conn,
|
|
|
|
const QRect &geometry,
|
|
|
|
xcb_window_t leaderWid = XCB_WINDOW_NONE)
|
|
|
|
{
|
|
|
|
xcb_window_t wid = xcb_generate_id(conn);
|
|
|
|
xcb_create_window(
|
|
|
|
conn, // c
|
|
|
|
XCB_COPY_FROM_PARENT, // depth
|
|
|
|
wid, // wid
|
|
|
|
rootWindow(), // parent
|
|
|
|
geometry.x(), // x
|
|
|
|
geometry.y(), // y
|
|
|
|
geometry.width(), // width
|
|
|
|
geometry.height(), // height
|
|
|
|
0, // border_width
|
|
|
|
XCB_WINDOW_CLASS_INPUT_OUTPUT, // _class
|
|
|
|
XCB_COPY_FROM_PARENT, // visual
|
|
|
|
0, // value_mask
|
|
|
|
nullptr // value_list
|
|
|
|
);
|
|
|
|
|
|
|
|
xcb_size_hints_t sizeHints = {};
|
|
|
|
xcb_icccm_size_hints_set_position(&sizeHints, 1, geometry.x(), geometry.y());
|
|
|
|
xcb_icccm_size_hints_set_size(&sizeHints, 1, geometry.width(), geometry.height());
|
|
|
|
xcb_icccm_set_wm_normal_hints(conn, wid, &sizeHints);
|
|
|
|
|
|
|
|
if (leaderWid == XCB_WINDOW_NONE) {
|
|
|
|
leaderWid = wid;
|
|
|
|
}
|
|
|
|
|
|
|
|
xcb_change_property(
|
|
|
|
conn, // c
|
|
|
|
XCB_PROP_MODE_REPLACE, // mode
|
|
|
|
wid, // window
|
|
|
|
atoms->wm_client_leader, // property
|
|
|
|
XCB_ATOM_WINDOW, // type
|
|
|
|
32, // format
|
|
|
|
1, // data_len
|
|
|
|
&leaderWid // data
|
|
|
|
);
|
|
|
|
|
|
|
|
return wid;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct XcbConnectionDeleter
|
|
|
|
{
|
|
|
|
static inline void cleanup(xcb_connection_t *c) {
|
|
|
|
xcb_disconnect(c);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void StackingOrderTest::testGroupTransientIsAboveWindowGroup()
|
|
|
|
{
|
|
|
|
// This test verifies that group transients are always above other
|
|
|
|
// window group members.
|
|
|
|
|
|
|
|
const QRect geometry = QRect(0, 0, 128, 128);
|
|
|
|
|
|
|
|
QScopedPointer<xcb_connection_t, XcbConnectionDeleter> conn(
|
|
|
|
xcb_connect(nullptr, nullptr));
|
|
|
|
|
|
|
|
QSignalSpy windowCreatedSpy(workspace(), &Workspace::clientAdded);
|
|
|
|
QVERIFY(windowCreatedSpy.isValid());
|
|
|
|
|
|
|
|
// Create the group leader.
|
|
|
|
xcb_window_t leaderWid = createGroupWindow(conn.data(), geometry);
|
|
|
|
xcb_map_window(conn.data(), leaderWid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *leader = windowCreatedSpy.first().first().value<X11Client *>();
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(leader);
|
|
|
|
QVERIFY(leader->isActive());
|
|
|
|
QCOMPARE(leader->windowId(), leaderWid);
|
|
|
|
QVERIFY(!leader->isTransient());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// Create another group member.
|
|
|
|
windowCreatedSpy.clear();
|
|
|
|
xcb_window_t member1Wid = createGroupWindow(conn.data(), geometry, leaderWid);
|
|
|
|
xcb_map_window(conn.data(), member1Wid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *member1 = windowCreatedSpy.first().first().value<X11Client *>();
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(member1);
|
|
|
|
QVERIFY(member1->isActive());
|
|
|
|
QCOMPARE(member1->windowId(), member1Wid);
|
|
|
|
QCOMPARE(member1->group(), leader->group());
|
|
|
|
QVERIFY(!member1->isTransient());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// Create yet another group member.
|
|
|
|
windowCreatedSpy.clear();
|
|
|
|
xcb_window_t member2Wid = createGroupWindow(conn.data(), geometry, leaderWid);
|
|
|
|
xcb_map_window(conn.data(), member2Wid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *member2 = windowCreatedSpy.first().first().value<X11Client *>();
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(member2);
|
|
|
|
QVERIFY(member2->isActive());
|
|
|
|
QCOMPARE(member2->windowId(), member2Wid);
|
|
|
|
QCOMPARE(member2->group(), leader->group());
|
|
|
|
QVERIFY(!member2->isTransient());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// Create a group transient.
|
|
|
|
windowCreatedSpy.clear();
|
|
|
|
xcb_window_t transientWid = createGroupWindow(conn.data(), geometry, leaderWid);
|
|
|
|
xcb_icccm_set_wm_transient_for(conn.data(), transientWid, rootWindow());
|
|
|
|
|
|
|
|
// Currently, we have some weird bug workaround: if a group transient
|
|
|
|
// is a non-modal dialog, then it won't be kept above its window group.
|
|
|
|
// We need to explicitly specify window type, otherwise the window type
|
|
|
|
// will be deduced to _NET_WM_WINDOW_TYPE_DIALOG because we set transient
|
|
|
|
// for before (the EWMH spec says to do that).
|
|
|
|
xcb_atom_t net_wm_window_type = Xcb::Atom(
|
|
|
|
QByteArrayLiteral("_NET_WM_WINDOW_TYPE"), false, conn.data());
|
|
|
|
xcb_atom_t net_wm_window_type_normal = Xcb::Atom(
|
|
|
|
QByteArrayLiteral("_NET_WM_WINDOW_TYPE_NORMAL"), false, conn.data());
|
|
|
|
xcb_change_property(
|
|
|
|
conn.data(), // c
|
|
|
|
XCB_PROP_MODE_REPLACE, // mode
|
|
|
|
transientWid, // window
|
|
|
|
net_wm_window_type, // property
|
|
|
|
XCB_ATOM_ATOM, // type
|
|
|
|
32, // format
|
|
|
|
1, // data_len
|
|
|
|
&net_wm_window_type_normal // data
|
|
|
|
);
|
|
|
|
|
|
|
|
xcb_map_window(conn.data(), transientWid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *transient = windowCreatedSpy.first().first().value<X11Client *>();
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(transient);
|
|
|
|
QVERIFY(transient->isActive());
|
|
|
|
QCOMPARE(transient->windowId(), transientWid);
|
|
|
|
QCOMPARE(transient->group(), leader->group());
|
|
|
|
QVERIFY(transient->isTransient());
|
|
|
|
QVERIFY(transient->groupTransient());
|
|
|
|
QVERIFY(!transient->isDialog()); // See above why
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// If we activate any member of the window group, the transient will be above it.
|
|
|
|
workspace()->activateClient(leader);
|
|
|
|
QTRY_VERIFY(leader->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member1, member2, leader, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
workspace()->activateClient(member1);
|
|
|
|
QTRY_VERIFY(member1->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member2, leader, member1, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
workspace()->activateClient(member2);
|
|
|
|
QTRY_VERIFY(member2->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
workspace()->activateClient(transient);
|
|
|
|
QTRY_VERIFY(transient->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void StackingOrderTest::testRaiseGroupTransient()
|
|
|
|
{
|
|
|
|
const QRect geometry = QRect(0, 0, 128, 128);
|
|
|
|
|
|
|
|
QScopedPointer<xcb_connection_t, XcbConnectionDeleter> conn(
|
|
|
|
xcb_connect(nullptr, nullptr));
|
|
|
|
|
|
|
|
QSignalSpy windowCreatedSpy(workspace(), &Workspace::clientAdded);
|
|
|
|
QVERIFY(windowCreatedSpy.isValid());
|
|
|
|
|
|
|
|
// Create the group leader.
|
|
|
|
xcb_window_t leaderWid = createGroupWindow(conn.data(), geometry);
|
|
|
|
xcb_map_window(conn.data(), leaderWid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *leader = windowCreatedSpy.first().first().value<X11Client *>();
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(leader);
|
|
|
|
QVERIFY(leader->isActive());
|
|
|
|
QCOMPARE(leader->windowId(), leaderWid);
|
|
|
|
QVERIFY(!leader->isTransient());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// Create another group member.
|
|
|
|
windowCreatedSpy.clear();
|
|
|
|
xcb_window_t member1Wid = createGroupWindow(conn.data(), geometry, leaderWid);
|
|
|
|
xcb_map_window(conn.data(), member1Wid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *member1 = windowCreatedSpy.first().first().value<X11Client *>();
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(member1);
|
|
|
|
QVERIFY(member1->isActive());
|
|
|
|
QCOMPARE(member1->windowId(), member1Wid);
|
|
|
|
QCOMPARE(member1->group(), leader->group());
|
|
|
|
QVERIFY(!member1->isTransient());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// Create yet another group member.
|
|
|
|
windowCreatedSpy.clear();
|
|
|
|
xcb_window_t member2Wid = createGroupWindow(conn.data(), geometry, leaderWid);
|
|
|
|
xcb_map_window(conn.data(), member2Wid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *member2 = windowCreatedSpy.first().first().value<X11Client *>();
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(member2);
|
|
|
|
QVERIFY(member2->isActive());
|
|
|
|
QCOMPARE(member2->windowId(), member2Wid);
|
|
|
|
QCOMPARE(member2->group(), leader->group());
|
|
|
|
QVERIFY(!member2->isTransient());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// Create a group transient.
|
|
|
|
windowCreatedSpy.clear();
|
|
|
|
xcb_window_t transientWid = createGroupWindow(conn.data(), geometry, leaderWid);
|
|
|
|
xcb_icccm_set_wm_transient_for(conn.data(), transientWid, rootWindow());
|
|
|
|
|
|
|
|
// Currently, we have some weird bug workaround: if a group transient
|
|
|
|
// is a non-modal dialog, then it won't be kept above its window group.
|
|
|
|
// We need to explicitly specify window type, otherwise the window type
|
|
|
|
// will be deduced to _NET_WM_WINDOW_TYPE_DIALOG because we set transient
|
|
|
|
// for before (the EWMH spec says to do that).
|
|
|
|
xcb_atom_t net_wm_window_type = Xcb::Atom(
|
|
|
|
QByteArrayLiteral("_NET_WM_WINDOW_TYPE"), false, conn.data());
|
|
|
|
xcb_atom_t net_wm_window_type_normal = Xcb::Atom(
|
|
|
|
QByteArrayLiteral("_NET_WM_WINDOW_TYPE_NORMAL"), false, conn.data());
|
|
|
|
xcb_change_property(
|
|
|
|
conn.data(), // c
|
|
|
|
XCB_PROP_MODE_REPLACE, // mode
|
|
|
|
transientWid, // window
|
|
|
|
net_wm_window_type, // property
|
|
|
|
XCB_ATOM_ATOM, // type
|
|
|
|
32, // format
|
|
|
|
1, // data_len
|
|
|
|
&net_wm_window_type_normal // data
|
|
|
|
);
|
|
|
|
|
|
|
|
xcb_map_window(conn.data(), transientWid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *transient = windowCreatedSpy.first().first().value<X11Client *>();
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(transient);
|
|
|
|
QVERIFY(transient->isActive());
|
|
|
|
QCOMPARE(transient->windowId(), transientWid);
|
|
|
|
QCOMPARE(transient->group(), leader->group());
|
|
|
|
QVERIFY(transient->isTransient());
|
|
|
|
QVERIFY(transient->groupTransient());
|
|
|
|
QVERIFY(!transient->isDialog()); // See above why
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// Create a Wayland client that is not a member of the window group.
|
|
|
|
KWayland::Client::Surface *anotherSurface =
|
|
|
|
Test::createSurface(Test::waylandCompositor());
|
|
|
|
QVERIFY(anotherSurface);
|
2019-08-27 15:01:14 +00:00
|
|
|
KWayland::Client::XdgShellSurface *anotherShellSurface =
|
|
|
|
Test::createXdgShellStableSurface(anotherSurface, anotherSurface);
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(anotherShellSurface);
|
2020-03-04 07:55:26 +00:00
|
|
|
AbstractClient *anotherClient = Test::renderAndWaitForShown(anotherSurface, QSize(128, 128), Qt::green);
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(anotherClient);
|
|
|
|
QVERIFY(anotherClient->isActive());
|
|
|
|
QVERIFY(!anotherClient->isTransient());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient, anotherClient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// If we activate the leader, then only it and the transient have to be raised.
|
|
|
|
workspace()->activateClient(leader);
|
|
|
|
QTRY_VERIFY(leader->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member1, member2, anotherClient, leader, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// If another member of the window group is activated, then the transient will
|
|
|
|
// be above that member and the leader.
|
|
|
|
workspace()->activateClient(member2);
|
|
|
|
QTRY_VERIFY(member2->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member1, anotherClient, leader, member2, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// FIXME: If we activate the transient, only it will be raised.
|
|
|
|
workspace()->activateClient(anotherClient);
|
|
|
|
QTRY_VERIFY(anotherClient->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member1, leader, member2, transient, anotherClient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
workspace()->activateClient(transient);
|
|
|
|
QTRY_VERIFY(transient->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member1, leader, member2, anotherClient, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
}
|
|
|
|
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
void StackingOrderTest::testDeletedGroupTransient()
|
|
|
|
{
|
|
|
|
// This test verifies that deleted group transients are kept above their
|
|
|
|
// old window groups.
|
|
|
|
|
|
|
|
const QRect geometry = QRect(0, 0, 128, 128);
|
|
|
|
|
|
|
|
QScopedPointer<xcb_connection_t, XcbConnectionDeleter> conn(
|
|
|
|
xcb_connect(nullptr, nullptr));
|
|
|
|
|
|
|
|
QSignalSpy windowCreatedSpy(workspace(), &Workspace::clientAdded);
|
|
|
|
QVERIFY(windowCreatedSpy.isValid());
|
|
|
|
|
|
|
|
// Create the group leader.
|
|
|
|
xcb_window_t leaderWid = createGroupWindow(conn.data(), geometry);
|
|
|
|
xcb_map_window(conn.data(), leaderWid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *leader = windowCreatedSpy.first().first().value<X11Client *>();
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
QVERIFY(leader);
|
|
|
|
QVERIFY(leader->isActive());
|
|
|
|
QCOMPARE(leader->windowId(), leaderWid);
|
|
|
|
QVERIFY(!leader->isTransient());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader}));
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
|
|
|
|
// Create another group member.
|
|
|
|
windowCreatedSpy.clear();
|
|
|
|
xcb_window_t member1Wid = createGroupWindow(conn.data(), geometry, leaderWid);
|
|
|
|
xcb_map_window(conn.data(), member1Wid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *member1 = windowCreatedSpy.first().first().value<X11Client *>();
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
QVERIFY(member1);
|
|
|
|
QVERIFY(member1->isActive());
|
|
|
|
QCOMPARE(member1->windowId(), member1Wid);
|
|
|
|
QCOMPARE(member1->group(), leader->group());
|
|
|
|
QVERIFY(!member1->isTransient());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1}));
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
|
|
|
|
// Create yet another group member.
|
|
|
|
windowCreatedSpy.clear();
|
|
|
|
xcb_window_t member2Wid = createGroupWindow(conn.data(), geometry, leaderWid);
|
|
|
|
xcb_map_window(conn.data(), member2Wid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *member2 = windowCreatedSpy.first().first().value<X11Client *>();
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
QVERIFY(member2);
|
|
|
|
QVERIFY(member2->isActive());
|
|
|
|
QCOMPARE(member2->windowId(), member2Wid);
|
|
|
|
QCOMPARE(member2->group(), leader->group());
|
|
|
|
QVERIFY(!member2->isTransient());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2}));
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
|
|
|
|
// Create a group transient.
|
|
|
|
windowCreatedSpy.clear();
|
|
|
|
xcb_window_t transientWid = createGroupWindow(conn.data(), geometry, leaderWid);
|
|
|
|
xcb_icccm_set_wm_transient_for(conn.data(), transientWid, rootWindow());
|
|
|
|
|
|
|
|
// Currently, we have some weird bug workaround: if a group transient
|
|
|
|
// is a non-modal dialog, then it won't be kept above its window group.
|
|
|
|
// We need to explicitly specify window type, otherwise the window type
|
|
|
|
// will be deduced to _NET_WM_WINDOW_TYPE_DIALOG because we set transient
|
|
|
|
// for before (the EWMH spec says to do that).
|
|
|
|
xcb_atom_t net_wm_window_type = Xcb::Atom(
|
|
|
|
QByteArrayLiteral("_NET_WM_WINDOW_TYPE"), false, conn.data());
|
|
|
|
xcb_atom_t net_wm_window_type_normal = Xcb::Atom(
|
|
|
|
QByteArrayLiteral("_NET_WM_WINDOW_TYPE_NORMAL"), false, conn.data());
|
|
|
|
xcb_change_property(
|
|
|
|
conn.data(), // c
|
|
|
|
XCB_PROP_MODE_REPLACE, // mode
|
|
|
|
transientWid, // window
|
|
|
|
net_wm_window_type, // property
|
|
|
|
XCB_ATOM_ATOM, // type
|
|
|
|
32, // format
|
|
|
|
1, // data_len
|
|
|
|
&net_wm_window_type_normal // data
|
|
|
|
);
|
|
|
|
|
|
|
|
xcb_map_window(conn.data(), transientWid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *transient = windowCreatedSpy.first().first().value<X11Client *>();
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
QVERIFY(transient);
|
|
|
|
QVERIFY(transient->isActive());
|
|
|
|
QCOMPARE(transient->windowId(), transientWid);
|
|
|
|
QCOMPARE(transient->group(), leader->group());
|
|
|
|
QVERIFY(transient->isTransient());
|
|
|
|
QVERIFY(transient->groupTransient());
|
|
|
|
QVERIFY(!transient->isDialog()); // See above why
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient}));
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
|
|
|
|
// Unmap the transient.
|
2019-09-24 08:48:08 +00:00
|
|
|
connect(transient, &X11Client::windowClosed, this,
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
[](Toplevel *toplevel, Deleted *deleted) {
|
|
|
|
Q_UNUSED(toplevel)
|
|
|
|
deleted->refWindow();
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2019-09-24 08:48:08 +00:00
|
|
|
QSignalSpy windowClosedSpy(transient, &X11Client::windowClosed);
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
QVERIFY(windowClosedSpy.isValid());
|
|
|
|
xcb_unmap_window(conn.data(), transientWid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
QVERIFY(windowClosedSpy.wait());
|
|
|
|
|
|
|
|
QScopedPointer<Deleted, WindowUnrefDeleter> deletedTransient(
|
|
|
|
windowClosedSpy.first().at(1).value<Deleted *>());
|
|
|
|
QVERIFY(deletedTransient.data());
|
|
|
|
|
|
|
|
// The transient has to be above each member of the window group.
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, deletedTransient.data()}));
|
Keep Deleted transients above old parents
Summary:
If a modal window is closed, usually, it will go behind its parent. The
reason for this is that Workspace::constrainedStackingOrder() puts only
AbstractClient transients above parents, not Deleted transients.
So, if fade/glide/scale effect animates the disappearing of a transient,
unfortunately, one can't see that animation.
BUG: 397448
FIXED-IN: 5.15.0
Test Plan:
=== Closing of a transient and parent window
Before:
https://www.youtube.com/watch?v=XiLq7EAVCp0
After:
https://www.youtube.com/watch?v=cH_Ki-sqY8M
=== Scale effect
Before:
https://www.youtube.com/watch?v=Eb2a3U7R10I
After:
https://www.youtube.com/watch?v=4AKu3fdrnYQ
=== Sheet effect
Before:
https://www.youtube.com/watch?v=xPPSnR5FUU0
After:
https://www.youtube.com/watch?v=o_hxTNT-5Hg
=== Popup menus on Wayland
Before:
https://www.youtube.com/watch?v=5DnrY8p3F5A
After:
https://www.youtube.com/watch?v=7XEo8n_CrCc
Reviewers: #kwin, davidedmundson
Reviewed By: #kwin, davidedmundson
Subscribers: abetts, davidedmundson, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D14868
2018-10-15 13:04:05 +00:00
|
|
|
}
|
|
|
|
|
2018-10-02 05:39:31 +00:00
|
|
|
void StackingOrderTest::testDontKeepAboveNonModalDialogGroupTransients()
|
|
|
|
{
|
|
|
|
// Bug 76026
|
|
|
|
|
|
|
|
const QRect geometry = QRect(0, 0, 128, 128);
|
|
|
|
|
|
|
|
QScopedPointer<xcb_connection_t, XcbConnectionDeleter> conn(
|
|
|
|
xcb_connect(nullptr, nullptr));
|
|
|
|
|
|
|
|
QSignalSpy windowCreatedSpy(workspace(), &Workspace::clientAdded);
|
|
|
|
QVERIFY(windowCreatedSpy.isValid());
|
|
|
|
|
|
|
|
// Create the group leader.
|
|
|
|
xcb_window_t leaderWid = createGroupWindow(conn.data(), geometry);
|
|
|
|
xcb_map_window(conn.data(), leaderWid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *leader = windowCreatedSpy.first().first().value<X11Client *>();
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(leader);
|
|
|
|
QVERIFY(leader->isActive());
|
|
|
|
QCOMPARE(leader->windowId(), leaderWid);
|
|
|
|
QVERIFY(!leader->isTransient());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// Create another group member.
|
|
|
|
windowCreatedSpy.clear();
|
|
|
|
xcb_window_t member1Wid = createGroupWindow(conn.data(), geometry, leaderWid);
|
|
|
|
xcb_map_window(conn.data(), member1Wid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *member1 = windowCreatedSpy.first().first().value<X11Client *>();
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(member1);
|
|
|
|
QVERIFY(member1->isActive());
|
|
|
|
QCOMPARE(member1->windowId(), member1Wid);
|
|
|
|
QCOMPARE(member1->group(), leader->group());
|
|
|
|
QVERIFY(!member1->isTransient());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// Create yet another group member.
|
|
|
|
windowCreatedSpy.clear();
|
|
|
|
xcb_window_t member2Wid = createGroupWindow(conn.data(), geometry, leaderWid);
|
|
|
|
xcb_map_window(conn.data(), member2Wid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *member2 = windowCreatedSpy.first().first().value<X11Client *>();
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(member2);
|
|
|
|
QVERIFY(member2->isActive());
|
|
|
|
QCOMPARE(member2->windowId(), member2Wid);
|
|
|
|
QCOMPARE(member2->group(), leader->group());
|
|
|
|
QVERIFY(!member2->isTransient());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
// Create a group transient.
|
|
|
|
windowCreatedSpy.clear();
|
|
|
|
xcb_window_t transientWid = createGroupWindow(conn.data(), geometry, leaderWid);
|
|
|
|
xcb_icccm_set_wm_transient_for(conn.data(), transientWid, rootWindow());
|
|
|
|
xcb_map_window(conn.data(), transientWid);
|
|
|
|
xcb_flush(conn.data());
|
|
|
|
|
|
|
|
QVERIFY(windowCreatedSpy.wait());
|
2019-09-24 08:48:08 +00:00
|
|
|
X11Client *transient = windowCreatedSpy.first().first().value<X11Client *>();
|
2018-10-02 05:39:31 +00:00
|
|
|
QVERIFY(transient);
|
|
|
|
QVERIFY(transient->isActive());
|
|
|
|
QCOMPARE(transient->windowId(), transientWid);
|
|
|
|
QCOMPARE(transient->group(), leader->group());
|
|
|
|
QVERIFY(transient->isTransient());
|
|
|
|
QVERIFY(transient->groupTransient());
|
|
|
|
QVERIFY(transient->isDialog());
|
|
|
|
QVERIFY(!transient->isModal());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
workspace()->activateClient(leader);
|
|
|
|
QTRY_VERIFY(leader->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member1, member2, transient, leader}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
workspace()->activateClient(member1);
|
|
|
|
QTRY_VERIFY(member1->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{member2, transient, leader, member1}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
workspace()->activateClient(member2);
|
|
|
|
QTRY_VERIFY(member2->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{transient, leader, member1, member2}));
|
2018-10-02 05:39:31 +00:00
|
|
|
|
|
|
|
workspace()->activateClient(transient);
|
|
|
|
QTRY_VERIFY(transient->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{leader, member1, member2, transient}));
|
2018-10-02 05:39:31 +00:00
|
|
|
}
|
|
|
|
|
2018-10-16 16:19:17 +00:00
|
|
|
void StackingOrderTest::testKeepAbove()
|
|
|
|
{
|
|
|
|
// This test verifies that "keep-above" windows are kept above other windows.
|
|
|
|
|
|
|
|
// Create the first client.
|
|
|
|
KWayland::Client::Surface *clientASurface =
|
|
|
|
Test::createSurface(Test::waylandCompositor());
|
|
|
|
QVERIFY(clientASurface);
|
2019-08-27 15:01:14 +00:00
|
|
|
KWayland::Client::XdgShellSurface *clientAShellSurface =
|
|
|
|
Test::createXdgShellStableSurface(clientASurface, clientASurface);
|
2018-10-16 16:19:17 +00:00
|
|
|
QVERIFY(clientAShellSurface);
|
2020-03-04 07:55:26 +00:00
|
|
|
AbstractClient *clientA = Test::renderAndWaitForShown(clientASurface, QSize(128, 128), Qt::green);
|
2018-10-16 16:19:17 +00:00
|
|
|
QVERIFY(clientA);
|
|
|
|
QVERIFY(clientA->isActive());
|
|
|
|
QVERIFY(!clientA->keepAbove());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{clientA}));
|
2018-10-16 16:19:17 +00:00
|
|
|
|
|
|
|
// Create the second client.
|
|
|
|
KWayland::Client::Surface *clientBSurface =
|
|
|
|
Test::createSurface(Test::waylandCompositor());
|
|
|
|
QVERIFY(clientBSurface);
|
2019-08-27 15:01:14 +00:00
|
|
|
KWayland::Client::XdgShellSurface *clientBShellSurface =
|
|
|
|
Test::createXdgShellStableSurface(clientBSurface, clientBSurface);
|
2018-10-16 16:19:17 +00:00
|
|
|
QVERIFY(clientBShellSurface);
|
2020-03-04 07:55:26 +00:00
|
|
|
AbstractClient *clientB = Test::renderAndWaitForShown(clientBSurface, QSize(128, 128), Qt::green);
|
2018-10-16 16:19:17 +00:00
|
|
|
QVERIFY(clientB);
|
|
|
|
QVERIFY(clientB->isActive());
|
|
|
|
QVERIFY(!clientB->keepAbove());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{clientA, clientB}));
|
2018-10-16 16:19:17 +00:00
|
|
|
|
|
|
|
// Go to the initial test position.
|
|
|
|
workspace()->activateClient(clientA);
|
|
|
|
QTRY_VERIFY(clientA->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{clientB, clientA}));
|
2018-10-16 16:19:17 +00:00
|
|
|
|
|
|
|
// Set the "keep-above" flag on the client B, it should go above other clients.
|
|
|
|
{
|
|
|
|
StackingUpdatesBlocker blocker(workspace());
|
|
|
|
clientB->setKeepAbove(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
QVERIFY(clientB->keepAbove());
|
|
|
|
QVERIFY(!clientB->isActive());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{clientA, clientB}));
|
2018-10-16 16:19:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void StackingOrderTest::testKeepBelow()
|
|
|
|
{
|
|
|
|
// This test verifies that "keep-below" windows are kept below other windows.
|
|
|
|
|
|
|
|
// Create the first client.
|
|
|
|
KWayland::Client::Surface *clientASurface =
|
|
|
|
Test::createSurface(Test::waylandCompositor());
|
|
|
|
QVERIFY(clientASurface);
|
2019-08-27 15:01:14 +00:00
|
|
|
KWayland::Client::XdgShellSurface *clientAShellSurface =
|
|
|
|
Test::createXdgShellStableSurface(clientASurface, clientASurface);
|
2018-10-16 16:19:17 +00:00
|
|
|
QVERIFY(clientAShellSurface);
|
2020-03-04 07:55:26 +00:00
|
|
|
AbstractClient *clientA = Test::renderAndWaitForShown(clientASurface, QSize(128, 128), Qt::green);
|
2018-10-16 16:19:17 +00:00
|
|
|
QVERIFY(clientA);
|
|
|
|
QVERIFY(clientA->isActive());
|
|
|
|
QVERIFY(!clientA->keepBelow());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{clientA}));
|
2018-10-16 16:19:17 +00:00
|
|
|
|
|
|
|
// Create the second client.
|
|
|
|
KWayland::Client::Surface *clientBSurface =
|
|
|
|
Test::createSurface(Test::waylandCompositor());
|
|
|
|
QVERIFY(clientBSurface);
|
2019-08-27 15:01:14 +00:00
|
|
|
KWayland::Client::XdgShellSurface *clientBShellSurface =
|
|
|
|
Test::createXdgShellStableSurface(clientBSurface, clientBSurface);
|
2018-10-16 16:19:17 +00:00
|
|
|
QVERIFY(clientBShellSurface);
|
2020-03-04 07:55:26 +00:00
|
|
|
AbstractClient *clientB = Test::renderAndWaitForShown(clientBSurface, QSize(128, 128), Qt::green);
|
2018-10-16 16:19:17 +00:00
|
|
|
QVERIFY(clientB);
|
|
|
|
QVERIFY(clientB->isActive());
|
|
|
|
QVERIFY(!clientB->keepBelow());
|
|
|
|
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{clientA, clientB}));
|
2018-10-16 16:19:17 +00:00
|
|
|
|
|
|
|
// Set the "keep-below" flag on the client B, it should go below other clients.
|
|
|
|
{
|
|
|
|
StackingUpdatesBlocker blocker(workspace());
|
|
|
|
clientB->setKeepBelow(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
QVERIFY(clientB->isActive());
|
|
|
|
QVERIFY(clientB->keepBelow());
|
Drop some custom list typedefs
Summary:
Qt has its own thing where a type might also have corresponding list
alias, e.g. QObject and QObjectList, QWidget and QWidgetList. I don't
know why Qt does that, maybe for some historical reasons, but what
matters is that we copy this pattern here in KWin. While this pattern
might be useful with some long list types, for example
QList<QWeakPointer<TabBoxClient>> TabBoxClientList
in general, it causes more harm than good. For example, we've got two
new client types, do we need corresponding list typedefs for them? If
no, why do we have ClientList and so on?
Another problem with these typedefs is that you need to include utils.h
header in order to use them. A better way to handle such things is to
just forward declare a client class (if that's possible) and use it
directly with QList or QVector. This way translation units don't get
"bloated" with utils.h stuff for no apparent reason.
So, in order to make code more consistent and easier to follow, this
change drops some of our custom typedefs. Namely ConstClientList,
ClientList, DeletedList, UnmanagedList, ToplevelList, and GroupList.
Test Plan: Compiles.
Reviewers: #kwin
Subscribers: kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D24950
2019-10-16 09:11:04 +00:00
|
|
|
QCOMPARE(workspace()->stackingOrder(), (QList<Toplevel *>{clientB, clientA}));
|
2018-10-16 16:19:17 +00:00
|
|
|
}
|
|
|
|
|
2018-10-02 05:39:31 +00:00
|
|
|
WAYLANDTEST_MAIN(StackingOrderTest)
|
|
|
|
#include "stacking_order_test.moc"
|