commit: 45346dc6570f2d6a5032046424fa4abedad040e5 Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Tue Feb 25 22:49:35 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Tue Feb 25 22:49:35 2025 +0000 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=45346dc6
kde-plasma/kwin: fix hang on startup Thanks to FireBurn and josef64 for reporting & testing. Signed-off-by: Sam James <sam <AT> gentoo.org> .../kwin/files/kwin-6.3.2-revert-fix-hang.patch | 307 +++++++++++++++++++++ .../{kwin-6.3.2.ebuild => kwin-6.3.2-r1.ebuild} | 4 + 2 files changed, 311 insertions(+) diff --git a/kde-plasma/kwin/files/kwin-6.3.2-revert-fix-hang.patch b/kde-plasma/kwin/files/kwin-6.3.2-revert-fix-hang.patch new file mode 100644 index 000000000000..9b68efb94bec --- /dev/null +++ b/kde-plasma/kwin/files/kwin-6.3.2-revert-fix-hang.patch @@ -0,0 +1,307 @@ +https://invent.kde.org/plasma/kwin/-/commit/544f3d1ae355d72cab0f28df5533b67085f85e88 + +From 544f3d1ae355d72cab0f28df5533b67085f85e88 Mon Sep 17 00:00:00 2001 +From: Xaver Hugl <xaver.h...@gmail.com> +Date: Tue, 25 Feb 2025 22:49:06 +0100 +Subject: [PATCH] Revert "workspace: better deal with having more outputs than + the GPU can drive" + +This reverts commit a23949582f05c1db7c9bb3bf7fd0292b7120045d. For some systems it caused +an infinite loop on startup +--- a/src/backends/drm/drm_backend.cpp ++++ b/src/backends/drm/drm_backend.cpp +@@ -367,7 +367,7 @@ size_t DrmBackend::gpuCount() const + return m_gpus.size(); + } + +-OutputConfigurationError DrmBackend::applyOutputChanges(const OutputConfiguration &config) ++bool DrmBackend::applyOutputChanges(const OutputConfiguration &config) + { + QList<DrmOutput *> toBeEnabled; + QList<DrmOutput *> toBeDisabled; +@@ -386,20 +386,14 @@ OutputConfigurationError DrmBackend::applyOutputChanges(const OutputConfiguratio + } + } + } +- const auto error = gpu->testPendingConfiguration(); +- if (error != DrmPipeline::Error::None) { ++ if (gpu->testPendingConfiguration() != DrmPipeline::Error::None) { + for (const auto &output : std::as_const(toBeEnabled)) { + output->revertQueuedChanges(); + } + for (const auto &output : std::as_const(toBeDisabled)) { + output->revertQueuedChanges(); + } +- if (error == DrmPipeline::Error::NotEnoughCrtcs) { +- // TODO make this more specific, this is per GPU! +- return OutputConfigurationError::TooManyEnabledOutputs; +- } else { +- return OutputConfigurationError::Unknown; +- } ++ return false; + } + } + // first, apply changes to drm outputs. +@@ -418,7 +412,7 @@ OutputConfigurationError DrmBackend::applyOutputChanges(const OutputConfiguratio + for (const auto &output : std::as_const(m_virtualOutputs)) { + output->applyChanges(config); + } +- return OutputConfigurationError::None; ++ return true; + } + + void DrmBackend::setRenderBackend(DrmRenderBackend *backend) +--- a/src/backends/drm/drm_backend.h ++++ b/src/backends/drm/drm_backend.h +@@ -73,7 +73,7 @@ Q_SIGNALS: + void gpuRemoved(DrmGpu *gpu); + + protected: +- OutputConfigurationError applyOutputChanges(const OutputConfiguration &config) override; ++ bool applyOutputChanges(const OutputConfiguration &config) override; + + private: + friend class DrmGpu; +--- a/src/backends/drm/drm_gpu.cpp ++++ b/src/backends/drm/drm_gpu.cpp +@@ -352,7 +352,7 @@ DrmPipeline::Error DrmGpu::checkCrtcAssignment(QList<DrmConnector *> connectors, + } + if (!connectors.empty()) { + // we have no crtcs left to drive the remaining connectors +- return DrmPipeline::Error::NotEnoughCrtcs; ++ return DrmPipeline::Error::InvalidArguments; + } + return testPipelines(); + } +@@ -442,10 +442,6 @@ DrmPipeline::Error DrmGpu::testPendingConfiguration() + output->cursorLayer()->setEnabled(false); + } + } +- if (connectors.size() > crtcs.size()) { +- // this can't work, we can return early +- return DrmPipeline::Error::NotEnoughCrtcs; +- } + return checkCrtcAssignment(connectors, crtcs); + } + +--- a/src/backends/drm/drm_pipeline.h ++++ b/src/backends/drm/drm_pipeline.h +@@ -48,7 +48,6 @@ public: + NoPermission, + FramePending, + TestBufferFailed, +- NotEnoughCrtcs, + Unknown, + }; + Q_ENUM(Error) +--- a/src/core/outputbackend.cpp ++++ b/src/core/outputbackend.cpp +@@ -43,7 +43,7 @@ std::unique_ptr<QPainterBackend> OutputBackend::createQPainterBackend() + return nullptr; + } + +-OutputConfigurationError OutputBackend::applyOutputChanges(const OutputConfiguration &config) ++bool OutputBackend::applyOutputChanges(const OutputConfiguration &config) + { + const auto availableOutputs = outputs(); + QList<Output *> toBeEnabledOutputs; +@@ -63,7 +63,7 @@ OutputConfigurationError OutputBackend::applyOutputChanges(const OutputConfigura + for (const auto &output : toBeDisabledOutputs) { + output->applyChanges(config); + } +- return OutputConfigurationError::None; ++ return true; + } + + Output *OutputBackend::findOutput(const QString &name) const +--- a/src/core/outputbackend.h ++++ b/src/core/outputbackend.h +@@ -92,7 +92,7 @@ public: + /** + * Applies the output changes. Default implementation only sets values common between platforms + */ +- virtual OutputConfigurationError applyOutputChanges(const OutputConfiguration &config); ++ virtual bool applyOutputChanges(const OutputConfiguration &config); + + virtual Session *session() const; + +--- a/src/effect/globals.h ++++ b/src/effect/globals.h +@@ -451,12 +451,6 @@ enum WindowTypeMask { + }; + Q_DECLARE_FLAGS(WindowTypes, WindowTypeMask) + +-enum class OutputConfigurationError { +- None, +- Unknown, +- TooManyEnabledOutputs, +-}; +- + } // namespace + + Q_DECLARE_METATYPE(std::chrono::nanoseconds) +--- a/src/wayland/outputmanagement_v2.cpp ++++ b/src/wayland/outputmanagement_v2.cpp +@@ -487,15 +487,11 @@ void OutputConfigurationV2Interface::kde_output_configuration_v2_apply(Resource + return pair.second->handle(); + }); + } +- switch (workspace()->applyOutputConfiguration(config, sortedOrder)) { +- case OutputConfigurationError::None: ++ if (workspace()->applyOutputConfiguration(config, sortedOrder)) { + send_applied(); +- break; +- case OutputConfigurationError::Unknown: +- case OutputConfigurationError::TooManyEnabledOutputs: ++ } else { + // TODO provide a more accurate error reason once the driver actually gives us anything + sendFailure(resource, i18n("The driver rejected the output configuration")); +- break; + } + } + +--- a/src/workspace.cpp ++++ b/src/workspace.cpp +@@ -496,11 +496,10 @@ Workspace::~Workspace() + _self = nullptr; + } + +-OutputConfigurationError Workspace::applyOutputConfiguration(const OutputConfiguration &config, const std::optional<QList<Output *>> &outputOrder) ++bool Workspace::applyOutputConfiguration(const OutputConfiguration &config, const std::optional<QList<Output *>> &outputOrder) + { +- auto error = kwinApp()->outputBackend()->applyOutputChanges(config); +- if (error != OutputConfigurationError::None) { +- return error; ++ if (!kwinApp()->outputBackend()->applyOutputChanges(config)) { ++ return false; + } + updateOutputs(outputOrder); + m_outputConfigStore->storeConfig(kwinApp()->outputBackend()->outputs(), m_lidSwitchTracker->isLidClosed(), config, m_outputOrder); +@@ -523,7 +522,7 @@ OutputConfigurationError Workspace::applyOutputConfiguration(const OutputConfigu + output->renderLoop()->scheduleRepaint(); + } + +- return OutputConfigurationError::None; ++ return true; + } + + void Workspace::updateOutputConfiguration() +@@ -540,12 +539,6 @@ void Workspace::updateOutputConfiguration() + return; + } + +- assignBrightnessDevices(); +- +- const bool alreadyHaveEnabledOutputs = std::ranges::any_of(outputs, [](Output *o) { +- return o->isEnabled(); +- }); +- + // Update the output order to a fallback list, to avoid dangling pointers + const auto setFallbackOutputOrder = [this, &outputs]() { + auto newOrder = outputs; +@@ -559,62 +552,40 @@ void Workspace::updateOutputConfiguration() + setOutputOrder(newOrder); + }; + +- QList<Output *> toEnable = outputs; +- OutputConfigurationError error = OutputConfigurationError::None; +- do { +- auto opt = m_outputConfigStore->queryConfig(toEnable, m_lidSwitchTracker->isLidClosed(), m_orientationSensor->reading(), kwinApp()->tabletModeManager()->effectiveTabletMode()); +- if (!opt) { +- return; +- } +- auto &[cfg, order, type] = *opt; ++ auto opt = m_outputConfigStore->queryConfig(outputs, m_lidSwitchTracker->isLidClosed(), m_orientationSensor->reading(), kwinApp()->tabletModeManager()->effectiveTabletMode()); ++ if (!opt) { ++ return; ++ } ++ auto &[cfg, order, type] = *opt; + +- for (const auto &output : outputs) { +- if (!toEnable.contains(output)) { +- cfg.changeSet(output)->enabled = false; +- } +- } +- for (Output *output : std::as_const(toEnable)) { +- const auto changeset = cfg.changeSet(output); +- if (output->brightnessDevice() && changeset->allowSdrSoftwareBrightness.value_or(true)) { +- changeset->allowSdrSoftwareBrightness = false; +- changeset->brightness = output->brightnessDevice()->observedBrightness(); +- } ++ assignBrightnessDevices(); ++ for (Output *output : outputs) { ++ const auto changeset = cfg.changeSet(output); ++ if (output->brightnessDevice() && changeset->allowSdrSoftwareBrightness.value_or(true)) { ++ changeset->allowSdrSoftwareBrightness = false; ++ changeset->brightness = output->brightnessDevice()->observedBrightness(); + } ++ } + +- error = applyOutputConfiguration(cfg, order); +- switch (error) { +- case OutputConfigurationError::None: +- setOutputOrder(order); +- if (type == OutputConfigurationStore::ConfigType::Generated) { +- const bool hasInternal = std::any_of(outputs.begin(), outputs.end(), [](Output *o) { +- return o->isInternal(); +- }); +- if (hasInternal && outputs.size() == 2) { +- // show the OSD with output configuration presets +- QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kscreen.osdService"), +- QStringLiteral("/org/kde/kscreen/osdService"), +- QStringLiteral("org.kde.kscreen.osdService"), +- QStringLiteral("showActionSelector")); +- QDBusConnection::sessionBus().asyncCall(message); +- } +- } +- return; +- case OutputConfigurationError::Unknown: +- qCWarning(KWIN_CORE) << "Applying output config failed!"; +- setFallbackOutputOrder(); +- return; +- case OutputConfigurationError::TooManyEnabledOutputs: +- if (alreadyHaveEnabledOutputs) { +- // just keeping the old output configuration is preferable +- break; +- } +- toEnable.removeLast(); +- break; ++ if (!applyOutputConfiguration(cfg, order)) { ++ qCWarning(KWIN_CORE) << "Applying output config failed!"; ++ setFallbackOutputOrder(); ++ return; ++ } ++ setOutputOrder(order); ++ if (type == OutputConfigurationStore::ConfigType::Generated) { ++ const bool hasInternal = std::any_of(outputs.begin(), outputs.end(), [](Output *o) { ++ return o->isInternal(); ++ }); ++ if (hasInternal && outputs.size() == 2) { ++ // show the OSD with output configuration presets ++ QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kscreen.osdService"), ++ QStringLiteral("/org/kde/kscreen/osdService"), ++ QStringLiteral("org.kde.kscreen.osdService"), ++ QStringLiteral("showActionSelector")); ++ QDBusConnection::sessionBus().asyncCall(message); + } +- } while (error == OutputConfigurationError::TooManyEnabledOutputs && !toEnable.isEmpty()); +- +- qCCritical(KWIN_CORE, "Applying output configuration failed!"); +- setFallbackOutputOrder(); ++ } + } + + void Workspace::setupWindowConnections(Window *window) +--- a/src/workspace.h ++++ b/src/workspace.h +@@ -466,7 +466,7 @@ public: + * Apply the requested output configuration. Note that you must use this function + * instead of Platform::applyOutputChanges(). + */ +- OutputConfigurationError applyOutputConfiguration(const OutputConfiguration &config, const std::optional<QList<Output *>> &outputOrder = std::nullopt); ++ bool applyOutputConfiguration(const OutputConfiguration &config, const std::optional<QList<Output *>> &outputOrder = std::nullopt); + + public Q_SLOTS: + void performWindowOperation(KWin::Window *window, Options::WindowOperation op); +-- +GitLab diff --git a/kde-plasma/kwin/kwin-6.3.2.ebuild b/kde-plasma/kwin/kwin-6.3.2-r1.ebuild similarity index 98% rename from kde-plasma/kwin/kwin-6.3.2.ebuild rename to kde-plasma/kwin/kwin-6.3.2-r1.ebuild index ad356a50bab6..9d406dfe2a82 100644 --- a/kde-plasma/kwin/kwin-6.3.2.ebuild +++ b/kde-plasma/kwin/kwin-6.3.2-r1.ebuild @@ -115,6 +115,10 @@ BDEPEND=" # -m 0755 to avoid suid with USE="-filecaps" FILECAPS=( -m 0755 cap_sys_nice=ep usr/bin/kwin_wayland ) +PATCHES=( + "${FILESDIR}"/${P}-revert-fix-hang.patch +) + src_prepare() { ecm_src_prepare