I have been working on creating a lightweight, perspective kiosk for Raspberry Pi hardware. I did a lot of experimentation, including looking into this thread and below is my favored setup.
Features:
- Tested on Pi 4s and 5s and DietPi OS and Raspberry Pi OS Lite
- This tutorial is for RPi OS Lite only (my preferred setup)
- OSK support by
Onboard
with auto-show and custom configuration capabilities - OSK works for login pages
- Lightweight with no GUI
- Chromium browser with all hotkeys blocked except F5 (Refresh)
- The only way to exit currently is to use
ctrl+alt+F5
to switch to aTTY
console, other function keys can do the same depending on yourTTY
service setup.ctrl+alt+F2
goes back to Chromium. - Auto runs on boot via service
-
First is to get your Pi up and running with
Raspberry Pi OS Lite
, I like to use the official RPi Imager utility, which allows you to pre-configure the hostname, wifi, ssh, user/password, etc. I use the 64-bit version. -
Optionally, I use
nmtui
andnano /etc/systemd/timesyncd.conf
to setup a static IP and NTP.
sudo nmtui
sudo nano /etc/systemd/timesyncd.conf # use gateway for NTP
sudo timedatectl set-ntp 0
sudo timedatectl set-ntp 1
date # check datetime is correct
sudo reboot
- Next is to update and install the needed packages
sudo apt update && sudo apt upgrade -y
sudo apt install xserver-xorg x11-xserver-utils xinit -y
sudo apt install chromium-browser -y
sudo apt install openbox -y
# check installation by manually starting X server, chromium show now be visible
# don't panic if the window size is off, we'll fix this later
sudo DISPLAY=:0 startx /usr/bin/chromium-browser --no-sandbox --kiosk
- Create Chromium service
sudo nano /etc/systemd/system/chromium.service
copy this into the new file and save
[Unit]
Description=Start Chromium on Boot
After=network.target graphical.target
[Service]
User=pi
Group=pi
Environment=DISPLAY=:0
ExecStart=/home/pi/chromium-autostart.sh
Restart=always
RestartSec=5
TimeoutStartSec=30
[Install]
WantedBy=multi-user.target
Enable the service
sudo systemctl enable chromium.service
# below are optional commands for debugging later if things do not work
journalctl -u chromium.service -b
cat /var/log/Xorg.0.log
- Edit the Xwrapper config file
sudo nano /etc/X11/Xwrapper.config
edit file contents and save
allowed_users=anybody
needs_root_rights=yes
- Create Chromium exension to block hotkeys
mkdir kiosk-extension
cd kiosk-extension
nano manifest.json
copy into file and save
{
"name": "Kiosk Shortcut Blocker",
"version": "1.0",
"manifest_version": 3,
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["blocker.js"]
}
]
}
nano blocker.js
copy into file and save
document.addEventListener('keydown', function(event) {
// List of all function keys to block, except F5 for refreshing
const functionKeys = ['F1', 'F2', 'F3', 'F4', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12'];
// Block all Ctrl, Alt, or Ctrl+Shift combinations
if (event.ctrlKey || event.altKey) {
event.preventDefault();
console.log(`Blocked ${event.ctrlKey ? 'Ctrl+' : ''}${event.altKey ? 'Alt+' : ''}${event.shiftKey ? 'Shift+' : ''}${event.key}`);
return;
}
// Block bare function keys
if (functionKeys.includes(event.key)) {
event.preventDefault();
console.log(`Blocked ${event.key}`);
return;
}
// Block Shift+F3 and Shift+F10 explicitly (as they may not use Ctrl/Alt)
if (event.shiftKey && (event.key === 'F3' || event.key === 'F10')) {
event.preventDefault();
console.log(`Blocked Shift+${event.key}`);
}
});
- Install OSK packages
sudo apt install mousetweaks -y
sudo apt install onboard -y
sudo apt install at-spi2-core libatk-bridge2.0-0 gir1.2-atspi-2.0 -y
sudo apt install dbus-x11 -y
Optionally, remove the settings and quit buttons from the keyboard layout to prevent tampering.
# copy your layout of choice so it can be customized without altering the original
sudo cp /usr/share/onboard/layouts/Compact.onboard /usr/share/onboard/layouts/Kiosk.onboard
sudo nano Kiosk.onboard
update the layout name and summary, then comment out the lines that are labeled id=quit
and id=settings
<keyboard
id="Kiosk"
format="3.2"
section="system"
summary="Custom Layout for Kiosks" >
...
<!-- <key group='bottomrow' id='quit' scan_priority="1"/>
<key group='bottomrow' id='settings' scan_priority="1"/> -->
Then stop the OSK and restart it.
pkill onboard && DISPLAY=:0 onboard &
- Create Autostart Script
cd # make sure you are in home directory
nano chromium-autostart.sh
copy into file and save
#!/bin/bash
# Set display environment
export DISPLAY=:0
# Clear Chromium lock files to prevent profile errors
rm -f /home/pi/.config/chromium/Default/Lock
rm -f /home/pi/.config/chromium/SingletonLock
rm -f /home/pi/.config/chromium/SingletonSocket
rm -f /home/pi/.config/chromium/SingletonCookie
# Turn off screensaver/blanking -> CURRENTLY NOT WORKING FOR SOME REASON
xset s noblank
xset s off
xset -dpms
# Start onboard (on-screen keyboard)
onboard &
# Chromium options
CHROMIUM_OPTS="--kiosk --window-size=1920,1080 --window-position=0,0 --load-extension=/home/pi/kiosk-extension"
CHROMIUM_OPTS="$CHROMIUM_OPTS --no-crash-upload --disable-crash-reporter --disable-session-crashed-bubble --disable-features=Translate,TranslateUI"
CHROMIUM_OPTS="$CHROMIUM_OPTS --noerrdialogs --disable-infobar --force-renderer-accessibility"
# Force Tablet Mode
CHROMIUM_OPTS="$CHROMIUM_OPTS --force-tablet-mode --tablet-ui"
# URL for kiosk mode
URL="http://<your gateway address>:8088/data/perspective/client/<your project name>"
# Find Chromium binary
FP_CHROMIUM=$(command -v chromium-browser || command -v chromium)
# Use "startx" as non-root user to get required permissions via systemd-logind
STARTX='xinit'
[ "$USER" = 'root' ] || STARTX='startx'
# Start Chromium with a hidden cursor
exec "$STARTX" "$FP_CHROMIUM" $CHROMIUM_OPTS "${URL:-}" -- -nocursor
make the file executable
chmod +x chromium-autostart.sh
run the OSK settings GUI to setup
sudo systemctl daemon-reload
sudo systemctl start chromium.service
DISPLAY=:0 onboard-settings &
I like nightshade theme, auto-show enabled, show floating icon when hidden, compact layout, and dock to edge.
- Reboot and Test