Migrate Display & Interaction menu; drop version number from installer filename; bump to v2.0.0

- menus/display.sh: second menu migrated onto lib/menu.sh + lib/config.sh,
  covering touch gesture mode, link navigation security, and the
  pause/keyboard/navigation button toggles (previously three separate
  Core Settings entries). Deliberately a different shape from Sites
  (toggle list vs. list CRUD) to exercise the framework more broadly.
  Wired into install.sh's top-level menu alongside Sites.

- Renamed ubuntu-based-kiosk-v1.0.3.sh -> ubuntu-based-kiosk.sh so the
  installer can be updated in place instead of growing a new
  version-numbered filename every release; released versions are now
  tracked via git history and the in-script changelog. Updated all
  Readme download/re-run commands accordingly. Older versioned files
  (ubuntu-based-kiosk-v*.sh, install_kiosk_*.sh) are left in place as
  archived releases.

- Bumped SCRIPT_VERSION to 2.0.0 (new script-level changelog entry) and
  the Readme version/changelog to match, given the new modular
  management path, the rename, and the two real bugs fixed along the
  way (settings clobbered on save, off-by-one in reorder).

Verified before moving on to the web admin work:
- Regression: re-ran the full Sites scratch-config test suite (add,
  edit, delete, reorder, home) - still clean, no invalid-input paths hit.
- New: scratch-config test for every display.sh action (touch mode,
  navigation security, all three toggles), confirming values persist
  through save/reload and that a previously-added site survives
  untouched across Display-menu saves.
- End-to-end: ran the real install.sh (not just sourced functions) as a
  genuine non-root, non-"kiosk" user with real sudo, driving actual menu
  input through Sites -> add a page -> Display -> toggle a setting ->
  exit. Confirmed final config.json on disk matches every action taken,
  and both guard clauses (run as root; no installed kiosk found) fire
  correctly.
