diff --git a/autotests/client/test_plasma_window_model.cpp b/autotests/client/test_plasma_window_model.cpp --- a/autotests/client/test_plasma_window_model.cpp +++ b/autotests/client/test_plasma_window_model.cpp @@ -70,6 +70,7 @@ void testIsOnAllDesktops(); void testIsDemandingAttention(); void testSkipTaskbar(); + void testSkipSwitcher(); void testIsShadeable(); void testIsShaded(); void testIsMovable(); @@ -235,6 +236,7 @@ QTest::newRow("IsOnAllDesktops") << int(PlasmaWindowModel::IsOnAllDesktops) << QByteArrayLiteral("IsOnAllDesktops"); QTest::newRow("IsDemandingAttention") << int(PlasmaWindowModel::IsDemandingAttention) << QByteArrayLiteral("IsDemandingAttention"); QTest::newRow("SkipTaskbar") << int(PlasmaWindowModel::SkipTaskbar) << QByteArrayLiteral("SkipTaskbar"); + QTest::newRow("SkipSwitcher") << int(PlasmaWindowModel::SkipSwitcher) << QByteArrayLiteral("SkipSwitcher"); QTest::newRow("IsShadeable") << int(PlasmaWindowModel::IsShadeable) << QByteArrayLiteral("IsShadeable"); QTest::newRow("IsShaded") << int(PlasmaWindowModel::IsShaded) << QByteArrayLiteral("IsShaded"); QTest::newRow("IsMovable") << int(PlasmaWindowModel::IsMovable) << QByteArrayLiteral("IsMovable"); @@ -414,6 +416,11 @@ QVERIFY(testBooleanData(PlasmaWindowModel::SkipTaskbar, &PlasmaWindowInterface::setSkipTaskbar)); } +void PlasmaWindowModelTest::testSkipSwitcher() +{ + QVERIFY(testBooleanData(PlasmaWindowModel::SkipSwitcher, &PlasmaWindowInterface::setSkipSwitcher)); +} + void PlasmaWindowModelTest::testIsShadeable() { QVERIFY(testBooleanData(PlasmaWindowModel::IsShadeable, &PlasmaWindowInterface::setShadeable)); diff --git a/autotests/client/test_plasmashell.cpp b/autotests/client/test_plasmashell.cpp --- a/autotests/client/test_plasmashell.cpp +++ b/autotests/client/test_plasmashell.cpp @@ -47,6 +47,7 @@ void testRole(); void testPosition(); void testSkipTaskbar(); + void testSkipSwitcher(); void testPanelBehavior_data(); void testPanelBehavior(); void testAutoHidePanel(); @@ -297,6 +298,41 @@ QVERIFY(!sps->skipTaskbar()); } +void TestPlasmaShell::testSkipSwitcher() +{ + // this test verifies that Skip Switcher is properly passed to server + QSignalSpy plasmaSurfaceCreatedSpy(m_plasmaShellInterface, &PlasmaShellInterface::surfaceCreated); + QVERIFY(plasmaSurfaceCreatedSpy.isValid()); + + QScopedPointer s(m_compositor->createSurface()); + QScopedPointer ps(m_plasmaShell->createSurface(s.data())); + QVERIFY(plasmaSurfaceCreatedSpy.wait()); + QCOMPARE(plasmaSurfaceCreatedSpy.count(), 1); + + // verify that we got a plasma shell surface + auto sps = plasmaSurfaceCreatedSpy.first().first().value(); + QVERIFY(sps); + QVERIFY(sps->surface()); + QVERIFY(!sps->skipSwitcher()); + + // now change + QSignalSpy skipSwitcherChangedSpy(sps, &PlasmaShellSurfaceInterface::skipSwitcherChanged); + QVERIFY(skipSwitcherChangedSpy.isValid()); + ps->setSkipSwitcher(true); + QVERIFY(skipSwitcherChangedSpy.wait()); + QVERIFY(sps->skipSwitcher()); + // setting to same again should not emit the signal + ps->setSkipSwitcher(true); + QEXPECT_FAIL("", "Should not be emitted if not changed", Continue); + QVERIFY(!skipSwitcherChangedSpy.wait(100)); + QVERIFY(sps->skipSwitcher()); + + // setting to false should change again + ps->setSkipSwitcher(false); + QVERIFY(skipSwitcherChangedSpy.wait()); + QVERIFY(!sps->skipSwitcher()); +} + void TestPlasmaShell::testPanelBehavior_data() { QTest::addColumn("client"); diff --git a/autotests/client/test_wayland_windowmanagement.cpp b/autotests/client/test_wayland_windowmanagement.cpp --- a/autotests/client/test_wayland_windowmanagement.cpp +++ b/autotests/client/test_wayland_windowmanagement.cpp @@ -407,6 +407,7 @@ QTest::newRow("maximizable") << &PlasmaWindowInterface::maximizeableRequested << int(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZABLE); QTest::newRow("fullscreenable") << &PlasmaWindowInterface::fullscreenableRequested << int(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_FULLSCREENABLE); QTest::newRow("skiptaskbar") << &PlasmaWindowInterface::skipTaskbarRequested << int(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPTASKBAR); + QTest::newRow("skipSwitcher") << &PlasmaWindowInterface::skipSwitcherRequested << int(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPSWITCHER); QTest::newRow("shadeable") << &PlasmaWindowInterface::shadeableRequested << int(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADEABLE); QTest::newRow("shaded") << &PlasmaWindowInterface::shadedRequested << int(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADED); QTest::newRow("movable") << &PlasmaWindowInterface::movableRequested << int(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MOVABLE); diff --git a/src/client/plasmashell.h b/src/client/plasmashell.h --- a/src/client/plasmashell.h +++ b/src/client/plasmashell.h @@ -287,6 +287,13 @@ */ void setSkipTaskbar(bool skip); + /** + * Setting this bit on a window will indicate it does not prefer + * to be included in a window switcher. + * @since 5.45 + */ + void setSkipSwitcher(bool skip); + /** * Requests to hide a surface with Role Panel and PanelBahvior AutoHide. * diff --git a/src/client/plasmashell.cpp b/src/client/plasmashell.cpp --- a/src/client/plasmashell.cpp +++ b/src/client/plasmashell.cpp @@ -322,6 +322,11 @@ org_kde_plasma_surface_set_skip_taskbar(d->surface, skip); } +void PlasmaShellSurface::setSkipSwitcher(bool skip) +{ + org_kde_plasma_surface_set_skip_switcher(d->surface, skip); +} + void PlasmaShellSurface::requestHideAutoHidingPanel() { org_kde_plasma_surface_panel_auto_hide_hide(d->surface); diff --git a/src/client/plasmawindowmanagement.h b/src/client/plasmawindowmanagement.h --- a/src/client/plasmawindowmanagement.h +++ b/src/client/plasmawindowmanagement.h @@ -342,6 +342,11 @@ * @see skipTaskbarChanged **/ bool skipTaskbar() const; + /** + * @returns Whether the window should be ignored by a switcher. + * @see skipSwitcherChanged + **/ + bool skipSwitcher() const; /** * @returns The icon of the window. * @see iconChanged @@ -556,6 +561,11 @@ * @see skipTaskbar **/ void skipTaskbarChanged(); + /** + * The skip switcher state changed. + * @see skipSwitcher + **/ + void skipSwitcherChanged(); /** * The window icon changed. * @see icon diff --git a/src/client/plasmawindowmanagement.cpp b/src/client/plasmawindowmanagement.cpp --- a/src/client/plasmawindowmanagement.cpp +++ b/src/client/plasmawindowmanagement.cpp @@ -82,6 +82,7 @@ bool maximizeable = false; bool fullscreenable = false; bool skipTaskbar = false; + bool skipSwitcher = false; bool shadeable = false; bool shaded = false; bool movable = false; @@ -120,6 +121,7 @@ void setMaximizeable(bool set); void setFullscreenable(bool set); void setSkipTaskbar(bool skip); + void setSkipSwitcher(bool skip); void setShadeable(bool set); void setShaded(bool set); void setMovable(bool set); @@ -473,6 +475,7 @@ p->setMaximizeable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZABLE); p->setMinimizeable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZABLE); p->setSkipTaskbar(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPTASKBAR); + p->setSkipSwitcher(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPSWITCHER); p->setShadeable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADEABLE); p->setShaded(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADED); p->setMovable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MOVABLE); @@ -671,6 +674,15 @@ emit q->skipTaskbarChanged(); } +void PlasmaWindow::Private::setSkipSwitcher(bool skip) +{ + if (skipSwitcher == skip) { + return; + } + skipSwitcher = skip; + emit q->skipSwitcherChanged(); +} + void PlasmaWindow::Private::setShadeable(bool set) { if (shadeable == set) { @@ -845,6 +857,10 @@ return d->skipTaskbar; } +bool PlasmaWindow::skipSwitcher() const +{ + return d->skipSwitcher; +} QIcon PlasmaWindow::icon() const { diff --git a/src/client/plasmawindowmodel.h b/src/client/plasmawindowmodel.h --- a/src/client/plasmawindowmodel.h +++ b/src/client/plasmawindowmodel.h @@ -105,7 +105,11 @@ /** * @since 5.35 */ - Pid + Pid, + /** + * @since 5.45 + */ + SkipSwitcher, }; Q_ENUM(AdditionalRoles) diff --git a/src/client/plasmawindowmodel.cpp b/src/client/plasmawindowmodel.cpp --- a/src/client/plasmawindowmodel.cpp +++ b/src/client/plasmawindowmodel.cpp @@ -133,6 +133,10 @@ [window, this] { this->dataChanged(window, SkipTaskbar); } ); + QObject::connect(window, &PlasmaWindow::skipSwitcherChanged, q, + [window, this] { this->dataChanged(window, SkipSwitcher); } + ); + QObject::connect(window, &PlasmaWindow::shadeableChanged, q, [window, this] { this->dataChanged(window, IsShadeable); } ); @@ -253,6 +257,8 @@ return window->isDemandingAttention(); } else if (role == SkipTaskbar) { return window->skipTaskbar(); + } else if (role == SkipSwitcher) { + return window->skipSwitcher(); } else if (role == IsShadeable) { return window->isShadeable(); } else if (role == IsShaded) { diff --git a/src/client/protocols/plasma-shell.xml b/src/client/protocols/plasma-shell.xml --- a/src/client/protocols/plasma-shell.xml +++ b/src/client/protocols/plasma-shell.xml @@ -130,7 +130,7 @@ --> - + An interface that may be implemented by a wl_surface, for implementations that provide the shell user interface. @@ -332,7 +332,7 @@ Setting this bit to the window, will make it say it prefers to not be listed in the taskbar. Taskbar implementations may or may not follow this hint. - + @@ -384,5 +384,14 @@ An auto-hiding panel got shown by the compositor. + + + + + Setting this bit will indicate that the window prefers not to be listed in a switcher. + + + + diff --git a/src/client/protocols/plasma-window-management.xml b/src/client/protocols/plasma-window-management.xml --- a/src/client/protocols/plasma-window-management.xml +++ b/src/client/protocols/plasma-window-management.xml @@ -17,7 +17,7 @@ along with this program. If not, see . ]]> - + This interface manages application windows. It provides requests to show and hide the desktop and emits @@ -46,6 +46,7 @@ + diff --git a/src/client/registry.cpp b/src/client/registry.cpp --- a/src/client/registry.cpp +++ b/src/client/registry.cpp @@ -163,14 +163,14 @@ &Registry::subCompositorRemoved }}, {Registry::Interface::PlasmaShell, { - 4, + 5, QByteArrayLiteral("org_kde_plasma_shell"), &org_kde_plasma_shell_interface, &Registry::plasmaShellAnnounced, &Registry::plasmaShellRemoved }}, {Registry::Interface::PlasmaWindowManagement, { - 7, + 9, QByteArrayLiteral("org_kde_plasma_window_management"), &org_kde_plasma_window_management_interface, &Registry::plasmaWindowManagementAnnounced, diff --git a/src/server/plasmashell_interface.h b/src/server/plasmashell_interface.h --- a/src/server/plasmashell_interface.h +++ b/src/server/plasmashell_interface.h @@ -135,9 +135,16 @@ * @returns true if this window doesn't want to be listed * in the taskbar * @since 5.5 - */ + **/ bool skipTaskbar() const; + /** + * @returns true if this window doesn't want to be listed + * in a window switcher + * @since 5.45 + **/ + bool skipSwitcher() const; + /** * Informs the PlasmaShellSurfaceInterface that the auto-hiding panel got hidden. * Once it is shown again the method {@link showAutoHidingPanel} should be used. @@ -192,6 +199,10 @@ * A change in the skip taskbar property has been requested */ void skipTaskbarChanged(); + /** + * A change in the skip switcher property has been requested + **/ + void skipSwitcherChanged(); /** * A surface with Role Panel and PanelBehavior AutoHide requested to be hidden. diff --git a/src/server/plasmashell_interface.cpp b/src/server/plasmashell_interface.cpp --- a/src/server/plasmashell_interface.cpp +++ b/src/server/plasmashell_interface.cpp @@ -50,7 +50,7 @@ static const quint32 s_version; }; -const quint32 PlasmaShellInterface::Private::s_version = 4; +const quint32 PlasmaShellInterface::Private::s_version = 5; PlasmaShellInterface::Private::Private(PlasmaShellInterface *q, Display *d) : Global::Private(d, &org_kde_plasma_shell_interface, s_version) @@ -76,6 +76,7 @@ bool m_positionSet = false; PanelBehavior m_panelBehavior = PanelBehavior::AlwaysVisible; bool m_skipTaskbar = false; + bool m_skipSwitcher = false; bool panelTakesFocus = false; private: @@ -85,6 +86,7 @@ static void setRoleCallback(wl_client *client, wl_resource *resource, uint32_t role); static void setPanelBehaviorCallback(wl_client *client, wl_resource *resource, uint32_t flag); static void setSkipTaskbarCallback(wl_client *client, wl_resource *resource, uint32_t skip); + static void setSkipSwitcherCallback(wl_client *client, wl_resource *resource, uint32_t skip); static void panelAutoHideHideCallback(wl_client *client, wl_resource *resource); static void panelAutoHideShowCallback(wl_client *client, wl_resource *resource); static void panelTakesFocusCallback(wl_client *client, wl_resource *resource, uint32_t takesFocus); @@ -165,7 +167,8 @@ setSkipTaskbarCallback, panelAutoHideHideCallback, panelAutoHideShowCallback, - panelTakesFocusCallback + panelTakesFocusCallback, + setSkipSwitcherCallback }; #endif @@ -277,6 +280,14 @@ emit s->q_func()->skipTaskbarChanged(); } +void PlasmaShellSurfaceInterface::Private::setSkipSwitcherCallback(wl_client *client, wl_resource *resource, uint32_t skip) +{ + auto s = cast(resource); + Q_ASSERT(client == *s->client); + s->m_skipSwitcher = (bool)skip; + emit s->q_func()->skipSwitcherChanged(); +} + void PlasmaShellSurfaceInterface::Private::panelAutoHideHideCallback(wl_client *client, wl_resource *resource) { auto s = cast(resource); @@ -361,6 +372,12 @@ return d->m_skipTaskbar; } +bool PlasmaShellSurfaceInterface::skipSwitcher() const +{ + Q_D(); + return d->m_skipSwitcher; +} + void PlasmaShellSurfaceInterface::hideAutoHidingPanel() { Q_D(); diff --git a/src/server/plasmawindowmanagement_interface.h b/src/server/plasmawindowmanagement_interface.h --- a/src/server/plasmawindowmanagement_interface.h +++ b/src/server/plasmawindowmanagement_interface.h @@ -108,6 +108,7 @@ void setMaximizeable(bool set); void setFullscreenable(bool set); void setSkipTaskbar(bool skip); + void setSkipSwitcher(bool skip); /** * @deprecated since 5.28 use setIcon * @see setIcon @@ -204,6 +205,7 @@ void maximizeableRequested(bool set); void fullscreenableRequested(bool set); void skipTaskbarRequested(bool set); + void skipSwitcherRequested(bool set); QRect minimizedGeometriesChanged(); /** * @since 5.22 diff --git a/src/server/plasmawindowmanagement_interface.cpp b/src/server/plasmawindowmanagement_interface.cpp --- a/src/server/plasmawindowmanagement_interface.cpp +++ b/src/server/plasmawindowmanagement_interface.cpp @@ -119,7 +119,7 @@ static const struct org_kde_plasma_window_interface s_interface; }; -const quint32 PlasmaWindowManagementInterface::Private::s_version = 7; +const quint32 PlasmaWindowManagementInterface::Private::s_version = 9; PlasmaWindowManagementInterface::Private::Private(PlasmaWindowManagementInterface *q, Display *d) : Global::Private(d, &org_kde_plasma_window_management_interface, s_version) @@ -602,6 +602,9 @@ if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPTASKBAR) { emit p->q->skipTaskbarRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPTASKBAR); } + if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPSWITCHER) { + emit p->q->skipSwitcherRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPSWITCHER); + } if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADEABLE) { emit p->q->shadeableRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADEABLE); } @@ -761,6 +764,11 @@ d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPTASKBAR, set); } +void PlasmaWindowInterface::setSkipSwitcher(bool skip) +{ + d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPSWITCHER, skip); +} + #ifndef KWAYLANDSERVER_NO_DEPRECATED void PlasmaWindowInterface::setThemedIconName(const QString &iconName) { diff --git a/tests/plasmasurfacetest.cpp b/tests/plasmasurfacetest.cpp --- a/tests/plasmasurfacetest.cpp +++ b/tests/plasmasurfacetest.cpp @@ -49,6 +49,10 @@ m_skipTaskbar = set; } + void setSkipSwitcher(bool set) { + m_skipSwitcher = set; + } + private: void setupRegistry(Registry *registry); void render(); @@ -64,6 +68,7 @@ PlasmaShellSurface *m_plasmaShellSurface = nullptr; PlasmaShellSurface::Role m_role = PlasmaShellSurface::Role::Normal; bool m_skipTaskbar = false; + bool m_skipSwitcher = false; }; PlasmaSurfaceTest::PlasmaSurfaceTest(QObject *parent) @@ -136,6 +141,7 @@ m_plasmaShellSurface = m_plasmaShell->createSurface(m_surface, this); Q_ASSERT(m_plasmaShellSurface); m_plasmaShellSurface->setSkipTaskbar(m_skipTaskbar); + m_plasmaShellSurface->setSkipSwitcher(m_skipSwitcher); m_plasmaShellSurface->setRole(m_role); render(); } @@ -177,6 +183,9 @@ QCommandLineOption skipTaskbarOption(QStringLiteral("skipTaskbar")); parser.addOption(skipTaskbarOption); parser.process(app); + QCommandLineOption skipSwitcherOption(QStringLiteral("skipSwitcher")); + parser.addOption(skipSwitcherOption); + parser.process(app); PlasmaSurfaceTest client; @@ -192,6 +201,7 @@ client.setRole(PlasmaShellSurface::Role::ToolTip); } client.setSkipTaskbar(parser.isSet(skipTaskbarOption)); + client.setSkipSwitcher(parser.isSet(skipSwitcherOption)); client.init();