summaryrefslogtreecommitdiff
path: root/x11-misc/sddm/files/sddm-0.20.0-fix-use-development-sessions.patch
blob: 3213828181cadd26ae72faa187ea48f61f68ed4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
From 5b702ae986464fe6dbc8557d4b2da725ac1ed175 Mon Sep 17 00:00:00 2001
From: Fabian Vogt <fvogt@suse.de>
Date: Mon, 26 Jun 2023 09:52:05 +0200
Subject: [PATCH] Session: Parse .desktop files manually again

Using QSettings::IniFormat doesn't quite work. Implement a custom parser
for those files to handle them according to the specification.

Fixes #1745
---
 src/common/Session.cpp | 52 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 51 insertions(+), 1 deletion(-)

diff --git a/src/common/Session.cpp b/src/common/Session.cpp
index 4bb2142ca..5eec64859 100644
--- a/src/common/Session.cpp
+++ b/src/common/Session.cpp
@@ -34,6 +34,56 @@
 const QString s_entryExtention = QStringLiteral(".desktop");
 
 namespace SDDM {
+    // QSettings::IniFormat can't be used to read .desktop files due to different
+    // syntax of values (escape sequences, quoting, automatic QStringList detection).
+    // So implement yet another .desktop file parser.
+    class DesktopFileFormat {
+        static bool readFunc(QIODevice &device, QSettings::SettingsMap &map)
+        {
+            QString currentSectionName;
+            while(!device.atEnd())
+            {
+                // Iterate each line, remove line terminators
+                const auto line = device.readLine().replace("\r", "").replace("\n", "");
+                if(line.isEmpty() || line.startsWith('#'))
+                    continue; // Ignore empty lines and comments
+
+                if(line.startsWith('[')) // Section header
+                {
+                    // Remove [ and ].
+                    currentSectionName = QString::fromUtf8(line.mid(1, line.length() - 2));
+                }
+                else if(int equalsPos = line.indexOf('='); equalsPos > 0) // Key=Value
+                {
+                    const auto key = QString::fromUtf8(line.left(equalsPos));
+
+                    // Read the value, handle escape sequences
+                    auto valueBytes = line.mid(equalsPos + 1);
+                    valueBytes.replace("\\s", " ").replace("\\n", "\n");
+                    valueBytes.replace("\\t", "\t").replace("\\r", "\r");
+                    valueBytes.replace("\\\\", "\\");
+
+                    auto value = QString::fromUtf8(valueBytes);
+                    map.insert(currentSectionName + QLatin1Char('/') + key, value);
+                }
+            }
+
+            return true;
+        }
+    public:
+        // Register the .desktop file format if necessary, return its id.
+        static QSettings::Format format()
+        {
+            static QSettings::Format s_format = QSettings::InvalidFormat;
+            if (s_format == QSettings::InvalidFormat)
+                s_format = QSettings::registerFormat(QStringLiteral("desktop"),
+                                                     DesktopFileFormat::readFunc, nullptr,
+                                                     Qt::CaseSensitive);
+
+            return s_format;
+        }
+    };
+
     Session::Session()
         : m_valid(false)
         , m_type(UnknownSession)
@@ -169,7 +219,7 @@ namespace SDDM {
         if (!file.isOpen())
             return;
 
-        QSettings settings(m_fileName, QSettings::IniFormat);
+        QSettings settings(m_fileName, DesktopFileFormat::format());
 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
         settings.setIniCodec("UTF-8");
 #endif