diff -pruN 4:6.3.4-1/.gitlab-ci.yml 4:6.4.5-0ubuntu2/.gitlab-ci.yml
--- 4:6.3.4-1/.gitlab-ci.yml	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/.gitlab-ci.yml	2025-09-09 08:27:15.000000000 +0000
@@ -6,3 +6,6 @@ include:
     file:
       - /gitlab-templates/linux-qt6.yml
       - /gitlab-templates/freebsd-qt6.yml
+      - /gitlab-templates/xml-lint.yml
+      - /gitlab-templates/yaml-lint.yml
+      - /gitlab-templates/linux-qt6-next.yml
diff -pruN 4:6.3.4-1/.kde-ci.yml 4:6.4.5-0ubuntu2/.kde-ci.yml
--- 4:6.3.4-1/.kde-ci.yml	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/.kde-ci.yml	2025-09-09 08:27:15.000000000 +0000
@@ -2,8 +2,8 @@
 # SPDX-License-Identifier: CC0-1.0
 
 Dependencies:
-- 'on': ['@all']
-  'require':
+ - 'on': ['@all']
+   'require':
     'frameworks/extra-cmake-modules': '@latest-kf6'
     'libraries/plasma-wayland-protocols': '@latest-kf6'
     'third-party/wayland': '@latest'
diff -pruN 4:6.3.4-1/CMakeLists.txt 4:6.4.5-0ubuntu2/CMakeLists.txt
--- 4:6.3.4-1/CMakeLists.txt	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/CMakeLists.txt	2025-09-09 08:27:15.000000000 +0000
@@ -1,13 +1,13 @@
 cmake_minimum_required(VERSION 3.16)
 
 project(libkscreen)
-set(PROJECT_VERSION "6.3.4")
+set(PROJECT_VERSION "6.4.5")
 
-set(QT_MIN_VERSION "6.7.0")
-set(KF6_MIN_VERSION "6.10.0")
+set(QT_MIN_VERSION "6.8.0")
+set(KF6_MIN_VERSION "6.14.0")
 set(KDE_COMPILERSETTINGS_LEVEL "5.82")
 
-set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD 23)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
 find_package(ECM ${KF6_MIN_VERSION} REQUIRED NO_MODULE)
@@ -30,8 +30,12 @@ include(KDEGitCommitHooks)
 include(ECMDeprecationSettings)
 
 find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED Core DBus Gui Test WaylandClient)
-find_package(WaylandScanner)
 
+if (Qt6Gui_VERSION VERSION_GREATER_EQUAL "6.10.0")
+    find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE)
+endif()
+
+find_package(WaylandScanner)
 
 find_package(PlasmaWaylandProtocols 1.16 CONFIG)
 set_package_properties(PlasmaWaylandProtocols PROPERTIES TYPE REQUIRED)
@@ -65,7 +69,7 @@ ecm_setup_version(${PROJECT_VERSION} VAR
                         SOVERSION 8)
 
 ecm_set_disabled_deprecation_versions(QT 5.15.0
-    KF 6.4.0
+    KF 6.12.0
 )
 
 add_subdirectory(src)
diff -pruN 4:6.3.4-1/autotests/testinprocess.cpp 4:6.4.5-0ubuntu2/autotests/testinprocess.cpp
--- 4:6.3.4-1/autotests/testinprocess.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/autotests/testinprocess.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -6,6 +6,7 @@
 
 #include <QCoreApplication>
 #include <QDBusConnectionInterface>
+#include <QElapsedTimer>
 #include <QLoggingCategory>
 #include <QObject>
 #include <QSignalSpy>
diff -pruN 4:6.3.4-1/backends/fake/fake.cpp 4:6.4.5-0ubuntu2/backends/fake/fake.cpp
--- 4:6.3.4-1/backends/fake/fake.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/fake/fake.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -88,12 +88,12 @@ ConfigPtr Fake::config() const
     return mConfig;
 }
 
-QString Fake::setConfig(const ConfigPtr &config)
+QFuture<SetConfigResult> Fake::setConfig(const ConfigPtr &config)
 {
     qCDebug(KSCREEN_FAKE) << "set config" << config->outputs();
     mConfig = config->clone();
     Q_EMIT configChanged(mConfig);
-    return QString();
+    return QtFuture::makeReadyFuture<SetConfigResult>(SetConfigResult());
 }
 
 bool Fake::isValid() const
diff -pruN 4:6.3.4-1/backends/fake/fake.h 4:6.4.5-0ubuntu2/backends/fake/fake.h
--- 4:6.3.4-1/backends/fake/fake.h	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/fake/fake.h	2025-09-09 08:27:15.000000000 +0000
@@ -26,7 +26,7 @@ public:
     QString name() const override;
     QString serviceName() const override;
     KScreen::ConfigPtr config() const override;
-    QString setConfig(const KScreen::ConfigPtr &config) override;
+    QFuture<KScreen::SetConfigResult> setConfig(const KScreen::ConfigPtr &config) override;
     QByteArray edid(int outputId) const override;
     bool isValid() const override;
 
diff -pruN 4:6.3.4-1/backends/fake/parser.cpp 4:6.4.5-0ubuntu2/backends/fake/parser.cpp
--- 4:6.3.4-1/backends/fake/parser.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/fake/parser.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -203,6 +203,11 @@ OutputPtr Parser::outputFromJson(QMap<QS
         map.remove(QStringLiteral("priority"));
     }
 
+    if (map.contains(QStringLiteral("rotation"))) {
+        output->setRotation(static_cast<KScreen::Output::Rotation>(map[QStringLiteral("rotation")].toUInt()));
+        map.remove(QStringLiteral("rotation"));
+    }
+
     // Remove some extra properties that we do not want or need special treatment
     map.remove(QStringLiteral("edid"));
 
diff -pruN 4:6.3.4-1/backends/kwayland/waylandbackend.cpp 4:6.4.5-0ubuntu2/backends/kwayland/waylandbackend.cpp
--- 4:6.3.4-1/backends/kwayland/waylandbackend.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/kwayland/waylandbackend.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -17,13 +17,44 @@
 #include <mode.h>
 #include <output.h>
 
-#include <QEventLoop>
 #include <QProcess>
 #include <QSettings>
 #include <QStandardPaths>
 
 using namespace KScreen;
 
+// This class scopes the connections to the internal config changes signals to the matching request
+// TODO it would be better if WaylandConfig::applyConfig handled the QFuture itself.
+class SetConfigJob : public QObject
+{
+    Q_OBJECT
+public:
+    explicit SetConfigJob(QObject *parent = nullptr)
+        : QObject(parent)
+    {
+        m_pendingResult.start();
+    }
+    void fail(const QString &error)
+    {
+        deleteLater();
+        m_pendingResult.addResult(std::unexpected(error));
+        m_pendingResult.finish();
+    }
+    void finish()
+    {
+        deleteLater();
+        m_pendingResult.addResult(SetConfigResult());
+        m_pendingResult.finish();
+    }
+    QFuture<SetConfigResult> future()
+    {
+        return m_pendingResult.future();
+    }
+
+private:
+    QPromise<SetConfigResult> m_pendingResult;
+};
+
 WaylandBackend::WaylandBackend()
     : KScreen::AbstractBackend()
     , m_internalConfig(new WaylandConfig(this))
@@ -50,25 +81,20 @@ ConfigPtr WaylandBackend::config() const
     return m_internalConfig->currentConfig();
 }
 
-QString WaylandBackend::setConfig(const KScreen::ConfigPtr &newconfig)
+QFuture<SetConfigResult> WaylandBackend::setConfig(const KScreen::ConfigPtr &newconfig)
 {
     if (!newconfig) {
-        return QString();
+        return QtFuture::makeReadyFuture<SetConfigResult>(std::unexpected(QStringLiteral("config is nullptr!")));
     }
-    // wait for KWin reply
-    QEventLoop loop;
 
-    QString ret;
-    connect(m_internalConfig, &WaylandConfig::configChanged, &loop, &QEventLoop::quit);
-    connect(m_internalConfig, &WaylandConfig::configFailed, [&ret](const QString &reason) {
-        ret = reason;
-    });
+    SetConfigJob *job = new SetConfigJob(this);
+    connect(m_internalConfig, &WaylandConfig::configChanged, job, &SetConfigJob::finish);
+    connect(m_internalConfig, &WaylandConfig::configFailed, job, &SetConfigJob::fail);
     if (!m_internalConfig->applyConfig(newconfig)) {
-        return QString();
+        // nothing changed
+        job->finish();
     }
-
-    loop.exec();
-    return ret;
+    return job->future();
 }
 
 QByteArray WaylandBackend::edid(int outputId) const
@@ -86,3 +112,4 @@ bool WaylandBackend::isValid() const
 }
 
 #include "moc_waylandbackend.cpp"
+#include "waylandbackend.moc"
diff -pruN 4:6.3.4-1/backends/kwayland/waylandbackend.h 4:6.4.5-0ubuntu2/backends/kwayland/waylandbackend.h
--- 4:6.3.4-1/backends/kwayland/waylandbackend.h	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/kwayland/waylandbackend.h	2025-09-09 08:27:15.000000000 +0000
@@ -27,7 +27,7 @@ public:
     QString name() const override;
     QString serviceName() const override;
     KScreen::ConfigPtr config() const override;
-    QString setConfig(const KScreen::ConfigPtr &config) override;
+    QFuture<SetConfigResult> setConfig(const KScreen::ConfigPtr &config) override;
     bool isValid() const override;
     QByteArray edid(int outputId) const override;
 
diff -pruN 4:6.3.4-1/backends/kwayland/waylandconfig.cpp 4:6.4.5-0ubuntu2/backends/kwayland/waylandconfig.cpp
--- 4:6.3.4-1/backends/kwayland/waylandconfig.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/kwayland/waylandconfig.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -34,9 +34,9 @@ using namespace std::chrono_literals;
 
 WaylandConfig::WaylandConfig(QObject *parent)
     : QObject(parent)
-    , m_outputManagement(std::make_unique<WaylandOutputManagement>(12))
+    , m_outputManagement(std::make_unique<WaylandOutputManagement>(16))
     , m_registryInitialized(false)
-    , m_blockSignals(true)
+    , m_blockSignals(false)
     , m_kscreenConfig(new Config)
     , m_kscreenPendingConfig(nullptr)
     , m_screen(new WaylandScreen(this))
@@ -113,7 +113,7 @@ void WaylandConfig::setupRegistry()
     auto globalAdded = [](void *data, wl_registry *registry, uint32_t name, const char *interface, uint32_t version) {
         auto self = static_cast<WaylandConfig *>(data);
         if (qstrcmp(interface, WaylandOutputDevice::interface()->name) == 0) {
-            self->addOutput(name, std::min(11u, version));
+            self->addOutput(name, std::min(16u, version));
         }
         if (qstrcmp(interface, WaylandOutputOrder::interface()->name) == 0) {
             self->m_outputOrder = std::make_unique<WaylandOutputOrder>(registry, name, std::min(1u, version));
@@ -145,7 +145,6 @@ void WaylandConfig::setupRegistry()
         Q_UNUSED(callbackData)
         auto self = static_cast<WaylandConfig *>(data);
         self->m_registryInitialized = true;
-        self->unblockSignals();
         self->checkInitialized();
     }};
     auto callback = wl_display_sync(waylandApp->display());
