Make WindowRules::checkDesktop take a list of desktops
This ports relevant apis in WindowRules to the VirtualDesktop class. If the client has no desktop rule, the desktop list that has been passed to the checkDesktops() function will be returned. If the client has a desktop window rule, the checkDesktop() function will return a list with a single VirtualDesktop object or none if the window is forced to be on all virtual desktops.
This commit is contained in:
parent
8e8fc55b0b
commit
7f04d730e6
6 changed files with 85 additions and 40 deletions
|
@ -424,7 +424,6 @@ void AbstractClient::setDesktop(int desktop)
|
|||
const int numberOfDesktops = VirtualDesktopManager::self()->count();
|
||||
if (desktop != NET::OnAllDesktops) // Do range check
|
||||
desktop = qMax(1, qMin(numberOfDesktops, desktop));
|
||||
desktop = qMin(numberOfDesktops, rules()->checkDesktop(desktop));
|
||||
|
||||
QVector<VirtualDesktop *> desktops;
|
||||
if (desktop != NET::OnAllDesktops) {
|
||||
|
@ -440,6 +439,7 @@ void AbstractClient::setDesktops(QVector<VirtualDesktop*> desktops)
|
|||
desktops = QVector<VirtualDesktop*>({desktops.last()});
|
||||
}
|
||||
|
||||
desktops = rules()->checkDesktops(desktops);
|
||||
if (desktops == m_desktops) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "x11client.h"
|
||||
#include "client_machine.h"
|
||||
#include "screens.h"
|
||||
#include "virtualdesktops.h"
|
||||
#include "workspace.h"
|
||||
#endif
|
||||
|
||||
|
@ -561,11 +562,26 @@ APPLY_FORCE_RULE(opacityactive, OpacityActive, int)
|
|||
APPLY_FORCE_RULE(opacityinactive, OpacityInactive, int)
|
||||
APPLY_RULE(ignoregeometry, IgnoreGeometry, bool)
|
||||
|
||||
APPLY_RULE(desktop, Desktop, int)
|
||||
APPLY_RULE(screen, Screen, int)
|
||||
APPLY_RULE(activity, Activity, QStringList)
|
||||
APPLY_FORCE_RULE(type, Type, NET::WindowType)
|
||||
|
||||
bool Rules::applyDesktops(QVector<VirtualDesktop *> &desktops, bool init) const
|
||||
{
|
||||
if (checkSetRule(desktoprule, init)) {
|
||||
if (desktop == NET::OnAllDesktops) {
|
||||
desktops = {};
|
||||
} else {
|
||||
if (auto vd = VirtualDesktopManager::self()->desktopForX11Id(desktop)) {
|
||||
desktops = {vd};
|
||||
} else {
|
||||
desktops = {VirtualDesktopManager::self()->currentDesktop()};
|
||||
}
|
||||
}
|
||||
}
|
||||
return checkSetStop(desktoprule);
|
||||
}
|
||||
|
||||
bool Rules::applyMaximizeHoriz(MaximizeMode& mode, bool init) const
|
||||
{
|
||||
if (checkSetRule(maximizehorizrule, init))
|
||||
|
@ -776,7 +792,7 @@ CHECK_FORCE_RULE(OpacityActive, int)
|
|||
CHECK_FORCE_RULE(OpacityInactive, int)
|
||||
CHECK_RULE(IgnoreGeometry, bool)
|
||||
|
||||
CHECK_RULE(Desktop, int)
|
||||
CHECK_RULE(Desktops, QVector<VirtualDesktop *>)
|
||||
CHECK_RULE(Activity, QStringList)
|
||||
CHECK_FORCE_RULE(Type, NET::WindowType)
|
||||
CHECK_RULE(MaximizeVert, MaximizeMode)
|
||||
|
@ -852,7 +868,7 @@ void AbstractClient::applyWindowRules()
|
|||
moveResize(geom);
|
||||
// MinSize, MaxSize handled by Geometry
|
||||
// IgnoreGeometry
|
||||
setDesktop(desktop());
|
||||
setDesktops(desktops());
|
||||
workspace()->sendClientToScreen(this, screen());
|
||||
setOnActivities(activities());
|
||||
// Type
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace KWin
|
|||
class AbstractClient;
|
||||
class Rules;
|
||||
class RuleSettings;
|
||||
class VirtualDesktop;
|
||||
|
||||
#ifndef KCMRULES // only for kwin core
|
||||
|
||||
|
@ -51,7 +52,7 @@ public:
|
|||
int checkOpacityActive(int s) const;
|
||||
int checkOpacityInactive(int s) const;
|
||||
bool checkIgnoreGeometry(bool ignore, bool init = false) const;
|
||||
int checkDesktop(int desktop, bool init = false) const;
|
||||
QVector<VirtualDesktop *> checkDesktops(QVector<VirtualDesktop *> desktops, bool init = false) const;
|
||||
int checkScreen(int screen, bool init = false) const;
|
||||
QStringList checkActivity(QStringList activity, bool init = false) const;
|
||||
NET::WindowType checkType(NET::WindowType type) const;
|
||||
|
@ -145,7 +146,7 @@ public:
|
|||
bool applyOpacityActive(int& s) const;
|
||||
bool applyOpacityInactive(int& s) const;
|
||||
bool applyIgnoreGeometry(bool& ignore, bool init) const;
|
||||
bool applyDesktop(int& desktop, bool init) const;
|
||||
bool applyDesktops(QVector<VirtualDesktop *> &desktops, bool init) const;
|
||||
bool applyScreen(int& desktop, bool init) const;
|
||||
bool applyActivity(QStringList& activity, bool init) const;
|
||||
bool applyType(NET::WindowType& type) const;
|
||||
|
|
|
@ -398,41 +398,46 @@ void Edge::switchDesktop(const QPoint &cursorPos)
|
|||
{
|
||||
QPoint pos(cursorPos);
|
||||
VirtualDesktopManager *vds = VirtualDesktopManager::self();
|
||||
const uint oldDesktop = vds->current();
|
||||
uint desktop = oldDesktop;
|
||||
VirtualDesktop *oldDesktop = vds->currentDesktop();
|
||||
VirtualDesktop *desktop = oldDesktop;
|
||||
const int OFFSET = 2;
|
||||
if (isLeft()) {
|
||||
const uint interimDesktop = desktop;
|
||||
const VirtualDesktop *interimDesktop = desktop;
|
||||
desktop = vds->toLeft(desktop, vds->isNavigationWrappingAround());
|
||||
if (desktop != interimDesktop)
|
||||
if (desktop != interimDesktop) {
|
||||
pos.setX(screens()->size().width() - 1 - OFFSET);
|
||||
}
|
||||
} else if (isRight()) {
|
||||
const uint interimDesktop = desktop;
|
||||
const VirtualDesktop *interimDesktop = desktop;
|
||||
desktop = vds->toRight(desktop, vds->isNavigationWrappingAround());
|
||||
if (desktop != interimDesktop)
|
||||
if (desktop != interimDesktop) {
|
||||
pos.setX(OFFSET);
|
||||
}
|
||||
}
|
||||
if (isTop()) {
|
||||
const uint interimDesktop = desktop;
|
||||
const VirtualDesktop *interimDesktop = desktop;
|
||||
desktop = vds->above(desktop, vds->isNavigationWrappingAround());
|
||||
if (desktop != interimDesktop)
|
||||
if (desktop != interimDesktop) {
|
||||
pos.setY(screens()->size().height() - 1 - OFFSET);
|
||||
}
|
||||
} else if (isBottom()) {
|
||||
const uint interimDesktop = desktop;
|
||||
const VirtualDesktop *interimDesktop = desktop;
|
||||
desktop = vds->below(desktop, vds->isNavigationWrappingAround());
|
||||
if (desktop != interimDesktop)
|
||||
if (desktop != interimDesktop) {
|
||||
pos.setY(OFFSET);
|
||||
}
|
||||
}
|
||||
#ifndef KWIN_UNIT_TEST
|
||||
if (AbstractClient *c = Workspace::self()->moveResizeClient()) {
|
||||
if (c->rules()->checkDesktop(desktop) != int(desktop)) {
|
||||
const QVector<VirtualDesktop *> desktops{desktop};
|
||||
if (c->rules()->checkDesktops(desktops) != desktops) {
|
||||
// user attempts to move a client to another desktop where it is ruleforced to not be
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
vds->setCurrent(desktop);
|
||||
if (vds->current() != oldDesktop) {
|
||||
if (vds->currentDesktop() != oldDesktop) {
|
||||
m_pushBackBlocked = true;
|
||||
Cursors::self()->mouse()->setPos(pos);
|
||||
QSharedPointer<QMetaObject::Connection> me(new QMetaObject::Connection);
|
||||
|
|
|
@ -499,11 +499,16 @@ bool X11Client::manage(xcb_window_t w, bool isMapped)
|
|||
readActivities(activitiesCookie);
|
||||
|
||||
// Initial desktop placement
|
||||
int desk = 0;
|
||||
std::optional<QVector<VirtualDesktop *>> initialDesktops;
|
||||
if (session) {
|
||||
desk = session->desktop;
|
||||
if (session->onAllDesktops)
|
||||
desk = NET::OnAllDesktops;
|
||||
if (session->onAllDesktops) {
|
||||
initialDesktops = QVector<VirtualDesktop *>{};
|
||||
} else {
|
||||
VirtualDesktop *desktop = VirtualDesktopManager::self()->desktopForX11Id(session->desktop);
|
||||
if (desktop) {
|
||||
initialDesktops = QVector<VirtualDesktop *>{desktop};
|
||||
}
|
||||
}
|
||||
setOnActivities(session->activities);
|
||||
} else {
|
||||
// If this window is transient, ensure that it is opened on the
|
||||
|
@ -528,20 +533,34 @@ bool X11Client::manage(xcb_window_t w, bool isMapped)
|
|||
if ((*it)->isOnAllDesktops())
|
||||
on_all = true;
|
||||
}
|
||||
if (on_all)
|
||||
desk = NET::OnAllDesktops;
|
||||
else if (on_current)
|
||||
desk = VirtualDesktopManager::self()->current();
|
||||
else if (maincl != nullptr)
|
||||
desk = maincl->desktop();
|
||||
if (on_all) {
|
||||
initialDesktops = QVector<VirtualDesktop *>{};
|
||||
} else if (on_current) {
|
||||
initialDesktops = QVector<VirtualDesktop *>{VirtualDesktopManager::self()->currentDesktop()};
|
||||
} else if (maincl) {
|
||||
initialDesktops = maincl->desktops();
|
||||
}
|
||||
|
||||
if (maincl)
|
||||
setOnActivities(maincl->activities());
|
||||
} else { // a transient shall appear on its leader and not drag that around
|
||||
if (info->desktop())
|
||||
desk = info->desktop(); // Window had the initial desktop property, force it
|
||||
if (desktop() == 0 && asn_valid && asn_data.desktop() != 0)
|
||||
desk = asn_data.desktop();
|
||||
int desktopId = 0;
|
||||
if (info->desktop()) {
|
||||
desktopId = info->desktop(); // Window had the initial desktop property, force it
|
||||
}
|
||||
if (desktop() == 0 && asn_valid && asn_data.desktop() != 0) {
|
||||
desktopId = asn_data.desktop();
|
||||
}
|
||||
if (desktopId) {
|
||||
if (desktopId == NET::OnAllDesktops) {
|
||||
initialDesktops = QVector<VirtualDesktop *>{};
|
||||
} else {
|
||||
VirtualDesktop *desktop = VirtualDesktopManager::self()->desktopForX11Id(desktopId);
|
||||
if (desktop) {
|
||||
initialDesktops = QVector<VirtualDesktop *>{desktop};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef KWIN_BUILD_ACTIVITIES
|
||||
if (Activities::self() && !isMapped && !skipTaskbar() && isNormalWindow() && !activitiesDefined) {
|
||||
|
@ -557,13 +576,17 @@ bool X11Client::manage(xcb_window_t w, bool isMapped)
|
|||
#endif
|
||||
}
|
||||
|
||||
if (desk == 0) // Assume window wants to be visible on the current desktop
|
||||
desk = isDesktop() ? static_cast<int>(NET::OnAllDesktops) : VirtualDesktopManager::self()->current();
|
||||
desk = rules()->checkDesktop(desk, !isMapped);
|
||||
if (desk != NET::OnAllDesktops) // Do range check
|
||||
desk = qBound(1, desk, static_cast<int>(VirtualDesktopManager::self()->count()));
|
||||
setDesktop(desk);
|
||||
info->setDesktop(desk);
|
||||
// If initialDesktops has no value, it means that the client doesn't prefer any
|
||||
// desktop so place it on the current virtual desktop.
|
||||
if (!initialDesktops.has_value()) {
|
||||
if (isDesktop()) {
|
||||
initialDesktops = QVector<VirtualDesktop *>{};
|
||||
} else {
|
||||
initialDesktops = QVector<VirtualDesktop *>{VirtualDesktopManager::self()->currentDesktop()};
|
||||
}
|
||||
}
|
||||
setDesktops(rules()->checkDesktops(*initialDesktops, !isMapped));
|
||||
info->setDesktop(desktop());
|
||||
workspace()->updateOnAllDesktopsOfTransients(this); // SELI TODO
|
||||
//onAllDesktopsChange(); // Decoration doesn't exist here yet
|
||||
|
||||
|
|
|
@ -1205,7 +1205,7 @@ void XdgToplevelClient::initialize()
|
|||
maximize(rules()->checkMaximize(initialMaximizeMode(), true));
|
||||
setFullScreen(rules()->checkFullScreen(initialFullScreenMode(), true), false);
|
||||
setOnActivities(rules()->checkActivity(activities(), true));
|
||||
setDesktop(rules()->checkDesktop(desktop(), true));
|
||||
setDesktops(rules()->checkDesktops(desktops(), true));
|
||||
setDesktopFileName(rules()->checkDesktopFile(desktopFileName(), true).toUtf8());
|
||||
if (rules()->checkMinimize(isMinimized(), true)) {
|
||||
minimize(true); // No animation.
|
||||
|
|
Loading…
Reference in a new issue