Skip to content

Commit bf4da43

Browse files
committed
feat: Starting X11 dde-session using ddm
This commit modifies X11DisplayServerType to start X11 with ddm. It use treeland as greeter to handle user login. Once user logged in, it kills the wayland compositor and start the X11 server. To test, change the General -> DisplayServer field of /etc/ddm.conf to "x11".
1 parent b0bf6e9 commit bf4da43

File tree

9 files changed

+109
-23
lines changed

9 files changed

+109
-23
lines changed

data/scripts/Xsetup

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#!/bin/sh
22
# Xsetup - run as root before the login dialog appears
3-
3+
xhost +

src/auth/Auth.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,15 @@ namespace DDM {
6565
QLocalSocket *socket { nullptr };
6666
QString displayServerCmd;
6767
QString sessionPath { };
68+
int sessionType { 0 };
6869
QString user { };
6970
QString password { };
7071
QByteArray cookie { };
7172
bool autologin { false };
7273
bool greeter { false };
7374
bool singleMode { false };
7475
bool identifyOnly { false };
76+
bool skipAuth { false };
7577
QProcessEnvironment environment { };
7678
qint64 id { 0 };
7779
static qint64 lastId;
@@ -317,6 +319,14 @@ namespace DDM {
317319
return d->sessionId;
318320
}
319321

322+
int Auth::sessionType() const {
323+
return d->sessionType;
324+
}
325+
326+
bool Auth::isSingleMode() const {
327+
return d->singleMode;
328+
}
329+
320330
bool Auth::isActive() const {
321331
return d->child->state() != QProcess::NotRunning;
322332
}
@@ -394,6 +404,11 @@ namespace DDM {
394404
}
395405
}
396406

407+
void Auth::setSessionType(const int &type) {
408+
if (type != d->sessionType)
409+
d->sessionType = type;
410+
}
411+
397412
int Auth::tty() const {
398413
return d->tty;
399414
}
@@ -424,6 +439,12 @@ namespace DDM {
424439
}
425440
}
426441

442+
void Auth::setSkipAuth(bool on) {
443+
if (on != d->skipAuth) {
444+
d->skipAuth = on;
445+
}
446+
}
447+
427448
void Auth::start() {
428449
QStringList args;
429450
args << QStringLiteral("--socket") << SocketServer::instance()->fullServerName();
@@ -442,6 +463,8 @@ namespace DDM {
442463
args << QStringLiteral("--single-mode");
443464
if (d->identifyOnly)
444465
args << QStringLiteral("--identify-only");
466+
if (d->skipAuth)
467+
args << QStringLiteral("--skip-auth");
445468
d->child->start(QStringLiteral("%1/ddm-helper").arg(QStringLiteral(LIBEXEC_INSTALL_DIR)), args);
446469
}
447470

@@ -453,7 +476,7 @@ namespace DDM {
453476
d->child->terminate();
454477

455478
// wait for finished
456-
if (!d->child->waitForFinished(5000))
479+
if (!d->child->waitForFinished(500))
457480
d->child->kill();
458481
}
459482
}

