-
Notifications
You must be signed in to change notification settings - Fork 780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Start i3 with a systemd service, if systemd is running and the service is loaded. #5591
base: next
Are you sure you want to change the base?
Conversation
is loaded. The systemd service activates `graphical-session.target` which in turn may activate other useful services such as the ssh-agent.
|
||
[Service] | ||
Type=exec | ||
ExecStart=i3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Units usually use absolute paths for exec.
Should it be @bindir@/i3
?
|
||
[Service] | ||
Type=exec | ||
ExecStart=i3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ExecStart=i3 | |
ExecStart=i3 | |
ExecReload=/usr/bin/i3-msg restart |
In case the user want's to reload or restart i3.
I'm referencing restart instead of reload here since systemd's restart doesn't allow
the user to specific it's on command for restarts, there is only the option to define
a reload, start or stop command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this PR, replacing autostart scripts with services becomes feasible. I would add documentation about something like this:
[Unit]
Description=picom
BindsTo=i3@%i.service
After=i3@%i.service
[Service]
Environment=DISPLAY=%i
ExecStart=picom <args>
[Install]
[email protected]
Placed at $XDG_CONFIG_HOME/systemd/user/picom.service
, it could then be enabled with systemctl --user enable picom@
.
Alternatively, if sticking with the current service in the PR and not implementing instances, a simpler service like this could be used:
[Unit]
Description=picom
BindsTo=i3.service
After=i3.service
[Service]
ExecStart=picom <args>
[Install]
WantedBy=i3.service
The enabling would then also be without the at sign.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If run a second time before the first is done, it will hang and wait for the same service. If not implementing support for multiple instances, a check and message for if the service is already running would at least show that the single instance limit is intended.
BindsTo=graphical-session.target | ||
Before=graphical-session.target | ||
|
||
[Service] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slice=session.slice
should be set in this case according to systemd.special
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, this might not be the best since it seems like all processes i3 spawns, including applications, then fall under the session slice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where does the service get DISPLAY
and XAUTHORITY
from? I can get it to work using systemctl --user import-environment DISPLAY XAUTHORITY
in .xinitrc
or adding ENVIRONMENT=...
to the service, but I don't see how the service can work as is, although I might be missing something.
Although I don't often have two instances open, it does happen. My suggestion is to make the unit into a template and use the instance variable like Environment=DISPLAY=%i
. This will support multiple instances and nonstandard DISPLAY
values, making i3-session-start
a drop-in replacement for running i3
.
As for XAUTHORITY
, asking the user to run/script systemctl --user import-environment XAUTHORITY
before i3-session-start
seems like a good choice since it is global for a user/systemd user instance (unlike DISPLAY
), although a fallback to ~/.Xauthority
would probably be enough for most. For reference, Arch already sets XAUTHORITY
this way, although it is only suggested in a note that you actually include this in your user's .xinitrc
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where does the service get
DISPLAY
andXAUTHORITY
from?
/etc/X11/xinit/xinitrc.d/50-systemd-user.sh
should be sourced by the user's $XINITRC
(default ~/.xinitrc
, falling back to /etc/X11/xinit/xinitrc
if neither is found), which is sourced by startx
/xinit
. The fallback xinitrc
contains:
# ...
# start some nice programs
if [ -d /etc/X11/xinit/xinitrc.d ] ; then
for f in /etc/X11/xinit/xinitrc.d/?*.sh ; do
[ -x "$f" ] && . "$f"
done
unset f
fi
As per the Arch Wiki:
Units started by user instance of systemd do not inherit any of the environment variables set in places like .bashrc etc. There are several ways to set environment variables for them ...
There's a bit in 2.1.1 talking about DISPLAY
and XAUTHORITY
in particular.
I hope some of this is useful and not just stuff you already know!
Edit: I've just read that /etc/X11/xinit/xinitrc.d/50-systemd-user.sh
might be an Arch-implemented file (although it contains a license specifying it as part of systemd...), so here's its contents for convenience:
#!/bin/sh
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
systemctl --user import-environment DISPLAY XAUTHORITY
if command -v dbus-update-activation-environment >/dev/null 2>&1; then
dbus-update-activation-environment DISPLAY XAUTHORITY
fi
I think applications should be started by the session-manager not by the
window-manager.
I don't think ***@***.*** is needed as there wouldn't be more than one
windoww-manager in the session.
Using `Install=windwmanager.servcice` in i3.service and
`After=windowmanager.service` in picom.service would make the unit more
universal for e.g. upstreaming of the picom service file.
|
What do you mean by this?
After sleeping on it, this sounds more reasonable. The extra complexity is probably not justifiable for such a niche case. Using I am curious though about how you provide
Yep, seems obvious in hindsight. Although |
faivirol ***@***.***> writes:
> I think applications should be started by the session-manager not by the
window-manager.
What do you mean by this?
> I don't think \*\*\*@\*\*\*.\*\*\* is needed as there wouldn't be more than one
windoww-manager in the session.
After sleeping on it, this sounds more reasonable. The extra
complexity is probably not justifiable for such a niche case. Using
`systemd --user import-environment DISPLAY` would remove the need to
provide it through an instance variable or hardcode it. If a user
needs to run multiple instances, they can always fall back to
executing the `i3` binary directly.
I am curious though about how you provide `DISPLAY` and `XAUTHORITY`
to the service you posted in #5186, @Thaodan. Did you use
`import-environment` as well?
I only used the existing session started by KDE. The KDE session starter
first sets up it's own config, runs env scripts and then also imports the
systemd environment:
https://invent.kde.org/plasma/plasma-workspace/-/blob/master/startkde/startplasma-x11.cpp?ref_type=heads#L78
> Using `Install=windwmanager.servcice` in i3.service and
`After=windowmanager.service` in picom.service would make the unit more
universal for e.g. upstreaming of the picom service file.
Yep, seems obvious in hindsight. Although `graphical-session.target`
works as well (for `BindsTo`, `After` and `WantedBy`), so I think
that's better than creating a new `windowmanager.service` standard.
It's the same technique used to have multiple units to provide the same
service such as a display-manager.
|
i3-session-start is a bash script ( Also the service type can be changed to
I use ExecStopPost to shut down other graphical programs started by systemd gracefully when i3 stops. In my experience (i have been starting i3 with systemd for years), there are more environment variables one probably want. PATH, without it, relative paths in the i3 config file will not be found f.i.
You will break lots of peoples configs if they start i3 without access to the PATH environment variable, but you will also upset lots of people for compromising security if you do import the PATH environment variable. In my opinion this whole systemd stuff is headaches that the package maintainers could customize for their distros if they wanted to. I wouldn't be surprised if a large chunk of i3 user base doesn't even have systemd.. |
The systemd service activates
graphical-session.target
which in turn may activate other useful services such as the ssh-agent.Fixes #5186