├── .gitignore ├── README.md ├── conkeror@.service ├── dbus.service ├── dbus.socket ├── default.target ├── emacs-trunk@.service ├── emacs@.service ├── emacsclient@.service ├── emacsd.service ├── env.service ├── firefox@.service ├── gpg-agent.service ├── gui@.target ├── guilewm@.service ├── irexec.service ├── lxde@.service ├── midi.service ├── mosd@.service ├── numlock@.service ├── openbox@.service ├── setxkbmap@.service ├── stumpwm@.service ├── timidity.service ├── tvguide.service ├── tvguide.timer ├── unclutter@.service ├── x@.service ├── xbase@.target ├── xmodmap@.service ├── xrdb@.service ├── xset@.service ├── xsetroot@.service └── xterm@.service /.gitignore: -------------------------------------------------------------------------------- 1 | *.target.wants -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository is dead: nowadays I use GNU Shepherd to manage my user 2 | services: https://github.com/alezost/shepherd-config 3 | 4 | 5 | ## About 6 | 7 | These are my systemd user units located in 8 | `$HOME/.config/systemd/user`. I use systemd not only for running 9 | daemons, but for starting X session, window manager, various GUI utils 10 | and applications. 11 | 12 | For information about systemd user session and about managing X 13 | session with user services, you may read: 14 | - [systemd/User - ArchWiki](https://wiki.archlinux.org/index.php/Systemd/User) 15 | - [Automatic X login without a DM - Arch Linux Forums](https://bbs.archlinux.org/viewtopic.php?id=147913) 16 | 17 | ## Description 18 | 19 | Basically the structure of my user units is the following: 20 | - user daemons (like gpg-agent) and `gui@.target` are "attached" 21 | to (WantedBy) `default.target`; 22 | - `gui@.target` provides a GUI interface – it starts: 23 | + `xbase@.target` – X server with configuration utils (xmodmap, 24 | xset, ...); 25 | + GUI applications (emacs, xterm, ...) "attacted" to this target. 26 | 27 | For turning X server into a daemon (for `x@.service`), notifying when 28 | it is ready, i use a wonderful tiny bash script `x-daemon` from 29 | [joukewitteveen/xlogin](https://github.com/joukewitteveen/xlogin). 30 | Previously i used 31 | [sofar/xorg-launch-helper](https://github.com/sofar/xorg-launch-helper). 32 | 33 | It is possible to organize multiple X sessions with different settings 34 | and starting applications: ``DISPLAY :0`` will be run on `vt7`, 35 | ``DISPLAY :1`` on `vt8` and so on. 36 | 37 | ## Example 38 | 39 | Here is my configuration of X session. 40 | 41 | Window manager and vital apps: 42 | ```shell 43 | systemctl --user enable stumpwm@0 44 | systemctl --user enable emacs@0 45 | systemctl --user enable conkeror@0 46 | ``` 47 | X settings: 48 | ```shell 49 | systemctl --user enable numlock@0 50 | systemctl --user enable setxkbmap@0 51 | systemctl --user enable xmodmap@0 52 | systemctl --user enable xrdb@0 53 | systemctl --user enable xset@0 54 | systemctl --user enable xsetroot@0 55 | ``` 56 | I want this X session to start on login, so: 57 | ```shell 58 | systemctl --user enable gui@0.target 59 | ``` 60 | (I set up autologin as described at 61 | [Automatic login to virtual console - ArchWiki](https://wiki.archlinux.org/index.php/Automatic_login_to_virtual_console)) 62 | 63 | Sometimes i need another instance of X server with another 64 | configuration: 65 | ```shell 66 | systemctl --user enable numlock@1 67 | systemctl --user enable xmodmap@1 68 | systemctl --user enable xrdb@1 69 | systemctl --user enable xset@1 70 | systemctl --user enable openbox@1 71 | systemctl --user enable xterm@1 72 | ``` 73 | 74 | Actually i have a shell alias `scu` for `systemctl --user` (and `sc` for 75 | `systemctl`), so i can run the second X session with `scu start 76 | gui@1.target` (it will be started on virtual terminal 8, 77 | i.e. Ctrl+Alt+F7/F8 to switch between X sessions) and if i 78 | don't need it anymore, then just `scu stop gui@1.target` and there is no 79 | sign of it. 80 | -------------------------------------------------------------------------------- /conkeror@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Conkeror service (display %i) 3 | 4 | After=xbase@%i.target 5 | 6 | [Service] 7 | ExecStart=/usr/local/bin/conkeror 8 | Environment=DISPLAY=:%i 9 | 10 | [Install] 11 | WantedBy=gui@%i.target 12 | -------------------------------------------------------------------------------- /dbus.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=D-Bus Message Bus 3 | Requires=dbus.socket 4 | 5 | [Service] 6 | ExecStart=/usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation 7 | ExecReload=/usr/bin/dbus-send --print-reply --session --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig 8 | 9 | -------------------------------------------------------------------------------- /dbus.socket: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=D-Bus Message Bus Socket 3 | 4 | [Socket] 5 | ListenStream=/run/user/%U/bus 6 | 7 | [Install] 8 | WantedBy=default.target 9 | -------------------------------------------------------------------------------- /default.target: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Default user target 3 | -------------------------------------------------------------------------------- /emacs-trunk@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Emacs (trunk) service (display %i) 3 | 4 | After=xbase@%i.target 5 | 6 | [Service] 7 | ExecStart=/usr/local/bin/emacs-trunk 8 | Environment=DISPLAY=:%i 9 | 10 | [Install] 11 | WantedBy=gui@%i.target 12 | -------------------------------------------------------------------------------- /emacs@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Emacs service (display %i) 3 | 4 | After=xbase@%i.target 5 | 6 | [Service] 7 | ExecStart=/usr/bin/emacs -mm 8 | Environment=DISPLAY=:%i 9 | 10 | [Install] 11 | WantedBy=gui@%i.target 12 | -------------------------------------------------------------------------------- /emacsclient@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Emacs client service (display %i) 3 | 4 | After=xbase@%i.target 5 | After=emacsd.service 6 | Requires=emacsd.service 7 | 8 | [Service] 9 | ExecStart=/usr/bin/emacsclient -c 10 | Environment=DISPLAY=:%i 11 | 12 | [Install] 13 | WantedBy=gui@%i.target 14 | -------------------------------------------------------------------------------- /emacsd.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Emacs daemon service 3 | Before=default.target 4 | 5 | [Service] 6 | Type=forking 7 | ExecStart=/usr/bin/emacs --daemon 8 | ExecStop=/usr/bin/emacsclient --eval "(let (kill-emacs-hook) (kill-emacs))" 9 | 10 | [Install] 11 | WantedBy=default.target 12 | -------------------------------------------------------------------------------- /env.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=User environment 3 | Before=default.target 4 | 5 | [Service] 6 | Type=oneshot 7 | ExecStart=-/usr/bin/systemctl --user set-environment \ 8 | LANG=en_US.UTF-8 \ 9 | XAUTHORITY=%h/.Xauthority \ 10 | SSH_AUTH_SOCK=%h/.gnupg/S.gpg-agent.ssh \ 11 | GUILE_LOAD_COMPILED_PATH=%h/.guix-profile/share/guile/site/2.0:%h/.guix-profile/share/guile/site:%h/usr/lib/guile/2.0/site-ccache:%h/devel/guix:%h/devel/dmd/modules \ 12 | GUILE_LOAD_PATH=%h/progs/guile/modules:%h/.guix-profile/share/guile/site/2.0:%h/.guix-profile/share/guile/site:%h/usr/share/guile/site/2.0:%h/devel/guix:%h/devel/dmd/modules \ 13 | GUIX_PACKAGE_PATH=%h/config/guix/guix-package-path \ 14 | PATH=%h/bin:/usr/local/bin:/usr/bin:%h/.guix-profile/bin:/usr/bin/core_perl 15 | 16 | [Install] 17 | WantedBy=default.target 18 | -------------------------------------------------------------------------------- /firefox@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Firefox service (display %i) 3 | 4 | After=xbase@%i.target 5 | 6 | [Service] 7 | ExecStart=/usr/sbin/firefox 8 | Environment=DISPLAY=:%i 9 | 10 | [Install] 11 | WantedBy=gui@%i.target 12 | -------------------------------------------------------------------------------- /gpg-agent.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=GPG Agent service 3 | IgnoreOnIsolate=true 4 | Before=default.target 5 | 6 | [Service] 7 | Type=forking 8 | ExecStart=/usr/bin/gpg-agent --daemon 9 | 10 | [Install] 11 | WantedBy=default.target 12 | -------------------------------------------------------------------------------- /gui@.target: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Graphical User Interface (display %i) 3 | 4 | Wants=xbase@%i.target 5 | 6 | [Install] 7 | WantedBy=default.target 8 | -------------------------------------------------------------------------------- /guilewm@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=GuileWM service (display %i) 3 | 4 | Before=gui@%i.target 5 | After=xbase@%i.target 6 | 7 | Conflicts=openbox@%i.service 8 | Conflicts=stumpwm@%i.service 9 | 10 | [Service] 11 | ExecStart=/usr/local/bin/guile-wm 12 | Environment=DISPLAY=:%i 13 | 14 | [Install] 15 | WantedBy=gui@%i.target 16 | -------------------------------------------------------------------------------- /irexec.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=IR Exec service 3 | Before=default.target 4 | # After=lirc.service 5 | # Wants=lirc.service 6 | 7 | [Service] 8 | Type=forking 9 | ExecStart=/usr/bin/irexec --daemon 10 | 11 | [Install] 12 | WantedBy=default.target 13 | -------------------------------------------------------------------------------- /lxde@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=LXDE service (display %i) 3 | 4 | Before=gui@%i.target 5 | After=xbase@%i.target 6 | 7 | Conflicts=stumpwm@%i.service 8 | 9 | [Service] 10 | ExecStart=/usr/bin/lxsession -s LXDE -e LXDE 11 | # Restart=on-failure 12 | # RestartSec=1 13 | Environment=DISPLAY=:%i 14 | 15 | [Install] 16 | WantedBy=gui@%i.target 17 | -------------------------------------------------------------------------------- /midi.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Connect MIDI keyboard to ALSA 3 | Before=default.target 4 | 5 | After=timidity.service 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=/usr/bin/aconnect 28 129 10 | ExecStop=/usr/bin/aconnect -x 11 | 12 | [Install] 13 | WantedBy=default.target 14 | -------------------------------------------------------------------------------- /mosd@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=mosdd service (display %i) 3 | StopWhenUnneeded=true 4 | 5 | After=x@%i.service 6 | 7 | [Service] 8 | Type=simple 9 | ExecStart=/usr/local/bin/mosdd --script=%h/config/mosd/rc 10 | ExecStop=/usr/local/bin/mosdctl -x 11 | KillMode=none 12 | Environment=DISPLAY=:%i 13 | 14 | [Install] 15 | WantedBy=gui@%i.target 16 | -------------------------------------------------------------------------------- /numlock@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Numlockx service - turn NumLock ON (display %i) 3 | 4 | Before=xbase@%i.target 5 | After=x@%i.service 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=/usr/bin/numlockx on 10 | Environment=DISPLAY=:%i 11 | 12 | [Install] 13 | WantedBy=xbase@%i.target 14 | -------------------------------------------------------------------------------- /openbox@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Openbox service (display %i) 3 | 4 | Before=gui@%i.target 5 | After=xbase@%i.target 6 | 7 | Conflicts=stumpwm@%i.service 8 | 9 | [Service] 10 | ExecStart=/usr/bin/openbox 11 | ExecStop=/usr/bin/openbox --exit 12 | # Restart=on-failure 13 | # RestartSec=1 14 | Environment=DISPLAY=:%i 15 | 16 | [Install] 17 | WantedBy=gui@%i.target 18 | -------------------------------------------------------------------------------- /setxkbmap@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=setxkbmap service (display %i) 3 | 4 | Before=xbase@%i.target 5 | # setxkbmap destroys xmodmap and numlock settings somehow, so start it before 6 | Before=xmodmap@%i.service 7 | Before=numlock@%i.service 8 | After=x@%i.service 9 | 10 | [Service] 11 | Type=oneshot 12 | ExecStart=/usr/bin/setxkbmap dvorak,ru,us 13 | Environment=DISPLAY=:%i 14 | 15 | [Install] 16 | WantedBy=xbase@%i.target 17 | -------------------------------------------------------------------------------- /stumpwm@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Stumpwm service (display %i) 3 | 4 | Before=gui@%i.target 5 | After=xbase@%i.target 6 | 7 | Conflicts=openbox@%i.service 8 | Conflicts=lxde@%i.service 9 | 10 | [Service] 11 | ExecStart=/usr/local/bin/stumpwm 12 | # Restart=on-failure 13 | # RestartSec=1 14 | Environment=DISPLAY=:%i 15 | 16 | [Install] 17 | WantedBy=gui@%i.target 18 | -------------------------------------------------------------------------------- /timidity.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=TiMidity++ Daemon 3 | Before=default.target 4 | After=sound.target 5 | 6 | [Service] 7 | ExecStart=/usr/bin/timidity -iA -B2,8 8 | 9 | [Install] 10 | WantedBy=default.target 11 | -------------------------------------------------------------------------------- /tvguide.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=TV guide service 3 | 4 | [Service] 5 | Type=oneshot 6 | ExecStart=/usr/local/bin/tvguide-refresh 7 | Nice=19 8 | 9 | -------------------------------------------------------------------------------- /tvguide.timer: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=TV guide timer 3 | 4 | [Timer] 5 | OnCalendar=Mon *-*-* 00:01 6 | AccuracySec=10min 7 | 8 | [Install] 9 | WantedBy=default.target 10 | -------------------------------------------------------------------------------- /unclutter@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Unclutter (hide idle cursor) service (display %i) 3 | 4 | After=xbase@%i.target 5 | 6 | [Service] 7 | ExecStart=/usr/bin/unclutter -root -jitter 5 8 | Environment=DISPLAY=:%i 9 | 10 | [Install] 11 | WantedBy=gui@%i.target 12 | -------------------------------------------------------------------------------- /x@.service: -------------------------------------------------------------------------------- 1 | # x-daemon is a bash script from 2 | 3 | [Unit] 4 | Description=X server service (display %i) 5 | StopWhenUnneeded=true 6 | 7 | [Service] 8 | # Type=notify 9 | # ExecStart=/usr/bin/bash -c "/usr/bin/xorg-launch-helper :%i -nolisten tcp -noreset vt$((7+%i))" 10 | Type=forking 11 | ExecStart=/usr/bin/bash -c "/usr/local/bin/x-daemon :%i vt$((7+%i)) -nolisten tcp -noreset" 12 | # Restart=always 13 | # RestartSec=10 14 | -------------------------------------------------------------------------------- /xbase@.target: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=X server with essential environment and settings (display %i) 3 | StopWhenUnneeded=true 4 | 5 | After=dbus.socket 6 | After=gpg-agent.service 7 | After=env.service 8 | After=x@%i.service 9 | 10 | Wants=dbus.socket 11 | Wants=gpg-agent.service 12 | Wants=env.service 13 | Requires=x@%i.service 14 | -------------------------------------------------------------------------------- /xmodmap@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Xmodmap service (display %i) 3 | 4 | Before=xbase@%i.target 5 | After=x@%i.service 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=/usr/bin/xmodmap %h/.Xmodmap 10 | Environment=DISPLAY=:%i 11 | 12 | [Install] 13 | WantedBy=xbase@%i.target 14 | -------------------------------------------------------------------------------- /xrdb@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=X resource database (xrdb) service (display %i) 3 | 4 | Before=xbase@%i.target 5 | After=x@%i.service 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=/usr/bin/xrdb -merge %h/.Xresources 10 | Environment=DISPLAY=:%i 11 | 12 | [Install] 13 | WantedBy=xbase@%i.target 14 | -------------------------------------------------------------------------------- /xset@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Xset service (display %i) 3 | 4 | Before=xbase@%i.target 5 | After=x@%i.service 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=/usr/bin/xset r rate 193 43 m 2 0 s off -dpms 10 | Environment=DISPLAY=:%i 11 | 12 | [Install] 13 | WantedBy=xbase@%i.target 14 | -------------------------------------------------------------------------------- /xsetroot@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Xsetroot service (display %i) 3 | 4 | Before=xbase@%i.target 5 | After=x@%i.service 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=/usr/bin/xsetroot -solid gray30 -xcf %h/.icons/ComixCursors-Opaque-Green-Regular-Slim/cursors/cell 1 10 | Environment=DISPLAY=:%i 11 | 12 | [Install] 13 | WantedBy=xbase@%i.target 14 | -------------------------------------------------------------------------------- /xterm@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Xterm service (display %i) 3 | 4 | After=xbase@%i.target 5 | 6 | [Service] 7 | Type=simple 8 | ExecStart=/usr/bin/xterm 9 | Environment=DISPLAY=:%i 10 | 11 | [Install] 12 | WantedBy=gui@%i.target 13 | --------------------------------------------------------------------------------