mirror of
https://github.com/sddm/sddm.git
synced 2024-11-23 18:13:26 +08:00
Display: Do not offer a tty if it's already taken by a logind session
Otherwise, it all freezes and nothing works as it should. Fixes #1588
This commit is contained in:
parent
a16f612e34
commit
21e965aab8
@ -35,6 +35,9 @@ option(ENABLE_PAM "Enable PAM support" ON)
|
||||
option(NO_SYSTEMD "Disable systemd support" OFF)
|
||||
option(USE_ELOGIND "Use elogind instead of logind" OFF)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# ECM
|
||||
find_package(ECM 1.4.0 REQUIRED NO_MODULE)
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH};${ECM_MODULE_PATH}")
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <linux/kd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <qscopeguard.h>
|
||||
#include <QFileInfo>
|
||||
|
||||
#define RELEASE_DISPLAY_SIGNAL (SIGRTMAX)
|
||||
#define ACQUIRE_DISPLAY_SIGNAL (SIGRTMAX - 1)
|
||||
@ -116,8 +117,8 @@ out:
|
||||
qDebug() << "VT mode didn't need to be fixed";
|
||||
}
|
||||
|
||||
int fetchAvailableVt() {
|
||||
// open VT master
|
||||
int currentVt()
|
||||
{
|
||||
int fd = open("/dev/tty0", O_RDWR | O_NOCTTY);
|
||||
if (fd < 0) {
|
||||
qCritical() << "Failed to open VT master:" << strerror(errno);
|
||||
@ -129,19 +130,12 @@ out:
|
||||
|
||||
vt_stat vtState = { 0 };
|
||||
if (ioctl(fd, VT_GETSTATE, &vtState) < 0) {
|
||||
qCritical() << "Failed to get current VT:" << strerror(errno);
|
||||
|
||||
int vt = 0;
|
||||
// If there's no current tty, request the next to open
|
||||
if (ioctl(fd, VT_OPENQRY, &vt) < 0) {
|
||||
qCritical() << "Failed to open new VT:" << strerror(errno);
|
||||
return -1;
|
||||
}
|
||||
return vt;
|
||||
return -1;
|
||||
}
|
||||
return vtState.v_active;
|
||||
}
|
||||
|
||||
|
||||
int setUpNewVt() {
|
||||
// open VT master
|
||||
int fd = open("/dev/tty0", O_RDWR | O_NOCTTY);
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
namespace SDDM {
|
||||
namespace VirtualTerminal {
|
||||
int fetchAvailableVt();
|
||||
int currentVt();
|
||||
int setUpNewVt();
|
||||
void jumpToVt(int vt, bool vt_auto);
|
||||
}
|
||||
|
@ -35,10 +35,9 @@ namespace SDDM {
|
||||
static char ttyvX[] = "/dev/ttyvX";
|
||||
static const char ttyvs[] = "0123456789ab";
|
||||
|
||||
int setUpNewVt() {
|
||||
// there is no way to create VTs on FreeBSD, so
|
||||
// just try to fetch any available
|
||||
return fetchAvailableVt();
|
||||
int currentVt()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void jumpToVt(int vt, bool vt_auto) {
|
||||
@ -64,7 +63,7 @@ namespace SDDM {
|
||||
}
|
||||
}
|
||||
|
||||
int fetchAvailableVt() {
|
||||
int setUpNewVt() {
|
||||
int fd = ::open("/dev/console", O_RDONLY);
|
||||
if(fd == -1) {
|
||||
qWarning() << "Failed to open /dev/console: " << strerror(errno);
|
||||
|
@ -40,6 +40,10 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/vt.h>
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusReply>
|
||||
@ -51,6 +55,35 @@
|
||||
|
||||
|
||||
namespace SDDM {
|
||||
bool isTtyInUse(const QString &desiredTty) {
|
||||
if (Logind::isAvailable()) {
|
||||
OrgFreedesktopLogin1ManagerInterface manager(Logind::serviceName(), Logind::managerPath(), QDBusConnection::systemBus());
|
||||
auto reply = manager.ListSessions();
|
||||
reply.waitForFinished();
|
||||
|
||||
const auto info = reply.value();
|
||||
for(const SessionInfo &s : info) {
|
||||
OrgFreedesktopLogin1SessionInterface session(Logind::serviceName(), s.sessionPath.path(), QDBusConnection::systemBus());
|
||||
if (desiredTty == session.tTY() && session.state() != QLatin1String("closing")) {
|
||||
qDebug() << "tty" << desiredTty << "already in use by" << session.user().path << session.state()
|
||||
<< session.display() << session.desktop() << session.vTNr();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int fetchAvailableVt() {
|
||||
const auto vt = VirtualTerminal::currentVt();
|
||||
if (vt > 0) {
|
||||
if (!isTtyInUse(QStringLiteral("tty%1").arg(vt))) {
|
||||
return vt;
|
||||
}
|
||||
}
|
||||
return VirtualTerminal::setUpNewVt();
|
||||
}
|
||||
|
||||
Display::Display(Seat *parent) : QObject(parent),
|
||||
m_auth(new Auth(this)),
|
||||
m_seat(parent),
|
||||
@ -62,10 +95,10 @@ namespace SDDM {
|
||||
const QString &displayServerType = mainConfig.DisplayServer.get().toLower();
|
||||
if (displayServerType == QStringLiteral("x11-user")) {
|
||||
m_displayServerType = X11UserDisplayServerType;
|
||||
m_terminalId = VirtualTerminal::fetchAvailableVt();
|
||||
m_terminalId = fetchAvailableVt();
|
||||
} else if (displayServerType == QStringLiteral("wayland")) {
|
||||
m_displayServerType = WaylandDisplayServerType;
|
||||
m_terminalId = VirtualTerminal::fetchAvailableVt();
|
||||
m_terminalId = fetchAvailableVt();
|
||||
} else {
|
||||
if (displayServerType != QLatin1String("x11")) {
|
||||
qWarning("\"%s\" is an invalid value for General.DisplayServer: fall back to \"x11\"",
|
||||
|
Loading…
Reference in New Issue
Block a user