How To: Perspective Kiosk for Rasberry Pi

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 a TTY console, other function keys can do the same depending on your TTY service setup. ctrl+alt+F2 goes back to Chromium.
  • Auto runs on boot via service
  1. 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.

  2. Optionally, I use nmtui and nano /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
  1. 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
  1. 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
  1. Edit the Xwrapper config file
sudo nano /etc/X11/Xwrapper.config

edit file contents and save

allowed_users=anybody
needs_root_rights=yes
  1. 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}`);
  }
});
  1. 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 &
  1. 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.

  1. Reboot and Test :slight_smile:
7 Likes

A little on performance of the above:

Same project and same operations performed. Basically using the OSK, running some queries bound to tables, and navigation.

  1. I found Ubuntu-frame + Webkit very laggy on Pi4s and still somewhat laggy on Pi5s.
  2. DietPi and RaspPi OS Lite run very smooth with Chromium setups
  3. Pi5 performance is much better than the 4
  4. My touchscreen that I tested with is a ViewSonic TD2465
Setup Load Average Peak Avg Core %
Pi4, DietPi, Chromium 0.65 38%
Pi4, Ubuntu-Frame, Webkit 0.22 31%
Pi5, DietPi, Chromium 0.07 11%
Pi5, Rpi OS Lite, Chrome 0.03 6%
Pi5, Ubuntu-Frame, Webkit 0.19 12.5%

Below are gifs using the htop command
Pi4, DietPi, Chromium
DietPi_Chromium_Pi4_Kiosk

Pi4, Ubuntu-Frame, Webkit
UbuntuFrame_Webkit_Pi4_Kiosk

Pi5, DietPi, Chromium
DietPi_Chromium_Pi5_Kiosk

Pi5, Rpi OS Lite, Chrome
PiOS_Chromium_Pi5_Kiosk

Pi5, Ubuntu-Frame, Webkit
PiOS_Webkit_Pi5_Kiosk

4 Likes

I updated the instructions above to include how to remove the quit and settings buttons from the OSK.

1 Like