[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:
parent
3482378278
commit
b22c362bd5
7 changed files with 61 additions and 88 deletions
|
@ -291,15 +291,15 @@ void DecorationInputTest::testDoubleTap_data()
|
||||||
QTest::addColumn<Qt::WindowFrameSection>("expectedSection");
|
QTest::addColumn<Qt::WindowFrameSection>("expectedSection");
|
||||||
QTest::addColumn<Test::ShellSurfaceType>("type");
|
QTest::addColumn<Test::ShellSurfaceType>("type");
|
||||||
|
|
||||||
QTest::newRow("topLeft") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::WlShell;
|
QTest::newRow("topLeft") << QPoint(10, 10) << Qt::TopLeftSection << Test::ShellSurfaceType::WlShell;
|
||||||
QTest::newRow("top") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::WlShell;
|
QTest::newRow("top") << QPoint(260, 10) << Qt::TopSection << Test::ShellSurfaceType::WlShell;
|
||||||
QTest::newRow("topRight") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::WlShell;
|
QTest::newRow("topRight") << QPoint(509, 10) << Qt::TopRightSection << Test::ShellSurfaceType::WlShell;
|
||||||
QTest::newRow("topLeft|xdgv5") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV5;
|
QTest::newRow("topLeft|xdgv5") << QPoint(10, 10) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV5;
|
||||||
QTest::newRow("top|xdgv5") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV5;
|
QTest::newRow("top|xdgv5") << QPoint(260, 10) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV5;
|
||||||
QTest::newRow("topRight|xdgv5") << QPoint(499, 0) << Qt::TopRightSection << Test::ShellSurfaceType::XdgShellV5;
|
QTest::newRow("topRight|xdgv5") << QPoint(509, 10) << Qt::TopRightSection << Test::ShellSurfaceType::XdgShellV5;
|
||||||
QTest::newRow("topLeft|xdgv6") << QPoint(0, 0) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV6;
|
QTest::newRow("topLeft|xdgv6") << QPoint(10, 10) << Qt::TopLeftSection << Test::ShellSurfaceType::XdgShellV6;
|
||||||
QTest::newRow("top|xdgv6") << QPoint(250, 0) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV6;
|
QTest::newRow("top|xdgv6") << QPoint(260, 10) << Qt::TopSection << Test::ShellSurfaceType::XdgShellV6;
|
||||||
QTest::newRow("topRight|xdgv6") << QPoint(499, 0) << Qt::TopRightSection << 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());
|
QVERIFY(!c->isOnAllDesktops());
|
||||||
|
|
||||||
// test top most deco pixel, BUG: 362860
|
// 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);
|
QFETCH(QPoint, decoPoint);
|
||||||
// double click
|
// double click
|
||||||
kwinApp()->platform()->touchDown(0, decoPoint, timestamp++);
|
kwinApp()->platform()->touchDown(0, decoPoint, timestamp++);
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
VirtualScreens::VirtualScreens(VirtualBackend *backend, QObject *parent)
|
VirtualScreens::VirtualScreens(VirtualBackend *backend, QObject *parent)
|
||||||
: Screens(parent)
|
: OutputScreens(backend, parent)
|
||||||
, m_backend(backend)
|
, m_backend(backend)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ void VirtualScreens::init()
|
||||||
connect(m_backend, &VirtualBackend::virtualOutputsSet, this,
|
connect(m_backend, &VirtualBackend::virtualOutputsSet, this,
|
||||||
[this] (bool countChanged) {
|
[this] (bool countChanged) {
|
||||||
if (countChanged) {
|
if (countChanged) {
|
||||||
setCount(m_backend->outputCount());
|
setCount(m_backend->outputs().size());
|
||||||
} else {
|
} else {
|
||||||
emit changed();
|
emit changed();
|
||||||
}
|
}
|
||||||
|
@ -50,45 +50,4 @@ void VirtualScreens::init()
|
||||||
emit changed();
|
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
|
#ifndef KWIN_SCREENS_VIRTUAL_H
|
||||||
#define KWIN_SCREENS_VIRTUAL_H
|
#define KWIN_SCREENS_VIRTUAL_H
|
||||||
#include "screens.h"
|
#include "outputscreens.h"
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
class VirtualBackend;
|
class VirtualBackend;
|
||||||
|
|
||||||
class VirtualScreens : public Screens
|
class VirtualScreens : public OutputScreens
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
VirtualScreens(VirtualBackend *backend, QObject *parent = nullptr);
|
VirtualScreens(VirtualBackend *backend, QObject *parent = nullptr);
|
||||||
virtual ~VirtualScreens();
|
virtual ~VirtualScreens();
|
||||||
void init() override;
|
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:
|
private:
|
||||||
void createOutputs();
|
void createOutputs();
|
||||||
|
|
|
@ -76,8 +76,9 @@ void VirtualBackend::init()
|
||||||
*/
|
*/
|
||||||
if (!m_outputs.size()) {
|
if (!m_outputs.size()) {
|
||||||
VirtualOutput *dummyOutput = new VirtualOutput(this);
|
VirtualOutput *dummyOutput = new VirtualOutput(this);
|
||||||
dummyOutput->m_geo = QRect(QPoint(0, 0), initialWindowSize());
|
dummyOutput->setGeometry(QRect(QPoint(0, 0), initialWindowSize()));
|
||||||
m_outputs = { dummyOutput };
|
m_outputs << dummyOutput ;
|
||||||
|
m_enabledOutputs << dummyOutput ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,6 +114,16 @@ OpenGLBackend *VirtualBackend::createOpenGLBackend()
|
||||||
return new EglGbmBackend(this);
|
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)
|
void VirtualBackend::setVirtualOutputs(int count, QVector<QRect> geometries)
|
||||||
{
|
{
|
||||||
Q_ASSERT(geometries.size() == 0 || geometries.size() == count);
|
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;
|
bool countChanged = m_outputs.size() != count;
|
||||||
qDeleteAll(m_outputs.begin(), m_outputs.end());
|
qDeleteAll(m_outputs.begin(), m_outputs.end());
|
||||||
m_outputs.resize(count);
|
m_outputs.resize(count);
|
||||||
|
m_enabledOutputs.resize(count);
|
||||||
|
|
||||||
int sumWidth = 0;
|
int sumWidth = 0;
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
VirtualOutput *vo = new VirtualOutput(this);
|
VirtualOutput *vo = new VirtualOutput(this);
|
||||||
if (geometries.size()) {
|
if (geometries.size()) {
|
||||||
vo->m_geo = geometries.at(i);
|
vo->setGeometry(geometries.at(i));
|
||||||
} else if (!vo->m_geo.isValid()) {
|
} else if (!vo->geometry().isValid()) {
|
||||||
vo->m_geo = QRect(QPoint(sumWidth, 0), initialWindowSize());
|
vo->setGeometry(QRect(QPoint(sumWidth, 0), initialWindowSize()));
|
||||||
sumWidth += vo->m_geo.width();
|
sumWidth += initialWindowSize().width();
|
||||||
}
|
}
|
||||||
m_outputs[i] = vo;
|
m_outputs[i] = m_enabledOutputs[i] = vo;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit virtualOutputsSet(countChanged);
|
emit virtualOutputsSet(countChanged);
|
||||||
|
|
|
@ -45,16 +45,6 @@ public:
|
||||||
virtual ~VirtualBackend();
|
virtual ~VirtualBackend();
|
||||||
void init() override;
|
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 {
|
bool saveFrames() const {
|
||||||
return !m_screenshotDir.isNull();
|
return !m_screenshotDir.isNull();
|
||||||
}
|
}
|
||||||
|
@ -66,9 +56,8 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void setVirtualOutputs(int count, QVector<QRect> geometries = QVector<QRect>());
|
Q_INVOKABLE void setVirtualOutputs(int count, QVector<QRect> geometries = QVector<QRect>());
|
||||||
|
|
||||||
Q_INVOKABLE void setOutputScale(qreal scale) {
|
Outputs outputs() const override;
|
||||||
m_outputScale = scale;
|
Outputs enabledOutputs() const override;
|
||||||
}
|
|
||||||
|
|
||||||
int drmFd() const {
|
int drmFd() const {
|
||||||
return m_drmFd;
|
return m_drmFd;
|
||||||
|
@ -95,8 +84,7 @@ Q_SIGNALS:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVector<VirtualOutput*> m_outputs;
|
QVector<VirtualOutput*> m_outputs;
|
||||||
|
QVector<VirtualOutput*> m_enabledOutputs;
|
||||||
qreal m_outputScale = 1;
|
|
||||||
|
|
||||||
QScopedPointer<QTemporaryDir> m_screenshotDir;
|
QScopedPointer<QTemporaryDir> m_screenshotDir;
|
||||||
int m_drmFd = -1;
|
int m_drmFd = -1;
|
||||||
|
|
|
@ -23,12 +23,26 @@ namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
VirtualOutput::VirtualOutput(QObject *parent)
|
VirtualOutput::VirtualOutput(QObject *parent)
|
||||||
: QObject(parent)
|
: AbstractOutput()
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
|
||||||
|
setScale(1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualOutput::~VirtualOutput()
|
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
|
#ifndef KWIN_VIRTUAL_OUTPUT_H
|
||||||
#define KWIN_VIRTUAL_OUTPUT_H
|
#define KWIN_VIRTUAL_OUTPUT_H
|
||||||
|
|
||||||
|
#include "abstract_output.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QRect>
|
#include <QRect>
|
||||||
|
|
||||||
|
@ -27,7 +29,7 @@ namespace KWin
|
||||||
{
|
{
|
||||||
class VirtualBackend;
|
class VirtualBackend;
|
||||||
|
|
||||||
class VirtualOutput : public QObject
|
class VirtualOutput : public AbstractOutput
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -35,16 +37,15 @@ public:
|
||||||
VirtualOutput(QObject *parent = nullptr);
|
VirtualOutput(QObject *parent = nullptr);
|
||||||
virtual ~VirtualOutput();
|
virtual ~VirtualOutput();
|
||||||
|
|
||||||
QRect geometry() const {
|
QSize pixelSize() const override;
|
||||||
return m_geo;
|
|
||||||
}
|
void setGeometry(const QRect &geo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY(VirtualOutput);
|
Q_DISABLE_COPY(VirtualOutput);
|
||||||
friend class VirtualBackend;
|
friend class VirtualBackend;
|
||||||
|
|
||||||
QRect m_geo;
|
QSize m_pixelSize;
|
||||||
qreal m_outputScale = 1;
|
|
||||||
|
|
||||||
int m_gammaSize = 200;
|
int m_gammaSize = 200;
|
||||||
bool m_gammaResult = true;
|
bool m_gammaResult = true;
|
||||||
|
|
Loading…
Reference in a new issue