Drop Platform::enabledOutputs()

At the moment, a platform should provide two output lists - one that
lists all available outputs, and the other one that contains only
enabled outputs. In general, this amounts to some boilerplate code and
forces backends to be implemented in some certain way, which sometimes
is inconvenient, e.g. if an output is disabled or enabled, it will be
simpler if we only change Output::isEnabled(), otherwise we need to
start accounting for corner cases such as the order in which
Output::isEnabled() and Platform::enabledOutputs() are changed, etc.
This commit is contained in:
Vlad Zahorodnii 2022-07-21 12:23:43 +03:00
parent 2629007eef
commit a198516871
22 changed files with 94 additions and 95 deletions

View file

@ -140,7 +140,7 @@ void WaylandTestApplication::performStartup()
createInput();
createVirtualInputDevices();
if (!platform()->enabledOutputs().isEmpty()) {
if (!platform()->outputs().isEmpty()) {
continueStartupWithScreens();
} else {
connect(platform(), &Platform::screensQueried, this, &WaylandTestApplication::continueStartupWithScreens);

View file

@ -152,7 +152,7 @@ void ScreensTest::testCurrent_data()
void ScreensTest::testCurrent()
{
QFETCH(int, currentId);
Output *output = kwinApp()->platform()->enabledOutputs().at(currentId);
Output *output = workspace()->outputs().at(currentId);
// Disable "active screen follows mouse"
auto group = kwinApp()->config()->group("Windows");
@ -197,7 +197,7 @@ void ScreensTest::testCurrentWithFollowsMouse()
KWin::Cursors::self()->mouse()->setPos(cursorPos);
QFETCH(int, expectedId);
Output *expected = kwinApp()->platform()->enabledOutputs().at(expectedId);
Output *expected = workspace()->outputs().at(expectedId);
QCOMPARE(workspace()->activeOutput(), expected);
}
@ -234,7 +234,7 @@ void ScreensTest::testCurrentPoint()
workspace()->setActiveOutput(cursorPos);
QFETCH(int, expectedId);
Output *expected = kwinApp()->platform()->enabledOutputs().at(expectedId);
Output *expected = workspace()->outputs().at(expectedId);
QCOMPARE(workspace()->activeOutput(), expected);
}

View file

@ -108,11 +108,6 @@ Outputs DrmBackend::outputs() const
return m_outputs;
}
Outputs DrmBackend::enabledOutputs() const
{
return m_enabledOutputs;
}
void DrmBackend::createDpmsFilter()
{
if (m_dpmsFilter) {

View file

@ -54,7 +54,6 @@ public:
bool initialize() override;
Outputs outputs() const override;
Outputs enabledOutputs() const override;
void enableOutput(DrmAbstractOutput *output, bool enable);

View file

@ -522,14 +522,15 @@ void Connection::applyScreenToDevice(Device *device)
}
Output *deviceOutput = nullptr;
const QVector<Output *> outputs = kwinApp()->platform()->enabledOutputs();
const QVector<Output *> outputs = kwinApp()->platform()->outputs();
// let's try to find a screen for it
if (outputs.count() == 1) {
deviceOutput = outputs.constFirst();
}
if (!deviceOutput && !device->outputName().isEmpty()) {
if (!device->outputName().isEmpty()) {
// we have an output name, try to find a screen with matching name
for (Output *output : outputs) {
if (!output->isEnabled()) {
continue;
}
if (output->name() == device->outputName()) {
deviceOutput = output;
break;
@ -540,6 +541,9 @@ void Connection::applyScreenToDevice(Device *device)
// do we have an internal screen?
Output *internalOutput = nullptr;
for (Output *output : outputs) {
if (!output->isEnabled()) {
continue;
}
if (output->isInternal()) {
internalOutput = output;
break;
@ -556,6 +560,9 @@ void Connection::applyScreenToDevice(Device *device)
}
// let's compare all screens for size
for (Output *output : outputs) {
if (!output->isEnabled()) {
continue;
}
if (testScreenMatches(output)) {
deviceOutput = output;
break;
@ -566,9 +573,14 @@ void Connection::applyScreenToDevice(Device *device)
if (internalOutput) {
// we have an internal id, so let's use that
deviceOutput = internalOutput;
} else if (!outputs.isEmpty()) {
// just take first screen, we have no clue
deviceOutput = outputs.constFirst();
} else {
for (Output *output : outputs) {
// just take first screen, we have no clue
if (output->isEnabled()) {
deviceOutput = output;
break;
}
}
}
}
}

View file

@ -647,8 +647,11 @@ void Device::setOutputName(const QString &name)
setOutput(nullptr);
return;
}
auto outputs = kwinApp()->platform()->enabledOutputs();
auto outputs = kwinApp()->platform()->outputs();
for (int i = 0; i < outputs.count(); ++i) {
if (!outputs[i]->isEnabled()) {
continue;
}
if (outputs[i]->name() == name) {
setOutput(outputs[i]);
break;

View file

@ -87,11 +87,6 @@ Outputs VirtualBackend::outputs() const
return m_outputs;
}
Outputs VirtualBackend::enabledOutputs() const
{
return m_outputsEnabled;
}
void VirtualBackend::setVirtualOutputs(int count, QVector<QRect> geometries, QVector<int> scales)
{
Q_ASSERT(geometries.size() == 0 || geometries.size() == count);

View file

@ -44,7 +44,6 @@ public:
Q_INVOKABLE void setVirtualOutputs(int count, QVector<QRect> geometries = QVector<QRect>(), QVector<int> scales = QVector<int>());
Outputs outputs() const override;
Outputs enabledOutputs() const override;
QVector<CompositingType> supportedCompositors() const override
{

View file

@ -120,9 +120,11 @@ void VirtualEglBackend::init()
setSupportsBufferAge(false);
initWayland();
const auto outputs = m_backend->enabledOutputs();
const auto outputs = m_backend->outputs();
for (Output *output : outputs) {
addOutput(output);
if (output->isEnabled()) {
addOutput(output);
}
}
connect(m_backend, &VirtualBackend::outputEnabled, this, &VirtualEglBackend::addOutput);

View file

@ -50,9 +50,11 @@ VirtualQPainterBackend::VirtualQPainterBackend(VirtualBackend *backend)
connect(backend, &VirtualBackend::outputEnabled, this, &VirtualQPainterBackend::addOutput);
connect(backend, &VirtualBackend::outputDisabled, this, &VirtualQPainterBackend::removeOutput);
const auto outputs = backend->enabledOutputs();
const auto outputs = backend->outputs();
for (Output *output : outputs) {
addOutput(output);
if (output->isEnabled()) {
addOutput(output);
}
}
}

View file

@ -942,17 +942,6 @@ Outputs WaylandBackend::outputs() const
return m_outputs;
}
Outputs WaylandBackend::enabledOutputs() const
{
Outputs ret;
for (auto o : m_outputs) {
if (o->isEnabled()) {
ret << o;
}
}
return ret;
}
void WaylandBackend::addConfiguredOutput(WaylandOutput *output)
{
m_outputs << output;

View file

@ -289,7 +289,6 @@ public:
WaylandOutput *getOutputAt(const QPointF &globalPosition);
WaylandOutput *findOutput(KWayland::Client::Surface *nativeSurface) const;
Outputs outputs() const override;
Outputs enabledOutputs() const override;
QVector<WaylandOutput *> waylandOutputs() const
{
return m_outputs;

View file

@ -638,11 +638,6 @@ Outputs X11StandalonePlatform::outputs() const
return m_outputs;
}
Outputs X11StandalonePlatform::enabledOutputs() const
{
return m_outputs;
}
RenderLoop *X11StandalonePlatform::renderLoop() const
{
return m_renderLoop.get();
@ -660,7 +655,7 @@ static int currentRefreshRate()
return refreshRate;
}
const QVector<Output *> outputs = kwinApp()->platform()->enabledOutputs();
const QVector<Output *> outputs = kwinApp()->platform()->outputs();
if (outputs.isEmpty()) {
return 60000;
}

View file

@ -65,7 +65,6 @@ public:
RenderLoop *renderLoop() const;
Outputs outputs() const override;
Outputs enabledOutputs() const override;
private:
/**

View file

@ -696,9 +696,4 @@ Outputs X11WindowedBackend::outputs() const
return m_outputs;
}
Outputs X11WindowedBackend::enabledOutputs() const
{
return m_outputs;
}
}
} // namespace KWin

View file

@ -131,7 +131,6 @@ public:
X11WindowedInputDevice *touchDevice() const;
Outputs outputs() const override;
Outputs enabledOutputs() const override;
Q_SIGNALS:
void sizeChanged();

View file

@ -50,9 +50,11 @@ X11WindowedQPainterBackend::X11WindowedQPainterBackend(X11WindowedBackend *backe
: QPainterBackend()
, m_backend(backend)
{
const auto outputs = m_backend->enabledOutputs();
const auto outputs = m_backend->outputs();
for (Output *output : outputs) {
addOutput(output);
if (output->isEnabled()) {
addOutput(output);
}
}
connect(backend, &X11WindowedBackend::outputEnabled, this, &X11WindowedQPainterBackend::addOutput);

View file

@ -26,9 +26,11 @@ ColorManager::ColorManager()
{
Platform *platform = kwinApp()->platform();
const QVector<Output *> outputs = platform->enabledOutputs();
const QVector<Output *> outputs = platform->outputs();
for (Output *output : outputs) {
handleOutputEnabled(output);
if (output->isEnabled()) {
handleOutputEnabled(output);
}
}
connect(platform, &Platform::outputEnabled, this, &ColorManager::handleOutputEnabled);

View file

@ -49,7 +49,15 @@ Platform::Platform(QObject *parent)
{
connect(this, &Platform::outputDisabled, this, [this](Output *output) {
if (m_primaryOutput == output) {
setPrimaryOutput(enabledOutputs().value(0, nullptr));
Output *primary = nullptr;
const auto candidates = outputs();
for (Output *output : candidates) {
if (output->isEnabled()) {
primary = output;
break;
}
}
setPrimaryOutput(primary);
}
});
connect(this, &Platform::outputEnabled, this, [this](Output *output) {
@ -170,7 +178,14 @@ void Platform::requestOutputsChange(KWaylandServer::OutputConfigurationV2Interfa
if (requestedPrimaryOutput && requestedPrimaryOutput->isEnabled()) {
setPrimaryOutput(requestedPrimaryOutput);
} else {
auto defaultPrimaryOutput = enabledOutputs().constFirst();
Output *defaultPrimaryOutput = nullptr;
const auto candidates = outputs();
for (Output *output : candidates) {
if (output->isEnabled()) {
defaultPrimaryOutput = output;
break;
}
}
qCWarning(KWIN_CORE) << "Requested invalid primary screen, using" << defaultPrimaryOutput;
setPrimaryOutput(defaultPrimaryOutput);
}

View file

@ -300,16 +300,10 @@ public:
return m_supportsGammaControl;
}
// outputs with connections (org_kde_kwin_outputdevice)
virtual Outputs outputs() const
{
return Outputs();
}
// actively compositing outputs (wl_output)
virtual Outputs enabledOutputs() const
{
return Outputs();
}
Output *findOutput(const QUuid &uuid) const;
Output *findOutput(const QString &name) const;

View file

@ -290,11 +290,9 @@ void WaylandServer::initPlatform()
const QVector<Output *> outputs = kwinApp()->platform()->outputs();
for (Output *output : outputs) {
handleOutputAdded(output);
}
const QVector<Output *> enabledOutputs = kwinApp()->platform()->enabledOutputs();
for (Output *output : enabledOutputs) {
handleOutputEnabled(output);
if (output->isEnabled()) {
handleOutputEnabled(output);
}
}
}

View file

@ -209,9 +209,11 @@ void Workspace::init()
connect(platform, &Platform::outputEnabled, this, &Workspace::slotOutputEnabled);
connect(platform, &Platform::outputDisabled, this, &Workspace::slotOutputDisabled);
const QVector<Output *> outputs = platform->enabledOutputs();
const QVector<Output *> outputs = platform->outputs();
for (Output *output : outputs) {
slotOutputEnabled(output);
if (output->isEnabled()) {
slotOutputEnabled(output);
}
}
Screens *screens = Screens::self();
@ -1572,7 +1574,7 @@ QString Workspace::supportInformation() const
} else {
support.append(QStringLiteral(" no\n"));
}
const QVector<Output *> outputs = kwinApp()->platform()->enabledOutputs();
const QVector<Output *> outputs = kwinApp()->platform()->outputs();
support.append(QStringLiteral("Number of Screens: %1\n\n").arg(outputs.count()));
for (int i = 0; i < outputs.count(); ++i) {
const auto output = outputs[i];
@ -1580,28 +1582,31 @@ QString Workspace::supportInformation() const
support.append(QStringLiteral("Screen %1:\n").arg(i));
support.append(QStringLiteral("---------\n"));
support.append(QStringLiteral("Name: %1\n").arg(output->name()));
support.append(QStringLiteral("Geometry: %1,%2,%3x%4\n")
.arg(geo.x())
.arg(geo.y())
.arg(geo.width())
.arg(geo.height()));
support.append(QStringLiteral("Scale: %1\n").arg(output->scale()));
support.append(QStringLiteral("Refresh Rate: %1\n").arg(output->refreshRate()));
QString vrr = QStringLiteral("incapable");
if (output->capabilities() & Output::Capability::Vrr) {
switch (output->vrrPolicy()) {
case RenderLoop::VrrPolicy::Never:
vrr = QStringLiteral("never");
break;
case RenderLoop::VrrPolicy::Always:
vrr = QStringLiteral("always");
break;
case RenderLoop::VrrPolicy::Automatic:
vrr = QStringLiteral("automatic");
break;
support.append(QStringLiteral("Enabled: %1\n").arg(output->isEnabled()));
if (output->isEnabled()) {
support.append(QStringLiteral("Geometry: %1,%2,%3x%4\n")
.arg(geo.x())
.arg(geo.y())
.arg(geo.width())
.arg(geo.height()));
support.append(QStringLiteral("Scale: %1\n").arg(output->scale()));
support.append(QStringLiteral("Refresh Rate: %1\n").arg(output->refreshRate()));
QString vrr = QStringLiteral("incapable");
if (output->capabilities() & Output::Capability::Vrr) {
switch (output->vrrPolicy()) {
case RenderLoop::VrrPolicy::Never:
vrr = QStringLiteral("never");
break;
case RenderLoop::VrrPolicy::Always:
vrr = QStringLiteral("always");
break;
case RenderLoop::VrrPolicy::Automatic:
vrr = QStringLiteral("automatic");
break;
}
}
support.append(QStringLiteral("Adaptive Sync: %1\n").arg(vrr));
}
support.append(QStringLiteral("Adaptive Sync: %1\n").arg(vrr));
}
support.append(QStringLiteral("\nCompositing\n"));
support.append(QStringLiteral("===========\n"));