Thursday, 26 June 2025

Raspberry Pi Desktop Digital Signage (RaspbianOS + Wayland) - Part 2 - Mouse Automation

 In my last post I detailed how I turned one of my desktop Raspberry Pis into a digital sign that could automatically switch between multiple kiosk-mode web pages. The method that I presented works, but leaves the mouse cursor visible on the screen.

In this post I will continue that topic and show how I used ydotool to hide the mouse cursor when this solution is running.

Why ydotool?

I am by no means a Wayland expert, but my understanding is that Wayland based compositors are lean, mean and designed for security.  The security model of Wayland prevents mouse input events from being generated by an end-user, and requires daemon level authorisation. This is a problem for anyone who actually wants to automate mouse movements from a user-space tool.

ydotool  is an application that can enable user-space based automation on Wayland systems by creating a socket-based bridge that can transmit user requested events to an authorised daemon. I couldn't find detailed documentation of how to implement it, so what follows is my understanding:

There are three main components to this solution:

  • A user space tool (ydotool), which enables command line requests for  mouse and keyboard events
  • A system level daemon  (ydotoold) which processes automation requests and transmits them to Wayland
  • A file-system socket, which act as a bridge between the two components
In essence, it seems to work like this,
    The ydotoold daemon starts with system privileges, and creates a socket to listen to
    The ydotool application transmits automation requests to this socket
    The user-space requests from ydotool are turned into system level input events by ydotoold
    The mouse moves!

Of course, this will only work if the user has sufficient rights to write to the socket!

Implementing ydotool


Here is a summary I added ydotool to my digital signage solution

  • Download, build and install ydotool
  • Create a startup script for the ydotoold daemon
  • Create a systemd service for the ydotoold daemon
  • Add a ydotool command to the digital sign launch script 

I'll provide more detail for these steps below


Download, build and install ydotool


Here are the steps I used to build and install ydotool

(note - this step may be unnecessary. Apt packages for ydotool and ydotoold are available for Raspbian,  BUT I wasn't able to get the solution to work with the packaged versions. Your mileage may vary).

Install cmake 
> sudo apt install cmake

clone the ydotool repository 
> git clone https://github.com/ReimuNotMoe/ydotool.git

change into the ydotool repository directory 
>cd ydotool

run the ydotool build steps:

mkdir build
cd build
cmake ..
make -j `nproc`


install the solution (make install)

(see the ydotool github repository for more information)

If all goes well then you will have fresh copy of ydtool and ydotoold installed to /usr/local/bin

Create a startup script for the ydtoold daemon


The next step is to create a launch script for the ydotoold daemon.  I called mine /usr/local/bin/run_ydotoold.sh

Edit this file and add the following:

#!/bin/sh
export YDOTOOL_SOCKET=/tmp/.ydotool_socket

/usr/local/bin/ydotoold &

sleep 1
chmod 777 /tmp/.ydotool_socket

while true; do
    echo "ydotoold is running at $(date)" >> /var/log/ydotoold.log
    sleep 300
done

This script starts the daemon, ensures that the ydotoold socket is user writeable and then sleeps to prevent the daemon from being terminated.

Make sure to make this script executable.
> sudo chmod u+x /usr/local/bin/run_ydotoold.sh

Enable ydotoold as a systemd service


To ensure that ydotoold is run as a system level service, we need to create a systemd service script.

Edit a new service script as the superuser:
> sudo nano /etc/systemd/service/ydotoold

Add and save the following contents:

[Unit]
Description=Run ydotoold
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/run_ydotoold.sh &
User=root

[Install]
WantedBy=multi-user.target

After creating the file, enable and start the service using systemctl:

>sudo systemctl enable /etc/systemd/service/ydotoold.service
>sudo systemctl start ydotool.service
>sudo systemctl status ydotoold.service

If all goes well you should see that the service is now active and running:



Test ydotool


It should now be possible to use ydtool to move the mouse.

Open a terminal in the GUI desktop (not SSH)

set the YDOTOOL_SOCKET environment variable (don't skip this step!)

> export YDOTOOL_SOCKET=/tmp/.ydotool_socket

run a test command

> /usr/local/bin/ydotool mousemove --absolute 100 100

If everything has worked,  you should see the mouse cursor jump to coordinates 100,100 on the screen


Add ydotool to the digital sign launch script


The final step is to add the ydotool command to our digital signage launch script.  

Edit pysign/pysign_launch.sh and change it to the following:

#!/bin/bash

#Move mouse
export YDOTOOL_SOCKET=/tmp/.ydotool_socket
/usr/local/bin/ydotool mousemove --absolute 1000 1000

#run chromium using playwright
cd /home/pi/dev/pysign
source ./pysign_env/bin/activate
python3 ./pysign.py

This inserts a command to move the mouse off screen before launching the browser.


Conclusion


..and with that we are done.  Hiding the mouse cursor turned out to be just as complex as automating the browser window, but the end result is worth the effort!

Obviously, huge thanks are due to the people who maintain the ydotool repository.  Once you understand how to make it work, it is a very useful tool for automating a Wayland desktop.



Raspberry Pi Desktop Digital Signage (RaspbianOS + Wayland) - Part 2 - Mouse Automation

 In my last post I detailed how I turned one of my desktop Raspberry Pis into a digital sign that could automatically switch between multipl...