Commit b22c362b authored by Roman Gilg's avatar Roman Gilg

[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
parent 34823782
......@@ -291,15 +291,15 @@ void DecorationInputTest::testDoubleTap_data()
QTest::addColumn<Qt::WindowFrameSection>("expectedSection");
QTest::addColumn<Test::ShellSurfaceType>("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++);
......
......@@ -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;
}
}
......@@ -19,24 +19,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_SCREENS_VIRTUAL_H
#define KWIN_SCREENS_VIRTUAL_H
#include "screens.h"
#include "outputscreens.h"
#include <QVector>
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();
......
......@@ -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<QRect> geometries)
{
Q_ASSERT(geometries.size() == 0 || geometries.size() == count);
......@@ -120,17 +131,18 @@ void VirtualBackend::setVirtualOutputs(int count, QVector<QRect> 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);
......
......@@ -45,16 +45,6 @@ public:
virtual ~VirtualBackend();
void init() override;
int outputCount() const {
return m_outputs.size();
}
const QVector<VirtualOutput*> 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<QRect> geometries = QVector<QRect>());
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<VirtualOutput*> m_outputs;
qreal m_outputScale = 1;
QVector<VirtualOutput*> m_enabledOutputs;
QScopedPointer<QTemporaryDir> m_screenshotDir;
int m_drmFd = -1;
......
......@@ -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());
}
}
......@@ -20,6 +20,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef KWIN_VIRTUAL_OUTPUT_H
#define KWIN_VIRTUAL_OUTPUT_H
#include "abstract_output.h"
#include <QObject>
#include <QRect>
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment