Port Workspace::topClientOnDesktop() to VirtualDesktop
This patch has one behavioral change - raiseOrLowerClient() will not work if the client is not on the current virtual desktop. However, raiseOrLowerClient() can be called only in two cases: * user triggers the raise or lower shortcut for the active client. Since the active client is on the current virtual desktop, it's not an issue * an x11 window restacks itself. It makes no sense if an x11 window restacks itself while it's inactive or not on current virtual desktop. Also, the Opposite restack mode is rarely used, some window managers don't even bother implementing it. So, having such a constraint should not be a problem. The main reason for not allowing raiseOrLowerClient() for windows that are not on the current virtual desktop is that a window can be on multiple virtual desktops. If a window is on A and B virtual desktops, the only logical option is to toggle stacking position if the window is on the current desktop. It's the only viable option as kwin does not maintain per virtual desktop stacking order.
This commit is contained in:
parent
76e74d7660
commit
b75f089981
6 changed files with 24 additions and 19 deletions
|
@ -16,6 +16,7 @@
|
|||
#include "options.h"
|
||||
#include "screenedge.h"
|
||||
#include "screens.h"
|
||||
#include "virtualdesktops.h"
|
||||
#include "wayland_server.h"
|
||||
#include "workspace.h"
|
||||
#include "xcursortheme.h"
|
||||
|
@ -756,7 +757,7 @@ void PointerInputTest::testFocusFollowsMouse()
|
|||
AbstractClient *window2 = workspace()->activeClient();
|
||||
QVERIFY(window2);
|
||||
QVERIFY(window1 != window2);
|
||||
QCOMPARE(workspace()->topClientOnDesktop(1, -1), window2);
|
||||
QCOMPARE(workspace()->topClientOnDesktop(VirtualDesktopManager::self()->currentDesktop(), -1), window2);
|
||||
// geometry of the two windows should be overlapping
|
||||
QVERIFY(window1->frameGeometry().intersects(window2->frameGeometry()));
|
||||
|
||||
|
@ -775,18 +776,18 @@ void PointerInputTest::testFocusFollowsMouse()
|
|||
Cursors::self()->mouse()->setPos(10, 10);
|
||||
QVERIFY(stackingOrderChangedSpy.wait());
|
||||
QCOMPARE(stackingOrderChangedSpy.count(), 1);
|
||||
QCOMPARE(workspace()->topClientOnDesktop(1, -1), window1);
|
||||
QCOMPARE(workspace()->topClientOnDesktop(VirtualDesktopManager::self()->currentDesktop(), -1), window1);
|
||||
QTRY_VERIFY(window1->isActive());
|
||||
|
||||
// move on second window, but move away before active window change delay hits
|
||||
Cursors::self()->mouse()->setPos(810, 810);
|
||||
QVERIFY(stackingOrderChangedSpy.wait());
|
||||
QCOMPARE(stackingOrderChangedSpy.count(), 2);
|
||||
QCOMPARE(workspace()->topClientOnDesktop(1, -1), window2);
|
||||
QCOMPARE(workspace()->topClientOnDesktop(VirtualDesktopManager::self()->currentDesktop(), -1), window2);
|
||||
Cursors::self()->mouse()->setPos(10, 10);
|
||||
QVERIFY(!activeWindowChangedSpy.wait(250));
|
||||
QVERIFY(window1->isActive());
|
||||
QCOMPARE(workspace()->topClientOnDesktop(1, -1), window1);
|
||||
QCOMPARE(workspace()->topClientOnDesktop(VirtualDesktopManager::self()->currentDesktop(), -1), window1);
|
||||
// as we moved back on window 1 that should been raised in the mean time
|
||||
QCOMPARE(stackingOrderChangedSpy.count(), 3);
|
||||
|
||||
|
@ -842,7 +843,7 @@ void PointerInputTest::testMouseActionInactiveWindow()
|
|||
AbstractClient *window2 = workspace()->activeClient();
|
||||
QVERIFY(window2);
|
||||
QVERIFY(window1 != window2);
|
||||
QCOMPARE(workspace()->topClientOnDesktop(1, -1), window2);
|
||||
QCOMPARE(workspace()->topClientOnDesktop(VirtualDesktopManager::self()->currentDesktop(), -1), window2);
|
||||
// geometry of the two windows should be overlapping
|
||||
QVERIFY(window1->frameGeometry().intersects(window2->frameGeometry()));
|
||||
|
||||
|
@ -871,7 +872,7 @@ void PointerInputTest::testMouseActionInactiveWindow()
|
|||
// should raise window1 and activate it
|
||||
QCOMPARE(stackingOrderChangedSpy.count(), 1);
|
||||
QVERIFY(!activeWindowChangedSpy.isEmpty());
|
||||
QCOMPARE(workspace()->topClientOnDesktop(1, -1), window1);
|
||||
QCOMPARE(workspace()->topClientOnDesktop(VirtualDesktopManager::self()->currentDesktop(), -1), window1);
|
||||
QVERIFY(window1->isActive());
|
||||
QVERIFY(!window2->isActive());
|
||||
|
||||
|
@ -936,12 +937,12 @@ void PointerInputTest::testMouseActionActiveWindow()
|
|||
QVERIFY(window1 != window2);
|
||||
QSignalSpy window2DestroyedSpy(window2, &QObject::destroyed);
|
||||
QVERIFY(window2DestroyedSpy.isValid());
|
||||
QCOMPARE(workspace()->topClientOnDesktop(1, -1), window2);
|
||||
QCOMPARE(workspace()->topClientOnDesktop(VirtualDesktopManager::self()->currentDesktop(), -1), window2);
|
||||
// geometry of the two windows should be overlapping
|
||||
QVERIFY(window1->frameGeometry().intersects(window2->frameGeometry()));
|
||||
// lower the currently active window
|
||||
workspace()->lowerClient(window2);
|
||||
QCOMPARE(workspace()->topClientOnDesktop(1, -1), window1);
|
||||
QCOMPARE(workspace()->topClientOnDesktop(VirtualDesktopManager::self()->currentDesktop(), -1), window1);
|
||||
|
||||
// signal spy for stacking order spy
|
||||
QSignalSpy stackingOrderChangedSpy(workspace(), &Workspace::stackingOrderChanged);
|
||||
|
@ -959,11 +960,11 @@ void PointerInputTest::testMouseActionActiveWindow()
|
|||
QVERIFY(buttonSpy.wait());
|
||||
if (clickRaise) {
|
||||
QCOMPARE(stackingOrderChangedSpy.count(), 1);
|
||||
QTRY_COMPARE_WITH_TIMEOUT(workspace()->topClientOnDesktop(1, -1), window2, 200);
|
||||
QTRY_COMPARE_WITH_TIMEOUT(workspace()->topClientOnDesktop(VirtualDesktopManager::self()->currentDesktop(), -1), window2, 200);
|
||||
} else {
|
||||
QCOMPARE(stackingOrderChangedSpy.count(), 0);
|
||||
QVERIFY(!stackingOrderChangedSpy.wait(100));
|
||||
QCOMPARE(workspace()->topClientOnDesktop(1, -1), window1);
|
||||
QCOMPARE(workspace()->topClientOnDesktop(VirtualDesktopManager::self()->currentDesktop(), -1), window1);
|
||||
}
|
||||
|
||||
// release again
|
||||
|
|
|
@ -389,7 +389,7 @@ void AbstractClient::autoRaise()
|
|||
bool AbstractClient::isMostRecentlyRaised() const
|
||||
{
|
||||
// The last toplevel in the unconstrained stacking order is the most recently raised one.
|
||||
return workspace()->topClientOnDesktop(VirtualDesktopManager::self()->current(), -1, true, false) == this;
|
||||
return workspace()->topClientOnDesktop(VirtualDesktopManager::self()->currentDesktop(), -1, true, false) == this;
|
||||
}
|
||||
|
||||
bool AbstractClient::wantsTabFocus() const
|
||||
|
@ -2525,7 +2525,7 @@ void AbstractClient::enterEvent(const QPoint &globalPos)
|
|||
if (options->isAutoRaise() && !isDesktop() &&
|
||||
!isDock() && workspace()->focusChangeEnabled() &&
|
||||
globalPos != workspace()->focusMousePosition() &&
|
||||
workspace()->topClientOnDesktop(VirtualDesktopManager::self()->current(),
|
||||
workspace()->topClientOnDesktop(VirtualDesktopManager::self()->currentDesktop(),
|
||||
options->isSeparateScreenFocus() ? screen() : -1) != this) {
|
||||
startAutoRaise();
|
||||
}
|
||||
|
|
|
@ -218,7 +218,7 @@ void Workspace::propagateClients(bool propagate_new_clients)
|
|||
* doesn't accept focus it's excluded.
|
||||
*/
|
||||
// TODO misleading name for this method, too many slightly different ways to use it
|
||||
AbstractClient* Workspace::topClientOnDesktop(int desktop, int screen, bool unconstrained, bool only_normal) const
|
||||
AbstractClient *Workspace::topClientOnDesktop(VirtualDesktop *desktop, int screen, bool unconstrained, bool only_normal) const
|
||||
{
|
||||
// TODO Q_ASSERT( block_stacking_updates == 0 );
|
||||
QList<Toplevel *> list;
|
||||
|
@ -268,9 +268,12 @@ AbstractClient* Workspace::findDesktop(bool topmost, int desktop) const
|
|||
|
||||
void Workspace::raiseOrLowerClient(AbstractClient *c)
|
||||
{
|
||||
if (!c) return;
|
||||
if (!c || !c->isOnCurrentDesktop()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const AbstractClient *topmost =
|
||||
topClientOnDesktop(c->isOnAllDesktops() ? VirtualDesktopManager::self()->current() : c->desktop(),
|
||||
topClientOnDesktop(VirtualDesktopManager::self()->currentDesktop(),
|
||||
options->isSeparateScreenFocus() ? c->screen() : -1);
|
||||
|
||||
if (c == topmost)
|
||||
|
|
|
@ -1425,7 +1425,7 @@ void Workspace::slotWindowLower()
|
|||
if (next && next != active_client)
|
||||
requestFocus(next, false);
|
||||
} else {
|
||||
activateClient(topClientOnDesktop(VirtualDesktopManager::self()->current(), -1));
|
||||
activateClient(topClientOnDesktop(VirtualDesktopManager::self()->currentDesktop(), -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -432,7 +432,7 @@ void Workspace::initializeX11()
|
|||
&& activeClient() == nullptr && should_get_focus.count() == 0) {
|
||||
// No client activated in manage()
|
||||
if (new_active_client == nullptr)
|
||||
new_active_client = topClientOnDesktop(VirtualDesktopManager::self()->current(), -1);
|
||||
new_active_client = topClientOnDesktop(VirtualDesktopManager::self()->currentDesktop(), -1);
|
||||
if (new_active_client == nullptr)
|
||||
new_active_client = findDesktop(true, VirtualDesktopManager::self()->current());
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ class ShortcutDialog;
|
|||
class Toplevel;
|
||||
class Unmanaged;
|
||||
class UserActionsMenu;
|
||||
class VirtualDesktop;
|
||||
class X11Client;
|
||||
class X11EventFilter;
|
||||
enum class Predicate;
|
||||
|
@ -274,8 +275,8 @@ public:
|
|||
QList<X11Client *> ensureStackingOrder(const QList<X11Client *> &clients) const;
|
||||
QList<AbstractClient*> ensureStackingOrder(const QList<AbstractClient*> &clients) const;
|
||||
|
||||
AbstractClient* topClientOnDesktop(int desktop, int screen, bool unconstrained = false,
|
||||
bool only_normal = true) const;
|
||||
AbstractClient *topClientOnDesktop(VirtualDesktop *desktop, int screen, bool unconstrained = false,
|
||||
bool only_normal = true) const;
|
||||
AbstractClient* findDesktop(bool topmost, int desktop) const;
|
||||
void sendClientToDesktop(AbstractClient* c, int desktop, bool dont_activate);
|
||||
void windowToPreviousDesktop(AbstractClient* c);
|
||||
|
|
Loading…
Reference in a new issue