summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-07-26 07:00:18 +0000
committerCoprDistGit <infra@openeuler.org>2023-07-26 07:00:18 +0000
commit4cc79aa789f3135241ebb34072cb88caf403d7d0 (patch)
tree6b6ec7296bf064560f419af6d5cde0b1531fa81c
parente45543c25ec2b3282d0b570bf76a0c486ee56d07 (diff)
-rw-r--r--.gitignore1
-rw-r--r--0001-Delay-for-logind-and-fallback-to-seat0.patch138
-rw-r--r--0001-Redesign-Xauth-handling.patch619
-rw-r--r--0001-Remove-suffix-for-Wayland-session.patch44
-rw-r--r--0001-Retry-starting-the-display-server.patch118
-rw-r--r--0016-Fix-sessions-being-started-as-the-wrong-type-on-auto.patch35
-rw-r--r--0018-wayland-session-Ensure-SHELL-remains-correctly-set.patch39
-rw-r--r--308fd0df2583b02251f0d80c397ccbf9fa7a9e04.patch216
-rw-r--r--3c92e9206dc2e17fa5dc13f37be2926e9131ce94.patch163
-rw-r--r--README.scripts2
-rw-r--r--sddm-0.18.0-environment_file.patch11
-rw-r--r--sddm-0.19.0-allow-hiding-wayland-sessions.patch57
-rw-r--r--sddm-autologin.pam20
-rw-r--r--sddm-systemd-sysusers.conf1
-rw-r--r--sddm.conf122
-rw-r--r--sddm.pam23
-rw-r--r--sddm.spec184
-rw-r--r--sddm.sysconfig5
-rw-r--r--sources1
-rw-r--r--tmpfiles-sddm.conf2
20 files changed, 1801 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..0a49112 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/sddm-0.19.0.tar.gz
diff --git a/0001-Delay-for-logind-and-fallback-to-seat0.patch b/0001-Delay-for-logind-and-fallback-to-seat0.patch
new file mode 100644
index 0000000..e2c9fed
--- /dev/null
+++ b/0001-Delay-for-logind-and-fallback-to-seat0.patch
@@ -0,0 +1,138 @@
+From 77a1f3148f515ae7c9b65f45dafe85bc58348ff9 Mon Sep 17 00:00:00 2001
+From: Jeremy Linton <jeremy.linton@arm.com>
+Date: Fri, 22 Oct 2021 14:51:54 -0500
+Subject: [PATCH] Delay for logind, and fallback to seat0
+
+There is systemd/logind race with when restarting
+sddm that causes logind1 not to be available. Previously
+this meant the seat0 was immediately created regardless
+of the state of CanGraphical.
+
+Fixing this, though we still want seat0 to be started
+if none of the seats appear to be graphical. Presumably
+there are some graphics on the machine ,otherwise
+why run sddm? Wait a bit, and create seat0 anyway. If
+this fails the output from Xorg should tell us why. This
+is generally a better strategy than what happens a goodly
+amount of time now, where sddm is started and silent about
+why the screen is blank.
+
+Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
+---
+ src/daemon/LogindDBusTypes.cpp | 31 +++++++++++++++++++++----------
+ src/daemon/SeatManager.cpp | 22 ++++++++++++++++++++++
+ src/daemon/SeatManager.h | 1 +
+ 3 files changed, 44 insertions(+), 10 deletions(-)
+
+diff --git a/src/daemon/LogindDBusTypes.cpp b/src/daemon/LogindDBusTypes.cpp
+index 011bb7f..e19f1db 100644
+--- a/src/daemon/LogindDBusTypes.cpp
++++ b/src/daemon/LogindDBusTypes.cpp
+@@ -8,6 +8,8 @@
+
+ #include <QDebug>
+
++#include <unistd.h>
++
+ class LogindPathInternal {
+ public:
+ LogindPathInternal();
+@@ -46,17 +48,26 @@ LogindPathInternal::LogindPathInternal()
+ qRegisterMetaType<UserInfoList>("UserInfoList");
+ qDBusRegisterMetaType<UserInfoList>();
+
+- if (QDBusConnection::systemBus().interface()->isServiceRegistered(QStringLiteral("org.freedesktop.login1"))) {
+- qDebug() << "Logind interface found";
+- available = true;
+- serviceName = QStringLiteral("org.freedesktop.login1");
+- managerPath = QStringLiteral("/org/freedesktop/login1");
+- managerIfaceName = QStringLiteral("org.freedesktop.login1.Manager");
+- seatIfaceName = QStringLiteral("org.freedesktop.login1.Seat");
+- sessionIfaceName = QStringLiteral("org.freedesktop.login1.Session");
+- userIfaceName = QStringLiteral("org.freedesktop.login1.User");
+- return;
++ // Fedora _should_ have a systemd-logind running, although because it takes a few moments to restart after
++ // systemctl isolate calls, it may not yet be running. Wait a few seconds for it, while blocking everything else.
++#ifdef HAVE_SYSTEMD
++ int logind_wait_seconds = 50;
++ while (logind_wait_seconds--) {
++ if (QDBusConnection::systemBus().interface()->isServiceRegistered(QStringLiteral("org.freedesktop.login1"))) {
++ qDebug() << "Logind interface found";
++ available = true;
++ serviceName = QStringLiteral("org.freedesktop.login1");
++ managerPath = QStringLiteral("/org/freedesktop/login1");
++ managerIfaceName = QStringLiteral("org.freedesktop.login1.Manager");
++ seatIfaceName = QStringLiteral("org.freedesktop.login1.Seat");
++ sessionIfaceName = QStringLiteral("org.freedesktop.login1.Session");
++ userIfaceName = QStringLiteral("org.freedesktop.login1.User");
++ return;
++ }
++ qDebug() << "Sleeping for systemd-logind";
++ usleep(100000);
+ }
++#endif
+
+ if (QDBusConnection::systemBus().interface()->isServiceRegistered(QStringLiteral("org.freedesktop.ConsoleKit"))) {
+ qDebug() << "Console kit interface found";
+diff --git a/src/daemon/SeatManager.cpp b/src/daemon/SeatManager.cpp
+index 60d22ea..96d2b82 100644
+--- a/src/daemon/SeatManager.cpp
++++ b/src/daemon/SeatManager.cpp
+@@ -26,6 +26,9 @@
+ #include <QDBusMessage>
+ #include <QDBusPendingReply>
+ #include <QDBusContext>
++#include <QDebug>
++#include <QFileInfo>
++#include <QTimer>
+
+ #include "LogindDBusTypes.h"
+
+@@ -115,6 +118,8 @@ namespace SDDM {
+
+ QDBusConnection::systemBus().connect(Logind::serviceName(), Logind::managerPath(), Logind::managerIfaceName(), QStringLiteral("SeatNew"), this, SLOT(logindSeatAdded(QString,QDBusObjectPath)));
+ QDBusConnection::systemBus().connect(Logind::serviceName(), Logind::managerPath(), Logind::managerIfaceName(), QStringLiteral("SeatRemoved"), this, SLOT(logindSeatRemoved(QString,QDBusObjectPath)));
++
++ QTimer::singleShot(5000, this, &SeatManager::checkSeat);
+ }
+
+ void SeatManager::createSeat(const QString &name) {
+@@ -152,6 +157,23 @@ namespace SDDM {
+ m_seats.value(name)->createDisplay();
+ }
+
++ // this is a bit hacky, but linux DRM drivers
++ // won't initially be available so there is a race
++ // between determing if a efifb/etc graphical object
++ // is the only graphics on the machine, or a DRM driver
++ // will take over the display. So we will hang out for a few
++ // seconds and if none of the seats are declared cangraphical
++ // its possible the only graphics on the machine don't have
++ // a drm driver.
++ void SeatManager::checkSeat(void) {
++ if (m_seats.isEmpty()) {
++ //if (QFileInfo::exists(QStringLiteral("/dev/fb0"))) {
++ qWarning() << "No graphical seats found, attempt to start one on the main console anyway...";
++ createSeat(QStringLiteral("seat0"));
++ //}
++ }
++ }
++
+ void SDDM::SeatManager::logindSeatAdded(const QString& name, const QDBusObjectPath& objectPath)
+ {
+ auto logindSeat = new LogindSeat(name, objectPath, this);
+diff --git a/src/daemon/SeatManager.h b/src/daemon/SeatManager.h
+index b2f9796..aa43047 100644
+--- a/src/daemon/SeatManager.h
++++ b/src/daemon/SeatManager.h
+@@ -49,6 +49,7 @@ namespace SDDM {
+ private:
+ QHash<QString, Seat *> m_seats; //these will exist only for graphical seats
+ QHash<QString, LogindSeat*> m_systemSeats; //these will exist for all seats
++ void checkSeat(void);
+ };
+ }
+
+--
+2.32.0
+
diff --git a/0001-Redesign-Xauth-handling.patch b/0001-Redesign-Xauth-handling.patch
new file mode 100644
index 0000000..088e736
--- /dev/null
+++ b/0001-Redesign-Xauth-handling.patch
@@ -0,0 +1,619 @@
+From fbdf20d59d1c63cd2b8fd78efb3125478a2ea07c Mon Sep 17 00:00:00 2001
+From: Fabian Vogt <fabian@ritter-vogt.de>
+Date: Wed, 21 Aug 2019 16:32:03 +0200
+Subject: [PATCH] Redesign Xauth handling
+
+This commit moves Xauthority handling over to libXau.
+Advantage is that this allows use of FamilyWild, is faster, more reliable
+and easier to read. However, we lose the ability to merge the new cookie into
+an existing Xauthority file, so support for using a non-temporary file is
+dropped. Even if merging was implemented manually, use of FamilyWild would
+"infect" such a file and break it for DMs which don't write it.
+
+Unfortunately, a hack in UserSession is required to get XAUTHORITY into
+the process environment. The Xauthority file has to be created as the target
+user, but that's only possible in setupChildProcess(). In there, changes to
+processEnvironment() to set XAUTHORITY to the generated path are not effective,
+so configure the process to inherit the environment instead and use qputenv.
+---
+ CMakeLists.txt | 3 ++
+ data/man/sddm.conf.rst.in | 8 ----
+ src/auth/Auth.cpp | 6 +--
+ src/auth/Auth.h | 6 +--
+ src/common/Configuration.h | 2 -
+ src/common/XauthUtils.cpp | 82 ++++++++++++++++++++++++++++++++
+ src/common/XauthUtils.h | 16 +++++++
+ src/daemon/CMakeLists.txt | 3 ++
+ src/daemon/XorgDisplayServer.cpp | 45 ++----------------
+ src/daemon/XorgDisplayServer.h | 4 +-
+ src/helper/Backend.cpp | 7 ---
+ src/helper/CMakeLists.txt | 8 +++-
+ src/helper/HelperApp.cpp | 4 +-
+ src/helper/HelperApp.h | 4 +-
+ src/helper/UserSession.cpp | 53 +++++++++++----------
+ src/helper/UserSession.h | 9 ++++
+ 16 files changed, 165 insertions(+), 95 deletions(-)
+ create mode 100644 src/common/XauthUtils.cpp
+ create mode 100644 src/common/XauthUtils.h
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index e52e0e9..fc3f2ce 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -88,6 +88,9 @@ add_feature_info("PAM" PAM_FOUND "PAM support")
+ include(CheckFunctionExists)
+ check_function_exists(getspnam HAVE_GETSPNAM)
+
++# XAU
++pkg_check_modules(LIBXAU REQUIRED "xau")
++
+ # XCB
+ find_package(XCB REQUIRED)
+
+diff --git a/data/man/sddm.conf.rst.in b/data/man/sddm.conf.rst.in
+index bee0768..e91280a 100644
+--- a/data/man/sddm.conf.rst.in
++++ b/data/man/sddm.conf.rst.in
+@@ -110,10 +110,6 @@ OPTIONS
+ Path of the Xephyr.
+ Default value is "/usr/bin/Xephyr".
+
+-`XauthPath=`
+- Path of the Xauth.
+- Default value is "/usr/bin/xauth".
+-
+ `SessionDir=`
+ Path of the directory containing session files.
+ Default value is "/usr/share/xsessions".
+@@ -128,10 +124,6 @@ OPTIONS
+ Path to the user session log file, relative to the home directory.
+ Default value is ".local/share/sddm/xorg-session.log".
+
+-`UserAuthFile=`
+- Path to the Xauthority file, relative to the home directory.
+- Default value is ".Xauthority".
+-
+ `DisplayCommand=`
+ Path of script to execute when starting the display server.
+ Default value is "@DATA_INSTALL_DIR@/scripts/Xsetup".
+diff --git a/src/auth/Auth.cpp b/src/auth/Auth.cpp
+index caca314..c2228ae 100644
+--- a/src/auth/Auth.cpp
++++ b/src/auth/Auth.cpp
+@@ -64,7 +64,7 @@ namespace SDDM {
+ QLocalSocket *socket { nullptr };
+ QString sessionPath { };
+ QString user { };
+- QString cookie { };
++ QByteArray cookie { };
+ bool autologin { false };
+ bool greeter { false };
+ QProcessEnvironment environment { };
+@@ -266,7 +266,7 @@ namespace SDDM {
+ return d->greeter;
+ }
+
+- const QString& Auth::cookie() const {
++ const QByteArray& Auth::cookie() const {
+ return d->cookie;
+ }
+
+@@ -298,7 +298,7 @@ namespace SDDM {
+ d->environment.insert(key, value);
+ }
+
+- void Auth::setCookie(const QString& cookie) {
++ void Auth::setCookie(const QByteArray& cookie) {
+ if (cookie != d->cookie) {
+ d->cookie = cookie;
+ Q_EMIT cookieChanged();
+diff --git a/src/auth/Auth.h b/src/auth/Auth.h
+index 87f5f44..38d63fc 100644
+--- a/src/auth/Auth.h
++++ b/src/auth/Auth.h
+@@ -54,7 +54,7 @@ namespace SDDM {
+ Q_PROPERTY(bool autologin READ autologin WRITE setAutologin NOTIFY autologinChanged)
+ Q_PROPERTY(bool greeter READ isGreeter WRITE setGreeter NOTIFY greeterChanged)
+ Q_PROPERTY(bool verbose READ verbose WRITE setVerbose NOTIFY verboseChanged)
+- Q_PROPERTY(QString cookie READ cookie WRITE setCookie NOTIFY cookieChanged)
++ Q_PROPERTY(QByteArray cookie READ cookie WRITE setCookie NOTIFY cookieChanged)
+ Q_PROPERTY(QString user READ user WRITE setUser NOTIFY userChanged)
+ Q_PROPERTY(QString session READ session WRITE setSession NOTIFY sessionChanged)
+ Q_PROPERTY(AuthRequest* request READ request NOTIFY requestChanged)
+@@ -90,7 +90,7 @@ namespace SDDM {
+ bool autologin() const;
+ bool isGreeter() const;
+ bool verbose() const;
+- const QString &cookie() const;
++ const QByteArray &cookie() const;
+ const QString &user() const;
+ const QString &session() const;
+ AuthRequest *request();
+@@ -149,7 +149,7 @@ namespace SDDM {
+ * Set the display server cookie, to be inserted into the user's $XAUTHORITY
+ * @param cookie cookie data
+ */
+- void setCookie(const QString &cookie);
++ void setCookie(const QByteArray &cookie);
+
+ public Q_SLOTS:
+ /**
+diff --git a/src/common/Configuration.h b/src/common/Configuration.h
+index cf44a62..a7e0585 100644
+--- a/src/common/Configuration.h
++++ b/src/common/Configuration.h
+@@ -63,11 +63,9 @@ namespace SDDM {
+ Entry(ServerPath, QString, _S("/usr/bin/X"), _S("Path to X server binary"));
+ Entry(ServerArguments, QString, _S("-nolisten tcp"), _S("Arguments passed to the X server invocation"));
+ Entry(XephyrPath, QString, _S("/usr/bin/Xephyr"), _S("Path to Xephyr binary"));
+- Entry(XauthPath, QString, _S("/usr/bin/xauth"), _S("Path to xauth binary"));
+ Entry(SessionDir, QString, _S("/usr/share/xsessions"), _S("Directory containing available X sessions"));
+ Entry(SessionCommand, QString, _S(SESSION_COMMAND), _S("Path to a script to execute when starting the desktop session"));
+ Entry(SessionLogFile, QString, _S(".local/share/sddm/xorg-session.log"), _S("Path to the user session log file"));
+- Entry(UserAuthFile, QString, _S(".Xauthority"), _S("Path to the Xauthority file"));
+ Entry(DisplayCommand, QString, _S(DATA_INSTALL_DIR "/scripts/Xsetup"), _S("Path to a script to execute when starting the display server"));
+ Entry(DisplayStopCommand, QString, _S(DATA_INSTALL_DIR "/scripts/Xstop"), _S("Path to a script to execute when stopping the display server"));
+ Entry(MinimumVT, int, MINIMUM_VT, _S("The lowest virtual terminal number that will be used."));
+diff --git a/src/common/XauthUtils.cpp b/src/common/XauthUtils.cpp
+new file mode 100644
+index 0000000..da1c691
+--- /dev/null
++++ b/src/common/XauthUtils.cpp
+@@ -0,0 +1,82 @@
++/****************************************************************************
++ * SPDX-FileCopyrightText: 2020 Fabian Vogt <fvogt@suse.de>
++ *
++ * SPDX-License-Identifier: GPL-2.0-or-later
++ ***************************************************************************/
++
++#include <limits.h>
++#include <unistd.h>
++#include <X11/Xauth.h>
++
++#include <random>
++
++#include <QString>
++
++#include "XauthUtils.h"
++
++namespace SDDM { namespace Xauth {
++ QByteArray generateCookie()
++ {
++ std::random_device rd;
++ std::mt19937 gen(rd());
++ std::uniform_int_distribution<> dis(0, 0xFF);
++
++ QByteArray cookie;
++ cookie.reserve(16);
++
++ for(int i = 0; i < 16; i++)
++ cookie[i] = dis(gen);
++
++ return cookie;
++ }
++
++ bool writeCookieToFile(const QString &filename, const QString &display, QByteArray cookie)
++ {
++ if(display.size() < 2 || display[0] != QLatin1Char(':') || cookie.count() != 16)
++ return false;
++
++ // Truncate the file. We don't support merging like the xauth tool does.
++ FILE * const authFp = fopen(qPrintable(filename), "wb");
++ if (authFp == nullptr)
++ return false;
++
++ char localhost[HOST_NAME_MAX + 1] = "";
++ if (gethostname(localhost, HOST_NAME_MAX) < 0)
++ strcpy(localhost, "localhost");
++
++ ::Xauth auth = {};
++ char cookieName[] = "MIT-MAGIC-COOKIE-1";
++
++ // Skip the ':'
++ QByteArray displayNumberUtf8 = display.midRef(1).toUtf8();
++
++ auth.family = FamilyLocal;
++ auth.address = localhost;
++ auth.address_length = strlen(auth.address);
++ auth.number = displayNumberUtf8.data();
++ auth.number_length = displayNumberUtf8.size();
++ auth.name = cookieName;
++ auth.name_length = sizeof(cookieName) - 1;
++ auth.data = cookie.data();
++ auth.data_length = cookie.count();
++
++ if (XauWriteAuth(authFp, &auth) == 0) {
++ fclose(authFp);
++ return false;
++ }
++
++ // Write the same entry again, just with FamilyWild
++ auth.family = FamilyWild;
++ auth.address_length = 0;
++ if (XauWriteAuth(authFp, &auth) == 0) {
++ fclose(authFp);
++ return false;
++ }
++
++ bool success = fflush(authFp) != EOF;
++
++ fclose(authFp);
++
++ return success;
++ }
++}}
+diff --git a/src/common/XauthUtils.h b/src/common/XauthUtils.h
+new file mode 100644
+index 0000000..112d003
+--- /dev/null
++++ b/src/common/XauthUtils.h
+@@ -0,0 +1,16 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++
++#ifndef SDDM_XAUTHUTILS_H
++#define SDDM_XAUTHUTILS_H
++
++class QString;
++class QByteArray;
++
++namespace SDDM {
++ namespace Xauth {
++ QByteArray generateCookie();
++ bool writeCookieToFile(const QString &filename, const QString &display, QByteArray cookie);
++ }
++}
++
++#endif // SDDM_XAUTHUTILS_H
+diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt
+index 86d014b..9145607 100644
+--- a/src/daemon/CMakeLists.txt
++++ b/src/daemon/CMakeLists.txt
+@@ -2,6 +2,7 @@ include_directories(
+ "${CMAKE_SOURCE_DIR}/src/common"
+ "${CMAKE_SOURCE_DIR}/src/auth"
+ "${CMAKE_BINARY_DIR}/src/common"
++ ${LIBXAU_INCLUDE_DIRS}
+ "${LIBXCB_INCLUDE_DIR}"
+ )
+
+@@ -13,6 +14,7 @@ set(DAEMON_SOURCES
+ ${CMAKE_SOURCE_DIR}/src/common/ThemeMetadata.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/Session.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/SocketWriter.cpp
++ ${CMAKE_SOURCE_DIR}/src/common/XauthUtils.cpp
+ ${CMAKE_SOURCE_DIR}/src/auth/Auth.cpp
+ ${CMAKE_SOURCE_DIR}/src/auth/AuthPrompt.cpp
+ ${CMAKE_SOURCE_DIR}/src/auth/AuthRequest.cpp
+@@ -64,6 +66,7 @@ target_link_libraries(sddm
+ Qt5::DBus
+ Qt5::Network
+ Qt5::Qml
++ ${LIBXAU_LIBRARIES}
+ ${LIBXCB_LIBRARIES})
+ if(PAM_FOUND)
+ target_link_libraries(sddm ${PAM_LIBRARIES})
+diff --git a/src/daemon/XorgDisplayServer.cpp b/src/daemon/XorgDisplayServer.cpp
+index 5f93a1b..148ebcc 100644
+--- a/src/daemon/XorgDisplayServer.cpp
++++ b/src/daemon/XorgDisplayServer.cpp
+@@ -25,6 +25,7 @@
+ #include "Display.h"
+ #include "SignalHandler.h"
+ #include "Seat.h"
++#include "XauthUtils.h"
+
+ #include <QDebug>
+ #include <QFile>
+@@ -55,17 +56,7 @@ namespace SDDM {
+ m_authPath = QStringLiteral("%1/%2").arg(authDir).arg(QUuid::createUuid().toString());
+
+ // generate cookie
+- std::random_device rd;
+- std::mt19937 gen(rd());
+- std::uniform_int_distribution<> dis(0, 15);
+-
+- // resever 32 bytes
+- m_cookie.reserve(32);
+-
+- // create a random hexadecimal number
+- const char *digits = "0123456789abcdef";
+- for (int i = 0; i < 32; ++i)
+- m_cookie[i] = digits[dis(gen)];
++ m_cookie = Xauth::generateCookie();
+ }
+
+ XorgDisplayServer::~XorgDisplayServer() {
+@@ -84,35 +75,10 @@ namespace SDDM {
+ return QStringLiteral("x11");
+ }
+
+- const QString &XorgDisplayServer::cookie() const {
++ const QByteArray &XorgDisplayServer::cookie() const {
+ return m_cookie;
+ }
+
+- bool XorgDisplayServer::addCookie(const QString &file) {
+- // log message
+- qDebug() << "Adding cookie to" << file;
+-
+- // Touch file
+- QFile file_handler(file);
+- file_handler.open(QIODevice::Append);
+- file_handler.close();
+-
+- QString cmd = QStringLiteral("%1 -f %2 -q").arg(mainConfig.X11.XauthPath.get()).arg(file);
+-
+- // execute xauth
+- FILE *fp = popen(qPrintable(cmd), "w");
+-
+- // check file
+- if (!fp)
+- return false;
+- fprintf(fp, "remove %s\n", qPrintable(m_display));
+- fprintf(fp, "add %s . %s\n", qPrintable(m_display), qPrintable(m_cookie));
+- fprintf(fp, "exit\n");
+-
+- // close pipe
+- return pclose(fp) == 0;
+- }
+-
+ bool XorgDisplayServer::start() {
+ // check flag
+ if (m_started)
+@@ -130,8 +96,7 @@ namespace SDDM {
+ // generate auth file.
+ // For the X server's copy, the display number doesn't matter.
+ // An empty file would result in no access control!
+- m_display = QStringLiteral(":0");
+- if(!addCookie(m_authPath)) {
++ if(!Xauth::writeCookieToFile(m_authPath, QStringLiteral(":0"), m_cookie)) {
+ qCritical() << "Failed to write xauth file";
+ return false;
+ }
+@@ -229,7 +194,7 @@ namespace SDDM {
+ // The file is also used by the greeter, which does care about the
+ // display number. Write the proper entry, if it's different.
+ if(m_display != QStringLiteral(":0")) {
+- if(!addCookie(m_authPath)) {
++ if(!Xauth::writeCookieToFile(m_authPath, m_display, m_cookie)) {
+ qCritical() << "Failed to write xauth file";
+ return false;
+ }
+diff --git a/src/daemon/XorgDisplayServer.h b/src/daemon/XorgDisplayServer.h
+index e97a0b5..05e0a4c 100644
+--- a/src/daemon/XorgDisplayServer.h
++++ b/src/daemon/XorgDisplayServer.h
+@@ -38,7 +38,7 @@ namespace SDDM {
+
+ QString sessionType() const;
+
+- const QString &cookie() const;
++ const QByteArray &cookie() const;
+
+ bool addCookie(const QString &file);
+
+@@ -50,7 +50,7 @@ namespace SDDM {
+
+ private:
+ QString m_authPath;
+- QString m_cookie;
++ QByteArray m_cookie;
+
+ QProcess *process { nullptr };
+
+diff --git a/src/helper/Backend.cpp b/src/helper/Backend.cpp
+index a324b39..a053310 100644
+--- a/src/helper/Backend.cpp
++++ b/src/helper/Backend.cpp
+@@ -68,13 +68,6 @@ namespace SDDM {
+ env.insert(QStringLiteral("SHELL"), QString::fromLocal8Bit(pw->pw_shell));
+ env.insert(QStringLiteral("USER"), QString::fromLocal8Bit(pw->pw_name));
+ env.insert(QStringLiteral("LOGNAME"), QString::fromLocal8Bit(pw->pw_name));
+- if (env.contains(QStringLiteral("DISPLAY")) && !env.contains(QStringLiteral("XAUTHORITY"))) {
+- // determine Xauthority path
+- QString value = QStringLiteral("%1/%2")
+- .arg(QString::fromLocal8Bit(pw->pw_dir))
+- .arg(mainConfig.X11.UserAuthFile.get());
+- env.insert(QStringLiteral("XAUTHORITY"), value);
+- }
+ #if defined(Q_OS_FREEBSD)
+ /* get additional environment variables via setclassenvironment();
+ this needs to be done here instead of in UserSession::setupChildProcess
+diff --git a/src/helper/CMakeLists.txt b/src/helper/CMakeLists.txt
+index 8914ea7..81b939b 100644
+--- a/src/helper/CMakeLists.txt
++++ b/src/helper/CMakeLists.txt
+@@ -3,6 +3,7 @@ include(CheckLibraryExists)
+ include_directories(
+ "${CMAKE_SOURCE_DIR}/src/common"
+ "${CMAKE_SOURCE_DIR}/src/auth"
++ ${LIBXAU_INCLUDE_DIRS}
+ )
+ include_directories("${CMAKE_BINARY_DIR}/src/common")
+
+@@ -10,6 +11,7 @@ set(HELPER_SOURCES
+ ${CMAKE_SOURCE_DIR}/src/common/Configuration.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/ConfigReader.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/SafeDataStream.cpp
++ ${CMAKE_SOURCE_DIR}/src/common/XauthUtils.cpp
+ Backend.cpp
+ HelperApp.cpp
+ UserSession.cpp
+@@ -41,7 +43,11 @@ else()
+ endif()
+
+ add_executable(sddm-helper ${HELPER_SOURCES})
+-target_link_libraries(sddm-helper Qt5::Network Qt5::DBus Qt5::Qml)
++target_link_libraries(sddm-helper
++ Qt5::Network
++ Qt5::DBus
++ Qt5::Qml
++ ${LIBXAU_LIBRARIES})
+ if("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
+ # On FreeBSD (possibly other BSDs as well), we want to use
+ # setusercontext() to set up the login configuration from login.conf
+diff --git a/src/helper/HelperApp.cpp b/src/helper/HelperApp.cpp
+index 672359a..4ad9cbd 100644
+--- a/src/helper/HelperApp.cpp
++++ b/src/helper/HelperApp.cpp
+@@ -237,7 +237,7 @@ namespace SDDM {
+ str >> m >> env >> m_cookie;
+ if (m != AUTHENTICATED) {
+ env = QProcessEnvironment();
+- m_cookie = QString();
++ m_cookie = {};
+ qCritical() << "Received a wrong opcode instead of AUTHENTICATED:" << m;
+ }
+ return env;
+@@ -263,7 +263,7 @@ namespace SDDM {
+ return m_user;
+ }
+
+- const QString& HelperApp::cookie() const {
++ const QByteArray& HelperApp::cookie() const {
+ return m_cookie;
+ }
+
+diff --git a/src/helper/HelperApp.h b/src/helper/HelperApp.h
+index 3742df1..d417494 100644
+--- a/src/helper/HelperApp.h
++++ b/src/helper/HelperApp.h
+@@ -40,7 +40,7 @@ namespace SDDM {
+
+ UserSession *session();
+ const QString &user() const;
+- const QString &cookie() const;
++ const QByteArray &cookie() const;
+
+ public slots:
+ Request request(const Request &request);
+@@ -62,7 +62,7 @@ namespace SDDM {
+ QLocalSocket *m_socket { nullptr };
+ QString m_user { };
+ // TODO: get rid of this in a nice clean way along the way with moving to user session X server
+- QString m_cookie { };
++ QByteArray m_cookie { };
+
+ /*!
+ \brief Write utmp/wtmp/btmp records when a user logs in
+diff --git a/src/helper/UserSession.cpp b/src/helper/UserSession.cpp
+index c9a8a20..e55e69e 100644
+--- a/src/helper/UserSession.cpp
++++ b/src/helper/UserSession.cpp
+@@ -23,6 +23,7 @@
+ #include "UserSession.h"
+ #include "HelperApp.h"
+ #include "VirtualTerminal.h"
++#include "XauthUtils.h"
+
+ #include <sys/types.h>
+ #include <sys/ioctl.h>
+@@ -35,6 +36,8 @@
+ #include <fcntl.h>
+ #include <sched.h>
+
++#include <QStandardPaths>
++
+ namespace SDDM {
+ UserSession::UserSession(HelperApp *parent)
+ : QProcess(parent) {
+@@ -260,38 +263,38 @@ namespace SDDM {
+ qWarning() << "Could not redirect stdout";
+ }
+
++ // Drop the current environment
++ for (QString key : QProcessEnvironment::systemEnvironment().keys())
++ qunsetenv(qPrintable(key));
++
++ // Apply the new one. This has the nice effect that XDG_RUNTIME_DIR etc are effective
++ for (QString key : processEnvironment().keys())
++ qputenv(qPrintable(key), processEnvironment().value(key).toLocal8Bit());
++
+ // set X authority for X11 sessions only
+ if (sessionType != QLatin1String("x11"))
+ return;
+- QString cookie = qobject_cast<HelperApp*>(parent())->cookie();
+- if (!cookie.isEmpty()) {
+- QString file = processEnvironment().value(QStringLiteral("XAUTHORITY"));
+- QString display = processEnvironment().value(QStringLiteral("DISPLAY"));
+- qDebug() << "Adding cookie to" << file;
+-
+-
+- // create the path
+- QFileInfo finfo(file);
+- QDir().mkpath(finfo.absolutePath());
+
+- QFile file_handler(file);
+- file_handler.open(QIODevice::Append);
+- file_handler.close();
+-
+- QString cmd = QStringLiteral("%1 -f %2 -q").arg(mainConfig.X11.XauthPath.get()).arg(file);
++ QByteArray cookie = qobject_cast<HelperApp*>(parent())->cookie();
++ if (cookie.isEmpty())
++ return;
+
+- // execute xauth
+- FILE *fp = popen(qPrintable(cmd), "w");
++ QString dir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
++ if (!dir.isEmpty()) {
++ m_xauthFile.setFileTemplate(dir + QStringLiteral("/xauth_XXXXXX"));
++ m_xauthFile.open();
++ }
+
+- // check file
+- if (!fp)
+- return;
+- fprintf(fp, "remove %s\n", qPrintable(display));
+- fprintf(fp, "add %s . %s\n", qPrintable(display), qPrintable(cookie));
+- fprintf(fp, "exit\n");
++ if (m_xauthFile.fileName().isEmpty())
++ qWarning() << "Could not create the Xauthority file";
++ else {
++ QString display = processEnvironment().value(QStringLiteral("DISPLAY"));
++ qDebug() << "Adding cookie to" << m_xauthFile.fileName();
+
+- // close pipe
+- pclose(fp);
++ if (!Xauth::writeCookieToFile(m_xauthFile.fileName(), display, cookie))
++ qWarning() << "Failed to write the Xauthority file";
++ else
++ qputenv("XAUTHORITY", m_xauthFile.fileName().toUtf8());
+ }
+ }
+
+diff --git a/src/helper/UserSession.h b/src/helper/UserSession.h
+index 7069084..23776f4 100644
+--- a/src/helper/UserSession.h
++++ b/src/helper/UserSession.h
+@@ -25,6 +25,7 @@
+ #include <QtCore/QObject>
+ #include <QtCore/QString>
+ #include <QtCore/QProcess>
++#include <QtCore/QTemporaryFile>
+
+ namespace SDDM {
+ class HelperApp;
+@@ -53,12 +54,20 @@ namespace SDDM {
+ */
+ qint64 cachedProcessId();
+
++ /* Hack! QProcess does not allow changing processEnvironment by
++ setupChildProcess(), but this is needed for creating XAUTHORITY.
++ So inherit the caller's environment and apply the assignments manually. */
++ QProcessEnvironment processEnvironment() { return m_processEnv; }
++ void setProcessEnvironment(QProcessEnvironment env) { m_processEnv = env; }
++
+ protected:
+ void setupChildProcess();
+
+ private:
+ QString m_path { };
+ qint64 m_cachedProcessId;
++ QProcessEnvironment m_processEnv;
++ QTemporaryFile m_xauthFile;
+ };
+ }
+
+--
+2.25.1
+
diff --git a/0001-Remove-suffix-for-Wayland-session.patch b/0001-Remove-suffix-for-Wayland-session.patch
new file mode 100644
index 0000000..656d75e
--- /dev/null
+++ b/0001-Remove-suffix-for-Wayland-session.patch
@@ -0,0 +1,44 @@
+From 0f207a9cc6c0fda8ff47f53598404e1c878f7610 Mon Sep 17 00:00:00 2001
+From: Pier Luigi Fiorini <pierluigi.fiorini@liri.io>
+Date: Tue, 20 Mar 2018 18:22:39 +0100
+Subject: [PATCH] Remove suffix for Wayland session
+
+Some desktops like GNOME specify which windowing system is in use
+with the Name entry of their desktop file.
+
+For Wayland-only desktops such as Liri this information is
+redundant and so is for X11-only window managers.
+
+Do not append the Wayland suffix and let desktops handle it
+themeselves.
+
+[ChangeLog][Greeter] Remove suffix for Wayland sessions
+---
+ src/common/Session.cpp | 11 ++---------
+ 1 file changed, 2 insertions(+), 9 deletions(-)
+
+diff --git a/src/common/Session.cpp b/src/common/Session.cpp
+index 2d7b04f..cb4cef7 100644
+--- a/src/common/Session.cpp
++++ b/src/common/Session.cpp
+@@ -157,15 +157,8 @@ namespace SDDM {
+ if (current_section != QLatin1String("Desktop Entry"))
+ continue; // We are only interested in the "Desktop Entry" section
+
+- if (line.startsWith(QLatin1String("Name="))) {
+- if (type == WaylandSession)
+- if (line.mid(5).endsWith(QLatin1String(" (Wayland)")))
+- m_displayName = QObject::tr("%1").arg(line.mid(5));
+- else
+- m_displayName = QObject::tr("%1 (Wayland)").arg(line.mid(5));
+- else
+- m_displayName = line.mid(5);
+- }
++ if (line.startsWith(QLatin1String("Name=")))
++ m_displayName = line.mid(5);
+ if (line.startsWith(QLatin1String("Comment=")))
+ m_comment = line.mid(8);
+ if (line.startsWith(QLatin1String("Exec=")))
+--
+2.25.1
+
diff --git a/0001-Retry-starting-the-display-server.patch b/0001-Retry-starting-the-display-server.patch
new file mode 100644
index 0000000..18fcff4
--- /dev/null
+++ b/0001-Retry-starting-the-display-server.patch
@@ -0,0 +1,118 @@
+From 42c51761cc82edbaa50d702a4614e179ad4bcd63 Mon Sep 17 00:00:00 2001
+From: Fabian Vogt <fabian@ritter-vogt.de>
+Date: Thu, 12 Nov 2020 20:30:55 +0100
+Subject: [PATCH] Retry starting the display server
+
+Even if the CanGraphical property of a Seat is true, it's possible that it's
+still too early for X to start, as it might need some driver or device which
+isn't present yet.
+
+Fixes #1316
+---
+ src/daemon/Seat.cpp | 23 ++++++++++++++++++-----
+ src/daemon/Seat.h | 4 +++-
+ src/daemon/XorgDisplayServer.cpp | 10 ++++++----
+ 3 files changed, 27 insertions(+), 10 deletions(-)
+
+diff --git a/src/daemon/Seat.cpp b/src/daemon/Seat.cpp
+index eef26da..838c222 100644
+--- a/src/daemon/Seat.cpp
++++ b/src/daemon/Seat.cpp
+@@ -28,6 +28,7 @@
+
+ #include <QDebug>
+ #include <QFile>
++#include <QTimer>
+
+ #include <functional>
+
+@@ -52,7 +53,7 @@ namespace SDDM {
+ return m_name;
+ }
+
+- bool Seat::createDisplay(int terminalId) {
++ void Seat::createDisplay(int terminalId) {
+ //reload config if needed
+ mainConfig.load();
+
+@@ -84,12 +85,24 @@ namespace SDDM {
+ m_displays << display;
+
+ // start the display
+- if (!display->start()) {
+- qCritical() << "Could not start Display server on vt" << terminalId;
+- return false;
++ startDisplay(display);
++ }
++
++ void Seat::startDisplay(Display *display, int tryNr) {
++ if (display->start())
++ return;
++
++ // It's possible that the system isn't ready yet (driver not loaded,
++ // device not enumerated, ...). It's not possible to tell when that changes,
++ // so try a few times with a delay in between.
++ qWarning() << "Attempt" << tryNr << "starting the Display server on vt" << display->terminalId() << "failed";
++
++ if(tryNr >= 3) {
++ qCritical() << "Could not start Display server on vt" << display->terminalId();
++ return;
+ }
+
+- return true;
++ QTimer::singleShot(2000, display, [=] { startDisplay(display, tryNr + 1); });
+ }
+
+ void Seat::removeDisplay(Display* display) {
+diff --git a/src/daemon/Seat.h b/src/daemon/Seat.h
+index bf22566..f9fe733 100644
+--- a/src/daemon/Seat.h
++++ b/src/daemon/Seat.h
+@@ -35,13 +35,15 @@ namespace SDDM {
+ const QString &name() const;
+
+ public slots:
+- bool createDisplay(int terminalId = -1);
++ void createDisplay(int terminalId = -1);
+ void removeDisplay(SDDM::Display* display);
+
+ private slots:
+ void displayStopped();
+
+ private:
++ void startDisplay(SDDM::Display *display, int tryNr = 1);
++
+ QString m_name;
+
+ QVector<Display *> m_displays;
+diff --git a/src/daemon/XorgDisplayServer.cpp b/src/daemon/XorgDisplayServer.cpp
+index e60c022..5f40fe8 100644
+--- a/src/daemon/XorgDisplayServer.cpp
++++ b/src/daemon/XorgDisplayServer.cpp
+@@ -248,6 +248,12 @@ namespace SDDM {
+ }
+
+ void XorgDisplayServer::finished() {
++ // clean up
++ if (process) {
++ process->deleteLater();
++ process = nullptr;
++ }
++
+ // check flag
+ if (!m_started)
+ return;
+@@ -283,10 +289,6 @@ namespace SDDM {
+ displayStopScript->deleteLater();
+ displayStopScript = nullptr;
+
+- // clean up
+- process->deleteLater();
+- process = nullptr;
+-
+ // remove authority file
+ QFile::remove(m_authPath);
+
+--
+2.31.1
+
diff --git a/0016-Fix-sessions-being-started-as-the-wrong-type-on-auto.patch b/0016-Fix-sessions-being-started-as-the-wrong-type-on-auto.patch
new file mode 100644
index 0000000..665001f
--- /dev/null
+++ b/0016-Fix-sessions-being-started-as-the-wrong-type-on-auto.patch
@@ -0,0 +1,35 @@
+From e81dfcd6913c4fbd1801597168291b1e396633d8 Mon Sep 17 00:00:00 2001
+From: Fabian Vogt <fabian@ritter-vogt.de>
+Date: Wed, 6 Jan 2021 16:00:34 +0100
+Subject: [PATCH 16/18] Fix sessions being started as the wrong type on
+ autologin
+
+For autologin, the last session is used, which contains a full path.
+Display::findSessionEntry didn't handle that correctly, which led to
+X11 sessions getting started as Wayland ones (or the other way around
+before 994fa67).
+
+Fixes #1348
+---
+ src/daemon/Display.cpp | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/daemon/Display.cpp b/src/daemon/Display.cpp
+index b95f6e5..9f1fabc 100644
+--- a/src/daemon/Display.cpp
++++ b/src/daemon/Display.cpp
+@@ -245,6 +245,11 @@ namespace SDDM {
+ }
+
+ bool Display::findSessionEntry(const QDir &dir, const QString &name) const {
++ // Given an absolute path: Check that it matches dir
++ const QFileInfo fileInfo(name);
++ if (fileInfo.isAbsolute() && fileInfo.absolutePath() != dir.absolutePath())
++ return false;
++
+ QString fileName = name;
+
+ // append extension
+--
+2.29.2
+
diff --git a/0018-wayland-session-Ensure-SHELL-remains-correctly-set.patch b/0018-wayland-session-Ensure-SHELL-remains-correctly-set.patch
new file mode 100644
index 0000000..8ebbef1
--- /dev/null
+++ b/0018-wayland-session-Ensure-SHELL-remains-correctly-set.patch
@@ -0,0 +1,39 @@
+From bc5a18f34c0881929a6b2e5d3993971c4f692f4f Mon Sep 17 00:00:00 2001
+From: Neal Gompa <ngompa13@gmail.com>
+Date: Sun, 17 Jan 2021 11:48:28 -0500
+Subject: [PATCH 18/18] wayland-session: Ensure $SHELL remains correctly set
+
+In some circumstances, the effort of setting the environment
+correctly can wind up clobbering the user-specified shell. To
+work around this issue, capture the shell setting in a variable
+and set it back at the end of environment and profile setup.
+---
+ data/scripts/wayland-session | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/data/scripts/wayland-session b/data/scripts/wayland-session
+index de4f519..1f90554 100755
+--- a/data/scripts/wayland-session
++++ b/data/scripts/wayland-session
+@@ -6,6 +6,10 @@
+ # Copyright (C) 2001-2005 Oswald Buddenhagen <ossi@kde.org>
+
+ # Note that the respective logout scripts are not sourced.
++
++# Backup the user shell setting into SDDM specific variable
++SDDM_USER_SHELL=$SHELL
++
+ case $SHELL in
+ */bash)
+ [ -z "$BASH" ] && exec $SHELL $0 "$@"
+@@ -50,4 +54,7 @@ case $SHELL in
+ ;;
+ esac
+
++# Restore user shell setting that may have been clobbered by setting environment
++export SHELL=$SDDM_USER_SHELL
++
+ exec $@
+--
+2.29.2
+
diff --git a/308fd0df2583b02251f0d80c397ccbf9fa7a9e04.patch b/308fd0df2583b02251f0d80c397ccbf9fa7a9e04.patch
new file mode 100644
index 0000000..1bef47c
--- /dev/null
+++ b/308fd0df2583b02251f0d80c397ccbf9fa7a9e04.patch
@@ -0,0 +1,216 @@
+From 308fd0df2583b02251f0d80c397ccbf9fa7a9e04 Mon Sep 17 00:00:00 2001
+From: Pier Luigi Fiorini <pierluigi.fiorini@liri.io>
+Date: Sun, 28 Feb 2021 12:07:33 +0100
+Subject: [PATCH] Allocate VT for the display
+
+Replace the old crude algorithm to find the next available VT with a
+more reliable method using the VT_OPENQRY ioctl.
+
+General.MinimumVT setting is now obsolete and it's no longer used.
+---
+ CMakeLists.txt | 4 ----
+ data/man/sddm.conf.rst.in | 2 +-
+ src/common/Configuration.h | 1 -
+ src/common/Constants.h.in | 1 -
+ src/daemon/Display.cpp | 8 +++++---
+ src/daemon/Display.h | 2 +-
+ src/daemon/Seat.cpp | 38 +++-----------------------------------
+ src/daemon/Seat.h | 3 +--
+ 8 files changed, 11 insertions(+), 48 deletions(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index e52e0e90..9614b4e1 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -141,7 +141,6 @@ if(SYSTEMD_FOUND)
+ string(REGEX REPLACE "[ \t\n]+" "" SYSTEMD_SYSTEM_UNIT_DIR ${SYSTEMD_SYSTEM_UNIT_DIR})
+ endif()
+
+- set(MINIMUM_VT 1)
+ set(HALT_COMMAND "/usr/bin/systemctl poweroff")
+ set(REBOOT_COMMAND "/usr/bin/systemctl reboot")
+ else()
+@@ -159,7 +158,6 @@ if(ELOGIND_FOUND)
+ add_definitions(-DHAVE_ELOGIND)
+ set(CMAKE_AUTOMOC_MOC_OPTIONS -DHAVE_ELOGIND)
+
+- set(MINIMUM_VT 7)
+ set(HALT_COMMAND "/usr/bin/loginctl poweroff")
+ set(REBOOT_COMMAND "/usr/bin/loginctl reboot")
+ endif()
+@@ -171,10 +169,8 @@ if (NOT ELOGIND_FOUND AND NOT SYSTEMD_FOUND)
+ # commands for shutdown and reboot. On FreeBSD, there are
+ # normally more getty's running than on Linux.
+ if("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
+- set(MINIMUM_VT 9)
+ set(HALT_COMMAND "/sbin/shutdown -p now")
+ else()
+- set(MINIMUM_VT 7)
+ set(HALT_COMMAND "/sbin/shutdown -h -P now")
+ endif()
+ set(REBOOT_COMMAND "/sbin/shutdown -r now")
+diff --git a/data/man/sddm.conf.rst.in b/data/man/sddm.conf.rst.in
+index bee07681..1061540c 100644
+--- a/data/man/sddm.conf.rst.in
++++ b/data/man/sddm.conf.rst.in
+@@ -144,7 +144,7 @@ OPTIONS
+ Minimum virtual terminal number that will be used
+ by the first display. Virtual terminal number will
+ increase as new displays added.
+- Default value is @MINIMUM_VT@.
++ This setting is no longer available since SDDM v0.20.
+
+ `EnableHiDPI=`
+ Enables Qt's automatic HiDPI scaling.
+diff --git a/src/common/Configuration.h b/src/common/Configuration.h
+index cf44a629..b7987198 100644
+--- a/src/common/Configuration.h
++++ b/src/common/Configuration.h
+@@ -70,7 +70,6 @@ namespace SDDM {
+ Entry(SessionLogFile, QString, _S(".local/share/sddm/xorg-session.log"), _S("Path to the user session log file"));
+ Entry(DisplayCommand, QString, _S(DATA_INSTALL_DIR "/scripts/Xsetup"), _S("Path to a script to execute when starting the display server"));
+ Entry(DisplayStopCommand, QString, _S(DATA_INSTALL_DIR "/scripts/Xstop"), _S("Path to a script to execute when stopping the display server"));
+- Entry(MinimumVT, int, MINIMUM_VT, _S("The lowest virtual terminal number that will be used."));
+ Entry(EnableHiDPI, bool, false, _S("Enable Qt's automatic high-DPI scaling"));
+ );
+
+diff --git a/src/common/Constants.h.in b/src/common/Constants.h.in
+index e174b5bf..48051288 100644
+--- a/src/common/Constants.h.in
++++ b/src/common/Constants.h.in
+@@ -37,7 +37,6 @@
+ #define SYSTEM_CONFIG_DIR "@SYSTEM_CONFIG_DIR@"
+
+ #define LOG_FILE "@LOG_FILE@"
+-#define MINIMUM_VT @MINIMUM_VT@
+
+ #define UID_MIN @UID_MIN@
+ #define UID_MAX @UID_MAX@
+diff --git a/src/daemon/Display.cpp b/src/daemon/Display.cpp
+index a65df3f0..dbef510d 100644
+--- a/src/daemon/Display.cpp
++++ b/src/daemon/Display.cpp
+@@ -45,17 +45,19 @@
+
+ #include "Login1Manager.h"
+ #include "Login1Session.h"
+-
++#include "VirtualTerminal.h"
+
+ namespace SDDM {
+- Display::Display(const int terminalId, Seat *parent) : QObject(parent),
+- m_terminalId(terminalId),
++ Display::Display(Seat *parent) : QObject(parent),
+ m_auth(new Auth(this)),
+ m_displayServer(new XorgDisplayServer(this)),
+ m_seat(parent),
+ m_socketServer(new SocketServer(this)),
+ m_greeter(new Greeter(this)) {
+
++ // Allocate vt
++ m_terminalId = VirtualTerminal::setUpNewVt();
++
+ // respond to authentication requests
+ m_auth->setVerbose(true);
+ connect(m_auth, &Auth::requestChanged, this, &Display::slotRequestChanged);
+diff --git a/src/daemon/Display.h b/src/daemon/Display.h
+index e68bc128..9db954d1 100644
+--- a/src/daemon/Display.h
++++ b/src/daemon/Display.h
+@@ -41,7 +41,7 @@ namespace SDDM {
+ Q_OBJECT
+ Q_DISABLE_COPY(Display)
+ public:
+- explicit Display(int terminalId, Seat *parent);
++ explicit Display(Seat *parent);
+ ~Display();
+
+ QString displayId() const;
+diff --git a/src/daemon/Seat.cpp b/src/daemon/Seat.cpp
+index 838c2221..a2f3d0c3 100644
+--- a/src/daemon/Seat.cpp
++++ b/src/daemon/Seat.cpp
+@@ -33,18 +33,6 @@
+ #include <functional>
+
+ namespace SDDM {
+- int findUnused(int minimum, std::function<bool(const int)> used) {
+- // initialize with minimum
+- int number = minimum;
+-
+- // find unused
+- while (used(number))
+- number++;
+-
+- // return number;
+- return number;
+- }
+-
+ Seat::Seat(const QString &name, QObject *parent) : QObject(parent), m_name(name) {
+ createDisplay();
+ }
+@@ -53,30 +41,13 @@ namespace SDDM {
+ return m_name;
+ }
+
+- void Seat::createDisplay(int terminalId) {
++ void Seat::createDisplay() {
+ //reload config if needed
+ mainConfig.load();
+
+- if (m_name == QLatin1String("seat0")) {
+- if (terminalId == -1) {
+- // find unused terminal
+- terminalId = findUnused(mainConfig.X11.MinimumVT.get(), [&](const int number) {
+- return m_terminalIds.contains(number);
+- });
+- }
+-
+- // mark terminal as used
+- m_terminalIds << terminalId;
+-
+- // log message
+- qDebug() << "Adding new display" << "on vt" << terminalId << "...";
+- }
+- else {
+- qDebug() << "Adding new VT-less display...";
+- }
+-
+ // create a new display
+- Display *display = new Display(terminalId, this);
++ qDebug() << "Adding new display...";
++ Display *display = new Display(this);
+
+ // restart display on stop
+ connect(display, &Display::stopped, this, &Seat::displayStopped);
+@@ -112,9 +83,6 @@ namespace SDDM {
+ // remove display from list
+ m_displays.removeAll(display);
+
+- // mark display and terminal ids as unused
+- m_terminalIds.removeAll(display->terminalId());
+-
+ // stop the display
+ display->blockSignals(true);
+ display->stop();
+diff --git a/src/daemon/Seat.h b/src/daemon/Seat.h
+index f9fe7331..685eaedd 100644
+--- a/src/daemon/Seat.h
++++ b/src/daemon/Seat.h
+@@ -35,7 +35,7 @@ namespace SDDM {
+ const QString &name() const;
+
+ public slots:
+- void createDisplay(int terminalId = -1);
++ void createDisplay();
+ void removeDisplay(SDDM::Display* display);
+
+ private slots:
+@@ -47,7 +47,6 @@ namespace SDDM {
+ QString m_name;
+
+ QVector<Display *> m_displays;
+- QVector<int> m_terminalIds;
+ };
+ }
+
diff --git a/3c92e9206dc2e17fa5dc13f37be2926e9131ce94.patch b/3c92e9206dc2e17fa5dc13f37be2926e9131ce94.patch
new file mode 100644
index 0000000..b94a535
--- /dev/null
+++ b/3c92e9206dc2e17fa5dc13f37be2926e9131ce94.patch
@@ -0,0 +1,163 @@
+From 3c92e9206dc2e17fa5dc13f37be2926e9131ce94 Mon Sep 17 00:00:00 2001
+From: Pier Luigi Fiorini <pierluigi.fiorini@liri.io>
+Date: Sun, 7 Mar 2021 17:36:11 +0100
+Subject: [PATCH] Stop the helper process
+
+Make sure the helper process is stopped when shutting down.
+---
+ src/auth/Auth.cpp | 9 +++++++++
+ src/auth/Auth.h | 5 +++++
+ src/{daemon => common}/SignalHandler.cpp | 0
+ src/{daemon => common}/SignalHandler.h | 0
+ src/daemon/CMakeLists.txt | 3 ++-
+ src/daemon/Greeter.cpp | 2 ++
+ src/helper/CMakeLists.txt | 2 ++
+ src/helper/HelperApp.cpp | 14 +++++++++++++-
+ src/helper/HelperApp.h | 2 ++
+ 9 files changed, 35 insertions(+), 2 deletions(-)
+ rename src/{daemon => common}/SignalHandler.cpp (100%)
+ rename src/{daemon => common}/SignalHandler.h (100%)
+
+diff --git a/src/auth/Auth.cpp b/src/auth/Auth.cpp
+index caca3146..042d938b 100644
+--- a/src/auth/Auth.cpp
++++ b/src/auth/Auth.cpp
+@@ -358,6 +358,15 @@ namespace SDDM {
+ args << QStringLiteral("--greeter");
+ d->child->start(QStringLiteral("%1/sddm-helper").arg(QStringLiteral(LIBEXEC_INSTALL_DIR)), args);
+ }
++
++ void Auth::stop()
++ {
++ if (d->child->state() != QProcess::NotRunning) {
++ d->child->terminate();
++ if (!d->child->waitForFinished(5000))
++ d->child->kill();
++ }
++ }
+ }
+
+ #include "Auth.moc"
+diff --git a/src/auth/Auth.h b/src/auth/Auth.h
+index 87f5f440..c3ce1a62 100644
+--- a/src/auth/Auth.h
++++ b/src/auth/Auth.h
+@@ -157,6 +157,11 @@ namespace SDDM {
+ */
+ void start();
+
++ /**
++ * Stops the process.
++ */
++ void stop();
++
+ Q_SIGNALS:
+ void autologinChanged();
+ void greeterChanged();
+diff --git a/src/daemon/SignalHandler.cpp b/src/common/SignalHandler.cpp
+similarity index 100%
+rename from src/daemon/SignalHandler.cpp
+rename to src/common/SignalHandler.cpp
+diff --git a/src/daemon/SignalHandler.h b/src/common/SignalHandler.h
+similarity index 100%
+rename from src/daemon/SignalHandler.h
+rename to src/common/SignalHandler.h
+diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt
+index 86d014be..4660a2f2 100644
+--- a/src/daemon/CMakeLists.txt
++++ b/src/daemon/CMakeLists.txt
+@@ -13,6 +13,8 @@ set(DAEMON_SOURCES
+ ${CMAKE_SOURCE_DIR}/src/common/Session.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/SocketWriter.cpp
++ ${CMAKE_SOURCE_DIR}/src/common/SignalHandler.cpp
++ ${CMAKE_SOURCE_DIR}/src/common/SignalHandler.h
+ ${CMAKE_SOURCE_DIR}/src/common/XauthUtils.cpp
+ ${CMAKE_SOURCE_DIR}/src/auth/Auth.cpp
+ ${CMAKE_SOURCE_DIR}/src/auth/AuthPrompt.cpp
+ ${CMAKE_SOURCE_DIR}/src/auth/AuthRequest.cpp
+@@ -27,7 +29,6 @@ set(DAEMON_SOURCES
+ PowerManager.cpp
+ Seat.cpp
+ SeatManager.cpp
+- SignalHandler.cpp
+ SocketServer.cpp
+ )
+
+diff --git a/src/daemon/Greeter.cpp b/src/daemon/Greeter.cpp
+index 436ecc3d..3b0ab2c3 100644
+--- a/src/daemon/Greeter.cpp
++++ b/src/daemon/Greeter.cpp
+@@ -225,6 +225,8 @@ namespace SDDM {
+ // wait for finished
+ if (!m_process->waitForFinished(5000))
+ m_process->kill();
++ } else {
++ m_auth->stop();
+ }
+ }
+
+diff --git a/src/helper/CMakeLists.txt b/src/helper/CMakeLists.txt
+index 8914ea75..f63dcc92 100644
+--- a/src/helper/CMakeLists.txt
++++ b/src/helper/CMakeLists.txt
+@@ -10,6 +10,8 @@ set(HELPER_SOURCES
+ ${CMAKE_SOURCE_DIR}/src/common/ConfigReader.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/SafeDataStream.cpp
++ ${CMAKE_SOURCE_DIR}/src/common/SignalHandler.cpp
++ ${CMAKE_SOURCE_DIR}/src/common/SignalHandler.h
+ ${CMAKE_SOURCE_DIR}/src/common/XauthUtils.cpp
+ Backend.cpp
+ HelperApp.cpp
+ UserSession.cpp
+diff --git a/src/helper/HelperApp.cpp b/src/helper/HelperApp.cpp
+index 672359ae..12c3206e 100644
+--- a/src/helper/HelperApp.cpp
++++ b/src/helper/HelperApp.cpp
+@@ -22,7 +22,7 @@
+ #include "Backend.h"
+ #include "UserSession.h"
+ #include "SafeDataStream.h"
+-
++#include "SignalHandler.h"
+ #include "MessageHandler.h"
+ #include "VirtualTerminal.h"
+
+@@ -50,6 +50,18 @@ namespace SDDM {
+ , m_socket(new QLocalSocket(this)) {
+ qInstallMessageHandler(HelperMessageHandler);
+
++ m_signalHandler = new SignalHandler(this);
++ m_signalHandler->initialize();
++ connect(m_signalHandler, &SignalHandler::sigintReceived, this, &HelperApp::quit);
++ connect(m_signalHandler, &SignalHandler::sigtermReceived, this, &HelperApp::quit);
++
++ connect(this, &QCoreApplication::aboutToQuit, this, [this] {
++ m_session->terminate();
++ if (!m_session->waitForFinished(5000))
++ m_session->kill();
++ m_backend->closeSession();
++ });
++
+ QTimer::singleShot(0, this, SLOT(setUp()));
+ }
+
+diff --git a/src/helper/HelperApp.h b/src/helper/HelperApp.h
+index 3742df12..d08fd37b 100644
+--- a/src/helper/HelperApp.h
++++ b/src/helper/HelperApp.h
+@@ -31,6 +31,7 @@ class QLocalSocket;
+ namespace SDDM {
+ class Backend;
+ class UserSession;
++ class SignalHandler;
+ class HelperApp : public QCoreApplication
+ {
+ Q_OBJECT
+@@ -63,6 +64,7 @@ namespace SDDM {
+ QString m_user { };
+ // TODO: get rid of this in a nice clean way along the way with moving to user session X server
+ QByteArray m_cookie { };
++ SignalHandler *m_signalHandler = nullptr;
+
+ /*!
+ \brief Write utmp/wtmp/btmp records when a user logs in
diff --git a/README.scripts b/README.scripts
new file mode 100644
index 0000000..70b5243
--- /dev/null
+++ b/README.scripts
@@ -0,0 +1,2 @@
+This scripts dir contains only samples, but are generally not used directly.
+In practice, sddm runtime uses items under /etc/sddm by default
diff --git a/sddm-0.18.0-environment_file.patch b/sddm-0.18.0-environment_file.patch
new file mode 100644
index 0000000..6f89c36
--- /dev/null
+++ b/sddm-0.18.0-environment_file.patch
@@ -0,0 +1,11 @@
+diff -up sddm-0.18.0/services/sddm.service.in.env sddm-0.18.0/services/sddm.service.in
+--- sddm-0.18.0/services/sddm.service.in.env 2018-07-18 05:31:40.000000000 -0500
++++ sddm-0.18.0/services/sddm.service.in 2019-03-14 08:23:22.095498405 -0500
+@@ -7,6 +7,7 @@ After=systemd-user-sessions.service gett
+ [Service]
+ ExecStart=@CMAKE_INSTALL_FULL_BINDIR@/sddm
+ Restart=always
++EnvironmentFile=-/etc/sysconfig/sddm
+
+ [Install]
+ Alias=display-manager.service
diff --git a/sddm-0.19.0-allow-hiding-wayland-sessions.patch b/sddm-0.19.0-allow-hiding-wayland-sessions.patch
new file mode 100644
index 0000000..9eb550e
--- /dev/null
+++ b/sddm-0.19.0-allow-hiding-wayland-sessions.patch
@@ -0,0 +1,57 @@
+From 0b5040a887459a974bb4a3a4512a8392daa0eb66 Mon Sep 17 00:00:00 2001
+From: Jeremy Linton <jeremy.linton@arm.com>
+Date: Mon, 25 Oct 2021 14:56:14 -0500
+Subject: [PATCH] greeter: Do not populate Wayland sessions if they are to be
+ hidden
+
+Check for /dev/dri which should indicate that the Wayland will work
+on this hardware.
+
+Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
+---
+ src/greeter/SessionModel.cpp | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/src/greeter/SessionModel.cpp b/src/greeter/SessionModel.cpp
+index 1953c76..b1f3296 100644
+--- a/src/greeter/SessionModel.cpp
++++ b/src/greeter/SessionModel.cpp
+@@ -22,6 +22,7 @@
+
+ #include "Configuration.h"
+
++#include <QFileInfo>
+ #include <QVector>
+ #include <QProcessEnvironment>
+ #include <QFileSystemWatcher>
+@@ -39,18 +40,25 @@ namespace SDDM {
+ };
+
+ SessionModel::SessionModel(QObject *parent) : QAbstractListModel(parent), d(new SessionModelPrivate()) {
++ // Check for flag to hide Wayland sessions
++ bool dri_active = QFileInfo::exists(QStringLiteral("/dev/dri"));
++
+ // initial population
+ beginResetModel();
+- populate(Session::WaylandSession, mainConfig.Wayland.SessionDir.get());
++ if (dri_active)
++ populate(Session::WaylandSession, mainConfig.Wayland.SessionDir.get());
+ populate(Session::X11Session, mainConfig.X11.SessionDir.get());
+ endResetModel();
+
+ // refresh everytime a file is changed, added or removed
+ QFileSystemWatcher *watcher = new QFileSystemWatcher(this);
+ connect(watcher, &QFileSystemWatcher::directoryChanged, [this](const QString &path) {
++ // Recheck for flag to hide Wayland sessions
++ bool dri_active = QFileInfo::exists(QStringLiteral("/dev/dri"));
+ beginResetModel();
+ d->sessions.clear();
+- populate(Session::WaylandSession, mainConfig.Wayland.SessionDir.get());
++ if (dri_active)
++ populate(Session::WaylandSession, mainConfig.Wayland.SessionDir.get());
+ populate(Session::X11Session, mainConfig.X11.SessionDir.get());
+ endResetModel();
+ });
+--
+2.32.0
+
diff --git a/sddm-autologin.pam b/sddm-autologin.pam
new file mode 100644
index 0000000..f62fad0
--- /dev/null
+++ b/sddm-autologin.pam
@@ -0,0 +1,20 @@
+ #%PAM-1.0
+auth required pam_env.so
+auth required pam_permit.so
+auth include postlogin
+
+account required pam_nologin.so
+account include system-auth
+
+password include system-auth
+
+session required pam_selinux.so close
+session required pam_loginuid.so
+session required pam_selinux.so open
+session optional pam_keyinit.so force revoke
+session required pam_namespace.so
+session include system-auth
+-session optional pam_gnome_keyring.so auto_start
+-session optional pam_kwallet5.so auto_start
+-session optional pam_kwallet.so auto_start
+session include postlogin
diff --git a/sddm-systemd-sysusers.conf b/sddm-systemd-sysusers.conf
new file mode 100644
index 0000000..a48f929
--- /dev/null
+++ b/sddm-systemd-sysusers.conf
@@ -0,0 +1 @@
+u sddm - "Simple Desktop Display Manager" /var/lib/sddm
diff --git a/sddm.conf b/sddm.conf
new file mode 100644
index 0000000..de667ab
--- /dev/null
+++ b/sddm.conf
@@ -0,0 +1,122 @@
+[Autologin]
+# Whether sddm should automatically log back into sessions when they exit
+#Relogin=false
+
+# Name of session file for autologin session
+#Session=
+
+# Username for autologin session
+#User=
+
+
+[General]
+# Enable Qt's automatic high-DPI scaling
+#EnableHiDPI=false
+
+# Halt command
+#HaltCommand=/usr/bin/systemctl poweroff
+
+# Initial NumLock state. Can be on, off or none.
+# If property is set to none, numlock won't be changed
+# NOTE: Currently ignored if autologin is enabled.
+#Numlock=none
+
+# Reboot command
+#RebootCommand=/usr/bin/systemctl reboot
+
+# Control x11/wayland startup
+# DisplayServer=x11
+
+[Theme]
+# Current theme name
+#Current=
+
+# Cursor theme used in the greeter
+#CursorTheme=
+
+# Number of users to use as threshold
+# above which avatars are disabled
+# unless explicitly enabled with EnableAvatars
+#DisableAvatarsThreshold=7
+
+# Enable display of custom user avatars
+#EnableAvatars=true
+
+# Global directory for user avatars
+# The files should be named <username>.face.icon
+#FacesDir=/usr/share/sddm/faces
+
+# Theme directory path
+#ThemeDir=/usr/share/sddm/themes
+
+
+[Users]
+# Default $PATH for logged in users
+#DefaultPath=/usr/local/bin:/usr/bin:/bin
+
+# Comma-separated list of shells.
+# Users with these shells as their default won't be listed
+#HideShells=
+
+# Comma-separated list of users that should not be listed
+#HideUsers=
+
+# Maximum user id for displayed users
+#MaximumUid=60000
+
+# Minimum user id for displayed users
+#MinimumUid=1000
+
+# Remember the session of the last successfully logged in user
+#RememberLastSession=true
+
+# Remember the last successfully logged in user
+#RememberLastUser=true
+
+
+[Wayland]
+# Path to a script to execute when starting the desktop session
+#SessionCommand=/etc/sddm/wayland-session
+
+# Directory containing available Wayland sessions
+#SessionDir=/usr/share/wayland-sessions
+
+# Path to the user session log file
+#SessionLogFile=.cache/wayland-errors
+
+
+[X11]
+# Path to a script to execute when starting the display server
+#DisplayCommand=/etc/sddm/Xsetup
+
+# Path to a script to execute when stopping the display server
+#DisplayStopCommand=/etc/sddm/Xstop
+
+# The lowest virtual terminal number that will be used.
+#MinimumVT=1
+
+# Arguments passed to the X server invocation
+#ServerArguments=-nolisten tcp
+
+# Path to X server binary
+#ServerPath=/usr/bin/X
+
+# Path to a script to execute when starting the desktop session
+#SessionCommand=/etc/X11/xinit/Xsession
+
+# Directory containing available X sessions
+#SessionDir=/usr/share/xsessions
+
+# Path to the user session log file
+#SessionLogFile=.cache/xsession-errors
+
+# Path to the Xauthority file
+#UserAuthFile=.Xauthority
+
+# Path to xauth binary
+#XauthPath=/usr/bin/xauth
+
+# Path to Xephyr binary
+#XephyrPath=/usr/bin/Xephyr
+
+
diff --git a/sddm.pam b/sddm.pam
new file mode 100644
index 0000000..34c0777
--- /dev/null
+++ b/sddm.pam
@@ -0,0 +1,23 @@
+auth [success=done ignore=ignore default=bad] pam_selinux_permit.so
+auth substack password-auth
+-auth optional pam_gnome_keyring.so
+-auth optional pam_kwallet5.so
+-auth optional pam_kwallet.so
+auth include postlogin
+
+account required pam_nologin.so
+account include password-auth
+
+password include password-auth
+
+session required pam_selinux.so close
+session required pam_loginuid.so
+-session optional pam_ck_connector.so
+session required pam_selinux.so open
+session optional pam_keyinit.so force revoke
+session required pam_namespace.so
+session include password-auth
+-session optional pam_gnome_keyring.so auto_start
+-session optional pam_kwallet5.so auto_start
+-session optional pam_kwallet.so auto_start
+session include postlogin
diff --git a/sddm.spec b/sddm.spec
new file mode 100644
index 0000000..9f930ed
--- /dev/null
+++ b/sddm.spec
@@ -0,0 +1,184 @@
+%undefine __cmake_in_source_build
+
+# Control wayland by default
+#bcond_with wayland_default
+
+Name: sddm
+Version: 0.19.0
+Release: 1
+License: GPLv2+
+Summary: QML based X11 desktop manager
+
+Url: https://github.com/sddm/sddm
+Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
+
+Patch16: 0016-Fix-sessions-being-started-as-the-wrong-type-on-auto.patch
+Patch18: 0018-wayland-session-Ensure-SHELL-remains-correctly-set.patch
+Patch051: 0001-Remove-suffix-for-Wayland-session.patch
+Patch052: 0001-Redesign-Xauth-handling.patch
+Patch053: 0001-Retry-starting-the-display-server.patch
+Patch054: 3c92e9206dc2e17fa5dc13f37be2926e9131ce94.patch
+Patch055: 308fd0df2583b02251f0d80c397ccbf9fa7a9e04.patch
+
+# sddm.service: +EnvironmentFile=-/etc/sysconfig/sddm
+Patch103: sddm-0.18.0-environment_file.patch
+
+# Disable wayland sessions when /dev/dri doesn't exist
+Patch104: sddm-0.19.0-allow-hiding-wayland-sessions.patch
+
+# Fix race with logind restart, and start seat0 if !CanGraphical on timer
+Patch105: 0001-Delay-for-logind-and-fallback-to-seat0.patch
+
+# Shamelessly stolen from fedora
+Source11: sddm.pam
+Source12: sddm-autologin.pam
+Source13: tmpfiles-sddm.conf
+# sample sddm.conf generated with sddm --example-config
+Source14: sddm.conf
+# README.scripts
+Source15: README.scripts
+# sysconfig snippet
+Source16: sddm.sysconfig
+# systemd sysusers config
+Source18: sddm-systemd-sysusers.conf
+
+Provides: service(graphical-login) = sddm
+
+BuildRequires: cmake >= 2.8.8
+BuildRequires: extra-cmake-modules
+BuildRequires: libxcb-devel
+BuildRequires: pam-devel
+BuildRequires: pkgconfig(libsystemd)
+BuildRequires: pkgconfig(systemd)
+# Check which package contains /usr/bin/rst2man
+BuildRequires: python3-docutils
+BuildRequires: qt5-qtbase-devel >= 5.6
+BuildRequires: qt5-qtdeclarative-devel >= 5.6
+BuildRequires: qt5-qttools-devel >= 5.6
+BuildRequires: shadow-utils
+BuildRequires: systemd
+
+Obsoletes: kde-settings-sddm < 20-5
+
+Requires: systemd
+Requires: xorg-x11-xinit
+Requires: xorg-x11-server-Xorg
+
+Suggests: qt5-qtvirtualkeyboard%{?_isa}
+
+%{?systemd_requires}
+
+Requires(pre): shadow-utils
+
+%description
+SDDM is a modern display manager for X11 aiming to be fast, simple and
+beautiful. It uses modern technologies like QtQuick, which in turn gives the
+designer the ability to create smooth, animated user interfaces.
+
+%package themes
+Summary: SDDM Themes
+Obsoletes: sddm < 0.2.0-0.12
+Requires: %{name} = %{version}-%{release}
+BuildArch: noarch
+
+%description themes
+A collection of sddm themes, including: elarun, maldives, maya
+
+
+%prep
+%autosetup -p1
+
+%build
+%cmake \
+ -DBUILD_MAN_PAGES:BOOL=ON \
+ -DCMAKE_BUILD_TYPE:STRING="Release" \
+ -DENABLE_JOURNALD:BOOL=ON \
+ -DSESSION_COMMAND:PATH=/etc/X11/xinit/Xsession \
+ -DWAYLAND_SESSION_COMMAND:PATH=/etc/sddm/wayland-session
+
+%make_build
+
+
+%install
+make install/fast DESTDIR=%{buildroot}
+
+mkdir -p %{buildroot}%{_sysconfdir}/sddm.conf.d
+install -Dpm 644 %{SOURCE11} %{buildroot}%{_sysconfdir}/pam.d/sddm
+install -Dpm 644 %{SOURCE12} %{buildroot}%{_sysconfdir}/pam.d/sddm-autologin
+install -Dpm 644 %{SOURCE13} %{buildroot}%{_tmpfilesdir}/sddm.conf
+install -Dpm 644 %{SOURCE14} %{buildroot}%{_sysconfdir}/sddm.conf
+install -Dpm 644 %{SOURCE15} %{buildroot}%{_datadir}/sddm/scripts/README.scripts
+install -Dpm 644 %{SOURCE16} %{buildroot}%{_sysconfdir}/sysconfig/sddm
+install -Dpm 644 %{SOURCE18} %{buildroot}%{_sysusersdir}/sddm.conf
+mkdir -p %{buildroot}/run/sddm
+mkdir -p %{buildroot}%{_localstatedir}/lib/sddm
+mkdir -p %{buildroot}%{_sysconfdir}/sddm/
+cp -a %{buildroot}%{_datadir}/sddm/scripts/* \
+ %{buildroot}%{_sysconfdir}/sddm/
+rm -fv %{buildroot}%{_sysconfdir}/sddm/Xsession
+
+%pre
+mkdir %{_sysusersdir}/sddm.conf.d
+echo 'u sddm - "Simple Desktop Display Manager" /var/lib/sddm' > %{_sysusersdir}/sddm.conf.d/sddm-systemd-sysusers.conf
+
+%post
+%systemd_post sddm.service
+# handle incompatible configuration changes
+(grep \
+ -e '^\[XDisplay\]$' \
+ -e '^\[WaylandDisplay\]$' \
+ %{_sysconfdir}/sddm.conf > /dev/null && \
+ sed -i.rpmsave \
+ -e 's|^\[XDisplay\]$|\[X11\]|' \
+ -e 's|^\[WaylandDisplay\]$|\[Wayland\]|' \
+ %{_sysconfdir}/sddm.conf
+) ||:
+
+%preun
+%systemd_preun sddm.service
+
+%postun
+%systemd_postun sddm.service
+
+%files
+%license LICENSE
+%doc README.md CONTRIBUTORS
+%dir %{_sysconfdir}/sddm/
+%dir %{_sysconfdir}/sddm.conf.d
+%config(noreplace) %{_sysconfdir}/sddm/*
+%config(noreplace) %{_sysconfdir}/sddm.conf
+%config(noreplace) %{_sysconfdir}/pam.d/sddm
+%config(noreplace) %{_sysconfdir}/pam.d/sddm-autologin
+%config(noreplace) %{_sysconfdir}/pam.d/sddm-greeter
+%config(noreplace) %{_sysconfdir}/sysconfig/sddm
+# THIS IS NOT A CONFIG FILE, but a script that is run by sddm.service
+%{_sysconfdir}/dbus-1/system.d/org.freedesktop.DisplayManager.conf
+%{_bindir}/sddm
+%{_bindir}/sddm-greeter
+%{_libexecdir}/sddm-helper
+%{_tmpfilesdir}/sddm.conf
+%{_sysusersdir}/sddm.conf
+%attr(0711, root, sddm) %dir /run/sddm
+%attr(1770, sddm, sddm) %dir %{_localstatedir}/lib/sddm
+%{_unitdir}/sddm.service
+%{_qt5_archdatadir}/qml/SddmComponents/
+%dir %{_datadir}/sddm
+%{_datadir}/sddm/faces/
+%{_datadir}/sddm/flags/
+%{_datadir}/sddm/scripts/
+%dir %{_datadir}/sddm/themes/
+%{_datadir}/sddm/translations/
+%{_mandir}/man1/sddm.1*
+%{_mandir}/man1/sddm-greeter.1*
+%{_mandir}/man5/sddm.conf.5*
+%{_mandir}/man5/sddm-state.conf.5*
+
+%files themes
+%{_datadir}/sddm/themes/elarun/
+%{_datadir}/sddm/themes/maldives/
+%{_datadir}/sddm/themes/maya/
+
+
+%changelog
+* Fri Jul 22 2022 misaka00251 <misaka00251@misakanet.cn> - 0.19.0-1
+- Init package
diff --git a/sddm.sysconfig b/sddm.sysconfig
new file mode 100644
index 0000000..ddd6aab
--- /dev/null
+++ b/sddm.sysconfig
@@ -0,0 +1,5 @@
+# https://bugzilla.redhat.com/1686675
+# https://bugreports.qt.io/browse/QTBUG-58508
+QML_DISABLE_DISK_CACHE=1
+# enable qDebug messages for debug build
+# QT_LOGGING_RULES="*.debug=true"
diff --git a/sources b/sources
new file mode 100644
index 0000000..2f50fab
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+2e3268a30531d6ae98f02cbf3772fea1 sddm-0.19.0.tar.gz
diff --git a/tmpfiles-sddm.conf b/tmpfiles-sddm.conf
new file mode 100644
index 0000000..c573868
--- /dev/null
+++ b/tmpfiles-sddm.conf
@@ -0,0 +1,2 @@
+d /run/sddm 1733 root root -
+Z /var/lib/sddm - sddm sddm - -