#+TITLE: XFCE4 Application Shortcut for Starting my Chat Clients #+AUTHOR: Philipp Matthias Schäfer #+HTML_DOCTYPE: html5 #+OPTIONS: toc:nil I am using three chat clients on my personal laptop: [[https://signal.org/][Signal]] and two instances of [[https://element.io/][Element]], one with my personal account and one with my work account. Because I like to work on my computer without distractions, I do not have the clients running most of the time. To read new messages I start the clients and once I am done close them again. In the past I started each client from the command line. Then I wrote a function in [[https://www.gnu.org/software/emacs/manual/elisp.html][Emacs Lisp]] that I called using an [[https://docs.xfce.org/xfce/xfce4-settings/keyboard#application_shortcuts][XFCE4 Application Shortcut]]. The function created three buffers, if they did not exist already, and started a process for each of the chat clients. This always opened a new [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Frames.html][Emacs frame]] in addition to the clients and three buffers that I never used. The was not a satisfying solution. My newest solution uses [[https://www.freedesktop.org/software/systemd/man/latest/systemd.html][systemd]] user service units that are started and stopped via XFCE4 Application Shortcuts. This has the advantage that no Emacs frame is opened, no buffers clutter my Emacs session, and I can close all three clients with a single shortcut. What still irks me in the current setup are the long startup times of the Element clients. oBut turning of notification is not enough for me, There may be no vestiges of these processes left on my desktop when I want to focus. * systemd Unit Files :PROPERTIES: :CUSTOM_ID: systemd_unit_files :END: The three unit files are very similar. I give a full explanation for the first one and restrict the others to changes. ** Signal :PROPERTIES: :header-args: :padline no :tangle "signal.service" :CUSTOM_ID: signal :END: The configuration file begins with the ~[Unit]~ block and a description. #+BEGIN_SRC systemd [Unit] Description=Signal chat client #+END_SRC In the ~[Service]~ block, I first give the command line to start the service. The argument is necessary, because without it Signal at some point stopped finding the credentials is stored during setup. #+BEGIN_SRC systemd :padline yes [Service] ExecStart=/usr/bin/signal-desktop --password-store=gnome-libsecret #+END_SRC Next I configure the ~LANGUAGE~ environment variable to be set to two languages, so that Signal’s spellchecker uses both dictionaries instead of just the one for the system language. #+BEGIN_SRC systemd Environment="LANGUAGE=en_US:de_DE" #+END_SRC I also want the process to be restarted on failure instead of not at all, as is the default, and store the standard output of the last session in a file, so I can debug any problems, when they arise. #+BEGIN_SRC systemd Restart=on-failure StandardOutput=file:%h/.cache/logs/signal.log #+END_SRC ** Private Element :PROPERTIES: :header-args: :tangle "element.service" :CUSTOM_ID: element :END: The structure of the unit file for Element with my private profile is very similar. It obviously has a different command line, as it starts a different program. It also does not need any Environment variables. And the filename for the standard output is different. #+BEGIN_SRC systemd [Unit] Description=Element chat client (private) [Service] ExecStart=/usr/bin/element-desktop Restart=on-failure StandardOutput=file:%h/.cache/logs/element.log #+END_SRC ** Work Element :PROPERTIES: :header-args: :tangle "element_fsu.service" :CUSTOM_ID: element_fsu :END: For the work account Element, the command line has an additional argument to select the profile. The profile name ~fsu~ stands for [[https://www.uni-jena.de/][Friedrich Schiller University]], which is my employer and the provider of the [[https://matrix.org/][Matrix]] server on which the account resides. Again, the file for the standard output is different. #+BEGIN_SRC systemd [Unit] Description=Element chat client (fsu) [Service] Type=simple ExecStart=/usr/bin/element-desktop --profile fsu Restart=on-failure StandardOutput=file:%h/.cache/logs/element_fsu.log #+END_SRC * Setup :PROPERTIES: :CUSTOM_ID: setup :END: Running ~org-babel-tangle~ (~C-c C-v t~) on this file creates all three unit files in the same directory. To let systemd now about the unit files, which are supposed to be only available to my user, I create symlinks to them in ~~/.config/systemd/user/~ (see man page [[https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html][systemd.unit]]) by running #+BEGIN_SRC bash for unit in signal element element_fsu; do ln -s -t ~/.config/systemd/user $(realpath "${unit}.service"); done #+END_SRC Afterwards I trigger a reload of the systemd configuration #+BEGIN_SRC bash systemctl daemon-reload #+END_SRC I also make sure that the directory for the log files exist, otherwise systemd will not be able start the processes: #+BEGIN_SRC bash mkdir -p ~/.cache/logs #+END_SRC To put it on an XFCE4 Application Shortcut, I open the settings (~xfce4-settings~), choose “Keyboard”, then the “Application Shortcuts” tab, and click “Add” to add first one, then another. In my case I configure ~Super+R~ to start the chat clients, running the command line #+BEGIN_SRC bash systemctl --user start signal element element_fsu #+END_SRC and ~Super+I~ (like ignore) to stop the chat clients, running the command line #+BEGIN_SRC bash systemctl --user stop signal element element_fsu #+END_SRC