@@ -277,7 +276,7 @@ KScreen::ConfigPtr WaylandConfig::curren
     const auto features = Config::Feature::Writable | Config::Feature::PerOutputScaling | Config::Feature::AutoRotation | Config::Feature::TabletMode
         | Config::Feature::PrimaryDisplay | Config::Feature::XwaylandScales | Config::Feature::SynchronousOutputChanges | Config::Feature::OutputReplication;
     m_kscreenConfig->setSupportedFeatures(features);
-    m_kscreenConfig->setValid(qGuiApp->nativeInterface<QNativeInterface::QWaylandApplication>());
+    m_kscreenConfig->setValid(m_outputManagement->isActive());
 
     KScreen::ScreenPtr screen = m_kscreenConfig->screen();
     m_screen->updateKScreenScreen(screen);
@@ -291,15 +290,14 @@ KScreen::ConfigPtr WaylandConfig::curren
     }
 
     // Add KScreen::Outputs that aren't in the list yet
-    KScreen::OutputList kscreenOutputs = m_kscreenConfig->outputs();
     QMap<OutputPtr, uint32_t> priorities;
     for (const auto &output : m_outputMap) {
         KScreen::OutputPtr kscreenOutput;
         if (m_kscreenConfig->outputs().contains(output->id())) {
             kscreenOutput = m_kscreenConfig->outputs()[output->id()];
-            output->updateKScreenOutput(kscreenOutput);
+            output->updateKScreenOutput(kscreenOutput, m_outputMap);
         } else {
-            kscreenOutput = output->toKScreenOutput();
+            kscreenOutput = output->toKScreenOutput(m_outputMap);
             m_kscreenConfig->addOutput(kscreenOutput);
         }
         priorities[kscreenOutput] = output->index();
@@ -360,7 +358,7 @@ bool WaylandConfig::applyConfig(const KS
     bool changed = false;
 
     for (const auto &output : newConfig->outputs()) {
-        changed |= m_outputMap[output->id()]->setWlConfig(wlConfig, output);
+        changed |= m_outputMap[output->id()]->setWlConfig(wlConfig, output, m_outputMap);
     }
 
     if (!changed) {
diff -pruN 4:6.3.4-1/backends/kwayland/waylandoutputdevice.cpp 4:6.4.5-0ubuntu2/backends/kwayland/waylandoutputdevice.cpp
--- 4:6.3.4-1/backends/kwayland/waylandoutputdevice.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/kwayland/waylandoutputdevice.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -78,11 +78,11 @@ void WaylandOutputDevice::kde_output_dev
     });
 }
 
-OutputPtr WaylandOutputDevice::toKScreenOutput()
+OutputPtr WaylandOutputDevice::toKScreenOutput(const QMap<int, WaylandOutputDevice *> &outputMap)
 {
     OutputPtr output(new Output());
     output->setId(m_id);
-    updateKScreenOutput(output);
+    updateKScreenOutput(output, outputMap);
     return output;
 }
 
@@ -164,7 +164,7 @@ void KScreen::WaylandOutputDevice::updat
     output->setModes(modeList);
 }
 
-void WaylandOutputDevice::updateKScreenOutput(OutputPtr &output)
+void WaylandOutputDevice::updateKScreenOutput(OutputPtr &output, const QMap<int, WaylandOutputDevice *> &outputMap)
 {
     // Initialize primary output
     output->setId(m_id);
@@ -204,6 +204,23 @@ void WaylandOutputDevice::updateKScreenO
     output->setBrightness(m_brightness / 10'000.0);
     output->setColorPowerPreference(static_cast<Output::ColorPowerTradeoff>(m_colorPowerPreference));
     output->setDimming(m_dimming / 10'000.0);
+    output->setUuid(m_uuid);
+    int replicationSourceId = 0;
+    for (auto it = outputMap.begin(); it != outputMap.end(); it++) {
+        if (it.value()->uuid() == m_replicationSource) {
+            replicationSourceId = it.key();
+            break;
+        }
+    }
+    output->setReplicationSource(replicationSourceId);
+    output->setDdcCiAllowed(m_ddcCiAllowed);
+    output->setMaxBitsPerColor(m_maxBpc);
+    output->setAutomaticMaxBitsPerColorLimit(m_autoMaxBpcLimit);
+    output->setBitsPerColorRange(Output::BpcRange{
+        .min = bpcRange.min,
+        .max = bpcRange.max,
+    });
+    output->setEdrPolicy(static_cast<Output::EdrPolicy>(m_edrPolicy));
 
     updateKScreenModes(output);
 }
@@ -223,7 +240,7 @@ WaylandOutputDeviceMode *WaylandOutputDe
     return nullptr;
 }
 
-bool WaylandOutputDevice::setWlConfig(WaylandOutputConfiguration *wlConfig, const KScreen::OutputPtr &output)
+bool WaylandOutputDevice::setWlConfig(WaylandOutputConfiguration *wlConfig, const KScreen::OutputPtr &output, const QMap<int, WaylandOutputDevice *> &outputMap)
 {
     bool changed = false;
 
@@ -333,6 +350,26 @@ bool WaylandOutputDevice::setWlConfig(Wa
         wlConfig->set_dimming(object(), std::round(output->dimming() * 10'000));
         changed = true;
     }
+    if (version >= KDE_OUTPUT_CONFIGURATION_V2_SET_REPLICATION_SOURCE_SINCE_VERSION) {
+        const auto source = outputMap[output->replicationSource()];
+        if (source) {
+            wlConfig->set_replication_source(object(), source->uuid());
+        } else {
+            wlConfig->set_replication_source(object(), QString());
+        }
+        changed = true;
+    }
+    if (version >= KDE_OUTPUT_CONFIGURATION_V2_SET_DDC_CI_ALLOWED_SINCE_VERSION && m_ddcCiAllowed != output->ddcCiAllowed()) {
+        wlConfig->set_ddc_ci_allowed(object(), output->ddcCiAllowed() ? 1 : 0);
+    }
+    if (version >= KDE_OUTPUT_CONFIGURATION_V2_SET_MAX_BITS_PER_COLOR_SINCE_VERSION && m_maxBpc != output->maxBitsPerColor()) {
+        wlConfig->set_max_bits_per_color(object(), output->maxBitsPerColor());
+        changed = true;
+    }
+    if (version >= KDE_OUTPUT_CONFIGURATION_V2_SET_EDR_POLICY_SINCE_VERSION && m_edrPolicy != uint32_t(output->edrPolicy())) {
+        wlConfig->set_edr_policy(object(), uint32_t(output->edrPolicy()));
+        changed = true;
+    }
 
     return changed;
 }
@@ -501,6 +538,39 @@ void WaylandOutputDevice::kde_output_dev
     m_dimming = dimming;
 }
 
+void WaylandOutputDevice::kde_output_device_v2_replication_source(const QString &source)
+{
+    m_replicationSource = source;
+}
+
+void WaylandOutputDevice::kde_output_device_v2_ddc_ci_allowed(uint32_t allowed)
+{
+    m_ddcCiAllowed = allowed == 1;
+}
+
+void WaylandOutputDevice::kde_output_device_v2_max_bits_per_color(uint32_t max_bpc)
+{
+    m_maxBpc = max_bpc;
+}
+
+void WaylandOutputDevice::kde_output_device_v2_max_bits_per_color_range(uint32_t min_value, uint32_t max_value)
+{
+    bpcRange = {
+        .min = min_value,
+        .max = max_value,
+    };
+}
+
+void WaylandOutputDevice::kde_output_device_v2_automatic_max_bits_per_color_limit(uint32_t value)
+{
+    m_autoMaxBpcLimit = value;
+}
+
+void WaylandOutputDevice::kde_output_device_v2_edr_policy(uint32_t policy)
+{
+    m_edrPolicy = policy;
+}
+
 QByteArray WaylandOutputDevice::edid() const
 {
     return m_edid;
diff -pruN 4:6.3.4-1/backends/kwayland/waylandoutputdevice.h 4:6.4.5-0ubuntu2/backends/kwayland/waylandoutputdevice.h
--- 4:6.3.4-1/backends/kwayland/waylandoutputdevice.h	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/kwayland/waylandoutputdevice.h	2025-09-09 08:27:15.000000000 +0000
@@ -44,13 +44,13 @@ public:
     uint32_t capabilities() const;
     uint32_t rgbRange() const;
 
-    OutputPtr toKScreenOutput();
-    void updateKScreenOutput(OutputPtr &output);
+    OutputPtr toKScreenOutput(const QMap<int, WaylandOutputDevice *> &outputMap);
+    void updateKScreenOutput(OutputPtr &output, const QMap<int, WaylandOutputDevice *> &outputMap);
     void updateKScreenModes(OutputPtr &output);
 
     void setIndex(uint32_t priority);
     uint32_t index() const;
-    bool setWlConfig(WaylandOutputConfiguration *wlConfig, const KScreen::OutputPtr &output);
+    bool setWlConfig(WaylandOutputConfiguration *wlConfig, const KScreen::OutputPtr &output, const QMap<int, WaylandOutputDevice *> &outputMap);
 
     QString modeId() const;
     QString uuid() const
@@ -96,6 +96,12 @@ protected:
     void kde_output_device_v2_brightness(uint32_t brightness) override;
     void kde_output_device_v2_color_power_tradeoff(uint32_t preference) override;
     void kde_output_device_v2_dimming(uint32_t dimming) override;
+    void kde_output_device_v2_replication_source(const QString &source) override;
+    void kde_output_device_v2_ddc_ci_allowed(uint32_t allowed) override;
+    void kde_output_device_v2_max_bits_per_color(uint32_t max_bpc) override;
+    void kde_output_device_v2_max_bits_per_color_range(uint32_t min_value, uint32_t max_value) override;
+    void kde_output_device_v2_automatic_max_bits_per_color_limit(uint32_t max_bpc_limit) override;
+    void kde_output_device_v2_edr_policy(uint32_t policy) override;
 
 private:
     QString modeName(const WaylandOutputDeviceMode *m) const;
@@ -136,9 +142,18 @@ private:
     std::optional<double> m_minBrightnessOverride;
     double m_sdrGamutWideness = 0;
     uint32_t m_colorProfileSource = color_profile_source_sRGB;
+    bool m_ddcCiAllowed = true;
     uint32_t m_brightness = 10'000;
     color_power_tradeoff m_colorPowerPreference = color_power_tradeoff_efficiency;
     uint32_t m_dimming = 10'000;
+    QString m_replicationSource;
+    uint32_t m_maxBpc = 0;
+    uint32_t m_autoMaxBpcLimit = 0;
+    struct {
+        uint32_t min = 0;
+        uint32_t max = 0;
+    } bpcRange;
+    uint32_t m_edrPolicy = edr_policy_always;
 };
 
 }
diff -pruN 4:6.3.4-1/backends/kwayland/waylandoutputmanagement.h 4:6.4.5-0ubuntu2/backends/kwayland/waylandoutputmanagement.h
--- 4:6.3.4-1/backends/kwayland/waylandoutputmanagement.h	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/kwayland/waylandoutputmanagement.h	2025-09-09 08:27:15.000000000 +0000
@@ -27,7 +27,7 @@ public:
 
 Q_SIGNALS:
     void applied();
-    void failed(QString errorMessage);
+    void failed(const QString &errorMessage);
 
 protected:
     void kde_output_configuration_v2_applied() override;
diff -pruN 4:6.3.4-1/backends/qscreen/qscreenbackend.cpp 4:6.4.5-0ubuntu2/backends/qscreen/qscreenbackend.cpp
--- 4:6.3.4-1/backends/qscreen/qscreenbackend.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/qscreen/qscreenbackend.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -46,16 +46,11 @@ ConfigPtr QScreenBackend::config() const
     return s_internalConfig->toKScreenConfig();
 }
 
