In my last post I mentioned turning a Raspberry Pi + Official Touch Screen into a nifty desk clock. Well, it turns out that I actually have two desktop Raspberry Pis and as I also wanted something to do with the second one I decided to turn it into digital signage that could swap between multiple full screen web pages in a kiosk mode browser.
Because I am probably a masochist, I wanted to do this with a typical Raspbian 64-bit OS install running Wayland. Many of the 'traditional' solutions to this problem are X-Windows based and these don't work with a Wayland descended compositor.
I'll detail the steps in the next couple of posts, but the summary of the recipe is
- Use python playwright and create a python script and shells script to drive the browser
- Use the /etc/xdg/labwc/autostart script to autostart this python script
- Use ydotool to hide the mouse cursor
- Create a shell scripts and a systemd service script to enable ydotool
If you are still with me, you will have noticed that it takes much more effort to hide the mouse cursor than it does to create the page flipping kiosk browser solution. Thanks Wayland!
I'll cover the steps to get the browser automation working in this post, and cover the mouse automation in a future post. Here is a detailed description of the first couple of steps above
Assumptions
For this recipe I am assuming that you have a Raspberry Pi 4 or better running the current (2025) 64-bit version of Raspbian OS based on Debian Bookworm. I am also going to assume that you have configured Raspbian to automatically login to the GUI.
Install and configure SSH
Make sure that you have SSH installed and working on the device, so that you can control the device once the kiosk browser is running, otherwise you will be locked out!
Create a project folder
Create a folder to hold all of the scripts etc for this recipe. Mine is called /home/pi/dev/pysign
Create (and activate) a virtual python environment
We are going to be using python for this recipe, and for Raspbian OS this requires us to create and activate a virtual environment. I recommend that you create this in the project folder to keep everything together.
>cd /home/pi/dev/pysign
> python3 -m venv /home/pi/dev/pysign/pysign_env
> source /home/pi/dev/pysign/pysign_env/bin/activate
(important, from this point forwards make sure that you activate the virtual environment in each ssh/terminal window that you use to do python related tasks)
Install Playwright Python
Playwright (https://playwright.dev/) is a modern web testing suite that supports multiple browsers and has multiple SDKs. Unlike older suites like Puppeteer, it works well Wayland and the version of Chromium installed by Raspbian OS.
To install playwright, use a terminal with the python virtual environment activated and run the the following commands:
> pip install pytest-playwright asyncio
This will install playwright and the python playwright SDK. It will also install asyncio, which we will use for making asynchronous python methods.
Create the browser automation script
Next we will create the python script that uses playwright to drive the browser. Here is a basic script, which swaps between a couple of hard coded URLs. I called mine pysign.py
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
app_data_path="/tmp"
browser = await p.chromium.launch_persistent_context(
app_data_path,
executable_path="/usr/lib/chromium/chromium",
args=[ "--kiosk",
"--start-maximized",
# "--disable-infobars",
"--ozone-platform=wayland",
"--no-restore-on-startup",
"--noerrdialogs"],
ignore_default_args=["--enable-automation"],
headless=False,
no_viewport=True
)
page = await browser.new_page()
while True:
await page.goto("https://playwright.dev") #Display Web Page 1
time.sleep(30) #Wait 30 seconds
await page.goto("https://old.reddit.com") #Display Web Page 2
time.sleep(30)
await browser.close()
asyncio.run(main())
This script uses playwright to configure chromium to launch in full screen kiosk mode, then flips between two different URLs. The script pauses for 30 seconds after showing each page.
You can easily edit this to modify the web page URLs, change the timing or add additional pages. A better version (for a future post) would also accept command line arguments and an array of URLs to flip between, but this version is good enough to prove the concept.
Create a python launch script
Next we will create a shell script that will launch the python program above. Creating this script will simplify the automation process later.
create a new shell script in the project folder. I called mine pysign_launch.sh
#!/bin/bash
#run chromium using playwright
cd /home/pi/dev/pysign
source ./pysign_env/bin/activate
python3 ./pysign.py
Use chmod to make this script executable
> chmod 777 ./pysign_launch.sh
Test the python launch script
At this point it is probably worth testing the python launch script. If all goes well then chromium should launch and start flipping between a couple of windows.
(open a GUI terminal)
> source /home/dev/pysign/pysign_launch.sh
( To terminate the script, you will need to use ps and kill from an SSH session.)
Autostart the python launch script
The next step is to make sure that our launch script is automatically launched when the user logs into the desktop. This uses the same approach as in the previous post. We just need to add our script to /etc/xdg/labwc/autostart
> sudo nano /etc/xdg/labwc/autostart
append the following line (modify as appropriate for the folders/filenames you have chosen for your implementation)
/home/pi/dev/pysign/pysign_launch.sh &
For the record, my complete autostart file looks like this:
/usr/bin/lwrespawn /usr/bin/pcmanfm --desktop --profile LXDE-pi &
/usr/bin/lwrespawn /usr/bin/wf-panel-pi &
/usr/bin/kanshi &
/usr/bin/lxsession-xdg-autostart
/home/pi/dev/pysign/pysign_launch.sh &
Reboot and test
The final step is to reboot the device. If everything has gone well then a few seconds after the desktop appears, the browser should launch into kiosk mode and start flipping between the URLs in the python script.
Recommended site
The default sites in the script are fairly lame. One site I recommend trying is this great implementation of the 'digital rain' effect from The Matrix.
https://rezmason.github.io/matrix/
It looks great on the Pi screen!
Conclusion
You'll probably notice that although the solution works, the mouse cursor is often annoyingly visible on the screen. In the next post I'll cover how to use ydotool to hide this.