diff --git a/autotests/mock_effectshandler.h b/autotests/mock_effectshandler.h index b6229979b3..3c819ff9bb 100644 --- a/autotests/mock_effectshandler.h +++ b/autotests/mock_effectshandler.h @@ -24,8 +24,8 @@ public: bool hasActiveFullScreenEffect() const override { return false; } - int activeScreen() const override { - return 0; + KWin::EffectScreen *activeScreen() const override { + return nullptr; } KWin::EffectWindow *activeWindow() const override { return nullptr; @@ -46,7 +46,7 @@ public: QRect clientArea(KWin::clientAreaOption, const KWin::EffectWindow *) const override { return QRect(); } - QRect clientArea(KWin::clientAreaOption, int, int) const override { + QRect clientArea(KWin::clientAreaOption, const KWin::EffectScreen *, int) const override { return QRect(); } void closeTabBox() override {} @@ -183,9 +183,6 @@ public: QPainter *scenePainter() override { return nullptr; } - int screenNumber(const QPoint &) const override { - return 0; - } void setActiveFullScreenEffect(KWin::Effect *) override {} void setCurrentDesktop(int) override {} void setElevatedWindow(KWin::EffectWindow *, bool) override {} @@ -210,7 +207,7 @@ public: return QSize(); } void windowToDesktop(KWin::EffectWindow *, int) override {} - void windowToScreen(KWin::EffectWindow *, int) override {} + void windowToScreen(KWin::EffectWindow *, KWin::EffectScreen *) override {} int workspaceHeight() const override { return 0; } diff --git a/autotests/test_window_paint_data.cpp b/autotests/test_window_paint_data.cpp index b980d9bc70..22af4bd867 100644 --- a/autotests/test_window_paint_data.cpp +++ b/autotests/test_window_paint_data.cpp @@ -105,8 +105,8 @@ public: QRect clientGeometry() const override { return QRect(); } - int screen() const override { - return 0; + EffectScreen *screen() const override { + return nullptr; } QPoint pos() const override { return QPoint(); diff --git a/src/abstract_output.h b/src/abstract_output.h index 42ee58dfcf..8183715c52 100644 --- a/src/abstract_output.h +++ b/src/abstract_output.h @@ -25,7 +25,7 @@ class OutputChangeSetV2; namespace KWin { - +class EffectScreenImpl; class RenderLoop; class KWIN_EXPORT GammaRamp @@ -266,7 +266,9 @@ Q_SIGNALS: private: Q_DISABLE_COPY(AbstractOutput) + EffectScreenImpl *m_effectScreen = nullptr; int m_directScanoutCount = 0; + friend class EffectScreenImpl; // to access m_effectScreen }; KWIN_EXPORT QDebug operator<<(QDebug debug, const AbstractOutput *output); diff --git a/src/effects.cpp b/src/effects.cpp index b63f254d99..f6f50f4911 100644 --- a/src/effects.cpp +++ b/src/effects.cpp @@ -902,15 +902,12 @@ void EffectsHandlerImpl::windowToDesktops(EffectWindow *w, const QVector & cl->setDesktops(desktops); } -void EffectsHandlerImpl::windowToScreen(EffectWindow* w, int screen) +void EffectsHandlerImpl::windowToScreen(EffectWindow* w, EffectScreen *screen) { - AbstractOutput *output = kwinApp()->platform()->findOutput(screen); - if (!output) { - return; - } auto cl = qobject_cast(static_cast(w)->window()); if (cl && !cl->isDesktop() && !cl->isDock()) { - Workspace::self()->sendClientToOutput(cl, output); + EffectScreenImpl *screenImpl = static_cast(screen); + Workspace::self()->sendClientToOutput(cl, screenImpl->platformOutput()); } } @@ -1193,9 +1190,9 @@ void EffectsHandlerImpl::addRepaint(int x, int y, int w, int h) m_compositor->addRepaint(x, y, w, h); } -int EffectsHandlerImpl::activeScreen() const +EffectScreen *EffectsHandlerImpl::activeScreen() const { - return kwinApp()->platform()->enabledOutputs().indexOf(workspace()->activeOutput()); + return EffectScreenImpl::get(workspace()->activeOutput()); } int EffectsHandlerImpl::numScreens() const @@ -1203,14 +1200,17 @@ int EffectsHandlerImpl::numScreens() const return Screens::self()->count(); } -int EffectsHandlerImpl::screenNumber(const QPoint& pos) const +QRect EffectsHandlerImpl::clientArea(clientAreaOption opt, const EffectScreen *screen, int desktop) const { - return Screens::self()->number(pos); -} + const VirtualDesktop *virtualDesktop; + if (desktop == 0 || desktop == -1) { + virtualDesktop = VirtualDesktopManager::self()->currentDesktop(); + } else { + virtualDesktop = VirtualDesktopManager::self()->desktopForX11Id(desktop); + } -QRect EffectsHandlerImpl::clientArea(clientAreaOption opt, int screen, int desktop) const -{ - return Workspace::self()->clientArea(opt, screen, desktop); + const EffectScreenImpl *screenImpl = static_cast(screen); + return Workspace::self()->clientArea(opt, screenImpl->platformOutput(), virtualDesktop); } QRect EffectsHandlerImpl::clientArea(clientAreaOption opt, const EffectWindow* c) const @@ -1684,7 +1684,7 @@ QList EffectsHandlerImpl::screens() const EffectScreen *EffectsHandlerImpl::screenAt(const QPoint &point) const { - return m_effectScreens.value(screenNumber(point)); + return EffectScreenImpl::get(kwinApp()->platform()->outputAt(point)); } EffectScreen *EffectsHandlerImpl::findScreen(const QString &name) const @@ -1711,15 +1711,10 @@ void EffectsHandlerImpl::slotOutputEnabled(AbstractOutput *output) void EffectsHandlerImpl::slotOutputDisabled(AbstractOutput *output) { - auto it = std::find_if(m_effectScreens.begin(), m_effectScreens.end(), [&output](EffectScreen *screen) { - return static_cast(screen)->platformOutput() == output; - }); - if (it != m_effectScreens.end()) { - EffectScreen *screen = *it; - m_effectScreens.erase(it); - Q_EMIT screenRemoved(screen); - delete screen; - } + EffectScreen *screen = EffectScreenImpl::get(output); + m_effectScreens.removeOne(screen); + Q_EMIT screenRemoved(screen); + delete screen; } void EffectsHandlerImpl::renderScreen(EffectScreen *screen) @@ -1736,6 +1731,8 @@ EffectScreenImpl::EffectScreenImpl(AbstractOutput *output, QObject *parent) : EffectScreen(parent) , m_platformOutput(output) { + m_platformOutput->m_effectScreen = this; + connect(output, &AbstractOutput::aboutToChange, this, &EffectScreen::aboutToChange); connect(output, &AbstractOutput::changed, this, &EffectScreen::changed); connect(output, &AbstractOutput::wakeUp, this, &EffectScreen::wakeUp); @@ -1744,6 +1741,18 @@ EffectScreenImpl::EffectScreenImpl(AbstractOutput *output, QObject *parent) connect(output, &AbstractOutput::geometryChanged, this, &EffectScreen::geometryChanged); } +EffectScreenImpl::~EffectScreenImpl() +{ + if (m_platformOutput) { + m_platformOutput->m_effectScreen = nullptr; + } +} + +EffectScreenImpl *EffectScreenImpl::get(AbstractOutput *output) +{ + return output->m_effectScreen; +} + AbstractOutput *EffectScreenImpl::platformOutput() const { return m_platformOutput; @@ -1865,6 +1874,11 @@ void EffectWindowImpl::unrefWindow() abort(); // TODO } +EffectScreen *EffectWindowImpl::screen() const +{ + return EffectScreenImpl::get(toplevel->output()); +} + #define TOPLEVEL_HELPER( rettype, prototype, toplevelPrototype) \ rettype EffectWindowImpl::prototype ( ) const \ { \ @@ -1879,7 +1893,6 @@ TOPLEVEL_HELPER(int, width, width) TOPLEVEL_HELPER(int, height, height) TOPLEVEL_HELPER(QPoint, pos, pos) TOPLEVEL_HELPER(QSize, size, size) -TOPLEVEL_HELPER(int, screen, screen) TOPLEVEL_HELPER(QRect, geometry, frameGeometry) TOPLEVEL_HELPER(QRect, frameGeometry, frameGeometry) TOPLEVEL_HELPER(QRect, bufferGeometry, bufferGeometry) diff --git a/src/effects.h b/src/effects.h index 1c1aa79780..72a3ff507b 100644 --- a/src/effects.h +++ b/src/effects.h @@ -77,7 +77,7 @@ public: EffectWindow* activeWindow() const override; void moveWindow(EffectWindow* w, const QPoint& pos, bool snap = false, double snapAdjust = 1.0) override; void windowToDesktop(EffectWindow* w, int desktop) override; - void windowToScreen(EffectWindow* w, int screen) override; + void windowToScreen(EffectWindow* w, EffectScreen *screen) override; void setShowingDesktop(bool showing) override; QString currentActivity() const override; @@ -140,10 +140,9 @@ public: void addRepaint(const QRect& r) override; void addRepaint(const QRegion& r) override; void addRepaint(int x, int y, int w, int h) override; - int activeScreen() const override; + EffectScreen *activeScreen() const override; int numScreens() const override; - int screenNumber(const QPoint& pos) const override; - QRect clientArea(clientAreaOption, int screen, int desktop) const override; + QRect clientArea(clientAreaOption, const EffectScreen *screen, int desktop) const override; QRect clientArea(clientAreaOption, const EffectWindow* c) const override; QRect clientArea(clientAreaOption, const QPoint& p, int desktop) const override; QSize virtualScreenSize() const override; @@ -364,6 +363,7 @@ class EffectScreenImpl : public EffectScreen public: explicit EffectScreenImpl(AbstractOutput *output, QObject *parent = nullptr); + ~EffectScreenImpl() override; AbstractOutput *platformOutput() const; @@ -372,6 +372,8 @@ public: QRect geometry() const override; Transform transform() const override; + static EffectScreenImpl *get(AbstractOutput *output); + private: AbstractOutput *m_platformOutput; }; @@ -420,7 +422,7 @@ public: QString caption() const override; QRect expandedGeometry() const override; - int screen() const override; + EffectScreen *screen() const override; QPoint pos() const override; QSize size() const override; QRect rect() const override; diff --git a/src/effects/desktopgrid/desktopgrid.cpp b/src/effects/desktopgrid/desktopgrid.cpp index dd696caab7..cf7e563c67 100644 --- a/src/effects/desktopgrid/desktopgrid.cpp +++ b/src/effects/desktopgrid/desktopgrid.cpp @@ -218,9 +218,11 @@ void DesktopGridEffect::prePaintScreen(ScreenPrePaintData& data, std::chrono::mi if (timeline.currentValue() != 0 || activated || (isUsingPresentWindows() && isMotionManagerMovingWindows())) { if (isUsingPresentWindows()) { - QList::iterator i; - for (i = m_managers.begin(); i != m_managers.end(); ++i) - (*i).calculate(timeline.currentTime()); + for (auto i = m_managers.begin(); i != m_managers.end(); ++i) { + for (WindowMotionManager &manager : *i) { + manager.calculate(timeline.currentTime()); + } + } } // PAINT_SCREEN_BACKGROUND_FIRST is needed because screen will be actually painted more than once, // so with normal screen painting second screen paint would erase parts of the first paint @@ -265,8 +267,9 @@ void DesktopGridEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaint } if (desktopNameAlignment) { - for (int screen = 0; screen < effects->numScreens(); screen++) { - QRect screenGeom = effects->clientArea(ScreenArea, screen, 0); + const QList screens = effects->screens(); + for (EffectScreen *screen : screens) { + QRect screenGeom = effects->clientArea(ScreenArea, screen, effects->currentDesktop()); int desktop = 1; Q_FOREACH (EffectFrame * frame, desktopNames) { QPointF posTL(scalePos(screenGeom.topLeft(), desktop, screen)); @@ -363,12 +366,13 @@ void DesktopGridEffect::paintWindow(EffectWindow* w, int mask, QRegion region, W data.multiplyBrightness(1.0 - (0.3 * (1.0 - hoverTimeline[paintingDesktop - 1]->currentValue()))); - for (int screen = 0; screen < effects->numScreens(); screen++) { - QRect screenGeom = effects->clientArea(ScreenArea, screen, 0); + const QList screens = effects->screens(); + for (EffectScreen *screen : screens) { + QRect screenGeom = effects->clientArea(ScreenArea, screen, effects->currentDesktop()); QRectF transformedGeo = w->frameGeometry(); if (isUsingPresentWindows()) { - WindowMotionManager& manager = m_managers[(paintingDesktop-1)*(effects->numScreens())+screen ]; + WindowMotionManager& manager = m_managers[screen][paintingDesktop - 1]; if (manager.isManaging(w)) { transformedGeo = manager.transformedGeometry(w); if (!manager.areWindowsMoving() && timeline.currentValue() == 1.0) @@ -420,7 +424,7 @@ void DesktopGridEffect::slotWindowAdded(EffectWindow* w) if (!isRelevantWithPresentWindows(w)) return; // don't add Q_FOREACH (const int i, desktopList(w)) { - WindowMotionManager& manager = m_managers[ i*effects->numScreens()+w->screen()]; + WindowMotionManager& manager = m_managers[w->screen()][i]; manager.manage(w); m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager); } @@ -438,7 +442,7 @@ void DesktopGridEffect::slotWindowClosed(EffectWindow* w) } if (isUsingPresentWindows()) { Q_FOREACH (const int i, desktopList(w)) { - WindowMotionManager& manager = m_managers[i*effects->numScreens()+w->screen()]; + WindowMotionManager& manager = m_managers[w->screen()][i]; manager.unmanage(w); m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager); } @@ -451,9 +455,10 @@ void DesktopGridEffect::slotWindowDeleted(EffectWindow* w) if (w == windowMove) windowMove = nullptr; if (isUsingPresentWindows()) { - for (QList::iterator it = m_managers.begin(), - end = m_managers.end(); it != end; ++it) { - it->unmanage(w); + for (auto it = m_managers.begin(); it != m_managers.end(); ++it) { + for (WindowMotionManager &manager : *it) { + manager.unmanage(w); + } } } } @@ -467,7 +472,7 @@ void DesktopGridEffect::slotWindowFrameGeometryChanged(EffectWindow* w, const QR return; if (isUsingPresentWindows()) { Q_FOREACH (const int i, desktopList(w)) { - WindowMotionManager& manager = m_managers[i*effects->numScreens()+w->screen()]; + WindowMotionManager& manager = m_managers[w->screen()][i]; m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager); } } @@ -502,7 +507,7 @@ void DesktopGridEffect::windowInputMouseEvent(QEvent* e) if (!wasWindowMove) { // Activate on move if (isUsingPresentWindows()) { Q_FOREACH (const int i, desktopList(windowMove)) { - WindowMotionManager& manager = m_managers[(i)*(effects->numScreens()) + windowMove->screen()]; + WindowMotionManager& manager = m_managers[windowMove->screen()][i]; if ((i + 1) == sourceDesktop) { const QRectF transformedGeo = manager.transformedGeometry(windowMove); const QPointF pos = scalePos(transformedGeo.topLeft().toPoint(), sourceDesktop, windowMove->screen()); @@ -523,7 +528,7 @@ void DesktopGridEffect::windowInputMouseEvent(QEvent* e) } if (windowMove->isMovable() && !isUsingPresentWindows()) { wasWindowMove = true; - int screen = effects->screenNumber(me->pos()); + EffectScreen *screen = effects->screenAt(me->pos()); effects->moveWindow(windowMove, unscalePos(me->pos(), nullptr) + windowMoveDiff, true, 1.0 / scale[screen]); } if (wasWindowMove) { @@ -543,7 +548,7 @@ void DesktopGridEffect::windowInputMouseEvent(QEvent* e) desktops.removeOne(highlightedDesktop); } effects->windowToDesktops(windowMove, desktops); - const int screen = effects->screenNumber(me->pos()); + EffectScreen *screen = effects->screenAt(me->pos()); if (screen != windowMove->screen()) effects->windowToScreen(windowMove, screen); } @@ -581,16 +586,17 @@ void DesktopGridEffect::windowInputMouseEvent(QEvent* e) effects->windowToDesktops(w, desktops); if (isUsingPresentWindows()) { - m_managers[(desks[i]-1)*(effects->numScreens()) + w->screen()].unmanage(w); - m_managers[(desks[i+1]-1)*(effects->numScreens()) + w->screen()].manage(w); + m_managers[w->screen()][desks[i] - 1].unmanage(w); + m_managers[w->screen()][desks[i + 1] - 1].manage(w); } } } if (isUsingPresentWindows()) { - for (int i = 0; i < effects->numScreens(); i++) { + const QList screens = effects->screens(); + for (EffectScreen *screen : screens) { for (int j = 0; j < 3; ++j) { - WindowMotionManager& manager = m_managers[(desks[j]-1)*(effects->numScreens()) + i ]; - m_proxy->calculateWindowTransformations(manager.managedWindows(), i, manager); + WindowMotionManager& manager = m_managers[screen][desks[j] - 1]; + m_proxy->calculateWindowTransformations(manager.managedWindows(), screen, manager); } } effects->addRepaintFull(); @@ -634,7 +640,7 @@ void DesktopGridEffect::windowInputMouseEvent(QEvent* e) if (isUsingPresentWindows()) { for (int i = 0; i < effects->numberOfDesktops(); i++) { if (i != desktop - 1) { - WindowMotionManager& manager = m_managers[ i*effects->numScreens() + w->screen()]; + WindowMotionManager& manager = m_managers[w->screen()][i]; if (isOnAllDesktops) manager.manage(w); else @@ -672,7 +678,7 @@ void DesktopGridEffect::windowInputMouseEvent(QEvent* e) if (wasWindowMove && isUsingPresentWindows()) { const int targetDesktop = posToDesktop(cursorPos()); Q_FOREACH (const int i, desktopList(windowMove)) { - WindowMotionManager& manager = m_managers[(i)*(effects->numScreens()) + windowMove->screen()]; + WindowMotionManager& manager = m_managers[windowMove->screen()][i]; manager.manage(windowMove); if (EffectWindow* modal = windowMove->findModal()) manager.manage(modal); @@ -794,10 +800,8 @@ bool DesktopGridEffect::borderActivated(ElectricBorder border) // Helper functions // Transform a point to its position on the scaled grid -QPointF DesktopGridEffect::scalePos(const QPoint& pos, int desktop, int screen) const +QPointF DesktopGridEffect::scalePos(const QPoint& pos, int desktop, EffectScreen *screen) const { - if (screen == -1) - screen = effects->screenNumber(pos); QRect screenGeom = effects->clientArea(ScreenArea, screen, 0); QPoint desktopCell; if (orientation == Qt::Horizontal) { @@ -841,8 +845,8 @@ QPointF DesktopGridEffect::scalePos(const QPoint& pos, int desktop, int screen) // TODO: Doesn't correctly interpolate (Final position is correct though), don't forget to copy to posToDesktop() QPoint DesktopGridEffect::unscalePos(const QPoint& pos, int* desktop) const { - int screen = effects->screenNumber(pos); - QRect screenGeom = effects->clientArea(ScreenArea, screen, 0); + EffectScreen *screen = effects->screenAt(pos); + QRect screenGeom = effects->clientArea(ScreenArea, screen, effects->currentDesktop()); //double progress = timeline.currentValue(); double scaledX = /*interpolate( @@ -889,7 +893,7 @@ QPoint DesktopGridEffect::unscalePos(const QPoint& pos, int* desktop) const int DesktopGridEffect::posToDesktop(const QPoint& pos) const { // Copied from unscalePos() - int screen = effects->screenNumber(pos); + EffectScreen *screen = effects->screenAt(pos); double scaledX = (pos.x() - scaledOffset[screen].x() + double(border) / 2.0) / (scaledSize[screen].width() + border); double scaledY = (pos.y() - scaledOffset[screen].y() + double(border) / 2.0) / (scaledSize[screen].height() + border); @@ -915,9 +919,8 @@ EffectWindow* DesktopGridEffect::windowAt(QPoint pos) const if (desktop > effects->numberOfDesktops()) return nullptr; if (isUsingPresentWindows()) { - const int screen = effects->screenNumber(pos); - EffectWindow *w = - m_managers.at((desktop - 1) * (effects->numScreens()) + screen).windowAtPoint(pos, false); + EffectScreen *screen = effects->screenAt(pos); + EffectWindow *w = m_managers[screen][desktop - 1].windowAtPoint(pos, false); if (w) return w; Q_FOREACH (EffectWindow * w, windows) { @@ -1104,23 +1107,26 @@ void DesktopGridEffect::setup() m_proxy = static_cast(effects->getProxy(QStringLiteral("presentwindows"))); if (isUsingPresentWindows()) { m_proxy->reCreateGrids(); // revalidation on multiscreen, bug #351724 - for (int i = 1; i <= effects->numberOfDesktops(); i++) { - for (int j = 0; j < effects->numScreens(); j++) { - WindowMotionManager manager; - Q_FOREACH (EffectWindow * w, effects->stackingOrder()) { - if (w->isOnDesktop(i) && w->screen() == j &&isRelevantWithPresentWindows(w)) { - manager.manage(w); + const QList screens = effects->screens(); + for (EffectScreen *screen : screens) { + QList managers; + for (int i = 1; i <= effects->numberOfDesktops(); i++) { + WindowMotionManager manager; + Q_FOREACH (EffectWindow * w, effects->stackingOrder()) { + if (w->isOnDesktop(i) && w->screen() == screen &&isRelevantWithPresentWindows(w)) { + manager.manage(w); + } } - } - m_proxy->calculateWindowTransformations(manager.managedWindows(), j, manager); - m_managers.append(manager); + m_proxy->calculateWindowTransformations(manager.managedWindows(), screen, manager); + managers.append(manager); } + m_managers[screen] = managers; } } auto it = m_desktopButtons.begin(); - const int n = DesktopGridConfig::showAddRemove() ? effects->numScreens() : 0; - for (int i = 0; i < n; ++i) { + const QList screens = DesktopGridConfig::showAddRemove() ? effects->screens() : QList{}; + for (EffectScreen *screen : screens) { EffectQuickScene *view; QSize size; if (it == m_desktopButtons.end()) { @@ -1148,7 +1154,7 @@ void DesktopGridEffect::setup() ++it; size = view->size(); } - const QRect screenRect = effects->clientArea(FullScreenArea, i, 1); + const QRect screenRect = effects->clientArea(FullScreenArea, screen, 1); view->show(); // pseudo show must happen before geometry changes const QPoint position(screenRect.right() - border/3 - size.width(), screenRect.bottom() - border/3 - size.height()); @@ -1194,8 +1200,10 @@ void DesktopGridEffect::setupGrid() unscaledBorder.clear(); scaledSize.clear(); scaledOffset.clear(); - for (int i = 0; i < effects->numScreens(); i++) { - QRect geom = effects->clientArea(ScreenArea, i, 0); + + const QList screens = effects->screens(); + for (EffectScreen *screen : screens) { + QRect geom = effects->clientArea(ScreenArea, screen, effects->currentDesktop()); double sScale; if (gridSize.width() > gridSize.height()) sScale = (geom.width() - border * (gridSize.width() + 1)) / double(geom.width() * gridSize.width()); @@ -1210,10 +1218,10 @@ void DesktopGridEffect::setupGrid() geom.x() + (geom.width() - size.width() * gridSize.width() - border *(gridSize.width() - 1)) / 2.0, geom.y() + (geom.height() - size.height() * gridSize.height() - border *(gridSize.height() - 1)) / 2.0 ); - scale.append(sScale); - unscaledBorder.append(sBorder); - scaledSize.append(size); - scaledOffset.append(offset); + scale[screen] = sScale; + unscaledBorder[screen] = sBorder; + scaledSize[screen] = size; + scaledOffset[screen] = offset; } } @@ -1225,10 +1233,11 @@ void DesktopGridEffect::finish() } if (isUsingPresentWindows()) { - QList::iterator it; - for (it = m_managers.begin(); it != m_managers.end(); ++it) { - Q_FOREACH (EffectWindow * w, (*it).managedWindows()) { - (*it).moveWindow(w, w->frameGeometry()); + for (auto it = m_managers.begin(); it != m_managers.end(); ++it) { + for (WindowMotionManager &manager : *it) { + Q_FOREACH (EffectWindow * w, manager.managedWindows()) { + manager.moveWindow(w, w->frameGeometry()); + } } } } @@ -1252,10 +1261,12 @@ void DesktopGridEffect::finish() effects->stopMouseInterception(this); effects->setActiveFullScreenEffect(nullptr); if (isUsingPresentWindows()) { - while (!m_managers.isEmpty()) { - m_managers.first().unmanageAll(); - m_managers.removeFirst(); + for (auto it = m_managers.begin(); it != m_managers.end(); ++it) { + for (WindowMotionManager &manager : *it) { + manager.unmanageAll(); + } } + m_managers.clear(); m_proxy = nullptr; } @@ -1274,10 +1285,11 @@ void DesktopGridEffect::globalShortcutChanged(QAction *action, const QKeySequenc bool DesktopGridEffect::isMotionManagerMovingWindows() const { if (isUsingPresentWindows()) { - QList::const_iterator it; - for (it = m_managers.begin(); it != m_managers.end(); ++it) { - if ((*it).areWindowsMoving()) - return true; + for (auto it = m_managers.constBegin(); it != m_managers.constEnd(); ++it) { + for (const WindowMotionManager &manager : *it) { + if (manager.areWindowsMoving()) + return true; + } } } return false; @@ -1357,16 +1369,17 @@ void DesktopGridEffect::desktopsAdded(int old) } if (isUsingPresentWindows()) { - for (int i = old+1; i <= effects->numberOfDesktops(); ++i) { - for (int j = 0; j < effects->numScreens(); ++j) { + const QList screens = effects->screens(); + for (EffectScreen *screen : screens) { + for (int i = old+1; i <= effects->numberOfDesktops(); ++i) { WindowMotionManager manager; Q_FOREACH (EffectWindow * w, effects->stackingOrder()) { - if (w->isOnDesktop(i) && w->screen() == j &&isRelevantWithPresentWindows(w)) { + if (w->isOnDesktop(i) && w->screen() == screen &&isRelevantWithPresentWindows(w)) { manager.manage(w); } } - m_proxy->calculateWindowTransformations(manager.managedWindows(), j, manager); - m_managers.append(manager); + m_proxy->calculateWindowTransformations(manager.managedWindows(), screen, manager); + m_managers[screen].append(manager); } } } @@ -1387,25 +1400,27 @@ void DesktopGridEffect::desktopsRemoved(int old) desktopNames.removeLast(); } if (isUsingPresentWindows()) { - for (int j = 0; j < effects->numScreens(); ++j) { - WindowMotionManager& manager = m_managers.last(); + const QList screens = effects->screens(); + for (EffectScreen *screen : screens) { + WindowMotionManager& manager = m_managers[screen].last(); manager.unmanageAll(); - m_managers.removeLast(); + m_managers[screen].removeLast(); } } } // add removed windows to the last desktop if (isUsingPresentWindows()) { - for (int j = 0; j < effects->numScreens(); ++j) { - WindowMotionManager& manager = m_managers[(desktop-1)*(effects->numScreens())+j ]; + const QList screens = effects->screens(); + for (EffectScreen *screen : screens) { + WindowMotionManager& manager = m_managers[screen][desktop - 1]; Q_FOREACH (EffectWindow * w, effects->stackingOrder()) { if (manager.isManaging(w)) continue; - if (w->isOnDesktop(desktop) && w->screen() == j && isRelevantWithPresentWindows(w)) { + if (w->isOnDesktop(desktop) && w->screen() == screen && isRelevantWithPresentWindows(w)) { manager.manage(w); } } - m_proxy->calculateWindowTransformations(manager.managedWindows(), j, manager); + m_proxy->calculateWindowTransformations(manager.managedWindows(), screen, manager); } } diff --git a/src/effects/desktopgrid/desktopgrid.h b/src/effects/desktopgrid/desktopgrid.h index dba1fb6e57..aff31525a8 100644 --- a/src/effects/desktopgrid/desktopgrid.h +++ b/src/effects/desktopgrid/desktopgrid.h @@ -95,7 +95,7 @@ private Q_SLOTS: void slotWindowFrameGeometryChanged(KWin::EffectWindow *w, const QRect &old); private: - QPointF scalePos(const QPoint& pos, int desktop, int screen = -1) const; + QPointF scalePos(const QPoint& pos, int desktop, EffectScreen *screen) const; QPoint unscalePos(const QPoint& pos, int* desktop = nullptr) const; int posToDesktop(const QPoint& pos) const; EffectWindow* windowAt(QPoint pos) const; @@ -155,16 +155,16 @@ private: Qt::Orientation orientation; QPoint activeCell; // Per screen variables - QList scale; // Because the border isn't a ratio each screen is different - QList unscaledBorder; - QList scaledSize; - QList scaledOffset; + QMap scale; // Because the border isn't a ratio each screen is different + QMap unscaledBorder; + QMap scaledSize; + QMap scaledOffset; // Shortcut - needed to toggle the effect QList shortcut; PresentWindowsEffectProxy* m_proxy; - QList m_managers; + QMap> m_managers; QRect m_windowMoveGeometry; QPoint m_windowMoveStartPoint; diff --git a/src/effects/kscreen/kscreen.cpp b/src/effects/kscreen/kscreen.cpp index ac33563a42..0624afacc0 100644 --- a/src/effects/kscreen/kscreen.cpp +++ b/src/effects/kscreen/kscreen.cpp @@ -130,7 +130,7 @@ void KscreenEffect::postPaintScreen() void KscreenEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) { - auto screen = effects->findScreen(w->screen()); + auto screen = w->screen(); if (isScreenActive(screen)) { auto &state = !effects->waylandDisplay() ? m_xcbState : m_waylandStates[screen]; if (state.m_state != StateNormal) { @@ -142,7 +142,7 @@ void KscreenEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, st void KscreenEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) { - auto screen = effects->findScreen(w->screen()); + auto screen = w->screen(); if (isScreenActive(screen)) { auto &state = !effects->waylandDisplay() ? m_xcbState : m_waylandStates[screen]; //fade to black and fully opaque diff --git a/src/effects/overview/expoarea.cpp b/src/effects/overview/expoarea.cpp index 44f6480e27..058403c0c2 100644 --- a/src/effects/overview/expoarea.cpp +++ b/src/effects/overview/expoarea.cpp @@ -61,8 +61,7 @@ void ExpoArea::update() } const QRect oldRect = m_rect; - const int screen = effects->screens().indexOf(m_screen); - m_rect = effects->clientArea(MaximizeArea, screen, effects->currentDesktop()); + m_rect = effects->clientArea(MaximizeArea, m_screen, effects->currentDesktop()); // Map the area to the output local coordinates. m_rect.translate(-m_screen->geometry().topLeft()); diff --git a/src/effects/overview/overvieweffect.cpp b/src/effects/overview/overvieweffect.cpp index df94b88dde..1abb714241 100644 --- a/src/effects/overview/overvieweffect.cpp +++ b/src/effects/overview/overvieweffect.cpp @@ -326,8 +326,7 @@ void OverviewEffect::grabbedKeyboardEvent(QKeyEvent *keyEvent) } return; } - EffectScreen *activeScreen = effects->findScreen(effects->activeScreen()); - OverviewScreenView *screenView = m_screenViews.value(activeScreen); + OverviewScreenView *screenView = m_screenViews.value(effects->activeScreen()); if (screenView) { screenView->contentItem()->setFocus(true); screenView->forwardKeyEvent(keyEvent); diff --git a/src/effects/presentwindows/presentwindows.cpp b/src/effects/presentwindows/presentwindows.cpp index 3101398c75..31b15a5d1a 100644 --- a/src/effects/presentwindows/presentwindows.cpp +++ b/src/effects/presentwindows/presentwindows.cpp @@ -966,9 +966,7 @@ void PresentWindowsEffect::rearrangeWindows() // Work out which windows are on which screens EffectWindowList windowlist; - QList windowlists; - for (int i = 0; i < effects->numScreens(); i++) - windowlists.append(EffectWindowList()); + QMap windowlists; if (m_windowFilter.isEmpty()) { windowlist = m_motionManager.managedWindows(); @@ -1009,8 +1007,8 @@ void PresentWindowsEffect::rearrangeWindows() } else setHighlightedWindow(findFirstWindow()); - int screens = effects->numScreens(); - for (int screen = 0; screen < screens; screen++) { + const QList screens = effects->screens(); + for (EffectScreen *screen : screens) { EffectWindowList windows; windows = windowlists[screen]; @@ -1049,7 +1047,7 @@ void PresentWindowsEffect::rearrangeWindows() delete metrics; } -void PresentWindowsEffect::calculateWindowTransformations(EffectWindowList windowlist, int screen, +void PresentWindowsEffect::calculateWindowTransformations(EffectWindowList windowlist, EffectScreen *screen, WindowMotionManager& motionManager, bool external) { if (m_layoutMode == LayoutRegularGrid) @@ -1071,7 +1069,7 @@ static inline int distance(QPoint &pos1, QPoint &pos2) return int(sqrt(float(xdiff*xdiff + ydiff*ydiff))); } -void PresentWindowsEffect::calculateWindowTransformationsClosest(EffectWindowList windowlist, int screen, +void PresentWindowsEffect::calculateWindowTransformationsClosest(EffectWindowList windowlist, EffectScreen *screen, WindowMotionManager& motionManager) { // This layout mode requires at least one window visible @@ -1170,7 +1168,7 @@ void PresentWindowsEffect::calculateWindowTransformationsClosest(EffectWindowLis } } -void PresentWindowsEffect::calculateWindowTransformationsKompose(EffectWindowList windowlist, int screen, +void PresentWindowsEffect::calculateWindowTransformationsKompose(EffectWindowList windowlist, EffectScreen *screen, WindowMotionManager& motionManager) { // This layout mode requires at least one window visible @@ -1306,7 +1304,7 @@ void PresentWindowsEffect::calculateWindowTransformationsKompose(EffectWindowLis } } -void PresentWindowsEffect::calculateWindowTransformationsNatural(EffectWindowList windowlist, int screen, +void PresentWindowsEffect::calculateWindowTransformationsNatural(EffectWindowList windowlist, EffectScreen *screen, WindowMotionManager& motionManager) { // If windows do not overlap they scale into nothingness, fix by resetting. To reproduce @@ -2032,8 +2030,9 @@ bool PresentWindowsEffect::isActive() const void PresentWindowsEffect::reCreateGrids() { m_gridSizes.clear(); - for (int i = 0; i < effects->numScreens(); ++i) { - m_gridSizes.append(GridSize()); + const QList screens = effects->screens(); + for (EffectScreen *screen : screens) { + m_gridSizes.insert(screen, GridSize()); } rearrangeWindows(); } diff --git a/src/effects/presentwindows/presentwindows.h b/src/effects/presentwindows/presentwindows.h index dc143715a1..e4a14d0053 100644 --- a/src/effects/presentwindows/presentwindows.h +++ b/src/effects/presentwindows/presentwindows.h @@ -214,13 +214,13 @@ protected: // Window rearranging void rearrangeWindows(); void reCreateGrids(); - void calculateWindowTransformations(EffectWindowList windowlist, int screen, + void calculateWindowTransformations(EffectWindowList windowlist, EffectScreen *screen, WindowMotionManager& motionManager, bool external = false); - void calculateWindowTransformationsClosest(EffectWindowList windowlist, int screen, + void calculateWindowTransformationsClosest(EffectWindowList windowlist, EffectScreen *screen, WindowMotionManager& motionManager); - void calculateWindowTransformationsKompose(EffectWindowList windowlist, int screen, + void calculateWindowTransformationsKompose(EffectWindowList windowlist, EffectScreen *screen, WindowMotionManager& motionManager); - void calculateWindowTransformationsNatural(EffectWindowList windowlist, int screen, + void calculateWindowTransformationsNatural(EffectWindowList windowlist, EffectScreen *screen, WindowMotionManager& motionManager); // Helper functions for window rearranging @@ -289,7 +289,7 @@ private: std::chrono::milliseconds m_lastPresentTime; // Grid layout info - QList m_gridSizes; + QMap m_gridSizes; // Filter box EffectFrame* m_filterFrame; diff --git a/src/effects/presentwindows/presentwindows_proxy.cpp b/src/effects/presentwindows/presentwindows_proxy.cpp index 9b978ec28e..d1580fc103 100644 --- a/src/effects/presentwindows/presentwindows_proxy.cpp +++ b/src/effects/presentwindows/presentwindows_proxy.cpp @@ -22,7 +22,7 @@ PresentWindowsEffectProxy::~PresentWindowsEffectProxy() { } -void PresentWindowsEffectProxy::calculateWindowTransformations(EffectWindowList windows, int screen, +void PresentWindowsEffectProxy::calculateWindowTransformations(EffectWindowList windows, EffectScreen *screen, WindowMotionManager& manager) { return m_effect->calculateWindowTransformations(windows, screen, manager, true); diff --git a/src/effects/presentwindows/presentwindows_proxy.h b/src/effects/presentwindows/presentwindows_proxy.h index f48f7ebd60..8d6240550a 100644 --- a/src/effects/presentwindows/presentwindows_proxy.h +++ b/src/effects/presentwindows/presentwindows_proxy.h @@ -22,7 +22,7 @@ public: explicit PresentWindowsEffectProxy(PresentWindowsEffect* effect); ~PresentWindowsEffectProxy(); - void calculateWindowTransformations(EffectWindowList windows, int screen, WindowMotionManager& manager); + void calculateWindowTransformations(EffectWindowList windows, EffectScreen *screen, WindowMotionManager& manager); void reCreateGrids(); diff --git a/src/effects/screenshot/screenshot.cpp b/src/effects/screenshot/screenshot.cpp index 20933d7cfc..23e58584cf 100644 --- a/src/effects/screenshot/screenshot.cpp +++ b/src/effects/screenshot/screenshot.cpp @@ -213,7 +213,7 @@ void ScreenShotEffect::takeScreenShot(ScreenShotWindowData *screenshot) geometry = window->clientGeometry(); } if (screenshot->flags & ScreenShotNativeResolution) { - if (const EffectScreen *screen = effects->findScreen(window->screen())) { + if (const EffectScreen *screen = window->screen()) { devicePixelRatio = screen->devicePixelRatio(); } } diff --git a/src/effects/screentransform/screentransform.cpp b/src/effects/screentransform/screentransform.cpp index b49dd9deb9..f128c3aab4 100644 --- a/src/effects/screentransform/screentransform.cpp +++ b/src/effects/screentransform/screentransform.cpp @@ -165,7 +165,7 @@ void ScreenTransformEffect::paintScreen(int mask, const QRegion ®ion, KWin::S void ScreenTransformEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) { - auto screen = effects->findScreen(w->screen()); + auto screen = w->screen(); if (isScreenTransforming(screen)) { auto &state = m_states[screen]; if (!state.isSecondHalf()) { @@ -177,7 +177,7 @@ void ScreenTransformEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData & void ScreenTransformEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) { - auto screen = effects->findScreen(w->screen()); + auto screen = w->screen(); if (isScreenTransforming(screen)) { auto &state = m_states[screen]; if (!state.isSecondHalf()) { diff --git a/src/effects/snaphelper/snaphelper.cpp b/src/effects/snaphelper/snaphelper.cpp index c966c3dfff..d5028b7a18 100644 --- a/src/effects/snaphelper/snaphelper.cpp +++ b/src/effects/snaphelper/snaphelper.cpp @@ -30,8 +30,10 @@ static QRegion computeDirtyRegion(const QRect &windowRect) ); QRegion dirtyRegion; - for (int i = 0; i < effects->numScreens(); ++i) { - const QRect screenRect = effects->clientArea(ScreenArea, i, 0); + + const QList screens = effects->screens(); + for (EffectScreen *screen : screens) { + const QRect screenRect = effects->clientArea(ScreenArea, screen, effects->currentDesktop()); QRect screenWindowRect = windowRect; screenWindowRect.moveCenter(screenRect.center()); @@ -102,6 +104,7 @@ void SnapHelperEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintD const qreal opacityFactor = m_animation.active ? m_animation.timeLine.value() : 1.0; + const QList screens = effects->screens(); // Display the guide if (effects->isOpenGLCompositing()) { @@ -119,9 +122,9 @@ void SnapHelperEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintD glLineWidth(s_lineWidth); QVector verts; - verts.reserve(effects->numScreens() * 24); - for (int i = 0; i < effects->numScreens(); ++i) { - const QRect rect = effects->clientArea(ScreenArea, i, 0); + verts.reserve(screens.count() * 24); + for (EffectScreen *screen : screens) { + const QRect rect = effects->clientArea(ScreenArea, screen, effects->currentDesktop()); const int midX = rect.x() + rect.width() / 2; const int midY = rect.y() + rect.height() / 2 ; const int halfWidth = m_geometry.width() / 2; @@ -166,8 +169,8 @@ void SnapHelperEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintD painter->setPen(pen); painter->setBrush(Qt::NoBrush); - for (int i = 0; i < effects->numScreens(); ++i) { - const QRect rect = effects->clientArea(ScreenArea, i, 0); + for (EffectScreen *screen : screens) { + const QRect rect = effects->clientArea(ScreenArea, screen, effects->currentDesktop()); // Center lines. painter->drawLine(rect.center().x(), rect.y(), rect.center().x(), rect.y() + rect.height()); painter->drawLine(rect.x(), rect.center().y(), rect.x() + rect.width(), rect.center().y()); diff --git a/src/effects/thumbnailaside/thumbnailaside.cpp b/src/effects/thumbnailaside/thumbnailaside.cpp index 613e31d6a0..c3fbc0b938 100644 --- a/src/effects/thumbnailaside/thumbnailaside.cpp +++ b/src/effects/thumbnailaside/thumbnailaside.cpp @@ -149,8 +149,8 @@ void ThumbnailAsideEffect::arrange() mwidth = qMax(mwidth, d.window->width()); pos[ d.index ] = d.window->height(); } - int effectiveScreen = screen; - if (effectiveScreen == -1) { + EffectScreen *effectiveScreen = effects->findScreen(screen); + if (!effectiveScreen ) { effectiveScreen = effects->activeScreen(); } QRect area = effects->clientArea(MaximizeArea, effectiveScreen, effects->currentDesktop()); diff --git a/src/libkwineffects/kwindeformeffect.cpp b/src/libkwineffects/kwindeformeffect.cpp index c27907861a..a14d905df4 100644 --- a/src/libkwineffects/kwindeformeffect.cpp +++ b/src/libkwineffects/kwindeformeffect.cpp @@ -81,7 +81,7 @@ GLTexture *DeformEffectPrivate::maybeRender(EffectWindow *window, DeformOffscree const QRect geometry = window->expandedGeometry(); QSize textureSize = geometry.size(); - if (const EffectScreen *screen = effects->findScreen(window->screen())) { + if (const EffectScreen *screen = window->screen()) { textureSize *= screen->devicePixelRatio(); } diff --git a/src/libkwineffects/kwineffects.h b/src/libkwineffects/kwineffects.h index 6fc240d805..5e7497f4dd 100644 --- a/src/libkwineffects/kwineffects.h +++ b/src/libkwineffects/kwineffects.h @@ -777,7 +777,7 @@ class KWINEFFECTS_EXPORT EffectsHandler : public QObject */ Q_PROPERTY(int desktops READ numberOfDesktops WRITE setNumberOfDesktops NOTIFY numberDesktopsChanged) Q_PROPERTY(bool optionRollOverDesktops READ optionRollOverDesktops) - Q_PROPERTY(int activeScreen READ activeScreen) + Q_PROPERTY(KWin::EffectScreen *activeScreen READ activeScreen) Q_PROPERTY(int numScreens READ numScreens NOTIFY numberScreensChanged) /** * Factor by which animation speed in the effect should be modified (multiplied). @@ -943,7 +943,7 @@ public: */ Q_SCRIPTABLE virtual void windowToDesktops(KWin::EffectWindow* w, const QVector &desktopIds) = 0; - Q_SCRIPTABLE virtual void windowToScreen(KWin::EffectWindow* w, int screen) = 0; + Q_SCRIPTABLE virtual void windowToScreen(KWin::EffectWindow* w, EffectScreen *screen) = 0; virtual void setShowingDesktop(bool showing) = 0; // Activities @@ -1024,10 +1024,9 @@ public: Q_SCRIPTABLE virtual QString desktopName(int desktop) const = 0; virtual bool optionRollOverDesktops() const = 0; - virtual int activeScreen() const = 0; // Xinerama + virtual EffectScreen *activeScreen() const = 0; // Xinerama virtual int numScreens() const = 0; // Xinerama - Q_SCRIPTABLE virtual int screenNumber(const QPoint& pos) const = 0; // Xinerama - virtual QRect clientArea(clientAreaOption, int screen, int desktop) const = 0; + virtual QRect clientArea(clientAreaOption, const EffectScreen *screen, int desktop) const = 0; virtual QRect clientArea(clientAreaOption, const EffectWindow* c) const = 0; virtual QRect clientArea(clientAreaOption, const QPoint& p, int desktop) const = 0; @@ -1917,7 +1916,7 @@ class KWINEFFECTS_EXPORT EffectWindow : public QObject Q_PROPERTY(int height READ height) Q_PROPERTY(qreal opacity READ opacity) Q_PROPERTY(QPoint pos READ pos) - Q_PROPERTY(int screen READ screen) + Q_PROPERTY(KWin::EffectScreen *screen READ screen) Q_PROPERTY(QSize size READ size) Q_PROPERTY(int width READ width) Q_PROPERTY(int x READ x) @@ -2298,7 +2297,7 @@ public: * @since 4.9 */ virtual QRect expandedGeometry() const = 0; - virtual int screen() const = 0; + virtual EffectScreen *screen() const = 0; virtual QPoint pos() const = 0; virtual QSize size() const = 0; virtual QRect rect() const = 0; diff --git a/src/plugins/scenes/opengl/lanczosfilter.cpp b/src/plugins/scenes/opengl/lanczosfilter.cpp index 8ae961f732..b82d39480c 100644 --- a/src/plugins/scenes/opengl/lanczosfilter.cpp +++ b/src/plugins/scenes/opengl/lanczosfilter.cpp @@ -176,7 +176,7 @@ void LanczosFilter::performPaint(EffectWindowImpl* w, int mask, QRegion region, if (data.xScale() < 0.9 || data.yScale() < 0.9) { if (!m_inited) init(); - const QRect screenRect = Workspace::self()->clientArea(ScreenArea, w->screen(), w->desktop()); + const QRect screenRect = Workspace::self()->clientArea(ScreenArea, w->window()); // window geometry may not be bigger than screen geometry to fit into the FBO QRect winGeo(w->expandedGeometry()); if (m_shader && winGeo.width() <= screenRect.width() && winGeo.height() <= screenRect.height()) { diff --git a/src/scene.cpp b/src/scene.cpp index bce81cf646..b49430d77e 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -185,11 +185,12 @@ void Scene::paintScreen(const QRegion &damage, const QRegion &repaint, } // preparation step - static_cast(effects)->startPaint(); + auto effectsImpl = static_cast(effects); + effectsImpl->startPaint(); QRegion region = damage; - auto screen = effects->findScreen(kwinApp()->platform()->enabledOutputs().indexOf(painted_screen)); + auto screen = painted_screen ? EffectScreenImpl::get(painted_screen) : nullptr; ScreenPrePaintData pdata; pdata.mask = (damage == displayRegion) ? 0 : PAINT_SCREEN_REGION; pdata.paint = region;