[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
This commit is contained in:
Roman Gilg 2018-03-29 18:38:27 +02:00
parent 3482378278
commit b22c362bd5
7 changed files with 61 additions and 88 deletions

View file

@ -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++);

View file

@ -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;
}
}

View file

@ -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();

View file

@ -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);

View file

@ -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;

View file

@ -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());
}
}

View file

@ -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;