-QString QScreenBackend::setConfig(const ConfigPtr &config)
+QFuture<SetConfigResult> QScreenBackend::setConfig(const ConfigPtr &config)
 {
-    if (!config) {
-        return QString();
-    }
-
-    qWarning() << "The QScreen backend for libkscreen is read-only,";
-    qWarning() << "setting a configuration is not supported.";
-    qWarning() << "You can force another backend using the KSCREEN_BACKEND env var.";
-    return QString();
+    return QtFuture::makeReadyFuture<SetConfigResult>(std::unexpected(
+        QStringLiteral("The QScreen backend for libkscreen is read-only, setting a configuration is not supported. You can force another backend using the "
+                       "KSCREEN_BACKEND env var")));
 }
 
 bool QScreenBackend::isValid() const
diff -pruN 4:6.3.4-1/backends/qscreen/qscreenbackend.h 4:6.4.5-0ubuntu2/backends/qscreen/qscreenbackend.h
--- 4:6.3.4-1/backends/qscreen/qscreenbackend.h	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/qscreen/qscreenbackend.h	2025-09-09 08:27:15.000000000 +0000
@@ -28,7 +28,7 @@ public:
     QString name() const override;
     QString serviceName() const override;
     KScreen::ConfigPtr config() const override;
-    QString setConfig(const KScreen::ConfigPtr &config) override;
+    QFuture<KScreen::SetConfigResult> setConfig(const KScreen::ConfigPtr &config) override;
     bool isValid() const override;
 
 private:
diff -pruN 4:6.3.4-1/backends/xcbeventlistener.cpp 4:6.4.5-0ubuntu2/backends/xcbeventlistener.cpp
--- 4:6.3.4-1/backends/xcbeventlistener.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/xcbeventlistener.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -187,7 +187,8 @@ void XCBEventListener::handleXRandRNotif
         qCDebug(KSCREEN_XCB_HELPER) << "RRNotify_OutputProperty (ignored)";
         qCDebug(KSCREEN_XCB_HELPER) << "\tTimestamp: " << property.timestamp;
         qCDebug(KSCREEN_XCB_HELPER) << "\tOutput: " << property.output;
-        qCDebug(KSCREEN_XCB_HELPER) << "\tProperty: " << QByteArray::fromRawData(xcb_get_atom_name_name(reply.data()), xcb_get_atom_name_name_length(reply.data()));
+        qCDebug(KSCREEN_XCB_HELPER) << "\tProperty: "
+                                    << QByteArray::fromRawData(xcb_get_atom_name_name(reply.data()), xcb_get_atom_name_name_length(reply.data()));
         qCDebug(KSCREEN_XCB_HELPER) << "\tState (newValue, Deleted): " << property.status;
     }
 }
diff -pruN 4:6.3.4-1/backends/xcbwrapper.h 4:6.4.5-0ubuntu2/backends/xcbwrapper.h
--- 4:6.3.4-1/backends/xcbwrapper.h	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/xcbwrapper.h	2025-09-09 08:27:15.000000000 +0000
@@ -21,7 +21,8 @@
 
 namespace XCB
 {
-template<typename T> using ScopedPointer = QScopedPointer<T, QScopedPointerPodDeleter>;
+template<typename T>
+using ScopedPointer = QScopedPointer<T, QScopedPointerPodDeleter>;
 
 xcb_connection_t *connection();
 void closeConnection();
@@ -44,7 +45,7 @@ public:
         m_cookie.sequence = 0;
     }
 
-    explicit Wrapper(const RequestFuncArgs &... args)
+    explicit Wrapper(const RequestFuncArgs &...args)
         : m_retrieved(false)
         , m_cookie(requestFunc(connection(), args...))
         , m_window(requestWindow<RequestFuncArgs...>(args...))
@@ -167,7 +168,8 @@ private:
         }
     }
 
-    template<typename... Args> constexpr xcb_window_t requestWindow(const Args &... args) const
+    template<typename... Args>
+    constexpr xcb_window_t requestWindow(const Args &...args) const
     {
         return std::is_same<typename std::tuple_element<0, std::tuple<Args...>>::type, xcb_window_t>::value ? std::get<0>(std::tuple<Args...>(args...))
                                                                                                             : static_cast<xcb_window_t>(XCB_WINDOW_NONE);
diff -pruN 4:6.3.4-1/backends/xrandr/xrandr.cpp 4:6.4.5-0ubuntu2/backends/xrandr/xrandr.cpp
--- 4:6.3.4-1/backends/xrandr/xrandr.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/xrandr/xrandr.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -176,16 +176,16 @@ ConfigPtr XRandR::config() const
     return s_internalConfig->toKScreenConfig();
 }
 
-QString XRandR::setConfig(const ConfigPtr &config)
+QFuture<SetConfigResult> XRandR::setConfig(const ConfigPtr &config)
 {
     if (!config) {
-        return QString();
+        return QtFuture::makeReadyFuture<SetConfigResult>(std::unexpected(QStringLiteral("config is nullptr!")));
     }
 
     qCDebug(KSCREEN_XRANDR) << "XRandR::setConfig";
     s_internalConfig->applyKScreenConfig(config);
     qCDebug(KSCREEN_XRANDR) << "XRandR::setConfig done!";
-    return QString();
+    return QtFuture::makeReadyFuture(SetConfigResult());
 }
 
 QByteArray XRandR::edid(int outputId) const
diff -pruN 4:6.3.4-1/backends/xrandr/xrandr.h 4:6.4.5-0ubuntu2/backends/xrandr/xrandr.h
--- 4:6.3.4-1/backends/xrandr/xrandr.h	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/xrandr/xrandr.h	2025-09-09 08:27:15.000000000 +0000
@@ -32,7 +32,7 @@ public:
     QString name() const override;
     QString serviceName() const override;
     KScreen::ConfigPtr config() const override;
-    QString setConfig(const KScreen::ConfigPtr &config) override;
+    QFuture<KScreen::SetConfigResult> setConfig(const KScreen::ConfigPtr &config) override;
     bool isValid() const override;
     QByteArray edid(int outputId) const override;
 
diff -pruN 4:6.3.4-1/backends/xrandr/xrandroutput.cpp 4:6.4.5-0ubuntu2/backends/xrandr/xrandroutput.cpp
--- 4:6.3.4-1/backends/xrandr/xrandroutput.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/backends/xrandr/xrandroutput.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -20,7 +20,7 @@
 #include <xcb/randr.h>
 #include <xcb/render.h>
 
-#define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t)((d)*65536))
+#define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t)((d) * 65536))
 #define FIXED_TO_DOUBLE(f) ((double)((f) / 65536.0))
 
 xcb_render_fixed_t fOne = DOUBLE_TO_FIXED(1);
diff -pruN 4:6.3.4-1/debian/changelog 4:6.4.5-0ubuntu2/debian/changelog
--- 4:6.3.4-1/debian/changelog	2025-04-02 22:59:10.000000000 +0000
+++ 4:6.4.5-0ubuntu2/debian/changelog	2025-09-16 13:13:37.000000000 +0000
@@ -1,24 +1,56 @@
-libkscreen (4:6.3.4-1) unstable; urgency=medium
+libkscreen (4:6.4.5-0ubuntu2) questing; urgency=medium
 
-  [ Patrick Franz ]
-  * New upstream release (6.3.4).
+  * No-change rebuild for Qt 6.9.2 private ABI.
 
- -- Patrick Franz <deltaone@debian.org>  Thu, 03 Apr 2025 00:59:10 +0200
+ -- Rik Mills <rikmills@kde.org>  Tue, 16 Sep 2025 14:13:37 +0100
 
-libkscreen (4:6.3.2-4) unstable; urgency=medium
+libkscreen (4:6.4.5-0ubuntu1) questing; urgency=medium
 
-  * Team upload.
-  * Limit also the plasma-wayland-protocols build dependency as linux-any,
-    as Wayland bits are available only on Linux.
+  * New upstream release (6.4.5)
 
- -- Pino Toscano <pino@debian.org>  Thu, 20 Mar 2025 06:41:02 +0100
+ -- Rik Mills <rikmills@kde.org>  Tue, 09 Sep 2025 17:02:22 +0100
 
-libkscreen (4:6.3.2-3) unstable; urgency=medium
+libkscreen (4:6.4.4-0ubuntu1) questing; urgency=medium
 
-  * Team upload.
-  * Switch the hwdata recommend to pnp.ids, as libkscreen uses only pnp.ids.
+  * New upstream release (6.4.4)
+  * Update symbols from build logs.
+
+ -- Rik Mills <rikmills@kde.org>  Tue, 12 Aug 2025 17:29:19 +0100
+
+libkscreen (4:6.3.5-0ubuntu1) questing; urgency=medium
+
+  * New upstream release (6.3.5)
+
+ -- Rik Mills <rikmills@kde.org>  Tue, 06 May 2025 21:34:24 +0100
+
+libkscreen (4:6.3.4-0ubuntu1) plucky; urgency=medium
+
+  * New upstream release (6.3.4)
+
+ -- Rik Mills <rikmills@kde.org>  Wed, 02 Apr 2025 08:56:13 +0100
 
