marsqing / libinput-three-finger-drag

Three-finger-drag support for libinput
MIT License
102 stars 16 forks source link

Executable failed to start when executed as a systemd service #15

Closed lmr97 closed 2 months ago

lmr97 commented 2 months ago

I wanted to have this highly useful utility available as a daemon, but I'm running into trouble. The executable runs beautifully when run from the command line, but fails to launch when run as a systemd service. I was unable to build the project from the source code (due to local linker issues), so the copy I have is simply the pre-built executable.

Error log

This error log is the one generated by running journalctl -xeu three-finger-drag.service:

libinput-three-finger-drag[10748]: Error: Can't open display: (null)
libinput-three-finger-drag[10748]: thread 'main' panicked at 'can not initialize libxdo: Ffi', src/main.rs:19:15
libinput-three-finger-drag[10748]: note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
systemd[1]: three-finger-drag.service: Main process exited, code=exited, status=101/n/a
systemd[1]: three-finger-drag.service: Failed with result 'exit-code'.
systemd[1]: Failed to start three-finger-drag.service - Three Finger Drag daemon.

My service file

[Unit]
Description=Three Finger Drag daemon
After=network.target

[Service]
ExecStart=/usr/bin/libinput-three-finger-drag  # this fails whether it's /usr/bin/ or just /bin/; I have it in both dirs
Type=notify
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target

Setup:

From what I was able to find online, the first error implies a lack of access to the the windows it needs. Should I be executing the command from in a different working directory, or after a different target?

I am new to Linux, so maybe this is a simple fix; if so, I apologize for wasting your time.

Thanks!

lmr97 commented 2 months ago

Update: after installing the libxdo-dev library, I was able to build the utility from the source.

The problem, however, persists, with identical errors.

marsqing commented 2 months ago

libinput-three-finger-drag[10748]: Error: Can't open display: (null) Maybe because it starts too early, even before X. Can you try KDE auto start?

lmr97 commented 2 months ago

Okay, I think I got it. I did add the executable to KDE's autostart, and it's no longer raising any errors. That must've been it! I'm also running it as a user-level daemon (not root-level), so that may have helped as well.

For people figuring this out for the first time like me, here's what I did:

  1. Get the program on your machine, either by downloading the pre-compiled binary or building from the source (if building from the source, make sure libxdo-dev is installed before building).
  2. Test it on the command line.
  3. If it works, we can define a user-level system daemon with it. Start by making a directory in your home directory called ~/.config/systemd/user, if one doesn't already exist.
  4. Make a file there called three-finger-drag.service (or whatever you please), and paste the following text into it (substituting the path to the executable for /your/path/to/three-finger-drag-executable, of course), then save:
    
    [Unit]
    Description=Three Finger Drag daemon
    DefaultDependencies=no
    Before=shutdown.target

[Service] ExecStart=/your/path/to/three-finger-drag-executable Type=simple Restart=on-failure RestartSec=1

[Install] WantedBy=shutdown.target

5. Go into your System Settings application (GUI), then Startup & Shutdown > Autostart, and add your executable to the list of applications (you'll probably have to add it by its path).
6. Run the following in the terminal:

systemctl --user enable three-finger-drag.service systemctl --user start three-finger-drag.service


7. You should be able to use three-finger dragging on your trackpad now!

This is probably only one solution to this problem; I'm not sure everything in the `three-finger-drag.service` file is necessary for it to run properly, but I can say that **`Type=simple` is essential**: this allows the OS to consider the service started as soon as the process forks. Some other options for this line  (like `exec`) require `main()` to exit before considering the service started. Since this executable runs continuously, an option like that would not be ideal.

Thanks for the great program, and your help!
lmr97 commented 2 months ago

I have since learned that the systemd service file is redundant for the executable to run in the background; you only need to add it to the KDE Autostart list.