This commit is contained in:
Claude
2026-08-18 15:48:21 +00:00
parent 21a0768c8c
commit c1370edc3e
4 changed files with 188 additions and 28 deletions
+26 -22
View File
@@ -1,6 +1,6 @@
# Ubuntu Based Kiosk # Ubuntu Based Kiosk
**Current Version:** 1.0.3 (check script header for latest version) **Current Version:** 2.0.0 (check script header for latest version)
**Built with Claude Sonnet 4.6 AI assistance** **Built with Claude Sonnet 4.6 AI assistance**
**License:** GPL v3 - Keep derivatives open source **License:** GPL v3 - Keep derivatives open source
**Repository:** https://github.com/outis1one/ubuntu-based-kiosk/ **Repository:** https://github.com/outis1one/ubuntu-based-kiosk/
@@ -47,12 +47,9 @@ Home/office kiosk for reusing old hardware, displaying:
# Configure WiFi if no ethernet available # Configure WiFi if no ethernet available
# Enable SSH during installation # Enable SSH during installation
# Download and run the latest installer # Download and run the installer
LATEST=$(curl -fsSL https://api.github.com/repos/outis1one/ubuntu-based-kiosk/contents \ wget https://github.com/outis1one/ubuntu-based-kiosk/raw/main/ubuntu-based-kiosk.sh
| grep -oP 'ubuntu-based-kiosk-v[0-9.]+\.sh' \ chmod +x ubuntu-based-kiosk.sh && ./ubuntu-based-kiosk.sh
| grep -v beta | sort -V | tail -1)
wget "https://github.com/outis1one/ubuntu-based-kiosk/raw/main/$LATEST"
chmod +x "$LATEST" && ./"$LATEST"
``` ```
The installer will guide you through configuration during setup. The installer will guide you through configuration during setup.
@@ -68,13 +65,10 @@ If the kiosk machine can't reach GitHub directly (no browser, restrictive proxy,
**On a machine with internet access:** **On a machine with internet access:**
```bash ```bash
# Option A: download just the latest installer script # Option A: download just the installer script
LATEST=$(curl -fsSL https://api.github.com/repos/outis1one/ubuntu-based-kiosk/contents \ wget https://github.com/outis1one/ubuntu-based-kiosk/raw/main/ubuntu-based-kiosk.sh
| grep -oP 'ubuntu-based-kiosk-v[0-9.]+\.sh' \
| grep -v beta | sort -V | tail -1)
wget "https://github.com/outis1one/ubuntu-based-kiosk/raw/main/$LATEST"
# Option B: download the whole repo as a ZIP (includes all installer versions and addon scripts) # Option B: download the whole repo as a ZIP (includes install.sh, addon scripts, and older archived installer versions)
wget https://github.com/outis1one/ubuntu-based-kiosk/archive/refs/heads/main.zip wget https://github.com/outis1one/ubuntu-based-kiosk/archive/refs/heads/main.zip
unzip main.zip unzip main.zip
``` ```
@@ -83,8 +77,8 @@ Copy the downloaded `.sh` file (or the extracted ZIP contents) to a USB drive, t
```bash ```bash
# Mount the USB drive and copy the script over, then: # Mount the USB drive and copy the script over, then:
chmod +x ubuntu-based-kiosk-v*.sh chmod +x ubuntu-based-kiosk.sh
./ubuntu-based-kiosk-v*.sh ./ubuntu-based-kiosk.sh
``` ```
The kiosk machine still needs a working internet connection (ethernet, or WiFi configured during Ubuntu install) for the script to complete. The kiosk machine still needs a working internet connection (ethernet, or WiFi configured during Ubuntu install) for the script to complete.
@@ -160,7 +154,7 @@ After running the addon it prints the full server-side setup, but the summary is
```bash ```bash
ssh user@kiosk-machine ssh user@kiosk-machine
./$(ls ubuntu-based-kiosk-v*.sh | sort -V | tail -1) ./ubuntu-based-kiosk.sh
# Addons → 5. Authelia Auto-Login # Addons → 5. Authelia Auto-Login
# Enter your Authelia URL, username, and password when prompted # Enter your Authelia URL, username, and password when prompted
``` ```
@@ -591,7 +585,7 @@ smb://WORKGROUP/COMPUTER/PrinterName
```bash ```bash
# Run installer script again to access menu # Run installer script again to access menu
./$(ls ubuntu-based-kiosk-v*.sh | sort -V | tail -1) ./ubuntu-based-kiosk.sh
# Menu structure: # Menu structure:
# 1. Core Settings - Sites, WiFi, schedules, passwords, full reinstall, complete uninstall # 1. Core Settings - Sites, WiFi, schedules, passwords, full reinstall, complete uninstall
@@ -606,7 +600,7 @@ The Easy Asterisk Intercom addon provides voice communication capabilities to yo
**Access the addon menu:** **Access the addon menu:**
```bash ```bash
./$(ls ubuntu-based-kiosk-v*.sh | sort -V | tail -1) ./ubuntu-based-kiosk.sh
# Select: 2) Addons # Select: 2) Addons
# Then: 4) Easy Asterisk Intercom # Then: 4) Easy Asterisk Intercom
``` ```
@@ -636,7 +630,7 @@ asterisk -rvvv
systemctl restart asterisk systemctl restart asterisk
# Configure intercom (rerun installation to update) # Configure intercom (rerun installation to update)
./$(ls ubuntu-based-kiosk-v*.sh | sort -V | tail -1) ./ubuntu-based-kiosk.sh
# Select: 2) Addons → 4) Easy Asterisk Intercom # Select: 2) Addons → 4) Easy Asterisk Intercom
``` ```
@@ -1020,7 +1014,7 @@ Full system cleanup that removes all kiosk components and restores the system to
**Access:** **Access:**
```bash ```bash
# Core Settings menu → option 11 # Core Settings menu → option 11
./$(ls ubuntu-based-kiosk-v*.sh | sort -V | tail -1) ./ubuntu-based-kiosk.sh
# Choose: Core Settings → Complete Uninstall # Choose: Core Settings → Complete Uninstall
``` ```
@@ -1186,6 +1180,10 @@ terminal menu and the web UI, so they can't drift apart).
delete, and reorder pages, and set the duration/timing mode delete, and reorder pages, and set the duration/timing mode
(auto-rotate / manual / hidden) and home page — as a working proof of (auto-rotate / manual / hidden) and home page — as a working proof of
concept for this approach. concept for this approach.
- `menus/display.sh`**Display & Interaction**: touch gesture mode,
link navigation security, and the on-screen pause/keyboard/navigation
button toggles. A second proof of concept covering a different menu
shape (settings toggles vs. the list CRUD in Sites).
- `install.sh` — entry point for the modular tool. Run it against an - `install.sh` — entry point for the modular tool. Run it against an
*already-installed* kiosk: *already-installed* kiosk:
```bash ```bash
@@ -1204,9 +1202,15 @@ menu at a time, and `install.sh` will eventually take over the whole
## Project Status & Future Plans ## Project Status & Future Plans
**Current Version:** 1.0.3 **Current Version:** 2.0.0
**Recent Updates (v1.0.3):** **Recent Updates (v2.0.0):**
- **Modular management path:** new `lib/menu.sh` (reusable numbered-menu framework: auto-numbered entries, `0` always exits/returns) and `lib/config.sh` (single load/save for `config.json`), with menus migrating into `menus/*.sh` one at a time — **Sites & Page Timing** and **Display & Interaction** are migrated so far. Run via `./install.sh` after cloning the repo, against an already-installed kiosk (see "Modular Management" below). Groundwork for the planned web-based GUI, which will share this same `lib/config.sh` layer.
- **Bug fix:** the old Sites menu could save `config.json` without first loading swipe/navigation/lockout settings, silently resetting them to script defaults.
- **Bug fix:** reordering sites had an off-by-one that left the moved site one slot short of the requested position.
- **Renamed installer:** the main script is now `ubuntu-based-kiosk.sh` (no version number in the filename), updated in place going forward. Released versions are tracked via git history and this changelog instead of the filename; older `ubuntu-based-kiosk-v*.sh` / `install_kiosk_*.sh` files remain in the repo as archived releases.
**Previous (v1.0.3):**
- **HDMI/external display mirroring:** any connected display beyond the primary (e.g. HDMI-out to a monitor/TV) is now mirrored automatically at the primary's exact resolution — generating a custom `cvt` mode if the external display doesn't natively list it — both at kiosk login/boot and live on plug/unplug via a new udev-triggered `kiosk-hotplug.service`. Previously the external output was left inactive even when detected by X, and would otherwise mirror at its own native resolution instead of matching the kiosk panel - **HDMI/external display mirroring:** any connected display beyond the primary (e.g. HDMI-out to a monitor/TV) is now mirrored automatically at the primary's exact resolution — generating a custom `cvt` mode if the external display doesn't natively list it — both at kiosk login/boot and live on plug/unplug via a new udev-triggered `kiosk-hotplug.service`. Previously the external output was left inactive even when detected by X, and would otherwise mirror at its own native resolution instead of matching the kiosk panel
- **HDMI audio routing:** audio now follows the same hotplug event — the default PipeWire sink automatically switches to the HDMI audio output when an external display is connected/mirrored, and back to the built-in sink when it's disconnected (`kiosk-audio-route.sh`) - **HDMI audio routing:** audio now follows the same hotplug event — the default PipeWire sink automatically switches to the HDMI audio output when an external display is connected/mirrored, and back to the built-in sink when it's disconnected (`kiosk-audio-route.sh`)
- **Package install:** installer now also installs `net-tools` and `ncdu` (alongside the already-installed `curl` and `git`) - **Package install:** installer now also installs `net-tools` and `ncdu` (alongside the already-installed `curl` and `git`)
+6 -4
View File
@@ -10,8 +10,8 @@
# lib/ and menus/, so a change to (say) the Sites menu can't accidentally # lib/ and menus/, so a change to (say) the Sites menu can't accidentally
# break WiFi setup or the uninstaller three thousand lines away. # break WiFi setup or the uninstaller three thousand lines away.
# #
# Today this only wires up the Sites & Page Timing menu (menus/sites.sh) # Today this wires up Sites & Page Timing (menus/sites.sh) and Display &
# as a working proof of concept. The rest of Core Settings/Addons/Advanced # Interaction (menus/display.sh). The rest of Core Settings/Addons/Advanced
# will move over the same way, one menus/*.sh file at a time. # will move over the same way, one menus/*.sh file at a time.
# #
# Usage (once the kiosk has already been installed): # Usage (once the kiosk has already been installed):
@@ -30,6 +30,8 @@ source "$SCRIPT_DIR/lib/menu.sh"
source "$SCRIPT_DIR/lib/config.sh" source "$SCRIPT_DIR/lib/config.sh"
# shellcheck source=menus/sites.sh # shellcheck source=menus/sites.sh
source "$SCRIPT_DIR/menus/sites.sh" source "$SCRIPT_DIR/menus/sites.sh"
# shellcheck source=menus/display.sh
source "$SCRIPT_DIR/menus/display.sh"
################################################################################ ################################################################################
# Preflight # Preflight
@@ -66,8 +68,8 @@ fi
################################################################################ ################################################################################
main_menu_builder() { main_menu_builder() {
MENU_LABELS=("Sites & Page Timing") MENU_LABELS=("Sites & Page Timing" "Display & Interaction")
MENU_HANDLERS=(sites_menu) MENU_HANDLERS=(sites_menu display_menu)
} }
main_menu_status() { main_menu_status() {
+137
View File
@@ -0,0 +1,137 @@
#!/bin/bash
################################################################################
# menus/display.sh - "Display & Interaction" menu.
#
# Second menu migrated off the old single-file installer, folding together
# three small settings screens that used to be separate Core Settings
# entries (Touch controls, Navigation security, Optional Features). All
# three are simple scalar/boolean fields on config.json, so this is a
# deliberately different shape from menus/sites.sh's list CRUD - a toggle
# list where each entry shows its current value and flips/edits itself,
# saving immediately (same immediate-save pattern as Sites, so behavior
# stays consistent no matter which menu you're in).
#
# Depends on: lib/menu.sh, lib/config.sh being sourced first.
################################################################################
display_status() {
echo "Touch gesture mode: $SWIPE_MODE"
echo "Link navigation: $ALLOW_NAVIGATION"
echo "Pause button: $(display_onoff "$ENABLE_PAUSE_BUTTON")"
echo "Keyboard button: $(display_onoff "$ENABLE_KEYBOARD_BUTTON")"
echo "Navigation button: $(display_onoff "$ENABLE_NAV_BUTTON")"
}
display_onoff() {
[[ "$1" == "true" ]] && echo "ON" || echo "OFF"
}
display_menu_builder() {
MENU_LABELS=(
"Touch gesture mode (currently: $SWIPE_MODE)"
"Link navigation security (currently: $ALLOW_NAVIGATION)"
"Toggle pause button (currently: $(display_onoff "$ENABLE_PAUSE_BUTTON"))"
"Toggle on-screen keyboard button (currently: $(display_onoff "$ENABLE_KEYBOARD_BUTTON"))"
"Toggle navigation/help button (currently: $(display_onoff "$ENABLE_NAV_BUTTON"))"
)
MENU_HANDLERS=(
action_set_touch_mode
action_set_navigation_security
action_toggle_pause_button
action_toggle_keyboard_button
action_toggle_nav_button
)
}
display_menu() {
load_existing_config
run_menu "DISPLAY & INTERACTION" display_menu_builder display_status
}
################################################################################
# Touch gesture mode
################################################################################
action_set_touch_mode() {
echo
echo "DUAL-DIRECTION (recommended for touchscreens):"
echo " 2-finger swipe = switch pages, 1-finger swipe = navigate within page"
echo "STANDARD (simpler):"
echo " 2-finger swipe = switch pages only, 1-finger swipes do nothing"
echo
local default
[[ "$SWIPE_MODE" == "dual" ]] && default="y" || default="n"
if ask_yes_no "Use dual-direction mode?" "$default"; then
SWIPE_MODE="dual"
else
SWIPE_MODE="standard"
fi
log_success "Touch mode: $SWIPE_MODE"
save_config
}
################################################################################
# Navigation security
################################################################################
action_set_navigation_security() {
echo
echo " r) restricted - only the loaded URL, no link clicking"
echo " s) same-origin - can click links within the same domain (recommended)"
echo " o) open - can click any link, browse anywhere"
echo
local choice
read -r -p "(r)estricted / (s)ame-origin / (o)pen [${ALLOW_NAVIGATION}]: " choice
case "${choice,,}" in
r) ALLOW_NAVIGATION="restricted" ;;
o) ALLOW_NAVIGATION="open" ;;
s) ALLOW_NAVIGATION="same-origin" ;;
"") ;; # keep current value
*) log_warning "Unrecognized choice, keeping '$ALLOW_NAVIGATION'" ;;
esac
log_success "Link navigation: $ALLOW_NAVIGATION"
save_config
}
################################################################################
# On-screen button toggles
################################################################################
action_toggle_pause_button() {
if [[ "$ENABLE_PAUSE_BUTTON" == "true" ]]; then
ENABLE_PAUSE_BUTTON="false"
log_warning "Pause button disabled"
else
ENABLE_PAUSE_BUTTON="true"
log_success "Pause button enabled"
fi
save_config
}
action_toggle_keyboard_button() {
if [[ "$ENABLE_KEYBOARD_BUTTON" == "true" ]]; then
ENABLE_KEYBOARD_BUTTON="false"
log_warning "On-screen keyboard button disabled"
else
ENABLE_KEYBOARD_BUTTON="true"
log_success "On-screen keyboard button enabled"
fi
save_config
}
action_toggle_nav_button() {
if [[ "$ENABLE_NAV_BUTTON" == "true" ]]; then
ENABLE_NAV_BUTTON="false"
log_warning "Navigation/help button disabled"
else
ENABLE_NAV_BUTTON="true"
log_success "Navigation/help button enabled"
fi
save_config
}
@@ -1,8 +1,25 @@
#!/bin/bash #!/bin/bash
################################################################################ ################################################################################
### Ubuntu Based Kiosk v1.0.3 ### ### Ubuntu Based Kiosk v2.0.0 ###
################################################################################ ################################################################################
# #
# RELEASE v2.0.0 - Modular Management & Unversioned Filename
# - New git-clone-based management path: lib/menu.sh (reusable numbered-menu
# framework) + lib/config.sh (single config.json load/save) + menus/*.sh,
# run via ./install.sh against an already-installed kiosk. Sites & Page
# Timing and Display & Interaction are migrated; the rest of Core
# Settings/Addons/Advanced still live here and will move over the same
# way, one menu at a time. See Readme.md ("Modular Management").
# - Fixed: the old Sites menu could save config.json without first loading
# swipe/navigation/lockout settings, silently resetting them to defaults.
# - Fixed: reordering sites had an off-by-one that left the moved site one
# slot short of the requested position.
# - This script is now distributed as ubuntu-based-kiosk.sh (no version
# number in the filename) so it can be updated in place; released
# versions are tracked via git history and this changelog instead.
# Older ubuntu-based-kiosk-v*.sh / install_kiosk_*.sh files remain in the
# repo as archived releases.
#
# RELEASE v1.0.3 - Touch Screen Detection & Upgrade Reliability # RELEASE v1.0.3 - Touch Screen Detection & Upgrade Reliability
# - Authelia auto-login addon (Addons menu → 5) # - Authelia auto-login addon (Addons menu → 5)
# Password encrypted with AES-256-CBC keyed from /etc/machine-id # Password encrypted with AES-256-CBC keyed from /etc/machine-id
@@ -68,7 +85,7 @@ set -euo pipefail
### SECTION 1: CONSTANTS & GLOBALS ### SECTION 1: CONSTANTS & GLOBALS
################################################################################ ################################################################################
SCRIPT_VERSION="1.0.3" SCRIPT_VERSION="2.0.0"
# Resolve the real path to this script file. # Resolve the real path to this script file.
# When piped (curl|bash or wget|bash), BASH_SOURCE[0] is a pipe descriptor, # When piped (curl|bash or wget|bash), BASH_SOURCE[0] is a pipe descriptor,