diff --git a/src/abstract_client.cpp b/src/abstract_client.cpp index 4e8344a031..2e7609b121 100644 --- a/src/abstract_client.cpp +++ b/src/abstract_client.cpp @@ -1327,11 +1327,11 @@ void AbstractClient::handleInteractiveMoveResize(int x, int y, int x_root, int y Q_ASSERT(mode == PositionCenter); if (!isMovable()) { // isMovableAcrossScreens() must have been true to get here // Special moving of maximized windows on Xinerama screens - int screen = screens()->number(globalPos); + AbstractOutput *output = kwinApp()->platform()->outputAt(globalPos); if (isFullScreen()) - setMoveResizeGeometry(workspace()->clientArea(FullScreenArea, this, screen)); + setMoveResizeGeometry(workspace()->clientArea(FullScreenArea, this, output)); else { - QRect moveResizeGeom = workspace()->clientArea(MaximizeArea, this, screen); + QRect moveResizeGeom = workspace()->clientArea(MaximizeArea, this, output); QSize adjSize = constrainFrameSize(moveResizeGeom.size(), SizeModeMax); if (adjSize != moveResizeGeom.size()) { QRect r(moveResizeGeom); @@ -3382,8 +3382,7 @@ void AbstractClient::checkWorkspacePosition(QRect oldGeometry, QRect oldClientGe } } } else { - const int oldScreen = screens()->number(oldGeometry.center()); - oldScreenArea = workspace()->clientArea(ScreenArea, kwinApp()->platform()->findOutput(oldScreen), oldDesktop); + oldScreenArea = workspace()->clientArea(ScreenArea, kwinApp()->platform()->outputAt(oldGeometry.center()), oldDesktop); } const QRect oldGeomTall = QRect(oldGeometry.x(), oldScreenArea.y(), oldGeometry.width(), oldScreenArea.height()); // Full screen height const QRect oldGeomWide = QRect(oldScreenArea.x(), oldGeometry.y(), oldScreenArea.width(), oldGeometry.height()); // Full screen width diff --git a/src/platform.cpp b/src/platform.cpp index 3821455e11..17ce5b53c7 100644 --- a/src/platform.cpp +++ b/src/platform.cpp @@ -170,6 +170,28 @@ AbstractOutput *Platform::findOutput(const QUuid &uuid) const return nullptr; } +AbstractOutput *Platform::outputAt(const QPoint &pos) const +{ + AbstractOutput *bestOutput = nullptr; + int minDistance = INT_MAX; + const auto candidates = enabledOutputs(); + for (AbstractOutput *output : candidates) { + const QRect &geo = output->geometry(); + if (geo.contains(pos)) { + return output; + } + int distance = QPoint(geo.topLeft() - pos).manhattanLength(); + distance = std::min(distance, QPoint(geo.topRight() - pos).manhattanLength()); + distance = std::min(distance, QPoint(geo.bottomRight() - pos).manhattanLength()); + distance = std::min(distance, QPoint(geo.bottomLeft() - pos).manhattanLength()); + if (distance < minDistance) { + minDistance = distance; + bestOutput = output; + } + } + return bestOutput; +} + bool Platform::usesSoftwareCursor() const { return m_softwareCursor; diff --git a/src/platform.h b/src/platform.h index 236e2a9c59..249a2a4058 100644 --- a/src/platform.h +++ b/src/platform.h @@ -352,6 +352,7 @@ public: } AbstractOutput *findOutput(int screenId) const; AbstractOutput *findOutput(const QUuid &uuid) const; + AbstractOutput *outputAt(const QPoint &pos) const; /** * A string of information to include in kwin debug output diff --git a/src/pointer_input.cpp b/src/pointer_input.cpp index 38ca4ab953..ffd516fcfe 100644 --- a/src/pointer_input.cpp +++ b/src/pointer_input.cpp @@ -9,6 +9,7 @@ SPDX-License-Identifier: GPL-2.0-or-later */ #include "pointer_input.h" +#include "abstract_output.h" #include "platform.h" #include "x11client.h" #include "effects.h" @@ -813,8 +814,8 @@ void PointerInputRedirection::updatePosition(const QPointF &pos) const QRectF unitedScreensGeometry = screens()->geometry(); p = confineToBoundingBox(p, unitedScreensGeometry); if (!screenContainsPos(p)) { - const QRectF currentScreenGeometry = screens()->geometry(screens()->number(m_pos.toPoint())); - p = confineToBoundingBox(p, currentScreenGeometry); + const AbstractOutput *currentOutput = kwinApp()->platform()->outputAt(m_pos.toPoint()); + p = confineToBoundingBox(p, currentOutput->geometry()); } } p = applyPointerConfinement(p); @@ -903,9 +904,9 @@ void PointerInputRedirection::updateAfterScreenChange() return; } // pointer no longer on a screen, reposition to closes screen - const QPointF pos = screens()->geometry(screens()->number(m_pos.toPoint())).center(); + const AbstractOutput *output = kwinApp()->platform()->outputAt(m_pos.toPoint()); // TODO: better way to get timestamps - processMotion(pos, waylandServer()->seat()->timestamp()); + processMotion(output->geometry().center(), waylandServer()->seat()->timestamp()); } QPointF PointerInputRedirection::position() const diff --git a/src/screens.cpp b/src/screens.cpp index 262dff98a2..a7b9dbc075 100644 --- a/src/screens.cpp +++ b/src/screens.cpp @@ -295,24 +295,7 @@ int Screens::number(const QPoint &pos) const Q_UNUSED(pos) return -1; #else - int bestScreen = 0; - int minDistance = INT_MAX; - const auto outputs = kwinApp()->platform()->enabledOutputs(); - for (int i = 0; i < outputs.size(); ++i) { - const QRect &geo = outputs[i]->geometry(); - if (geo.contains(pos)) { - return i; - } - int distance = QPoint(geo.topLeft() - pos).manhattanLength(); - distance = qMin(distance, QPoint(geo.topRight() - pos).manhattanLength()); - distance = qMin(distance, QPoint(geo.bottomRight() - pos).manhattanLength()); - distance = qMin(distance, QPoint(geo.bottomLeft() - pos).manhattanLength()); - if (distance < minDistance) { - minDistance = distance; - bestScreen = i; - } - } - return bestScreen; + return kwinApp()->platform()->enabledOutputs().indexOf(kwinApp()->platform()->outputAt(pos)); #endif } diff --git a/src/workspace.cpp b/src/workspace.cpp index 906fb5d4a7..c64ba9e3d2 100644 --- a/src/workspace.cpp +++ b/src/workspace.cpp @@ -2433,9 +2433,9 @@ QPoint Workspace::adjustClientPosition(AbstractClient* c, QPoint pos, bool unres if (options->windowSnapZone() || !borderSnapZone.isNull() || options->centerSnapZone()) { const bool sOWO = options->isSnapOnlyWhenOverlapping(); - const int screen = screens()->number(pos + c->rect().center()); + const AbstractOutput *output = kwinApp()->platform()->outputAt(pos + c->rect().center()); if (maxRect.isNull()) - maxRect = clientArea(MovementArea, c, screen); + maxRect = clientArea(MovementArea, c, output); const int xmin = maxRect.left(); const int xmax = maxRect.right() + 1; //desk size const int ymin = maxRect.top(); diff --git a/src/xdgshellclient.cpp b/src/xdgshellclient.cpp index 9d0f2de01e..2e2ddaaeea 100644 --- a/src/xdgshellclient.cpp +++ b/src/xdgshellclient.cpp @@ -1565,8 +1565,8 @@ void XdgToplevelClient::setFullScreen(bool set, bool user) updateDecoration(false, false); if (set) { - const int screen = m_fullScreenRequestedOutput ? kwinApp()->platform()->enabledOutputs().indexOf(m_fullScreenRequestedOutput) : screens()->number(moveResizeGeometry().center()); - moveResize(workspace()->clientArea(FullScreenArea, this, screen)); + const AbstractOutput *output = m_fullScreenRequestedOutput ? m_fullScreenRequestedOutput.data() : kwinApp()->platform()->outputAt(moveResizeGeometry().center()); + moveResize(workspace()->clientArea(FullScreenArea, this, output)); } else { m_fullScreenRequestedOutput.clear(); if (fullscreenGeometryRestore().isValid()) {