SDDM ignores custom configuration (/etc/sddm.conf)

4.4k views Asked by At

I've been trying to configure a new theme for SDDM but whatever the changes I do the settings window or manually in /etc/sddm.conf, the embedded default greeter is still the one I get when booting, and the default lock-screen is still the one I get after sleep. I'm on Fedora 28, KDE 5.13.5, kernel 4.19, trying to set Chili as my lockscreen and greeter. Installed it via KDE's SDDM settings GUI, checked the install dir and everything's where it should be. Here is my /etc/sddm.conf :

       │ File: sddm.conf
       │________________________
   1   │ [Autologin]
   2   │ Relogin=false
   3   │ Session=plasma.desktop
   4   │ User=renard
   5   │ 
   6   │ [General]
   7   │ Numlock=on
   8   │ HaltCommand=
   9   │ RebootCommand=
  10   │ 
  11   │ [Theme]
  12   │ Current=plasma-chili
  13   │ CursorTheme=Adwaita
  14   │ 
  15   │ [Users]
  16   │ MaximumUid=65000
  17   │ MinimumUid=1000

Also the theme works just fine when using sddm-greeter --test-mode --theme /usr/share/sddm/themes/plasma-chili/. I can't acces /var/lib/ssdm which seems normal, and I have no sddm.conf.d folder anywhere. Even more puzzling is that it's an issue I've read a bit about before coming here, and I've seen people back from 2014 having the same problems, but I couldn't find a fix anywhere.

1

There are 1 answers

2
Zoltan K. On

It actually does not ignore it - or rather: it is complicated.

I had the same problem, so I checked how it works:

In the sddm source file daemon/PowerManager.cpp there are several backends listed, how pushing the shutdown or the restart button should be handled, and only one of them uses the HaltCommand from /etc/sddm.conf.

For shutdown/HaltCommand, the relevant function is powerOff().

So, what does powerOff() actually do?

/************************************************/
/* POWER MANAGER BACKEND                        */
/************************************************/
    virtual void powerOff() const = 0;
/**********************************************/
/* UPOWER BACKEND                             */
/**********************************************/
// comment from me: some reference to org.freedesktop.UPower"
    void powerOff() const {
        QProcess::execute(mainConfig.HaltCommand.get());   // <---------------
    }
/**********************************************/
/* LOGIN1 && ConsoleKit2 BACKEND              */
/**********************************************/
    void powerOff() const {
        m_interface->call(QStringLiteral("PowerOff"), true);
    }
/**********************************************/
/* POWER MANAGER                              */
/**********************************************/
void PowerManager::powerOff() const {
    if (daemonApp->testing())
        return;

    for (PowerManagerBackend *backend: m_backends) {
        if (backend->capabilities() & Capability::PowerOff) {
            backend->powerOff();
            break;
        }
    }
}

The sddm.conf is read into mainConfig, so mainConfig.HaltCommand holds that command from /etc/sddm.conf, which you are so eager to have executed when you press the button on the screen.

I don't know, if the HaltCommand in /etc/fstab is a feature in progress, which will eventually get to be implemented in every backend, or the documentation is broken, as it fails to mention that this only will ever work with a specific backend...

I did not go over the whole code, so it is even possible that the intention is that if a HaltCommand is presented in sddm.conf, then regardless of backend, that command should be executed, only they did not get around to implement it, or they forgot it over time.

I am using Debian Stretch with systemd, so I am pretty sure, I have the LOGIN1 && ConsoleKit2 backend. Wile this is not ideal, at least I now know that I am not messing up the config, rather, what I wanted cannot be done with sddm tweaking...

NOTE: I was using the sddm-0.14.0 code from the Debian sources for my investigation. I checked the latest sources at

src/daemon/PowerManager.cpp

And it seems, this code did not change.

Although, I did not check it (not even sure, how to do it), it seems, if you switch to UPower backend, you will get the HaltCommand functionality.

Also, it seems to me, a couple of if-s in all the backends would do the trick of using the HaltCommand, whenever it is changed from the default by the user.


While I am at it, checked what happens to the Current configuration item in the latest source. It seems, it should work:

Here is the [theme] config, as the code sees it:

src/common/Configuration.h

    Section(Theme,
        Entry(ThemeDir,            QString,     _S(DATA_INSTALL_DIR "/themes"),             _S("Theme directory path"));
        Entry(Current,             QString,     _S(""),                                     _S("Current theme name"));
        Entry(FacesDir,            QString,     _S(DATA_INSTALL_DIR "/faces"),              _S("Global directory for user avatars\n"
                                                                                               "The files should be named <username>.face.icon"));
        Entry(CursorTheme,         QString,     QString(),                                  _S("Cursor theme used in the greeter"));
        Entry(EnableAvatars,       bool,        true,                                       _S("Enable display of custom user avatars"));
        Entry(DisableAvatarsThreshold,int,      7,                                          _S("Number of users to use as threshold\n"
                                                                                               "above which avatars are disabled\n"
                                                                                               "unless explicitly enabled with EnableAvatars"));
    );

This is the part, where the "Current" theme is actually gets parsed and checked, it seems, it should give you a warning - maybe in /var/log/sddm.log - if it does not find it:

src/daemon/Display.cpp

QString Display::findGreeterTheme() const {
    QString themeName = mainConfig.Theme.Current.get();

    // an unconfigured theme means the user wants to load the
    // default theme from the resources
    if (themeName.isEmpty())
        return QString();

    QDir dir(mainConfig.Theme.ThemeDir.get());

    // return the default theme if it exists
    if (dir.exists(themeName))
        return dir.absoluteFilePath(themeName);

    // otherwise use the embedded theme
    qWarning() << "The configured theme" << themeName << "doesn't exist, using the embedded theme instead";
    return QString();
}

I am a bit lost here, but it seems, IF the theme is found on the path, then it looks for the theme configuration files, either in the themePath/metadata.desktop, or somehow you can configure a custom named theme configuration file. I think themePath is [theme] ThemeDir in sddm.conf.

src/daemon/Greeter.cpp

void Greeter::setTheme(const QString &theme) {
    m_themePath = theme;

    if (theme.isEmpty()) {
        m_metadata->setTo(QString());
        m_themeConfig->setTo(QString());
    } else {
        const QString path = QStringLiteral("%1/metadata.desktop").arg(m_themePath);
        m_metadata->setTo(path);

        QString configFile = QStringLiteral("%1/%2").arg(m_themePath).arg(m_metadata->configFile());
        m_themeConfig->setTo(configFile);
    }
}

All-in-all, you could try look into (from problem-solving to work-around):

  1. is your theme on the path? try giving the absolute path! check /var/log/sddm.log and also /var/log/syslog for this "The configured theme" << themeName << "doesn't exist, using the embedded theme instead" error message!
  2. try adding themeDir
  3. does your theme have a metadata.desktop file? if not, try to rename/symlink a file that seems like it could be the theme's version of it
  4. sddm --example-config prints your current config; if it pops up a [theme] Current, copy/symlink your theme in that location (maybe backup the original), and see what happens

NOTE: I did not see any more conditions in the code for using theme other than "does this file exists?" - which does not mean they are not there. However, I did see that the theme is used to create user-icons, user-face, whatever, so it possible that it fails due to some missing resources down the road - I doubt this is the case, but it is possible.

While it is not a full answer, I already looked at the code, so I gave it a go, I hope I turned up something you can use to solve the problem!