tabbox: Drop TabBoxClient
The indirection contributes unnecessary complexity. The usage of std::weak_ptr and std::shared_ptr complicates the things further, e.g. ![Screenshot_20230325_170226](/uploads/d8b68a9eff47c93c4463bb230b5bbe49/Screenshot_20230325_170226.png) --- Ideally, same should be done with TabBox and TabBoxHandler, but that can be done in another MR.
This commit is contained in:
parent
fc890340d9
commit
c5eabfa4d1
19 changed files with 217 additions and 1062 deletions
|
@ -3,7 +3,6 @@ remove_definitions(-DQT_USE_QSTRINGBUILDER)
|
|||
add_subdirectory(libkwineffects)
|
||||
add_subdirectory(integration)
|
||||
add_subdirectory(libinput)
|
||||
add_subdirectory(tabbox)
|
||||
add_subdirectory(drm)
|
||||
|
||||
########################################################
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
add_definitions(-DKWIN_UNIT_TEST)
|
||||
########################################################
|
||||
# Test TabBox::ClientModel
|
||||
########################################################
|
||||
set(testTabBoxClientModel_SRCS
|
||||
../../src/tabbox/clientmodel.cpp
|
||||
../../src/tabbox/tabbox_logging.cpp
|
||||
../../src/tabbox/tabboxconfig.cpp
|
||||
../../src/tabbox/tabboxhandler.cpp
|
||||
mock_tabboxclient.cpp
|
||||
mock_tabboxhandler.cpp
|
||||
test_tabbox_clientmodel.cpp
|
||||
)
|
||||
|
||||
add_executable(testTabBoxClientModel ${testTabBoxClientModel_SRCS})
|
||||
set_target_properties(testTabBoxClientModel PROPERTIES COMPILE_DEFINITIONS "NO_NONE_WINDOW")
|
||||
target_link_libraries(testTabBoxClientModel
|
||||
Qt::Core
|
||||
Qt::DBus
|
||||
Qt::Quick
|
||||
Qt::Test
|
||||
Qt::Widgets
|
||||
Qt::GuiPrivate
|
||||
|
||||
KF6::ConfigCore
|
||||
KF6::I18n
|
||||
KF6::Package
|
||||
KF6::WindowSystem
|
||||
|
||||
XCB::XCB
|
||||
)
|
||||
add_test(NAME kwin-testTabBoxClientModel COMMAND testTabBoxClientModel)
|
||||
ecm_mark_as_test(testTabBoxClientModel)
|
||||
|
||||
########################################################
|
||||
# Test TabBox::TabBoxHandler
|
||||
########################################################
|
||||
set(testTabBoxHandler_SRCS
|
||||
../../src/tabbox/clientmodel.cpp
|
||||
../../src/tabbox/tabbox_logging.cpp
|
||||
../../src/tabbox/tabboxconfig.cpp
|
||||
../../src/tabbox/tabboxhandler.cpp
|
||||
mock_tabboxclient.cpp
|
||||
mock_tabboxhandler.cpp
|
||||
test_tabbox_handler.cpp
|
||||
)
|
||||
|
||||
add_executable(testTabBoxHandler ${testTabBoxHandler_SRCS})
|
||||
set_target_properties(testTabBoxHandler PROPERTIES COMPILE_DEFINITIONS "NO_NONE_WINDOW")
|
||||
target_link_libraries(testTabBoxHandler
|
||||
Qt::Core
|
||||
Qt::DBus
|
||||
Qt::Quick
|
||||
Qt::Test
|
||||
Qt::Widgets
|
||||
Qt::GuiPrivate
|
||||
|
||||
KF6::ConfigCore
|
||||
KF6::I18n
|
||||
KF6::Package
|
||||
KF6::WindowSystem
|
||||
|
||||
XCB::XCB
|
||||
)
|
||||
add_test(NAME kwin-testTabBoxHandler COMMAND testTabBoxHandler)
|
||||
ecm_mark_as_test(testTabBoxHandler)
|
||||
|
||||
########################################################
|
||||
# Test TabBox::TabBoxConfig
|
||||
########################################################
|
||||
set(testTabBoxConfig_SRCS
|
||||
../../src/tabbox/tabbox_logging.cpp
|
||||
../../src/tabbox/tabboxconfig.cpp
|
||||
test_tabbox_config.cpp
|
||||
)
|
||||
|
||||
add_executable(testTabBoxConfig ${testTabBoxConfig_SRCS})
|
||||
target_link_libraries(testTabBoxConfig Qt::Core Qt::Test)
|
||||
add_test(NAME kwin-testTabBoxConfig COMMAND testTabBoxConfig)
|
||||
ecm_mark_as_test(testTabBoxConfig)
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
SPDX-FileCopyrightText: 2012 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#include "mock_tabboxclient.h"
|
||||
#include "mock_tabboxhandler.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
MockTabBoxClient::MockTabBoxClient(QString caption)
|
||||
: TabBoxClient()
|
||||
, m_caption(caption)
|
||||
{
|
||||
}
|
||||
|
||||
void MockTabBoxClient::close()
|
||||
{
|
||||
static_cast<MockTabBoxHandler *>(TabBox::tabBox)->closeWindow(this);
|
||||
}
|
||||
|
||||
} // namespace KWin
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
SPDX-FileCopyrightText: 2012 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef KWIN_MOCK_TABBOX_CLIENT_H
|
||||
#define KWIN_MOCK_TABBOX_CLIENT_H
|
||||
|
||||
#include "tabbox/tabboxhandler.h"
|
||||
|
||||
#include <QIcon>
|
||||
#include <QUuid>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
class MockTabBoxClient : public TabBox::TabBoxClient
|
||||
{
|
||||
public:
|
||||
explicit MockTabBoxClient(QString caption);
|
||||
bool isMinimized() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
QString caption() const override
|
||||
{
|
||||
return m_caption;
|
||||
}
|
||||
void close() override;
|
||||
int height() const override
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
virtual QPixmap icon(const QSize &size = QSize(32, 32)) const
|
||||
{
|
||||
return QPixmap(size);
|
||||
}
|
||||
bool isCloseable() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
int width() const override
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
int x() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int y() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
QIcon icon() const override
|
||||
{
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
QUuid internalId() const override
|
||||
{
|
||||
return QUuid{};
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_caption;
|
||||
};
|
||||
} // namespace KWin
|
||||
#endif
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
SPDX-FileCopyrightText: 2012 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#include "mock_tabboxhandler.h"
|
||||
#include "mock_tabboxclient.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
MockTabBoxHandler::MockTabBoxHandler(QObject *parent)
|
||||
: TabBoxHandler(parent)
|
||||
{
|
||||
}
|
||||
|
||||
MockTabBoxHandler::~MockTabBoxHandler()
|
||||
{
|
||||
}
|
||||
|
||||
void MockTabBoxHandler::grabbedKeyEvent(QKeyEvent *event) const
|
||||
{
|
||||
}
|
||||
|
||||
std::weak_ptr<TabBox::TabBoxClient> MockTabBoxHandler::activeClient() const
|
||||
{
|
||||
return m_activeClient;
|
||||
}
|
||||
|
||||
void MockTabBoxHandler::setActiveClient(const std::weak_ptr<TabBox::TabBoxClient> &client)
|
||||
{
|
||||
m_activeClient = client;
|
||||
}
|
||||
|
||||
std::weak_ptr<TabBox::TabBoxClient> MockTabBoxHandler::clientToAddToList(TabBox::TabBoxClient *client, int desktop) const
|
||||
{
|
||||
QList<std::shared_ptr<TabBox::TabBoxClient>>::const_iterator it = m_windows.constBegin();
|
||||
for (; it != m_windows.constEnd(); ++it) {
|
||||
if ((*it).get() == client) {
|
||||
return std::weak_ptr<TabBox::TabBoxClient>(*it);
|
||||
}
|
||||
}
|
||||
return std::weak_ptr<TabBox::TabBoxClient>();
|
||||
}
|
||||
|
||||
std::weak_ptr<TabBox::TabBoxClient> MockTabBoxHandler::nextClientFocusChain(TabBox::TabBoxClient *client) const
|
||||
{
|
||||
QList<std::shared_ptr<TabBox::TabBoxClient>>::const_iterator it = m_windows.constBegin();
|
||||
for (; it != m_windows.constEnd(); ++it) {
|
||||
if ((*it).get() == client) {
|
||||
++it;
|
||||
if (it == m_windows.constEnd()) {
|
||||
return std::weak_ptr<TabBox::TabBoxClient>(m_windows.first());
|
||||
} else {
|
||||
return std::weak_ptr<TabBox::TabBoxClient>(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!m_windows.isEmpty()) {
|
||||
return std::weak_ptr<TabBox::TabBoxClient>(m_windows.last());
|
||||
}
|
||||
return std::weak_ptr<TabBox::TabBoxClient>();
|
||||
}
|
||||
|
||||
std::weak_ptr<TabBox::TabBoxClient> MockTabBoxHandler::firstClientFocusChain() const
|
||||
{
|
||||
if (m_windows.isEmpty()) {
|
||||
return std::weak_ptr<TabBox::TabBoxClient>();
|
||||
}
|
||||
return m_windows.first();
|
||||
}
|
||||
|
||||
bool MockTabBoxHandler::isInFocusChain(TabBox::TabBoxClient *client) const
|
||||
{
|
||||
if (!client) {
|
||||
return false;
|
||||
}
|
||||
QList<std::shared_ptr<TabBox::TabBoxClient>>::const_iterator it = m_windows.constBegin();
|
||||
for (; it != m_windows.constEnd(); ++it) {
|
||||
if ((*it).get() == client) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::weak_ptr<TabBox::TabBoxClient> MockTabBoxHandler::createMockWindow(const QString &caption)
|
||||
{
|
||||
std::shared_ptr<TabBox::TabBoxClient> client(new MockTabBoxClient(caption));
|
||||
m_windows.append(client);
|
||||
m_activeClient = client;
|
||||
return std::weak_ptr<TabBox::TabBoxClient>(client);
|
||||
}
|
||||
|
||||
void MockTabBoxHandler::closeWindow(TabBox::TabBoxClient *client)
|
||||
{
|
||||
QList<std::shared_ptr<TabBox::TabBoxClient>>::iterator it = m_windows.begin();
|
||||
for (; it != m_windows.end(); ++it) {
|
||||
if ((*it).get() == client) {
|
||||
m_windows.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace KWin
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
SPDX-FileCopyrightText: 2012 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef KWIN_MOCK_TABBOX_HANDLER_H
|
||||
#define KWIN_MOCK_TABBOX_HANDLER_H
|
||||
|
||||
#include "tabbox/tabboxhandler.h"
|
||||
namespace KWin
|
||||
{
|
||||
class MockTabBoxHandler : public TabBox::TabBoxHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MockTabBoxHandler(QObject *parent = nullptr);
|
||||
~MockTabBoxHandler() override;
|
||||
void activateAndClose() override
|
||||
{
|
||||
}
|
||||
std::weak_ptr<TabBox::TabBoxClient> activeClient() const override;
|
||||
void setActiveClient(const std::weak_ptr<TabBox::TabBoxClient> &client);
|
||||
int activeScreen() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
std::weak_ptr<TabBox::TabBoxClient> clientToAddToList(TabBox::TabBoxClient *client, int desktop) const override;
|
||||
int currentDesktop() const override
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
std::weak_ptr<TabBox::TabBoxClient> desktopClient() const override
|
||||
{
|
||||
return std::weak_ptr<TabBox::TabBoxClient>();
|
||||
}
|
||||
QString desktopName(TabBox::TabBoxClient *client) const override
|
||||
{
|
||||
return "desktop";
|
||||
}
|
||||
void elevateClient(TabBox::TabBoxClient *c, QWindow *tabbox, bool elevate) const override
|
||||
{
|
||||
}
|
||||
void shadeClient(TabBox::TabBoxClient *c, bool b) const override
|
||||
{
|
||||
}
|
||||
virtual void hideOutline()
|
||||
{
|
||||
}
|
||||
std::weak_ptr<TabBox::TabBoxClient> nextClientFocusChain(TabBox::TabBoxClient *client) const override;
|
||||
std::weak_ptr<TabBox::TabBoxClient> firstClientFocusChain() const override;
|
||||
bool isInFocusChain(TabBox::TabBoxClient *client) const override;
|
||||
bool isKWinCompositing() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
void raiseClient(TabBox::TabBoxClient *c) const override
|
||||
{
|
||||
}
|
||||
void restack(TabBox::TabBoxClient *c, TabBox::TabBoxClient *under) override
|
||||
{
|
||||
}
|
||||
virtual void showOutline(const QRect &outline)
|
||||
{
|
||||
}
|
||||
TabBox::TabBoxClientList stackingOrder() const override
|
||||
{
|
||||
return TabBox::TabBoxClientList();
|
||||
}
|
||||
void grabbedKeyEvent(QKeyEvent *event) const override;
|
||||
|
||||
void highlightWindows(TabBox::TabBoxClient *window = nullptr, QWindow *controller = nullptr) override
|
||||
{
|
||||
}
|
||||
|
||||
bool noModifierGrab() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// mock methods
|
||||
std::weak_ptr<TabBox::TabBoxClient> createMockWindow(const QString &caption);
|
||||
void closeWindow(TabBox::TabBoxClient *client);
|
||||
|
||||
private:
|
||||
QList<std::shared_ptr<TabBox::TabBoxClient>> m_windows;
|
||||
std::weak_ptr<TabBox::TabBoxClient> m_activeClient;
|
||||
};
|
||||
} // namespace KWin
|
||||
#endif
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
SPDX-FileCopyrightText: 2012 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#include "test_tabbox_clientmodel.h"
|
||||
#include "../testutils.h"
|
||||
#include "mock_tabboxhandler.h"
|
||||
#include "tabbox/clientmodel.h"
|
||||
|
||||
#include <QtTest>
|
||||
#include <private/qtx11extras_p.h>
|
||||
|
||||
using namespace KWin;
|
||||
|
||||
void TestTabBoxClientModel::initTestCase()
|
||||
{
|
||||
qApp->setProperty("x11Connection", QVariant::fromValue<void *>(QX11Info::connection()));
|
||||
}
|
||||
|
||||
void TestTabBoxClientModel::testLongestCaptionWithNullClient()
|
||||
{
|
||||
MockTabBoxHandler tabboxhandler;
|
||||
TabBox::ClientModel *clientModel = new TabBox::ClientModel(&tabboxhandler);
|
||||
clientModel->createClientList();
|
||||
QCOMPARE(clientModel->longestCaption(), QString());
|
||||
// add a window to the mock
|
||||
tabboxhandler.createMockWindow(QString("test"));
|
||||
clientModel->createClientList();
|
||||
QCOMPARE(clientModel->longestCaption(), QString("test"));
|
||||
// delete the one client in the list
|
||||
QModelIndex index = clientModel->index(0, 0);
|
||||
QVERIFY(index.isValid());
|
||||
TabBox::TabBoxClient *client = static_cast<TabBox::TabBoxClient *>(clientModel->data(index, TabBox::ClientModel::ClientRole).value<void *>());
|
||||
client->close();
|
||||
// internal model of ClientModel now contains a deleted pointer
|
||||
// longestCaption should behave just as if the window were not in the list
|
||||
QCOMPARE(clientModel->longestCaption(), QString());
|
||||
}
|
||||
|
||||
void TestTabBoxClientModel::testCreateClientListNoActiveClient()
|
||||
{
|
||||
MockTabBoxHandler tabboxhandler;
|
||||
tabboxhandler.setConfig(TabBox::TabBoxConfig());
|
||||
TabBox::ClientModel *clientModel = new TabBox::ClientModel(&tabboxhandler);
|
||||
clientModel->createClientList();
|
||||
QCOMPARE(clientModel->rowCount(), 0);
|
||||
// create two windows, rowCount() should go to two
|
||||
std::weak_ptr<TabBox::TabBoxClient> client = tabboxhandler.createMockWindow(QString("test"));
|
||||
tabboxhandler.createMockWindow(QString("test2"));
|
||||
clientModel->createClientList();
|
||||
QCOMPARE(clientModel->rowCount(), 2);
|
||||
// let's ensure there is no active client
|
||||
tabboxhandler.setActiveClient(std::weak_ptr<TabBox::TabBoxClient>());
|
||||
// now it should still have two members in the list
|
||||
clientModel->createClientList();
|
||||
QCOMPARE(clientModel->rowCount(), 2);
|
||||
}
|
||||
|
||||
void TestTabBoxClientModel::testCreateClientListActiveClientNotInFocusChain()
|
||||
{
|
||||
MockTabBoxHandler tabboxhandler;
|
||||
tabboxhandler.setConfig(TabBox::TabBoxConfig());
|
||||
TabBox::ClientModel *clientModel = new TabBox::ClientModel(&tabboxhandler);
|
||||
// create two windows, rowCount() should go to two
|
||||
std::weak_ptr<TabBox::TabBoxClient> client = tabboxhandler.createMockWindow(QString("test"));
|
||||
client = tabboxhandler.createMockWindow(QString("test2"));
|
||||
clientModel->createClientList();
|
||||
QCOMPARE(clientModel->rowCount(), 2);
|
||||
|
||||
// simulate that the active client is not in the focus chain
|
||||
// for that we use the closeWindow of the MockTabBoxHandler which
|
||||
// removes the Client from the Focus Chain but leaves the active window as it is
|
||||
std::shared_ptr<TabBox::TabBoxClient> clientOwner = client.lock();
|
||||
tabboxhandler.closeWindow(clientOwner.get());
|
||||
clientModel->createClientList();
|
||||
QCOMPARE(clientModel->rowCount(), 1);
|
||||
}
|
||||
|
||||
Q_CONSTRUCTOR_FUNCTION(forceXcb)
|
||||
QTEST_MAIN(TestTabBoxClientModel)
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
SPDX-FileCopyrightText: 2012 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef TEST_TABBOX_CLIENT_MODEL_H
|
||||
#define TEST_TABBOX_CLIENT_MODEL_H
|
||||
#include <QObject>
|
||||
|
||||
class TestTabBoxClientModel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
/**
|
||||
* Tests that calculating the longest caption does not
|
||||
* crash in case the internal m_clientList contains a weak
|
||||
* pointer to a deleted TabBoxClient.
|
||||
*
|
||||
* See bug #303840
|
||||
*/
|
||||
void testLongestCaptionWithNullClient();
|
||||
/**
|
||||
* Tests the creation of the Client list for the case that
|
||||
* there is no active Client, but that Clients actually exist.
|
||||
*
|
||||
* See BUG: 305449
|
||||
*/
|
||||
void testCreateClientListNoActiveClient();
|
||||
/**
|
||||
* Tests the creation of the Client list for the case that
|
||||
* the active Client is not in the Focus chain.
|
||||
*
|
||||
* See BUG: 306260
|
||||
*/
|
||||
void testCreateClientListActiveClientNotInFocusChain();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
SPDX-FileCopyrightText: 2012 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#include "tabbox/tabboxconfig.h"
|
||||
#include <QtTest>
|
||||
using namespace KWin;
|
||||
using namespace KWin::TabBox;
|
||||
|
||||
class TestTabBoxConfig : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private Q_SLOTS:
|
||||
void testDefaultCtor();
|
||||
void testAssignmentOperator();
|
||||
};
|
||||
|
||||
void TestTabBoxConfig::testDefaultCtor()
|
||||
{
|
||||
TabBoxConfig config;
|
||||
QCOMPARE(config.isShowTabBox(), TabBoxConfig::defaultShowTabBox());
|
||||
QCOMPARE(config.isHighlightWindows(), TabBoxConfig::defaultHighlightWindow());
|
||||
QCOMPARE(config.clientDesktopMode(), TabBoxConfig::defaultDesktopMode());
|
||||
QCOMPARE(config.clientActivitiesMode(), TabBoxConfig::defaultActivitiesMode());
|
||||
QCOMPARE(config.clientApplicationsMode(), TabBoxConfig::defaultApplicationsMode());
|
||||
QCOMPARE(config.orderMinimizedMode(), TabBoxConfig::defaultOrderMinimizedMode());
|
||||
QCOMPARE(config.clientMinimizedMode(), TabBoxConfig::defaultMinimizedMode());
|
||||
QCOMPARE(config.showDesktopMode(), TabBoxConfig::defaultShowDesktopMode());
|
||||
QCOMPARE(config.clientMultiScreenMode(), TabBoxConfig::defaultMultiScreenMode());
|
||||
QCOMPARE(config.clientSwitchingMode(), TabBoxConfig::defaultSwitchingMode());
|
||||
QCOMPARE(config.layoutName(), TabBoxConfig::defaultLayoutName());
|
||||
}
|
||||
|
||||
void TestTabBoxConfig::testAssignmentOperator()
|
||||
{
|
||||
TabBoxConfig config;
|
||||
// changing all values of the config object
|
||||
config.setShowTabBox(!TabBoxConfig::defaultShowTabBox());
|
||||
config.setHighlightWindows(!TabBoxConfig::defaultHighlightWindow());
|
||||
config.setClientDesktopMode(TabBoxConfig::AllDesktopsClients);
|
||||
config.setClientActivitiesMode(TabBoxConfig::AllActivitiesClients);
|
||||
config.setClientApplicationsMode(TabBoxConfig::OneWindowPerApplication);
|
||||
config.setOrderMinimizedMode(TabBoxConfig::GroupByMinimized);
|
||||
config.setClientMinimizedMode(TabBoxConfig::ExcludeMinimizedClients);
|
||||
config.setShowDesktopMode(TabBoxConfig::ShowDesktopClient);
|
||||
config.setClientMultiScreenMode(TabBoxConfig::ExcludeCurrentScreenClients);
|
||||
config.setClientSwitchingMode(TabBoxConfig::StackingOrderSwitching);
|
||||
config.setLayoutName(QStringLiteral("grid"));
|
||||
TabBoxConfig config2;
|
||||
config2 = config;
|
||||
// verify the config2 values
|
||||
QCOMPARE(config2.isShowTabBox(), !TabBoxConfig::defaultShowTabBox());
|
||||
QCOMPARE(config2.isHighlightWindows(), !TabBoxConfig::defaultHighlightWindow());
|
||||
QCOMPARE(config2.clientDesktopMode(), TabBoxConfig::AllDesktopsClients);
|
||||
QCOMPARE(config2.clientActivitiesMode(), TabBoxConfig::AllActivitiesClients);
|
||||
QCOMPARE(config2.clientApplicationsMode(), TabBoxConfig::OneWindowPerApplication);
|
||||
QCOMPARE(config2.orderMinimizedMode(), TabBoxConfig::GroupByMinimized);
|
||||
QCOMPARE(config2.clientMinimizedMode(), TabBoxConfig::ExcludeMinimizedClients);
|
||||
QCOMPARE(config2.showDesktopMode(), TabBoxConfig::ShowDesktopClient);
|
||||
QCOMPARE(config2.clientMultiScreenMode(), TabBoxConfig::ExcludeCurrentScreenClients);
|
||||
QCOMPARE(config2.clientSwitchingMode(), TabBoxConfig::StackingOrderSwitching);
|
||||
QCOMPARE(config2.layoutName(), QStringLiteral("grid"));
|
||||
}
|
||||
|
||||
QTEST_MAIN(TestTabBoxConfig)
|
||||
|
||||
#include "test_tabbox_config.moc"
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
SPDX-FileCopyrightText: 2012 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#include "../testutils.h"
|
||||
#include "mock_tabboxhandler.h"
|
||||
#include "tabbox/clientmodel.h"
|
||||
#include <QtTest>
|
||||
#include <private/qtx11extras_p.h>
|
||||
|
||||
using namespace KWin;
|
||||
|
||||
class TestTabBoxHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
/**
|
||||
* Test to verify that update outline does not crash
|
||||
* if the ModelIndex for which the outline should be
|
||||
* shown is not valid. That is accessing the Pointer
|
||||
* to the Client returns an invalid QVariant.
|
||||
* BUG: 304620
|
||||
*/
|
||||
void testDontCrashUpdateOutlineNullClient();
|
||||
};
|
||||
|
||||
void TestTabBoxHandler::initTestCase()
|
||||
{
|
||||
qApp->setProperty("x11Connection", QVariant::fromValue<void *>(QX11Info::connection()));
|
||||
}
|
||||
|
||||
void TestTabBoxHandler::testDontCrashUpdateOutlineNullClient()
|
||||
{
|
||||
MockTabBoxHandler tabboxhandler;
|
||||
TabBox::TabBoxConfig config;
|
||||
config.setShowTabBox(false);
|
||||
config.setHighlightWindows(false);
|
||||
tabboxhandler.setConfig(config);
|
||||
// now show the tabbox which will attempt to show the outline
|
||||
tabboxhandler.show();
|
||||
}
|
||||
|
||||
Q_CONSTRUCTOR_FUNCTION(forceXcb)
|
||||
QTEST_MAIN(TestTabBoxHandler)
|
||||
|
||||
#include "test_tabbox_handler.moc"
|
|
@ -7,16 +7,16 @@
|
|||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
// own
|
||||
#include "clientmodel.h"
|
||||
// tabbox
|
||||
#include "tabboxconfig.h"
|
||||
// Qt
|
||||
#include "window.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <QIcon>
|
||||
#include <QTextDocument> // TODO: remove with Qt 5, only for HTML escaping the caption
|
||||
#include <QUuid>
|
||||
// TODO: remove with Qt 5, only for HTML escaping the caption
|
||||
#include <QTextDocument>
|
||||
// other
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace KWin
|
||||
|
@ -47,13 +47,17 @@ QVariant ClientModel::data(const QModelIndex &index, int role) const
|
|||
if (clientIndex >= m_clientList.count()) {
|
||||
return QVariant();
|
||||
}
|
||||
std::shared_ptr<TabBoxClient> client = m_clientList[clientIndex].lock();
|
||||
Window *client = m_clientList[clientIndex];
|
||||
if (!client) {
|
||||
return QVariant();
|
||||
}
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
case CaptionRole: {
|
||||
if (client->isDesktop()) {
|
||||
return i18nc("Special entry in alt+tab list for minimizing all windows",
|
||||
"Show Desktop");
|
||||
}
|
||||
QString caption = client->caption();
|
||||
if (Qt::mightBeRichText(caption)) {
|
||||
caption = caption.toHtmlEscaped();
|
||||
|
@ -61,9 +65,9 @@ QVariant ClientModel::data(const QModelIndex &index, int role) const
|
|||
return caption;
|
||||
}
|
||||
case ClientRole:
|
||||
return QVariant::fromValue<void *>(client.get());
|
||||
return QVariant::fromValue<void *>(client);
|
||||
case DesktopNameRole: {
|
||||
return tabBox->desktopName(client.get());
|
||||
return tabBox->desktopName(client);
|
||||
}
|
||||
case WIdRole:
|
||||
return client->internalId();
|
||||
|
@ -72,6 +76,9 @@ QVariant ClientModel::data(const QModelIndex &index, int role) const
|
|||
case CloseableRole:
|
||||
return client->isCloseable();
|
||||
case IconRole:
|
||||
if (client->isDesktop()) {
|
||||
return QIcon::fromTheme(QStringLiteral("user-desktop"));
|
||||
}
|
||||
return client->icon();
|
||||
default:
|
||||
return QVariant();
|
||||
|
@ -81,13 +88,9 @@ QVariant ClientModel::data(const QModelIndex &index, int role) const
|
|||
QString ClientModel::longestCaption() const
|
||||
{
|
||||
QString caption;
|
||||
for (const std::weak_ptr<TabBoxClient> &clientPointer : std::as_const(m_clientList)) {
|
||||
std::shared_ptr<TabBoxClient> client = clientPointer.lock();
|
||||
if (!client) {
|
||||
continue;
|
||||
}
|
||||
if (client->caption().size() > caption.size()) {
|
||||
caption = client->caption();
|
||||
for (Window *window : std::as_const(m_clientList)) {
|
||||
if (window->caption().size() > caption.size()) {
|
||||
caption = window->caption();
|
||||
}
|
||||
}
|
||||
return caption;
|
||||
|
@ -135,15 +138,12 @@ QHash<int, QByteArray> ClientModel::roleNames() const
|
|||
};
|
||||
}
|
||||
|
||||
QModelIndex ClientModel::index(std::weak_ptr<TabBoxClient> client) const
|
||||
QModelIndex ClientModel::index(Window *client) const
|
||||
{
|
||||
const auto it = std::find_if(m_clientList.cbegin(), m_clientList.cend(), [c = client.lock()](auto &client) {
|
||||
return client.lock() == c;
|
||||
});
|
||||
if (it == m_clientList.cend()) {
|
||||
const int index = m_clientList.indexOf(client);
|
||||
if (index == -1) {
|
||||
return QModelIndex();
|
||||
}
|
||||
int index = std::distance(m_clientList.cbegin(), it);
|
||||
int row = index / columnCount();
|
||||
int column = index % columnCount();
|
||||
return createIndex(row, column);
|
||||
|
@ -154,40 +154,37 @@ void ClientModel::createClientList(bool partialReset)
|
|||
createClientList(tabBox->currentDesktop(), partialReset);
|
||||
}
|
||||
|
||||
void ClientModel::createFocusChainClientList(int desktop, const std::shared_ptr<TabBoxClient> &start)
|
||||
void ClientModel::createFocusChainClientList(int desktop, Window *start)
|
||||
{
|
||||
auto c = start;
|
||||
if (!tabBox->isInFocusChain(c.get())) {
|
||||
std::shared_ptr<TabBoxClient> firstClient = tabBox->firstClientFocusChain().lock();
|
||||
if (!tabBox->isInFocusChain(c)) {
|
||||
Window *firstClient = tabBox->firstClientFocusChain();
|
||||
if (firstClient) {
|
||||
c = firstClient;
|
||||
}
|
||||
}
|
||||
auto stop = c;
|
||||
do {
|
||||
std::shared_ptr<TabBoxClient> add = tabBox->clientToAddToList(c.get(), desktop).lock();
|
||||
Window *add = tabBox->clientToAddToList(c, desktop);
|
||||
if (add) {
|
||||
m_mutableClientList += add;
|
||||
}
|
||||
c = tabBox->nextClientFocusChain(c.get()).lock();
|
||||
c = tabBox->nextClientFocusChain(c);
|
||||
} while (c && c != stop);
|
||||
}
|
||||
|
||||
void ClientModel::createStackingOrderClientList(int desktop, const std::shared_ptr<TabBoxClient> &start)
|
||||
void ClientModel::createStackingOrderClientList(int desktop, Window *start)
|
||||
{
|
||||
// TODO: needs improvement
|
||||
const TabBoxClientList stacking = tabBox->stackingOrder();
|
||||
auto c = stacking.first().lock();
|
||||
const QList<Window *> stacking = tabBox->stackingOrder();
|
||||
auto c = stacking.first();
|
||||
auto stop = c;
|
||||
int index = 0;
|
||||
while (c) {
|
||||
std::shared_ptr<TabBoxClient> add = tabBox->clientToAddToList(c.get(), desktop).lock();
|
||||
Window *add = tabBox->clientToAddToList(c, desktop);
|
||||
if (add) {
|
||||
if (start == add) {
|
||||
m_mutableClientList.erase(std::remove_if(m_mutableClientList.begin(), m_mutableClientList.end(), [&add](auto &client) {
|
||||
return client.lock() == add;
|
||||
}),
|
||||
m_mutableClientList.end());
|
||||
m_mutableClientList.removeAll(add);
|
||||
m_mutableClientList.prepend(add);
|
||||
} else {
|
||||
m_mutableClientList += add;
|
||||
|
@ -196,7 +193,7 @@ void ClientModel::createStackingOrderClientList(int desktop, const std::shared_p
|
|||
if (index >= stacking.size() - 1) {
|
||||
c = nullptr;
|
||||
} else {
|
||||
c = stacking[++index].lock();
|
||||
c = stacking[++index];
|
||||
}
|
||||
|
||||
if (c == stop) {
|
||||
|
@ -207,10 +204,10 @@ void ClientModel::createStackingOrderClientList(int desktop, const std::shared_p
|
|||
|
||||
void ClientModel::createClientList(int desktop, bool partialReset)
|
||||
{
|
||||
auto start = tabBox->activeClient().lock();
|
||||
auto start = tabBox->activeClient();
|
||||
// TODO: new clients are not added at correct position
|
||||
if (partialReset && !m_mutableClientList.isEmpty()) {
|
||||
std::shared_ptr<TabBoxClient> firstClient = m_mutableClientList.constFirst().lock();
|
||||
Window *firstClient = m_mutableClientList.constFirst();
|
||||
if (firstClient) {
|
||||
start = firstClient;
|
||||
}
|
||||
|
@ -232,23 +229,19 @@ void ClientModel::createClientList(int desktop, bool partialReset)
|
|||
if (tabBox->config().orderMinimizedMode() == TabBoxConfig::GroupByMinimized) {
|
||||
// Put all non-minimized included clients first.
|
||||
std::stable_partition(m_mutableClientList.begin(), m_mutableClientList.end(), [](const auto &client) {
|
||||
return !client.lock()->isMinimized();
|
||||
return !client->isMinimized();
|
||||
});
|
||||
}
|
||||
|
||||
if (tabBox->config().clientApplicationsMode() != TabBoxConfig::AllWindowsCurrentApplication
|
||||
&& (tabBox->config().showDesktopMode() == TabBoxConfig::ShowDesktopClient || m_mutableClientList.isEmpty())) {
|
||||
std::weak_ptr<TabBoxClient> desktopClient = tabBox->desktopClient();
|
||||
if (!desktopClient.expired()) {
|
||||
Window *desktopClient = tabBox->desktopClient();
|
||||
if (desktopClient) {
|
||||
m_mutableClientList.append(desktopClient);
|
||||
}
|
||||
}
|
||||
|
||||
bool equal = m_clientList.size() == m_mutableClientList.size();
|
||||
for (int i = 0; i < m_clientList.size() && equal; i++) {
|
||||
equal &= m_clientList[i].lock() == m_mutableClientList[i].lock();
|
||||
}
|
||||
if (equal) {
|
||||
if (m_clientList == m_mutableClientList) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -263,9 +256,9 @@ void ClientModel::close(int i)
|
|||
if (!ind.isValid()) {
|
||||
return;
|
||||
}
|
||||
std::shared_ptr<TabBoxClient> client = m_mutableClientList.at(i).lock();
|
||||
Window *client = m_mutableClientList.at(i);
|
||||
if (client) {
|
||||
client->close();
|
||||
client->closeWindow();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include <QModelIndex>
|
||||
/**
|
||||
* @file
|
||||
* This file defines the class ClientModel, the model for TabBoxClients.
|
||||
* This file defines the class ClientModel, the model for Windows.
|
||||
*
|
||||
* @author Martin Gräßlin <mgraesslin@kde.org>
|
||||
* @since 4.4
|
||||
|
@ -25,7 +25,7 @@ namespace TabBox
|
|||
{
|
||||
|
||||
/**
|
||||
* The model for TabBoxClients used in TabBox.
|
||||
* The model for Windows used in TabBox.
|
||||
*
|
||||
* @author Martin Gräßlin <mgraesslin@kde.org>
|
||||
* @since 4.4
|
||||
|
@ -36,13 +36,13 @@ class ClientModel
|
|||
Q_OBJECT
|
||||
public:
|
||||
enum {
|
||||
ClientRole = Qt::UserRole, ///< The TabBoxClient
|
||||
CaptionRole = Qt::UserRole + 1, ///< The caption of TabBoxClient
|
||||
DesktopNameRole = Qt::UserRole + 2, ///< The name of the desktop the TabBoxClient is on
|
||||
ClientRole = Qt::UserRole, ///< The Window
|
||||
CaptionRole = Qt::UserRole + 1, ///< The caption of Window
|
||||
DesktopNameRole = Qt::UserRole + 2, ///< The name of the desktop the Window is on
|
||||
IconRole = Qt::UserRole + 3, // TODO: to be removed
|
||||
WIdRole = Qt::UserRole + 5, ///< The window ID of TabBoxClient
|
||||
MinimizedRole = Qt::UserRole + 6, ///< TabBoxClient is minimized
|
||||
CloseableRole = Qt::UserRole + 7 ///< TabBoxClient can be closed
|
||||
WIdRole = Qt::UserRole + 5, ///< The window ID of Window
|
||||
MinimizedRole = Qt::UserRole + 6, ///< Window is minimized
|
||||
CloseableRole = Qt::UserRole + 7 ///< Window can be closed
|
||||
};
|
||||
explicit ClientModel(QObject *parent = nullptr);
|
||||
~ClientModel() override;
|
||||
|
@ -55,14 +55,14 @@ public:
|
|||
Q_INVOKABLE QString longestCaption() const;
|
||||
|
||||
/**
|
||||
* @param client The TabBoxClient whose index should be returned
|
||||
* @return Returns the ModelIndex of given TabBoxClient or an invalid ModelIndex
|
||||
* if the model does not contain the given TabBoxClient.
|
||||
* @param client The Window whose index should be returned
|
||||
* @return Returns the ModelIndex of given Window or an invalid ModelIndex
|
||||
* if the model does not contain the given Window.
|
||||
*/
|
||||
QModelIndex index(std::weak_ptr<TabBoxClient> client) const;
|
||||
QModelIndex index(Window *client) const;
|
||||
|
||||
/**
|
||||
* Generates a new list of TabBoxClients based on the current config.
|
||||
* Generates a new list of Windows based on the current config.
|
||||
* Calling this method will reset the model. If partialReset is true
|
||||
* the top of the list is kept as a starting point. If not the
|
||||
* current active client is used as the starting point to generate the
|
||||
|
@ -77,9 +77,9 @@ public:
|
|||
*/
|
||||
void createClientList(bool partialReset = false);
|
||||
/**
|
||||
* @return Returns the current list of TabBoxClients.
|
||||
* @return Returns the current list of Windows.
|
||||
*/
|
||||
TabBoxClientList clientList() const
|
||||
QList<Window *> clientList() const
|
||||
{
|
||||
return m_mutableClientList;
|
||||
}
|
||||
|
@ -93,11 +93,11 @@ public Q_SLOTS:
|
|||
void activate(int index);
|
||||
|
||||
private:
|
||||
void createFocusChainClientList(int desktop, const std::shared_ptr<TabBoxClient> &start);
|
||||
void createStackingOrderClientList(int desktop, const std::shared_ptr<TabBoxClient> &start);
|
||||
void createFocusChainClientList(int desktop, Window *start);
|
||||
void createStackingOrderClientList(int desktop, Window *start);
|
||||
|
||||
TabBoxClientList m_clientList;
|
||||
TabBoxClientList m_mutableClientList;
|
||||
QList<Window *> m_clientList;
|
||||
QList<Window *> m_mutableClientList;
|
||||
};
|
||||
|
||||
} // namespace Tabbox
|
||||
|
|
|
@ -77,106 +77,81 @@ int TabBoxHandlerImpl::currentDesktop() const
|
|||
return VirtualDesktopManager::self()->current();
|
||||
}
|
||||
|
||||
QString TabBoxHandlerImpl::desktopName(TabBoxClient *client) const
|
||||
QString TabBoxHandlerImpl::desktopName(Window *client) const
|
||||
{
|
||||
if (TabBoxClientImpl *c = static_cast<TabBoxClientImpl *>(client)) {
|
||||
if (!c->client()->isOnAllDesktops()) {
|
||||
return VirtualDesktopManager::self()->desktopForX11Id(c->client()->desktop())->name();
|
||||
}
|
||||
if (!client->isOnAllDesktops()) {
|
||||
return client->desktops().last()->name();
|
||||
}
|
||||
return VirtualDesktopManager::self()->currentDesktop()->name();
|
||||
}
|
||||
|
||||
std::weak_ptr<TabBoxClient> TabBoxHandlerImpl::nextClientFocusChain(TabBoxClient *client) const
|
||||
Window *TabBoxHandlerImpl::nextClientFocusChain(Window *client) const
|
||||
{
|
||||
if (TabBoxClientImpl *c = static_cast<TabBoxClientImpl *>(client)) {
|
||||
auto next = Workspace::self()->focusChain()->nextMostRecentlyUsed(c->client());
|
||||
if (next) {
|
||||
return std::static_pointer_cast<TabBoxClientImpl>(next->tabBoxClient().lock());
|
||||
}
|
||||
}
|
||||
return std::weak_ptr<TabBoxClient>();
|
||||
return Workspace::self()->focusChain()->nextMostRecentlyUsed(client);
|
||||
}
|
||||
|
||||
std::weak_ptr<TabBoxClient> TabBoxHandlerImpl::firstClientFocusChain() const
|
||||
Window *TabBoxHandlerImpl::firstClientFocusChain() const
|
||||
{
|
||||
if (auto c = Workspace::self()->focusChain()->firstMostRecentlyUsed()) {
|
||||
return std::static_pointer_cast<TabBoxClientImpl>(c->tabBoxClient().lock());
|
||||
} else {
|
||||
return std::weak_ptr<TabBoxClient>();
|
||||
}
|
||||
return Workspace::self()->focusChain()->firstMostRecentlyUsed();
|
||||
}
|
||||
|
||||
bool TabBoxHandlerImpl::isInFocusChain(TabBoxClient *client) const
|
||||
bool TabBoxHandlerImpl::isInFocusChain(Window *client) const
|
||||
{
|
||||
if (TabBoxClientImpl *c = static_cast<TabBoxClientImpl *>(client)) {
|
||||
return Workspace::self()->focusChain()->contains(c->client());
|
||||
}
|
||||
return false;
|
||||
return Workspace::self()->focusChain()->contains(client);
|
||||
}
|
||||
|
||||
std::weak_ptr<TabBoxClient> TabBoxHandlerImpl::activeClient() const
|
||||
Window *TabBoxHandlerImpl::activeClient() const
|
||||
{
|
||||
if (Workspace::self()->activeWindow()) {
|
||||
return std::static_pointer_cast<TabBoxClientImpl>(Workspace::self()->activeWindow()->tabBoxClient().lock());
|
||||
} else {
|
||||
return std::weak_ptr<TabBoxClient>();
|
||||
}
|
||||
return Workspace::self()->activeWindow();
|
||||
}
|
||||
|
||||
bool TabBoxHandlerImpl::checkDesktop(TabBoxClient *client, int desktop) const
|
||||
bool TabBoxHandlerImpl::checkDesktop(Window *client, int desktop) const
|
||||
{
|
||||
auto current = (static_cast<TabBoxClientImpl *>(client))->client();
|
||||
|
||||
switch (config().clientDesktopMode()) {
|
||||
case TabBoxConfig::AllDesktopsClients:
|
||||
return true;
|
||||
case TabBoxConfig::ExcludeCurrentDesktopClients:
|
||||
return !current->isOnDesktop(desktop);
|
||||
return !client->isOnDesktop(desktop);
|
||||
default: // TabBoxConfig::OnlyCurrentDesktopClients
|
||||
return current->isOnDesktop(desktop);
|
||||
return client->isOnDesktop(desktop);
|
||||
}
|
||||
}
|
||||
|
||||
bool TabBoxHandlerImpl::checkActivity(TabBoxClient *client) const
|
||||
bool TabBoxHandlerImpl::checkActivity(Window *client) const
|
||||
{
|
||||
auto current = (static_cast<TabBoxClientImpl *>(client))->client();
|
||||
|
||||
switch (config().clientActivitiesMode()) {
|
||||
case TabBoxConfig::AllActivitiesClients:
|
||||
return true;
|
||||
case TabBoxConfig::ExcludeCurrentActivityClients:
|
||||
return !current->isOnCurrentActivity();
|
||||
return !client->isOnCurrentActivity();
|
||||
default: // TabBoxConfig::OnlyCurrentActivityClients
|
||||
return current->isOnCurrentActivity();
|
||||
return client->isOnCurrentActivity();
|
||||
}
|
||||
}
|
||||
|
||||
bool TabBoxHandlerImpl::checkApplications(TabBoxClient *client) const
|
||||
bool TabBoxHandlerImpl::checkApplications(Window *client) const
|
||||
{
|
||||
const auto current = (static_cast<TabBoxClientImpl *>(client))->client();
|
||||
const auto list = clientList();
|
||||
|
||||
switch (config().clientApplicationsMode()) {
|
||||
case TabBoxConfig::OneWindowPerApplication:
|
||||
// check if the list already contains an entry of this application
|
||||
for (const auto &weakClient : list) {
|
||||
const std::shared_ptr<TabBoxClientImpl> client = std::dynamic_pointer_cast<TabBoxClientImpl>(weakClient.lock());
|
||||
if (client && Window::belongToSameApplication(client->client(), current, Window::SameApplicationCheck::AllowCrossProcesses)) {
|
||||
for (const Window *other : list) {
|
||||
if (Window::belongToSameApplication(other, client, Window::SameApplicationCheck::AllowCrossProcesses)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
case TabBoxConfig::AllWindowsCurrentApplication: {
|
||||
const std::shared_ptr<TabBoxClientImpl> client = std::dynamic_pointer_cast<TabBoxClientImpl>(tabBox->activeClient().lock());
|
||||
return client && Window::belongToSameApplication(client->client(), current, Window::SameApplicationCheck::AllowCrossProcesses);
|
||||
const Window *active = tabBox->activeClient();
|
||||
return active && Window::belongToSameApplication(active, client, Window::SameApplicationCheck::AllowCrossProcesses);
|
||||
}
|
||||
default: // TabBoxConfig::AllWindowsAllApplications
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool TabBoxHandlerImpl::checkMinimized(TabBoxClient *client) const
|
||||
bool TabBoxHandlerImpl::checkMinimized(Window *client) const
|
||||
{
|
||||
switch (config().clientMinimizedMode()) {
|
||||
case TabBoxConfig::ExcludeMinimizedClients:
|
||||
|
@ -188,65 +163,54 @@ bool TabBoxHandlerImpl::checkMinimized(TabBoxClient *client) const
|
|||
}
|
||||
}
|
||||
|
||||
bool TabBoxHandlerImpl::checkMultiScreen(TabBoxClient *client) const
|
||||
bool TabBoxHandlerImpl::checkMultiScreen(Window *client) const
|
||||
{
|
||||
auto current = (static_cast<TabBoxClientImpl *>(client))->client();
|
||||
|
||||
switch (config().clientMultiScreenMode()) {
|
||||
case TabBoxConfig::IgnoreMultiScreen:
|
||||
return true;
|
||||
case TabBoxConfig::ExcludeCurrentScreenClients:
|
||||
return current->output() != workspace()->activeOutput();
|
||||
return client->output() != workspace()->activeOutput();
|
||||
default: // TabBoxConfig::OnlyCurrentScreenClients
|
||||
return current->output() == workspace()->activeOutput();
|
||||
return client->output() == workspace()->activeOutput();
|
||||
}
|
||||
}
|
||||
|
||||
std::weak_ptr<TabBoxClient> TabBoxHandlerImpl::clientToAddToList(TabBoxClient *client, int desktop) const
|
||||
Window *TabBoxHandlerImpl::clientToAddToList(Window *client, int desktop) const
|
||||
{
|
||||
if (!client) {
|
||||
return std::weak_ptr<TabBoxClient>();
|
||||
return nullptr;
|
||||
}
|
||||
Window *ret = nullptr;
|
||||
Window *current = (static_cast<TabBoxClientImpl *>(client))->client();
|
||||
|
||||
bool addClient = checkDesktop(client, desktop)
|
||||
&& checkActivity(client)
|
||||
&& checkApplications(client)
|
||||
&& checkMinimized(client)
|
||||
&& checkMultiScreen(client);
|
||||
addClient = addClient && current->wantsTabFocus() && !current->skipSwitcher();
|
||||
addClient = addClient && client->wantsTabFocus() && !client->skipSwitcher();
|
||||
if (addClient) {
|
||||
// don't add windows that have modal dialogs
|
||||
Window *modal = current->findModal();
|
||||
if (modal == nullptr || modal == current) {
|
||||
ret = current;
|
||||
Window *modal = client->findModal();
|
||||
if (modal == nullptr || modal == client) {
|
||||
ret = client;
|
||||
} else {
|
||||
const auto list = clientList();
|
||||
const bool contains = std::any_of(list.cbegin(), list.cend(), [c = std::static_pointer_cast<TabBoxClientImpl>(modal->tabBoxClient().lock())](auto &weak) {
|
||||
return weak.lock() == c;
|
||||
});
|
||||
if (contains) {
|
||||
if (clientList().contains(modal)) {
|
||||
ret = modal;
|
||||
} else {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret) {
|
||||
return std::static_pointer_cast<TabBoxClientImpl>(ret->tabBoxClient().lock());
|
||||
} else {
|
||||
return std::weak_ptr<TabBoxClient>();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
TabBoxClientList TabBoxHandlerImpl::stackingOrder() const
|
||||
QList<Window *> TabBoxHandlerImpl::stackingOrder() const
|
||||
{
|
||||
const QList<Window *> stacking = Workspace::self()->stackingOrder();
|
||||
TabBoxClientList ret;
|
||||
QList<Window *> ret;
|
||||
for (Window *window : stacking) {
|
||||
if (window->isClient()) {
|
||||
ret.append(std::static_pointer_cast<TabBoxClientImpl>(window->tabBoxClient().lock()));
|
||||
ret.append(window);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -257,46 +221,43 @@ bool TabBoxHandlerImpl::isKWinCompositing() const
|
|||
return Compositor::compositing();
|
||||
}
|
||||
|
||||
void TabBoxHandlerImpl::raiseClient(TabBoxClient *c) const
|
||||
void TabBoxHandlerImpl::raiseClient(Window *c) const
|
||||
{
|
||||
Workspace::self()->raiseWindow(static_cast<TabBoxClientImpl *>(c)->client());
|
||||
Workspace::self()->raiseWindow(c);
|
||||
}
|
||||
|
||||
void TabBoxHandlerImpl::restack(TabBoxClient *c, TabBoxClient *under)
|
||||
void TabBoxHandlerImpl::restack(Window *c, Window *under)
|
||||
{
|
||||
Workspace::self()->restack(static_cast<TabBoxClientImpl *>(c)->client(),
|
||||
static_cast<TabBoxClientImpl *>(under)->client(), true);
|
||||
Workspace::self()->restack(c, under, true);
|
||||
}
|
||||
|
||||
void TabBoxHandlerImpl::elevateClient(TabBoxClient *c, QWindow *tabbox, bool b) const
|
||||
void TabBoxHandlerImpl::elevateClient(Window *c, QWindow *tabbox, bool b) const
|
||||
{
|
||||
auto cl = static_cast<TabBoxClientImpl *>(c)->client();
|
||||
cl->elevate(b);
|
||||
c->elevate(b);
|
||||
if (Window *w = Workspace::self()->findInternal(tabbox)) {
|
||||
w->elevate(b);
|
||||
}
|
||||
}
|
||||
|
||||
void TabBoxHandlerImpl::shadeClient(TabBoxClient *c, bool b) const
|
||||
void TabBoxHandlerImpl::shadeClient(Window *c, bool b) const
|
||||
{
|
||||
Window *client = static_cast<TabBoxClientImpl *>(c)->client();
|
||||
client->cancelShadeHoverTimer(); // stop core shading action
|
||||
if (!b && client->shadeMode() == ShadeNormal) {
|
||||
client->setShade(ShadeHover);
|
||||
} else if (b && client->shadeMode() == ShadeHover) {
|
||||
client->setShade(ShadeNormal);
|
||||
c->cancelShadeHoverTimer(); // stop core shading action
|
||||
if (!b && c->shadeMode() == ShadeNormal) {
|
||||
c->setShade(ShadeHover);
|
||||
} else if (b && c->shadeMode() == ShadeHover) {
|
||||
c->setShade(ShadeNormal);
|
||||
}
|
||||
}
|
||||
|
||||
std::weak_ptr<TabBoxClient> TabBoxHandlerImpl::desktopClient() const
|
||||
Window *TabBoxHandlerImpl::desktopClient() const
|
||||
{
|
||||
const auto stackingOrder = Workspace::self()->stackingOrder();
|
||||
for (Window *window : stackingOrder) {
|
||||
if (window->isClient() && window->isDesktop() && window->isOnCurrentDesktop() && window->output() == workspace()->activeOutput()) {
|
||||
return window->tabBoxClient();
|
||||
return window;
|
||||
}
|
||||
}
|
||||
return std::weak_ptr<TabBoxClient>();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TabBoxHandlerImpl::activateAndClose()
|
||||
|
@ -304,14 +265,14 @@ void TabBoxHandlerImpl::activateAndClose()
|
|||
m_tabBox->accept();
|
||||
}
|
||||
|
||||
void TabBoxHandlerImpl::highlightWindows(TabBoxClient *window, QWindow *controller)
|
||||
void TabBoxHandlerImpl::highlightWindows(Window *window, QWindow *controller)
|
||||
{
|
||||
if (!effects) {
|
||||
return;
|
||||
}
|
||||
QVector<EffectWindow *> windows;
|
||||
if (window) {
|
||||
windows << static_cast<TabBoxClientImpl *>(window)->client()->effectWindow();
|
||||
windows << window->effectWindow();
|
||||
}
|
||||
if (Window *t = workspace()->findInternal(controller)) {
|
||||
windows << t->effectWindow();
|
||||
|
@ -324,77 +285,6 @@ bool TabBoxHandlerImpl::noModifierGrab() const
|
|||
return m_tabBox->noModifierGrab();
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
* TabBoxClientImpl
|
||||
*********************************************************/
|
||||
|
||||
TabBoxClientImpl::TabBoxClientImpl(Window *client)
|
||||
: TabBoxClient()
|
||||
, m_client(client)
|
||||
{
|
||||
}
|
||||
|
||||
TabBoxClientImpl::~TabBoxClientImpl()
|
||||
{
|
||||
}
|
||||
|
||||
QString TabBoxClientImpl::caption() const
|
||||
{
|
||||
if (m_client->isDesktop()) {
|
||||
return i18nc("Special entry in alt+tab list for minimizing all windows",
|
||||
"Show Desktop");
|
||||
}
|
||||
return m_client->caption();
|
||||
}
|
||||
|
||||
QIcon TabBoxClientImpl::icon() const
|
||||
{
|
||||
if (m_client->isDesktop()) {
|
||||
return QIcon::fromTheme(QStringLiteral("user-desktop"));
|
||||
}
|
||||
return m_client->icon();
|
||||
}
|
||||
|
||||
bool TabBoxClientImpl::isMinimized() const
|
||||
{
|
||||
return m_client->isMinimized();
|
||||
}
|
||||
|
||||
int TabBoxClientImpl::x() const
|
||||
{
|
||||
return m_client->x();
|
||||
}
|
||||
|
||||
int TabBoxClientImpl::y() const
|
||||
{
|
||||
return m_client->y();
|
||||
}
|
||||
|
||||
int TabBoxClientImpl::width() const
|
||||
{
|
||||
return m_client->width();
|
||||
}
|
||||
|
||||
int TabBoxClientImpl::height() const
|
||||
{
|
||||
return m_client->height();
|
||||
}
|
||||
|
||||
bool TabBoxClientImpl::isCloseable() const
|
||||
{
|
||||
return m_client->isCloseable();
|
||||
}
|
||||
|
||||
void TabBoxClientImpl::close()
|
||||
{
|
||||
m_client->closeWindow();
|
||||
}
|
||||
|
||||
QUuid TabBoxClientImpl::internalId() const
|
||||
{
|
||||
return m_client->internalId();
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
* TabBox
|
||||
*********************************************************/
|
||||
|
@ -555,11 +445,11 @@ void TabBox::nextPrev(bool next)
|
|||
|
||||
Window *TabBox::currentClient()
|
||||
{
|
||||
if (TabBoxClientImpl *client = static_cast<TabBoxClientImpl *>(m_tabBox->client(m_tabBox->currentIndex()))) {
|
||||
if (!Workspace::self()->hasWindow(client->client())) {
|
||||
if (Window *client = m_tabBox->client(m_tabBox->currentIndex())) {
|
||||
if (!Workspace::self()->hasWindow(client)) {
|
||||
return nullptr;
|
||||
}
|
||||
return client->client();
|
||||
return client;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -567,23 +457,12 @@ Window *TabBox::currentClient()
|
|||
|
||||
QList<Window *> TabBox::currentClientList()
|
||||
{
|
||||
const TabBoxClientList list = m_tabBox->clientList();
|
||||
QList<Window *> ret;
|
||||
for (const std::weak_ptr<TabBoxClient> &clientPointer : list) {
|
||||
std::shared_ptr<TabBoxClient> client = clientPointer.lock();
|
||||
if (!client) {
|
||||
continue;
|
||||
}
|
||||
if (const TabBoxClientImpl *c = static_cast<const TabBoxClientImpl *>(client.get())) {
|
||||
ret.append(c->client());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return m_tabBox->clientList();
|
||||
}
|
||||
|
||||
void TabBox::setCurrentClient(Window *newClient)
|
||||
{
|
||||
setCurrentIndex(m_tabBox->index(std::static_pointer_cast<TabBoxClientImpl>(newClient->tabBoxClient().lock())));
|
||||
setCurrentIndex(m_tabBox->index(newClient));
|
||||
}
|
||||
|
||||
void TabBox::setCurrentIndex(QModelIndex index, bool notifyEffects)
|
||||
|
|
|
@ -41,60 +41,34 @@ public:
|
|||
~TabBoxHandlerImpl() override;
|
||||
|
||||
int activeScreen() const override;
|
||||
std::weak_ptr<TabBoxClient> activeClient() const override;
|
||||
Window *activeClient() const override;
|
||||
int currentDesktop() const override;
|
||||
QString desktopName(TabBoxClient *client) const override;
|
||||
QString desktopName(Window *client) const override;
|
||||
bool isKWinCompositing() const override;
|
||||
std::weak_ptr<TabBoxClient> nextClientFocusChain(TabBoxClient *client) const override;
|
||||
std::weak_ptr<TabBoxClient> firstClientFocusChain() const override;
|
||||
bool isInFocusChain(TabBoxClient *client) const override;
|
||||
TabBoxClientList stackingOrder() const override;
|
||||
void elevateClient(TabBoxClient *c, QWindow *tabbox, bool elevate) const override;
|
||||
void raiseClient(TabBoxClient *client) const override;
|
||||
void restack(TabBoxClient *c, TabBoxClient *under) override;
|
||||
void shadeClient(TabBoxClient *c, bool b) const override;
|
||||
std::weak_ptr<TabBoxClient> clientToAddToList(KWin::TabBox::TabBoxClient *client, int desktop) const override;
|
||||
std::weak_ptr<TabBoxClient> desktopClient() const override;
|
||||
Window *nextClientFocusChain(Window *client) const override;
|
||||
Window *firstClientFocusChain() const override;
|
||||
bool isInFocusChain(Window *client) const override;
|
||||
QList<Window *> stackingOrder() const override;
|
||||
void elevateClient(Window *c, QWindow *tabbox, bool elevate) const override;
|
||||
void raiseClient(Window *client) const override;
|
||||
void restack(Window *c, Window *under) override;
|
||||
void shadeClient(Window *c, bool b) const override;
|
||||
Window *clientToAddToList(Window *client, int desktop) const override;
|
||||
Window *desktopClient() const override;
|
||||
void activateAndClose() override;
|
||||
void highlightWindows(TabBoxClient *window = nullptr, QWindow *controller = nullptr) override;
|
||||
void highlightWindows(Window *window = nullptr, QWindow *controller = nullptr) override;
|
||||
bool noModifierGrab() const override;
|
||||
|
||||
private:
|
||||
bool checkDesktop(TabBoxClient *client, int desktop) const;
|
||||
bool checkActivity(TabBoxClient *client) const;
|
||||
bool checkApplications(TabBoxClient *client) const;
|
||||
bool checkMinimized(TabBoxClient *client) const;
|
||||
bool checkMultiScreen(TabBoxClient *client) const;
|
||||
bool checkDesktop(Window *client, int desktop) const;
|
||||
bool checkActivity(Window *client) const;
|
||||
bool checkApplications(Window *client) const;
|
||||
bool checkMinimized(Window *client) const;
|
||||
bool checkMultiScreen(Window *client) const;
|
||||
|
||||
TabBox *m_tabBox;
|
||||
};
|
||||
|
||||
class TabBoxClientImpl : public TabBoxClient
|
||||
{
|
||||
public:
|
||||
explicit TabBoxClientImpl(Window *client);
|
||||
~TabBoxClientImpl() override;
|
||||
|
||||
QString caption() const override;
|
||||
QIcon icon() const override;
|
||||
bool isMinimized() const override;
|
||||
int x() const override;
|
||||
int y() const override;
|
||||
int width() const override;
|
||||
int height() const override;
|
||||
bool isCloseable() const override;
|
||||
void close() override;
|
||||
QUuid internalId() const override;
|
||||
|
||||
Window *client() const
|
||||
{
|
||||
return m_client;
|
||||
}
|
||||
|
||||
private:
|
||||
Window *m_client;
|
||||
};
|
||||
|
||||
class KWIN_EXPORT TabBox : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
|
@ -41,71 +41,71 @@ class TabBoxConfig
|
|||
public:
|
||||
/**
|
||||
* ClientDesktopMode defines whether windows from the current desktop or from all
|
||||
* desktops are included in the TabBoxClient List in the TabBoxClientModel
|
||||
* desktops are included in the Window List in the ClientModel
|
||||
*/
|
||||
enum ClientDesktopMode {
|
||||
AllDesktopsClients, ///< TabBoxClients from all desktops are included.
|
||||
OnlyCurrentDesktopClients, ///< Only TabBoxClients on current desktop are included
|
||||
ExcludeCurrentDesktopClients ///< Exclude TabBoxClients on current desktop
|
||||
AllDesktopsClients, ///< Windows from all desktops are included.
|
||||
OnlyCurrentDesktopClients, ///< Only Windows on current desktop are included
|
||||
ExcludeCurrentDesktopClients ///< Exclude Windows on current desktop
|
||||
};
|
||||
/**
|
||||
* ClientActivitiesMode defines whether windows from the current activity or from all
|
||||
* activities are included in the TabBoxClient List in the TabBoxClientModel
|
||||
* activities are included in the Window List in the ClientModel
|
||||
*/
|
||||
enum ClientActivitiesMode {
|
||||
AllActivitiesClients, ///< TabBoxClients from all Activities are included.
|
||||
OnlyCurrentActivityClients, ///< Only TabBoxClients on current activity are included
|
||||
ExcludeCurrentActivityClients ///< Exclude TabBoxClients on current activity
|
||||
AllActivitiesClients, ///< Windows from all Activities are included.
|
||||
OnlyCurrentActivityClients, ///< Only Windows on current activity are included
|
||||
ExcludeCurrentActivityClients ///< Exclude Windows on current activity
|
||||
};
|
||||
/**
|
||||
* ClientApplicationsMode defines which windows from the current application or from all
|
||||
* applications are included in the TabBoxClient List in the TabBoxClientModel
|
||||
* applications are included in the Window List in the ClientModel
|
||||
*/
|
||||
enum ClientApplicationsMode {
|
||||
AllWindowsAllApplications, ///< TabBoxClients from all applications are included
|
||||
OneWindowPerApplication, ///< Only one TabBoxClient for each application is included
|
||||
AllWindowsCurrentApplication ///< Only TabBoxClients for the current application are included
|
||||
AllWindowsAllApplications, ///< Windows from all applications are included
|
||||
OneWindowPerApplication, ///< Only one Window for each application is included
|
||||
AllWindowsCurrentApplication ///< Only Windows for the current application are included
|
||||
};
|
||||
/**
|
||||
* ClientMinimizedMode defines which windows are included in the TabBoxClient List
|
||||
* in the TabBoxClientModel based on whether they are minimized or not
|
||||
* ClientMinimizedMode defines which windows are included in the Window List
|
||||
* in the ClientModel based on whether they are minimized or not
|
||||
*/
|
||||
enum ClientMinimizedMode {
|
||||
IgnoreMinimizedStatus, ///< TabBoxClients are included no matter they are minimized or not
|
||||
ExcludeMinimizedClients, ///< Exclude minimized TabBoxClients
|
||||
OnlyMinimizedClients ///< Only minimized TabBoxClients are included
|
||||
IgnoreMinimizedStatus, ///< Windows are included no matter they are minimized or not
|
||||
ExcludeMinimizedClients, ///< Exclude minimized Windows
|
||||
OnlyMinimizedClients ///< Only minimized Windows are included
|
||||
};
|
||||
/**
|
||||
* ShowDesktopMode defines whether a TabBoxClient representing the desktop
|
||||
* is included in the TabBoxClient List in the TabBoxClientModel
|
||||
* ShowDesktopMode defines whether a Window representing the desktop
|
||||
* is included in the Window List in the ClientModel
|
||||
*/
|
||||
enum ShowDesktopMode {
|
||||
DoNotShowDesktopClient, ///< A TabBoxClient representing the desktop is not included
|
||||
ShowDesktopClient ///< A TabBoxClient representing the desktop is included
|
||||
DoNotShowDesktopClient, ///< A Window representing the desktop is not included
|
||||
ShowDesktopClient ///< A Window representing the desktop is included
|
||||
};
|
||||
/**
|
||||
* OrderMinimizedMode defines whether the TabBoxClients considered part of the
|
||||
* TabBoxClient List should be grouped by the minimisation status
|
||||
* OrderMinimizedMode defines whether the Windows considered part of the
|
||||
* Window List should be grouped by the minimisation status
|
||||
*/
|
||||
enum OrderMinimizedMode {
|
||||
NoGroupByMinimized, ///< TabBoxClients are not grouped by whether they are minimized
|
||||
GroupByMinimized ///< TabBoxClients are grouped by whether they are minimized or not
|
||||
NoGroupByMinimized, ///< Windows are not grouped by whether they are minimized
|
||||
GroupByMinimized ///< Windows are grouped by whether they are minimized or not
|
||||
};
|
||||
/**
|
||||
* ClientActivitiesMode defines whether windows from the current activity or from all
|
||||
* activities are included in the TabBoxClient List in the TabBoxClientModel
|
||||
* activities are included in the Window List in the ClientModel
|
||||
*/
|
||||
enum ClientMultiScreenMode {
|
||||
IgnoreMultiScreen, ///< TabBoxClients are included independently of the screen they are on
|
||||
OnlyCurrentScreenClients, ///< Only TabBoxClients on current screen are included
|
||||
ExcludeCurrentScreenClients ///< Exclude TabBoxClients from the current screen
|
||||
IgnoreMultiScreen, ///< Windows are included independently of the screen they are on
|
||||
OnlyCurrentScreenClients, ///< Only Windows on current screen are included
|
||||
ExcludeCurrentScreenClients ///< Exclude Windows from the current screen
|
||||
};
|
||||
/**
|
||||
* ClientSwitchingMode defines the sorting of the TabBoxClients in the
|
||||
* TabBoxClientModel.
|
||||
* ClientSwitchingMode defines the sorting of the Windows in the
|
||||
* ClientModel.
|
||||
*/
|
||||
enum ClientSwitchingMode {
|
||||
FocusChainSwitching, ///< Sort by recently used. Most recently used TabBoxClient is the first
|
||||
FocusChainSwitching, ///< Sort by recently used. Most recently used Window is the first
|
||||
StackingOrderSwitching ///< Sort by current stacking order
|
||||
};
|
||||
TabBoxConfig();
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "scripting/scripting.h"
|
||||
#include "switcheritem.h"
|
||||
#include "tabbox_logging.h"
|
||||
#include "window.h"
|
||||
// Qt
|
||||
#include <QKeyEvent>
|
||||
#include <QQmlComponent>
|
||||
|
@ -73,7 +74,7 @@ public:
|
|||
* Indicates if the tabbox is shown.
|
||||
*/
|
||||
bool isShown;
|
||||
TabBoxClient *lastRaisedClient, *lastRaisedClientSucc;
|
||||
Window *lastRaisedClient, *lastRaisedClientSucc;
|
||||
int wheelAngleDelta = 0;
|
||||
|
||||
private:
|
||||
|
@ -144,7 +145,7 @@ void TabBoxHandlerPrivate::updateHighlightWindows()
|
|||
return;
|
||||
}
|
||||
|
||||
TabBoxClient *currentClient = q->client(index);
|
||||
Window *currentClient = q->client(index);
|
||||
QWindow *w = window();
|
||||
|
||||
if (q->isKWinCompositing()) {
|
||||
|
@ -153,7 +154,7 @@ void TabBoxHandlerPrivate::updateHighlightWindows()
|
|||
}
|
||||
lastRaisedClient = currentClient;
|
||||
// don't elevate desktop
|
||||
const auto desktop = q->desktopClient().lock();
|
||||
const auto desktop = q->desktopClient();
|
||||
if (currentClient && (!desktop || currentClient->internalId() != desktop->internalId())) {
|
||||
q->elevateClient(currentClient, w, true);
|
||||
}
|
||||
|
@ -171,15 +172,15 @@ void TabBoxHandlerPrivate::updateHighlightWindows()
|
|||
q->shadeClient(lastRaisedClient, false);
|
||||
// TODO if ( (lastRaisedClientWasMinimized = lastRaisedClient->isMinimized()) )
|
||||
// lastRaisedClient->setMinimized( false );
|
||||
TabBoxClientList order = q->stackingOrder();
|
||||
QList<Window *> order = q->stackingOrder();
|
||||
int succIdx = order.count() + 1;
|
||||
for (int i = 0; i < order.count(); ++i) {
|
||||
if (order.at(i).lock().get() == lastRaisedClient) {
|
||||
if (order.at(i) == lastRaisedClient) {
|
||||
succIdx = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
lastRaisedClientSucc = (succIdx < order.count()) ? order.at(succIdx).lock().get() : nullptr;
|
||||
lastRaisedClientSucc = (succIdx < order.count()) ? order.at(succIdx) : nullptr;
|
||||
q->raiseClient(lastRaisedClient);
|
||||
}
|
||||
}
|
||||
|
@ -193,14 +194,12 @@ void TabBoxHandlerPrivate::updateHighlightWindows()
|
|||
|
||||
void TabBoxHandlerPrivate::endHighlightWindows(bool abort)
|
||||
{
|
||||
TabBoxClient *currentClient = q->client(index);
|
||||
Window *currentClient = q->client(index);
|
||||
if (isHighlightWindows() && q->isKWinCompositing()) {
|
||||
const auto stackingOrder = q->stackingOrder();
|
||||
for (const std::weak_ptr<TabBoxClient> &clientPointer : stackingOrder) {
|
||||
if (std::shared_ptr<TabBoxClient> client = clientPointer.lock()) {
|
||||
if (client.get() != currentClient) { // to not mess up with wanted ShadeActive/ShadeHover state
|
||||
q->shadeClient(client.get(), true);
|
||||
}
|
||||
for (Window *window : stackingOrder) {
|
||||
if (window != currentClient) { // to not mess up with wanted ShadeActive/ShadeHover state
|
||||
q->shadeClient(window, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -377,10 +376,8 @@ void TabBoxHandler::initHighlightWindows()
|
|||
{
|
||||
if (isKWinCompositing()) {
|
||||
const auto stack = stackingOrder();
|
||||
for (const std::weak_ptr<TabBoxClient> &clientPointer : stack) {
|
||||
if (std::shared_ptr<TabBoxClient> client = clientPointer.lock()) {
|
||||
shadeClient(client.get(), false);
|
||||
}
|
||||
for (Window *window : stack) {
|
||||
shadeClient(window, false);
|
||||
}
|
||||
}
|
||||
d->updateHighlightWindows();
|
||||
|
@ -490,22 +487,22 @@ bool TabBoxHandler::containsPos(const QPoint &pos) const
|
|||
return false;
|
||||
}
|
||||
|
||||
QModelIndex TabBoxHandler::index(std::weak_ptr<KWin::TabBox::TabBoxClient> client) const
|
||||
QModelIndex TabBoxHandler::index(Window *client) const
|
||||
{
|
||||
return d->clientModel()->index(client);
|
||||
}
|
||||
|
||||
TabBoxClientList TabBoxHandler::clientList() const
|
||||
QList<Window *> TabBoxHandler::clientList() const
|
||||
{
|
||||
return d->clientModel()->clientList();
|
||||
}
|
||||
|
||||
TabBoxClient *TabBoxHandler::client(const QModelIndex &index) const
|
||||
Window *TabBoxHandler::client(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
TabBoxClient *c = static_cast<TabBoxClient *>(
|
||||
Window *c = static_cast<Window *>(
|
||||
d->clientModel()->data(index, ClientModel::ClientRole).value<void *>());
|
||||
return c;
|
||||
}
|
||||
|
@ -517,15 +514,11 @@ void TabBoxHandler::createModel(bool partialReset)
|
|||
bool lastRaised = false;
|
||||
bool lastRaisedSucc = false;
|
||||
const auto clients = stackingOrder();
|
||||
for (const auto &clientPointer : clients) {
|
||||
std::shared_ptr<TabBoxClient> client = clientPointer.lock();
|
||||
if (!client) {
|
||||
continue;
|
||||
}
|
||||
if (client.get() == d->lastRaisedClient) {
|
||||
for (Window *window : clients) {
|
||||
if (window == d->lastRaisedClient) {
|
||||
lastRaised = true;
|
||||
}
|
||||
if (client.get() == d->lastRaisedClientSucc) {
|
||||
if (window == d->lastRaisedClientSucc) {
|
||||
lastRaisedSucc = true;
|
||||
}
|
||||
}
|
||||
|
@ -571,13 +564,5 @@ bool TabBoxHandler::eventFilter(QObject *watched, QEvent *e)
|
|||
|
||||
TabBoxHandler *tabBox = nullptr;
|
||||
|
||||
TabBoxClient::TabBoxClient()
|
||||
{
|
||||
}
|
||||
|
||||
TabBoxClient::~TabBoxClient()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace TabBox
|
||||
} // namespace KWin
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
/**
|
||||
* @file
|
||||
* This file contains the classes which hide KWin core from tabbox.
|
||||
* It defines the pure virtual classes TabBoxHandler and TabBoxClient.
|
||||
* The classes have to be implemented in KWin Core.
|
||||
*
|
||||
* @author Martin Gräßlin <mgraesslin@kde.org>
|
||||
* @since 4.4
|
||||
|
@ -29,13 +27,15 @@ class QKeyEvent;
|
|||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class Window;
|
||||
|
||||
/**
|
||||
* The TabBox is a model based view for displaying a list while switching windows.
|
||||
* This functionality is mostly referred to as Alt+Tab. TabBox itself does not provide support for
|
||||
* switching windows. This has to be done outside of TabBox inside an independent controller.
|
||||
*
|
||||
* The main entrance point to TabBox is the class TabBoxHandler, which has to be subclassed and implemented.
|
||||
* The class TabBoxClient, which represents a window client inside TabBox, has to be implemented as well.
|
||||
*
|
||||
* The behavior of the TabBox is defined by the TabBoxConfig and has to be set in the TabBoxHandler.
|
||||
*
|
||||
|
@ -62,9 +62,7 @@ namespace TabBox
|
|||
{
|
||||
class ClientModel;
|
||||
class TabBoxConfig;
|
||||
class TabBoxClient;
|
||||
class TabBoxHandlerPrivate;
|
||||
typedef QList<std::weak_ptr<TabBoxClient>> TabBoxClientList;
|
||||
|
||||
/**
|
||||
* This class is a wrapper around KWin Workspace. It is used for accessing the
|
||||
|
@ -85,15 +83,15 @@ public:
|
|||
*/
|
||||
virtual int activeScreen() const = 0;
|
||||
/**
|
||||
* @return The current active TabBoxClient or NULL
|
||||
* @return The current active Window or NULL
|
||||
* if there is no active client.
|
||||
*/
|
||||
virtual std::weak_ptr<TabBoxClient> activeClient() const = 0;
|
||||
virtual Window *activeClient() const = 0;
|
||||
/**
|
||||
* @param client The client which is starting point to find the next client
|
||||
* @return The next TabBoxClient in focus chain
|
||||
* @return The next Window in focus chain
|
||||
*/
|
||||
virtual std::weak_ptr<TabBoxClient> nextClientFocusChain(TabBoxClient *client) const = 0;
|
||||
virtual Window *nextClientFocusChain(Window *client) const = 0;
|
||||
/**
|
||||
* This method is used by the ClientModel to find an entrance into the focus chain in case
|
||||
* there is no active Client.
|
||||
|
@ -101,7 +99,7 @@ public:
|
|||
* @return The first Client of the focus chain
|
||||
* @since 4.9.1
|
||||
*/
|
||||
virtual std::weak_ptr<TabBoxClient> firstClientFocusChain() const = 0;
|
||||
virtual Window *firstClientFocusChain() const = 0;
|
||||
/**
|
||||
* Checks whether the given @p client is part of the focus chain at all.
|
||||
* This is useful to figure out whether the currently active Client can be used
|
||||
|
@ -115,13 +113,13 @@ public:
|
|||
* @return @c true in case the Client is part of the focus chain, @c false otherwise.
|
||||
* @since 4.9.2
|
||||
*/
|
||||
virtual bool isInFocusChain(TabBoxClient *client) const = 0;
|
||||
virtual bool isInFocusChain(Window *client) const = 0;
|
||||
/**
|
||||
* @param client The client whose desktop name should be retrieved
|
||||
* @return The desktop name of the given TabBoxClient. If the client is
|
||||
* @return The desktop name of the given Window. If the client is
|
||||
* on all desktops the name of current desktop will be returned.
|
||||
*/
|
||||
virtual QString desktopName(TabBoxClient *client) const = 0;
|
||||
virtual QString desktopName(Window *client) const = 0;
|
||||
/**
|
||||
* @return The number of current desktop
|
||||
*/
|
||||
|
@ -135,32 +133,32 @@ public:
|
|||
/**
|
||||
* De-/Elevate a client using the compositor (if enabled)
|
||||
*/
|
||||
virtual void elevateClient(TabBoxClient *c, QWindow *tabbox, bool elevate) const = 0;
|
||||
virtual void elevateClient(Window *c, QWindow *tabbox, bool elevate) const = 0;
|
||||
|
||||
/**
|
||||
* Raise a client (w/o activating it)
|
||||
*/
|
||||
virtual void raiseClient(TabBoxClient *c) const = 0;
|
||||
virtual void raiseClient(Window *c) const = 0;
|
||||
|
||||
/**
|
||||
* @param c The client to be restacked
|
||||
* @param under The client the other one will be placed below
|
||||
*/
|
||||
virtual void restack(TabBoxClient *c, TabBoxClient *under) = 0;
|
||||
virtual void restack(Window *c, Window *under) = 0;
|
||||
|
||||
/**
|
||||
* Toggle between ShadeHover and ShadeNormal - not shaded windows are unaffected
|
||||
* @param c The client to be shaded
|
||||
* @param b Whether to un- or shade
|
||||
*/
|
||||
virtual void shadeClient(TabBoxClient *c, bool b) const = 0;
|
||||
virtual void shadeClient(Window *c, bool b) const = 0;
|
||||
|
||||
virtual void highlightWindows(TabBoxClient *window = nullptr, QWindow *controller = nullptr) = 0;
|
||||
virtual void highlightWindows(Window *window = nullptr, QWindow *controller = nullptr) = 0;
|
||||
|
||||
/**
|
||||
* @return The current stacking order of TabBoxClients
|
||||
* @return The current stacking order of Windows
|
||||
*/
|
||||
virtual TabBoxClientList stackingOrder() const = 0;
|
||||
virtual QList<Window *> stackingOrder() const = 0;
|
||||
/**
|
||||
* Determines if given client will be added to the list:
|
||||
* <UL>
|
||||
|
@ -177,11 +175,11 @@ public:
|
|||
* @param allDesktops Add clients from all desktops or only from current
|
||||
* @return The client to be included in the list or NULL if it isn't to be included
|
||||
*/
|
||||
virtual std::weak_ptr<TabBoxClient> clientToAddToList(TabBoxClient *client, int desktop) const = 0;
|
||||
virtual Window *clientToAddToList(Window *client, int desktop) const = 0;
|
||||
/**
|
||||
* @return The first desktop window in the stacking order.
|
||||
*/
|
||||
virtual std::weak_ptr<TabBoxClient> desktopClient() const = 0;
|
||||
virtual Window *desktopClient() const = 0;
|
||||
/**
|
||||
* Activates the currently selected client and closes the TabBox.
|
||||
*/
|
||||
|
@ -253,24 +251,24 @@ public:
|
|||
*/
|
||||
bool containsPos(const QPoint &pos) const;
|
||||
/**
|
||||
* @param client The TabBoxClient whose index should be returned
|
||||
* @return Returns the ModelIndex of given TabBoxClient or an invalid ModelIndex
|
||||
* if the model does not contain the given TabBoxClient.
|
||||
* @param client The Window whose index should be returned
|
||||
* @return Returns the ModelIndex of given Window or an invalid ModelIndex
|
||||
* if the model does not contain the given Window.
|
||||
* @see ClientModel::index
|
||||
*/
|
||||
QModelIndex index(std::weak_ptr<TabBoxClient> client) const;
|
||||
QModelIndex index(Window *client) const;
|
||||
/**
|
||||
* @return Returns the current list of TabBoxClients.
|
||||
* @return Returns the current list of Windows.
|
||||
* @see ClientModel::clientList
|
||||
*/
|
||||
TabBoxClientList clientList() const;
|
||||
QList<Window *> clientList() const;
|
||||
/**
|
||||
* @param index The index of the client to be returned
|
||||
* @return Returns the TabBoxClient at given model index. If
|
||||
* @return Returns the Window at given model index. If
|
||||
* the index is invalid, does not point to a Client or the list
|
||||
* is empty, NULL will be returned.
|
||||
*/
|
||||
TabBoxClient *client(const QModelIndex &index) const;
|
||||
Window *client(const QModelIndex &index) const;
|
||||
/**
|
||||
* @return The first model index. That is the model index at position 0, 0.
|
||||
* It is valid, as desktop has at least one desktop and if there are no
|
||||
|
@ -302,41 +300,6 @@ private:
|
|||
TabBoxHandlerPrivate *d;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is a wrapper around a KWin Client. It is used for accessing the
|
||||
* required client methods from inside TabBox and has to be implemented in KWin core.
|
||||
*
|
||||
* @author Martin Gräßlin <mgraesslin@kde.org>
|
||||
* @since 4.4
|
||||
*/
|
||||
class TabBoxClient
|
||||
{
|
||||
public:
|
||||
TabBoxClient();
|
||||
virtual ~TabBoxClient();
|
||||
|
||||
/**
|
||||
* @return The caption of the client
|
||||
*/
|
||||
virtual QString caption() const = 0;
|
||||
/**
|
||||
* @param size Requested size of the icon
|
||||
* @return The icon of the client
|
||||
*/
|
||||
virtual QIcon icon() const = 0;
|
||||
/**
|
||||
* @return Minimized state of the client
|
||||
*/
|
||||
virtual bool isMinimized() const = 0;
|
||||
virtual int x() const = 0;
|
||||
virtual int y() const = 0;
|
||||
virtual int width() const = 0;
|
||||
virtual int height() const = 0;
|
||||
virtual bool isCloseable() const = 0;
|
||||
virtual void close() = 0;
|
||||
virtual QUuid internalId() const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Pointer to the global TabBoxHandler object.
|
||||
*/
|
||||
|
|
|
@ -76,9 +76,6 @@ Window::Window()
|
|||
, m_clientMachine(new ClientMachine(this))
|
||||
, m_wmClientLeader(XCB_WINDOW_NONE)
|
||||
, m_skipCloseAnimation(false)
|
||||
#if KWIN_BUILD_TABBOX
|
||||
, m_tabBoxClient(std::make_shared<TabBox::TabBoxClientImpl>(this))
|
||||
#endif
|
||||
, m_colorScheme(QStringLiteral("kdeglobals"))
|
||||
, m_moveResizeOutput(workspace()->activeOutput())
|
||||
{
|
||||
|
|
10
src/window.h
10
src/window.h
|
@ -66,11 +66,6 @@ enum class ReleaseReason {
|
|||
KWinShutsDown ///< Release on KWin Shutdown (window still valid)
|
||||
};
|
||||
|
||||
namespace TabBox
|
||||
{
|
||||
class TabBoxClientImpl;
|
||||
}
|
||||
|
||||
namespace Decoration
|
||||
{
|
||||
class DecoratedClientImpl;
|
||||
|
@ -821,10 +816,6 @@ public:
|
|||
int stackingOrder() const;
|
||||
void setStackingOrder(int order); ///< @internal
|
||||
|
||||
std::weak_ptr<TabBox::TabBoxClientImpl> tabBoxClient() const
|
||||
{
|
||||
return m_tabBoxClient;
|
||||
}
|
||||
bool skipSwitcher() const
|
||||
{
|
||||
return m_skipSwitcher;
|
||||
|
@ -1886,7 +1877,6 @@ private:
|
|||
QRectF moveToArea(const QRectF &geometry, const QRectF &oldArea, const QRectF &newArea);
|
||||
QRectF ensureSpecialStateGeometry(const QRectF &geometry);
|
||||
|
||||
std::shared_ptr<TabBox::TabBoxClientImpl> m_tabBoxClient;
|
||||
bool m_skipTaskbar = false;
|
||||
/**
|
||||
* Unaffected by KWin
|
||||
|
|
Loading…
Reference in a new issue