ubuntu kiosk with phidgethub using touch screen
# --- Switch DM to SDDM and configure autologin ---
[ -f /etc/sddm.conf ] || sudo touch /etc/sddm.conf
if grep -q '^\[Autologin\]' /etc/sddm.conf; then
sudo sed -i '/^\[Autologin\]/,/^\[/{s/^User.*/User=kiosk/;s/^Session.*/Session=plasmawayland/}' /etc/sddm.conf
else
sudo tee -a /etc/sddm.conf >/dev/null <<'EOF'
[Autologin]
User=kiosk
Session=plasmawayland
EOF
fi
sudo systemctl disable gdm3 || true
sudo systemctl enable sddm
sudo systemctl set-default graphical.target
systemctl status sddm
sudo reboot
#!/bin/bash
set -eu
# Enable pipefail if supported
if set -o | grep -q pipefail; then
set -o pipefail
fi
# Function definitions for each section
section_1() {
#read -p "Press [Enter] key to continue... stopping screen blanking (best effort for GNOME; harmless on Plasma)"
##############################################
# SECTION 1: POWER MANAGEMENT AND SCREEN BLANKING for current user
##############################################
# IMMEDIATE: Disable screen blanking and dimming for current session
# This ensures the screen stays active during script execution
echo "=== DISABLING SCREEN BLANKING FOR CURRENT SESSION ==="
# Get current user (works even when running with sudo)
CURRENT_USER=$(logname 2>/dev/null || echo "$SUDO_USER" || echo "$USER" || who am i | awk '{print $1}')
echo "Current user detected: $CURRENT_USER"
# Immediate X11 screen blanking disable (if running X11 session)
if command -v xset >/dev/null 2>&1 && [ -n "${DISPLAY:-}"DISPLAY" ]; then
echo "Disabling X11 screen saver and DPMS for current session..."
xset s off 2>/dev/null || true
xset -dpms 2>/dev/null || true
xset s noblank 2>/dev/null || true
echo "X11 screen blanking disabled"
fi
# Immediate GNOME settings disable for current user session
if [ -n "$CURRENT_USER" ] && [ "$CURRENT_USER" != "root" ]; then
echo "Applying immediate GNOME power settings for user: $CURRENT_USER"
# Try to disable GNOME power management for current session
sudo -u "$CURRENT_USER" DISPLAY="${DISPLAY:-:0}"DISPLAY" dbus-launch gsettings set org.gnome.desktop.session idle-delay 0 2>/dev/null || true
sudo -u "$CURRENT_USER" DISPLAY="${DISPLAY:-:0}"DISPLAY" dbus-launch gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type 'nothing' 2>/dev/null || true
sudo -u "$CURRENT_USER" DISPLAY="${DISPLAY:-:0}"DISPLAY" dbus-launch gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-type 'nothing' 2>/dev/null || true
sudo -u "$CURRENT_USER" DISPLAY="${DISPLAY:-:0}"DISPLAY" dbus-launch gsettings set org.gnome.desktop.notifications show-banners false 2>/dev/null || true
echo "GNOME power settings applied for current session"
else
echo "Skipping GNOME settings (running as root or user not detected)"
fi
# Also try for root session if applicable
if [ "$USER" = "root" ] || [ "$(id -u)" -eq 0 ]; then
echo "Applying GNOME power settings for root session..."
DISPLAY="${DISPLAY:-:0}"DISPLAY" dbus-launch gsettings set org.gnome.desktop.session idle-delay 0 2>/dev/null || true
DISPLAY="${DISPLAY:-:0}"DISPLAY" dbus-launch gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type 'nothing' 2>/dev/null || true
DISPLAY="${DISPLAY:-:0}"DISPLAY" dbus-launch gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-type 'nothing' 2>/dev/null || true
fi
echo "=== SCREEN BLANKING DISABLED - SCRIPT CAN NOW RUN UNATTENDEDSAFELY ==="
echo ""
# Function definitions for each section
section_1() {
##############################################
# SECTION 1: SYSTEM-WIDE POWER MANAGEMENT AND SCREEN BLANKING CONFIGURATION
##############################################
echo "=== SECTION 1: POWER MANAGEMENT AND HARD DISABLE SUSPEND/IDLE/BLANK (SYSTEM-WIDE) ==="
# Apply user-specific settings for current user0.0
current_user=$(logname 2>/dev/null || echo "$SUDO_USER" || echo "$USER")
sudo -u "$current_user" dbus-run-session gsettings set org.gnome.desktop.session idle-delay 0 || true
sudo -u "$current_user" dbus-run-session gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type 'nothing' || true
sudo -u "$current_user" dbus-run-session gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-type 'nothing' || true
# 0.1 Block all systemd sleep targets (system-wide)
systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target || true # hard block
# 0.2 systemd-logind: ignore idle/lid/suspend/hibernate
install -d -m 0755 /etc/systemd/logind.conf.d
cat >/etc/systemd/logind.conf.d/99-kiosk-nosleep.conf <<'EOF'
[Login]
HandleLidSwitch=ignore
HandleLidSwitchDocked=ignore
HandleSuspendKey=ignore
HandleHibernateKey=ignore
IdleAction=ignore
IdleActionSec=0
EOF
systemctl daemon-reload || true
# Note: systemd-logind changes will take effect after next reboot/logout
# This daemon-reload does NOT interrupt current user sessions
# 0.3 Prevent tty console blanking (kernel)
if ! grep -q 'consoleblank=0' /etc/default/grub 2>/dev/null; then
sed -i 's/^\(GRUB_CMDLINE_LINUX_DEFAULT="[^"]*\)"/\1 consoleblank=0"/' /etc/default/grub || true # append
update-grub || true
fi
# 0.4 Disable X11 DPMS/screensaver globally (affects SDDM/X sessions)
install -d -m 0755 /etc/X11/xorg.conf.d
cat >/etc/X11/xorg.conf.d/10-nodpms.conf <<'EOF'
Section "ServerFlags"
Option "BlankTime" "0"
Option "StandbyTime" "0"
Option "SuspendTime" "0"
Option "OffTime" "0"
EndSection
Section "Extensions"
Option "DPMS" "Disable"
EndSection
EOF
# 0.5 SDDM greeter: kill DPMS even before login (X11 greeter path)
install -d -m 0755 /etc/sddm
cat >/etc/sddm/Xsetup <<'EOF'
#!/bin/sh
# Disable screen blanking/DPMS in the greeter
xset s off || true
xset -dpms || true
xset s noblank || true
EOF
chmod +x /etc/sddm/Xsetup
# 0.6 GNOME: system dconf defaults + locks (ensures org.gnome stays off)
install -d -m 0755 /etc/dconf/db/local.d /etc/dconf/db/local.d/locks
cat >/etc/dconf/db/local.d/00-kiosk-nosleep <<'EOF'
[org/gnome/desktop/session]
idle-delay=uint32 0
[org/gnome/settings-daemon/plugins/power]
sleep-inactive-ac-type='nothing'
sleep-inactive-battery-type='nothing'
sleep-inactive-ac-timeout=0
sleep-inactive-battery-timeout=0
[org/gnome/desktop/notifications]
show-banners=false
show-in-lock-screen=false
EOF
cat >/etc/dconf/db/local.d/locks/00-kiosk-nosleep <<'EOF'
/org/gnome/desktop/session/idle-delay
/org/gnome/settings-daemon/plugins/power/sleep-inactive-ac-type
/org/gnome/settings-daemon/plugins/power/sleep-inactive-battery-type
/org/gnome/settings-daemon/plugins/power/sleep-inactive-ac-timeout
/org/gnome/settings-daemon/plugins/power/sleep-inactive-battery-timeout
/org/gnome/desktop/notifications/show-banners
/org/gnome/desktop/notifications/show-in-lock-screen
EOF
dconf update || true # compile system database
# 0.7 KDE/Plasma: default profile (system-wide seed via /etc/xdg)
install -d -m 0755 /etc/xdg
cat >/etc/xdg/powermanagementprofilesrc <<'EOF'
[AC]
iconBrightness=100
idleDim=false
idleTime=0
suspendWhenInactive=false
[Battery]
idleDim=false
idleTime=0
suspendWhenInactive=false
[LowBattery]
idleDim=false
idleTime=0
suspendWhenInactive=false
EOF
# 0.8 Wayland/Plasma session kicker: ensure DPMS off for running sessions
install -d -m 0755 /etc/profile.d
cat >/etc/profile.d/99-nodpms.sh <<'EOF'
#!/bin/sh
# Best-effort: kill screen blanking for X11 clients if any; harmless on Wayland
if command -v xset >/dev/null 2>&1; then
(xset s off -dpms s noblank >/dev/null 2>&1 || true)
fi
EOF
chmod +x /etc/profile.d/99-nodpms.sh
echo "=== SECTION 10 COMPLETE ==="
}
# --- MODIFY: run_all_sections() to include section_0 ---
# Before: for i in $(seq 1 $MAX_SECTIONS); do
# After:
# (change start index to 0 so section_0 runs first)
section_2() {
##############################################
# SECTION 2: INITIAL SYSTEM SETUP
##############################################
echo "=== SECTION 2: INITIAL SYSTEM SETUP ==="
apt-get update -yq
apt-get upgrade -yq
apt-get update -yq
#wait for user input
#read -p "Press [Enter] key to continue... try gdm3, ssdm has issues with my app"
}
section_3() {
#######################################################
# SECTION 3: DESKTOP ENVIRONMENT INSTALLATION
#######################################################
echo "=== SECTION 3: DESKTOP ENVIRONMENT INSTALLATION ==="
# Pre-configure display manager selection to avoid interactive prompts
echo "gdm3 shared/default-x-display-manager select gdm3" | debconf-set-selections
# Install packages non-interactively
DEBIAN_FRONTEND=noninteractive apt install -yq kde-plasma-desktop chromium-browser xdotool unclutter sed curl libinput-tools net-tools ssh
systemctl enable ssh
apt install -y inotify-tools zenity udevil udisks2
echo "KDE Plasma desktop installed successfully"
}
section_4() {
##############################################
# SECTION 4: PHIDGET SETUP AND DEPENDENCIES
##############################################
echo "=== SECTION 4: PHIDGET SETUP AND DEPENDENCIES ==="
apt install -y chromium-browser sed xdotool unclutter
curl -fsSL https://www.phidgets.com/downloads/setup_linux | bash -
apt install -y libphidget22 phidget22networkserver
apt install -y libphidget22* phidget22*
apt install -y python3 npm nodejs
ifconfig
}
section_5() {
##############################################
# SECTION 5: TOUCHSCREEN CONFIGURATION
##############################################
echo "=== SECTION 5: TOUCHSCREEN CONFIGURATION ==="
#setup touchscreen
echo -e "usbtouchscreen\nusbhid" | tee /etc/modules-load.d/touchscreen.conf
modprobe usbtouchscreen
modprobe usbhid
lsmod | grep usb
lsmod | grep hid
lsmod | grep usb
lsmod | grep hid
dmesg | grep -i touch
}
section_6() {
##############################################
# SECTION 6: PHIDGET NETWORK SERVER SETUP
##############################################
echo "=== SECTION 6: PHIDGET NETWORK SERVER SETUP ==="
#setup phidget22networkserver
DEFAULT_PHIDGET_PORT_VAR=""
DEFAULT_WEB_PORT_VAR=""
SERVICE_NAME="phidget22networkserver"
INIT_PATH="/etc/init.d/$SERVICE_NAME"
#v1 (works???)
if [[ "$(id -u)" -ne 0 ]]; then
echo "Run this as root."
exit 1
fi
cat > "$INIT_PATH" <<'EOF'
#!/bin/sh
### BEGIN INIT INFO
# Provides: phidget22networkserver
# Required-Start: $network $remote_fs
# Required-Stop: $network $remote_fs
# Should-Start: avahi avahi-daemon
# Should-Stop: avahi avahi-daemon
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Phidget Network Server
# Description: Phidget network server for accessing Phidgets over the network.
### END INIT INFO
sudo phidget22networkserver -c /etc/phidgets/phidget22networkserver.pc -D
EOF
#add ipv6 to phidget config??? { port: 8080 }
chmod +x "$INIT_PATH"
sudo sed -i "s#docroot: '/var/phidgets/www'#docroot: '/home/recharjme/Desktop/APP'#" /etc/phidgets/phidget22networkserver.pc
update-rc.d "$SERVICE_NAME" defaults
service "$SERVICE_NAME" start
systemctl daemon-reload
systemctl enable "$SERVICE_NAME"
systemctl restart "$SERVICE_NAME"
echo "Phidget network server configured and started successfully"
# Service status check - non-blocking
systemctl is-active "$SERVICE_NAME" >/dev/null && echo "Service is running" || echo "Service failed to start"
#wait for user input
#read -p "Press [Enter] key to continue... this is usuially where shit breaks"
}
section_7() {
##############################################
# SECTION 7: KIOSK USER SETUP
##############################################
echo "=== SECTION 7: KIOSK USER SETUP ==="
# 1) Ensure kiosk exists
if ! id kiosk &>/dev/null; then adduser --disabled-password --gecos "" kiosk; fi
passwd -d kiosk || true
usermod -aG sudo kiosk
install -d -m 0755 /home/kiosk/.config/autostart
chown -R kiosk:kiosk /home/kiosk
#read -p "Press [Enter] key to continue... touch works now, configuring GDM for Plasma Wayland"
# Force Wayland in GDM for admin acct
sed -i 's/^#\?WaylandEnable=.*/WaylandEnable=true/' /etc/gdm3/custom.conf
grep WaylandEnable /etc/gdm3/custom.conf || true
#read -p "Press [Enter] key to continue... setting autologin for GDM3 (Plasma Wayland)"
sudo -u kiosk kwriteconfig6 --file startkderc --group General --key desktopSession empty
sudo -u kiosk kwriteconfig6 --file ksmserverrc --group General --key loginMode emptySession
# KDE/Plasma power management settings for kiosk user
# Comprehensive power and session management configuration to ensure kiosk stability
# Disable screen blanking and power management
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group AC --key DimDisplay false
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group AC --key idleDim false
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group AC --key idleTime 0
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group AC --key suspendWhenInactive false
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group AC --key DPMSEnable false
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group AC --key TurnOffDisplay 0
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group Battery --key DimDisplay false
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group Battery --key idleDim false
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group Battery --key idleTime 0
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group Battery --key suspendWhenInactive false
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group Battery --key DPMSEnable false
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group Battery --key TurnOffDisplay 0
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group LowBattery --key DimDisplay false
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group LowBattery --key idleDim false
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group LowBattery --key idleTime 0
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group LowBattery --key suspendWhenInactive false
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group LowBattery --key DPMSEnable false
sudo -u kiosk kwriteconfig6 --file powermanagementprofilesrc --group LowBattery --key TurnOffDisplay 0
# Disable session management features that might interfere with kiosk
sudo -u kiosk kwriteconfig6 --file ksmserverrc --group General --key confirmLogout false
sudo -u kiosk kwriteconfig6 --file ksmserverrc --group General --key shutdownType 0
sudo -u kiosk kwriteconfig6 --file ksmserverrc --group General --key loginMode emptySession
# Disable KDE screen locker
sudo -u kiosk kwriteconfig6 --file kscreenlockerrc --group Daemon --key Autolock false
sudo -u kiosk kwriteconfig6 --file kscreenlockerrc --group Daemon --key LockOnResume false
sudo -u kiosk kwriteconfig6 --file kscreenlockerrc --group Daemon --key Timeout 0
# Disable KWin compositor effects that might interfere
sudo -u kiosk kwriteconfig6 --file kwinrc --group Compositing --key Enabled true
sudo -u kiosk kwriteconfig6 --file kwinrc --group Compositing --key GLCore true
# Disable desktop effects that might cause issues
sudo -u kiosk kwriteconfig6 --file kwinrc --group Plugins --key blurEnabled false
sudo -u kiosk kwriteconfig6 --file kwinrc --group Plugins --key contrastEnabled false
sudo -u kiosk kwriteconfig6 --file kwinrc --group Plugins --key slideEnabled false
sudo -u kiosk kwriteconfig6 --file kwinrc --group Plugins --key fadeEnabled false
}
section_8() {
##############################################
# SECTION 8: GDM3 AUTOLOGIN CONFIGURATION
##############################################
echo "=== SECTION 8: GDM3 AUTOLOGIN CONFIGURATION ==="
# GDM3 Autologin to Plasma Wayland
if [ -f /etc/gdm3/custom.conf ]; then
awk '
BEGIN{inDaemon=0; hasALE=0; hasAL=0; hasDS=0}
/^\[daemon\]/{inDaemon=1; print; next}
/^\[/{ if(inDaemon && !(hasALE&&hasAL&&hasDS)){print "AutomaticLoginEnable=true\nAutomaticLogin=kiosk\nDefaultSession=plasma"}; inDaemon=0; print; next}
{
if(inDaemon){
if($0 ~ /^AutomaticLoginEnable=/){$0="AutomaticLoginEnable=true"; hasALE=1}
if($0 ~ /^AutomaticLogin=/){$0="AutomaticLogin=kiosk"; hasAL=1}
if($0 ~ /^DefaultSession=/){$0="DefaultSession=plasma"; hasDS=1}
}
print
}
END{
if(inDaemon && !(hasALE&&hasAL&&hasDS)){
print "AutomaticLoginEnable=true"
print "AutomaticLogin=kiosk"
print "DefaultSession=plasma"
}
}
' /etc/gdm3/custom.conf > /tmp/custom.conf && mv /tmp/custom.conf /etc/gdm3/custom.conf
# Make sure AccountsService maps kiosk -> plasma
install -d -m 0755 /var/lib/AccountsService/users
cat >/var/lib/AccountsService/users/kiosk <<'EOF'
[User]
XSession=plasma
SystemAccount=false
EOF
chmod 0644 /var/lib/AccountsService/users/kiosk
#systemctl restart gdm3
fi
}
section_9() {
##############################################
# SECTION 9: SDDM CONFIGURATION (ALTERNATIVE)
##############################################
echo "=== SECTION 9: SDDM CONFIGURATION (ALTERNATIVE) ==="
# Make sure /etc/sddm.conf exists
[ -f /etc/sddm.conf ] || touch /etc/sddm.conf
# Ensure autologin block exists and points to kiosk + plasma
if grep -q '^\[Autologin\]' /etc/sddm.conf; then
sed -i '/^\[Autologin\]/,/^\[/{s/^User.*/User=kiosk/;s/^Session.*/Session=plasma/}' /etc/sddm.conf
else
tee -a /etc/sddm.conf >/dev/null <<'EOF'
[Autologin]
User=kiosk
Session=plasma
EOF
fi
# Switch DM to SDDM
echo "sddm shared/default-x-display-manager select sddm" | sudo debconf-set-selections
sudo dpkg-reconfigure -fnoninteractive sddm
systemctl disable gdm3 || true
systemctl enable sddm
systemctl set-default graphical.target
#systemctl restart sddm
# Show resulting configs
[ -f /etc/gdm3/custom.conf ] && cat /etc/gdm3/custom.conf || true
[ -f /etc/sddm.conf ] && cat /etc/sddm.conf || true
#read -p "Press [Enter] key to continue... creating Chromium autostart"
}
section_10() {
##############################################
# SECTION 10: CHROMIUM KIOSK AUTOSTART SETUP
##############################################
echo "=== SECTION 10: CHROMIUM KIOSK AUTOSTART SETUP ==="
# Create Chromium kiosk autostart for Plasma session
APP_URL="http://localhost:8080"
# Create a wrapper script for delayed Chromium startup
cat >/home/kiosk/.config/autostart/chromium-kiosk-wrapper.sh <<'EOF'
#!/bin/bash
# Wait for desktop environment to fully load
sleep 5
# Launch Chromium in kiosk mode
/usr/bin/chromium-browser --ozone-platform=wayland --enable-features=UseOzonePlatform,WaylandWindowDecorations --no-first-run --no-default-browser-check --disable-session-crashed-bubble --disable-infobars --start-maximized --noerrdialogs --incognito --kiosk "http://localhost:8080" &
# Wait for Chromium to fully load, then refresh
sleep 5
# Send F5 key to refresh the page
DISPLAY=:0 xdotool key F5
EOF
chmod +x /home/kiosk/.config/autostart/chromium-kiosk-wrapper.sh
cat >/home/kiosk/.config/autostart/chromium-kiosk.desktop <<EOF
[Desktop Entry]
Type=Application
Name=Chromium Kiosk
Exec=/home/kiosk/.config/autostart/chromium-kiosk-wrapper.sh
X-GNOME-Autostart-enabled=true
X-KDE-AutostartScript=true
EOF
chown kiosk:kiosk /home/kiosk/.config/autostart/chromium-kiosk-wrapper.sh
chown kiosk:kiosk /home/kiosk/.config/autostart/chromium-kiosk.desktop
chmod 0644 /home/kiosk/.config/autostart/chromium-kiosk.desktop
}
section_11() {
#read -p "Press [Enter] key to continue... verifying Wayland toggles and kiosk autostart path"
##############################################
# SECTION 11: WAYLAND AND KIOSK VERIFICATION
##############################################
echo "=== SECTION 11: WAYLAND AND KIOSK VERIFICATION ==="
# Ensure WaylandEnable=false is commented if present
if grep -q '^WaylandEnable=false' /etc/gdm3/custom.conf; then
sed -i 's/^WaylandEnable=false/#WaylandEnable=false/' /etc/gdm3/custom.conf
fi
# Make sure APP_URL uses http (Phidget web piece typically)
sed -i 's#https://localhost:8080#http://localhost:8080#g' /home/kiosk/.config/autostart/chromium-kiosk.desktop
chown kiosk:kiosk /home/kiosk/.config/autostart/chromium-kiosk.desktop
}
section_12() {
#read -p "Press [Enter] key to continue... disabling touch gestures (GNOME keys; ignored on Plasma)"
##############################################
# SECTION 12: TOUCH GESTURE CONFIGURATION
##############################################
echo "=== SECTION 12: TOUCH GESTURE CONFIGURATION ==="
# Get current user
current_user=$(logname 2>/dev/null || echo "$SUDO_USER" || echo "$USER")
# Remove Wayland touch shortcuts for current user (GNOME dconf; harmless if schema missing)
sudo -u "$current_user" dbus-run-session gsettings set org.gnome.desktop.peripherals.touchpad three-finger-swipe-enabled false || true
sudo -u "$current_user" dbus-run-session gsettings set org.gnome.desktop.peripherals.touchpad pinch-to-zoom false || true
# Also apply to kiosk user if exists
if id kiosk &>/dev/null; then
sudo -u kiosk dbus-run-session gsettings set org.gnome.desktop.peripherals.touchpad three-finger-swipe-enabled false || true
sudo -u kiosk dbus-run-session gsettings set org.gnome.desktop.peripherals.touchpad pinch-to-zoom false || true
fi
}
section_13() {
#read -p "Press [Enter] key to continue... applying KWin tweaks"
echo "=== SECTION 13: KWIN TWEAKS AND FINAL KDE SETUP ==="
# Apply KWin global shortcuts cleanup and additional KDE settings for kiosk user
sudo -u kiosk kwriteconfig6 --file kwinrc --group "Global Shortcuts" --key _k_friendly_name "" || true
# Additional KDE settings for kiosk stability
# Disable KDE desktop effects and animations
sudo -u kiosk kwriteconfig6 --file kwinrc --group Effect-Blur --key Enabled false
sudo -u kiosk kwriteconfig6 --file kwinrc --group Effect-DesktopGrid --key Enabled false
sudo -u kiosk kwriteconfig6 --file kwinrc --group Effect-PresentWindows --key Enabled false
sudo -u kiosk kwriteconfig6 --file kwinrc --group Effect-Zoom --key Enabled false
sudo -u kiosk kwriteconfig6 --file kwinrc --group Effect-MouseClick --key Enabled false
sudo -u kiosk kwriteconfig6 --file kwinrc --group Effect-MouseMark --key Enabled false
# Disable workspace switching and desktop switching
sudo -u kiosk kwriteconfig6 --file kwinrc --group Desktops --key Number 1
sudo -u kiosk kwriteconfig6 --file kwinrc --group Windows --key RollOverDesktops false
# Disable window snapping and edge actions
sudo -u kiosk kwriteconfig6 --file kwinrc --group Windows --key ElectricBorderDelay 0
sudo -u kiosk kwriteconfig6 --file kwinrc --group Windows --key ElectricBorderCooldown 0
sudo -u kiosk kwriteconfig6 --file kwinrc --group Windows --key ElectricBorderMaximize false
sudo -u kiosk kwriteconfig6 --file kwinrc --group Windows --key ElectricBorderTiling false
# Disable window management features
sudo -u kiosk kwriteconfig6 --file kwinrc --group Windows --key FocusPolicy "ClickToFocus"
sudo -u kiosk kwriteconfig6 --file kwinrc --group Windows --key AutoRaise false
sudo -u kiosk kwriteconfig6 --file kwinrc --group Windows --key DelayFocusInterval 0
# Disable KDE notifications for kiosk user
sudo -u kiosk kwriteconfig6 --file plasmanotifyrc --group Notifications --key PopupPosition "TopRight"
sudo -u kiosk kwriteconfig6 --file plasmanotifyrc --group Notifications --key LowPriorityHistory false
sudo -u kiosk kwriteconfig6 --file plasmanotifyrc --group Notifications --key ShowInHistory false
# Disable Plasma desktop containment actions and widgets
sudo -u kiosk kwriteconfig6 --file plasma-org.kde.plasma.desktop-appletsrc --group Containments --key locked true
# Create autostart script to reload KWin and apply settings
install -d -m 0755 /home/kiosk/.config/autostart-scripts
chown kiosk:kiosk /home/kiosk/.config/autostart-scripts
cat > /home/kiosk/.config/autostart-scripts/reload-kwin.sh <<'EOF'
#!/bin/sh
# Wait for KDE to fully start
sleep 3
# Reload KWin configuration
(qdbus6 org.kde.KWin /KWin reconfigure || qdbus6 org.kde.KWin.Wayland /KWin reconfigure) || true
# Disable DPMS again in case it was re-enabled
xset s off -dpms s noblank >/dev/null 2>&1 || true
EOF
chmod +x /home/kiosk/.config/autostart-scripts/reload-kwin.sh
chown kiosk:kiosk /home/kiosk/.config/autostart-scripts/reload-kwin.sh
echo "KWin tweaks and KDE settings applied for kiosk user"
}
section_14() {
#read -p "Press [Enter] key to continue... stopping screen blanking for kiosk user (best effort for GNOME; harmless on Plasma)"
##############################################
# SECTION 14: POWER MANAGEMENT AND SCREEN BLANKING for kiosk user
##############################################
echo "=== SECTION 14: POWER MANAGEMENT AND SCREEN BLANKING FOR KIOSK USER ==="
# GNOME settings (for GNOME sessions - no-op if schema absent)
sudo -u kiosk dbus-run-session gsettings set org.gnome.desktop.session idle-delay 0 || true
sudo -u kiosk dbus-run-session gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type 'nothing' || true
sudo -u kiosk dbus-run-session gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-type 'nothing' || true
# KDE/Plasma specific settings for kiosk user (additional reinforcement)
# Ensure power management is completely disabled
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group AC --key icon ""
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group AC --key "Display Brightness" 100
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group AC --key "Dim display when idle" false
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group AC --key "Screen Energy Saving" false
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group AC --key "Suspend session" false
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group AC --key "Lock screen when suspending" false
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group Battery --key icon ""
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group Battery --key "Display Brightness" 100
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group Battery --key "Dim display when idle" false
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group Battery --key "Screen Energy Saving" false
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group Battery --key "Suspend session" false
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group Battery --key "Lock screen when suspending" false
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group LowBattery --key icon ""
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group LowBattery --key "Display Brightness" 100
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group LowBattery --key "Dim display when idle" false
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group LowBattery --key "Screen Energy Saving" false
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group LowBattery --key "Suspend session" false
sudo -u kiosk kwriteconfig6 --file powerdevilrc --group LowBattery --key "Lock screen when suspending" false
# Additional KDE power settings
sudo -u kiosk kwriteconfig6 --file kdeglobals --group KDE --key SingleClick true
sudo -u kiosk kwriteconfig6 --file kdeglobals --group General --key BrowserApplication "chromium-browser.desktop"
# Create a KDE autostart script to ensure power settings stay disabled
cat > /home/kiosk/.config/autostart/kde-power-disable.desktop <<'EOF'
[Desktop Entry]
Type=Application
Name=KDE Power Disable
Exec=/bin/sh -c "kwriteconfig6 --file powermanagementprofilesrc --group AC --key idleTime 0; kwriteconfig6 --file powermanagementprofilesrc --group Battery --key idleTime 0; kwriteconfig6 --file powermanagementprofilesrc --group LowBattery --key idleTime 0"
X-GNOME-Autostart-enabled=true
X-KDE-AutostartScript=true
Hidden=false
EOF
chown kiosk:kiosk /home/kiosk/.config/autostart/kde-power-disable.desktop
chmod 0644 /home/kiosk/.config/autostart/kde-power-disable.desktop
echo "Power management settings applied for both GNOME and KDE for kiosk user"
}
section_15() {
##############################################
# SECTION 15: FINAL SYSTEM RESTART
##############################################
echo "=== SECTION 15: FINAL SYSTEM RESTART ==="
systemctl enable chromium-kiosk || true
systemctl disable gdm3 || true
systemctl enable sddm
systemctl set-default graphical.target
im-config -n none
sudo tee /etc/environment >/dev/null <<'EOF'
GTK_IM_MODULE=none
QT_IM_MODULE=none
XMODIFIERS=@im=none
EOF
}
section_16() {
echo "=== SECTION 16: remove notifs and enable auto updater ==="
# Placeholder for future sections
sudo snap remove snapd-desktop-integration
sudo snap remove snapd-desktop-integration-test
sudo -u kiosk im-config -n none || true
}
section_17() {
##############################################
# SECTION 17: DISABLE ERROR POPUPS (Apport, notifications)
##############################################
echo "=== SECTION 17: Disable error popups for kiosk user ==="
# Disable Apport (Ubuntu crash reporter)
sed -i 's/^enabled=1/enabled=0/' /etc/default/apport || true
systemctl disable apport.service || true
systemctl mask apport.service || true
systemctl stop apport.service || true
# Disable update-notifier crash reports
rm -f /var/crash/* || true
# For kiosk user: suppress all desktop notifications
sudo -u kiosk dbus-launch gsettings set org.gnome.desktop.notifications show-banners false || true
sudo -u kiosk dbus-launch gsettings set org.gnome.desktop.notifications show-in-lock-screen false || true
# Divert stderr of systemd services to logs only (no journal popups)
mkdir -p /etc/systemd/system.conf.d
cat >/etc/systemd/system.conf.d/no-notify.conf <<'EOF'
[Manager]
DefaultStandardError=journal
DefaultStandardOutput=journal
EOF
systemctl daemon-reexec || true
}
section_18() {
rm -rf /usr/local/bin/usb-app-updater.sh; rm -rf /etc/systemd/system/usb-app-updater.service; rm -rf /var/log/usb-updater.log; rm -rf /var/lock/usb-updater.lock
##############################################
# SECTION 18: USB AUTO-UPDATE SERVICE + EVENTUAL REBOOT
##############################################
echo "=== SECTION 18: USB AUTO-UPDATE SERVICE + Eventual Reboot ==="
apt install -y inotify-tools zenity udevil udisks2
SERVICE_NAME="usb-app-updater"
SERVICE_PATH="/etc/systemd/system/${SERVICE_NAME}.service"
SCRIPT_PATH="/usr/local/bin/${SERVICE_NAME}.sh"
cat >"$SCRIPT_PATH" <<'EOF'
#!/bin/bash
set -euo pipefail
MOUNT_POINT="/mnt/RECHARJME"
TARGET_DIR="/home/kiosk/recharjme/Desktop/APP"
LOG_FILE="/var/log/usb-updater.log"
# Ensure log file exists and is writable
touch "$LOG_FILE" 2>/dev/null || LOG_FILE="/tmp/usb-updater.log"
# Function to log messages
log_msg() {
echo "$(date): $1" >> "$LOG_FILE"
}
# Function to get all logged-in users
get_all_logged_users() {
local users=()
# Method 1: Get users from who command (currently logged in)
while read -r user; do
[[ -n "$user" ]] && users+=("$user")
done < <(who | awk '{print $1}' | sort -u)
# Method 2: Get users from loginctl (active sessions)
while read -r user; do
[[ -n "$user" ]] && [[ ! " ${users[*]} " =~ " $user " ]] && users+=("$user")
done < <(loginctl --no-pager list-sessions --no-legend | awk '{print $3}' | sort -u)
# Method 3: If no users found, check for kiosk user specifically
if [ ${#users[@]} -eq 0 ] && id kiosk &>/dev/null; then
users+=("kiosk")
fi
# Method 4: If still no users, get first non-system user as fallback
if [ ${#users[@]} -eq 0 ]; then
local fallback_user=$(awk -F: '$3>=1000 && $3<65534 {print $1}' /etc/passwd | head -1 2>/dev/null || echo "")
[[ -n "$fallback_user" ]] && users+=("$fallback_user")
fi
# Return users as space-separated string
printf "%s\n" "${users[@]}"
}
# Function to get primary user for file ownership (first logged-in user)
get_primary_user() {
local all_users=($(get_all_logged_users))
if [ ${#all_users[@]} -gt 0 ]; then
echo "${all_users[0]}"
return 0
fi
return 1
}
# Function to show notification to all logged-in users
broadcast_notification() {
local message="$1"
local users=($(get_all_logged_users))
local notification_sent=false
log_msg "Broadcasting notification to ${#users[@]} user(s): ${users[*]}"
for user in "${users[@]}"; do
local user_uid=$(id -u "$user" 2>/dev/null || echo "")
if [ -z "$user_uid" ]; then
log_msg "Could not get UID for user $user, skipping"
continue
fi
# Set up environment for GUI applications
export XDG_RUNTIME_DIR="/run/user/$user_uid"
export DISPLAY=:0
# Try different notification methods
if sudo -u "$user" DISPLAY=:0 zenity --info --text="$message" --timeout=5 2>/dev/null; then
log_msg "Zenity notification sent to user $user"
notification_sent=true
elif sudo -u "$user" DISPLAY=:0 notify-send "USB Update" "$message" 2>/dev/null; then
log_msg "notify-send notification sent to user $user"
notification_sent=true
else
log_msg "Could not show notification to user $user"
fi
done
if [ "$notification_sent" = false ]; then
log_msg "Failed to send notification to any user"
fi
}
log_msg "USB Auto-Update Service started"
# Lock file to prevent concurrent updates
LOCK_FILE="/var/lock/usb-updater.lock"
while true; do
# FIRST: Check if there's a lock file - handle cleanup logic before doing any USB detection
if [ -f "$LOCK_FILE" ]; then
log_msg "Lock file exists, checking if USB key is still present"
# Quick check: is USB still present? (minimal detection for cleanup purposes)
USB_PRESENT=false
# Method 1: Check if already auto-mounted
if find /media /mnt /run/media -name "*RECHARJME*" -type d 2>/dev/null | head -1 | grep -q RECHARJME; then
USB_PRESENT=true
fi
# Method 2: Check device list if not auto-mounted
if [ "$USB_PRESENT" = false ] && lsblk -o LABEL -nr 2>/dev/null | grep -q "RECHARJME"; then
USB_PRESENT=true
fi
if [ "$USB_PRESENT" = false ]; then
log_msg "USB key removed, removing lock file"
rm -f "$LOCK_FILE"
else
log_msg "USB key still present with active lock, doing nothing"
fi
sleep 5
continue
fi
# SECOND: No lock file exists, do full USB detection for processing
DEV=""
MOUNT_PATH=""
# Method 1: Check if already auto-mounted by system
AUTO_MOUNT=$(find /media /mnt /run/media -name "*RECHARJME*" -type d 2>/dev/null | head -1)
if [ -n "$AUTO_MOUNT" ] && [ -d "$AUTO_MOUNT" ]; then
DEV="auto-mounted"
MOUNT_PATH="$AUTO_MOUNT"
log_msg "Found auto-mounted USB at: $MOUNT_PATH"
else
# Method 2: Find device by label and try to mount manually
DEV=$(lsblk -o LABEL,PATH -nr 2>/dev/null | awk '$1=="RECHARJME"{print $2; exit}')
if [ -n "$DEV" ]; then
MOUNT_PATH="$MOUNT_POINT"
log_msg "Found USB device: $DEV (not auto-mounted)"
fi
fi
# Process USB if found
if [ -n "$DEV" ] &&|| [ -n "$DEV" != "auto-mounted"AUTO_MOUNT" ]; then
log_msg "Found USB device: $DEV - starting update process"
elifif [ -n "$AUTO_MOUNT" ]; then
log_msg "Found auto-mounted USB device at: $MOUNT_PATH - starting update process"
DEV=else
log_msg "auto-mounted"Found USB device: $DEV - starting update process"
fi
if [ -n "$DEV" ]; then
# Create lock file
echo $$ > "$LOCK_FILE"
# Get all logged-in users and primary user for file ownership
ALL_USERS=($(get_all_logged_users))
PRIMARY_USER=$(get_primary_user)
if [ ${#ALL_USERS[@]} -eq 0 ] || [ -z "$PRIMARY_USER" ]; then
log_msg "Could not determine any logged-in users, skipping USB processing"
rm -f "$LOCK_FILE" # Remove lock if we can't process
sleep 5
continue
fi
log_msg "Logged-in users detected: ${ALL_USERS[*]}"
log_msg "Primary user (for file ownership): $PRIMARY_USER"
# Handle mounting if not already auto-mounted
MOUNTED=false
if [ "$DEV" != "auto-mounted" ]; then
# Create mount point if it doesn't exist
mkdir -p "$MOUNT_POINT"
2>/dev/null || {
log_msg "ERROR: Could not create mount point $MOUNT_POINT"
rm -f "$LOCK_FILE"
sleep 5
continue
}
# Try multiple mount methods
if mount "$DEV" "$MOUNT_POINT" 2>/dev/null; then
MOUNTED=true
log_msg "Successfully mounted $DEV to $MOUNT_POINT"
elif udisksctl mount -b "$DEV" 2>/dev/null; then
# udisksctl auto-mounts, find where it mounted
sleep 2
NEW_MOUNT=$(find /media /mnt /run/media -name "*RECHARJME*" -type d 2>/dev/null | head -1)
if [ -n "$NEW_MOUNT" ]; then
MOUNT_PATH="$NEW_MOUNT"
MOUNTED=true
log_msg "Successfully auto-mounted $DEV to $MOUNT_PATH via udisksctl"
fi
else
log_msg "ERROR: Failed to mount $DEV using both mount and udisksctl"
fi
else
MOUNTED=true # Already auto-mounted
fi
if [ "$MOUNTED" = true ] && [ -d "$MOUNT_PATH" ]; then
# Check if APP directory exists
if [ -d "$MOUNT_PATH/APP" ]; then
log_msg "Found APP directory at $MOUNT_PATH/APP, starting update process"
# Show update notification to all users
broadcast_notification "Updating APP..."
# Create backup directory if it doesn't exist
if ! mkdir -p "/home/$PRIMARY_USER/Desktop/BACKUPS" 2>/dev/null;null then|| log_msg "WARNING: Could not create backup directory, proceeding without backup"
fitrue
# Backup existing APP if it exists
if [ -d "$TARGET_DIR" ]; then
BACKUP_NAME="APP.backup.$(date +%s)"
if mv "$TARGET_DIR" "/home/$PRIMARY_USER/Desktop/BACKUPS/$BACKUP_NAME" 2>/dev/null;null then|| true
log_msg "Backed up existing APP to BACKUPS/$BACKUP_NAME"
else
log_msg "WARNING: Could not backup existing APP, removing it"
rm -rf "$TARGET_DIR" 2>/dev/null || true
fi
fi
# Copy new APP with detailed error handling
mkdir -p "$(dirname "$TARGET_DIR")"
2>/dev/null || {
log_msg "ERROR: Could not create parent directory for $TARGET_DIR"
if [ "$DEV" != "auto-mounted" ]; then
umount "$MOUNT_PATH" 2>/dev/null || udisksctl unmount -b "$DEV" 2>/dev/null || true
fi
rm -f "$LOCK_FILE"
continue
}
if cp -r "$MOUNT_PATH/APP" "$TARGET_DIR" 2>/dev/null;; then
log_msg "Successfully copied APP to $TARGET_DIR"
# Set proper ownership to the primary user
chown -R "$PRIMARY_USER:$PRIMARY_USER" "$TARGET_DIR" 2>/dev/null || true
# Show completion notification and auto-reboot
broadcast_notification "Update complete. System will restart in 10 seconds..."
log_msg "Update completed successfully, rebooting system in 10 seconds"
sleep 10
# Unmount if we mounted it manually
if [ "$DEV" != "auto-mounted" ]; then
umount "$MOUNT_PATH" 2>/dev/null || udisksctl unmount -b "$DEV" 2>/dev/null || true
fi
# Keep lock file - it will be removed when USB is unplugged after reboot
reboot
else
log_msg "ERROR: Failed to copy APP directory from $MOUNT_PATH/APP to $TARGET_DIR"
# Show error notification
broadcast_notification "Update failed - could not copy files"directory"
if [ "$DEV" != "auto-mounted" ]; then
umount "$MOUNT_PATH" 2>/dev/null || udisksctl unmount -b "$DEV" 2>/dev/null || true
fi
rm -f "$LOCK_FILE" # Remove lock on failure
fi
else
log_msg "No APP directory found on USB device at $MOUNT_PATH"
if [ "$DEV" != "auto-mounted" ]; then
umount "$MOUNT_PATH" 2>/dev/null || udisksctl unmount -b "$DEV" 2>/dev/null || true
fi
rm -f "$LOCK_FILE" # Remove lock if no APP directory
fi
else
log_msg "ERROR: Could not mount or access USB device"
rm -f "$LOCK_FILE" # Remove lock on mount failure
fi
fi
sleep 5
done
EOF
chmod +x "$SCRIPT_PATH"
# Verify the script was created successfully
if [ ! -f "$SCRIPT_PATH" ] || [ ! -x "$SCRIPT_PATH" ]; then
echo "ERROR: Failed to create or make executable: $SCRIPT_PATH"
exit 1
fi
echo "USB updater script created at: $SCRIPT_PATH"
cat >"$SERVICE_PATH" <<EOF
[Unit]
Description=USB Auto-Update Service for APP
After=multi-user.target
Wants=systemd-udevd.service
After=systemd-udevd.service
[Service]
Type=simple
ExecStart=$SCRIPT_PATH
Restart=always
RestartSec=5
User=root
Group=root
StandardOutput=journal
StandardError=journal
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
[Install]
WantedBy=multi-user.target
EOF
# Verify the service file was created successfully
if [ ! -f "$SERVICE_PATH" ]; then
echo "ERROR: Failed to create systemd service file: $SERVICE_PATH"
exit 1
fi
echo "Systemd service file created at: $SERVICE_PATH"
systemctl daemon-reload
systemctl enable "$SERVICE_NAME"
systemctl restart "$SERVICE_NAME"
|| true
# Check servicesystemctl status
if systemctl is-active --quiet "$SERVICE_NAME"; then
echo "USB Auto-Update Service started successfully"
log_msg "USB Auto-Update Service started successfully"
else
echo "WARNING: USB Auto-Update Service may have failed to start"
echo "Check logs with: journalctl -u $SERVICE_NAME"
fi
echo "=== USB Auto-Update Service Installation Complete ==="-no-pager
}
# Automatically detect the number of sections
get_max_section() {
declare -F | grep -o 'section_[0-9]\+' | grep -o '[0-9]\+' | sort -n | tail -1
}
MAX_SECTIONS=$(get_max_section)
# Main script execution logic
show_usage() {
echo "Usage: $0 [-s SECTION_NUMBER]"
echo ""
echo "Options:"
echo " -s SECTION_NUMBER Run only the specified section (1-$MAX_SECTIONS)"
echo " -h, --help Show this help message"
echo ""
echo "If no options are provided, all sections will be run in order."
echo ""
echo "Available sections:"
echo " 1 - Power Management and Screen Blanking for current user"
echo " 2 - Initial System Setup"
echo " 3 - Desktop Environment Installation"
echo " 4 - Phidget Setup and Dependencies"
echo " 5 - Touchscreen Configuration"
echo " 6 - Phidget Network Server Setup"
echo " 7 - Kiosk User Setup"
echo " 8 - GDM3 Autologin Configuration"
echo " 9 - SDDM Configuration (Alternative)"
echo " 10 - Chromium Kiosk Autostart Setup"
echo " 11 - Wayland and Kiosk Verification"
echo " 12 - Touch Gesture Configuration"
echo " 13 - KWin Tweaks and Final Setup"
echo " 14 - Power Management and Screen Blanking for kiosk user"
echo " 15 - Final System Restart"
echo " 16 - Remove notifications and enable auto updater"
echo " 17 - Disable error popups for kiosk user"
echo " 18 - USB Auto-Update Service and eventual reboot"
}
run_all_sections() {
echo "Running all sections in order..."
for i in $(seq 1 $MAX_SECTIONS); do
echo ""
echo "========================================="
echo "Starting Section $i"
echo "========================================="
section_$i
echo "Section $i completed."
done
echo ""
echo "All sections completed successfully!"
}
run_specific_section() {
local section_num=$1
if [[ $section_num -lt 1 || $section_num -gt $MAX_SECTIONS ]]; then
echo "Error: Section number must be between 1 and $MAX_SECTIONS"
exit 1
fi
echo "Running section $section_num only..."
echo "========================================="
echo "Starting Section $section_num"
echo "========================================="
section_$section_num
echo "Section $section_num completed successfully!"
}
# Initialize variables
SECTION_NUM=""
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-s|--section)
if [[ -z "$2" ]] || [[ "$2" =~ ^-.*$ ]]; then
echo "Error: Option -s requires a section number"
show_usage
exit 1
fi
SECTION_NUM="$2"
shift 2
;;
-h|--help)
show_usage
exit 0
;;
-a|--all)
# -a flag just ensures we run all sections (default behavior)
SECTION_NUM=""
shift
;;
*)
echo "Error: Unknown option: $1"
show_usage
exit 1
;;
esac
done
# Execute based on arguments
if [[ -n "$SECTION_NUM" ]]; then
# Validate that section number is numeric
if ! [[ "$SECTION_NUM" =~ ^[0-9]+$ ]]; then
echo "Error: Section number must be ana integer"
exit 1
fi
run_specific_section "$SECTION_NUM"
else
run_all_sections
fi
rm -rf /home/kiosk/.config/chromium/Default/Preferences
rm -rf /home/kiosk/.config/chromium/Singleton*
kwriteconfig6 --file startkderc --group General --key desktopSession empty
kwriteconfig6 --file ksmserverrc --group General --key loginMode emptySession