Add Workspace::clientArea() that take no desktop

The new overloads take the client (as context) and the desired screen id
or a point and return the client area.

The main motivation behind this change is to make the transition to the
new virtual desktop model where a window can be on several desktops less
painful.
This commit is contained in:
Vlad Zahorodnii 2021-08-17 14:55:34 +03:00
parent 2b88432b17
commit d5c2518973
7 changed files with 62 additions and 38 deletions

View file

@ -84,7 +84,7 @@ AbstractClient::AbstractClient()
Q_UNUSED(c)
if (isOnScreenDisplay() && !frameGeometry().isEmpty() && old.size() != frameGeometry().size() && isPlaceable()) {
GeometryUpdatesBlocker blocker(this);
placeIn(workspace()->clientArea(PlacementArea, Screens::self()->current(), desktop()));
placeIn(workspace()->clientArea(PlacementArea, this, Screens::self()->current()));
}
}
);
@ -1020,7 +1020,7 @@ void AbstractClient::checkUnrestrictedInteractiveMoveResize()
if (isUnrestrictedInteractiveMoveResize())
return;
const QRect &moveResizeGeom = moveResizeGeometry();
QRect desktopArea = workspace()->clientArea(WorkArea, moveResizeGeom.center(), desktop());
QRect desktopArea = workspace()->clientArea(WorkArea, this, moveResizeGeom.center());
int left_marge, right_marge, top_marge, bottom_marge, titlebar_marge;
// restricted move/resize - keep at least part of the titlebar always visible
// how much must remain visible when moved away in that direction
@ -1221,7 +1221,7 @@ void AbstractClient::handleInteractiveMoveResize(int x, int y, int x_root, int y
// Make sure the titlebar isn't behind a restricted area. We don't need to restrict
// the other directions. If not visible enough, move the window to the closest valid
// point. We bruteforce this by slowly moving the window back to its previous position
QRegion availableArea(workspace()->clientArea(FullArea, -1, 0)); // On the screen
QRegion availableArea(workspace()->clientArea(FullArea, this, -1)); // On the screen
availableArea -= workspace()->restrictedMoveArea(desktop()); // Strut areas
bool transposed = false;
int requiredPixels;
@ -1328,9 +1328,9 @@ void AbstractClient::handleInteractiveMoveResize(int x, int y, int x_root, int y
// Special moving of maximized windows on Xinerama screens
int screen = screens()->number(globalPos);
if (isFullScreen())
setMoveResizeGeometry(workspace()->clientArea(FullScreenArea, screen, 0));
setMoveResizeGeometry(workspace()->clientArea(FullScreenArea, this, screen));
else {
QRect moveResizeGeom = workspace()->clientArea(MaximizeArea, screen, 0);
QRect moveResizeGeom = workspace()->clientArea(MaximizeArea, this, screen);
QSize adjSize = constrainFrameSize(moveResizeGeom.size(), SizeModeMax);
if (adjSize != moveResizeGeom.size()) {
QRect r(moveResizeGeom);
@ -1349,7 +1349,7 @@ void AbstractClient::handleInteractiveMoveResize(int x, int y, int x_root, int y
if (!isUnrestrictedInteractiveMoveResize()) {
const QRegion strut = workspace()->restrictedMoveArea(desktop()); // Strut areas
QRegion availableArea(workspace()->clientArea(FullArea, -1, 0)); // On the screen
QRegion availableArea(workspace()->clientArea(FullArea, this, -1)); // On the screen
availableArea -= strut; // Strut areas
bool transposed = false;
int requiredPixels;
@ -2172,7 +2172,7 @@ void AbstractClient::checkQuickTilingMaximizationZones(int xroot, int yroot)
return false;
};
QRect area = workspace()->clientArea(MaximizeArea, QPoint(xroot, yroot), desktop());
QRect area = workspace()->clientArea(MaximizeArea, this, QPoint(xroot, yroot));
if (options->electricBorderTiling()) {
if (xroot <= area.x() + 20) {
mode |= QuickTileFlag::Left;
@ -3247,7 +3247,7 @@ void AbstractClient::sendToScreen(int newScreen)
setQuickTileMode(QuickTileFlag::None, true);
QRect oldScreenArea = workspace()->clientArea(MaximizeArea, this);
QRect screenArea = workspace()->clientArea(MaximizeArea, newScreen, desktop());
QRect screenArea = workspace()->clientArea(MaximizeArea, this, newScreen);
// the window can have its center so that the position correction moves the new center onto
// the old screen, what will tile it where it is. Ie. the screen is not changed
@ -3301,7 +3301,7 @@ void AbstractClient::sendToScreen(int newScreen)
void AbstractClient::updateGeometryRestoresForFullscreen(int screen)
{
QRect screenArea = workspace()->clientArea(MaximizeArea, screen, desktop());
QRect screenArea = workspace()->clientArea(MaximizeArea, this, screen);
QRect newFullScreenGeometryRestore = screenArea;
if (!(maximizeMode() & MaximizeVertical)) {
newFullScreenGeometryRestore.setHeight(geometryRestore().height());
@ -3335,7 +3335,7 @@ void AbstractClient::checkWorkspacePosition(QRect oldGeometry, int oldDesktop, Q
if (!oldClientGeometry.isValid())
oldClientGeometry = oldGeometry.adjusted(border[Left], border[Top], -border[Right], -border[Bottom]);
if (isFullScreen()) {
moveResize(workspace()->clientArea(FullScreenArea, fullscreenGeometryRestore().center(), desktop()));
moveResize(workspace()->clientArea(FullScreenArea, this, fullscreenGeometryRestore().center()));
return;
}
@ -3343,7 +3343,7 @@ void AbstractClient::checkWorkspacePosition(QRect oldGeometry, int oldDesktop, Q
GeometryUpdatesBlocker block(this);
changeMaximize(false, false, true); // adjust size
QRect geom = moveResizeGeometry();
const QRect screenArea = workspace()->clientArea(ScreenArea, geom.center(), desktop());
const QRect screenArea = workspace()->clientArea(ScreenArea, this, geom.center());
checkOffscreenPosition(&geom, screenArea);
moveResize(geom);
return;
@ -3386,7 +3386,7 @@ void AbstractClient::checkWorkspacePosition(QRect oldGeometry, int oldDesktop, Q
int oldRightMax = oldScreenArea.x() + oldScreenArea.width();
int oldBottomMax = oldScreenArea.y() + oldScreenArea.height();
int oldLeftMax = oldScreenArea.x();
const QRect screenArea = workspace()->clientArea(ScreenArea, geometryRestore().center(), desktop());
const QRect screenArea = workspace()->clientArea(ScreenArea, this, geometryRestore().center());
int topMax = screenArea.y();
int rightMax = screenArea.x() + screenArea.width();
int bottomMax = screenArea.y() + screenArea.height();

View file

@ -71,7 +71,7 @@ void KWin::InputPanelV1Client::reposition()
if (waylandServer()->isScreenLocked()) {
availableArea = m_output->geometry();
} else {
availableArea = workspace()->clientArea(MaximizeArea, m_output, desktop());
availableArea = workspace()->clientArea(MaximizeArea, this, m_output);
}
QRect geo(availableArea.topLeft(), panelSize);
geo.translate((availableArea.width() - panelSize.width())/2, availableArea.height() - panelSize.height());

View file

@ -364,7 +364,7 @@ void Placement::reinitCascading(int desktop)
QPoint Workspace::cascadeOffset(const AbstractClient *c) const
{
QRect area = clientArea(PlacementArea, c->frameGeometry().center(), c->desktop());
QRect area = clientArea(PlacementArea, c, c->frameGeometry().center());
return QPoint(area.width()/48, area.height()/48);
}
@ -729,7 +729,8 @@ void AbstractClient::growHorizontal()
// check that it hasn't grown outside of the area, due to size increments
// TODO this may be wrong?
if (workspace()->clientArea(MovementArea,
QPoint((x() + newright) / 2, moveResizeGeometry().center().y()), desktop()).right() >= newright)
this,
QPoint((x() + newright) / 2, moveResizeGeometry().center().y())).right() >= newright)
geom.setRight(newright);
}
geom.setSize(constrainFrameSize(geom.size(), SizeModeFixedW));
@ -776,7 +777,8 @@ void AbstractClient::growVertical()
int newbottom = workspace()->packPositionDown(this, geom.bottom() + resizeIncrements().height() - 1, true);
// check that it hasn't grown outside of the area, due to size increments
if (workspace()->clientArea(MovementArea,
QPoint(moveResizeGeometry().center().x(), (y() + newbottom) / 2), desktop()).bottom() >= newbottom)
this,
QPoint(moveResizeGeometry().center().x(), (y() + newbottom) / 2)).bottom() >= newbottom)
geom.setBottom(newbottom);
}
geom.setSize(constrainFrameSize(geom.size(), SizeModeFixedH));
@ -838,7 +840,8 @@ int Workspace::packPositionLeft(const AbstractClient *client, int oldX, bool lef
int newX = clientArea(MaximizeArea, client).left();
if (oldX <= newX) { // try another Xinerama screen
newX = clientArea(MaximizeArea,
QPoint(client->frameGeometry().left() - 1, client->frameGeometry().center().y()), client->desktop()).left();
client,
QPoint(client->frameGeometry().left() - 1, client->frameGeometry().center().y())).left();
}
if (client->titlebarPosition() != AbstractClient::PositionLeft) {
const int right = newX - client->frameMargins().left();
@ -871,7 +874,8 @@ int Workspace::packPositionRight(const AbstractClient *client, int oldX, bool ri
int newX = clientArea(MaximizeArea, client).right();
if (oldX >= newX) { // try another Xinerama screen
newX = clientArea(MaximizeArea,
QPoint(client->frameGeometry().right() + 1, client->frameGeometry().center().y()), client->desktop()).right();
client,
QPoint(client->frameGeometry().right() + 1, client->frameGeometry().center().y())).right();
}
if (client->titlebarPosition() != AbstractClient::PositionRight) {
const int right = newX + client->frameMargins().right();
@ -904,7 +908,8 @@ int Workspace::packPositionUp(const AbstractClient *client, int oldY, bool topEd
int newY = clientArea(MaximizeArea, client).top();
if (oldY <= newY) { // try another Xinerama screen
newY = clientArea(MaximizeArea,
QPoint(client->frameGeometry().center().x(), client->frameGeometry().top() - 1), client->desktop()).top();
client,
QPoint(client->frameGeometry().center().x(), client->frameGeometry().top() - 1)).top();
}
if (client->titlebarPosition() != AbstractClient::PositionTop) {
const int top = newY - client->frameMargins().top();
@ -937,7 +942,8 @@ int Workspace::packPositionDown(const AbstractClient *client, int oldY, bool bot
int newY = clientArea(MaximizeArea, client).bottom();
if (oldY >= newY) { // try another Xinerama screen
newY = clientArea(MaximizeArea,
QPoint(client->frameGeometry().center().x(), client->frameGeometry().bottom() + 1), client->desktop()).bottom();
client,
QPoint(client->frameGeometry().center().x(), client->frameGeometry().bottom() + 1)).bottom();
}
if (client->titlebarPosition() != AbstractClient::PositionBottom) {
const int bottom = newY + client->frameMargins().bottom();

View file

@ -792,7 +792,7 @@ void Workspace::addShellClient(AbstractClient *client)
client->updateLayer();
if (client->isPlaceable()) {
const QRect area = clientArea(PlacementArea, Screens::self()->current(), client->desktop());
const QRect area = clientArea(PlacementArea, client, Screens::self()->current());
bool placementDone = false;
if (client->isRequestedFullScreen()) {
placementDone = true;
@ -1920,7 +1920,7 @@ void Workspace::addInternalClient(InternalClient *client)
client->updateLayer();
if (client->isPlaceable()) {
const QRect area = clientArea(PlacementArea, screens()->current(), client->desktop());
const QRect area = clientArea(PlacementArea, client, screens()->current());
client->placeIn(area);
}
@ -2387,6 +2387,21 @@ QRect Workspace::clientArea(clientAreaOption opt, const AbstractClient* c) const
return clientArea(opt, c->frameGeometry().center(), c->desktop());
}
QRect Workspace::clientArea(clientAreaOption opt, const AbstractClient *client, const AbstractOutput *output) const
{
return clientArea(opt, client, output->geometry().center());
}
QRect Workspace::clientArea(clientAreaOption opt, const AbstractClient *client, int screen) const
{
return clientArea(opt, screen, client->desktop());
}
QRect Workspace::clientArea(clientAreaOption opt, const AbstractClient *client, const QPoint &pos) const
{
return clientArea(opt, client, screens()->number(pos));
}
static QRegion strutsToRegion(int desktop, StrutAreas areas, const QVector<StrutRects> &struts)
{
if (desktop == NETWinInfo::OnAllDesktops || desktop == 0)
@ -2446,7 +2461,7 @@ QPoint Workspace::adjustClientPosition(AbstractClient* c, QPoint pos, bool unres
QRect maxRect;
int guideMaximized = MaximizeRestore;
if (c->maximizeMode() != MaximizeRestore) {
maxRect = clientArea(MaximizeArea, pos + c->rect().center(), c->desktop());
maxRect = clientArea(MaximizeArea, c, pos + c->rect().center());
QRect geo = c->frameGeometry();
if (c->maximizeMode() & MaximizeHorizontal && (geo.x() == maxRect.left() || geo.right() == maxRect.right())) {
guideMaximized |= MaximizeHorizontal;
@ -2463,7 +2478,7 @@ QPoint Workspace::adjustClientPosition(AbstractClient* c, QPoint pos, bool unres
const bool sOWO = options->isSnapOnlyWhenOverlapping();
const int screen = screens()->number(pos + c->rect().center());
if (maxRect.isNull())
maxRect = clientArea(MovementArea, screen, c->desktop());
maxRect = clientArea(MovementArea, c, screen);
const int xmin = maxRect.left();
const int xmax = maxRect.right() + 1; //desk size
const int ymin = maxRect.top();
@ -2633,7 +2648,7 @@ QRect Workspace::adjustClientSize(AbstractClient* c, QRect moveResizeGeom, int m
if (options->windowSnapZone() || options->borderSnapZone()) { // || options->centerSnapZone )
const bool sOWO = options->isSnapOnlyWhenOverlapping();
const QRect maxRect = clientArea(MovementArea, c->rect().center(), c->desktop());
const QRect maxRect = clientArea(MovementArea, c, c->rect().center());
const int xmin = maxRect.left();
const int xmax = maxRect.right(); //desk size
const int ymin = maxRect.top();

View file

@ -142,6 +142,9 @@ public:
QRect clientArea(clientAreaOption, const QPoint& p, int desktop) const;
QRect clientArea(clientAreaOption, const AbstractClient* c) const;
QRect clientArea(clientAreaOption, const AbstractClient *client, const AbstractOutput *output) const;
QRect clientArea(clientAreaOption, const AbstractClient *client, int screen) const;
QRect clientArea(clientAreaOption, const AbstractClient *client, const QPoint &pos) const;
QRect clientArea(clientAreaOption, int screen, int desktop) const;
QRect clientArea(clientAreaOption, const AbstractOutput *output, int desktop) const;

View file

@ -604,12 +604,12 @@ bool X11Client::manage(xcb_window_t w, bool isMapped)
QRect area;
bool partial_keep_in_area = isMapped || session;
if (isMapped || session) {
area = workspace()->clientArea(FullArea, geom.center(), desktop());
area = workspace()->clientArea(FullArea, this, geom.center());
checkOffscreenPosition(&geom, area);
} else {
int screen = asn_data.xinerama() == -1 ? screens()->current() : asn_data.xinerama();
screen = rules()->checkScreen(screen, !isMapped);
area = workspace()->clientArea(PlacementArea, screens()->geometry(screen).center(), desktop());
area = workspace()->clientArea(PlacementArea, this, screens()->geometry(screen).center());
}
if (isDesktop())
@ -648,7 +648,7 @@ bool X11Client::manage(xcb_window_t w, bool isMapped)
if (m_geometryHints.hasPosition()) {
placementDone = true;
// Disobey xinerama placement option for now (#70943)
area = workspace()->clientArea(PlacementArea, geom.center(), desktop());
area = workspace()->clientArea(PlacementArea, this, geom.center());
}
}
@ -682,7 +682,7 @@ bool X11Client::manage(xcb_window_t w, bool isMapped)
placementDone = true;
// Don't keep inside workarea if the window has specially configured position
partial_keep_in_area = true;
area = workspace()->clientArea(FullArea, geom.center(), desktop());
area = workspace()->clientArea(FullArea, this, geom.center());
}
if (!placementDone) {
// Placement needs to be after setting size
@ -707,8 +707,8 @@ bool X11Client::manage(xcb_window_t w, bool isMapped)
if (isMaximizable() && (width() >= area.width() || height() >= area.height())) {
// Window is too large for the screen, maximize in the
// directions necessary
const QSize ss = workspace()->clientArea(ScreenArea, area.center(), desktop()).size();
const QRect fsa = workspace()->clientArea(FullArea, geom.center(), desktop());
const QSize ss = workspace()->clientArea(ScreenArea, this, area.center()).size();
const QRect fsa = workspace()->clientArea(FullArea, this, geom.center());
const QSize cs = clientSize();
int pseudo_max = ((info->state() & NET::MaxVert) ? MaximizeVertical : 0) |
((info->state() & NET::MaxHoriz) ? MaximizeHorizontal : 0);
@ -4132,7 +4132,7 @@ void X11Client::changeMaximize(bool horizontal, bool vertical, bool adjust)
QRect clientArea;
if (isElectricBorderMaximizing())
clientArea = workspace()->clientArea(MaximizeArea, Cursors::self()->mouse()->pos(), desktop());
clientArea = workspace()->clientArea(MaximizeArea, this, Cursors::self()->mouse()->pos());
else
clientArea = workspace()->clientArea(MaximizeArea, this);
@ -4336,7 +4336,7 @@ void X11Client::changeMaximize(bool horizontal, bool vertical, bool adjust)
const bool overWidth = r.width() > clientArea.width();
if (closeWidth || closeHeight) {
Position titlePos = titlebarPosition();
const QRect screenArea = workspace()->clientArea(ScreenArea, clientArea.center(), desktop());
const QRect screenArea = workspace()->clientArea(ScreenArea, this, clientArea.center());
if (closeHeight) {
bool tryBottom = titlePos == PositionBottom;
if ((overHeight && titlePos == PositionTop) ||

View file

@ -1235,7 +1235,7 @@ void XdgToplevelClient::initialize()
needsPlacement = false;
}
if (needsPlacement) {
const QRect area = workspace()->clientArea(PlacementArea, Screens::self()->current(), desktop());
const QRect area = workspace()->clientArea(PlacementArea, this, Screens::self()->current());
placeIn(area);
}
@ -1566,7 +1566,7 @@ void XdgToplevelClient::setFullScreen(bool set, bool user)
if (set) {
const int screen = m_fullScreenRequestedOutput ? kwinApp()->platform()->enabledOutputs().indexOf(m_fullScreenRequestedOutput) : screens()->number(moveResizeGeometry().center());
moveResize(workspace()->clientArea(FullScreenArea, screen, desktop()));
moveResize(workspace()->clientArea(FullScreenArea, this, screen));
} else {
m_fullScreenRequestedOutput.clear();
if (fullscreenGeometryRestore().isValid()) {
@ -1600,8 +1600,8 @@ void XdgToplevelClient::changeMaximize(bool horizontal, bool vertical, bool adju
}
const QRect clientArea = isElectricBorderMaximizing() ?
workspace()->clientArea(MaximizeArea, Cursors::self()->mouse()->pos(), desktop()) :
workspace()->clientArea(MaximizeArea, moveResizeGeometry().center(), desktop());
workspace()->clientArea(MaximizeArea, this, Cursors::self()->mouse()->pos()) :
workspace()->clientArea(MaximizeArea, this, moveResizeGeometry().center());
const MaximizeMode oldMode = m_requestedMaximizeMode;
const QRect oldGeometry = moveResizeGeometry();
@ -2058,7 +2058,7 @@ void XdgPopupClient::initialize()
updateReactive();
const QRect area = workspace()->clientArea(PlacementArea, Screens::self()->current(), desktop());
const QRect area = workspace()->clientArea(PlacementArea, this, Screens::self()->current());
placeIn(area);
scheduleConfigure();
}