From 42c51761cc82edbaa50d702a4614e179ad4bcd63 Mon Sep 17 00:00:00 2001 From: Fabian Vogt 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 #include +#include #include @@ -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 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);