From c5eabfa4d15d71e635fb55a02d773b3b39a41f3f Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Sat, 25 Mar 2023 20:46:54 +0000 Subject: [PATCH] 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. --- autotests/CMakeLists.txt | 1 - autotests/tabbox/CMakeLists.txt | 80 ------- autotests/tabbox/mock_tabboxclient.cpp | 26 -- autotests/tabbox/mock_tabboxclient.h | 70 ------ autotests/tabbox/mock_tabboxhandler.cpp | 109 --------- autotests/tabbox/mock_tabboxhandler.h | 92 ------- autotests/tabbox/test_tabbox_clientmodel.cpp | 84 ------- autotests/tabbox/test_tabbox_clientmodel.h | 42 ---- autotests/tabbox/test_tabbox_config.cpp | 71 ------ autotests/tabbox/test_tabbox_handler.cpp | 51 ---- src/tabbox/clientmodel.cpp | 89 ++++--- src/tabbox/clientmodel.h | 38 +-- src/tabbox/tabbox.cpp | 239 +++++-------------- src/tabbox/tabbox.h | 62 ++--- src/tabbox/tabboxconfig.h | 64 ++--- src/tabbox/tabboxhandler.cpp | 55 ++--- src/tabbox/tabboxhandler.h | 93 +++----- src/window.cpp | 3 - src/window.h | 10 - 19 files changed, 217 insertions(+), 1062 deletions(-) delete mode 100644 autotests/tabbox/CMakeLists.txt delete mode 100644 autotests/tabbox/mock_tabboxclient.cpp delete mode 100644 autotests/tabbox/mock_tabboxclient.h delete mode 100644 autotests/tabbox/mock_tabboxhandler.cpp delete mode 100644 autotests/tabbox/mock_tabboxhandler.h delete mode 100644 autotests/tabbox/test_tabbox_clientmodel.cpp delete mode 100644 autotests/tabbox/test_tabbox_clientmodel.h delete mode 100644 autotests/tabbox/test_tabbox_config.cpp delete mode 100644 autotests/tabbox/test_tabbox_handler.cpp diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 1ccd552dc3..3466f3e1e7 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -3,7 +3,6 @@ remove_definitions(-DQT_USE_QSTRINGBUILDER) add_subdirectory(libkwineffects) add_subdirectory(integration) add_subdirectory(libinput) -add_subdirectory(tabbox) add_subdirectory(drm) ######################################################## diff --git a/autotests/tabbox/CMakeLists.txt b/autotests/tabbox/CMakeLists.txt deleted file mode 100644 index ba52a45cce..0000000000 --- a/autotests/tabbox/CMakeLists.txt +++ /dev/null @@ -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) diff --git a/autotests/tabbox/mock_tabboxclient.cpp b/autotests/tabbox/mock_tabboxclient.cpp deleted file mode 100644 index d4c22776eb..0000000000 --- a/autotests/tabbox/mock_tabboxclient.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2012 Martin Gräßlin - - 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(TabBox::tabBox)->closeWindow(this); -} - -} // namespace KWin diff --git a/autotests/tabbox/mock_tabboxclient.h b/autotests/tabbox/mock_tabboxclient.h deleted file mode 100644 index aa6c37a9ed..0000000000 --- a/autotests/tabbox/mock_tabboxclient.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2012 Martin Gräßlin - - 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 -#include - -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 diff --git a/autotests/tabbox/mock_tabboxhandler.cpp b/autotests/tabbox/mock_tabboxhandler.cpp deleted file mode 100644 index 1cc82f0646..0000000000 --- a/autotests/tabbox/mock_tabboxhandler.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2012 Martin Gräßlin - - 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 MockTabBoxHandler::activeClient() const -{ - return m_activeClient; -} - -void MockTabBoxHandler::setActiveClient(const std::weak_ptr &client) -{ - m_activeClient = client; -} - -std::weak_ptr MockTabBoxHandler::clientToAddToList(TabBox::TabBoxClient *client, int desktop) const -{ - QList>::const_iterator it = m_windows.constBegin(); - for (; it != m_windows.constEnd(); ++it) { - if ((*it).get() == client) { - return std::weak_ptr(*it); - } - } - return std::weak_ptr(); -} - -std::weak_ptr MockTabBoxHandler::nextClientFocusChain(TabBox::TabBoxClient *client) const -{ - QList>::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(m_windows.first()); - } else { - return std::weak_ptr(*it); - } - } - } - if (!m_windows.isEmpty()) { - return std::weak_ptr(m_windows.last()); - } - return std::weak_ptr(); -} - -std::weak_ptr MockTabBoxHandler::firstClientFocusChain() const -{ - if (m_windows.isEmpty()) { - return std::weak_ptr(); - } - return m_windows.first(); -} - -bool MockTabBoxHandler::isInFocusChain(TabBox::TabBoxClient *client) const -{ - if (!client) { - return false; - } - QList>::const_iterator it = m_windows.constBegin(); - for (; it != m_windows.constEnd(); ++it) { - if ((*it).get() == client) { - return true; - } - } - return false; -} - -std::weak_ptr MockTabBoxHandler::createMockWindow(const QString &caption) -{ - std::shared_ptr client(new MockTabBoxClient(caption)); - m_windows.append(client); - m_activeClient = client; - return std::weak_ptr(client); -} - -void MockTabBoxHandler::closeWindow(TabBox::TabBoxClient *client) -{ - QList>::iterator it = m_windows.begin(); - for (; it != m_windows.end(); ++it) { - if ((*it).get() == client) { - m_windows.erase(it); - return; - } - } -} - -} // namespace KWin diff --git a/autotests/tabbox/mock_tabboxhandler.h b/autotests/tabbox/mock_tabboxhandler.h deleted file mode 100644 index 1e760527ed..0000000000 --- a/autotests/tabbox/mock_tabboxhandler.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2012 Martin Gräßlin - - 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 activeClient() const override; - void setActiveClient(const std::weak_ptr &client); - int activeScreen() const override - { - return 0; - } - std::weak_ptr clientToAddToList(TabBox::TabBoxClient *client, int desktop) const override; - int currentDesktop() const override - { - return 1; - } - std::weak_ptr desktopClient() const override - { - return std::weak_ptr(); - } - 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 nextClientFocusChain(TabBox::TabBoxClient *client) const override; - std::weak_ptr 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 createMockWindow(const QString &caption); - void closeWindow(TabBox::TabBoxClient *client); - -private: - QList> m_windows; - std::weak_ptr m_activeClient; -}; -} // namespace KWin -#endif diff --git a/autotests/tabbox/test_tabbox_clientmodel.cpp b/autotests/tabbox/test_tabbox_clientmodel.cpp deleted file mode 100644 index 5240c187a3..0000000000 --- a/autotests/tabbox/test_tabbox_clientmodel.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2012 Martin Gräßlin - - 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 -#include - -using namespace KWin; - -void TestTabBoxClientModel::initTestCase() -{ - qApp->setProperty("x11Connection", QVariant::fromValue(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(clientModel->data(index, TabBox::ClientModel::ClientRole).value()); - 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 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()); - // 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 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 clientOwner = client.lock(); - tabboxhandler.closeWindow(clientOwner.get()); - clientModel->createClientList(); - QCOMPARE(clientModel->rowCount(), 1); -} - -Q_CONSTRUCTOR_FUNCTION(forceXcb) -QTEST_MAIN(TestTabBoxClientModel) diff --git a/autotests/tabbox/test_tabbox_clientmodel.h b/autotests/tabbox/test_tabbox_clientmodel.h deleted file mode 100644 index 924bb8005a..0000000000 --- a/autotests/tabbox/test_tabbox_clientmodel.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2012 Martin Gräßlin - - SPDX-License-Identifier: GPL-2.0-or-later -*/ -#ifndef TEST_TABBOX_CLIENT_MODEL_H -#define TEST_TABBOX_CLIENT_MODEL_H -#include - -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 diff --git a/autotests/tabbox/test_tabbox_config.cpp b/autotests/tabbox/test_tabbox_config.cpp deleted file mode 100644 index a995827baa..0000000000 --- a/autotests/tabbox/test_tabbox_config.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2012 Martin Gräßlin - - SPDX-License-Identifier: GPL-2.0-or-later -*/ -#include "tabbox/tabboxconfig.h" -#include -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" diff --git a/autotests/tabbox/test_tabbox_handler.cpp b/autotests/tabbox/test_tabbox_handler.cpp deleted file mode 100644 index ac2862e162..0000000000 --- a/autotests/tabbox/test_tabbox_handler.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2012 Martin Gräßlin - - SPDX-License-Identifier: GPL-2.0-or-later -*/ -#include "../testutils.h" -#include "mock_tabboxhandler.h" -#include "tabbox/clientmodel.h" -#include -#include - -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(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" diff --git a/src/tabbox/clientmodel.cpp b/src/tabbox/clientmodel.cpp index 565d633ea4..f6b142dda9 100644 --- a/src/tabbox/clientmodel.cpp +++ b/src/tabbox/clientmodel.cpp @@ -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 + #include +#include // TODO: remove with Qt 5, only for HTML escaping the caption #include -// TODO: remove with Qt 5, only for HTML escaping the caption -#include -// other + #include 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 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(client.get()); + return QVariant::fromValue(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 &clientPointer : std::as_const(m_clientList)) { - std::shared_ptr 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 ClientModel::roleNames() const }; } -QModelIndex ClientModel::index(std::weak_ptr 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 &start) +void ClientModel::createFocusChainClientList(int desktop, Window *start) { auto c = start; - if (!tabBox->isInFocusChain(c.get())) { - std::shared_ptr firstClient = tabBox->firstClientFocusChain().lock(); + if (!tabBox->isInFocusChain(c)) { + Window *firstClient = tabBox->firstClientFocusChain(); if (firstClient) { c = firstClient; } } auto stop = c; do { - std::shared_ptr 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 &start) +void ClientModel::createStackingOrderClientList(int desktop, Window *start) { // TODO: needs improvement - const TabBoxClientList stacking = tabBox->stackingOrder(); - auto c = stacking.first().lock(); + const QList stacking = tabBox->stackingOrder(); + auto c = stacking.first(); auto stop = c; int index = 0; while (c) { - std::shared_ptr 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 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 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 client = m_mutableClientList.at(i).lock(); + Window *client = m_mutableClientList.at(i); if (client) { - client->close(); + client->closeWindow(); } } diff --git a/src/tabbox/clientmodel.h b/src/tabbox/clientmodel.h index 90d7f53ec8..ee5c97934c 100644 --- a/src/tabbox/clientmodel.h +++ b/src/tabbox/clientmodel.h @@ -13,7 +13,7 @@ #include /** * @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 * @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 * @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 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 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 &start); - void createStackingOrderClientList(int desktop, const std::shared_ptr &start); + void createFocusChainClientList(int desktop, Window *start); + void createStackingOrderClientList(int desktop, Window *start); - TabBoxClientList m_clientList; - TabBoxClientList m_mutableClientList; + QList m_clientList; + QList m_mutableClientList; }; } // namespace Tabbox diff --git a/src/tabbox/tabbox.cpp b/src/tabbox/tabbox.cpp index cbbcb54691..b2a7922ba6 100644 --- a/src/tabbox/tabbox.cpp +++ b/src/tabbox/tabbox.cpp @@ -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(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 TabBoxHandlerImpl::nextClientFocusChain(TabBoxClient *client) const +Window *TabBoxHandlerImpl::nextClientFocusChain(Window *client) const { - if (TabBoxClientImpl *c = static_cast(client)) { - auto next = Workspace::self()->focusChain()->nextMostRecentlyUsed(c->client()); - if (next) { - return std::static_pointer_cast(next->tabBoxClient().lock()); - } - } - return std::weak_ptr(); + return Workspace::self()->focusChain()->nextMostRecentlyUsed(client); } -std::weak_ptr TabBoxHandlerImpl::firstClientFocusChain() const +Window *TabBoxHandlerImpl::firstClientFocusChain() const { - if (auto c = Workspace::self()->focusChain()->firstMostRecentlyUsed()) { - return std::static_pointer_cast(c->tabBoxClient().lock()); - } else { - return std::weak_ptr(); - } + return Workspace::self()->focusChain()->firstMostRecentlyUsed(); } -bool TabBoxHandlerImpl::isInFocusChain(TabBoxClient *client) const +bool TabBoxHandlerImpl::isInFocusChain(Window *client) const { - if (TabBoxClientImpl *c = static_cast(client)) { - return Workspace::self()->focusChain()->contains(c->client()); - } - return false; + return Workspace::self()->focusChain()->contains(client); } -std::weak_ptr TabBoxHandlerImpl::activeClient() const +Window *TabBoxHandlerImpl::activeClient() const { - if (Workspace::self()->activeWindow()) { - return std::static_pointer_cast(Workspace::self()->activeWindow()->tabBoxClient().lock()); - } else { - return std::weak_ptr(); - } + return Workspace::self()->activeWindow(); } -bool TabBoxHandlerImpl::checkDesktop(TabBoxClient *client, int desktop) const +bool TabBoxHandlerImpl::checkDesktop(Window *client, int desktop) const { - auto current = (static_cast(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(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(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 client = std::dynamic_pointer_cast(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 client = std::dynamic_pointer_cast(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(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 TabBoxHandlerImpl::clientToAddToList(TabBoxClient *client, int desktop) const +Window *TabBoxHandlerImpl::clientToAddToList(Window *client, int desktop) const { if (!client) { - return std::weak_ptr(); + return nullptr; } Window *ret = nullptr; - Window *current = (static_cast(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(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(ret->tabBoxClient().lock()); - } else { - return std::weak_ptr(); - } + return ret; } -TabBoxClientList TabBoxHandlerImpl::stackingOrder() const +QList TabBoxHandlerImpl::stackingOrder() const { const QList stacking = Workspace::self()->stackingOrder(); - TabBoxClientList ret; + QList ret; for (Window *window : stacking) { if (window->isClient()) { - ret.append(std::static_pointer_cast(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(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(c)->client(), - static_cast(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(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(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 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(); + 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 windows; if (window) { - windows << static_cast(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(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 TabBox::currentClientList() { - const TabBoxClientList list = m_tabBox->clientList(); - QList ret; - for (const std::weak_ptr &clientPointer : list) { - std::shared_ptr client = clientPointer.lock(); - if (!client) { - continue; - } - if (const TabBoxClientImpl *c = static_cast(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(newClient->tabBoxClient().lock()))); + setCurrentIndex(m_tabBox->index(newClient)); } void TabBox::setCurrentIndex(QModelIndex index, bool notifyEffects) diff --git a/src/tabbox/tabbox.h b/src/tabbox/tabbox.h index fc7699cd01..93d7abac5c 100644 --- a/src/tabbox/tabbox.h +++ b/src/tabbox/tabbox.h @@ -41,60 +41,34 @@ public: ~TabBoxHandlerImpl() override; int activeScreen() const override; - std::weak_ptr 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 nextClientFocusChain(TabBoxClient *client) const override; - std::weak_ptr 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 clientToAddToList(KWin::TabBox::TabBoxClient *client, int desktop) const override; - std::weak_ptr desktopClient() const override; + Window *nextClientFocusChain(Window *client) const override; + Window *firstClientFocusChain() const override; + bool isInFocusChain(Window *client) const override; + QList 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 diff --git a/src/tabbox/tabboxconfig.h b/src/tabbox/tabboxconfig.h index f9694f0ec8..c9a80c33e3 100644 --- a/src/tabbox/tabboxconfig.h +++ b/src/tabbox/tabboxconfig.h @@ -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(); diff --git a/src/tabbox/tabboxhandler.cpp b/src/tabbox/tabboxhandler.cpp index f438fe000b..876e87f375 100644 --- a/src/tabbox/tabboxhandler.cpp +++ b/src/tabbox/tabboxhandler.cpp @@ -15,6 +15,7 @@ #include "scripting/scripting.h" #include "switcheritem.h" #include "tabbox_logging.h" +#include "window.h" // Qt #include #include @@ -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 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 &clientPointer : stackingOrder) { - if (std::shared_ptr 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 &clientPointer : stack) { - if (std::shared_ptr 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 client) const +QModelIndex TabBoxHandler::index(Window *client) const { return d->clientModel()->index(client); } -TabBoxClientList TabBoxHandler::clientList() const +QList 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( + Window *c = static_cast( d->clientModel()->data(index, ClientModel::ClientRole).value()); 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 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 diff --git a/src/tabbox/tabboxhandler.h b/src/tabbox/tabboxhandler.h index ae38b74690..5a5cdc819e 100644 --- a/src/tabbox/tabboxhandler.h +++ b/src/tabbox/tabboxhandler.h @@ -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 * @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> 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 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 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 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 stackingOrder() const = 0; /** * Determines if given client will be added to the list: *
    @@ -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 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 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 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 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 - * @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. */ diff --git a/src/window.cpp b/src/window.cpp index 3a1a9c01f8..303ae48fe4 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -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(this)) -#endif , m_colorScheme(QStringLiteral("kdeglobals")) , m_moveResizeOutput(workspace()->activeOutput()) { diff --git a/src/window.h b/src/window.h index f7b3a18fcf..8eb30cab90 100644 --- a/src/window.h +++ b/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 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 m_tabBoxClient; bool m_skipTaskbar = false; /** * Unaffected by KWin