- -- Pino Toscano <pino@debian.org>  Fri, 14 Mar 2025 17:25:27 +0100
+libkscreen (4:6.3.3-0ubuntu2) plucky; urgency=medium
+
+  * No-change rebuild for Qt 6.8.3 (LP: #2103945).
+
+ -- Simon Quigley <tsimonq2@ubuntu.com>  Sat, 29 Mar 2025 15:06:23 -0500
+
+libkscreen (4:6.3.3-0ubuntu1) plucky; urgency=medium
+
+  * New upstream release (6.3.3)
+
+ -- Rik Mills <rikmills@kde.org>  Tue, 11 Mar 2025 15:20:23 +0000
+
+libkscreen (4:6.3.2-2ubuntu1) plucky; urgency=medium
+
+  * Merge from Debian unstable. Remaining changes:
+    - Kubuntu Vcs and maintainer fields.
+    - debian/patches/series: Comment out Make-qt6-wayland-optional.patch,
+      as we do not need this in Ubuntu.
+    - libkscreen-bin Breaks/Replaces against libkf5screen-bin for Ubuntu
+      version history. 
+
+ -- Rik Mills <rikmills@kde.org>  Sun, 02 Mar 2025 17:02:47 +0000
 
 libkscreen (4:6.3.2-2) unstable; urgency=medium
 
@@ -38,6 +70,18 @@ libkscreen (4:6.3.2-1) unstable; urgency
 
  -- Aurélien COUDERC <coucouf@debian.org>  Fri, 28 Feb 2025 00:51:47 +0100
 
+libkscreen (4:6.3.2-0ubuntu1) plucky; urgency=medium
+
+  * New upstream release (6.3.2)
+
+ -- Rik Mills <rikmills@kde.org>  Tue, 25 Feb 2025 18:16:31 +0000
+
+libkscreen (4:6.3.1-0ubuntu1) plucky; urgency=medium
+
+  * New upstream release (6.3.1)
+
+ -- Rik Mills <rikmills@kde.org>  Tue, 18 Feb 2025 14:23:32 +0000
+
 libkscreen (4:6.3.0-1) unstable; urgency=medium
 
   [ Aurélien COUDERC ]
@@ -46,6 +90,12 @@ libkscreen (4:6.3.0-1) unstable; urgency
 
  -- Aurélien COUDERC <coucouf@debian.org>  Mon, 10 Feb 2025 14:58:48 +0100
 
+libkscreen (4:6.3.0-0ubuntu1) plucky; urgency=medium
+
+  * New upstream release (6.3.0)
+
+ -- Rik Mills <rikmills@kde.org>  Tue, 11 Feb 2025 12:55:41 +0000
+
 libkscreen (4:6.2.91-1) experimental; urgency=medium
 
   [ Aurélien COUDERC ]
@@ -53,6 +103,18 @@ libkscreen (4:6.2.91-1) experimental; ur
 
  -- Aurélien COUDERC <coucouf@debian.org>  Thu, 23 Jan 2025 23:51:28 +0100
 
+libkscreen (4:6.2.91-0ubuntu2) plucky; urgency=medium
+
+  * No-change rebuild for Qt 6.8.2.
+
+ -- Simon Quigley <tsimonq2@ubuntu.com>  Tue, 04 Feb 2025 14:13:25 -0600
+
+libkscreen (4:6.2.91-0ubuntu1) plucky; urgency=medium
+
+  * New upstream (beta) release (6.2.91)
+
+ -- Rik Mills <rikmills@kde.org>  Thu, 23 Jan 2025 13:42:12 +0000
+
 libkscreen (4:6.2.90-1) experimental; urgency=medium
 
   [ Aurélien COUDERC ]
@@ -63,6 +125,13 @@ libkscreen (4:6.2.90-1) experimental; ur
 
  -- Aurélien COUDERC <coucouf@debian.org>  Sat, 11 Jan 2025 23:21:42 +0100
 
+libkscreen (4:6.2.90-0ubuntu1) plucky; urgency=medium
+
+  * New upstream (beta) release (6.2.90)
+  * Update symbols from build logs.
+
+ -- Rik Mills <rikmills@kde.org>  Sat, 11 Jan 2025 04:21:47 +0000
+
 libkscreen (4:6.2.5-1) unstable; urgency=medium
 
   [ Aurélien COUDERC ]
@@ -71,6 +140,12 @@ libkscreen (4:6.2.5-1) unstable; urgency
 
  -- Aurélien COUDERC <coucouf@debian.org>  Sun, 05 Jan 2025 10:57:27 +0100
 
+libkscreen (4:6.2.5-0ubuntu1) plucky; urgency=medium
+
+  * New upstream release (6.2.5)
+
+ -- Rik Mills <rikmills@kde.org>  Tue, 31 Dec 2024 19:01:25 +0000
+
 libkscreen (4:6.2.4-1) unstable; urgency=medium
 
   [ Aurélien COUDERC ]
@@ -80,6 +155,30 @@ libkscreen (4:6.2.4-1) unstable; urgency
 
  -- Aurélien COUDERC <coucouf@debian.org>  Tue, 03 Dec 2024 16:27:33 +0100
 
+libkscreen (4:6.2.4-0ubuntu4) plucky; urgency=medium
+
+  * Update symbols from build logs.
+
+ -- Simon Quigley <tsimonq2@ubuntu.com>  Thu, 05 Dec 2024 00:42:36 -0600
+
+libkscreen (4:6.2.4-0ubuntu3) plucky; urgency=medium
+
+  * No-change rebuild for Qt 6.8.1.
+
+ -- Simon Quigley <tsimonq2@ubuntu.com>  Wed, 04 Dec 2024 18:59:28 -0600
+
+libkscreen (4:6.2.4-0ubuntu2) plucky; urgency=medium
+
+  * No-change rebuild for Qt 6.8.0.
+
+ -- Simon Quigley <tsimonq2@ubuntu.com>  Wed, 04 Dec 2024 18:59:28 -0600
+
+libkscreen (4:6.2.4-0ubuntu1) plucky; urgency=medium
+
+  * New upstream release (6.2.4)
+
+ -- Rik Mills <rikmills@kde.org>  Tue, 26 Nov 2024 12:14:17 +0000
+
 libkscreen (4:6.2.3-1) unstable; urgency=medium
 
   [ Aurélien COUDERC ]
@@ -88,6 +187,19 @@ libkscreen (4:6.2.3-1) unstable; urgency
 
  -- Aurélien COUDERC <coucouf@debian.org>  Sat, 23 Nov 2024 21:57:26 +0100
 
+libkscreen (4:6.2.3-0ubuntu1) plucky; urgency=medium
+
+  * New upstream release (6.2.0)
+  * debian/patches/series: Comment out Make-qt6-wayland-optional.patch,
+    as we do not need this in Ubuntu.
+  * Bump plasma-wayland-protocols build dep to 1.14
+  * Update symbols from build logs.
+  * New upstream release (6.2.1)
+  * New upstream release (6.2.2)
+  * New upstream release (6.2.3)
+
+ -- Rik Mills <rikmills@kde.org>  Thu, 07 Nov 2024 19:57:26 +0000
+
 libkscreen (4:6.2.1-1) experimental; urgency=medium
 
   [ Aurélien COUDERC ]
@@ -113,6 +225,18 @@ libkscreen (4:6.1.5-1) experimental; urg
 
  -- Aurélien COUDERC <coucouf@debian.org>  Wed, 11 Sep 2024 23:27:42 +0200
 
+libkscreen (4:6.1.5-0ubuntu2) plucky; urgency=medium
+
+  * Rebuild against Qt 6.7.2 private-abi.
+
+ -- Rik Mills <rikmills@kde.org>  Thu, 17 Oct 2024 17:07:15 +0100
+
+libkscreen (4:6.1.5-0ubuntu1) oracular; urgency=medium
+
+  * New upstream release (6.1.5)
+
+ -- Rik Mills <rikmills@kde.org>  Wed, 11 Sep 2024 05:59:51 +0100
+
 libkscreen (4:6.1.4-1) experimental; urgency=medium
 
   [ Aurélien COUDERC ]
@@ -120,6 +244,31 @@ libkscreen (4:6.1.4-1) experimental; urg
 
  -- Aurélien COUDERC <coucouf@debian.org>  Sun, 11 Aug 2024 23:58:19 +0200
 
+libkscreen (4:6.1.4-0ubuntu3) oracular; urgency=medium
+
+  * Fix typo in breaks/replaces.
+
+ -- Rik Mills <rikmills@kde.org>  Mon, 19 Aug 2024 13:00:01 +0100
+
+libkscreen (4:6.1.4-0ubuntu2) oracular; urgency=medium
+
+  * Fix missing replaces version for libkf5screen-bin -> libkscreen-bin.
+
+ -- Rik Mills <rikmills@kde.org>  Mon, 19 Aug 2024 06:24:20 +0100
+
+libkscreen (4:6.1.4-0ubuntu1) oracular; urgency=medium
+
+  * New upstream release (6.1.4)
+  * Breaks replaces conflicting Qt5 binaries.
+
+ -- Rik Mills <rikmills@kde.org>  Tue, 13 Aug 2024 20:06:47 +0100
+
+libkscreen (4:6.1.3-1ubuntu1) UNRELEASED; urgency=medium
+
+  * Update symbols from build logs.
+
+ -- Rik Mills <rikmills@kde.org>  Mon, 29 Jul 2024 12:35:39 +0100
+
 libkscreen (4:6.1.3-1) experimental; urgency=medium
 
   [ Aurélien COUDERC ]
diff -pruN 4:6.3.4-1/debian/control 4:6.4.5-0ubuntu2/debian/control
--- 4:6.3.4-1/debian/control	2025-04-02 19:22:49.000000000 +0000
+++ 4:6.4.5-0ubuntu2/debian/control	2025-09-09 16:02:22.000000000 +0000
@@ -1,15 +1,16 @@
 Source: libkscreen
 Section: libs
 Priority: optional
-Maintainer: Debian Qt/KDE Maintainers <debian-qt-kde@lists.debian.org>
+Maintainer: Kubuntu Developers <kubuntu-devel@lists.ubuntu.com>
+XSBC-Original-Maintainer: Debian Qt/KDE Maintainers <debian-qt-kde@lists.debian.org>
 Uploaders: Aurélien COUDERC <coucouf@debian.org>,
            Patrick Franz <deltaone@debian.org>,
-Build-Depends: debhelper-compat (= 13),
+Build-Depends: cmake (>= 3.16~),
+               debhelper-compat (= 13),
                dh-sequence-kf6,
                dh-sequence-pkgkde-symbolshelper,
-               cmake (>= 3.16~),
                doxygen,
-               extra-cmake-modules (>= 6.10.0~),
+               extra-cmake-modules (>= 6.14.0~),
                libx11-dev,
                libx11-xcb-dev,
                libxcb-dpms0-dev,
@@ -18,23 +19,23 @@ Build-Depends: debhelper-compat (= 13),
                libxkbcommon-dev,
                libxrandr-dev,
                pkgconf,
-               plasma-wayland-protocols (>= 1.16~) [linux-any],
-               qt6-base-dev (>= 6.7.0~),
-               qt6-base-private-dev (>= 6.6.0+dfsg~),
-               qt6-tools-dev (>= 6.6.0~),
-               qt6-wayland-dev (>= 6.7.0~) [linux-any],
+               plasma-wayland-protocols (>= 1.16~),
+               qt6-base-dev (>= 6.8.0~),
+               qt6-base-private-dev (>= 6.8.0+dfsg~),
+               qt6-tools-dev (>= 6.8.0~),
+               qt6-wayland-dev (>= 6.8.0~) [linux-any],
 Standards-Version: 4.7.2
 Homepage: https://invent.kde.org/plasma/libkscreen
-Vcs-Browser: https://salsa.debian.org/qt-kde-team/kde/libkscreen
-Vcs-Git: https://salsa.debian.org/qt-kde-team/kde/libkscreen.git
+Vcs-Browser: https://code.launchpad.net/~kubuntu-packagers/kubuntu-packaging/+git/libkscreen
+Vcs-Git: https://git.launchpad.net/~kubuntu-packagers/kubuntu-packaging/+git/libkscreen
 Rules-Requires-Root: no
 
 Package: libkscreen-bin
 Architecture: any
 Multi-Arch: foreign
 Depends: ${misc:Depends}, ${shlibs:Depends},
-Breaks: libkf5screen-bin, libkf6screen-bin,
-Replaces: libkf5screen-bin, libkf6screen-bin,
+Breaks: libkf5screen-bin (<< 4:5.27.11-0ubuntu3~), libkf6screen-bin,
+Replaces: libkf5screen-bin (<< 4:5.27.11-0ubuntu3~), libkf6screen-bin,
 Description: library for screen management - helpers
  The KDE multiple monitor support is trying be as smart as possible
  adapting the behavior of it to each use case making the configuration
@@ -60,7 +61,7 @@ Section: libdevel
 Architecture: any
 Depends: libkf6screen8 (= ${binary:Version}),
          libkf6screendpms8 (= ${binary:Version}),
-         qt6-base-dev (>= 6.7.0~),
+         qt6-base-dev (>= 6.8.0~),
          ${misc:Depends},
 Recommends: libkscreen-doc (= ${source:Version}),
 Breaks: libkf6screen-dev,
@@ -92,7 +93,7 @@ Multi-Arch: same
 Depends: libkscreen-data (= ${source:Version}),
          ${misc:Depends},
          ${shlibs:Depends},
-Recommends: pnp.ids,
+Recommends: hwdata,
 Description: library for screen management - shared library
  The KDE multiple monitor support is trying be as smart as possible
  adapting the behavior of it to each use case making the configuration
diff -pruN 4:6.3.4-1/debian/libkf6screen8.symbols 4:6.4.5-0ubuntu2/debian/libkf6screen8.symbols
--- 4:6.3.4-1/debian/libkf6screen8.symbols	2025-02-12 00:38:15.000000000 +0000
+++ 4:6.4.5-0ubuntu2/debian/libkf6screen8.symbols	2025-09-09 16:02:22.000000000 +0000
@@ -1,4 +1,4 @@
-# SymbolsHelper-Confirmed: 4:6.2.90 amd64
+# SymbolsHelper-Confirmed: 4:6.3.91 amd64 arm64 armhf ppc64el riscv64 s390x
 libKF6Screen.so.8 libkf6screen8 #MINVER#, libkscreen-bin
 * Build-Depends-Package: libkscreen-dev
  _ZGVZN9QMetaType21registerConverterImplI14QSharedPointerIN7KScreen4ModeEEP7QObjectEEbSt8functionIFbPKvPvEES_S_E10unregister@Base 4:6.1.0
@@ -75,8 +75,8 @@ libKF6Screen.so.8 libkf6screen8 #MINVER#
  _ZN7KScreen16ConfigSerializer13serializeModeERK14QSharedPointerINS_4ModeEE@Base 4:6.1.0
  _ZN7KScreen16ConfigSerializer13serializeSizeERK5QSize@Base 4:6.1.0
  _ZN7KScreen16ConfigSerializer14serializePointERK6QPoint@Base 4:6.1.0
- (optional=templinst)_ZN7KScreen16ConfigSerializer15deserializeListI7QStringEE5QListIT_ERK13QDBusArgument@Base 4:6.1.0
- (optional=templinst)_ZN7KScreen16ConfigSerializer15deserializeListIiEE5QListIT_ERK13QDBusArgument@Base 4:6.1.0
+ (optional=templinst|arch=armhf riscv64)_ZN7KScreen16ConfigSerializer15deserializeListI7QStringEE5QListIT_ERK13QDBusArgument@Base 4:6.1.0
+ (optional=templinst|arch=armhf riscv64)_ZN7KScreen16ConfigSerializer15deserializeListIiEE5QListIT_ERK13QDBusArgument@Base 4:6.1.0
  _ZN7KScreen16ConfigSerializer15deserializeModeERK13QDBusArgument@Base 4:6.1.0
  _ZN7KScreen16ConfigSerializer15deserializeSizeERK13QDBusArgument@Base 4:6.1.0
  _ZN7KScreen16ConfigSerializer15serializeConfigERK14QSharedPointerINS_6ConfigEE@Base 4:6.1.0
@@ -179,10 +179,12 @@ libKF6Screen.so.8 libkf6screen8 #MINVER#
  _ZN7KScreen6Output11setRgbRangeENS0_8RgbRangeE@Base 4:6.1.0
  _ZN7KScreen6Output11setRotationENS0_8RotationE@Base 4:6.1.0
  _ZN7KScreen6Output11sizeChangedEv@Base 4:6.1.0
+ _ZN7KScreen6Output11uuidChangedEv@Base 4:6.3.80
  _ZN7KScreen6Output12modelChangedEv@Base 4:6.2.90
  _ZN7KScreen6Output12modesChangedEv@Base 4:6.1.0
  _ZN7KScreen6Output12scaleChangedEv@Base 4:6.1.0
  _ZN7KScreen6Output12setConnectedEb@Base 4:6.1.0
+ _ZN7KScreen6Output12setEdrPolicyENS0_9EdrPolicyE@Base 4:6.3.91
  _ZN7KScreen6Output12setVrrPolicyENS0_9VrrPolicyE@Base 4:6.1.0
  _ZN7KScreen6Output13clonesChangedEv@Base 4:6.1.0
  _ZN7KScreen6Output13outputChangedEv@Base 4:6.1.0
@@ -196,6 +198,8 @@ libKF6Screen.so.8 libkf6screen8 #MINVER#
  _ZN7KScreen6Output15rgbRangeChangedEv@Base 4:6.1.0
  _ZN7KScreen6Output15rotationChangedEv@Base 4:6.1.0
  _ZN7KScreen6Output15setCapabilitiesE6QFlagsINS0_10CapabilityEE@Base 4:6.1.0
+ _ZN7KScreen6Output15setDdcCiAllowedEb@Base 4:6.3.80
+ _ZN7KScreen6Output16edrPolicyChangedEv@Base 4:6.3.91
  _ZN7KScreen6Output16isEnabledChangedEv@Base 4:6.1.0
  _ZN7KScreen6Output16setCurrentModeIdERK7QString@Base 4:6.1.0
  _ZN7KScreen6Output16setMinBrightnessEd@Base 4:6.1.0
@@ -208,16 +212,20 @@ libKF6Screen.so.8 libkf6screen8 #MINVER#
  _ZN7KScreen6Output17setPreferredModesERK5QListI7QStringE@Base 4:6.1.0
  _ZN7KScreen6Output17wcgEnabledChangedEv@Base 4:6.1.0
  _ZN7KScreen6Output18isConnectedChangedEv@Base 4:6.1.0
+ _ZN7KScreen6Output18setMaxBitsPerColorEj@Base 4:6.3.91
  _ZN7KScreen6Output19capabilitiesChangedEv@Base 4:6.1.0
+ _ZN7KScreen6Output19ddcCiAllowedChangedEv@Base 4:6.3.80
  _ZN7KScreen6Output19setAutoRotatePolicyENS0_16AutoRotatePolicyE@Base 4:6.1.0
  _ZN7KScreen6Output19setSdrGamutWidenessEd@Base 4:6.1.0
  _ZN7KScreen6Output20currentModeIdChangedEv@Base 4:6.1.0
  _ZN7KScreen6Output20minBrightnessChangedEv@Base 4:6.1.0
  _ZN7KScreen6Output20sdrBrightnessChangedEv@Base 4:6.1.0
+ _ZN7KScreen6Output20setBitsPerColorRangeENS0_8BpcRangeE@Base 4:6.3.91
  _ZN7KScreen6Output20setMaxPeakBrightnessEd@Base 4:6.1.0
  _ZN7KScreen6Output20setReplicationSourceEi@Base 4:6.1.0
  _ZN7KScreen6Output21iccProfilePathChangedEv@Base 4:6.1.0
  _ZN7KScreen6Output21setColorProfileSourceENS0_18ColorProfileSourceE@Base 4:6.1.0
+ _ZN7KScreen6Output22maxBitsPerColorChangedEv@Base 4:6.3.91
  _ZN7KScreen6Output22setExplicitLogicalSizeERK6QSizeF@Base 4:6.1.0
  _ZN7KScreen6Output22setFollowPreferredModeEb@Base 4:6.1.0
  _ZN7KScreen6Output23autoRotatePolicyChangedEv@Base 4:6.1.0
@@ -236,6 +244,7 @@ libKF6Screen.so.8 libkf6screen8 #MINVER#
  _ZN7KScreen6Output28setMaxPeakBrightnessOverrideESt8optionalIdE@Base 4:6.1.0
  _ZN7KScreen6Output31setMaxAverageBrightnessOverrideESt8optionalIdE@Base 4:6.1.0
  _ZN7KScreen6Output32maxPeakBrightnessOverrideChangedEv@Base 4:6.1.0
+ _ZN7KScreen6Output32setAutomaticMaxBitsPerColorLimitEj@Base 4:6.3.91
  _ZN7KScreen6Output35maxAverageBrightnessOverrideChangedEv@Base 4:6.1.0
  _ZN7KScreen6Output5applyERK14QSharedPointerIS0_E@Base 4:6.1.0
  _ZN7KScreen6Output5setIdEi@Base 4:6.1.0
@@ -245,6 +254,7 @@ libKF6Screen.so.8 libkf6screen8 #MINVER#
  _ZN7KScreen6Output7setNameERK7QString@Base 4:6.1.0
  _ZN7KScreen6Output7setSizeERK5QSize@Base 4:6.1.0
  _ZN7KScreen6Output7setTypeENS0_4TypeE@Base 4:6.1.0
+ _ZN7KScreen6Output7setUuidERK7QString@Base 4:6.3.80
  _ZN7KScreen6Output8setModelERK7QString@Base 4:6.2.90
  _ZN7KScreen6Output8setModesERK4QMapI7QString14QSharedPointerINS_4ModeEEE@Base 4:6.1.0
  _ZN7KScreen6Output8setScaleEd@Base 4:6.1.0
@@ -315,6 +325,7 @@ libKF6Screen.so.8 libkf6screen8 #MINVER#
  _ZNK7KScreen4Mode4nameEv@Base 4:6.1.0
  _ZNK7KScreen4Mode4sizeEv@Base 4:6.1.0
  _ZNK7KScreen4Mode5cloneEv@Base 4:6.1.0
+ _ZNK7KScreen4ModeeqERKS0_@Base 4:6.3.80
  _ZNK7KScreen6Config10metaObjectEv@Base 4:6.1.0
  _ZNK7KScreen6Config13primaryOutputEv@Base 4:6.1.0
  _ZNK7KScreen6Config16connectedOutputsEv@Base 4:6.1.0
@@ -335,6 +346,7 @@ libKF6Screen.so.8 libkf6screen8 #MINVER#
  _ZNK7KScreen6Output11currentModeEv@Base 4:6.1.0
  _ZNK7KScreen6Output11isConnectedEv@Base 4:6.1.0
  _ZNK7KScreen6Output12capabilitiesEv@Base 4:6.1.0
+ _ZNK7KScreen6Output12ddcCiAllowedEv@Base 4:6.3.80
  _ZNK7KScreen6Output12isHdrEnabledEv@Base 4:6.1.0
  _ZNK7KScreen6Output12isWcgEnabledEv@Base 4:6.1.0
  _ZNK7KScreen6Output13currentModeIdEv@Base 4:6.1.0
@@ -344,10 +356,12 @@ libKF6Screen.so.8 libkf6screen8 #MINVER#
  _ZNK7KScreen6Output14iccProfilePathEv@Base 4:6.1.0
  _ZNK7KScreen6Output14isPositionableEv@Base 4:6.1.0
  _ZNK7KScreen6Output14preferredModesEv@Base 4:6.1.0
+ _ZNK7KScreen6Output15maxBitsPerColorEv@Base 4:6.3.91
  _ZNK7KScreen6Output15preferredModeIdEv@Base 4:6.1.0
  _ZNK7KScreen6Output16autoRotatePolicyEv@Base 4:6.1.0
  _ZNK7KScreen6Output16enforcedModeSizeEv@Base 4:6.1.0
  _ZNK7KScreen6Output16sdrGamutWidenessEv@Base 4:6.1.0
+ _ZNK7KScreen6Output17bitsPerColorRangeEv@Base 4:6.3.91
  _ZNK7KScreen6Output17maxPeakBrightnessEv@Base 4:6.1.0
  _ZNK7KScreen6Output17replicationSourceEv@Base 4:6.1.0
  _ZNK7KScreen6Output18colorProfileSourceEv@Base 4:6.1.0
@@ -359,6 +373,7 @@ libKF6Screen.so.8 libkf6screen8 #MINVER#
  _ZNK7KScreen6Output22explicitLogicalSizeIntEv@Base 4:6.1.0
  _ZNK7KScreen6Output25maxPeakBrightnessOverrideEv@Base 4:6.1.0
  _ZNK7KScreen6Output28maxAverageBrightnessOverrideEv@Base 4:6.1.0
+ _ZNK7KScreen6Output29automaticMaxBitsPerColorLimitEv@Base 4:6.3.91
  _ZNK7KScreen6Output2idEv@Base 4:6.1.0
  _ZNK7KScreen6Output3posEv@Base 4:6.1.0
  _ZNK7KScreen6Output4edidEv@Base 4:6.1.0
@@ -368,6 +383,7 @@ libKF6Screen.so.8 libkf6screen8 #MINVER#
  _ZNK7KScreen6Output4nameEv@Base 4:6.1.0
  _ZNK7KScreen6Output4sizeEv@Base 4:6.1.0
  _ZNK7KScreen6Output4typeEv@Base 4:6.1.0
+ _ZNK7KScreen6Output4uuidEv@Base 4:6.3.80
  _ZNK7KScreen6Output5cloneEv@Base 4:6.1.0
  _ZNK7KScreen6Output5modelEv@Base 4:6.2.90
  _ZNK7KScreen6Output5modesEv@Base 4:6.1.0
@@ -383,6 +399,7 @@ libKF6Screen.so.8 libkf6screen8 #MINVER#
  _ZNK7KScreen6Output8rgbRangeEv@Base 4:6.1.0
  _ZNK7KScreen6Output8rotationEv@Base 4:6.1.0
  _ZNK7KScreen6Output8typeNameEv@Base 4:6.1.0
+ _ZNK7KScreen6Output9edrPolicyEv@Base 4:6.3.91
  _ZNK7KScreen6Output9isEnabledEv@Base 4:6.1.0
  _ZNK7KScreen6Output9isPrimaryEv@Base 4:6.1.0
  _ZNK7KScreen6Output9vrrPolicyEv@Base 4:6.1.0
@@ -393,9 +410,10 @@ libKF6Screen.so.8 libkf6screen8 #MINVER#
  _ZNK7KScreen6Screen5cloneEv@Base 4:6.1.0
  _ZNK7KScreen6Screen7maxSizeEv@Base 4:6.1.0
  _ZNK7KScreen6Screen7minSizeEv@Base 4:6.1.0
- (optional=templinst)_ZNKSt8_Rb_treeI7QStringSt4pairIKS0_8QVariantESt10_Select1stIS4_ESt4lessIS0_ESaIS4_EE4findERS2_@Base 4:6.1.0
- (optional=templinst)_ZNSt8_Rb_treeI7QStringSt4pairIKS0_8QVariantESt10_Select1stIS4_ESt4lessIS0_ESaIS4_EE24_M_get_insert_unique_posERS2_@Base 4:6.1.0
- (optional=templinst)_ZNSt8_Rb_treeI7QStringSt4pairIKS0_8QVariantESt10_Select1stIS4_ESt4lessIS0_ESaIS4_EE29_M_get_insert_hint_unique_posESt23_Rb_tree_const_iteratorIS4_ERS2_@Base 4:6.1.0
+ (optional=templinst|arch=armhf riscv64)_ZNKSt8_Rb_treeI7QStringSt4pairIKS0_8QVariantESt10_Select1stIS4_ESt4lessIS0_ESaIS4_EE4findERS2_@Base 4:6.1.0
+ (optional=templinst|arch=armhf riscv64)_ZNSt8_Rb_treeI7QStringSt4pairIKS0_8QVariantESt10_Select1stIS4_ESt4lessIS0_ESaIS4_EE24_M_get_insert_unique_posERS2_@Base 4:6.1.0
+ (optional=templinst|arch=armhf riscv64)_ZNSt8_Rb_treeI7QStringSt4pairIKS0_8QVariantESt10_Select1stIS4_ESt4lessIS0_ESaIS4_EE29_M_get_insert_hint_unique_posESt23_Rb_tree_const_iteratorIS4_ERS2_@Base 4:6.1.0
+ _ZSt19piecewise_construct@Base 4:6.3.80
  _ZTIN7KScreen13ConfigMonitorE@Base 4:6.1.0
  _ZTIN7KScreen14BackendManagerE@Base 4:6.1.0
  _ZTIN7KScreen15AbstractBackendE@Base 4:6.1.0
diff -pruN 4:6.3.4-1/debian/patches/series 4:6.4.5-0ubuntu2/debian/patches/series
--- 4:6.3.4-1/debian/patches/series	2024-11-26 22:49:10.000000000 +0000
+++ 4:6.4.5-0ubuntu2/debian/patches/series	2025-09-09 16:02:22.000000000 +0000
@@ -1 +1 @@
-Make-qt6-wayland-optional.patch
+#Make-qt6-wayland-optional.patch
diff -pruN 4:6.3.4-1/poqm/sv/libkscreen6_qt.po 4:6.4.5-0ubuntu2/poqm/sv/libkscreen6_qt.po
--- 4:6.3.4-1/poqm/sv/libkscreen6_qt.po	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/poqm/sv/libkscreen6_qt.po	2025-09-09 08:27:15.000000000 +0000
@@ -2,7 +2,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: \n"
-"PO-Revision-Date: 2025-01-11 11:20+0100\n"
+"PO-Revision-Date: 2025-05-30 15:47+0200\n"
 "Last-Translator: Stefan Asserhäll <stefan.asserhall@gmail.com>\n"
 "Language-Team: Swedish <kde-i18n-doc@kde.org>\n"
 "Language: sv\n"
@@ -11,27 +11,27 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "X-Qt-Contexts: true\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Lokalize 24.12.0\n"
+"X-Generator: Lokalize 25.04.1\n"
 
 #: getconfigoperation.cpp:62
 msgctxt "KScreen::GetConfigOperationPrivate|"
 msgid "Failed to prepare backend"
-msgstr "Misslyckades förbereda bakgrundsprogram"
+msgstr "Misslyckades förbereda gränssnitt"
 
 #: getconfigoperation.cpp:87
 msgctxt "KScreen::GetConfigOperationPrivate|"
 msgid "Failed to deserialize backend response"
-msgstr "Misslyckades deserialisera svar från bakgrundsprogram"
+msgstr "Misslyckades deserialisera gränssnittssvar"
 
 #: getconfigoperation.cpp:99
 msgctxt "KScreen::GetConfigOperationPrivate|"
 msgid "Backend invalidated"
-msgstr "Bakgrundsprogram ogiltigt"
+msgstr "Gränssnitt ogiltigförklarat"
 
 #: setconfigoperation.cpp:58
 msgctxt "KScreen::SetConfigOperationPrivate|"
 msgid "Failed to prepare backend"
-msgstr "Misslyckades förbereda bakgrundsprogram"
+msgstr "Misslyckades förbereda gränssnitt"
 
 #: setconfigoperation.cpp:65
 msgctxt "KScreen::SetConfigOperationPrivate|"
@@ -41,4 +41,4 @@ msgstr "Misslyckades serialisera begära
 #: setconfigoperation.cpp:89
 msgctxt "KScreen::SetConfigOperationPrivate|"
 msgid "Failed to deserialize backend response"
-msgstr "Misslyckades deserialisera svar från bakgrundsprogram"
+msgstr "Misslyckades deserialisera gränssnittssvar"
diff -pruN 4:6.3.4-1/src/abstractbackend.h 4:6.4.5-0ubuntu2/src/abstractbackend.h
--- 4:6.3.4-1/src/abstractbackend.h	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/src/abstractbackend.h	2025-09-09 08:27:15.000000000 +0000
@@ -10,13 +10,18 @@
 #include "kscreen_export.h"
 #include "types.h"
 
+#include <QFuture>
 #include <QObject>
 #include <QString>
+#include <expected>
 
 namespace KScreen
 {
 class Config;
 
+
+typedef std::expected<void, QString> SetConfigResult;
+
 /**
  * Abstract class for backends.
  */
@@ -64,10 +69,10 @@ public:
      * Apply a config object to the system.
      *
      * @param config Configuration to apply
-     * @returns an error message in the case of failure
-     * TODO Plasma 6.4 port back to std::expected
+     * @returns a future leading to a SetConfigResult
+     * Out-of process backends must return a completed future.
      */
-    virtual QString setConfig(const KScreen::ConfigPtr &config) = 0;
+    virtual QFuture<SetConfigResult> setConfig(const KScreen::ConfigPtr &config) = 0;
 
     /**
      * Returns whether the backend is in valid state.
diff -pruN 4:6.3.4-1/src/backendlauncher/backenddbuswrapper.cpp 4:6.4.5-0ubuntu2/src/backendlauncher/backenddbuswrapper.cpp
--- 4:6.3.4-1/src/backendlauncher/backenddbuswrapper.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/src/backendlauncher/backenddbuswrapper.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -67,7 +67,8 @@ QVariantMap BackendDBusWrapper::setConfi
     }
 
     const KScreen::ConfigPtr config = KScreen::ConfigSerializer::deserializeConfig(configMap);
-    mBackend->setConfig(config);
+    auto result = mBackend->setConfig(config);
+    Q_ASSERT(result.isFinished());
 
     mCurrentConfig = mBackend->config();
     QMetaObject::invokeMethod(this, "doEmitConfigChanged", Qt::QueuedConnection);
diff -pruN 4:6.3.4-1/src/configserializer.cpp 4:6.4.5-0ubuntu2/src/configserializer.cpp
--- 4:6.3.4-1/src/configserializer.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/src/configserializer.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -97,26 +97,39 @@ QJsonObject ConfigSerializer::serializeO
     if (output->capabilities() & Output::Capability::Overscan) {
         obj[QLatin1String("overscan")] = static_cast<int>(output->overscan());
     }
-
     if (output->capabilities() & Output::Capability::Vrr) {
         obj[QLatin1String("vrrPolicy")] = static_cast<int>(output->vrrPolicy());
     }
-
     if (output->capabilities() & Output::Capability::RgbRange) {
         obj[QLatin1String("rgbRange")] = static_cast<int>(output->rgbRange());
     }
-
     if (output->capabilities() & Output::Capability::HighDynamicRange) {
         obj[QLatin1String("hdr")] = output->isHdrEnabled();
     }
-
     if (output->capabilities() & Output::Capability::HighDynamicRange) {
         obj[QLatin1String("sdr-brightness")] = static_cast<int>(output->sdrBrightness());
     }
-
     if (output->capabilities() & Output::Capability::WideColorGamut) {
         obj[QLatin1String("wcg")] = output->isWcgEnabled();
     }
+    if (output->capabilities() & Output::Capability::AutoRotation) {
+        obj[QLatin1String("autoRotatePolicy")] = static_cast<int>(output->autoRotatePolicy());
+    }
+    if (output->capabilities() & Output::Capability::IccProfile) {
+        obj[QLatin1String("iccProfilePath")] = output->iccProfilePath();
+    }
+    if (output->capabilities() & Output::Capability::BrightnessControl) {
+        obj[QLatin1String("brightness")] = output->brightness();
+    }
+    if (output->capabilities() & Output::Capability::DdcCi) {
+        obj[QLatin1String("ddcCiAllowed")] = output->ddcCiAllowed();
+    }
+    if (output->capabilities() & Output::Capability::MaxBitsPerColor) {
+        obj[QLatin1String("maxBpc")] = int(output->maxBitsPerColor());
+    }
+    if (output->capabilities() & Output::Capability::ExtendedDynamicRange) {
+        obj[QLatin1String("edrPolicy")] = static_cast<int>(output->edrPolicy());
+    }
 
     return obj;
 }
diff -pruN 4:6.3.4-1/src/configserializer_p.h 4:6.4.5-0ubuntu2/src/configserializer_p.h
--- 4:6.3.4-1/src/configserializer_p.h	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/src/configserializer_p.h	2025-09-09 08:27:15.000000000 +0000
@@ -21,7 +21,8 @@ namespace ConfigSerializer
 {
 KSCREEN_EXPORT QJsonObject serializePoint(const QPoint &point);
 KSCREEN_EXPORT QJsonObject serializeSize(const QSize &size);
-template<typename T> KSCREEN_EXPORT QJsonArray serializeList(const QList<T> &list)
+template<typename T>
+KSCREEN_EXPORT QJsonArray serializeList(const QList<T> &list)
 {
     QJsonArray arr;
     for (const T &t : list) {
@@ -37,7 +38,8 @@ KSCREEN_EXPORT QJsonObject serializeScre
 
 KSCREEN_EXPORT QPoint deserializePoint(const QDBusArgument &map);
 KSCREEN_EXPORT QSize deserializeSize(const QDBusArgument &map);
-template<typename T> KSCREEN_EXPORT QList<T> deserializeList(const QDBusArgument &arg)
+template<typename T>
+KSCREEN_EXPORT QList<T> deserializeList(const QDBusArgument &arg)
 {
     QList<T> list;
     arg.beginArray();
diff -pruN 4:6.3.4-1/src/doctor/doctor.cpp 4:6.4.5-0ubuntu2/src/doctor/doctor.cpp
--- 4:6.3.4-1/src/doctor/doctor.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/src/doctor/doctor.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -178,21 +178,22 @@ void Doctor::setOptionList(const QString
 
 OutputPtr Doctor::findOutput(const QString &query)
 {
-    // try as an output name or ID
-    for (const auto &output : m_config->outputs()) {
-        if (output->name() == query) {
-            return output;
-        }
+    const auto outputs = m_config->outputs();
+    const auto it = std::ranges::find_if(outputs, [&query](const auto &output) {
+        return query == output->name() || query == output->uuid();
+    });
+    if (it != outputs.end()) {
+        return *it;
     }
     bool ok;
     int id = query.toInt(&ok);
     if (!ok) {
-        cerr << "Output with name " << query << " not found." << Qt::endl;
+        cerr << "Output with name or uuid " << query << " not found." << Qt::endl;
         return OutputPtr();
     }
 
-    if (m_config->outputs().contains(id)) {
-        return m_config->outputs()[id];
+    if (const auto it = outputs.find(id); it != outputs.end()) {
+        return *it;
     } else {
         cerr << "Output with id " << id << " not found." << Qt::endl;
         return OutputPtr();
@@ -336,8 +337,10 @@ void Doctor::parseOutputArgs()
                         setHdrEnabled(output, true);
                     } else if (_enable == "disable") {
                         setHdrEnabled(output, false);
+                    } else if (_enable == "toggle") {
+                        setHdrEnabled(output, !output->isHdrEnabled());
                     } else {
-                        qCWarning(KSCREEN_DOCTOR) << "Wrong input: Only allowed values for hdr are \"enable\" and \"disable\"";
+                        qCWarning(KSCREEN_DOCTOR) << "Wrong input: Only allowed values for hdr are \"enable\", \"disable\" and \"toggle\"";
                         qApp->exit(9);
                         return;
                     }
@@ -355,8 +358,10 @@ void Doctor::parseOutputArgs()
                         setWcgEnabled(output, true);
                     } else if (_enable == "disable") {
                         setWcgEnabled(output, false);
+                    } else if (_enable == "toggle") {
+                        setWcgEnabled(output, !output->isWcgEnabled());
                     } else {
-                        qCWarning(KSCREEN_DOCTOR) << "Wrong input: Only allowed values for wcg are \"enable\" and \"disable\"";
+                        qCWarning(KSCREEN_DOCTOR) << "Wrong input: Only allowed values for wcg are \"enable\", \"disable\" and \"toggle\"";
                         qApp->exit(9);
                         return;
                     }
@@ -457,6 +462,56 @@ void Doctor::parseOutputArgs()
                     }
                     output->setDimming(dimming / 100.0);
                     m_changed = true;
+                } else if (ops.count() >= 4 && subcmd == "mirror") {
+                    if (ops[3] == "none") {
+                        output->setReplicationSource(0);
+                    } else {
+                        const auto source = findOutput(ops[3]);
+                        if (!source) {
+                            qCWarning(KSCREEN_DOCTOR, "No output %s", qPrintable(ops[3]));
+                            qApp->exit(9);
+                            return;
+                        }
+                        output->setReplicationSource(source->id());
+                    }
+                    m_changed = true;
+                } else if (ops.count() >= 4 && subcmd == "ddcCi") {
+                    const QString action = ops[3].toLower();
+                    if (action == "allow") {
+                        output->setDdcCiAllowed(true);
+                    } else if (action == "disallow") {
+                        output->setDdcCiAllowed(false);
+                    } else {
+                        qCWarning(KSCREEN_DOCTOR) << "Wrong input: Only allowed values for ddcCi are \"allow\" and \"disallow\"";
+                        qApp->exit(9);
+                        return;
+                    }
+                    m_changed = true;
+                } else if (ops.count() >= 4 && subcmd == "maxbpc") {
+                    if (ops[3] == "automatic") {
+                        output->setMaxBitsPerColor(0);
+                    } else {
+                        bool ok = false;
+                        const uint32_t bpc = ops[3].toUInt(&ok);
+                        if (!ok || bpc < 6 || bpc > 16 || bpc % 2 != 0) {
+                            qCWarning(KSCREEN_DOCTOR) << "Wrong input: Only 'automatic' and whole numbers between 6 and 16 are allowed";
+                            qApp->exit(9);
+                            return;
+                        }
+                        output->setMaxBitsPerColor(bpc);
+                    }
+                    m_changed = true;
+                } else if (ops.count() >= 4 && subcmd == "edrPolicy") {
+                    if (ops[3] == "never") {
+                        output->setEdrPolicy(Output::EdrPolicy::Never);
+                    } else if (ops[3] == "always") {
+                        output->setEdrPolicy(Output::EdrPolicy::Always);
+                    } else {
+                        qCWarning(KSCREEN_DOCTOR) << "Wrong input: Only 'never' and 'automatic' are valid";
+                        qApp->exit(9);
+                        return;
+                    }
+                    m_changed = true;
                 } else {
                     cerr << "Unable to parse arguments: " << op << Qt::endl;
                     qApp->exit(2);
@@ -487,8 +542,9 @@ void Doctor::configReceived(KScreen::Con
 
     parseOutputArgs();
 
-    if (const auto error = applyConfig()) {
-        cout << "applying config failed! " << *error << "\n";
+    const auto ret = applyConfig();
+    if (!ret.has_value()) {
+        cout << "applying config failed! " << ret.error() << "\n";
     }
     qApp->exit(0);
 }
@@ -517,12 +573,13 @@ void Doctor::showOutputs() const
 
     for (const auto &output : m_config->outputs()) {
         const auto endl = '\n';
-        cout << green << "Output: " << cr << output->id() << " " << output->name() << endl;
+        cout << green << "Output: " << cr << output->id() << " " << output->name() << " " << output->uuid() << endl;
         cout << "\t" << (output->isEnabled() ? green + QStringLiteral("enabled") : red + QStringLiteral("disabled")) << cr << endl;
         cout << "\t" << (output->isConnected() ? green + QStringLiteral("connected") : red + QStringLiteral("disconnected")) << cr << endl;
         cout << "\t" << (output->isEnabled() ? green : red) + QStringLiteral("priority ") << output->priority() << cr << endl;
         auto _type = typeString[output->type()];
         cout << "\t" << yellow << (_type.isEmpty() ? QStringLiteral("UnmappedOutputType") : _type) << cr << endl;
+        cout << "\t" << yellow << "replication source:" << cr << output->replicationSource() << endl;
         cout << "\t" << blue << "Modes: " << cr;
 
         const auto modes = output->modes();
@@ -634,7 +691,7 @@ void Doctor::showOutputs() const
             cout << cr << "incapable" << endl;
         }
         cout << yellow << "\tColor profile source: ";
-        if (output->capabilities() & Output::Capability::IccProfile) {
+        if (output->capabilities() & (Output::Capabilities(Output::Capability::IccProfile) | Output::Capability::BuiltInColorProfile)) {
             cout << cr;
             switch (output->colorProfileSource()) {
             case Output::ColorProfileSource::sRGB:
@@ -667,6 +724,46 @@ void Doctor::showOutputs() const
         } else {
             cout << cr << "unsupported" << endl;
         }
+        if (output->capabilities() & Output::Capability::DdcCi) {
+            cout << yellow << "\tDDC/CI: ";
+            cout << cr << (output->ddcCiAllowed() ? "allowed" : "disallowed") << endl;
+        }
+        cout << yellow << "\tColor resolution: ";
+        if (output->capabilities() & Output::Capability::MaxBitsPerColor) {
+            cout << cr;
+            if (output->maxBitsPerColor() != 0) {
+                cout << output->maxBitsPerColor() << " bits per color";
+            } else {
+                uint32_t autoBpc = 0;
+                if (output->colorPowerPreference() == Output::ColorPowerTradeoff::PreferEfficiency) {
+                    autoBpc = 10;
+                } else {
+                    autoBpc = 16;
+                }
+                if (output->automaticMaxBitsPerColorLimit()) {
+                    autoBpc = std::min(autoBpc, output->automaticMaxBitsPerColorLimit());
+                }
+                cout << "automatic (" << autoBpc << ")";
+            }
+            cout << ", range: [" << output->bitsPerColorRange().min << "; " << output->bitsPerColorRange().max << "] bits per color" << endl;
+        } else {
+            cout << "unknown" << endl;
+        }
+        cout << yellow << "\tAllow EDR: ";
+        if (output->capabilities() & Output::Capability::ExtendedDynamicRange) {
+            cout << cr;
+            switch (output->edrPolicy()) {
+            case Output::EdrPolicy::Never:
+                cout << "never";
+                break;
+            case Output::EdrPolicy::Always:
+                cout << "always";
+                break;
+            }
+            cout << endl;
+        } else {
+            cout << cr << "unsupported" << endl;
+        }
     }
 }
 
@@ -775,16 +872,16 @@ void Doctor::setWcgEnabled(OutputPtr out
     m_changed = true;
 }
 
-std::optional<QString> Doctor::applyConfig()
+std::expected<void, QString> Doctor::applyConfig()
 {
     if (!m_changed) {
-        return std::nullopt;
+        return {};
     }
     auto setop = new SetConfigOperation(m_config, this);
     if (setop->exec()) {
-        return std::nullopt;
+        return {};
     } else {
-        return setop->errorString();
+        return std::unexpected(setop->errorString());
     }
 }
 
diff -pruN 4:6.3.4-1/src/doctor/doctor.h 4:6.4.5-0ubuntu2/src/doctor/doctor.h
--- 4:6.3.4-1/src/doctor/doctor.h	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/src/doctor/doctor.h	2025-09-09 08:27:15.000000000 +0000
@@ -8,6 +8,7 @@
 
 #include <QCommandLineParser>
 #include <QObject>
+#include <expected>
 
 #include "output.h"
 #include "types.h"
@@ -56,7 +57,7 @@ Q_SIGNALS:
 
 private:
     // static QString modeString(KWayland::Server::OutputDeviceInterface* outputdevice, int mid);
-    std::optional<QString> applyConfig();
+    std::expected<void, QString> applyConfig();
     void parseOutputArgs();
     KScreen::ConfigPtr m_config;
     QCommandLineParser *m_parser;
diff -pruN 4:6.3.4-1/src/libdpms/waylanddpmshelper.cpp 4:6.4.5-0ubuntu2/src/libdpms/waylanddpmshelper.cpp
--- 4:6.3.4-1/src/libdpms/waylanddpmshelper.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/src/libdpms/waylanddpmshelper.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -119,11 +119,7 @@ public:
 private:
     void addScreen(QScreen *screen)
     {
-#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
-        auto waylandScreen = screen->nativeInterface<QNativeInterface::Private::QWaylandScreen>();
-#else
         auto waylandScreen = screen->nativeInterface<QNativeInterface::QWaylandScreen>();
-#endif
         if (waylandScreen && waylandScreen->output()) {
             m_dpmsPerScreen[screen] = new Dpms(get(waylandScreen->output()), m_dpms, screen);
         }
diff -pruN 4:6.3.4-1/src/mode.cpp 4:6.4.5-0ubuntu2/src/mode.cpp
--- 4:6.3.4-1/src/mode.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/src/mode.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -116,6 +116,11 @@ void Mode::setRefreshRate(float refresh)
     Q_EMIT modeChanged();
 }
 
+bool Mode::operator==(const Mode &other) const
+{
+    return d->size == other.d->size && d->rate == other.d->rate;
+}
+
 QDebug operator<<(QDebug dbg, const KScreen::ModePtr &mode)
 {
     if (mode) {
diff -pruN 4:6.3.4-1/src/mode.h 4:6.4.5-0ubuntu2/src/mode.h
--- 4:6.3.4-1/src/mode.h	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/src/mode.h	2025-09-09 08:27:15.000000000 +0000
@@ -43,6 +43,8 @@ public:
     float refreshRate() const;
     void setRefreshRate(float refresh);
 
+    bool operator==(const Mode &other) const;
+
 Q_SIGNALS:
     void modeChanged();
 
diff -pruN 4:6.3.4-1/src/output.cpp 4:6.4.5-0ubuntu2/src/output.cpp
--- 4:6.3.4-1/src/output.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/src/output.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -80,6 +80,12 @@ public:
         , brightness(other.brightness)
         , colorPowerPreference(other.colorPowerPreference)
         , dimming(other.dimming)
+        , uuid(other.uuid)
+        , ddcCiAllowed(other.ddcCiAllowed)
+        , maxBitsPerColor(other.maxBitsPerColor)
+        , bitsPerColorRange(other.bitsPerColorRange)
+        , automaticMaxBitsPerColorLimit(other.automaticMaxBitsPerColorLimit)
+        , edrPolicy(other.edrPolicy)
     {
         const auto otherModeList = other.modeList;
         for (const ModePtr &otherMode : otherModeList) {
@@ -139,6 +145,12 @@ public:
     double brightness = 1.0;
     ColorPowerTradeoff colorPowerPreference = ColorPowerTradeoff::PreferEfficiency;
     double dimming = 1.0;
+    QString uuid;
+    bool ddcCiAllowed = true;
+    uint32_t maxBitsPerColor = 0;
+    BpcRange bitsPerColorRange;
+    uint32_t automaticMaxBitsPerColorLimit = 0;
+    EdrPolicy edrPolicy = EdrPolicy::Always;
 };
 
 bool Output::Private::compareModeList(const ModeList &before, const ModeList &after)
@@ -948,6 +960,84 @@ void Output::setDimming(double dimming)
     }
 }
 
+QString Output::uuid() const
+{
+    return d->uuid;
+}
+
+void Output::setUuid(const QString &id)
+{
+    if (d->uuid != id) {
+        d->uuid = id;
+        Q_EMIT uuidChanged();
+    }
+}
+
+bool Output::ddcCiAllowed() const
+{
+    return d->ddcCiAllowed;
+}
+
+void Output::setDdcCiAllowed(bool allowed)
+{
+    if (d->ddcCiAllowed != allowed) {
+        d->ddcCiAllowed = allowed;
+        Q_EMIT ddcCiAllowedChanged();
+    }
+}
+
+uint32_t Output::maxBitsPerColor() const
+{
+    return d->maxBitsPerColor;
+}
+
+void Output::setMaxBitsPerColor(uint32_t value)
+{
+    if (d->maxBitsPerColor != value) {
+        d->maxBitsPerColor = value;
+        Q_EMIT maxBitsPerColorChanged();
+    }
+}
+
+Output::BpcRange Output::bitsPerColorRange() const
+{
+    return d->bitsPerColorRange;
+}
+
+void Output::setBitsPerColorRange(BpcRange range)
+{
+    if (d->bitsPerColorRange != range) {
+        d->bitsPerColorRange = range;
+        Q_EMIT maxBitsPerColorChanged();
+    }
+}
+
+uint32_t Output::automaticMaxBitsPerColorLimit() const
+{
+    return d->automaticMaxBitsPerColorLimit;
+}
+
+void Output::setAutomaticMaxBitsPerColorLimit(uint32_t chosenValue)
+{
+    if (d->automaticMaxBitsPerColorLimit != chosenValue) {
+        d->automaticMaxBitsPerColorLimit = chosenValue;
+        Q_EMIT maxBitsPerColorChanged();
+    }
+}
+
+Output::EdrPolicy Output::edrPolicy() const
+{
+    return d->edrPolicy;
+}
+
+void Output::setEdrPolicy(EdrPolicy policy)
+{
+    if (d->edrPolicy != policy) {
+        d->edrPolicy = policy;
+        Q_EMIT edrPolicy();
+    }
+}
+
 void Output::apply(const OutputPtr &other)
 {
     typedef void (KScreen::Output::*ChangeSignal)();
@@ -1098,6 +1188,25 @@ void Output::apply(const OutputPtr &othe
         changes << &Output::dimmingChanged;
         setDimming(other->d->dimming);
     }
+    if (d->uuid != other->d->uuid) {
+        changes << &Output::uuidChanged;
+        setUuid(other->d->uuid);
+    }
+    if (d->ddcCiAllowed != other->d->ddcCiAllowed) {
+        changes << &Output::ddcCiAllowedChanged;
+        setDdcCiAllowed(other->d->ddcCiAllowed);
+    }
+    if (d->maxBitsPerColor != other->d->maxBitsPerColor || d->bitsPerColorRange != other->d->bitsPerColorRange
+        || d->automaticMaxBitsPerColorLimit != other->d->automaticMaxBitsPerColorLimit) {
+        changes << &Output::maxBitsPerColorChanged;
+        setMaxBitsPerColor(other->d->maxBitsPerColor);
+        setBitsPerColorRange(other->d->bitsPerColorRange);
+        setAutomaticMaxBitsPerColorLimit(other->d->automaticMaxBitsPerColorLimit);
+    }
+    if (d->edrPolicy != other->d->edrPolicy) {
+        changes << &Output::edrPolicyChanged;
+        setEdrPolicy(other->d->edrPolicy);
+    }
 
     // Non-notifyable changes
     if (other->d->edid) {
diff -pruN 4:6.3.4-1/src/output.h 4:6.4.5-0ubuntu2/src/output.h
--- 4:6.3.4-1/src/output.h	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/src/output.h	2025-09-09 08:27:15.000000000 +0000
@@ -64,6 +64,7 @@ public:
     Q_PROPERTY(double brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged)
     Q_PROPERTY(ColorPowerTradeoff colorPowerPreference READ colorPowerPreference WRITE setColorPowerPreference NOTIFY colorPowerPreferenceChanged)
     Q_PROPERTY(double dimming READ dimming WRITE setDimming NOTIFY dimmingChanged)
+    Q_PROPERTY(bool ddcCiAllowed READ ddcCiAllowed WRITE setDdcCiAllowed NOTIFY ddcCiAllowedChanged)
 
     enum Type {
         Unknown,
@@ -105,6 +106,10 @@ public:
         AutoRotation = 1 << 5,
         IccProfile = 1 << 6,
         BrightnessControl = 1 << 7,
+        BuiltInColorProfile = 1 << 8,
+        DdcCi = 1 << 9,
+        MaxBitsPerColor = 1 << 10,
+        ExtendedDynamicRange = 1 << 11,
     };
     Q_ENUM(Capability)
     Q_DECLARE_FLAGS(Capabilities, Capability)
@@ -144,6 +149,12 @@ public:
     };
     Q_ENUM(ColorPowerTradeoff)
 
+    enum class EdrPolicy {
+        Never = 0,
+        Always,
+    };
+    Q_ENUM(EdrPolicy)
+
     explicit Output();
     ~Output() override;
 
@@ -549,6 +560,30 @@ public:
     double dimming() const;
     void setDimming(double dimming);
 
+    QString uuid() const;
+    void setUuid(const QString &id);
+
+    bool ddcCiAllowed() const;
+    void setDdcCiAllowed(bool allowed);
+
+    /**
+     * 0 if no limit is set
+     */
+    uint32_t maxBitsPerColor() const;
+    void setMaxBitsPerColor(uint32_t maxBitsPerColor);
+    struct BpcRange {
+        uint32_t min = 0;
+        uint32_t max = 0;
+        auto operator<=>(const BpcRange &) const = default;
+    };
+    BpcRange bitsPerColorRange() const;
+    void setBitsPerColorRange(BpcRange range);
+    uint32_t automaticMaxBitsPerColorLimit() const;
+    void setAutomaticMaxBitsPerColorLimit(uint32_t chosenValue);
+
+    EdrPolicy edrPolicy() const;
+    void setEdrPolicy(EdrPolicy policy);
+
     void apply(const OutputPtr &other);
 
 Q_SIGNALS:
@@ -587,6 +622,10 @@ Q_SIGNALS:
     void modelChanged();
     void colorPowerPreferenceChanged();
     void dimmingChanged();
+    void uuidChanged();
+    void ddcCiAllowedChanged();
+    void maxBitsPerColorChanged();
+    void edrPolicyChanged();
 
     /** The mode list changed.
      *
diff -pruN 4:6.3.4-1/src/setconfigoperation.cpp 4:6.4.5-0ubuntu2/src/setconfigoperation.cpp
--- 4:6.3.4-1/src/setconfigoperation.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/src/setconfigoperation.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -114,8 +114,18 @@ void SetConfigOperation::start()
     d->fixPrimaryOutput();
     if (BackendManager::instance()->method() == BackendManager::InProcess) {
         auto backend = d->loadBackend();
-        setError(backend->setConfig(d->config));
-        emitResult();
+        QFutureWatcher<SetConfigResult> *watcher = new QFutureWatcher<SetConfigResult>(this);
+        connect(watcher, &QFutureWatcher<SetConfigResult>::finished, this, [this, watcher]() {
+            watcher->deleteLater();
+            const SetConfigResult result = watcher->result();
+            if (!result.has_value()) {
+                setError(result.error());
+            }
+            emitResult();
+        });
+
+        QFuture<SetConfigResult> pendingResult = backend->setConfig(d->config);
+        watcher->setFuture(pendingResult);
     } else {
         d->requestBackend();
     }
diff -pruN 4:6.3.4-1/tests/testpnp.cpp 4:6.4.5-0ubuntu2/tests/testpnp.cpp
--- 4:6.3.4-1/tests/testpnp.cpp	2025-04-02 03:36:55.000000000 +0000
+++ 4:6.4.5-0ubuntu2/tests/testpnp.cpp	2025-09-09 08:27:15.000000000 +0000
@@ -17,7 +17,7 @@
 #include <QRect>
 #include <QScreen>
 #include <cstdint>
-//#include <QX11Info>
+// #include <QX11Info>
 
 using namespace KScreen;
 
