[wayland] add enter/leave virtual desktop API
Summary: As setDesktop was changed to "move" this left unSetDesktop non-symetric. This replaces it with explicit API to enter/leave. This also moves new API to the new object based API rather than still using ints. Where numbers are used it has been tidied up so that desktop IDs are uint, which should be used when we have a list of desktops. int is used only when we have either a desktop ID or NET::OnAllDesktops (-1) Effects API cleared up to use this and use a set of x11 IDs, which avoids any potential complications of handling add and removes any ambiguity with what happens if you leave all desktops and such. Test Plan: testVirtualDesktops passes (with pending kwayland patch) Moving a window in the desktop grid on X11 behaves Moving a window in the desktop grid on wayland behaves Reviewers: #kwin, zzag Subscribers: kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D16704icc-effect-5.17.5
parent
e6cf2e3efe
commit
f521d4bbe1
|
@ -571,24 +571,29 @@ void AbstractClient::doSetDesktop(int desktop, int was_desk)
|
|||
Q_UNUSED(was_desk)
|
||||
}
|
||||
|
||||
void AbstractClient::unSetDesktop(int desktop)
|
||||
void AbstractClient::enterDesktop(VirtualDesktop *virtualDesktop)
|
||||
{
|
||||
// Case in which we are on all desktops and gets asked to unset
|
||||
if (desktop == NET::OnAllDesktops) {
|
||||
if (m_desktops.isEmpty()) {
|
||||
setOnAllDesktops(false);
|
||||
}
|
||||
if (m_desktops.contains(virtualDesktop)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Out of range
|
||||
if (desktop < 1 || desktop > VirtualDesktopManager::self()->count()) {
|
||||
return;
|
||||
}
|
||||
|
||||
VirtualDesktop *virtualDesktop = VirtualDesktopManager::self()->desktopForX11Id(desktop);
|
||||
Q_ASSERT(virtualDesktop);
|
||||
auto desktops = m_desktops;
|
||||
desktops.append(virtualDesktop);
|
||||
setDesktops(desktops);
|
||||
}
|
||||
|
||||
void AbstractClient::leaveDesktop(VirtualDesktop *virtualDesktop)
|
||||
{
|
||||
QVector<VirtualDesktop*> currentDesktops;
|
||||
if (m_desktops.isEmpty()) {
|
||||
currentDesktops = VirtualDesktopManager::self()->desktops();
|
||||
} else {
|
||||
currentDesktops = m_desktops;
|
||||
}
|
||||
|
||||
if (!currentDesktops.contains(virtualDesktop)) {
|
||||
return;
|
||||
}
|
||||
auto desktops = currentDesktops;
|
||||
desktops.removeOne(virtualDesktop);
|
||||
setDesktops(desktops);
|
||||
}
|
||||
|
@ -604,10 +609,10 @@ void AbstractClient::setOnAllDesktops(bool b)
|
|||
setDesktop(VirtualDesktopManager::self()->current());
|
||||
}
|
||||
|
||||
QVector<int> AbstractClient::x11DesktopIds() const
|
||||
QVector<uint> AbstractClient::x11DesktopIds() const
|
||||
{
|
||||
const auto desks = desktops();
|
||||
QVector<int> x11Ids;
|
||||
QVector<uint> x11Ids;
|
||||
x11Ids.reserve(desks.count());
|
||||
std::transform(desks.constBegin(), desks.constEnd(),
|
||||
std::back_inserter(x11Ids),
|
||||
|
@ -999,21 +1004,21 @@ void AbstractClient::setupWindowManagementInterface()
|
|||
[this] (const QString &desktopId) {
|
||||
VirtualDesktop *vd = VirtualDesktopManager::self()->desktopForId(desktopId.toUtf8());
|
||||
if (vd) {
|
||||
workspace()->sendClientToDesktop(this, vd->x11DesktopNumber(), false);
|
||||
enterDesktop(vd);
|
||||
}
|
||||
}
|
||||
);
|
||||
connect(w, &PlasmaWindowInterface::enterNewPlasmaVirtualDesktopRequested, this,
|
||||
[this] () {
|
||||
VirtualDesktopManager::self()->setCount(VirtualDesktopManager::self()->count() + 1);
|
||||
workspace()->sendClientToDesktop(this, VirtualDesktopManager::self()->count(), false);
|
||||
enterDesktop(VirtualDesktopManager::self()->desktops().last());
|
||||
}
|
||||
);
|
||||
connect(w, &PlasmaWindowInterface::leavePlasmaVirtualDesktopRequested, this,
|
||||
[this] (const QString &desktopId) {
|
||||
VirtualDesktop *vd = VirtualDesktopManager::self()->desktopForId(desktopId.toUtf8());
|
||||
if (vd) {
|
||||
unSetDesktop(vd->x11DesktopNumber());
|
||||
leaveDesktop(vd);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
@ -94,7 +94,7 @@ class KWIN_EXPORT AbstractClient : public Toplevel
|
|||
/**
|
||||
* The x11 ids for all desktops this client is in. On X11 this list will always have a length of 1
|
||||
**/
|
||||
Q_PROPERTY(QVector<int> x11DesktopIds READ x11DesktopIds NOTIFY x11DesktopIdsChanged)
|
||||
Q_PROPERTY(QVector<uint> x11DesktopIds READ x11DesktopIds NOTIFY x11DesktopIdsChanged)
|
||||
/**
|
||||
* Indicates that the window should not be included on a taskbar.
|
||||
**/
|
||||
|
@ -428,7 +428,10 @@ public:
|
|||
virtual bool performMouseCommand(Options::MouseCommand, const QPoint &globalPos);
|
||||
void setOnAllDesktops(bool set);
|
||||
void setDesktop(int);
|
||||
Q_INVOKABLE virtual void unSetDesktop(int desktop);
|
||||
void enterDesktop(VirtualDesktop *desktop);
|
||||
void leaveDesktop(VirtualDesktop *desktop);
|
||||
void setDesktops(QVector<VirtualDesktop *> desktops);
|
||||
|
||||
int desktop() const override {
|
||||
return m_desktops.isEmpty() ? (int)NET::OnAllDesktops : m_desktops.last()->x11DesktopNumber();
|
||||
}
|
||||
|
@ -438,7 +441,7 @@ public:
|
|||
void removeDesktop(VirtualDesktop *desktop) {
|
||||
m_desktops.removeAll(desktop);
|
||||
}
|
||||
QVector<int> x11DesktopIds() const;
|
||||
QVector<uint> x11DesktopIds() const;
|
||||
|
||||
void setMinimized(bool set);
|
||||
/**
|
||||
|
@ -1104,8 +1107,6 @@ protected:
|
|||
|
||||
bool tabTo(AbstractClient *other, bool behind, bool activate);
|
||||
|
||||
void setDesktops(QVector<VirtualDesktop *> desktops);
|
||||
|
||||
private:
|
||||
void handlePaletteChange();
|
||||
QSharedPointer<TabBox::TabBoxClientImpl> m_tabBoxClient;
|
||||
|
|
|
@ -210,7 +210,7 @@ void VirtualDesktopTest::testWindowOnMultipleDesktops()
|
|||
QCOMPARE(VirtualDesktopManager::self()->currentDesktop(), client->desktops().first());
|
||||
|
||||
//Set the window on desktop 2 as well
|
||||
client->setDesktop(2u);
|
||||
client->enterDesktop(VirtualDesktopManager::self()->desktopForX11Id(2));
|
||||
QCOMPARE(client->desktops().count(), 2u);
|
||||
QCOMPARE(VirtualDesktopManager::self()->desktops()[2], client->desktops()[0]);
|
||||
QCOMPARE(VirtualDesktopManager::self()->desktops()[1], client->desktops()[1]);
|
||||
|
@ -218,33 +218,50 @@ void VirtualDesktopTest::testWindowOnMultipleDesktops()
|
|||
QVERIFY(client->isOnDesktop(3));
|
||||
|
||||
//leave desktop 3
|
||||
client->unSetDesktop(3);
|
||||
client->leaveDesktop(VirtualDesktopManager::self()->desktopForX11Id(3));
|
||||
QCOMPARE(client->desktops().count(), 1u);
|
||||
//leave desktop 2
|
||||
client->unSetDesktop(2);
|
||||
client->leaveDesktop(VirtualDesktopManager::self()->desktopForX11Id(2));
|
||||
QCOMPARE(client->desktops().count(), 0u);
|
||||
//we should be on all desktops now
|
||||
QVERIFY(client->isOnAllDesktops());
|
||||
//put on desktop 1
|
||||
client->setDesktop(1);
|
||||
client->enterDesktop(VirtualDesktopManager::self()->desktopForX11Id(1));
|
||||
QVERIFY(client->isOnDesktop(1));
|
||||
QVERIFY(!client->isOnDesktop(2));
|
||||
QVERIFY(!client->isOnDesktop(3));
|
||||
QCOMPARE(client->desktops().count(), 1u);
|
||||
//put on desktop 2
|
||||
client->setDesktop(2);
|
||||
client->enterDesktop(VirtualDesktopManager::self()->desktopForX11Id(2));
|
||||
QVERIFY(client->isOnDesktop(1));
|
||||
QVERIFY(client->isOnDesktop(2));
|
||||
QVERIFY(!client->isOnDesktop(3));
|
||||
QCOMPARE(client->desktops().count(), 2u);
|
||||
//put on desktop 3
|
||||
client->setDesktop(3);
|
||||
client->enterDesktop(VirtualDesktopManager::self()->desktopForX11Id(3));
|
||||
QVERIFY(client->isOnDesktop(1));
|
||||
QVERIFY(client->isOnDesktop(2));
|
||||
QVERIFY(client->isOnDesktop(3));
|
||||
QVERIFY(client->isOnAllDesktops());
|
||||
//when it gets on all desktops, it loses all desktops()
|
||||
QCOMPARE(client->desktops().count(), 3u);
|
||||
|
||||
//entering twice dooes nothing
|
||||
client->enterDesktop(VirtualDesktopManager::self()->desktopForX11Id(3));
|
||||
QCOMPARE(client->desktops().count(), 3u);
|
||||
|
||||
//adding to "all desktops" results in just that one desktop
|
||||
client->setOnAllDesktops(true);
|
||||
QCOMPARE(client->desktops().count(), 0u);
|
||||
client->enterDesktop(VirtualDesktopManager::self()->desktopForX11Id(3));
|
||||
QVERIFY(client->isOnDesktop(3));
|
||||
QCOMPARE(client->desktops().count(), 1u);
|
||||
|
||||
//leaving a desktop on "all desktops" puts on everything else
|
||||
client->setOnAllDesktops(true);
|
||||
QCOMPARE(client->desktops().count(), 0u);
|
||||
client->leaveDesktop(VirtualDesktopManager::self()->desktopForX11Id(3));
|
||||
QVERIFY(client->isOnDesktop(1));
|
||||
QVERIFY(client->isOnDesktop(2));
|
||||
QCOMPARE(client->desktops().count(), 2u);
|
||||
}
|
||||
|
||||
void VirtualDesktopTest::testRemoveDesktopWithWindow_data()
|
||||
|
@ -282,7 +299,7 @@ void VirtualDesktopTest::testRemoveDesktopWithWindow()
|
|||
QCOMPARE(VirtualDesktopManager::self()->currentDesktop(), client->desktops().first());
|
||||
|
||||
//Set the window on desktop 2 as well
|
||||
client->setDesktop(2u);
|
||||
client->enterDesktop(VirtualDesktopManager::self()->desktops()[1]);
|
||||
QCOMPARE(client->desktops().count(), 2u);
|
||||
QCOMPARE(VirtualDesktopManager::self()->desktops()[2], client->desktops()[0]);
|
||||
QCOMPARE(VirtualDesktopManager::self()->desktops()[1], client->desktops()[1]);
|
||||
|
@ -298,8 +315,8 @@ void VirtualDesktopTest::testRemoveDesktopWithWindow()
|
|||
//Again 3 desktops
|
||||
VirtualDesktopManager::self()->setCount(3);
|
||||
//move window to be only on desktop 3
|
||||
client->setDesktop(3);
|
||||
client->unSetDesktop(2);
|
||||
client->enterDesktop(VirtualDesktopManager::self()->desktops()[2]);
|
||||
client->leaveDesktop(VirtualDesktopManager::self()->desktops()[1]);
|
||||
QCOMPARE(client->desktops().count(), 1u);
|
||||
//window is only on desktop 3
|
||||
QCOMPARE(VirtualDesktopManager::self()->desktops()[2], client->desktops()[0]);
|
||||
|
|
|
@ -263,6 +263,11 @@ public:
|
|||
}
|
||||
void hideOnScreenMessage(OnScreenMessageHideFlags flags = OnScreenMessageHideFlags()) override { Q_UNUSED(flags)}
|
||||
|
||||
void windowToDesktops(KWin::EffectWindow *w, const QVector<uint> &desktops) {
|
||||
Q_UNUSED(w)
|
||||
Q_UNUSED(desktops)
|
||||
}
|
||||
|
||||
KSharedConfigPtr config() const override;
|
||||
KSharedConfigPtr inputConfig() const override;
|
||||
|
||||
|
|
22
effects.cpp
22
effects.cpp
|
@ -916,6 +916,28 @@ void EffectsHandlerImpl::windowToDesktop(EffectWindow* w, int desktop)
|
|||
}
|
||||
}
|
||||
|
||||
void EffectsHandlerImpl::windowToDesktops(EffectWindow *w, const QVector<uint> &desktopIds)
|
||||
{
|
||||
AbstractClient* cl = qobject_cast< AbstractClient* >(static_cast<EffectWindowImpl*>(w)->window());
|
||||
if (!cl || cl->isDesktop() || cl->isDock()) {
|
||||
return;
|
||||
}
|
||||
QVector<VirtualDesktop*> desktops;
|
||||
desktops.reserve(desktopIds.count());
|
||||
for (uint x11Id: desktopIds) {
|
||||
if (x11Id > VirtualDesktopManager::self()->count()) {
|
||||
continue;
|
||||
}
|
||||
VirtualDesktop *d = VirtualDesktopManager::self()->desktopForX11Id(x11Id);
|
||||
Q_ASSERT(d);
|
||||
if (desktops.contains(d)) {
|
||||
continue;
|
||||
}
|
||||
desktops << d;
|
||||
}
|
||||
cl->setDesktops(desktops);
|
||||
}
|
||||
|
||||
void EffectsHandlerImpl::windowToScreen(EffectWindow* w, int screen)
|
||||
{
|
||||
AbstractClient* cl = dynamic_cast< AbstractClient* >(static_cast<EffectWindowImpl*>(w)->window());
|
||||
|
|
|
@ -260,6 +260,8 @@ public:
|
|||
return registered_atoms.contains(atom);
|
||||
}
|
||||
|
||||
void windowToDesktops(EffectWindow *w, const QVector<uint> &desktops);
|
||||
|
||||
public Q_SLOTS:
|
||||
void slotCurrentTabAboutToChange(EffectWindow* from, EffectWindow* to);
|
||||
void slotTabAdded(EffectWindow* from, EffectWindow* to);
|
||||
|
|
|
@ -525,10 +525,14 @@ void DesktopGridEffect::windowInputMouseEvent(QEvent* e)
|
|||
effects->defineCursor(Qt::ClosedHandCursor);
|
||||
}
|
||||
if (d != highlightedDesktop) {
|
||||
effects->windowToDesktop(windowMove, d); // Not true all desktop move
|
||||
if (highlightedDesktop != sourceDesktop || !wasWindowCopy) {
|
||||
effects->removeWindowFromDesktop(windowMove, highlightedDesktop);
|
||||
auto desktops = windowMove->desktops();
|
||||
if (!desktops.contains(d)) {
|
||||
desktops.append(d);
|
||||
}
|
||||
if (highlightedDesktop != sourceDesktop || !wasWindowCopy) {
|
||||
desktops.removeOne(highlightedDesktop);
|
||||
}
|
||||
effects->windowToDesktops(windowMove, desktops);
|
||||
const int screen = effects->screenNumber(me->pos());
|
||||
if (screen != windowMove->screen())
|
||||
effects->windowToScreen(windowMove, screen);
|
||||
|
@ -561,8 +565,10 @@ void DesktopGridEffect::windowInputMouseEvent(QEvent* e)
|
|||
if (desks[i] == desks[i+1])
|
||||
continue;
|
||||
foreach (EffectWindow *w, stack[i]) {
|
||||
effects->windowToDesktop(w, desks[i+1]);
|
||||
effects->removeWindowFromDesktop(w, desks[i]);
|
||||
auto desktops = w->desktops();
|
||||
desktops.removeOne(desks[i]);
|
||||
desktops.append(desks[i+1]);
|
||||
effects->windowToDesktops(w, desktops);
|
||||
|
||||
if (isUsingPresentWindows()) {
|
||||
m_managers[(desks[i]-1)*(effects->numScreens()) + w->screen()].unmanage(w);
|
||||
|
|
|
@ -762,13 +762,6 @@ bool EffectsHandler::isOpenGLCompositing() const
|
|||
return compositing_type & OpenGLCompositing;
|
||||
}
|
||||
|
||||
void EffectsHandler::removeWindowFromDesktop(KWin::EffectWindow* w, int desktop)
|
||||
{
|
||||
if (w->parent() && !w->isDesktop() && !w->isDock()) {
|
||||
QMetaObject::invokeMethod(w->parent(), "unSetDesktop", Q_ARG(int, desktop));
|
||||
}
|
||||
}
|
||||
|
||||
EffectsHandler* effects = nullptr;
|
||||
|
||||
|
||||
|
@ -855,7 +848,7 @@ WINDOW_HELPER(QString, windowRole, "windowRole")
|
|||
WINDOW_HELPER(QStringList, activities, "activities")
|
||||
WINDOW_HELPER(bool, skipsCloseAnimation, "skipsCloseAnimation")
|
||||
WINDOW_HELPER(KWayland::Server::SurfaceInterface *, surface, "surface")
|
||||
WINDOW_HELPER(QVector<int>, desktops, "x11DesktopIds")
|
||||
WINDOW_HELPER(QVector<uint>, desktops, "x11DesktopIds")
|
||||
WINDOW_HELPER(bool, isPopupWindow, "popupWindow")
|
||||
|
||||
QString EffectWindow::windowClass() const
|
||||
|
@ -983,7 +976,7 @@ bool EffectWindow::isOnCurrentDesktop() const
|
|||
|
||||
bool EffectWindow::isOnDesktop(int d) const
|
||||
{
|
||||
const QVector<int> ds = desktops();
|
||||
const QVector<uint> ds = desktops();
|
||||
return ds.isEmpty() || ds.contains(d);
|
||||
}
|
||||
|
||||
|
|
|
@ -943,15 +943,25 @@ public:
|
|||
virtual void activateWindow(KWin::EffectWindow* c) = 0;
|
||||
virtual KWin::EffectWindow* activeWindow() const = 0 ;
|
||||
Q_SCRIPTABLE virtual void moveWindow(KWin::EffectWindow* w, const QPoint& pos, bool snap = false, double snapAdjust = 1.0) = 0;
|
||||
Q_SCRIPTABLE virtual void windowToDesktop(KWin::EffectWindow* w, int desktop) = 0;
|
||||
|
||||
/**
|
||||
* Removes a window from a desktop on wayland, no-op on X11
|
||||
* Moves the window to the specific desktop
|
||||
* Setting desktop to NET::OnAllDesktops will set the window on all desktops
|
||||
*/
|
||||
Q_SCRIPTABLE void removeWindowFromDesktop(KWin::EffectWindow* w, int desktop);
|
||||
Q_SCRIPTABLE virtual void windowToDesktop(KWin::EffectWindow* w, int desktop) = 0;
|
||||
|
||||
/**
|
||||
* Moves a window to the given desktops
|
||||
* On X11, the window will end up on the last window in the list
|
||||
* Setting this to an empty list will set the window on all desktops
|
||||
*
|
||||
* @arg desktopIds a list of desktops the window should be placed on. NET::OnAllDesktops is not a valid desktop X11Id
|
||||
*/
|
||||
Q_SCRIPTABLE virtual void windowToDesktops(KWin::EffectWindow* w, const QVector<uint> &desktopIds) = 0;
|
||||
|
||||
Q_SCRIPTABLE virtual void windowToScreen(KWin::EffectWindow* w, int screen) = 0;
|
||||
virtual void setShowingDesktop(bool showing) = 0;
|
||||
|
||||
|
||||
// Activities
|
||||
/**
|
||||
* @returns The ID of the current activity.
|
||||
|
@ -2091,7 +2101,7 @@ public:
|
|||
* a length of 1, on Wayland can be any subset.
|
||||
* If the list is empty it means the window is on all desktops
|
||||
*/
|
||||
QVector<int> desktops() const;
|
||||
QVector<uint> desktops() const;
|
||||
|
||||
int x() const;
|
||||
int y() const;
|
||||
|
|
|
@ -900,7 +900,6 @@ void UserActionsMenu::slotToggleOnVirtualDesktop(QAction *action)
|
|||
return;
|
||||
}
|
||||
|
||||
Workspace *ws = Workspace::self();
|
||||
VirtualDesktopManager *vds = VirtualDesktopManager::self();
|
||||
if (desk == 0) {
|
||||
// the 'on_all_desktops' menu entry
|
||||
|
@ -912,9 +911,9 @@ void UserActionsMenu::slotToggleOnVirtualDesktop(QAction *action)
|
|||
|
||||
VirtualDesktop *virtualDesktop = VirtualDesktopManager::self()->desktopForX11Id(desk);
|
||||
if (m_client.data()->desktops().contains(virtualDesktop)) {
|
||||
m_client.data()->unSetDesktop(desk);
|
||||
m_client.data()->leaveDesktop(virtualDesktop);
|
||||
} else {
|
||||
ws->sendClientToDesktop(m_client.data(), desk, false);
|
||||
m_client.data()->enterDesktop(virtualDesktop);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue