Skip to content

Commit

Permalink
Wayland display server
Browse files Browse the repository at this point in the history
Introduce a new display server option to run the greeter with.
In the future this will be the default display server.

This patch contains the most important parts to get the greeter running
on Wayland, but it's not possible to select a keyboard layout.

At the moment the Wayland socket is assumed to be "wayland-0" but in a
multi-seat configuration we would have more than one greeter running,
each with a diffent socket and the assumption won't work anymore.

In the future we will figure out how to do, after all at the moment this
is considered enough for most people.

Closes: #440
  • Loading branch information
plfiorini authored and aleixpol committed Apr 20, 2021
1 parent cfdf66b commit 34ecafa
Show file tree
Hide file tree
Showing 21 changed files with 677 additions and 31 deletions.
5 changes: 5 additions & 0 deletions data/man/sddm.conf.rst.in
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ OPTIONS
Valid values are:
* `x11`: X server running as root.
* `x11-user`: X server running as unprivileged user.
* `wayland`: Wayland compositor as unprivileged user.
Default value is "x11".
For `x11-user` you might need to configure Xorg.wrap(1).

Expand Down Expand Up @@ -165,6 +166,10 @@ OPTIONS

[Wayland] section:

`CompositorCommand=`
Path of the compositor to execute when starting the greeter.
Default value is "weston --shell=fullscreen-shell.so".

`SessionDir=`
Path of the directory containing session files.
Default value is "/usr/share/wayland-sessions".
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ configure_file("common/Constants.h.in" "common/Constants.h" IMMEDIATE @ONLY)
add_subdirectory(daemon)
add_subdirectory(greeter)
add_subdirectory(helper)
#add_subdirectory(helper-wayland)
3 changes: 2 additions & 1 deletion src/common/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace SDDM {
// Name Type Default value Description
// TODO: Change default to x11-user in a future release
Entry(DisplayServer, QString, _S("x11"), _S("Which display server should be used.\n"
"Valid values are: x11, x11-user."));
"Valid values are: x11, x11-user, wayland."));
Entry(HaltCommand, QString, _S(HALT_COMMAND), _S("Halt command"));
Entry(RebootCommand, QString, _S(REBOOT_COMMAND), _S("Reboot command"));
Entry(Numlock, NumState, NUM_NONE, _S("Initial NumLock state. Can be on, off or none.\n"
Expand Down Expand Up @@ -77,6 +77,7 @@ namespace SDDM {
);

Section(Wayland,
Entry(CompositorCommand, QString, _S("weston --shell=fullscreen-shell.so"), _S("Path of the Wayland compositor to execute when starting the greeter"));
Entry(SessionDir, QString, _S("/usr/share/wayland-sessions"), _S("Directory containing available Wayland sessions"));
Entry(SessionCommand, QString, _S(WAYLAND_SESSION_COMMAND), _S("Path to a script to execute when starting the desktop session"));
Entry(SessionLogFile, QString, _S(".local/share/sddm/wayland-session.log"),_S("Path to the user session log file"));
Expand Down
2 changes: 2 additions & 0 deletions src/daemon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ set(DAEMON_SOURCES
XorgDisplayServer.cpp
XorgUserDisplayServer.cpp
XorgUserDisplayServer.h
WaylandDisplayServer.cpp
WaylandDisplayServer.h
)

# Different implementations of the VT switching code
Expand Down
7 changes: 7 additions & 0 deletions src/daemon/Display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "Login1Manager.h"
#include "Login1Session.h"
#include "VirtualTerminal.h"
#include "WaylandDisplayServer.h"

#if defined(Q_OS_LINUX)
#include <utmp.h>
Expand All @@ -70,6 +71,8 @@ namespace SDDM {
m_displayServerType = X11DisplayServerType;
else if (displayServerType == QStringLiteral("x11-user"))
m_displayServerType = X11UserDisplayServerType;
else if (displayServerType == QStringLiteral("wayland"))
m_displayServerType = WaylandDisplayServerType;
else {
qWarning("\"%s\" is an invalid value for General.DisplayServer: fall back to \"x11\"",
qPrintable(displayServerType));
Expand All @@ -85,6 +88,10 @@ namespace SDDM {
m_displayServer = new XorgUserDisplayServer(this);
m_greeter->setDisplayServerCommand(XorgUserDisplayServer::command(this));
break;
case WaylandDisplayServerType:
m_displayServer = new WaylandDisplayServer(this);
m_greeter->setDisplayServerCommand(mainConfig.Wayland.CompositorCommand.get());
break;
}

// Print what VT we are using for more information
Expand Down
3 changes: 2 additions & 1 deletion src/daemon/Display.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ namespace SDDM {
public:
enum DisplayServerType {
X11DisplayServerType,
X11UserDisplayServerType
X11UserDisplayServerType,
WaylandDisplayServerType
};
Q_ENUM(DisplayServerType)

Expand Down
26 changes: 18 additions & 8 deletions src/daemon/Greeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "ThemeMetadata.h"
#include "Display.h"
#include "XorgUserDisplayServer.h"
#include "WaylandDisplayServer.h"

#include <QtCore/QDebug>
#include <QtCore/QProcess>
Expand Down Expand Up @@ -124,14 +125,15 @@ namespace SDDM {

args << QStringLiteral("--test-mode");

// set process environment
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert(QStringLiteral("DISPLAY"), m_display->name());
env.insert(QStringLiteral("XAUTHORITY"), m_authPath);
env.insert(QStringLiteral("XCURSOR_THEME"), xcursorTheme);
m_process->setProcessEnvironment(env);

// start greeter
if (m_display->displayServerType() == Display::X11DisplayServerType) {
// set process environment
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert(QStringLiteral("DISPLAY"), m_display->name());
env.insert(QStringLiteral("XAUTHORITY"), m_authPath);
env.insert(QStringLiteral("XCURSOR_THEME"), xcursorTheme);
m_process->setProcessEnvironment(env);
}
// Greeter command
m_process->start(QStringLiteral("%1/sddm-greeter").arg(QStringLiteral(BIN_INSTALL_DIR)), args);

//if we fail to start bail immediately, and don't block in waitForStarted
Expand Down Expand Up @@ -195,6 +197,9 @@ namespace SDDM {
if (m_display->displayServerType() == Display::X11DisplayServerType) {
env.insert(QStringLiteral("DISPLAY"), m_display->name());
env.insert(QStringLiteral("XAUTHORITY"), m_authPath);
env.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("xcb"));
} else if (m_display->displayServerType() == Display::WaylandDisplayServerType) {
env.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("wayland"));
}
m_auth->insertEnvironment(env);

Expand Down Expand Up @@ -273,9 +278,14 @@ namespace SDDM {
void Greeter::onDisplayServerReady(const QString &displayName)
{
auto *displayServer = m_display->displayServer();

auto *xorgUser = qobject_cast<XorgUserDisplayServer *>(displayServer);
if (xorgUser)
xorgUser->setDisplayName(displayName);

auto *wayland = qobject_cast<WaylandDisplayServer *>(displayServer);
if (wayland)
wayland->setDisplayName(displayName);
}

void Greeter::onHelperFinished(Auth::HelperExitStatus status) {
Expand Down
76 changes: 76 additions & 0 deletions src/daemon/WaylandDisplayServer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/***************************************************************************
* Copyright (c) 2021 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
***************************************************************************/

#include "WaylandDisplayServer.h"

namespace SDDM {

WaylandDisplayServer::WaylandDisplayServer(Display *parent)
: DisplayServer(parent)
{
}

WaylandDisplayServer::~WaylandDisplayServer()
{
stop();
}

QString WaylandDisplayServer::sessionType() const
{
return QStringLiteral("wayland");
}

void WaylandDisplayServer::setDisplayName(const QString &displayName)
{
m_display = displayName;
}

bool WaylandDisplayServer::start()
{
// Check flag
if (m_started)
return false;

// Set flag
m_started = true;
emit started();

return true;
}

void WaylandDisplayServer::stop()
{
// Check flag
if (!m_started)
return;

// Reset flag
m_started = false;
emit stopped();
}

void WaylandDisplayServer::finished()
{
}

void WaylandDisplayServer::setupDisplay()
{
}

} // namespace SDDM
48 changes: 48 additions & 0 deletions src/daemon/WaylandDisplayServer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/***************************************************************************
* Copyright (c) 2021 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
***************************************************************************/

#ifndef SDDM_WAYLANDDISPLAYSERVER_H
#define SDDM_WAYLANDDISPLAYSERVER_H

#include "DisplayServer.h"

namespace SDDM {

class WaylandDisplayServer : public DisplayServer
{
Q_OBJECT
Q_DISABLE_COPY(WaylandDisplayServer)
public:
explicit WaylandDisplayServer(Display *parent);
~WaylandDisplayServer();

QString sessionType() const;

void setDisplayName(const QString &displayName);

public Q_SLOTS:
bool start();
void stop();
void finished();
void setupDisplay();
};

} // namespace SDDM

#endif // SDDM_WAYLANDDISPLAYSERVER_H
2 changes: 2 additions & 0 deletions src/greeter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ set(GREETER_SOURCES
ScreenModel.cpp
SessionModel.cpp
UserModel.cpp
waylandkeyboardbackend.cpp
waylandkeyboardbackend.h
XcbKeyboardBackend.cpp
)

Expand Down
33 changes: 24 additions & 9 deletions src/greeter/KeyboardModel.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/***************************************************************************
* Copyright (c) 2021 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
* Copyright (c) 2013 Nikita Mikhaylov <nslqqq@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
Expand All @@ -17,8 +18,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
***************************************************************************/

#include <QGuiApplication>

#include "KeyboardModel.h"
#include "KeyboardModel_p.h"
#include "waylandkeyboardbackend.h"
#include "XcbKeyboardBackend.h"

namespace SDDM {
Expand All @@ -27,14 +31,21 @@ namespace SDDM {
/**********************************************/

KeyboardModel::KeyboardModel() : d(new KeyboardModelPrivate) {
m_backend = new XcbKeyboardBackend(d);
m_backend->init();
m_backend->connectEventsDispatcher(this);
if (QGuiApplication::platformName() == QLatin1String("xcb")) {
m_backend = new XcbKeyboardBackend(d);
m_backend->init();
m_backend->connectEventsDispatcher(this);
} else if (QGuiApplication::platformName().contains(QLatin1String("wayland"))) {
m_backend = new WaylandKeyboardBackend(d);
m_backend->init();
}
}

KeyboardModel::~KeyboardModel() {
m_backend->disconnect();
delete m_backend;
if (m_backend) {
m_backend->disconnect();
delete m_backend;
}

for (QObject *layout: d->layouts) {
delete layout;
Expand All @@ -49,7 +60,8 @@ namespace SDDM {
void KeyboardModel::setNumLockState(bool state) {
if (d->numlock.enabled != state) {
d->numlock.enabled = state;
m_backend->sendChanges();
if (m_backend)
m_backend->sendChanges();

emit numLockStateChanged();
}
Expand All @@ -62,7 +74,8 @@ namespace SDDM {
void KeyboardModel::setCapsLockState(bool state) {
if (d->capslock.enabled != state) {
d->capslock.enabled = state;
m_backend->sendChanges();
if (m_backend)
m_backend->sendChanges();

emit capsLockStateChanged();
}
Expand All @@ -79,7 +92,8 @@ namespace SDDM {
void KeyboardModel::setCurrentLayout(int id) {
if (d->layout_id != id) {
d->layout_id = id;
m_backend->sendChanges();
if (m_backend)
m_backend->sendChanges();

emit currentLayoutChanged();
}
Expand All @@ -96,7 +110,8 @@ namespace SDDM {
QList<QObject*> layouts_old = d->layouts;

// Process events
m_backend->dispatchEvents();
if (m_backend)
m_backend->dispatchEvents();

// Send updates
if (caps_old != d->capslock.enabled)
Expand Down
2 changes: 1 addition & 1 deletion src/greeter/KeyboardModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ namespace SDDM {

private:
KeyboardModelPrivate * d { nullptr };
KeyboardBackend * m_backend;
KeyboardBackend * m_backend = nullptr;
};
}

Expand Down

0 comments on commit 34ecafa

Please sign in to comment.