src/auth/Auth.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,14 @@ namespace DDM {
9797
bool isGreeter() const;
9898
bool verbose() const;
9999
bool identifyOnly() const;
100+
bool isSingleMode() const;
100101
const QByteArray &cookie() const;
101102
const QString &user() const;
102103
const QString &session() const;
103104
const QString &password() const;
104105
AuthRequest *request();
105106
QString sessionId() const;
107+
int sessionType() const;
106108
int tty() const;
107109

108110
void setTTY(int tty);
@@ -146,6 +148,8 @@ namespace DDM {
146148
void setVerbose(bool on = true);
147149

148150
void setIdentifyOnly(bool on = false);
151+
152+
void setSkipAuth(bool on = true);
149153
/**
150154
* Sets the user which will then authenticate
151155
* @param user username
@@ -179,7 +183,9 @@ namespace DDM {
179183
*/
180184
void setSingleMode(bool on = true);
181185

182-
void setSessionId(const QString& sessionId);
186+
void setSessionId(const QString &sessionId);
187+
188+
void setSessionType(const int &type);
183189

184190
public Q_SLOTS:
185191
/**

src/daemon/Display.cpp

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,9 @@ namespace DDM {
122122
// Create display server
123123
switch (m_displayServerType) {
124124
case X11DisplayServerType:
125-
m_terminalId = VirtualTerminal::setUpNewVt();
126-
m_displayServer = new XorgDisplayServer(this);
125+
m_terminalId = m_sessionTerminalId = fetchAvailableVt();
126+
m_displayServer = new SingleWaylandDisplayServer(m_socketServer, this);
127+
m_greeter->setSingleMode();
127128
break;
128129
case X11UserDisplayServerType:
129130
m_terminalId = fetchAvailableVt();
@@ -590,11 +591,12 @@ namespace DDM {
590591
}
591592

592593
auth->setUser(user);
594+
auth->setSessionType(session.type());
593595
if (m_reuseSessionId.isNull()) {
594596
auth->setSession(session.exec());
595597
}
596598
auth->insertEnvironment(env);
597-
auth->setSingleMode(m_displayServerType == DisplayServerType::SingleCompositerServerType);
599+
auth->setSingleMode(session.isSingleMode());
598600
auth->start();
599601
}
600602

@@ -639,17 +641,51 @@ namespace DDM {
639641
stateConfig.Last.Session.setDefault();
640642
stateConfig.save();
641643

642-
if (m_displayServerType == DisplayServerType::SingleCompositerServerType) {
644+
if (auth->isSingleMode()) {
643645
auto* server = reinterpret_cast<SingleWaylandDisplayServer*>(m_displayServer);
644646
server->onLoginSucceeded(user);
647+
switchToUser(auth->user());
645648
} else {
646649
if (m_socket) {
647650
emit loginSucceeded(m_socket, user);
648651
daemonApp->displayManager()->setLastSession(auth->sessionId());
649652
}
650-
}
651653

652-
switchToUser(auth->user());
654+
disconnect(m_displayServer, &DisplayServer::stopped, this, &Display::stop);
655+
m_displayServer->stop();
656+
delete m_displayServer;
657+
m_greeter->stop();
658+
delete m_greeter;
659+
m_currentAuth->stop();
660+
m_socketServer->stop();
661+
delete m_socketServer;
662+
663+
m_terminalId = m_sessionTerminalId = fetchAvailableVt();
664+
m_started = false;
665+
666+
if (auth->sessionType() == Session::X11Session) {
667+
m_displayServer = new XorgDisplayServer(this);
668+
m_displayServerType = X11DisplayServerType;
669+
} else {
670+
m_displayServer = new WaylandDisplayServer(this);
671+
m_displayServerType = WaylandDisplayServerType;
672+
}
673+
connect(m_displayServer, &DisplayServer::started, this, &Display::displayServerStarted);
674+
connect(m_displayServer, &DisplayServer::stopped, this, &Display::stop);
675+
676+
m_socketServer = new SocketServer(this);
677+
678+
m_greeter = new Greeter(this);
679+
m_greeter->setDisplayServerCommand(auth->session());
680+
m_greeter->setUser(user);
681+
m_greeter->setSkipAuth();
682+
683+
connect(m_greeter, &Greeter::failed, this, &Display::stop);
684+
connect(m_greeter, &Greeter::displayServerFailed, this, &Display::displayServerFailed);
685+
connect(m_greeter, &Greeter::succeed, this, &Display::stop);
686+
687+
m_displayServer->start();
688+
}
653689
}
654690
m_socket = nullptr;
655691
}
@@ -711,7 +747,8 @@ namespace DDM {
711747
}
712748
}
713749

714-
if (status != Auth::HELPER_AUTH_ERROR && m_displayServerType != DisplayServerType::SingleCompositerServerType)
750+
// Don't restart display when ddm-helper crashed (exit code 9)
751+
if (status != Auth::HELPER_AUTH_ERROR && status != Auth::HelperExitStatus(9) && m_displayServerType != DisplayServerType::SingleCompositerServerType)
715752
stop();
716753
}
717754

@@ -730,7 +767,7 @@ namespace DDM {
730767
void Display::slotSessionStarted(bool success) {
731768
qDebug() << "Session started" << success;
732769
Auth* auth = qobject_cast<Auth*>(sender());
733-
if (m_displayServerType == SingleCompositerServerType) {
770+
if (auth->isSingleMode()) {
734771
switchToUser(auth->user());
735772
}
736773

src/daemon/Greeter.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ namespace DDM {
8383
m_singleMode = on;
8484
}
8585

86+
void Greeter::setUser(const QString &user) {
87+
m_user = user;
88+
}
89+
90+
void Greeter::setSkipAuth(bool on) {
91+
m_skipAuth = on;
92+
}
93+
8694
void Greeter::setUserActivated(bool active) {
8795
m_userActivated = active;
8896
}
@@ -226,7 +234,8 @@ namespace DDM {
226234
if (m_display->displayServerType() == Display::X11DisplayServerType) {
227235
env.insert(QStringLiteral("DISPLAY"), m_display->name());
228236
env.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("xcb"));
229-
m_auth->setCookie(qobject_cast<XorgDisplayServer*>(displayServer)->cookie());
237+
if (m_display->sessionType() == "x11")
238+
m_auth->setCookie(qobject_cast<XorgDisplayServer*>(displayServer)->cookie());
230239
} else if (m_display->displayServerType() == Display::WaylandDisplayServerType) {
231240
env.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("wayland"));
232241
env.insert(QStringLiteral("QT_WAYLAND_SHELL_INTEGRATION"), QStringLiteral("fullscreen-shell-v1"));
@@ -240,7 +249,7 @@ namespace DDM {
240249
qDebug() << "Greeter starting...";
241250

242251
// start greeter
243-
m_auth->setUser(QStringLiteral("dde"));
252+
m_auth->setUser(m_user);
244253
QString displayServerCmd = m_displayServerCmd;
245254
if (m_singleMode) {
246255
displayServerCmd += " --lockscreen";
@@ -255,6 +264,10 @@ namespace DDM {
255264
return true;
256265
}
257266

267+
if (m_skipAuth) {
268+
m_auth->setSkipAuth();
269+
}
270+
258271
m_auth->start();
259272

260273
m_tryTimer->start();
@@ -371,6 +384,8 @@ namespace DDM {
371384
Q_EMIT ttyFailed();
372385
} else if (status == Auth::HELPER_SESSION_ERROR) {
373386
Q_EMIT failed();
387+
} else if (status == Auth::HELPER_SUCCESS) {
388+
Q_EMIT succeed();
374389
}
375390
}
376391

src/daemon/Greeter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ namespace DDM {
4242
void setSocket(const QString &socket);
4343
void setTheme(const QString &theme);
4444
void setSingleMode(bool on = true);
45+
void setUser(const QString &user);
46+
void setSkipAuth(bool on = true);
4547
void setUserActivated(bool active);
4648

4749
QString displayServerCommand() const;
@@ -67,6 +69,7 @@ namespace DDM {
6769
void ttyFailed();
6870
void failed();
6971
void displayServerFailed();
72+
void succeed();
7073
void greeterStarted();
7174

7275
private:
@@ -75,6 +78,8 @@ namespace DDM {
7578
bool m_userActivated { false };
7679
int m_currentRetry { 0 };
7780
int m_maxRetry{ 3 };
81+
QString m_user = QStringLiteral("dde");
82+
bool m_skipAuth { false };
7883

7984
Display * const m_display { nullptr };
8085
QString m_socket;

src/helper/HelperApp.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ namespace DDM {
123123
m_backend->setIdentifyOnly(true);
124124
}
125125

126+
if ((pos = args.indexOf(QStringLiteral("--skip-auth"))) >= 0) {
127+
m_skipAuth = true;
128+
}
129+
126130
if (server.isEmpty() || m_id <= 0) {
127131
qCritical() << "This application is not supposed to be executed manually";
128132
exit(Auth::HELPER_OTHER_ERROR);
@@ -163,7 +167,7 @@ namespace DDM {
163167
}
164168

165169
Q_ASSERT(getuid() == 0);
166-
if (!m_backend->authenticate()) {
170+
if (!m_skipAuth && !m_backend->authenticate()) {
167171
authenticated(QString());
168172

169173
// write failed login to btmp

src/helper/HelperApp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ namespace DDM {
6767
QString m_user { };
6868
// TODO: get rid of this in a nice clean way along the way with moving to user session X server
6969
QByteArray m_cookie { };
70+
bool m_skipAuth = false;
7071

7172
/*!
7273
\brief Write utmp/wtmp/btmp records when a user logs in

src/helper/UserSession.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,9 @@ namespace DDM {
122122
}
123123

124124
qInfo() << "Starting X11 session:" << m_displayServerCmd << command;
125-
if (m_displayServerCmd.isEmpty()) {
126-
auto args = QProcess::splitCommand(command);
127-
setProgram(args.takeFirst());
128-
setArguments(args);
129-
} else {
130-
setProgram(QStringLiteral(LIBEXEC_INSTALL_DIR "/ddm-helper-start-x11user"));
131-
setArguments({m_displayServerCmd, command});
132-
}
125+
auto args = QProcess::splitCommand(m_displayServerCmd);
126+
setProgram(args.takeFirst());
127+
setArguments(args);
133128
QProcess::start();
134129

135130
} else if (env.value(QStringLiteral("XDG_SESSION_TYPE")) == QLatin1String("wayland")) {
@@ -238,7 +233,7 @@ namespace DDM {
238233

239234
// take control of the tty
240235
if (takeControl) {
241-
if (ioctl(STDIN_FILENO, TIOCSCTTY, 0) < 0) {
236+
if (ioctl(STDIN_FILENO, TIOCSCTTY, 1) < 0) {
242237
const auto error = strerror(errno);
243238
qCritical().nospace() << "Failed to take control of " << ttyString << " (" << QFileInfo(ttyString).owner() << "): " << error;
244239
_exit(Auth::HELPER_TTY_ERROR);

0 commit comments

Comments
 (0)