wayland: Make kwin_wayland create virtual outputs

At the moment, we rely on placeholder output getting created, but there
are cases where it's desired to spin kwin with virtual outputs so you
could take screenshots and things as such.
This commit is contained in:
Vlad Zahorodnii 2022-12-06 15:20:43 +02:00
parent cdda8593d8
commit ca7f7a42c8
5 changed files with 37 additions and 33 deletions

View file

@ -66,6 +66,23 @@ Outputs VirtualBackend::outputs() const
return m_outputs;
}
VirtualOutput *VirtualBackend::createOutput(const QPoint &position, const QSize &size, qreal scale)
{
VirtualOutput *output = new VirtualOutput(this);
output->init(position, size, scale);
m_outputs.append(output);
Q_EMIT outputAdded(output);
output->updateEnabled(true);
return output;
}
Output *VirtualBackend::addOutput(const QSize &size, qreal scale)
{
VirtualOutput *output = createOutput(QPoint(), size * scale, scale);
Q_EMIT outputsQueried();
return output;
}
void VirtualBackend::setVirtualOutputs(const QVector<QRect> &geometries, QVector<int> scales)
{
Q_ASSERT(scales.size() == 0 || scales.size() == geometries.size());
@ -73,14 +90,7 @@ void VirtualBackend::setVirtualOutputs(const QVector<QRect> &geometries, QVector
const QVector<VirtualOutput *> removed = m_outputs;
for (int i = 0; i < geometries.size(); i++) {
VirtualOutput *vo = new VirtualOutput(this);
vo->init(geometries[i].topLeft(), geometries[i].size());
if (scales.size()) {
vo->updateScale(scales.at(i));
}
m_outputs.append(vo);
Q_EMIT outputAdded(vo);
vo->updateEnabled(true);
createOutput(geometries[i].topLeft(), geometries[i].size(), scales.value(i, 1.0));
}
for (VirtualOutput *output : removed) {

View file

@ -41,6 +41,7 @@ public:
std::unique_ptr<QPainterBackend> createQPainterBackend() override;
std::unique_ptr<OpenGLBackend> createOpenGLBackend() override;
Output *addOutput(const QSize &size, qreal scale);
Q_INVOKABLE void setVirtualOutputs(const QVector<QRect> &geometries, QVector<int> scales = QVector<int>());
Outputs outputs() const override;
@ -54,6 +55,8 @@ Q_SIGNALS:
void virtualOutputsSet(bool countChanged);
private:
VirtualOutput *createOutput(const QPoint &position, const QSize &size, qreal scale);
QVector<VirtualOutput *> m_outputs;
std::unique_ptr<QTemporaryDir> m_screenshotDir;
};

View file

@ -44,32 +44,20 @@ SoftwareVsyncMonitor *VirtualOutput::vsyncMonitor() const
return m_vsyncMonitor.get();
}
void VirtualOutput::init(const QPoint &logicalPosition, const QSize &pixelSize)
void VirtualOutput::init(const QPoint &logicalPosition, const QSize &pixelSize, qreal scale)
{
const int refreshRate = 60000; // TODO: Make the refresh rate configurable.
m_renderLoop->setRefreshRate(refreshRate);
m_vsyncMonitor->setRefreshRate(refreshRate);
setGeometry(QRect(logicalPosition, pixelSize));
}
auto mode = std::make_shared<OutputMode>(pixelSize, m_vsyncMonitor->refreshRate());
void VirtualOutput::setGeometry(const QRect &geo)
{
auto mode = std::make_shared<OutputMode>(geo.size(), m_vsyncMonitor->refreshRate());
State next = m_state;
next.modes = {mode};
next.currentMode = mode;
next.position = geo.topLeft();
setState(next);
}
void VirtualOutput::updateScale(qreal scale)
{
State next = m_state;
next.scale = scale;
setState(next);
setState(State{
.position = logicalPosition,
.scale = scale,
.modes = {mode},
.currentMode = mode,
});
}
void VirtualOutput::updateEnabled(bool enabled)

View file

@ -30,9 +30,7 @@ public:
RenderLoop *renderLoop() const override;
SoftwareVsyncMonitor *vsyncMonitor() const;
void init(const QPoint &logicalPosition, const QSize &pixelSize);
void setGeometry(const QRect &geo);
void updateScale(qreal scale);
void init(const QPoint &logicalPosition, const QSize &pixelSize, qreal scale);
void updateEnabled(bool enabled);
private:

View file

@ -553,10 +553,15 @@ int main(int argc, char *argv[])
}
a.setOutputBackend(std::make_unique<KWin::DrmBackend>(a.session()));
break;
case BackendType::Virtual:
case BackendType::Virtual: {
auto outputBackend = std::make_unique<KWin::VirtualBackend>();
for (int i = 0; i < outputCount; ++i) {
outputBackend->addOutput(initialWindowSize, outputScale);
}
a.setSession(KWin::Session::create(KWin::Session::Type::Noop));
a.setOutputBackend(std::make_unique<KWin::VirtualBackend>());
a.setOutputBackend(std::move(outputBackend));
break;
}
case BackendType::X11: {
QString display = parser.value(x11DisplayOption);
if (display.isEmpty()) {