ydotool requires the program ydotoold to be running in the background. Now to make this easier the developer ships a systemd
unit file with the project. If ydotoold isn't running the program won't work.
A systemd unit file basically calls programs in the background which are needed for the OS to run. In this case we will use this file to run ydotoold in the background as soon as we boot our device. If your distro packages ydotool sensibly then
the service (the background program run by the file) should already be running.
To check, run:
systemctl status ydotoold.serviceThis should return something like this :
● ydotool.service - Starts ydotoold service
Loaded: loaded (/usr/lib/systemd/system/ydotool.service; enabled; preset: disabled)
Drop-In: /usr/lib/systemd/system/service.d
└─10-timeout-abort.conf
Active: active (running) since Sun 2024-04-28 14:12:42 IST; 26min ago
Main PID: 1328 (ydotoold)If don't see something like 'active (running) since...' then you'll have to start the service. To start it, run :
systemctl start ydotoold.serviceTo always run the service at boot time, run :
systemctl enable ydotoold.serviceNow, since it's running, let's run a little test to check if yodtool is working as expected. Run :
ydotool type 'Hello World!'This should make ydotool type 'Hello World!' on the screen.
If you are facing an error that's something along the lines of error: /tmp/.ydotool_socket : permission denied or error: /tmp/.ydotool_socket : file not found or file doesn't exist.
This file, /tmp/.ydotool_socket, is a 'socket' file which the ydotoold service needs. By default this file in loacted in /tmp.
To make sure that this is the file used by ydotoold, make an env variable $YDOTOOL_SOCKET with the value of tmp/.ydotool_socket. To do this in bash, go to ~/.bashrc and add this line :
export YDOTOOL_SOCKET=/tmp/.ydotool_socketIf you use another shell like fish and zsh, go ahead and add this variable in your config. Now, try and restart the service again :
systemctl restart ydotoold.serviceNow run the test again. There is a chance that this might stil not work. If this is the case, run :
ls -l /tmp/.ydotool_socketIf the output is something along the lines of :
srw-------. 1 root root 0 Apr 28 14:18 /tmp/.ydotool_socket=Then, you can see that the file is owned by the root user. This means the ydotool command run by your
non-root user can't access this file, as a result of which, ydotool won't work. To fix this we need to edit
the unit file itself.
Locate the unit file, most probably in /usr/lib/systemd/system, if it's not there and in something like /usr/lib/systemd/user then delete the file under the user sub-directory and create another ydotoold.service file under /usr/lib/systemd/system.
This is because ydotoold needs root privileges to run, running .service files from the /usr/lib/systemd/system directory also requires the same privileges.
So instead of running it with sudo everytime, we will run the file once and ydotoold will acquire the permissions it needs forever.
Now, open the ydotoold.service file in your favorite editor as root (using sudo).
You'll see something like this:
[Unit]
Description=Starts ydotoold service
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/ydotoold
ExecReload=/usr/bin/kill -HUP $MAINPID
KillMode=process
TimeoutSec=180
[Install]
WantedBy=default.target
The program ydootoold has a flag named --socket-own which decides the ownership of the socket file, this takes in it's value in the format UID:GID, like 1000:1000. To get these values for yourself, run :
echo $(id -u):$(id -g)For me it's 1000:1000 but it might be different for you.
Now go to the 'ExecStart' line and after /usr/bin/ydotoold, add --socket-own=1000:1000 and save the file. Now this
line should look like :
[Unit]
...
[Service]
...
ExecStart=/usr/bin/ydotoold --socket-own=1000:1000
...
[Install]
...
Since you have changed the contents of the unit file, you'll first have to run :
systemctl daemon-reloadMake sure run to run :
sudo rm /tmp/.ydotool_socketWe need to remove the previous socket file before restarting the service because the old socket file will be used, which would still be owned by root. Removing that file results in the creation of a new file owned by your user.
Now finally run :
systemctl restart ydotoold.serviceThe program should now work as expected. As a test you can run :
ydotool type 'Hello World!'