Commit d8ea87a9 authored by Vlad Zahorodnii's avatar Vlad Zahorodnii
Browse files

Add dummy placeholder output type

Placeholder outputs are not rendered so they don't need render data.
Also, this simplifies the control flow when the last real output is
removed. The Platform::screensQueried signal won't be emitted inside a
Platform::screensQueried slot.
parent 192a57e2
Pipeline #227950 passed with stage
in 31 minutes and 47 seconds
......@@ -106,6 +106,7 @@ target_sources(kwin PRIVATE
osd.cpp
outline.cpp
placeholderinputeventfilter.cpp
placeholderoutput.cpp
placement.cpp
placementtracker.cpp
plugin.cpp
......
......@@ -403,9 +403,9 @@ QString DrmBackend::supportInformation() const
return supportInfo;
}
Output *DrmBackend::createVirtualOutput(const QString &name, const QSize &size, double scale, VirtualOutputType type)
Output *DrmBackend::createVirtualOutput(const QString &name, const QSize &size, double scale)
{
auto output = primaryGpu()->createVirtualOutput(name, size * scale, scale, type);
auto output = primaryGpu()->createVirtualOutput(name, size * scale, scale);
Q_EMIT screensQueried();
return output;
}
......
......@@ -60,7 +60,7 @@ public:
QVector<CompositingType> supportedCompositors() const override;
QString supportInformation() const override;
Output *createVirtualOutput(const QString &name, const QSize &size, double scale, VirtualOutputType type) override;
Output *createVirtualOutput(const QString &name, const QSize &size, double scale) override;
void removeVirtualOutput(Output *output) override;
DrmGpu *primaryGpu() const;
......
......@@ -587,9 +587,9 @@ const QVector<DrmPipeline *> DrmGpu::pipelines() const
return m_pipelines;
}
DrmVirtualOutput *DrmGpu::createVirtualOutput(const QString &name, const QSize &size, double scale, VirtualOutputType type)
DrmVirtualOutput *DrmGpu::createVirtualOutput(const QString &name, const QSize &size, double scale)
{
auto output = new DrmVirtualOutput(name, this, size, scale, type);
auto output = new DrmVirtualOutput(name, this, size, scale);
m_outputs << output;
Q_EMIT outputAdded(output);
return output;
......
......@@ -11,7 +11,6 @@
#define DRM_GPU_H
#include "drm_pipeline.h"
#include "drm_virtual_output.h"
#include <QPointer>
#include <QSize>
......@@ -42,6 +41,7 @@ class DrmBackend;
class EglGbmBackend;
class DrmAbstractOutput;
class DrmRenderBackend;
class DrmVirtualOutput;
class DrmGpu : public QObject
{
......@@ -74,7 +74,7 @@ public:
bool updateOutputs();
DrmVirtualOutput *createVirtualOutput(const QString &name, const QSize &size, double scale, VirtualOutputType type);
DrmVirtualOutput *createVirtualOutput(const QString &name, const QSize &size, double scale);
void removeVirtualOutput(DrmVirtualOutput *output);
DrmPipeline::Error testPendingConfiguration();
......
......@@ -20,7 +20,7 @@
namespace KWin
{
DrmVirtualOutput::DrmVirtualOutput(const QString &name, DrmGpu *gpu, const QSize &size, qreal scale, VirtualOutputType type)
DrmVirtualOutput::DrmVirtualOutput(const QString &name, DrmGpu *gpu, const QSize &size, qreal scale)
: DrmAbstractOutput(gpu)
, m_vsyncMonitor(SoftwareVsyncMonitor::create())
{
......@@ -32,7 +32,6 @@ DrmVirtualOutput::DrmVirtualOutput(const QString &name, DrmGpu *gpu, const QSize
setInformation(Information{
.name = QStringLiteral("Virtual-") + name,
.physicalSize = size,
.placeholder = type == VirtualOutputType::Placeholder,
});
setState(State{
......
......@@ -9,7 +9,6 @@
*/
#pragma once
#include "core/platform.h"
#include "drm_abstract_output.h"
#include <QObject>
......@@ -27,7 +26,7 @@ class DrmVirtualOutput : public DrmAbstractOutput
Q_OBJECT
public:
DrmVirtualOutput(const QString &name, DrmGpu *gpu, const QSize &size, qreal scale, VirtualOutputType type);
DrmVirtualOutput(const QString &name, DrmGpu *gpu, const QSize &size, qreal scale);
~DrmVirtualOutput() override;
bool present() override;
......
......@@ -775,11 +775,11 @@ void WaylandBackend::createOutputs()
for (int i = 0; i < initialOutputCount(); i++) {
const QString name = QStringLiteral("WL-%1").arg(i);
createOutput(name, QSize(pixelWidth, pixelHeight), false);
createOutput(name, QSize(pixelWidth, pixelHeight));
}
}
WaylandOutput *WaylandBackend::createOutput(const QString &name, const QSize &size, bool placeholder)
WaylandOutput *WaylandBackend::createOutput(const QString &name, const QSize &size)
{
auto surface = m_compositor->createSurface(this);
if (!surface || !surface->isValid()) {
......@@ -799,7 +799,7 @@ WaylandOutput *WaylandBackend::createOutput(const QString &name, const QSize &si
WaylandOutput *waylandOutput = nullptr;
if (m_xdgShell && m_xdgShell->isValid()) {
waylandOutput = new XdgShellOutput(name, surface, m_xdgShell, this, m_nextId++, placeholder);
waylandOutput = new XdgShellOutput(name, surface, m_xdgShell, this, m_nextId++);
}
if (!waylandOutput) {
......@@ -967,9 +967,9 @@ void WaylandBackend::clearDpmsFilter()
m_dpmsFilter.reset();
}
Output *WaylandBackend::createVirtualOutput(const QString &name, const QSize &size, double scale, VirtualOutputType type)
Output *WaylandBackend::createVirtualOutput(const QString &name, const QSize &size, double scale)
{
return createOutput(name, size * scale, type == VirtualOutputType::Placeholder);
return createOutput(name, size * scale);
}
void WaylandBackend::removeVirtualOutput(Output *output)
......
......@@ -298,7 +298,7 @@ public:
void createDpmsFilter();
void clearDpmsFilter();
Output *createVirtualOutput(const QString &name, const QSize &size, double scale, VirtualOutputType type) override;
Output *createVirtualOutput(const QString &name, const QSize &size, double scale) override;
void removeVirtualOutput(Output *output) override;
std::optional<DmaBufParams> testCreateDmaBuf(const QSize &size, quint32 format, const QVector<uint64_t> &modifiers) override;
......@@ -327,7 +327,7 @@ private:
void createOutputs();
void destroyOutputs();
WaylandOutput *createOutput(const QString &name, const QSize &size, bool placeholder);
WaylandOutput *createOutput(const QString &name, const QSize &size);
wl_display *m_display;
KWayland::Client::EventQueue *m_eventQueue;
......
......@@ -24,7 +24,7 @@ namespace Wayland
using namespace KWayland::Client;
static const int s_refreshRate = 60000; // TODO: can we get refresh rate data from Wayland host?
WaylandOutput::WaylandOutput(const QString &name, Surface *surface, WaylandBackend *backend, bool placeholder)
WaylandOutput::WaylandOutput(const QString &name, Surface *surface, WaylandBackend *backend)
: Output(backend)
, m_renderLoop(std::make_unique<RenderLoop>())
, m_surface(surface)
......@@ -34,7 +34,6 @@ WaylandOutput::WaylandOutput(const QString &name, Surface *surface, WaylandBacke
.name = name,
.model = name,
.capabilities = Capability::Dpms,
.placeholder = placeholder,
});
connect(surface, &Surface::frameRendered, this, &WaylandOutput::frameRendered);
......@@ -114,8 +113,8 @@ void WaylandOutput::updateEnabled(bool enabled)
setState(next);
}
XdgShellOutput::XdgShellOutput(const QString &name, Surface *surface, XdgShell *xdgShell, WaylandBackend *backend, int number, bool placeholder)
: WaylandOutput(name, surface, backend, placeholder)
XdgShellOutput::XdgShellOutput(const QString &name, Surface *surface, XdgShell *xdgShell, WaylandBackend *backend, int number)
: WaylandOutput(name, surface, backend)
, m_number(number)
{
m_xdgShellSurface = xdgShell->createSurface(surface, this);
......
......@@ -39,7 +39,7 @@ class WaylandOutput : public Output
{
Q_OBJECT
public:
WaylandOutput(const QString &name, KWayland::Client::Surface *surface, WaylandBackend *backend, bool placeholder);
WaylandOutput(const QString &name, KWayland::Client::Surface *surface, WaylandBackend *backend);
~WaylandOutput() override;
RenderLoop *renderLoop() const override;
......@@ -92,7 +92,7 @@ public:
XdgShellOutput(const QString &name,
KWayland::Client::Surface *surface,
KWayland::Client::XdgShell *xdgShell,
WaylandBackend *backend, int number, bool placeholder);
WaylandBackend *backend, int number);
~XdgShellOutput() override;
void lockPointer(KWayland::Client::Pointer *pointer, bool lock) override;
......
......@@ -142,12 +142,11 @@ void Platform::setReady(bool ready)
Q_EMIT readyChanged(m_ready);
}
Output *Platform::createVirtualOutput(const QString &name, const QSize &size, double scale, VirtualOutputType type)
Output *Platform::createVirtualOutput(const QString &name, const QSize &size, double scale)
{
Q_UNUSED(name);
Q_UNUSED(size);
Q_UNUSED(scale);
Q_UNUSED(type);
return nullptr;
}
......
......@@ -40,11 +40,6 @@ class ScreenEdges;
class OutputConfiguration;
struct DmaBufParams;
enum class VirtualOutputType {
Normal,
Placeholder,
};
class KWIN_EXPORT Outputs : public QVector<Output *>
{
public:
......@@ -322,7 +317,7 @@ public:
m_selectedCompositor = type;
}
virtual Output *createVirtualOutput(const QString &name, const QSize &size, qreal scaling, VirtualOutputType type);
virtual Output *createVirtualOutput(const QString &name, const QSize &size, qreal scale);
virtual void removeVirtualOutput(Output *output);
/**
......
/*
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "placeholderoutput.h"
namespace KWin
{
PlaceholderOutput::PlaceholderOutput(const QSize &size, qreal scale)
{
auto mode = std::make_shared<OutputMode>(size, 60000);
m_renderLoop = std::make_unique<RenderLoop>();
m_renderLoop->setRefreshRate(mode->refreshRate());
m_renderLoop->inhibit();
setState(State{
.scale = scale,
.modes = {mode},
.currentMode = mode,
.enabled = true,
});
setInformation(Information{
.name = QStringLiteral("Placeholder-1"),
.placeholder = true,
});
}
PlaceholderOutput::~PlaceholderOutput()
{
}
RenderLoop *PlaceholderOutput::renderLoop() const
{
return m_renderLoop.get();
}
} // namespace KWin
/*
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "core/output.h"
namespace KWin
{
class PlaceholderOutput : public Output
{
Q_OBJECT
public:
PlaceholderOutput(const QSize &size, qreal scale = 1);
~PlaceholderOutput() override;
RenderLoop *renderLoop() const override;
private:
std::unique_ptr<RenderLoop> m_renderLoop;
};
} // namespace KWin
......@@ -110,7 +110,7 @@ void ScreencastManager::streamVirtualOutput(KWaylandServer::ScreencastStreamV1In
double scale,
KWaylandServer::ScreencastV1Interface::CursorMode mode)
{
auto output = kwinApp()->platform()->createVirtualOutput(name, size, scale, VirtualOutputType::Normal);
auto output = kwinApp()->platform()->createVirtualOutput(name, size, scale);
streamOutput(stream, output, mode);
connect(stream, &KWaylandServer::ScreencastStreamV1Interface::finished, output, [output] {
kwinApp()->platform()->removeVirtualOutput(output);
......
......@@ -48,6 +48,7 @@
#include "decorations/decorationbridge.h"
#include "main.h"
#include "placeholderinputeventfilter.h"
#include "placeholderoutput.h"
#include "placementtracker.h"
#include "unmanaged.h"
#include "useractions.h"
......@@ -1452,8 +1453,9 @@ void Workspace::addOutput(Output *output)
Q_EMIT outputAdded(output);
if (m_placeholderOutput) {
kwinApp()->platform()->removeVirtualOutput(m_placeholderOutput);
m_placeholderOutput = nullptr;
m_outputs.removeOne(m_placeholderOutput.get());
Q_EMIT outputRemoved(m_placeholderOutput.get());
m_placeholderOutput.reset();
m_placeholderFilter.reset();
}
}
......@@ -1465,8 +1467,9 @@ void Workspace::removeOutput(Output *output)
}
if (m_outputs.empty()) {
// not all parts of KWin handle having no output yet. To prevent crashes, create a placeholder output
m_placeholderOutput = kwinApp()->platform()->createVirtualOutput("placeholder", output->pixelSize(), output->scale(), VirtualOutputType::Placeholder);
m_placeholderOutput->renderLoop()->inhibit();
m_placeholderOutput = std::make_unique<PlaceholderOutput>(output->pixelSize(), output->scale());
m_outputs.append(m_placeholderOutput.get());
Q_EMIT outputAdded(m_placeholderOutput.get());
// also prevent accidental inputs while the user has no screen connected
m_placeholderFilter = std::make_unique<PlaceholderInputEventFilter>();
input()->prependInputEventFilter(m_placeholderFilter.get());
......
......@@ -76,6 +76,7 @@ class Screens;
class Activities;
#endif
class PlaceholderInputEventFilter;
class PlaceholderOutput;
class Placement;
class KWIN_EXPORT Workspace : public QObject
......@@ -756,7 +757,7 @@ private:
#endif
std::unique_ptr<PlacementTracker> m_placementTracker;
Output *m_placeholderOutput = nullptr;
std::unique_ptr<PlaceholderOutput> m_placeholderOutput;
std::unique_ptr<PlaceholderInputEventFilter> m_placeholderFilter;
private:
......
Supports Markdown
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