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

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.

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):
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!
try adding themeDir
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
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!

Related

Retrieve file contents during Gatsby build

I need to pull in the contents of a program source file for display in a page generated by Gatsby. I've got everything wired up to the point where I should be able to call
// my-fancy-template.tsx
import { readFileSync } from "fs";
// ...
const fileContents = readFileSync("./my/relative/file/path.cs");
However, on running either gatsby develop or gatsby build, I'm getting the following error
This dependency was not found:
⠀
* fs in ./src/templates/my-fancy-template.tsx
⠀
To install it, you can run: npm install --save fs
However, all the documentation would suggest that this module is native to Node unless it is being run on the browser. I'm not overly familiar with Node yet, but given that gatsby build also fails (this command does not even start a local server), I'd be a little surprised if this was the problem.
I even tried this from a new test site (gatsby new test) to the same effect.
I found this in the sidebar and gave that a shot, but it appears it just declared that fs was available; it didn't actually provide fs.
It then struck me that while Gatsby creates the pages at build-time, it may not render those pages until they're needed. This may be a faulty assessment, but it ultimately led to the solution I needed:
You'll need to add the file contents to a field on File (assuming you're using gatsby-source-filesystem) during exports.onCreateNode in gatsby-node.js. You can do this via the usual means:
if (node.internal.type === `File`) {
fs.readFile(node.absolutePath, undefined, (_err, buf) => {
createNodeField({ node, name: `contents`, value: buf.toString()});
});
}
You can then access this field in your query inside my-fancy-template.tsx:
{
allFile {
nodes {
fields { content }
}
}
}
From there, you're free to use fields.content inside each element of allFile.nodes. (This of course also applies to file query methods.)
Naturally, I'd be ecstatic if someone has a more elegant solution :-)

Babel / Node / Relay / Webpack cache?

Generally:
Do these four systems have caches? And if so, what is the method for clearing each?
Specifically:
Having trouble with a react app we are developing. Seemingly sporadically we get the following error when developing locally:
"Invariant Violation: RelayQL: Unexpected invocation at runtime. Either the Babel transform was not set up, or it failed to identify this call site. Make sure it is being used verbatim as `Relay.QL`."
Am yet to notice any particular reason why/when this starts happening.
I finally found a hack solution which involved me going into the referenced component file referenced (further in the error msg, unshown) and deleting the RelayQL fragment inside e.g.
export default Relay.createContainer(PinterestShare, {
fragments: {
resource: () => Relay.QL`
fragment on Resource {
id
title
files {
type
images {
medium { url width }
}
}
}
`
}
});
to
export default Relay.createContainer(PinterestShare, {
fragments: {
resource: () => Relay.QL`
`
}
});
I then save, and reboot the app. It crashes, obviously, as the fragment is malformed. So I undo the change back to the original, and reboot the app again. Now, the original error is fixed, despite no code actually changing.
So what happened? Somehow doing this process is flushing some cache? Is this in node, webpack, relay, or babel? I've tried rebooting my machine inbetween, as well as killall node, neither which work, which implies to me it is not RAM based...
The annoying part now is I am having to do this for all of my individual component files. Surely there must be a way to purge this mystery cache enmass for the whole app?

Error setting scrollFactor on FlxSprite after update to HaxeFlixel 3.3.0

I just finished updating my HaxeFlixel install to 3.3.0 and after ironing out all the other upgrade changes I am still getting one error I can't find any explanation for. I am setting the scrollFactor property on the FlxSprites that make up my background elements, and had no problem with it before 3.3.0. I can't seem to find any references to that property changing with the update.
Here is the relevant code where I am setting the property:
//Setup bg
var bg:FlxSprite;
var scrollFactor:FlxPoint;
for (i in 0...loader.bgArray.length){
bg = new FlxSprite(0, 0, loader.bgArray[i][0]);
scrollFactor = new FlxPoint(
Std.parseFloat(loader.bgArray[i][1]),
Std.parseFloat(loader.bgArray[i][2]));
bg.scrollFactor = scrollFactor;
add(bg);
}
Here is my output from haxelib list:
flixel: [3.3.0] hxcpp: [3.1.30] lime-tools: [1.4.0] lime:
[0.9.7] openfl-html5: [1.4.0-beta] openfl-native: [1.4.0]
openfl-samples: [1.3.0] openfl: [1.4.0]
When I run lime test flash in my project folder with the above snippet I get:
source/PlayState.hx:54: characters 3-33 : Cannot access field or
identifier scrollFactor for writing
Line 54 is the one where I am setting bg.scrollFactor.
I'm not sure about notices about this update, but indeed the current situation is that scrollFactor accessors are (default, null), so there is no chance you could set it up like that.
It also isn't even the most proper way to do that, since in HaxeFlixel FlxPoints could and mostly should be pooled, so you would usually use not new FlxPoint(x, y), but FlxPoint.get(x, y) which will make your code run much faster.
Anyhow, down to your current situation, just use
bg.scrollFactor.set(
Std.parseFloat(loader.bgArray[i][1]),
Std.parseFloat(loader.bgArray[i][2])
);
instead of
scrollFactor = new FlxPoint(
Std.parseFloat(loader.bgArray[i][1]),
Std.parseFloat(loader.bgArray[i][2])
);
bg.scrollFactor = scrollFactor;
and it will work perfectly (and faster).

