diff --git a/autotests/kwindowinfox11test.cpp b/autotests/kwindowinfox11test.cpp --- a/autotests/kwindowinfox11test.cpp +++ b/autotests/kwindowinfox11test.cpp @@ -192,14 +192,15 @@ { QTest::addColumn("state"); - QTest::newRow("max") << NET::States(NET::Max); - QTest::newRow("maxHoriz") << NET::States(NET::MaxHoriz); - QTest::newRow("shaded") << NET::States(NET::Shaded); - QTest::newRow("skipTaskbar") << NET::States(NET::SkipTaskbar); - QTest::newRow("skipPager") << NET::States(NET::SkipPager); - QTest::newRow("keep above") << NET::States(NET::KeepAbove); - QTest::newRow("keep below") << NET::States(NET::KeepBelow); - QTest::newRow("fullscreen") << NET::States(NET::FullScreen); + QTest::newRow("max") << NET::States(NET::Max); + QTest::newRow("maxHoriz") << NET::States(NET::MaxHoriz); + QTest::newRow("shaded") << NET::States(NET::Shaded); + QTest::newRow("skipTaskbar") << NET::States(NET::SkipTaskbar); + QTest::newRow("skipPager") << NET::States(NET::SkipPager); + QTest::newRow("skipSwitcher") << NET::States(NET::SkipSwitcher); + QTest::newRow("keep above") << NET::States(NET::KeepAbove); + QTest::newRow("keep below") << NET::States(NET::KeepBelow); + QTest::newRow("fullscreen") << NET::States(NET::FullScreen); // NOTE: modal, sticky and hidden cannot be tested with this variant // demands attention is not tested as that's already part of the first run adjustments diff --git a/autotests/netwininfotestwm.cpp b/autotests/netwininfotestwm.cpp --- a/autotests/netwininfotestwm.cpp +++ b/autotests/netwininfotestwm.cpp @@ -429,6 +429,7 @@ const QByteArray maxHoriz = QByteArrayLiteral("_NET_WM_STATE_MAXIMIZED_HORZ"); const QByteArray shaded = QByteArrayLiteral("_NET_WM_STATE_SHADED"); const QByteArray skipTaskbar = QByteArrayLiteral("_NET_WM_STATE_SKIP_TASKBAR"); + const QByteArray skipSwitcher = QByteArrayLiteral("_NET_WM_STATE_SKIP_SWITCHER"); const QByteArray keepAbove = QByteArrayLiteral("_NET_WM_STATE_ABOVE"); const QByteArray staysOnTop = QByteArrayLiteral("_NET_WM_STATE_STAYS_ON_TOP"); const QByteArray skipPager = QByteArrayLiteral("_NET_WM_STATE_SKIP_PAGER"); @@ -450,6 +451,7 @@ QTest::newRow("fullScreen") << NET::States(NET::FullScreen) << (QVector() << fullScreen); QTest::newRow("keepBelow") << NET::States(NET::KeepBelow) << (QVector() << keepBelow); QTest::newRow("demandsAttention") << NET::States(NET::DemandsAttention) << (QVector() << demandsAttention); + QTest::newRow("skipSwitcher") << NET::States(NET::SkipSwitcher) << (QVector() << skipSwitcher); // TODO: it's possible to be keep above and below at the same time?!? QTest::newRow("all") << NET::States(NET::Modal | @@ -462,11 +464,12 @@ NET::KeepBelow | NET::Hidden | NET::FullScreen | - NET::DemandsAttention) + NET::DemandsAttention | + NET::SkipSwitcher) << (QVector() << modal << sticky << maxVert << maxHoriz << shaded << skipTaskbar << keepAbove << skipPager << hidden << fullScreen - << keepBelow << demandsAttention << staysOnTop); + << keepBelow << demandsAttention << staysOnTop << skipSwitcher); } void NetWinInfoTestWM::testState() diff --git a/src/kwindowsystem.h b/src/kwindowsystem.h --- a/src/kwindowsystem.h +++ b/src/kwindowsystem.h @@ -345,7 +345,8 @@ * Possible values are or'ed combinations of NET::Modal, * NET::Sticky, NET::MaxVert, NET::MaxHoriz, NET::Shaded, * NET::SkipTaskbar, NET::SkipPager, NET::Hidden, - * NET::FullScreen, NET::KeepAbove, NET::KeepBelow, NET::StaysOnTop + * NET::FullScreen, NET::KeepAbove, NET::KeepBelow, NET::StaysOnTop, + * NET::SkipSwitcher * * @param win the id of the window * @param state the new flags that will be set @@ -358,7 +359,8 @@ * Possible values are or'ed combinations of NET::Modal, * NET::Sticky, NET::MaxVert, NET::MaxHoriz, NET::Shaded, * NET::SkipTaskbar, NET::SkipPager, NET::Hidden, - * NET::FullScreen, NET::KeepAbove, NET::KeepBelow, NET::StaysOnTop + * NET::FullScreen, NET::KeepAbove, NET::KeepBelow, NET::StaysOnTop, + * NET::SkipSwitcher * * @param win the id of the window * @param state the flags that will be cleared diff --git a/src/netwm_def.h b/src/netwm_def.h --- a/src/netwm_def.h +++ b/src/netwm_def.h @@ -418,10 +418,10 @@ To set the state of a window, you'll typically do something like: \code - KWindowSystem::setState( winId(), NET::SkipTaskbar | NET::SkipPager ); + KWindowSystem::setState( winId(), NET::SkipTaskbar | NET::SkipPager | NET::SkipSwitcher ); \endcode - for example to not show the window on the taskbar and desktop pager. + for example to not show the window on the taskbar, desktop pager, or window switcher. winId() is a function of QWidget() Note that KeepAbove (StaysOnTop) and KeepBelow are meant as user preference and @@ -489,11 +489,18 @@ **/ KeepBelow = 1u << 10, /** + indicates that a window should not be included on a switcher. + + @since 5.45 + **/ + SkipSwitcher = 1u << 11, + /** there was an attempt to activate this window, but the window manager prevented this. E.g. taskbar should mark such window specially to bring user's attention to this window. Only the window manager is allowed to change it. **/ - DemandsAttention = 1u << 11 + DemandsAttention = 1u << 12 + }; Q_DECLARE_FLAGS(States, State) diff --git a/src/platforms/xcb/atoms_p.h b/src/platforms/xcb/atoms_p.h --- a/src/platforms/xcb/atoms_p.h +++ b/src/platforms/xcb/atoms_p.h @@ -133,6 +133,7 @@ ENUM(_NET_WM_STATE_ABOVE), ENUM(_NET_WM_STATE_BELOW), ENUM(_NET_WM_STATE_DEMANDS_ATTENTION), + ENUM(_NET_WM_STATE_SKIP_SWITCHER), // allowed actions ENUM(_NET_WM_ACTION_MOVE), diff --git a/src/platforms/xcb/netwm.cpp b/src/platforms/xcb/netwm.cpp --- a/src/platforms/xcb/netwm.cpp +++ b/src/platforms/xcb/netwm.cpp @@ -23,7 +23,7 @@ */ -//#define NETWMDEBUG +// #define NETWMDEBUG #include "netwm.h" #include @@ -1003,6 +1003,9 @@ if (p->states & SkipPager) { atoms[pnum++] = p->atom(_NET_WM_STATE_SKIP_PAGER); } + if (p->states & SkipSwitcher) { + atoms[pnum++] = p->atom(_NET_WM_STATE_SKIP_SWITCHER); + } if (p->states & Hidden) { atoms[pnum++] = p->atom(_NET_WM_STATE_HIDDEN); } @@ -1316,6 +1319,8 @@ p->states |= SkipTaskbar; } else if (atom == p->atom(_NET_WM_STATE_SKIP_PAGER)) { p->states |= SkipPager; + } else if (atom == p->atom(_NET_WM_STATE_SKIP_SWITCHER)) { + p->states |= SkipSwitcher; } else if (atom == p->atom(_NET_WM_STATE_HIDDEN)) { p->states |= Hidden; } else if (atom == p->atom(_NET_WM_STATE_FULLSCREEN)) { @@ -2973,6 +2978,14 @@ xcb_send_event(p->conn, false, p->root, netwm_sendevent_mask, (const char *) &event); } + if ((mask & SkipSwitcher) && ((p->state & SkipSwitcher) != (state & SkipSwitcher))) { + event.data.data32[0] = (state & SkipSwitcher) ? 1 : 0; + event.data.data32[1] = p->atom(_NET_WM_STATE_SKIP_SWITCHER); + event.data.data32[2] = 0l; + + xcb_send_event(p->conn, false, p->root, netwm_sendevent_mask, (const char *) &event); + } + if ((mask & Hidden) && ((p->state & Hidden) != (state & Hidden))) { event.data.data32[0] = (state & Hidden) ? 1 : 0; event.data.data32[1] = p->atom(_NET_WM_STATE_HIDDEN); @@ -3070,6 +3083,9 @@ if (p->state & SkipPager) { data[count++] = p->atom(_NET_WM_STATE_SKIP_PAGER); } + if (p->state & SkipSwitcher) { + data[count++] = p->atom(_NET_WM_STATE_SKIP_SWITCHER); + } #ifdef NETWMDEBUG fprintf(stderr, "NETWinInfo::setState: setting state property (%d)\n", count); @@ -3633,6 +3649,8 @@ mask |= SkipTaskbar; } else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_SKIP_PAGER)) { mask |= SkipPager; + } else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_SKIP_SWITCHER)) { + mask |= SkipSwitcher; } else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_HIDDEN)) { mask |= Hidden; } else if ((xcb_atom_t) message->data.data32[i] == p->atom(_NET_WM_STATE_FULLSCREEN)) { @@ -4042,6 +4060,10 @@ p->state |= SkipPager; } + else if (state == p->atom(_NET_WM_STATE_SKIP_SWITCHER)) { + p->state |= SkipSwitcher; + } + else if (state == p->atom(_NET_WM_STATE_HIDDEN)) { p->state |= Hidden; }