Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libkscreen6 for openSUSE:Factory checked in at 2026-06-18 21:35:40 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libkscreen6 (Old) and /work/SRC/openSUSE:Factory/.libkscreen6.new.1981 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libkscreen6" Thu Jun 18 21:35:40 2026 rev:42 rq:1359165 version:6.7.0 Changes: -------- --- /work/SRC/openSUSE:Factory/libkscreen6/libkscreen6.changes 2026-05-13 21:38:28.113554091 +0200 +++ /work/SRC/openSUSE:Factory/.libkscreen6.new.1981/libkscreen6.changes 2026-06-18 21:36:10.956986706 +0200 @@ -1,0 +2,49 @@ +Fri Jun 12 19:07:42 UTC 2026 - Fabian Vogt <[email protected]> + +- Update to 6.7.0: + * New bugfix release + * For more details see https://kde.org/announcements/plasma/6/6.7.0 +- Changes since 6.6.91: + * Update version for new release 6.7.0 + +------------------------------------------------------------------- +Thu May 28 18:44:37 UTC 2026 - Fabian Vogt <[email protected]> + +- Update to 6.6.91: + * New bugfix release + * For more details see https://kde.org/announcements/plasma/6/6.6.91 +- Changes since 6.6.90: + * Update version for new release 6.6.91 + +------------------------------------------------------------------- +Sun May 24 11:18:08 UTC 2026 - Fabian Vogt <[email protected]> + +- Update to 6.6.90: + * New feature release + * For more details see https://kde.org/announcements/plasma/6/6.6.90 +- Changes since 6.6.5: + * Update version for new release 6.6.90 + * cmake: bump PlasmaWaylandProtocols version to 1.21 + * Remove duplicate headers in cpp file + * output: add setting for adaptive backlight modulation + * output: add ICC profile path and color profile source for HDR mode + * dpms: Log more information when platform detection fails + * setconfigoperation: don't normalize output positions on Wayland (kde#514411) + * doctor: Add hdrAndWcg output subcommand + * doctor: Add "activeOutput" as valid screen ID + * backends/kwayland: Port to kde-output-device-v2 v21 (kde#507691) + * doctor: enable modification of AutoRotatePolicy + * Remove unneeded Qt version check + * config: restore method used by kscreen + * backends/kwayland: directly update priority value + * output: add sizeMm property synchronization in apply method + * doctor: make removing custom modes actually work + * Enable LSAN in CI + * backends/kwayland: Guard against potentially cleaning up resources without QPA + * backends/kwayland: Broadcast config changes even with pending outputs + * backends/kwayland: Mark config as valid if the output management global is available + * backends/kwayland: Properly destroy wl_registry + * backends/kwayland: Clean up output devices in WaylandConfig destructor + * Update version for new release 6.6.80 + +------------------------------------------------------------------- Old: ---- libkscreen-6.6.5.tar.xz libkscreen-6.6.5.tar.xz.sig New: ---- libkscreen-6.7.0.tar.xz libkscreen-6.7.0.tar.xz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libkscreen6.spec ++++++ --- /var/tmp/diff_new_pack.JV8BIJ/_old 2026-06-18 21:36:11.789021402 +0200 +++ /var/tmp/diff_new_pack.JV8BIJ/_new 2026-06-18 21:36:11.793021569 +0200 @@ -16,14 +16,14 @@ # -%define kf6_version 6.18.0 -%define qt6_version 6.9.0 +%define kf6_version 6.26.0 +%define qt6_version 6.10.0 %bcond_without released %define rname libkscreen %define sover 8 Name: libkscreen6 -Version: 6.6.5 +Version: 6.7.0 Release: 0 # Full Plasma 6 version (e.g. 6.0.0) %{!?_plasma6_bugfix: %define _plasma6_bugfix %{version}} @@ -32,9 +32,9 @@ Summary: Plasma screen management library License: GPL-2.0-or-later URL: https://www.kde.org -Source: https://download.kde.org/stable/plasma/%{version}/%{rname}-%{version}.tar.xz +Source: %{rname}-%{version}.tar.xz %if %{with released} -Source1: https://download.kde.org/stable/plasma/%{version}/%{rname}-%{version}.tar.xz.sig +Source1: %{rname}-%{version}.tar.xz.sig Source2: plasma.keyring %endif BuildRequires: doxygen ++++++ libkscreen-6.6.5.tar.xz -> libkscreen-6.7.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/.kde-ci.yml new/libkscreen-6.7.0/.kde-ci.yml --- old/libkscreen-6.6.5/.kde-ci.yml 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/.kde-ci.yml 2026-06-11 11:34:04.000000000 +0200 @@ -10,3 +10,4 @@ Options: require-passing-tests-on: ['@all'] + enable-lsan: True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/CMakeLists.txt new/libkscreen-6.7.0/CMakeLists.txt --- old/libkscreen-6.6.5/CMakeLists.txt 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/CMakeLists.txt 2026-06-11 11:34:04.000000000 +0200 @@ -1,10 +1,10 @@ cmake_minimum_required(VERSION 3.16) project(libkscreen) -set(PROJECT_VERSION "6.6.5") +set(PROJECT_VERSION "6.7.0") set(QT_MIN_VERSION "6.10.0") -set(KF6_MIN_VERSION "6.22.0") +set(KF6_MIN_VERSION "6.26.0") set(KDE_COMPILERSETTINGS_LEVEL "5.82") set(CMAKE_CXX_STANDARD 23) @@ -37,7 +37,7 @@ find_package(WaylandScanner) -find_package(PlasmaWaylandProtocols 1.20 CONFIG) +find_package(PlasmaWaylandProtocols 1.21 CONFIG) set_package_properties(PlasmaWaylandProtocols PROPERTIES TYPE REQUIRED) find_package(Wayland 1.24 COMPONENTS Client) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/autotests/testconfigmonitor.cpp new/libkscreen-6.7.0/autotests/testconfigmonitor.cpp --- old/libkscreen-6.6.5/autotests/testconfigmonitor.cpp 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/autotests/testconfigmonitor.cpp 2026-06-11 11:34:04.000000000 +0200 @@ -16,7 +16,6 @@ #include "../src/getconfigoperation.h" #include "../src/output.h" #include "../src/setconfigoperation.h" -#include <QSignalSpy> #include "fakebackendinterface.h" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/backends/kwayland/CMakeLists.txt new/libkscreen-6.7.0/backends/kwayland/CMakeLists.txt --- old/libkscreen-6.6.5/backends/kwayland/CMakeLists.txt 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/backends/kwayland/CMakeLists.txt 2026-06-11 11:34:04.000000000 +0200 @@ -20,14 +20,11 @@ add_library(KSC_KWayland MODULE) -if (Qt6_VERSION VERSION_GREATER_EQUAL "6.8.0") - set(private_code_option "PRIVATE_CODE") -endif() qt6_generate_wayland_protocol_client_sources(KSC_KWayland + PRIVATE_CODE FILES ${PLASMA_WAYLAND_PROTOCOLS_DIR}/kde-output-device-v2.xml ${PLASMA_WAYLAND_PROTOCOLS_DIR}/kde-output-management-v2.xml - ${private_code_option} ) target_sources(KSC_KWayland PRIVATE ${wayland_SRCS}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/backends/kwayland/waylandconfig.cpp new/libkscreen-6.7.0/backends/kwayland/waylandconfig.cpp --- old/libkscreen-6.6.5/backends/kwayland/waylandconfig.cpp 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/backends/kwayland/waylandconfig.cpp 2026-06-11 11:34:04.000000000 +0200 @@ -25,13 +25,12 @@ #include <wayland-client-protocol.h> -#include <utility> - using namespace KScreen; WaylandConfig::WaylandConfig(QObject *parent) : QObject(parent) - , m_outputManagement(std::make_unique<WaylandOutputManagement>(19)) + , m_outputManagement(std::make_unique<WaylandOutputManagement>(21)) + , m_outputRegistry(std::make_unique<WaylandOutputDeviceRegistry>()) , m_blockSignals(false) , m_kscreenConfig(new Config) , m_kscreenPendingConfig(nullptr) @@ -40,15 +39,20 @@ , m_tabletModeEngaged(false) { connect(m_outputManagement.get(), &WaylandOutputManagement::activeChanged, this, &WaylandConfig::handleActiveChanged); + connect(m_outputRegistry.get(), &WaylandOutputDeviceRegistry::outputAdded, this, &WaylandConfig::addOutput); + connect(m_outputRegistry.get(), &WaylandOutputDeviceRegistry::outputRemoved, this, &WaylandConfig::removeOutput); + initKWinTabletMode(); - setupRegistry(); + + if (auto waylandApp = qGuiApp->nativeInterface<QNativeInterface::QWaylandApplication>()) { + auto display = waylandApp->display(); + wl_display_roundtrip(display); // list output devices + wl_display_roundtrip(display); // get output device properties + } } WaylandConfig::~WaylandConfig() { - if (m_registry) { - destroyRegistry(); - } } void WaylandConfig::initKWinTabletMode() @@ -96,99 +100,29 @@ m_blockSignals = false; } -void WaylandConfig::setupRegistry() -{ - auto waylandApp = qGuiApp->nativeInterface<QNativeInterface::QWaylandApplication>(); - if (!waylandApp) { - return; - } - - auto display = waylandApp->display(); - m_registry = wl_display_get_registry(display); - - 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, kde_output_device_v2_interface.name) == 0) { - self->addOutput(name, std::min(20u, version)); - } else if (qstrcmp(interface, wl_fixes_interface.name) == 0) { - self->m_fixes = static_cast<wl_fixes *>(wl_registry_bind(registry, name, &wl_fixes_interface, 1)); - } - }; - - auto globalRemoved = [](void *data, wl_registry *registry, uint32_t name) { - Q_UNUSED(registry) - auto self = static_cast<WaylandConfig *>(data); - Q_EMIT self->globalRemoved(name); - }; - - static const wl_registry_listener registryListener{globalAdded, globalRemoved}; - wl_registry_add_listener(m_registry, ®istryListener, this); - - wl_display_roundtrip(display); // list output devices - wl_display_roundtrip(display); // get output device properties -} - -void WaylandConfig::destroyRegistry() -{ - qDeleteAll(m_initializingOutputs); - m_initializingOutputs.clear(); - - auto outputs = std::move(m_outputMap); - m_screen->setOutputs({}); - qDeleteAll(outputs); - - if (m_registry) { - if (m_fixes) { - wl_fixes_destroy_registry(m_fixes, m_registry); - } - wl_registry_destroy(m_registry); - m_registry = nullptr; - } - - if (m_fixes) { - wl_fixes_destroy(m_fixes); - m_fixes = nullptr; - } -} - void WaylandConfig::handleActiveChanged() { if (m_outputManagement->isActive()) { - if (!m_registry) { - setupRegistry(); - } - return; - } - // the compositor went away, clean up all the Wayland resources - if (!m_registry) { return; } - destroyRegistry(); + // the compositor went away, clean up all the resources + m_initializingOutputs.clear(); + m_screen->setOutputs({}); if (!m_blockSignals) { Q_EMIT configChanged(); } } -int s_outputId = 0; - -void WaylandConfig::addOutput(quint32 name, quint32 version) +void WaylandConfig::addOutput(WaylandOutputDevice *output) { - qCDebug(KSCREEN_WAYLAND) << "adding output" << name; + qCDebug(KSCREEN_WAYLAND) << "adding output" << output; - auto device = new WaylandOutputDevice(++s_outputId); - m_initializingOutputs << device; - - connect(this, &WaylandConfig::globalRemoved, device, [name, device, this](const uint32_t &interfaceName) { - if (name == interfaceName) { - removeOutput(device); - } - }); - - connect(device, &WaylandOutputDevice::done, this, [this, device]() { - if (m_initializingOutputs.removeOne(device)) { - m_outputMap.insert(device->id(), device); + m_initializingOutputs << output; + connect(output, &WaylandOutputDevice::done, this, [this, output]() { + if (m_initializingOutputs.removeOne(output)) { + m_outputMap.insert(output->id(), output); m_screen->setOutputs(m_outputMap.values()); } @@ -196,8 +130,6 @@ Q_EMIT configChanged(); } }); - - device->init(m_registry, name, version); } void WaylandConfig::removeOutput(WaylandOutputDevice *output) @@ -205,17 +137,13 @@ qCDebug(KSCREEN_WAYLAND) << "removing output" << output->name(); if (m_initializingOutputs.removeOne(output)) { - // output was not yet fully initialized, just remove here and return - delete output; return; } - // remove the output from output mapping const auto removedOutput = m_outputMap.take(output->id()); Q_ASSERT(removedOutput == output); Q_UNUSED(removedOutput); m_screen->setOutputs(m_outputMap.values()); - delete output; if (!m_blockSignals) { Q_EMIT configChanged(); @@ -224,7 +152,7 @@ bool WaylandConfig::isValid() const { - return m_outputManagement->isActive(); + return m_outputManagement->isActive() && m_outputRegistry->isActive(); } KScreen::ConfigPtr WaylandConfig::currentConfig() @@ -248,19 +176,13 @@ } // Add KScreen::Outputs that aren't in the list yet - 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, m_outputMap); + output->updateKScreenOutput(m_kscreenConfig->outputs()[output->id()], m_outputMap); } else { - kscreenOutput = output->toKScreenOutput(m_outputMap); - m_kscreenConfig->addOutput(kscreenOutput); + m_kscreenConfig->addOutput(output->toKScreenOutput(m_outputMap)); } - priorities[kscreenOutput] = output->index(); } - m_kscreenConfig->setOutputPriorities(priorities); m_kscreenConfig->setTabletModeAvailable(m_tabletModeAvailable); m_kscreenConfig->setTabletModeEngaged(m_tabletModeEngaged); @@ -282,16 +204,6 @@ m_kscreenPendingConfig = nullptr; } -WaylandOutputDevice *WaylandConfig::findOutputDevice(struct ::kde_output_device_v2 *outputdevice) const -{ - for (WaylandOutputDevice *device : m_outputMap) { - if (device->object() == outputdevice) { - return device; - } - } - return nullptr; -} - bool WaylandConfig::applyConfig(const KScreen::ConfigPtr &newConfig) { for (const auto &output : newConfig->outputs()) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/backends/kwayland/waylandconfig.h new/libkscreen-6.7.0/backends/kwayland/waylandconfig.h --- old/libkscreen-6.6.5/backends/kwayland/waylandconfig.h 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/backends/kwayland/waylandconfig.h 2026-06-11 11:34:04.000000000 +0200 @@ -14,15 +14,12 @@ #include <QSize> #include <QSocketNotifier> -struct kde_output_device_v2; -struct wl_registry; -struct wl_fixes; - namespace KScreen { class Output; class WaylandOutputDevice; class WaylandScreen; +class WaylandOutputDeviceRegistry; class WaylandOutputManagement; class WaylandConfig : public QObject @@ -37,7 +34,6 @@ QMap<int, WaylandOutputDevice *> outputMap() const; bool applyConfig(const KScreen::ConfigPtr &newConfig); - WaylandOutputDevice *findOutputDevice(struct ::kde_output_device_v2 *outputdevice) const; bool isValid() const; @@ -47,23 +43,19 @@ void configFailed(const QString &reason); private: - void setupRegistry(); - void destroyRegistry(); void handleActiveChanged(); void initKWinTabletMode(); - void addOutput(quint32 name, quint32 version); + void addOutput(WaylandOutputDevice *output); void removeOutput(WaylandOutputDevice *output); void blockSignals(); void unblockSignals(); void tryPendingConfig(); - wl_registry *m_registry = nullptr; - wl_fixes *m_fixes = nullptr; - std::unique_ptr<WaylandOutputManagement> m_outputManagement; + std::unique_ptr<WaylandOutputDeviceRegistry> m_outputRegistry; // KWayland names as keys QMap<int, WaylandOutputDevice *> m_outputMap; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/backends/kwayland/waylandoutputdevice.cpp new/libkscreen-6.7.0/backends/kwayland/waylandoutputdevice.cpp --- old/libkscreen-6.6.5/backends/kwayland/waylandoutputdevice.cpp 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/backends/kwayland/waylandoutputdevice.cpp 2026-06-11 11:34:04.000000000 +0200 @@ -22,10 +22,49 @@ using namespace KScreen; -WaylandOutputDevice::WaylandOutputDevice(int id) - : QObject() - , kde_output_device_v2() - , m_id(id) +WaylandOutputDeviceRegistry::WaylandOutputDeviceRegistry() + : QWaylandClientExtensionTemplate<WaylandOutputDeviceRegistry>(23) +{ + initialize(); +} + +WaylandOutputDeviceRegistry::~WaylandOutputDeviceRegistry() +{ + if (qGuiApp && isActive()) { + stop(); + + // The WaylandConfig lives until the whole application goes down, so we don't bother + // waiting until the finished event arrives and destroy the proxy object immediately. + kde_output_device_registry_v2_destroy(object()); + } +} + +void WaylandOutputDeviceRegistry::kde_output_device_registry_v2_output(struct ::kde_output_device_v2 *output) +{ + auto outputDevice = m_outputDevices.emplace_back(std::make_unique<WaylandOutputDevice>(output)).get(); + Q_EMIT outputAdded(outputDevice); + + connect(outputDevice, &WaylandOutputDevice::removed, this, [this, outputDevice]() { + Q_EMIT outputRemoved(outputDevice); + + const auto it = std::ranges::find_if(m_outputDevices, [outputDevice](const auto &candidate) { + return candidate.get() == outputDevice; + }); + if (it != m_outputDevices.end()) { + m_outputDevices.erase(it); + } + }); +} + +static int nextOutputId() +{ + static int id = 1; + return id++; +} + +WaylandOutputDevice::WaylandOutputDevice(::kde_output_device_v2 *outputDevice) + : kde_output_device_v2(outputDevice) + , m_id(nextOutputId()) { } @@ -34,7 +73,7 @@ qDeleteAll(m_modes); if (qGuiApp) { - kde_output_device_v2_destroy(object()); + release(); } } @@ -170,7 +209,6 @@ void WaylandOutputDevice::updateKScreenOutput(OutputPtr &output, const QMap<int, WaylandOutputDevice *> &outputMap) { - // Initialize primary output output->setId(m_id); output->setEnabled(enabled()); output->setConnected(true); @@ -227,6 +265,9 @@ output->setEdrPolicy(static_cast<Output::EdrPolicy>(m_edrPolicy)); output->setSharpness(m_sharpness / 10'000.0); output->setAutomaticBrightness(m_autoBrightness); + output->setHdrIccProfilePath(m_hdrIccProfilePath); + output->setHdrColorProfileSource(Output::ColorProfileSource(m_hdrColorProfileSource)); + output->setAbmLevel(m_abmLevel); updateKScreenModes(output); @@ -242,6 +283,7 @@ }); } output->setCustomModes(m_customModes); + output->setPriority(m_priority); } QString WaylandOutputDevice::modeId() const @@ -313,7 +355,7 @@ wlConfig->set_rgb_range(object(), static_cast<uint32_t>(output->rgbRange())); changed = true; } - if (output->priority() != m_index) { + if (output->priority() != m_priority) { changed = true; } // always send all outputs @@ -413,6 +455,18 @@ wlConfig->set_auto_brightness(object(), output->automaticBrightness() ? 1 : 0); changed = true; } + if (version >= KDE_OUTPUT_CONFIGURATION_V2_SET_HDR_ICC_PROFILE_PATH_SINCE_VERSION && m_hdrIccProfilePath != output->hdrIccProfilePath()) { + wlConfig->set_hdr_icc_profile_path(object(), output->hdrIccProfilePath()); + changed = true; + } + if (version >= KDE_OUTPUT_CONFIGURATION_V2_SET_HDR_COLOR_PROFILE_SOURCE_SINCE_VERSION + && m_hdrColorProfileSource != uint32_t(output->hdrColorProfileSource())) { + wlConfig->set_hdr_color_profile_source(object(), uint32_t(output->hdrColorProfileSource())); + } + if (version >= KDE_OUTPUT_CONFIGURATION_V2_SET_ABM_LEVEL_SINCE_VERSION && m_abmLevel != output->abmLevel()) { + wlConfig->set_abm_level(object(), output->abmLevel()); + changed = true; + } return changed; } @@ -434,11 +488,6 @@ return dbg; } -uint32_t WaylandOutputDevice::index() const -{ - return m_index; -} - void WaylandOutputDevice::kde_output_device_v2_done() { Q_EMIT done(); @@ -616,7 +665,7 @@ void WaylandOutputDevice::kde_output_device_v2_priority(uint32_t priority) { - m_index = priority; + m_priority = priority; } void WaylandOutputDevice::kde_output_device_v2_auto_brightness(uint32_t enabled) @@ -624,6 +673,26 @@ m_autoBrightness = enabled; } +void WaylandOutputDevice::kde_output_device_v2_removed() +{ + Q_EMIT removed(); +} + +void WaylandOutputDevice::kde_output_device_v2_hdr_icc_profile_path(const QString &profile_path) +{ + m_hdrIccProfilePath = profile_path; +} + +void WaylandOutputDevice::kde_output_device_v2_hdr_color_profile_source(uint32_t source) +{ + m_hdrColorProfileSource = source; +} + +void WaylandOutputDevice::kde_output_device_v2_abm_level(uint32_t level) +{ + m_abmLevel = level; +} + QByteArray WaylandOutputDevice::edid() const { return m_edid; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/backends/kwayland/waylandoutputdevice.h new/libkscreen-6.7.0/backends/kwayland/waylandoutputdevice.h --- old/libkscreen-6.6.5/backends/kwayland/waylandoutputdevice.h 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/backends/kwayland/waylandoutputdevice.h 2026-06-11 11:34:04.000000000 +0200 @@ -15,19 +15,39 @@ #include <QPoint> #include <QSize> +#include <QWaylandClientExtension> namespace KScreen { class WaylandOutputConfiguration; +class WaylandOutputDevice; class WaylandOutputManagement; -class WaylandOutputDevice : public QObject, public QtWayland::kde_output_device_v2 +class WaylandOutputDeviceRegistry : public QWaylandClientExtensionTemplate<WaylandOutputDeviceRegistry>, public QtWayland::kde_output_device_registry_v2 { Q_OBJECT public: - WaylandOutputDevice(int id); + WaylandOutputDeviceRegistry(); + ~WaylandOutputDeviceRegistry() override; + +Q_SIGNALS: + void outputAdded(WaylandOutputDevice *outputDevice); + void outputRemoved(WaylandOutputDevice *outputDevice); +protected: + void kde_output_device_registry_v2_output(struct ::kde_output_device_v2 *output) override; + +private: + std::vector<std::unique_ptr<WaylandOutputDevice>> m_outputDevices; +}; + +class WaylandOutputDevice : public QObject, public QtWayland::kde_output_device_v2 +{ + Q_OBJECT + +public: + explicit WaylandOutputDevice(::kde_output_device_v2 *outputDevice); ~WaylandOutputDevice(); QByteArray edid() const; @@ -49,7 +69,6 @@ void updateKScreenOutput(OutputPtr &output, const QMap<int, WaylandOutputDevice *> &outputMap); void updateKScreenModes(OutputPtr &output); - uint32_t index() const; bool setWlConfig(WaylandOutputManagement *management, WaylandOutputConfiguration *wlConfig, const KScreen::OutputPtr &output, @@ -63,6 +82,7 @@ Q_SIGNALS: void done(); + void removed(); protected: void kde_output_device_v2_geometry(int32_t x, @@ -108,6 +128,10 @@ void kde_output_device_v2_sharpness(uint32_t sharpness) override; void kde_output_device_v2_priority(uint32_t priority) override; void kde_output_device_v2_auto_brightness(uint32_t enabled) override; + void kde_output_device_v2_removed() override; + void kde_output_device_v2_hdr_icc_profile_path(const QString &profile_path) override; + void kde_output_device_v2_hdr_color_profile_source(uint32_t source) override; + void kde_output_device_v2_abm_level(uint32_t level) override; private: QString modeName(const WaylandOutputDeviceMode *m) const; @@ -134,7 +158,7 @@ uint32_t m_overscan; uint32_t m_vrr_policy; uint32_t m_rgbRange; - uint32_t m_index; + uint32_t m_priority; bool m_hdrEnabled = false; uint32_t m_sdrBrightness = 200; bool m_wideColorGamutEnabled = false; @@ -163,6 +187,9 @@ uint32_t m_sharpness = 0; QList<ModeInfo> m_customModes; bool m_autoBrightness = false; + QString m_hdrIccProfilePath; + uint32_t m_hdrColorProfileSource = color_profile_source_EDID; + uint32_t m_abmLevel = 0; }; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/poqm/lt/libkscreen6_qt.po new/libkscreen-6.7.0/poqm/lt/libkscreen6_qt.po --- old/libkscreen-6.6.5/poqm/lt/libkscreen6_qt.po 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/poqm/lt/libkscreen6_qt.po 2026-06-11 11:34:04.000000000 +0200 @@ -1,42 +1,45 @@ msgid "" msgstr "" "Project-Id-Version: trunk-kf 5\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: lt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Qt-Contexts: true\n" "Plural-Forms: nplurals=4; plural=(n==1 ? 0 : n%10>=2 && (n%100<10 || n" "%100>=20) ? 1 : n%10==0 || (n%100>10 && n%100<20) ? 2 : 3);\n" +"X-Qt-Contexts: true\n" +"X-Generator: Poedit 3.8\n" #: getconfigoperation.cpp:62 msgctxt "KScreen::GetConfigOperationPrivate|" msgid "Failed to prepare backend" -msgstr "" +msgstr "Nepavyko paruošti vidinės pusės" #: getconfigoperation.cpp:87 msgctxt "KScreen::GetConfigOperationPrivate|" msgid "Failed to deserialize backend response" -msgstr "" +msgstr "Nepavyko išnuoseklinti vidinės pusės atsako" #: getconfigoperation.cpp:99 msgctxt "KScreen::GetConfigOperationPrivate|" msgid "Backend invalidated" -msgstr "" +msgstr "Vidinė pusė padaryta negaliojančia" #: setconfigoperation.cpp:59 msgctxt "KScreen::SetConfigOperationPrivate|" msgid "Failed to prepare backend" -msgstr "" +msgstr "Nepavyko paruošti vidinės pusės" #: setconfigoperation.cpp:66 msgctxt "KScreen::SetConfigOperationPrivate|" msgid "Failed to serialize request" -msgstr "" +msgstr "Nepavyko nuoseklinti užklausos" #: setconfigoperation.cpp:90 msgctxt "KScreen::SetConfigOperationPrivate|" msgid "Failed to deserialize backend response" -msgstr "" +msgstr "Nepavyko išnuoseklinti vidinės pusės atsako" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/poqm/nb/libkscreen6_qt.po new/libkscreen-6.7.0/poqm/nb/libkscreen6_qt.po --- old/libkscreen-6.6.5/poqm/nb/libkscreen6_qt.po 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/poqm/nb/libkscreen6_qt.po 2026-06-11 11:34:04.000000000 +0200 @@ -5,7 +5,7 @@ "Project-Id-Version: \n" "PO-Revision-Date: 2025-03-23 18:52+0100\n" "Last-Translator: Martin Hansen <[email protected]>\n" -"Language-Team: Norwegian Bokmål <[email protected]>\n" +"Language-Team: Norwegian Bokmål <[email protected]>\n" "Language: nb\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/poqm/nn/libkscreen6_qt.po new/libkscreen-6.7.0/poqm/nn/libkscreen6_qt.po --- old/libkscreen-6.6.5/poqm/nn/libkscreen6_qt.po 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/poqm/nn/libkscreen6_qt.po 2026-06-11 11:34:04.000000000 +0200 @@ -6,7 +6,7 @@ "Project-Id-Version: \n" "PO-Revision-Date: 2023-03-05 12:32+0100\n" "Last-Translator: Karl Ove Hufthammer <[email protected]>\n" -"Language-Team: Norwegian Nynorsk <[email protected]>\n" +"Language-Team: Norwegian Nynorsk <[email protected]>\n" "Language: nn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/poqm/sv/libkscreen6_qt.po new/libkscreen-6.7.0/poqm/sv/libkscreen6_qt.po --- old/libkscreen-6.6.5/poqm/sv/libkscreen6_qt.po 1970-01-01 01:00:00.000000000 +0100 +++ new/libkscreen-6.7.0/poqm/sv/libkscreen6_qt.po 2026-06-11 11:34:04.000000000 +0200 @@ -0,0 +1,44 @@ +# SPDX-FileCopyrightText: 2024 Stefan Asserhäll <[email protected]> +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2024-06-21 14:34+0200\n" +"Last-Translator: Stefan Asserhäll <[email protected]>\n" +"Language-Team: Swedish <[email protected]>\n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Qt-Contexts: true\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 23.08.5\n" + +#: getconfigoperation.cpp:62 +msgctxt "KScreen::GetConfigOperationPrivate|" +msgid "Failed to prepare backend" +msgstr "Misslyckades förbereda gränssnitt" + +#: getconfigoperation.cpp:87 +msgctxt "KScreen::GetConfigOperationPrivate|" +msgid "Failed to deserialize backend response" +msgstr "Misslyckades deserialisera gränssnittssvar" + +#: getconfigoperation.cpp:99 +msgctxt "KScreen::GetConfigOperationPrivate|" +msgid "Backend invalidated" +msgstr "Gränssnitt ogiltigförklarat" + +#: setconfigoperation.cpp:59 +msgctxt "KScreen::SetConfigOperationPrivate|" +msgid "Failed to prepare backend" +msgstr "Misslyckades förbereda gränssnitt" + +#: setconfigoperation.cpp:66 +msgctxt "KScreen::SetConfigOperationPrivate|" +msgid "Failed to serialize request" +msgstr "Misslyckades serialisera begäran" + +#: setconfigoperation.cpp:90 +msgctxt "KScreen::SetConfigOperationPrivate|" +msgid "Failed to deserialize backend response" +msgstr "Misslyckades deserialisera gränssnittssvar" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/src/doctor/doctor.cpp new/libkscreen-6.7.0/src/doctor/doctor.cpp --- old/libkscreen-6.6.5/src/doctor/doctor.cpp 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/src/doctor/doctor.cpp 2026-06-11 11:34:04.000000000 +0200 @@ -10,6 +10,8 @@ #include <QCollator> #include <QCoreApplication> +#include <QDBusConnection> +#include <QDBusMessage> #include <QDateTime> #include <QFile> #include <QGuiApplication> @@ -210,7 +212,29 @@ if (ops.count() > 2) { bool ok; if (ops[0] == QLatin1String("output")) { - OutputPtr output = findOutput(ops[1]); + QString outputQuery = ops[1]; + + // handle "activeOutput" as an ID to operate on the current active display + if (outputQuery == QLatin1String("activeOutput")) { + QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"), + QStringLiteral("/KWin"), + QStringLiteral("org.kde.KWin"), + QStringLiteral("activeOutputName")); + + auto reply = QDBusConnection::sessionBus().call(message); + if (reply.type() == QDBusMessage::ErrorMessage) { + qCWarning(KSCREEN_DOCTOR) << "DBus error from KWin:" << reply.errorName() << reply.errorMessage(); + return; + } + auto args = reply.arguments(); + if (args.isEmpty()) { + qCWarning(KSCREEN_DOCTOR) << "activeOutputName returned no arguments"; + return; + } + outputQuery = args.first().toString(); + } + + OutputPtr output = findOutput(outputQuery); if (!output) { qApp->exit(3); return; @@ -367,17 +391,37 @@ qApp->exit(9); return; } + } else if (ops.count() == 4 && subcmd == "hdrAndWcg") { + const QString _enable = ops[3].toLower(); + if (_enable == "enable") { + setHdrEnabled(output, true); + setWcgEnabled(output, true); + } else if (_enable == "disable") { + setHdrEnabled(output, false); + setWcgEnabled(output, false); + } else if (_enable == "toggle") { + // HDR and Wcg couple should be in the same state, so we base the Wcg value on HDR's value + bool isHdrEnabled = output->isHdrEnabled(); + setHdrEnabled(output, !isHdrEnabled); + setWcgEnabled(output, !isHdrEnabled); + } else { + qCWarning(KSCREEN_DOCTOR) << "Wrong input: Only allowed values for hdrAndWcg are \"enable\", \"disable\" and \"toggle\""; + qApp->exit(9); + return; + } } else if (ops.count() >= 4 && subcmd == "iccprofile") { QString profilePath = ops[3]; for (uint32_t i = 4; i < ops.size(); i++) { profilePath += "." + ops[i]; } output->setIccProfilePath(profilePath); - if (profilePath.isEmpty()) { - output->setColorProfileSource(Output::ColorProfileSource::sRGB); - } else { - output->setColorProfileSource(Output::ColorProfileSource::ICC); + m_changed = true; + } else if (ops.count() >= 4 && subcmd == "hdrIccProfile") { + QString profilePath = ops[3]; + for (uint32_t i = 4; i < ops.size(); i++) { + profilePath += "." + ops[i]; } + output->setHdrIccProfilePath(profilePath); m_changed = true; } else if (ops.count() >= 4 && subcmd == "sdrGamut") { const uint32_t wideness = ops[3].toUInt(); @@ -435,6 +479,17 @@ return; } m_changed = true; + } else if (ops.count() >= 4 && subcmd == "hdrColorProfileSource") { + if (ops[3] == "ICC") { + output->setHdrColorProfileSource(Output::ColorProfileSource::ICC); + } else if (ops[3] == "EDID") { + output->setHdrColorProfileSource(Output::ColorProfileSource::EDID); + } else { + qCWarning(KSCREEN_DOCTOR) << "Wrong input: only allowed values for hdrColorProfileSource are \"ICC\" and \"EDID\""; + qApp->exit(9); + return; + } + m_changed = true; } else if (ops.count() >= 4 && subcmd == "brightness") { const uint32_t brightness = ops[3].toUInt(); if (brightness > 100) { @@ -564,6 +619,28 @@ return; } m_changed = true; + } else if (ops.count() == 4 && subcmd == "autoRotatePolicy") { + if (ops[3] == "never") { + setAutoRotatePolicy(output, KScreen::Output::AutoRotatePolicy::Never); + } else if (ops[3] == "inTabletMode") { + setAutoRotatePolicy(output, KScreen::Output::AutoRotatePolicy::InTabletMode); + } else if (ops[3] == "always") { + setAutoRotatePolicy(output, KScreen::Output::AutoRotatePolicy::Always); + } else { + qCWarning(KSCREEN_DOCTOR) << "Invalid input: Only 'never', 'inTabletMode', and 'always' are allowed"; + qApp->exit(9); + return; + } + } else if (ops.count() >= 4 && subcmd == "abm") { + bool ok = false; + const uint32_t level = ops[3].toUInt(&ok); + if (level >= 5 || !ok) { + qCWarning(KSCREEN_DOCTOR) << "Invalid input: Allowed values for abm level are 0, 1, 2, 3, 4"; + qApp->exit(9); + return; + } + output->setAbmLevel(level); + m_changed = true; } else { cerr << "Unable to parse arguments: " << op << Qt::endl; qApp->exit(2); @@ -733,6 +810,32 @@ cout << yellow << ", overridden with: " << cr << (*used) / 10'000.0 << " nits"; } cout << endl; + + cout << yellow << "\t\tHDR color profile source: "; + if (output->capabilities() & Output::Capability::HdrIccProfile) { + cout << cr; + switch (output->hdrColorProfileSource()) { + case Output::ColorProfileSource::sRGB: + cout << "sRGB"; + break; + case Output::ColorProfileSource::ICC: + cout << "ICC"; + break; + case Output::ColorProfileSource::EDID: + cout << "EDID"; + break; + } + cout << endl; + + cout << yellow << "\t\tHDR ICC profile: "; + if (!output->hdrIccProfilePath().isEmpty()) { + cout << cr << output->hdrIccProfilePath() << endl; + } else { + cout << cr << "none" << endl; + } + } else { + cout << cr << "incapable" << endl; + } } else { cout << cr << "disabled" << endl; } @@ -846,6 +949,28 @@ } else { cout << cr << "unsupported" << endl; } + cout << yellow << "\tAuto Rotate Policy: "; + if (output->capabilities() & Output::Capability::AutoRotation) { + switch (output->autoRotatePolicy()) { + case Output::AutoRotatePolicy::Never: + cout << cr << "never" << endl; + break; + case Output::AutoRotatePolicy::InTabletMode: + cout << cr << "inTabletMode" << endl; + break; + case Output::AutoRotatePolicy::Always: + cout << cr << "always" << endl; + } + } else { + cout << cr << "incapable" << endl; + } + + cout << yellow << "\tAdaptive backlight modulation: "; + if (output->capabilities() & Output::Capability::AbmLevel) { + cout << cr << "supported, set to " << output->abmLevel() << endl; + } else { + cout << cr << "unsupported" << endl; + } } } @@ -954,6 +1079,12 @@ m_changed = true; } +void Doctor::setAutoRotatePolicy(OutputPtr output, KScreen::Output::AutoRotatePolicy policy) +{ + output->setAutoRotatePolicy(policy); + m_changed = true; +} + std::expected<void, QString> Doctor::applyConfig() { if (!m_changed) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/src/doctor/doctor.h new/libkscreen-6.7.0/src/doctor/doctor.h --- old/libkscreen-6.6.5/src/doctor/doctor.h 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/src/doctor/doctor.h 2026-06-11 11:34:04.000000000 +0200 @@ -49,6 +49,7 @@ void setHdrEnabled(OutputPtr output, bool enable); void setSdrBrightness(OutputPtr output, uint32_t brightness); void setWcgEnabled(OutputPtr output, bool enable); + void setAutoRotatePolicy(OutputPtr output, KScreen::Output::AutoRotatePolicy policy); Q_SIGNALS: void outputsChanged(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/src/doctor/main.cpp new/libkscreen-6.7.0/src/doctor/main.cpp --- old/libkscreen-6.6.5/src/doctor/main.cpp 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/src/doctor/main.cpp 2026-06-11 11:34:04.000000000 +0200 @@ -55,13 +55,21 @@ " $ kscreen-doctor output.HDMI-2.hdr.enable\n" "\n Set SDR brightness (possible values: 100-1000)\n" " $ kscreen-doctor output.HDMI-2.sdr-brightness.300\n" + "\n Toggle HDR and wide color gamut for the current active display\n" + " $ kscreen-doctor output.activeOutput.hdrAndWcg.toggle\n" "\n Set brightness on non HDR screens (possible values: 0-100)\n" " $ kscreen-doctor output.HDMI-2.brightness.10\n" "\n Set wide color gamut mode (possible values: enable, disable)\n" " $ kscreen-doctor output.HDMI-2.wcg.enable\n" - "\n Set ICC profile path\n" - " $ kscreen-doctor output.HDMI-2.iccprofile.\"/path/to/profile.icc\"\n\n" - " Show dpms information:\n" + "\n Set ICC profile path for SDR mode\n" + " $ kscreen-doctor output.HDMI-2.iccprofile.\"/path/to/profile.icc\"\n" + "\n Set color profile source for SDR mode (possible values: sRGB, ICC, EDID)\n" + " $ kscreen-doctor output.HDMI-2.colorProfileSource.ICC\n" + "\n Set ICC profile path for HDR mode\n" + " $ kscreen-doctor output.HDMI-2.hdrIccProfile.\"/path/to/profile.icc\"\n" + "\n Set color profile source for HDR mode (possible values: ICC, EDID)\n" + " $ kscreen-doctor output.HDMI-2.hdrColorProfileSource.ICC\n" + "\n Show dpms information:\n" " $ kscreen-doctor --dpms show\n\n" " Set dpms mode: (possible values: on, off)\n" " $ kscreen-doctor --dpms on\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/src/libdpms/CMakeLists.txt new/libkscreen-6.7.0/src/libdpms/CMakeLists.txt --- old/libkscreen-6.6.5/src/libdpms/CMakeLists.txt 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/src/libdpms/CMakeLists.txt 2026-06-11 11:34:04.000000000 +0200 @@ -8,11 +8,8 @@ Qt::GuiPrivate Qt::WaylandClient Wayland::Client ) -if (Qt6_VERSION VERSION_GREATER_EQUAL "6.8.0") - set(private_code_option "PRIVATE_CODE") -endif() qt6_generate_wayland_protocol_client_sources(KF6ScreenDpms - ${private_code_option} + PRIVATE_CODE FILES ${PLASMA_WAYLAND_PROTOCOLS_DIR}/dpms.xml ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/src/output.cpp new/libkscreen-6.7.0/src/output.cpp --- old/libkscreen-6.6.5/src/output.cpp 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/src/output.cpp 2026-06-11 11:34:04.000000000 +0200 @@ -69,6 +69,7 @@ , wideColorGamut(other.wideColorGamut) , autoRotatePolicy(other.autoRotatePolicy) , iccProfilePath(other.iccProfilePath) + , hdrIccProfilePath(other.hdrIccProfilePath) , sdrGamutWideness(other.sdrGamutWideness) , maxPeakBrightness(other.maxPeakBrightness) , maxAverageBrightness(other.maxAverageBrightness) @@ -77,6 +78,7 @@ , maxAverageBrightnessOverride(other.maxAverageBrightnessOverride) , minBrightnessOverride(other.minBrightnessOverride) , colorProfileSource(other.colorProfileSource) + , hdrColorProfileSource(other.hdrColorProfileSource) , brightness(other.brightness) , colorPowerPreference(other.colorPowerPreference) , dimming(other.dimming) @@ -89,6 +91,7 @@ , sharpness(other.sharpness) , customModes(other.customModes) , automaticBrightness(other.automaticBrightness) + , abmLevel(other.abmLevel) { const auto otherModeList = other.modeList; for (const ModePtr &otherMode : otherModeList) { @@ -137,6 +140,7 @@ bool wideColorGamut = false; AutoRotatePolicy autoRotatePolicy = AutoRotatePolicy::InTabletMode; QString iccProfilePath; + QString hdrIccProfilePath; double sdrGamutWideness = 0; double maxPeakBrightness = 0; double maxAverageBrightness = 0; @@ -145,6 +149,7 @@ std::optional<double> maxAverageBrightnessOverride; std::optional<double> minBrightnessOverride; ColorProfileSource colorProfileSource = ColorProfileSource::sRGB; + ColorProfileSource hdrColorProfileSource = ColorProfileSource::sRGB; double brightness = 1.0; ColorPowerTradeoff colorPowerPreference = ColorPowerTradeoff::PreferEfficiency; double dimming = 1.0; @@ -157,6 +162,7 @@ double sharpness = 0; QList<ModeInfo> customModes; bool automaticBrightness = false; + uint32_t abmLevel = 0; }; bool Output::Private::compareModeList(const ModeList &before, const ModeList &after) @@ -809,6 +815,19 @@ } } +QString Output::hdrIccProfilePath() const +{ + return d->hdrIccProfilePath; +} + +void Output::setHdrIccProfilePath(const QString &path) +{ + if (d->hdrIccProfilePath != path) { + d->hdrIccProfilePath = path; + Q_EMIT hdrIccProfilePathChanged(); + } +} + double Output::sdrGamutWideness() const { return d->sdrGamutWideness; @@ -913,6 +932,19 @@ } } +Output::ColorProfileSource Output::hdrColorProfileSource() const +{ + return d->hdrColorProfileSource; +} + +void Output::setHdrColorProfileSource(ColorProfileSource source) +{ + if (d->hdrColorProfileSource != source) { + d->hdrColorProfileSource = source; + Q_EMIT hdrColorProfileSourceChanged(); + } +} + double Output::brightness() const { return d->brightness; @@ -1069,6 +1101,19 @@ } } +uint32_t Output::abmLevel() const +{ + return d->abmLevel; +} + +void Output::setAbmLevel(uint32_t level) +{ + if (d->abmLevel != level) { + d->abmLevel = level; + Q_EMIT abmLevelChanged(); + } +} + void Output::apply(const OutputPtr &other) { typedef void (KScreen::Output::*ChangeSignal)(); @@ -1250,6 +1295,18 @@ changes << &Output::automaticBrightnessChanged; setAutomaticBrightness(other->d->automaticBrightness); } + if (d->hdrIccProfilePath != other->d->hdrIccProfilePath) { + changes << &Output::hdrIccProfilePathChanged; + setHdrIccProfilePath(other->d->hdrIccProfilePath); + } + if (d->hdrColorProfileSource != other->d->hdrColorProfileSource) { + changes << &Output::hdrColorProfileSourceChanged; + setHdrColorProfileSource(other->d->hdrColorProfileSource); + } + if (d->abmLevel != other->d->abmLevel) { + changes << &Output::abmLevelChanged; + setAbmLevel(other->d->abmLevel); + } // Non-notifyable changes if (other->d->edid) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/src/output.h new/libkscreen-6.7.0/src/output.h --- old/libkscreen-6.6.5/src/output.h 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/src/output.h 2026-06-11 11:34:04.000000000 +0200 @@ -130,6 +130,8 @@ SharpnessControl = 1 << 12, CustomModes = 1 << 13, AutomaticBrightness = 1 << 14, + HdrIccProfile = 1 << 15, + AbmLevel = 1 << 16, }; Q_ENUM(Capability) Q_DECLARE_FLAGS(Capabilities, Capability) @@ -544,6 +546,9 @@ */ void setIccProfilePath(const QString &path); + QString hdrIccProfilePath() const; + void setHdrIccProfilePath(const QString &path); + double sdrGamutWideness() const; void setSdrGamutWideness(double value); @@ -568,6 +573,9 @@ ColorProfileSource colorProfileSource() const; void setColorProfileSource(ColorProfileSource source); + ColorProfileSource hdrColorProfileSource() const; + void setHdrColorProfileSource(ColorProfileSource source); + double brightness() const; void setBrightness(double brightness); @@ -610,6 +618,9 @@ bool automaticBrightness() const; void setAutomaticBrightness(bool enable); + uint32_t abmLevel() const; + void setAbmLevel(uint32_t level); + void apply(const OutputPtr &other); Q_SIGNALS: @@ -643,6 +654,7 @@ void maxAverageBrightnessOverrideChanged(); void minBrightnessOverrideChanged(); void colorProfileSourceChanged(); + void hdrColorProfileSourceChanged(); void brightnessChanged(); void vendorChanged(); void modelChanged(); @@ -655,6 +667,8 @@ void sharpnessChanged(); void customModesChanged(); void automaticBrightnessChanged(); + void hdrIccProfilePathChanged(); + void abmLevelChanged(); /** The mode list changed. * diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkscreen-6.6.5/src/setconfigoperation.cpp new/libkscreen-6.7.0/src/setconfigoperation.cpp --- old/libkscreen-6.6.5/src/setconfigoperation.cpp 2026-05-12 12:27:47.000000000 +0200 +++ new/libkscreen-6.7.0/src/setconfigoperation.cpp 2026-06-11 11:34:04.000000000 +0200 @@ -134,7 +134,7 @@ void SetConfigOperationPrivate::normalizeOutputPositions() { - if (!config) { + if (!config || (config->supportedFeatures() & Config::Feature::PerOutputScaling)) { return; } int offsetX = INT_MAX;
