Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libkscreen2 for openSUSE:Factory 
checked in at 2022-02-07 23:37:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libkscreen2 (Old)
 and      /work/SRC/openSUSE:Factory/.libkscreen2.new.1898 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libkscreen2"

Mon Feb  7 23:37:04 2022 rev:133 rq:951886 version:5.24.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/libkscreen2/libkscreen2.changes  2022-01-11 
21:14:25.788754576 +0100
+++ /work/SRC/openSUSE:Factory/.libkscreen2.new.1898/libkscreen2.changes        
2022-02-07 23:37:21.762739534 +0100
@@ -1,0 +2,37 @@
+Sat Feb  5 19:50:59 UTC 2022 - Fabian Vogt <fab...@ritter-vogt.de>
+
+- Update to 5.24.0
+  * New bugfix release
+  * For more details please see:
+  * https://kde.org/announcements/plasma/5/5.24.0
+- Changes since 5.23.90:
+  * backends/kwayland: Use output name to guess output type
+  * Update required PlasmaWaylandProtocols version
+
+-------------------------------------------------------------------
+Thu Jan 13 20:30:22 UTC 2022 - Fabian Vogt <fab...@ritter-vogt.de>
+
+- Update to 5.23.90
+  * New feature release
+  * For more details please see:
+  * https://kde.org/announcements/plasma/5/5.23.90
+- Changes since 5.23.5:
+  * GetConfiguration: ensure to set explicitLogicalSize for returned outputs
+  * Add KScreen::Config::Feature::SynchronousOutputChanges
+  * Wayland: Wait for KWin reply before returning from setConfig
+  * Fix some clazy warnings
+  * Under X11 ignore per-screen scale to compute logicalSize
+  * Enable GitLab CI
+  * Add KScreen::Output::typeName
+  * wayland: Issue a configChanged when the primary changes
+  * Do not issue SetConfigOperations with bogus primary states
+  * Fix using correct log level by using systemd unit (kde#444084)
+  * wayland: Properly choose interface versions
+  * Implement Primary Displays on the wayland session
+  * Add support to primary into the kscreen-doctor tool
+  * XrandR: Fix impossibilty to change resolution in VirtualBox (kde#407058)
+  * Fix autorotate when "only in tablet mode" is selected (kde#428626)
+  * Add .kde-ci.yml
+  * fix all the new settings (kde#442520)
+
+-------------------------------------------------------------------

Old:
----
  libkscreen-5.23.5.tar.xz
  libkscreen-5.23.5.tar.xz.sig

New:
----
  libkscreen-5.24.0.tar.xz
  libkscreen-5.24.0.tar.xz.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libkscreen2.spec ++++++
--- /var/tmp/diff_new_pack.PLoYtj/_old  2022-02-07 23:37:22.386735334 +0100
+++ /var/tmp/diff_new_pack.PLoYtj/_new  2022-02-07 23:37:22.390735306 +0100
@@ -16,10 +16,10 @@
 #
 
 
-%bcond_without lang
+%bcond_without released
 %define lname   libKF5Screen7
 Name:           libkscreen2
-Version:        5.23.5
+Version:        5.24.0
 Release:        0
 # Full Plasma 5 version (e.g. 5.8.95)
 %{!?_plasma5_bugfix: %define _plasma5_bugfix %{version}}
@@ -29,9 +29,9 @@
 License:        GPL-2.0-or-later
 Group:          System/GUI/KDE
 URL:            http://www.kde.org
-Source:         
https://download.kde.org/stable/plasma/%{version}/libkscreen-%{version}.tar.xz
-%if %{with lang}
-Source1:        
https://download.kde.org/stable/plasma/%{version}/libkscreen-%{version}.tar.xz.sig
+Source:         libkscreen-%{version}.tar.xz
+%if %{with released}
+Source1:        libkscreen-%{version}.tar.xz.sig
 Source2:        plasma.keyring
 %endif
 BuildRequires:  cmake >= 3.16
@@ -92,6 +92,15 @@
 
 %postun -n %{lname} -p /sbin/ldconfig
 
+%post plugin
+%{systemd_user_post plasma-kscreen.service}
+
+%preun plugin
+%{systemd_user_preun plasma-kscreen.service}
+
+%postun plugin
+%{systemd_user_postun plasma-kscreen.service}
+
 %files plugin
 %license LICENSES/*
 %{_kf5_bindir}/kscreen-doctor
@@ -99,6 +108,7 @@
 %{_kf5_libexecdir}/
 %{_kf5_sharedir}/dbus-1/services/org.kde.kscreen.service
 %{_kf5_debugdir}/libkscreen.categories
+%{_userunitdir}/plasma-kscreen.service
 
 %files -n %{lname}
 %license LICENSES/*

++++++ libkscreen-5.23.5.tar.xz -> libkscreen-5.24.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/.arcconfig 
new/libkscreen-5.24.0/.arcconfig
--- old/libkscreen-5.23.5/.arcconfig    2022-01-04 10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/.arcconfig    1970-01-01 01:00:00.000000000 +0100
@@ -1,4 +0,0 @@
-{
-  "phabricator.uri" : "https://phabricator.kde.org/";
-}
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/.gitlab-ci.yml 
new/libkscreen-5.24.0/.gitlab-ci.yml
--- old/libkscreen-5.23.5/.gitlab-ci.yml        1970-01-01 01:00:00.000000000 
+0100
+++ new/libkscreen-5.24.0/.gitlab-ci.yml        2022-02-03 15:36:03.000000000 
+0100
@@ -0,0 +1,6 @@
+# SPDX-FileCopyrightText: None
+# SPDX-License-Identifier: CC0-1.0
+
+include:
+  - 
https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
+  - 
https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/.kde-ci.yml 
new/libkscreen-5.24.0/.kde-ci.yml
--- old/libkscreen-5.23.5/.kde-ci.yml   1970-01-01 01:00:00.000000000 +0100
+++ new/libkscreen-5.24.0/.kde-ci.yml   2022-02-03 15:36:03.000000000 +0100
@@ -0,0 +1,9 @@
+# SPDX-FileCopyrightText: None
+# SPDX-License-Identifier: CC0-1.0
+
+Dependencies:
+- 'on': ['@all']
+  'require':
+    'frameworks/extra-cmake-modules': '@latest'
+    'frameworks/kwayland': '@latest'
+    'plasma/kwayland-server': '@same'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/CMakeLists.txt 
new/libkscreen-5.24.0/CMakeLists.txt
--- old/libkscreen-5.23.5/CMakeLists.txt        2022-01-04 10:00:26.000000000 
+0100
+++ new/libkscreen-5.24.0/CMakeLists.txt        2022-02-03 15:36:03.000000000 
+0100
@@ -1,7 +1,7 @@
 cmake_minimum_required(VERSION 3.16)
 
 project(libkscreen)
-set(PROJECT_VERSION "5.23.5")
+set(PROJECT_VERSION "5.24.0")
 
 set(QT_MIN_VERSION "5.15.0")
 set(KF5_MIN_VERSION "5.86")
@@ -34,7 +34,7 @@
 find_package(KF5Wayland ${KF5_MIN_VERSION} CONFIG REQUIRED)
 add_feature_info("KF5Wayland" KF5Wayland_FOUND "Required for building 
libkscreen's KWayland backend")
 
-find_package(PlasmaWaylandProtocols 1.4.0 CONFIG)
+find_package(PlasmaWaylandProtocols 1.6.0 CONFIG)
 set_package_properties(PlasmaWaylandProtocols PROPERTIES TYPE REQUIRED)
 
 # Wayland backend
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/CMakePresets.json 
new/libkscreen-5.24.0/CMakePresets.json
--- old/libkscreen-5.23.5/CMakePresets.json     2022-01-04 10:00:26.000000000 
+0100
+++ new/libkscreen-5.24.0/CMakePresets.json     2022-02-03 15:36:03.000000000 
+0100
@@ -12,6 +12,17 @@
             }
         },
         {
+            "name": "dev-disable-deprecated",
+            "displayName": "Build as without deprecated methods",
+            "generator": "Ninja",
+            "binaryDir": "${sourceDir}/build-disable-deprecated",
+            "cacheVariables": {
+                "CMAKE_BUILD_TYPE": "Debug",
+                "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
+               "CMAKE_CXX_FLAGS_INIT": 
"-DQT_DISABLE_DEPRECATED_BEFORE=0x060000 
-DKF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x060000"
+            }
+        },
+        {
             "name": "asan",
             "displayName": "Build with Asan support.",
             "generator": "Ninja",
@@ -29,7 +40,7 @@
             "binaryDir": "${sourceDir}/build-unity",
             "cacheVariables": {
                 "CMAKE_BUILD_TYPE": "Debug",
-               "USE_UNITY_CMAKE_SUPPORT": "ON",
+               "CMAKE_UNITY_BUILD": "ON",
                "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
             }
         },
@@ -72,6 +83,18 @@
             "configurePreset": "dev"
         },
         {
+            "name": "asan",
+            "configurePreset": "asan"
+        },
+       {
+            "name": "dev-disable-deprecated",
+            "configurePreset": "dev-disable-deprecated"
+        },
+       {
+            "name": "unity",
+            "configurePreset": "unity"
+        },
+        {
             "name": "clazy",
             "configurePreset": "clazy",
             "environment": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/backends/fake/CMakeLists.txt 
new/libkscreen-5.24.0/backends/fake/CMakeLists.txt
--- old/libkscreen-5.23.5/backends/fake/CMakeLists.txt  2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/fake/CMakeLists.txt  2022-02-03 
15:36:03.000000000 +0100
@@ -6,6 +6,8 @@
 set(fake_SRCS
     fake.cpp
     parser.cpp
+    fake.h
+    parser.h
 )
 
 qt_add_dbus_adaptor(fake_SRCS 
${CMAKE_SOURCE_DIR}/interfaces/org.kde.KScreen.FakeBackend.xml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/backends/kwayland/CMakeLists.txt 
new/libkscreen-5.24.0/backends/kwayland/CMakeLists.txt
--- old/libkscreen-5.23.5/backends/kwayland/CMakeLists.txt      2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/kwayland/CMakeLists.txt      2022-02-03 
15:36:03.000000000 +0100
@@ -26,6 +26,10 @@
     BASENAME kde-output-management-v2
 )
 
+ecm_add_qtwayland_client_protocol(wayland_SRCS
+    PROTOCOL ${PLASMA_WAYLAND_PROTOCOLS_DIR}/kde-primary-output-v1.xml
+    BASENAME kde-primary-output-v1
+)
 
 add_library(KSC_KWayland MODULE ${wayland_SRCS})
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libkscreen-5.23.5/backends/kwayland/waylandbackend.cpp 
new/libkscreen-5.24.0/backends/kwayland/waylandbackend.cpp
--- old/libkscreen-5.23.5/backends/kwayland/waylandbackend.cpp  2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/kwayland/waylandbackend.cpp  2022-02-03 
15:36:03.000000000 +0100
@@ -53,7 +53,13 @@
     if (!newconfig) {
         return;
     }
+    // wait for KWin reply
+    QEventLoop loop;
+
+    connect(m_internalConfig, &WaylandConfig::configChanged, &loop, 
&QEventLoop::quit);
     m_internalConfig->applyConfig(newconfig);
+
+    loop.exec();
 }
 
 QByteArray WaylandBackend::edid(int outputId) const
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libkscreen-5.23.5/backends/kwayland/waylandconfig.cpp 
new/libkscreen-5.24.0/backends/kwayland/waylandconfig.cpp
--- old/libkscreen-5.23.5/backends/kwayland/waylandconfig.cpp   2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/kwayland/waylandconfig.cpp   2022-02-03 
15:36:03.000000000 +0100
@@ -121,10 +121,26 @@
 
     connect(m_registry, &KWayland::Client::Registry::interfaceAnnounced, this, 
[this](const QByteArray &interface, quint32 name, quint32 version) {
         if (interface == WaylandOutputDevice::interface()->name) {
-            addOutput(name, version);
+            addOutput(name, std::min(2u, version));
         }
         if (interface == WaylandOutputManagement::interface()->name) {
-            m_outputManagement = new 
WaylandOutputManagement(m_registry->registry(), name, version);
+            m_outputManagement = new 
WaylandOutputManagement(m_registry->registry(), name, std::min(2u, version));
+        }
+        if (interface == WaylandPrimaryOutput::interface()->name) {
+            m_primaryOutput.reset(new 
WaylandPrimaryOutput(m_registry->registry(), name, std::min(1u, version)));
+            connect(m_primaryOutput.data(), 
&WaylandPrimaryOutput::primaryOutputChanged, this, [this](const QString &name) {
+                if (m_primaryOutputName == name) {
+                    return;
+                }
+
+                m_primaryOutputName = name;
+                for (auto output : qAsConst(m_outputMap)) {
+                    output->setPrimary(output->outputName() == name);
+                }
+                if (!m_blockSignals) {
+                    Q_EMIT configChanged();
+                }
+            });
         }
     });
 
@@ -158,6 +174,7 @@
         QObject::disconnect(*connection);
         delete connection;
 
+        device->setPrimary(m_primaryOutputName == device->outputName());
         m_initializingOutputs.removeOne(device);
         m_outputMap.insert(device->id(), device);
         checkInitialized();
@@ -224,7 +241,8 @@
 {
     m_kscreenConfig->setScreen(m_screen->toKScreenScreen(m_kscreenConfig));
 
-    const auto features = Config::Feature::Writable | 
Config::Feature::PerOutputScaling | Config::Feature::AutoRotation | 
Config::Feature::TabletMode;
+    const auto features = Config::Feature::Writable | 
Config::Feature::PerOutputScaling | Config::Feature::AutoRotation | 
Config::Feature::TabletMode
+        | Config::Feature::PrimaryDisplay | 
Config::Feature::SynchronousOutputChanges;
     m_kscreenConfig->setSupportedFeatures(features);
     m_kscreenConfig->setValid(m_connection->display());
 
@@ -239,20 +257,15 @@
         }
     }
 
-    // Add KScreen::Outputs that aren't in the list yet, handle primaryOutput
+    // Add KScreen::Outputs that aren't in the list yet
     KScreen::OutputList kscreenOutputs = m_kscreenConfig->outputs();
     for (const auto &output : m_outputMap) {
-        KScreen::OutputPtr kscreenOutput = kscreenOutputs[output->id()];
+        KScreen::OutputPtr &kscreenOutput = kscreenOutputs[output->id()];
         if (!kscreenOutput) {
             kscreenOutput = output->toKScreenOutput();
-            kscreenOutputs.insert(kscreenOutput->id(), kscreenOutput);
-        }
-        if (kscreenOutput && m_outputMap.count() == 1) {
-            kscreenOutput->setPrimary(true);
-        } else if (m_outputMap.count() > 1) {
-            // primaryScreen concept doesn't exist in kwayland, so we don't 
set one
+        } else {
+            output->updateKScreenOutput(kscreenOutput);
         }
-        output->updateKScreenOutput(kscreenOutput);
     }
     m_kscreenConfig->setOutputs(kscreenOutputs);
 
@@ -276,6 +289,16 @@
     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;
+}
+
 void WaylandConfig::applyConfig(const KScreen::ConfigPtr &newConfig)
 {
     using namespace KWayland::Client;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/backends/kwayland/waylandconfig.h 
new/libkscreen-5.24.0/backends/kwayland/waylandconfig.h
--- old/libkscreen-5.23.5/backends/kwayland/waylandconfig.h     2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/kwayland/waylandconfig.h     2022-02-03 
15:36:03.000000000 +0100
@@ -15,6 +15,8 @@
 #include <QSize>
 #include <QSocketNotifier>
 
+struct kde_output_device_v2;
+
 namespace KWayland
 {
 namespace Client
@@ -29,6 +31,7 @@
 namespace KScreen
 {
 class Output;
+class WaylandPrimaryOutput;
 class WaylandOutputDevice;
 class WaylandScreen;
 class WaylandOutputManagement;
@@ -58,6 +61,7 @@
     QMap<int, WaylandOutputDevice *> outputMap() const;
 
     void applyConfig(const KScreen::ConfigPtr &newConfig);
+    WaylandOutputDevice *findOutputDevice(struct ::kde_output_device_v2 
*outputdevice) const;
 
     bool isReady() const;
 
@@ -84,9 +88,11 @@
 
     KWayland::Client::Registry *m_registry;
     WaylandOutputManagement *m_outputManagement = nullptr;
+    QScopedPointer<WaylandPrimaryOutput> m_primaryOutput;
 
     // KWayland names as keys
     QMap<int, WaylandOutputDevice *> m_outputMap;
+    QString m_primaryOutputName;
 
     // KWayland names
     QList<WaylandOutputDevice *> m_initializingOutputs;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libkscreen-5.23.5/backends/kwayland/waylandoutputdevice.cpp 
new/libkscreen-5.24.0/backends/kwayland/waylandoutputdevice.cpp
--- old/libkscreen-5.23.5/backends/kwayland/waylandoutputdevice.cpp     
2022-01-04 10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/kwayland/waylandoutputdevice.cpp     
2022-02-03 15:36:03.000000000 +0100
@@ -170,7 +170,7 @@
     output->setId(m_id);
     output->setEnabled(enabled());
     output->setConnected(true);
-    output->setPrimary(true); // FIXME: wayland doesn't have the concept of a 
primary display
+    output->setPrimary(m_isPrimary);
     output->setName(name());
     output->setSizeMm(m_physicalSize);
     output->setPos(m_pos);
@@ -182,7 +182,7 @@
     QSize currentSize = m_mode->size();
     output->setSize(output->isHorizontal() ? currentSize : 
currentSize.transposed());
     output->setScale(m_factor);
-    output->setType(Utils::guessOutputType(m_model, m_model));
+    output->setType(Utils::guessOutputType(m_outputName, m_outputName));
     
output->setCapabilities(static_cast<Output::Capabilities>(static_cast<uint32_t>(m_flags)));
     output->setOverscan(m_overscan);
     output->setVrrPolicy(static_cast<Output::VrrPolicy>(m_vrr_policy));
@@ -257,6 +257,11 @@
         changed = true;
     }
 
+    if (output->isPrimary()) {
+        wlConfig->set_primary_output(object());
+        changed = true;
+    }
+
     return changed;
 }
 
@@ -271,12 +276,27 @@
     return QStringLiteral("%1 %2").arg(m_manufacturer, m_model);
 }
 
+QString WaylandOutputDevice::outputName() const
+{
+    return m_outputName;
+}
+
 QDebug operator<<(QDebug dbg, const WaylandOutputDevice *output)
 {
     dbg << "WaylandOutput(Id:" << output->id() << ", Name:" << 
QString(output->manufacturer() + QLatin1Char(' ') + output->model()) << ")";
     return dbg;
 }
 
+bool WaylandOutputDevice::isPrimary() const
+{
+    return m_isPrimary;
+}
+
+void WaylandOutputDevice::setPrimary(bool primary)
+{
+    m_isPrimary = primary;
+}
+
 void WaylandOutputDevice::kde_output_device_v2_done()
 {
     Q_EMIT done();
@@ -332,6 +352,11 @@
     m_rgbRange = rgb_range;
 }
 
+void WaylandOutputDevice::kde_output_device_v2_name(const QString &outputName)
+{
+    m_outputName = outputName;
+}
+
 QByteArray WaylandOutputDevice::edid() const
 {
     return m_edid;
@@ -396,5 +421,3 @@
 {
     return m_rgbRange;
 }
-
-#include "waylandoutputdevice.moc"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libkscreen-5.23.5/backends/kwayland/waylandoutputdevice.h 
new/libkscreen-5.24.0/backends/kwayland/waylandoutputdevice.h
--- old/libkscreen-5.23.5/backends/kwayland/waylandoutputdevice.h       
2022-01-04 10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/kwayland/waylandoutputdevice.h       
2022-02-03 15:36:03.000000000 +0100
@@ -32,6 +32,7 @@
     bool enabled() const;
     int id() const;
     QString name() const;
+    QString outputName() const;
     QString model() const;
     QString manufacturer() const;
     qreal scale() const;
@@ -47,9 +48,15 @@
     void updateKScreenOutput(OutputPtr &output);
     void updateKScreenModes(OutputPtr &output);
 
+    bool isPrimary() const;
+    void setPrimary(bool primary);
     bool setWlConfig(WaylandOutputConfiguration *wlConfig, const 
KScreen::OutputPtr &output);
 
     QString modeId() const;
+    QString uuid() const
+    {
+        return m_uuid;
+    }
 
 Q_SIGNALS:
     void done();
@@ -76,6 +83,7 @@
     void kde_output_device_v2_overscan(uint32_t overscan) override;
     void kde_output_device_v2_vrr_policy(uint32_t vrr_policy) override;
     void kde_output_device_v2_rgb_range(uint32_t rgb_range) override;
+    void kde_output_device_v2_name(const QString &name) override;
 
 private:
     QString modeName(const WaylandOutputDeviceMode *m) const;
@@ -96,11 +104,13 @@
     int32_t m_enabled;
     QString m_uuid;
     QString m_serialNumber;
+    QString m_outputName;
     QString m_eisaId;
     uint32_t m_flags;
     uint32_t m_overscan;
     uint32_t m_vrr_policy;
     uint32_t m_rgbRange;
+    bool m_isPrimary = false;
 };
 
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libkscreen-5.23.5/backends/kwayland/waylandoutputmanagement.cpp 
new/libkscreen-5.24.0/backends/kwayland/waylandoutputmanagement.cpp
--- old/libkscreen-5.23.5/backends/kwayland/waylandoutputmanagement.cpp 
2022-01-04 10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/kwayland/waylandoutputmanagement.cpp 
2022-02-03 15:36:03.000000000 +0100
@@ -5,15 +5,15 @@
  *  SPDX-License-Identifier: LGPL-2.1-or-later
  */
 #include "waylandoutputmanagement.h"
+#include "waylandconfig.h"
 #include <QDebug>
 
 namespace KScreen
 {
 WaylandOutputManagement::WaylandOutputManagement(struct ::wl_registry 
*registry, int id, int version)
     : QObject()
-    , QtWayland::kde_output_management_v2()
+    , QtWayland::kde_output_management_v2(registry, id, version)
 {
-    init(registry, id, version);
 }
 
 WaylandOutputConfiguration *WaylandOutputManagement::createConfiguration()
@@ -37,4 +37,14 @@
     Q_EMIT failed();
 }
 
+WaylandPrimaryOutput::WaylandPrimaryOutput(struct ::wl_registry *registry, int 
id, int version)
+    : QObject()
+    , QtWayland::kde_primary_output_v1(registry, id, version)
+{
+}
+
+void WaylandPrimaryOutput::kde_primary_output_v1_primary_output(const QString 
&outputName)
+{
+    Q_EMIT primaryOutputChanged(outputName);
+}
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libkscreen-5.23.5/backends/kwayland/waylandoutputmanagement.h 
new/libkscreen-5.24.0/backends/kwayland/waylandoutputmanagement.h
--- old/libkscreen-5.23.5/backends/kwayland/waylandoutputmanagement.h   
2022-01-04 10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/kwayland/waylandoutputmanagement.h   
2022-02-03 15:36:03.000000000 +0100
@@ -8,12 +8,16 @@
 #define WAYLANDOUTPUTMANAGEMENT_H
 
 #include "qwayland-kde-output-management-v2.h"
+#include "qwayland-kde-primary-output-v1.h"
 
 #include <QObject>
 #include <QSize>
 
 namespace KScreen
 {
+class WaylandConfig;
+class WaylandOutputDevice;
+
 class WaylandOutputConfiguration : public QObject, public 
QtWayland::kde_output_configuration_v2
 {
     Q_OBJECT
@@ -38,6 +42,18 @@
     WaylandOutputConfiguration *createConfiguration();
 };
 
+class WaylandPrimaryOutput : public QObject, public 
QtWayland::kde_primary_output_v1
+{
+    Q_OBJECT
+public:
+    WaylandPrimaryOutput(struct ::wl_registry *registry, int id, int version);
+
+Q_SIGNALS:
+    void primaryOutputChanged(const QString &outputName);
+
+protected:
+    void kde_primary_output_v1_primary_output(const QString &outputName) 
override;
+};
 }
 
 #endif // WAYLANDOUTPUTMANAGEMENT_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/backends/qscreen/CMakeLists.txt 
new/libkscreen-5.24.0/backends/qscreen/CMakeLists.txt
--- old/libkscreen-5.23.5/backends/qscreen/CMakeLists.txt       2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/qscreen/CMakeLists.txt       2022-02-03 
15:36:03.000000000 +0100
@@ -2,15 +2,19 @@
                     ${CMAKE_BUILD_DIR}
 )
 
-set(qscreen_SRCS
+
+add_library(KSC_QScreen MODULE)
+target_sources(KSC_QScreen PRIVATE
     qscreenbackend.cpp
     qscreenconfig.cpp
     qscreenscreen.cpp
     qscreenoutput.cpp
+    qscreenbackend.h
+    qscreenconfig.h
+    qscreenscreen.h
+    qscreenoutput.h
 )
 
-add_library(KSC_QScreen MODULE ${qscreen_SRCS})
-
 set_target_properties(KSC_QScreen PROPERTIES LIBRARY_OUTPUT_DIRECTORY 
"${CMAKE_BINARY_DIR}/bin/kf5/kscreen")
 set_target_properties(KSC_QScreen PROPERTIES PREFIX "")
 target_link_libraries(KSC_QScreen Qt::Core
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/backends/xcbeventlistener.cpp 
new/libkscreen-5.24.0/backends/xcbeventlistener.cpp
--- old/libkscreen-5.23.5/backends/xcbeventlistener.cpp 2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/xcbeventlistener.cpp 2022-02-03 
15:36:03.000000000 +0100
@@ -139,6 +139,8 @@
     }
 
     qCDebug(KSCREEN_XCB_HELPER) << "RRScreenChangeNotify";
+    qCDebug(KSCREEN_XCB_HELPER) << "\tTimestamp: " << e2->timestamp;
+    qCDebug(KSCREEN_XCB_HELPER) << "\tConfig_timestamp: " << 
e2->config_timestamp;
     qCDebug(KSCREEN_XCB_HELPER) << "\tWindow:" << e2->request_window;
     qCDebug(KSCREEN_XCB_HELPER) << "\tRoot:" << e2->root;
     qCDebug(KSCREEN_XCB_HELPER) << "\tRotation: " << 
rotationToString((xcb_randr_rotation_t)e2->rotation);
@@ -157,15 +159,17 @@
     if (randrEvent->subCode == XCB_RANDR_NOTIFY_CRTC_CHANGE) {
         xcb_randr_crtc_change_t crtc = randrEvent->u.cc;
         qCDebug(KSCREEN_XCB_HELPER) << "RRNotify_CrtcChange";
+        qCDebug(KSCREEN_XCB_HELPER) << "\tTimestamp: " << crtc.timestamp;
         qCDebug(KSCREEN_XCB_HELPER) << "\tCRTC: " << crtc.crtc;
         qCDebug(KSCREEN_XCB_HELPER) << "\tMode: " << crtc.mode;
         qCDebug(KSCREEN_XCB_HELPER) << "\tRotation: " << 
rotationToString((xcb_randr_rotation_t)crtc.rotation);
         qCDebug(KSCREEN_XCB_HELPER) << "\tGeometry: " << crtc.x << crtc.y << 
crtc.width << crtc.height;
-        Q_EMIT crtcChanged(crtc.crtc, crtc.mode, 
(xcb_randr_rotation_t)crtc.rotation, QRect(crtc.x, crtc.y, crtc.width, 
crtc.height));
+        Q_EMIT crtcChanged(crtc.crtc, crtc.mode, 
(xcb_randr_rotation_t)crtc.rotation, QRect(crtc.x, crtc.y, crtc.width, 
crtc.height), crtc.timestamp);
 
     } else if (randrEvent->subCode == XCB_RANDR_NOTIFY_OUTPUT_CHANGE) {
         xcb_randr_output_change_t output = randrEvent->u.oc;
         qCDebug(KSCREEN_XCB_HELPER) << "RRNotify_OutputChange";
+        qCDebug(KSCREEN_XCB_HELPER) << "\tTimestamp: " << output.timestamp;
         qCDebug(KSCREEN_XCB_HELPER) << "\tOutput: " << output.output;
         qCDebug(KSCREEN_XCB_HELPER) << "\tCRTC: " << output.crtc;
         qCDebug(KSCREEN_XCB_HELPER) << "\tMode: " << output.mode;
@@ -181,6 +185,7 @@
             xcb_get_atom_name_reply(QX11Info::connection(), 
xcb_get_atom_name(QX11Info::connection(), property.atom), nullptr));
 
         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: " << 
xcb_get_atom_name_name(reply.data());
         qCDebug(KSCREEN_XCB_HELPER) << "\tState (newValue, Deleted): " << 
property.status;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/backends/xcbeventlistener.h 
new/libkscreen-5.24.0/backends/xcbeventlistener.h
--- old/libkscreen-5.23.5/backends/xcbeventlistener.h   2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/xcbeventlistener.h   2022-02-03 
15:36:03.000000000 +0100
@@ -30,7 +30,7 @@
     void outputsChanged();
 
     /* Emitted only when XRandR 1.2 or newer is available */
-    void crtcChanged(xcb_randr_crtc_t crtc, xcb_randr_mode_t mode, 
xcb_randr_rotation_t rotation, const QRect &geom);
+    void crtcChanged(xcb_randr_crtc_t crtc, xcb_randr_mode_t mode, 
xcb_randr_rotation_t rotation, const QRect &geom, xcb_timestamp_t timestamp);
     void outputChanged(xcb_randr_output_t output, xcb_randr_crtc_t crtc, 
xcb_randr_mode_t mode, xcb_randr_connection_t connection);
     void outputPropertyChanged(xcb_randr_output_t output);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/backends/xrandr/CMakeLists.txt 
new/libkscreen-5.24.0/backends/xrandr/CMakeLists.txt
--- old/libkscreen-5.23.5/backends/xrandr/CMakeLists.txt        2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/xrandr/CMakeLists.txt        2022-02-03 
15:36:03.000000000 +0100
@@ -2,7 +2,9 @@
                     ${CMAKE_BUILD_DIR}
 )
 
-set(xrandr_SRCS
+
+add_library(KSC_XRandR MODULE)
+target_sources(KSC_XRandR PRIVATE
     xrandr.cpp
     xrandrconfig.cpp
     xrandrcrtc.cpp
@@ -14,8 +16,6 @@
     ../utils.cpp
 )
 
-add_library(KSC_XRandR MODULE ${xrandr_SRCS})
-
 set_target_properties(KSC_XRandR PROPERTIES LIBRARY_OUTPUT_DIRECTORY 
"${CMAKE_BINARY_DIR}/bin/kf5/kscreen")
 set_target_properties(KSC_XRandR PROPERTIES PREFIX "")
 target_link_libraries(KSC_XRandR Qt::Core
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/backends/xrandr/xrandr.cpp 
new/libkscreen-5.24.0/backends/xrandr/xrandr.cpp
--- old/libkscreen-5.23.5/backends/xrandr/xrandr.cpp    2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/xrandr/xrandr.cpp    2022-02-03 
15:36:03.000000000 +0100
@@ -45,6 +45,7 @@
     qRegisterMetaType<xcb_randr_mode_t>("xcb_randr_mode_t");
     qRegisterMetaType<xcb_randr_connection_t>("xcb_randr_connection_t");
     qRegisterMetaType<xcb_randr_rotation_t>("xcb_randr_rotation_t");
+    qRegisterMetaType<xcb_timestamp_t>("xcb_timestamp_t");
 
     // Use our own connection to make sure that we won't mess up Qt's 
connection
     // if something goes wrong on our side.
@@ -143,7 +144,7 @@
     qCDebug(KSCREEN_XRANDR) << "Output" << xOutput->id() << ": connected =" << 
xOutput->isConnected() << ", enabled =" << xOutput->isEnabled();
 }
 
-void XRandR::crtcChanged(xcb_randr_crtc_t crtc, xcb_randr_mode_t mode, 
xcb_randr_rotation_t rotation, const QRect &geom)
+void XRandR::crtcChanged(xcb_randr_crtc_t crtc, xcb_randr_mode_t mode, 
xcb_randr_rotation_t rotation, const QRect &geom, xcb_timestamp_t timestamp)
 {
     XRandRCrtc *xCrtc = s_internalConfig->crtc(crtc);
     if (!xCrtc) {
@@ -152,6 +153,7 @@
         xCrtc->update(mode, rotation, geom);
     }
 
+    xCrtc->updateConfigTimestamp(timestamp);
     m_configChangeCompressor->start();
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/backends/xrandr/xrandr.h 
new/libkscreen-5.24.0/backends/xrandr/xrandr.h
--- old/libkscreen-5.23.5/backends/xrandr/xrandr.h      2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/xrandr/xrandr.h      2022-02-03 
15:36:03.000000000 +0100
@@ -44,7 +44,7 @@
 
 private:
     void outputChanged(xcb_randr_output_t output, xcb_randr_crtc_t crtc, 
xcb_randr_mode_t mode, xcb_randr_connection_t connection);
-    void crtcChanged(xcb_randr_crtc_t crtc, xcb_randr_mode_t mode, 
xcb_randr_rotation_t rotation, const QRect &geom);
+    void crtcChanged(xcb_randr_crtc_t crtc, xcb_randr_mode_t mode, 
xcb_randr_rotation_t rotation, const QRect &geom, xcb_timestamp_t timestamp);
     void screenChanged(xcb_randr_rotation_t rotation, const QSize &sizePx, 
const QSize &sizeMm);
 
     static quint8 *getXProperty(xcb_randr_output_t output, xcb_atom_t atom, 
size_t &len);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/backends/xrandr/xrandrconfig.cpp 
new/libkscreen-5.24.0/backends/xrandr/xrandrconfig.cpp
--- old/libkscreen-5.23.5/backends/xrandr/xrandrconfig.cpp      2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/xrandr/xrandrconfig.cpp      2022-02-03 
15:36:03.000000000 +0100
@@ -504,6 +504,8 @@
                         XCB_NONE,
                         xOutput->isConnected() ? 
XCB_RANDR_CONNECTION_CONNECTED : XCB_RANDR_CONNECTION_DISCONNECTED,
                         kscreenOutput->isPrimary());
+        if (xOutput->crtc())
+            xOutput->crtc()->updateTimestamp(reply->timestamp);
     }
     return (reply->status == XCB_RANDR_SET_CONFIG_SUCCESS);
 }
@@ -573,7 +575,7 @@
                             << "\n"
                             << "\tCRTC:" << xOutput->crtc()->crtc() << "\n"
                             << "\tPos:" << kscreenOutput->pos() << "\n"
-                            << "\tMode:" << modeId << 
kscreenOutput->currentMode() << "\n"
+                            << "\tMode:" << kscreenOutput->currentMode() << 
"Preferred:" << kscreenOutput->preferredModeId() << "\n"
                             << "\tRotation:" << kscreenOutput->rotation();
 
     if (!sendConfig(kscreenOutput, xOutput->crtc())) {
@@ -605,6 +607,9 @@
         qCDebug(KSCREEN_XRANDR) << "\tResult: unknown (error)";
         return false;
     }
-    qCDebug(KSCREEN_XRANDR) << "\tResult: " << reply->status;
+
+    crtc->updateTimestamp(reply->timestamp);
+
+    qCDebug(KSCREEN_XRANDR) << "\tResult: " << reply->status << " timestamp: " 
<< reply->timestamp;
     return (reply->status == XCB_RANDR_SET_CONFIG_SUCCESS);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/backends/xrandr/xrandrcrtc.cpp 
new/libkscreen-5.24.0/backends/xrandr/xrandrcrtc.cpp
--- old/libkscreen-5.23.5/backends/xrandr/xrandrcrtc.cpp        2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/xrandr/xrandrcrtc.cpp        2022-02-03 
15:36:03.000000000 +0100
@@ -16,6 +16,8 @@
     , m_crtc(crtc)
     , m_mode(0)
     , m_rotation(XCB_RANDR_ROTATION_ROTATE_0)
+    , m_timestamp(XCB_CURRENT_TIME)
+    , m_configTimestamp(XCB_CURRENT_TIME)
 {
     update();
 }
@@ -111,3 +113,24 @@
     m_geometry = geom;
     m_rotation = rotation;
 }
+
+void XRandRCrtc::updateTimestamp(const xcb_timestamp_t tmstamp)
+{
+    if (tmstamp > m_timestamp) {
+        qCDebug(KSCREEN_XRANDR) << "XRandRCrtc " << m_crtc << " m_timestamp 
update " << m_timestamp << " => " << tmstamp;
+        m_timestamp = tmstamp;
+    }
+}
+
+void XRandRCrtc::updateConfigTimestamp(const xcb_timestamp_t tmstamp)
+{
+    if (tmstamp > m_configTimestamp) {
+        qCDebug(KSCREEN_XRANDR) << "XRandRCrtc " << m_crtc << " 
m_configTimestamp update" << m_configTimestamp << " => " << tmstamp;
+        m_configTimestamp = tmstamp;
+    }
+}
+
+bool XRandRCrtc::isChangedFromOutside() const
+{
+    return m_configTimestamp > m_timestamp;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/backends/xrandr/xrandrcrtc.h 
new/libkscreen-5.24.0/backends/xrandr/xrandrcrtc.h
--- old/libkscreen-5.23.5/backends/xrandr/xrandrcrtc.h  2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/xrandr/xrandrcrtc.h  2022-02-03 
15:36:03.000000000 +0100
@@ -41,6 +41,10 @@
     void update();
     void update(xcb_randr_crtc_t mode, xcb_randr_rotation_t rotation, const 
QRect &geom);
 
+    void updateTimestamp(const xcb_timestamp_t tmstamp);
+    void updateConfigTimestamp(const xcb_timestamp_t tmstamp);
+    bool isChangedFromOutside() const;
+
 private:
     xcb_randr_crtc_t m_crtc;
     xcb_randr_mode_t m_mode;
@@ -50,4 +54,7 @@
 
     QVector<xcb_randr_output_t> m_possibleOutputs;
     QVector<xcb_randr_output_t> m_outputs;
+
+    xcb_timestamp_t m_timestamp;
+    xcb_timestamp_t m_configTimestamp;
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/backends/xrandr/xrandroutput.cpp 
new/libkscreen-5.24.0/backends/xrandr/xrandroutput.cpp
--- old/libkscreen-5.23.5/backends/xrandr/xrandroutput.cpp      2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/xrandr/xrandroutput.cpp      2022-02-03 
15:36:03.000000000 +0100
@@ -403,7 +403,7 @@
 
     // See https://bugzilla.redhat.com/show_bug.cgi?id=1290586
     // QXL will be creating a new mode we need to jump to every time the 
display is resized
-    kscreenOutput->setFollowPreferredMode(m_hotplugModeUpdate);
+    kscreenOutput->setFollowPreferredMode(m_hotplugModeUpdate && m_crtc && 
m_crtc->isChangedFromOutside());
 
     kscreenOutput->setConnected(isConnected());
     if (isConnected()) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/backends/xrandr1.1/CMakeLists.txt 
new/libkscreen-5.24.0/backends/xrandr1.1/CMakeLists.txt
--- old/libkscreen-5.23.5/backends/xrandr1.1/CMakeLists.txt     2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/backends/xrandr1.1/CMakeLists.txt     2022-02-03 
15:36:03.000000000 +0100
@@ -1,19 +1,18 @@
 find_package(XCB REQUIRED COMPONENTS XCB RANDR)
 
 include_directories(${CMAKE_SOURCE_DIR}/src
-                    ${KDE4_INCLUDES}
                     ${CMAKE_BUILD_DIR}
                     ${QT_INCLUDES}
 )
 
-set(xrandr11_SRCS
+
+add_library(KSC_XRandR11 MODULE)
+target_sources(KSC_XRandR11 PRIVATE
     xrandr11.cpp
     ../xcbeventlistener.cpp
     ../xcbwrapper.cpp
 )
 
-add_library(KSC_XRandR11 MODULE ${xrandr11_SRCS})
-
 set_target_properties(KSC_XRandR11 PROPERTIES LIBRARY_OUTPUT_DIRECTORY 
"${CMAKE_BINARY_DIR}/bin/kf5/kscreen")
 set_target_properties(KSC_XRandR11 PROPERTIES PREFIX "")
 target_link_libraries(KSC_XRandR11 Qt::Core
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/src/backendlauncher/CMakeLists.txt 
new/libkscreen-5.24.0/src/backendlauncher/CMakeLists.txt
--- old/libkscreen-5.23.5/src/backendlauncher/CMakeLists.txt    2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/src/backendlauncher/CMakeLists.txt    2022-02-03 
15:36:03.000000000 +0100
@@ -35,3 +35,10 @@
 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.kscreen.service
         DESTINATION ${KDE_INSTALL_DBUSSERVICEDIR}
 )
+
+configure_file(plasma-kscreen.service.cmake
+               ${CMAKE_CURRENT_BINARY_DIR}/plasma-kscreen.service @ONLY
+)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasma-kscreen.service
+        DESTINATION ${KDE_INSTALL_SYSTEMDUSERUNITDIR}
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libkscreen-5.23.5/src/backendlauncher/org.kde.kscreen.service.cmake 
new/libkscreen-5.24.0/src/backendlauncher/org.kde.kscreen.service.cmake
--- old/libkscreen-5.23.5/src/backendlauncher/org.kde.kscreen.service.cmake     
2022-01-04 10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/src/backendlauncher/org.kde.kscreen.service.cmake     
2022-02-03 15:36:03.000000000 +0100
@@ -1,3 +1,4 @@
 [D-BUS Service]
 Name=org.kde.KScreen
 Exec=@CMAKE_INSTALL_FULL_LIBEXECDIR_KF5@/kscreen_backend_launcher
+SystemdService=plasma-kscreen.service
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libkscreen-5.23.5/src/backendlauncher/plasma-kscreen.service.cmake 
new/libkscreen-5.24.0/src/backendlauncher/plasma-kscreen.service.cmake
--- old/libkscreen-5.23.5/src/backendlauncher/plasma-kscreen.service.cmake      
1970-01-01 01:00:00.000000000 +0100
+++ new/libkscreen-5.24.0/src/backendlauncher/plasma-kscreen.service.cmake      
2022-02-03 15:36:03.000000000 +0100
@@ -0,0 +1,12 @@
+[Unit]
+Description=KScreen
+PartOf=graphical-session.target
+
+[Service]
+ExecStart=@CMAKE_INSTALL_FULL_LIBEXECDIR_KF5@/kscreen_backend_launcher
+Type=dbus
+BusName=org.kde.KScreen
+TimeoutSec=5sec
+Slice=background.slice
+# Disable restart as we're dbus activated anyway
+Restart=no
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/src/config.cpp 
new/libkscreen-5.24.0/src/config.cpp
--- old/libkscreen-5.23.5/src/config.cpp        2022-01-04 10:00:26.000000000 
+0100
+++ new/libkscreen-5.24.0/src/config.cpp        2022-02-03 15:36:03.000000000 
+0100
@@ -203,13 +203,13 @@
 {
     ConfigPtr newConfig(new Config());
     newConfig->d->screen = d->screen->clone();
-    for (const OutputPtr &ourOutput : d->outputs) {
-        newConfig->addOutput(ourOutput->clone());
-    }
-    newConfig->d->primaryOutput = newConfig->d->findPrimaryOutput();
     newConfig->setSupportedFeatures(supportedFeatures());
     newConfig->setTabletModeAvailable(tabletModeAvailable());
     newConfig->setTabletModeEngaged(tabletModeEngaged());
+    for (const OutputPtr &ourOutput : qAsConst(d->outputs)) {
+        newConfig->addOutput(ourOutput->clone());
+    }
+    newConfig->d->primaryOutput = newConfig->d->findPrimaryOutput();
     return newConfig;
 }
 
@@ -325,6 +325,7 @@
 void Config::addOutput(const OutputPtr &output)
 {
     d->outputs.insert(output->id(), output);
+    output->setExplicitLogicalSize(logicalSizeForOutput(*output));
     connect(output.data(), &KScreen::Output::isPrimaryChanged, d, 
&KScreen::Config::Private::onPrimaryOutputChanged);
 
     Q_EMIT outputAdded(output);
@@ -384,6 +385,7 @@
         } else {
             // Update existing outputs
             d->outputs[otherOutput->id()]->apply(otherOutput);
+            
d->outputs[otherOutput->id()]->setExplicitLogicalSize(logicalSizeForOutput(*d->outputs[otherOutput->id()]));
         }
     }
 
@@ -391,6 +393,37 @@
     setValid(other->isValid());
 }
 
+QRect Config::outputGeometryForOutput(const KScreen::Output &output) const
+{
+    QSize size = logicalSizeForOutput(output).toSize();
+    if (!size.isValid()) {
+        return QRect();
+    }
+
+    return QRect(output.pos(), size);
+}
+
+QSizeF Config::logicalSizeForOutput(const KScreen::Output &output) const
+{
+    QSizeF size = output.enforcedModeSize();
+    if (!size.isValid()) {
+        return QSizeF();
+    }
+    // ignore scale where scaling is not per-output
+    if (supportedFeatures().testFlag(Feature::PerOutputScaling)) {
+        size = size / output.scale();
+    }
+
+    // We can't use output.size(), because it does not reflect the actual 
rotation() set by caller.
+    // It is only updated when we get update from KScreen, but not when user 
changes mode or
+    // rotation manually.
+
+    if (!output.isHorizontal()) {
+        size = size.transposed();
+    }
+    return size;
+}
+
 QDebug operator<<(QDebug dbg, const KScreen::ConfigPtr &config)
 {
     if (config) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/src/config.h 
new/libkscreen-5.24.0/src/config.h
--- old/libkscreen-5.23.5/src/config.h  2022-01-04 10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/src/config.h  2022-02-03 15:36:03.000000000 +0100
@@ -50,12 +50,13 @@
      */
     enum class Feature {
         None = 0, ///< None of the mentioned features are supported.
-        PrimaryDisplay = 1, ///< The backend knows about the concept of a 
primary display, this is mostly limited to X11.
+        PrimaryDisplay = 1, ///< The backend knows about the concept of a 
primary display
         Writable = 1 << 1, ///< The backend supports setting the config, it's 
not read-only.
         PerOutputScaling = 1 << 2, ///< The backend supports scaling each 
output individually.
         OutputReplication = 1 << 3, ///< The backend supports replication of 
outputs.
         AutoRotation = 1 << 4, ///< The backend supports automatic rotation of 
outputs.
         TabletMode = 1 << 5, ///< The backend supports querying if a device is 
in tablet mode.
+        SynchronousOutputChanges = 1 << 6, ///< The backend supports blocking 
until the output setting changes are applied
     };
     Q_DECLARE_FLAGS(Features, Feature)
 
@@ -190,6 +191,10 @@
      */
     void setTabletModeEngaged(bool engaged);
 
+    QRect outputGeometryForOutput(const KScreen::Output &output) const;
+
+    QSizeF logicalSizeForOutput(const KScreen::Output &output) const;
+
 Q_SIGNALS:
     void outputAdded(const KScreen::OutputPtr &output);
     void outputRemoved(int outputId);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/src/doctor/CMakeLists.txt 
new/libkscreen-5.24.0/src/doctor/CMakeLists.txt
--- old/libkscreen-5.23.5/src/doctor/CMakeLists.txt     2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/src/doctor/CMakeLists.txt     2022-02-03 
15:36:03.000000000 +0100
@@ -1,4 +1,4 @@
 
-add_executable(kscreen-doctor main.cpp doctor.cpp dpmsclient.cpp)
+add_executable(kscreen-doctor main.cpp doctor.cpp dpmsclient.cpp doctor.h 
dpmsclient.h)
 target_link_libraries(kscreen-doctor Qt::DBus KF5::Screen KF5::WaylandClient)
 install(TARGETS kscreen-doctor ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/src/doctor/doctor.cpp 
new/libkscreen-5.24.0/src/doctor/doctor.cpp
--- old/libkscreen-5.23.5/src/doctor/doctor.cpp 2022-01-04 10:00:26.000000000 
+0100
+++ new/libkscreen-5.24.0/src/doctor/doctor.cpp 2022-02-03 15:36:03.000000000 
+0100
@@ -194,7 +194,12 @@
                         return;
                     }
                 }
-                if (ops.count() == 3 && ops[2] == QLatin1String("enable")) {
+                if (ops.count() == 3 && ops[2] == QLatin1String("primary")) {
+                    if (!setPrimary(output_id)) {
+                        qApp->exit(1);
+                        return;
+                    };
+                } else if (ops.count() == 3 && ops[2] == 
QLatin1String("enable")) {
                     if (!setEnabled(output_id, true)) {
                         qApp->exit(1);
                         return;
@@ -238,7 +243,7 @@
                     // be lenient about . vs. comma as separator
                     qreal scale = ops[3].replace(QLatin1Char(','), 
QLatin1Char('.')).toDouble(&ok);
                     if (ops.count() == 5) {
-                        const QString dbl = ops[3] + QLatin1String(".") + 
ops[4];
+                        const QString dbl = ops[3] + QStringLiteral(".") + 
ops[4];
                         scale = dbl.toDouble(&ok);
                     };
                     // set scale
@@ -385,9 +390,9 @@
 
     for (const auto &output : m_config->outputs()) {
         cout << green << "Output: " << cr << output->id() << " " << 
output->name();
-        cout << " " << (output->isEnabled() ? green + QLatin1String("enabled") 
: red + QLatin1String("disabled"));
-        cout << " " << (output->isConnected() ? green + 
QLatin1String("connected") : red + QLatin1String("disconnected"));
-        cout << " " << (output->isPrimary() ? green + QLatin1String("primary") 
: QString());
+        cout << " " << (output->isEnabled() ? green + 
QStringLiteral("enabled") : red + QStringLiteral("disabled"));
+        cout << " " << (output->isConnected() ? green + 
QStringLiteral("connected") : red + QStringLiteral("disconnected"));
+        cout << " " << (output->isPrimary() ? green + 
QStringLiteral("primary") : QString());
         auto _type = typeString[output->type()];
         cout << " " << yellow << (_type.isEmpty() ? 
QStringLiteral("UnmappedOutputType") : _type);
         cout << blue << " Modes: " << cr;
@@ -506,7 +511,7 @@
     for (const auto &output : m_config->outputs()) {
         if (output->id() == id) {
             // find mode
-            for (const KScreen::ModePtr mode : output->modes()) {
+            for (const KScreen::ModePtr &mode : output->modes()) {
                 auto name =
                     QStringLiteral("%1x%2@%3")
                         .arg(QString::number(mode->size().width()), 
QString::number(mode->size().height()), 
QString::number(qRound(mode->refreshRate())));
@@ -613,6 +618,32 @@
     return false;
 }
 
+bool KScreen::Doctor::setPrimary(int id)
+{
+    if (!m_config) {
+        qCWarning(KSCREEN_DOCTOR) << "Invalid config.";
+        return false;
+    }
+
+    bool found = false;
+    for (const auto &output : m_config->outputs()) {
+        if (output->id() == id) {
+            output->setPrimary(true);
+            m_changed = true;
+            found = true;
+        }
+    }
+    if (found) {
+        for (const auto &output : m_config->outputs()) {
+            if (output->id() != id) {
+                output->setPrimary(false);
+                m_changed = true;
+            }
+        }
+    }
+    return found;
+}
+
 void Doctor::applyConfig()
 {
     if (!m_changed) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/src/doctor/doctor.h 
new/libkscreen-5.24.0/src/doctor/doctor.h
--- old/libkscreen-5.23.5/src/doctor/doctor.h   2022-01-04 10:00:26.000000000 
+0100
+++ new/libkscreen-5.24.0/src/doctor/doctor.h   2022-02-03 15:36:03.000000000 
+0100
@@ -46,6 +46,7 @@
     bool setOverscan(int id, uint32_t overscan);
     bool setVrrPolicy(int id, KScreen::Output::VrrPolicy policy);
     bool setRgbRange(int id, KScreen::Output::RgbRange rgbRange);
+    bool setPrimary(int id);
 
 Q_SIGNALS:
     void outputsChanged();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/src/output.cpp 
new/libkscreen-5.24.0/src/output.cpp
--- old/libkscreen-5.23.5/src/output.cpp        2022-01-04 10:00:26.000000000 
+0100
+++ new/libkscreen-5.24.0/src/output.cpp        2022-02-03 15:36:03.000000000 
+0100
@@ -13,6 +13,7 @@
 #include "mode.h"
 
 #include <QCryptographicHash>
+#include <QGuiApplication>
 #include <QRect>
 #include <QScopedPointer>
 #include <QStringList>
@@ -28,7 +29,7 @@
         , replicationSource(0)
         , rotation(None)
         , scale(1.0)
-        , logicalSize(QSizeF())
+        , explicitLogicalSize(QSizeF())
         , connected(false)
         , enabled(false)
         , primary(false)
@@ -51,6 +52,7 @@
         , size(other.size)
         , rotation(other.rotation)
         , scale(other.scale)
+        , explicitLogicalSize(other.explicitLogicalSize)
         , connected(other.connected)
         , enabled(other.enabled)
         , primary(other.primary)
@@ -87,7 +89,7 @@
     QSize size;
     Rotation rotation;
     qreal scale;
-    QSizeF logicalSize;
+    QSizeF explicitLogicalSize;
     bool connected;
     bool enabled;
     bool primary;
@@ -246,6 +248,43 @@
     Q_EMIT outputChanged();
 }
 
+QString Output::typeName() const
+{
+    switch (d->type) {
+    case Output::Unknown:
+        return QStringLiteral("Unknown");
+    case Output::Panel:
+        return QStringLiteral("Panel (Laptop)");
+    case Output::VGA:
+        return QStringLiteral("VGA");
+    case Output::DVI:
+        return QStringLiteral("DVI");
+    case Output::DVII:
+        return QStringLiteral("DVI-I");
+    case Output::DVIA:
+        return QStringLiteral("DVI-A");
+    case Output::DVID:
+        return QStringLiteral("DVI-D");
+    case Output::HDMI:
+        return QStringLiteral("HDMI");
+    case Output::TV:
+        return QStringLiteral("TV");
+    case Output::TVComposite:
+        return QStringLiteral("TV-Composite");
+    case Output::TVSVideo:
+        return QStringLiteral("TV-SVideo");
+    case Output::TVComponent:
+        return QStringLiteral("TV-Component");
+    case Output::TVSCART:
+        return QStringLiteral("TV-SCART");
+    case Output::TVC4:
+        return QStringLiteral("TV-C4");
+    case Output::DisplayPort:
+        return QStringLiteral("DisplayPort");
+    };
+    return QStringLiteral("Invalid Type") + QString::number(d->type);
+}
+
 QString Output::icon() const
 {
     return d->icon;
@@ -422,40 +461,18 @@
     Q_EMIT scaleChanged();
 }
 
-QSizeF Output::logicalSize() const
-{
-    if (d->logicalSize.isValid()) {
-        return d->logicalSize;
-    }
-
-    QSizeF size = enforcedModeSize();
-    if (!size.isValid()) {
-        return QSizeF();
-    }
-    size = size / d->scale;
-
-    // We can't use d->size, because d->size does not reflect the actual 
rotation() set by caller.
-    // It is only updated when we get update from KScreen, but not when user 
changes mode or
-    // rotation manually.
-
-    if (!isHorizontal()) {
-        size = size.transposed();
-    }
-    return size;
-}
-
 QSizeF Output::explicitLogicalSize() const
 {
-    return d->logicalSize;
+    return d->explicitLogicalSize;
 }
 
-void Output::setLogicalSize(const QSizeF &size)
+void Output::setExplicitLogicalSize(const QSizeF &size)
 {
-    if (qFuzzyCompare(d->logicalSize.width(), size.width()) && 
qFuzzyCompare(d->logicalSize.height(), size.height())) {
+    if (qFuzzyCompare(d->explicitLogicalSize.width(), size.width()) && 
qFuzzyCompare(d->explicitLogicalSize.height(), size.height())) {
         return;
     }
-    d->logicalSize = size;
-    Q_EMIT logicalSizeChanged();
+    d->explicitLogicalSize = size;
+    Q_EMIT explicitLogicalSizeChanged();
 }
 
 bool Output::isConnected() const
@@ -591,7 +608,7 @@
 
 QRect Output::geometry() const
 {
-    QSize size = logicalSize().toSize();
+    QSize size = explicitLogicalSize().toSize();
     if (!size.isValid()) {
         return QRect();
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/src/output.h 
new/libkscreen-5.24.0/src/output.h
--- old/libkscreen-5.23.5/src/output.h  2022-01-04 10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/src/output.h  2022-02-03 15:36:03.000000000 +0100
@@ -47,7 +47,7 @@
     Q_PROPERTY(QSize sizeMm READ sizeMm CONSTANT)
     Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged)
     Q_PROPERTY(bool followPreferredMode READ followPreferredMode WRITE 
setFollowPreferredMode NOTIFY followPreferredModeChanged)
-    Q_PROPERTY(QSizeF logicalSize READ logicalSize WRITE setLogicalSize NOTIFY 
logicalSizeChanged)
+    Q_PROPERTY(QSizeF explicitLogicalSize READ explicitLogicalSize WRITE 
setExplicitLogicalSize NOTIFY explicitLogicalSizeChanged)
     Q_PROPERTY(Capabilities capabilities READ capabilities NOTIFY 
capabilitiesChanged)
     Q_PROPERTY(uint32_t overscan READ overscan WRITE setOverscan NOTIFY 
overscanChanged)
     Q_PROPERTY(VrrPolicy vrrPolicy READ vrrPolicy WRITE setVrrPolicy NOTIFY 
vrrPolicyChanged)
@@ -139,6 +139,7 @@
     QString hashMd5() const;
 
     Type type() const;
+    QString typeName() const;
     void setType(Type type);
 
     QString icon() const;
@@ -314,16 +315,6 @@
      * The logical size is the output's representation internal to the display 
server and its
      * overall screen geometry.
      *
-     * returns the logical size of this output
-     *
-     * @since 5.18
-     */
-    QSizeF logicalSize() const;
-
-    /**
-     * The logical size is the output's representation internal to the display 
server and its
-     * overall screen geometry.
-     *
      * returns the explicitly set logical size of this output, is an invalid 
size if not set
      *
      * @since 5.18
@@ -337,9 +328,9 @@
      *
      * @param size of this output in logical space
      *
-     * @since 5.18
+     * @since 5.24
      */
-    void setLogicalSize(const QSizeF &size);
+    void setExplicitLogicalSize(const QSizeF &size);
 
     /**
      * @returns whether the mode should be changed to the new preferred mode
@@ -420,7 +411,7 @@
     void clonesChanged();
     void replicationSourceChanged();
     void scaleChanged();
-    void logicalSizeChanged();
+    void explicitLogicalSizeChanged();
     void followPreferredModeChanged(bool followPreferredMode);
     void capabilitiesChanged();
     void overscanChanged();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libkscreen-5.23.5/src/setconfigoperation.cpp 
new/libkscreen-5.24.0/src/setconfigoperation.cpp
--- old/libkscreen-5.23.5/src/setconfigoperation.cpp    2022-01-04 
10:00:26.000000000 +0100
+++ new/libkscreen-5.24.0/src/setconfigoperation.cpp    2022-02-03 
15:36:03.000000000 +0100
@@ -32,6 +32,7 @@
     void backendReady(org::kde::kscreen::Backend *backend) override;
     void onConfigSet(QDBusPendingCallWatcher *watcher);
     void normalizeOutputPositions();
+    void fixPrimaryOutput();
 
     KScreen::ConfigPtr config;
 
@@ -110,6 +111,7 @@
 {
     Q_D(SetConfigOperation);
     d->normalizeOutputPositions();
+    d->fixPrimaryOutput();
     if (BackendManager::instance()->method() == BackendManager::InProcess) {
         auto backend = d->loadBackend();
         backend->setConfig(d->config);
@@ -149,4 +151,41 @@
     }
 }
 
+void SetConfigOperationPrivate::fixPrimaryOutput()
+{
+    if (!config || !(config->supportedFeatures() & 
Config::Feature::PrimaryDisplay)) {
+        return;
+    }
+    const auto outputs = config->outputs();
+    if (outputs.isEmpty()) {
+        return;
+    }
+
+    // Here we make sure that:
+    // - that our primary is enabled
+    // - we have at least a primary
+    // - we have exactly 1 primary
+    // - we have a primary at all
+    bool found = false;
+    KScreen::OutputPtr candidate;
+    for (const KScreen::OutputPtr &output : outputs) {
+        if (!output->isEnabled() && output->isPrimary()) {
+            qCDebug(KSCREEN) << "can't be primary if disabled!!" << output;
+            output->setPrimary(false);
+        } else if (output->isPrimary() && !found) {
+            found = true;
+        } else if (output->isPrimary() && found) {
+            qCDebug(KSCREEN) << "can only have 1 primary" << output;
+            output->setPrimary(false);
+        } else if (output->isEnabled()) {
+            candidate = output;
+        }
+    }
+
+    if (!found && candidate) {
+        qCDebug(KSCREEN) << "setting primary instead" << candidate;
+        candidate->setPrimary(true);
+    }
+}
+
 #include "setconfigoperation.moc"

Reply via email to