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 eef26da45..838c2221d 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 bf22566b7..f9fe7331f 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 e60c02210..5f40fe8c3 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);