From b22c362bd5253664a4d52287292abd2cbff8eaa7 Mon Sep 17 00:00:00 2001 From: Roman Gilg Date: Thu, 29 Mar 2018 18:38:27 +0200 Subject: [PATCH] [platforms/virtual] Let VirtualOutput inherit Output Summary: Let VirtualOutput be a child class of the new generic class Output. This allows code sharing and a very similar behavior of the Virtual backend in comparision to the Drm backend. Test Plan: Autotests succesful with two exceptions: The decoration input test fails on testDoubleTap, row topLeft. This is to be expected because now the ScreenEdgeInputFilter captures the event at position (0,0) before the DecorationEventFilter can capture it. The autotest was adapted to take this special case into account. Also the lockscreen test fails, because the virtual output is currently missing the physical size yet. Reviewers: #kwin Subscribers: kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D11789 --- .../integration/decoration_input_test.cpp | 23 +++++----- plugins/platforms/virtual/screens_virtual.cpp | 45 +------------------ plugins/platforms/virtual/screens_virtual.h | 8 +--- plugins/platforms/virtual/virtual_backend.cpp | 26 ++++++++--- plugins/platforms/virtual/virtual_backend.h | 18 ++------ plugins/platforms/virtual/virtual_output.cpp | 16 ++++++- plugins/platforms/virtual/virtual_output.h | 13 +++--- 7 files changed, 61 insertions(+), 88 deletions(-) diff --git a/autotests/integration/decoration_input_test.cpp b/autotests/integration/decoration_input_test.cpp index 5ac5acc1d7..34eb190904 100644 --- a/autotests/integration/decoration_input_test.cpp +++ b/autotests/integration/decoration_input_test.cpp @@ -291,15 +291,15 @@ void DecorationInputTest::testDoubleTap_data() QTest::addColumn("expectedSection"); QTest::addColumn("type"); - QTest::newRow("topLeft") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::WlShell; - QTest::newRow("top") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::WlShell; - QTest::newRow("topRight") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::WlShell; - QTest::newRow("topLeft|xdgv5") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV5; - QTest::newRow("top|xdgv5") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV5; - QTest::newRow("topRight|xdgv5") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::XdgShellV5; - QTest::newRow("topLeft|xdgv6") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV6; - QTest::newRow("top|xdgv6") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV6; - QTest::newRow("topRight|xdgv6") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::XdgShellV6; + QTest::newRow("topLeft") << QPoint(10, 10) << Qt::TopLeftSection << Test::ShellSurfaceType::WlShell; + QTest::newRow("top") << QPoint(260, 10) << Qt::TopSection << Test::ShellSurfaceType::WlShell; + QTest::newRow("topRight") << QPoint(509, 10) << Qt::TopRightSection << Test::ShellSurfaceType::WlShell; + QTest::newRow("topLeft|xdgv5") << QPoint(10, 10) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV5; + QTest::newRow("top|xdgv5") << QPoint(260, 10) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV5; + QTest::newRow("topRight|xdgv5") << QPoint(509, 10) << Qt::TopRightSection << Test::ShellSurfaceType::XdgShellV5; + QTest::newRow("topLeft|xdgv6") << QPoint(10, 10) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV6; + QTest::newRow("top|xdgv6") << QPoint(260, 10) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV6; + QTest::newRow("topRight|xdgv6") << QPoint(509, 10) << Qt::TopRightSection << Test::ShellSurfaceType::XdgShellV6; } @@ -329,7 +329,10 @@ void KWin::DecorationInputTest::testDoubleTap() QVERIFY(!c->isOnAllDesktops()); // test top most deco pixel, BUG: 362860 - c->move(0, 0); + // + // Not directly at (0, 0), otherwise ScreenEdgeInputFilter catches + // event before DecorationEventFilter. + c->move(10, 10); QFETCH(QPoint, decoPoint); // double click kwinApp()->platform()->touchDown(0, decoPoint, timestamp++); diff --git a/plugins/platforms/virtual/screens_virtual.cpp b/plugins/platforms/virtual/screens_virtual.cpp index 2c6b30145b..d2c9871d58 100644 --- a/plugins/platforms/virtual/screens_virtual.cpp +++ b/plugins/platforms/virtual/screens_virtual.cpp @@ -25,7 +25,7 @@ namespace KWin { VirtualScreens::VirtualScreens(VirtualBackend *backend, QObject *parent) - : Screens(parent) + : OutputScreens(backend, parent) , m_backend(backend) { } @@ -40,7 +40,7 @@ void VirtualScreens::init() connect(m_backend, &VirtualBackend::virtualOutputsSet, this, [this] (bool countChanged) { if (countChanged) { - setCount(m_backend->outputCount()); + setCount(m_backend->outputs().size()); } else { emit changed(); } @@ -50,45 +50,4 @@ void VirtualScreens::init() emit changed(); } -QRect VirtualScreens::geometry(int screen) const -{ - const auto outputs = m_backend->virtualOutputs(); - if (screen >= outputs.size()) { - return QRect(); - } - return outputs.at(screen)->geometry(); -} - -QSize VirtualScreens::size(int screen) const -{ - return geometry(screen).size(); -} - -void VirtualScreens::updateCount() -{ - setCount(m_backend->outputCount()); -} - -int VirtualScreens::number(const QPoint &pos) const -{ - int bestScreen = 0; - int minDistance = INT_MAX; - const auto outputs = m_backend->virtualOutputs(); - for (int i = 0; i < outputs.size(); ++i) { - const QRect &geo = outputs.at(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; -} - } diff --git a/plugins/platforms/virtual/screens_virtual.h b/plugins/platforms/virtual/screens_virtual.h index d7962257f8..bdc4df3b1b 100644 --- a/plugins/platforms/virtual/screens_virtual.h +++ b/plugins/platforms/virtual/screens_virtual.h @@ -19,24 +19,20 @@ along with this program. If not, see . *********************************************************************/ #ifndef KWIN_SCREENS_VIRTUAL_H #define KWIN_SCREENS_VIRTUAL_H -#include "screens.h" +#include "outputscreens.h" #include namespace KWin { class VirtualBackend; -class VirtualScreens : public Screens +class VirtualScreens : public OutputScreens { Q_OBJECT public: VirtualScreens(VirtualBackend *backend, QObject *parent = nullptr); virtual ~VirtualScreens(); void init() override; - QRect geometry(int screen) const override; - int number(const QPoint &pos) const override; - QSize size(int screen) const override; - void updateCount() override; private: void createOutputs(); diff --git a/plugins/platforms/virtual/virtual_backend.cpp b/plugins/platforms/virtual/virtual_backend.cpp index fe6d4c443c..9c76855d67 100644 --- a/plugins/platforms/virtual/virtual_backend.cpp +++ b/plugins/platforms/virtual/virtual_backend.cpp @@ -76,8 +76,9 @@ void VirtualBackend::init() */ if (!m_outputs.size()) { VirtualOutput *dummyOutput = new VirtualOutput(this); - dummyOutput->m_geo = QRect(QPoint(0, 0), initialWindowSize()); - m_outputs = { dummyOutput }; + dummyOutput->setGeometry(QRect(QPoint(0, 0), initialWindowSize())); + m_outputs << dummyOutput ; + m_enabledOutputs << dummyOutput ; } @@ -113,6 +114,16 @@ OpenGLBackend *VirtualBackend::createOpenGLBackend() return new EglGbmBackend(this); } +Outputs VirtualBackend::outputs() const +{ + return m_outputs; +} + +Outputs VirtualBackend::enabledOutputs() const +{ + return m_enabledOutputs; +} + void VirtualBackend::setVirtualOutputs(int count, QVector geometries) { Q_ASSERT(geometries.size() == 0 || geometries.size() == count); @@ -120,17 +131,18 @@ void VirtualBackend::setVirtualOutputs(int count, QVector geometries) bool countChanged = m_outputs.size() != count; qDeleteAll(m_outputs.begin(), m_outputs.end()); m_outputs.resize(count); + m_enabledOutputs.resize(count); int sumWidth = 0; for (int i = 0; i < count; i++) { VirtualOutput *vo = new VirtualOutput(this); if (geometries.size()) { - vo->m_geo = geometries.at(i); - } else if (!vo->m_geo.isValid()) { - vo->m_geo = QRect(QPoint(sumWidth, 0), initialWindowSize()); - sumWidth += vo->m_geo.width(); + vo->setGeometry(geometries.at(i)); + } else if (!vo->geometry().isValid()) { + vo->setGeometry(QRect(QPoint(sumWidth, 0), initialWindowSize())); + sumWidth += initialWindowSize().width(); } - m_outputs[i] = vo; + m_outputs[i] = m_enabledOutputs[i] = vo; } emit virtualOutputsSet(countChanged); diff --git a/plugins/platforms/virtual/virtual_backend.h b/plugins/platforms/virtual/virtual_backend.h index bec9d9b78c..5723f7016a 100644 --- a/plugins/platforms/virtual/virtual_backend.h +++ b/plugins/platforms/virtual/virtual_backend.h @@ -45,16 +45,6 @@ public: virtual ~VirtualBackend(); void init() override; - int outputCount() const { - return m_outputs.size(); - } - const QVector virtualOutputs() const { - return m_outputs; - } - qreal outputScale() const { - return m_outputScale; - } - bool saveFrames() const { return !m_screenshotDir.isNull(); } @@ -66,9 +56,8 @@ public: Q_INVOKABLE void setVirtualOutputs(int count, QVector geometries = QVector()); - Q_INVOKABLE void setOutputScale(qreal scale) { - m_outputScale = scale; - } + Outputs outputs() const override; + Outputs enabledOutputs() const override; int drmFd() const { return m_drmFd; @@ -95,8 +84,7 @@ Q_SIGNALS: private: QVector m_outputs; - - qreal m_outputScale = 1; + QVector m_enabledOutputs; QScopedPointer m_screenshotDir; int m_drmFd = -1; diff --git a/plugins/platforms/virtual/virtual_output.cpp b/plugins/platforms/virtual/virtual_output.cpp index 7f34f7e58c..f798ea9e84 100644 --- a/plugins/platforms/virtual/virtual_output.cpp +++ b/plugins/platforms/virtual/virtual_output.cpp @@ -23,12 +23,26 @@ namespace KWin { VirtualOutput::VirtualOutput(QObject *parent) - : QObject(parent) + : AbstractOutput() { + Q_UNUSED(parent); + + setScale(1.); } VirtualOutput::~VirtualOutput() { } +QSize VirtualOutput::pixelSize() const +{ + return m_pixelSize; +} + +void VirtualOutput::setGeometry(const QRect &geo) +{ + m_pixelSize = geo.size(); + setGlobalPos(geo.topLeft()); +} + } diff --git a/plugins/platforms/virtual/virtual_output.h b/plugins/platforms/virtual/virtual_output.h index ecc7233cea..c81df06bee 100644 --- a/plugins/platforms/virtual/virtual_output.h +++ b/plugins/platforms/virtual/virtual_output.h @@ -20,6 +20,8 @@ along with this program. If not, see . #ifndef KWIN_VIRTUAL_OUTPUT_H #define KWIN_VIRTUAL_OUTPUT_H +#include "abstract_output.h" + #include #include @@ -27,7 +29,7 @@ namespace KWin { class VirtualBackend; -class VirtualOutput : public QObject +class VirtualOutput : public AbstractOutput { Q_OBJECT @@ -35,16 +37,15 @@ public: VirtualOutput(QObject *parent = nullptr); virtual ~VirtualOutput(); - QRect geometry() const { - return m_geo; - } + QSize pixelSize() const override; + + void setGeometry(const QRect &geo); private: Q_DISABLE_COPY(VirtualOutput); friend class VirtualBackend; - QRect m_geo; - qreal m_outputScale = 1; + QSize m_pixelSize; int m_gammaSize = 200; bool m_gammaResult = true;