How to do navigation durandal.js?

i am trying to use durandal.js for single page architecture,
i already have application where i am loading all pages in div = old approach for single page architecture,
what i want to do is when i click on page i need to open hotspa pages,
for now i write something like this . www.xyz.com#/details,
where # details is my durandal view page!
when i put <a> herf ....#/details, i got error like this :
http://postimg.org/image/hoeu1wiz5/
but when i refresh with same url, it is working fine, i am able to see view!
i do not know why i got this error
If you are using anything before version 2.0 of Durandal, you are getting this because in your Shell.js you are not defining router, or you have a bad definition of where the router module is, or possibly you are defining scripts in your index instead of 'requiring them' via require.js
1st - Check shell.js, at the top you should have a define function and it should say / do something like this, and should be exposing that to the view like so -
define(['durandal/plugins/router'], function (router) {
var shell = {
router: router
};
return shell;
};
2nd - Check and make sure the 'durandal/plugins/router' is point to the correct location in the solution explorer, in this case it is app > durandal > plugins > router. If it is not or if there is no router you can add it using nuget.
3rd - Make sure you aren't loading scripts up in your index or shell html pages. When using require.js you need to move any scripts you are loading into a require statement for everything to function properly. The 'Mismatched anonymous define() module' error usually occurs when you are loading them elsewhere - http://requirejs.org/docs/errors.html#mismatch

Standalone PHP script using Expression Engine

Is there a way to make a script where I can do stuff like $this->EE->db (i.e. using Expression Engine's classes, for example to access the database), but that can be run in the command line?
I tried searching for it, but the docs don't seem to contain this information (please correct me if I'm wrong). I'm using EE 2.4 (the link above should point to 2.4 docs).
The following article seems to have a possible approach: Bootstrapping EE for CLI Access
Duplicate your index.php file and name it cli.php.
Move the index.php file outside your DOCUMENT_ROOT. Now, technically, this isn’t required, but there’s no reason for prying
eyes to see your hard work so why not protect it.
Inside cli.php update the $system_path on line 26 to point to your system folder.
Inside cli.php update the $routing['controller'] on line 96 to be cli.
Inside cli.php update the APPPATH on line 96 to be $system_path.'cli/'.
Duplicate the system/expressionengine directory and name it system/cli.
Duplicate the cli/controllers/ee.php file and name it cli/controllers/cli.php.
Finally, update the class name in cli/controllers/cli.php to be Cli and remove the methods.
By default EE calls the index method, so add in an index method to do what you need.
#Zenbuman This was useful as a starting point although I would add I had issues with all of my requests going to cli -> index, whereas I wanted some that went to cli->task1, cli->task2 etc
I had to update *system\codeigniter\system\core\URI.php*so that it knew how to extract the parameters I was passing via the command line, I got the code below from a more recent version of Codeigniter which supports the CLI
// Is the request coming from the command line?
if (php_sapi_name() == 'cli' or defined('STDIN'))
{
$this->_set_uri_string($this->_parse_cli_args());
return;
}
// Let's try the REQUEST_URI first, this will work in most situations
and also created the function in the same file
private function _parse_cli_args()
{
$args = array_slice($_SERVER['argv'], 1);
return $args ? '/' . implode('/', $args) : '';
}
Also had to comment out the following in my cli.php file as all routing was going to the index method in my cli controller and ignoring my parameters
/*
* ~ line 109 - 111 /cli.php
* ---------------------------------------------------------------
* Disable all routing, send everything to the frontend
* ---------------------------------------------------------------
*/
$routing['directory'] = '';
$routing['controller'] = 'cli';
//$routing['function'] = '';
Even leaving
$routing['function'] = '';
Will force requests to go to index controller
In the end I felt this was a bit hacky but I really need to use the EE API library in my case. Otherwise I would have just created a separate application with Codeigniter to handle my CLI needs, hope the above helps others.
I found #Zenbuman's answer after solving my own variation of this problem. My example allows you to keep the cron script inside a module, so if you need your module to have a cron feature it all stays neatly packaged together. Here's a detailed guide on my blog.

Resources