diff --git a/chromium_change_homepage.md b/chromium_change_homepage.md
new file mode 100644
index 0000000..8bd1c75
--- /dev/null
+++ b/chromium_change_homepage.md
@@ -0,0 +1,24 @@
+---
+title: "Chromium - Skift startside"
+parent: "Kiosk"
+source: os2borgerpc-scripts/os2borgerpc/os2borgerpc_kiosk/chromium_change_homepage.sh
+parameters:
+ - name: "URL"
+ type: "string"
+ default: null
+ mandatory: true
+compatibility:
+ - "22.04"
+ - "Kiosk"
+---
+
+## Beskrivelse
+Skifter startside i Chromium.
+
+Hvis du oplever scriptet fejle, genkør da OS2borgerPC Kiosk - Autostart Chromium før dette.
+
+Dette script er blevet testet og virker på Ubuntu 22.04.
+
+## Parametre
+1: Hvilken URL der skal være den nye startside.
+
diff --git a/chromium_delete_profile.md b/chromium_delete_profile.md
new file mode 100644
index 0000000..1045ce4
--- /dev/null
+++ b/chromium_delete_profile.md
@@ -0,0 +1,14 @@
+---
+title: "Chromium Ryd Cache NU"
+parent: "Kiosk"
+source: os2borgerpc-scripts/os2borgerpc/os2borgerpc_kiosk/chromium_delete_profile.sh
+parameters:
+compatibility:
+ - "22.04"
+ - "Kiosk"
+---
+
+## Beskrivelse
+Dette script sletter Chromiums profil (inkl. cache) ÉN GANG, hvilket nulstiller browserens historik.
+
+Dette script er blevet testet og virker på Ubuntu 22.04.
\ No newline at end of file
diff --git a/desktop_program_shortcut.md b/desktop_program_shortcut.md
new file mode 100644
index 0000000..e3a2387
--- /dev/null
+++ b/desktop_program_shortcut.md
@@ -0,0 +1,37 @@
+---
+title: "Genvej til program fra skrivebordet"
+parent: "Desktop"
+source: os2borgerpc-scripts/os2borgerpc/desktop/desktop_program_shortcut.sh
+parameters:
+ - name: "Tilføj programmet?"
+ type: "boolean"
+ default: null
+ mandatory: false
+ - name: "Program"
+ type: "string"
+ default: null
+ mandatory: true
+compatibility:
+ - "22.04"
+ - "BorgerPC"
+---
+
+## Beskrivelse
+Tilføjer/Fjerner en genvej til/fra et program på skrivebordet.
+
+Log ud efter kørsel.
+
+BEMÆRK: Før genveje på skrivebordet fungerer, skal scriptet "Desktop - Aktiver genveje" også være kørt. Dette script er dog allerede indbygget i de nyere images.
+
+Dette script er blevet testet og virker på Ubuntu 22.04.
+
+## Parametre
+1: Tilføj programmet:
+ Sæt hak: Programmet tilføjes til Skrivebordet
+ Fjern hak: Programmet fjernes fra Skrivebordet (hvis det ligger der)
+2: Programnavn: Det program du ønsker at tilføje eller slette fra skrivebordet. Programnavnet skal matche navnet på en genvej til et installeret program.
+ Navnet er næsten altid med små bogstaver, og mellemrum erstattet af bindestreg.
+ Eksempler: firefox, google-chrome, microsoft-edge, simple-scan, yelp, libreoffice-impress, libreoffice-writer, libreoffice-calc
+
+Hvis du ikke kender program-navnet præcist, kan du bruge scriptet "Desktop - Vis programliste".
+
diff --git a/desktop_shortcut_to_directory.md b/desktop_shortcut_to_directory.md
new file mode 100644
index 0000000..eb2085c
--- /dev/null
+++ b/desktop_shortcut_to_directory.md
@@ -0,0 +1,33 @@
+---
+title: "Genvej til valgfri mappe fra skrivebordet"
+parent: "Desktop"
+source: os2borgerpc-scripts/os2borgerpc/desktop/desktop_shortcut_to_directory.sh
+parameters:
+ - name: "Tilføj?"
+ type: "boolean"
+ default: null
+ mandatory: false
+ - name: "Sti til mappe"
+ type: "string"
+ default: null
+ mandatory: true
+ - name: "Navn på genvej"
+ type: "string"
+ default: null
+ mandatory: true
+compatibility:
+ - "22.04"
+ - "BorgerPC"
+---
+
+## Beskrivelse
+Opretter en genvej til en valgfri mappe på Skrivebordet.
+Dette script er blevet testet og virker på Ubuntu 22.04.
+
+## Parametre
+1. Stien til mappen (eksempelvis: "/home/user/Dokumenter" )
+2. Navnet på genvejen (eksempelvis: "Skannede filer" )
+...begge uden citationstegnene rundt om.
+
+Bemærk at ift. stien, så har store og små bogstaver en betydning!
+
diff --git a/network_printer_add_no_ppd.md b/network_printer_add_no_ppd.md
new file mode 100644
index 0000000..5db14d1
--- /dev/null
+++ b/network_printer_add_no_ppd.md
@@ -0,0 +1,56 @@
+---
+title: "Tilføj netværksprinter"
+parent: "Printer"
+source: os2borgerpc-scripts/os2borgerpc/printer/network_printer_add_no_ppd.sh
+parameters:
+ - name: "Navn (OBS: INGEN ÆØÅ, mellemrum eller apostrofer)"
+ type: "string"
+ default: null
+ mandatory: true
+ - name: "IP-adresse"
+ type: "string"
+ default: null
+ mandatory: true
+ - name: "Beskrivelse / Placering (INGEN ÆØÅ)"
+ type: "string"
+ default: null
+ mandatory: true
+ - name: "Protokol"
+ type: "string"
+ default: "ipp"
+ mandatory: false
+ - name: "Sæt som standard?"
+ type: "boolean"
+ default: null
+ mandatory: false
+compatibility:
+ - "22.04"
+ - "BorgerPC"
+---
+
+## Beskrivelse
+Tilføjer en netværksprinter.
+
+Dette script er blevet testet og virker på Ubuntu 22.04.
+
+## Parametre
+* Printernavn - ingen Æ, Ø og Å, ingen mellemrum og ingen apostrofer
+* IP-adresse
+* Beskrivelse / Placering - denne kan godt indeholde mellemrum
+* Protokol - vi anbefaler at afprøve ipp først, medmindre du ved, at denne protokol ikke er understøttet. Andre muligheder er eksempelvis "socket".
+* Sæt som standard? Afgører om printeren også sættes som standard-printer eller ej. Det vil typisk sige, om den er forvalgt i diverse programmer, når der printes.
+
+EFTER kørsel af dette script, kan du evt. ændre indstillinger på printeren med scriptet "Printer - Sæt printer-indstillinger".
+
+NÆRMERE INFO OMKRING PROTOKOLLER:
+Scriptet "Vis printer-liste" kan give en idé om hvilke protokoller en printer understøtter, men det er ikke altid, de er til at identificere. Den sikreste metode for at afgøre hvilke protokoller der understøttes, er derfor at kigge i printerens dokumentation.
+
+IPP:
+IPP kører over TCP og bruger normalt port 631.
+Nærmere info: https://en.wikipedia.org/wiki/Internet_Printing_Protocol
+
+Socket/Appscoket/Jetdirect
+http://www.cups.org/doc/network.html
+https://wiki.debian.org/CUPSPrintQueues#appsock
+
+
diff --git a/network_printer_add_ppd.md b/network_printer_add_ppd.md
new file mode 100644
index 0000000..aaa0066
--- /dev/null
+++ b/network_printer_add_ppd.md
@@ -0,0 +1,64 @@
+---
+title: "Tilføj netværksprinter (PPD-fil skal angives)"
+parent: "Printer"
+source: os2borgerpc-scripts/os2borgerpc/printer/network_printer_add_ppd.sh
+parameters:
+ - name: "Navn (OBS: INGEN ÆØÅ, mellemrum eller apostrofer)"
+ type: "string"
+ default: null
+ mandatory: true
+ - name: "IP-adresse"
+ type: "string"
+ default: null
+ mandatory: true
+ - name: "Beskrivelse / Placering (INGEN ÆØÅ)"
+ type: "string"
+ default: null
+ mandatory: true
+ - name: "PPD-fil"
+ type: "file"
+ default: null
+ mandatory: true
+ - name: "Protokol"
+ type: "string"
+ default: "ipp"
+ mandatory: false
+ - name: "Sæt som standard?"
+ type: "boolean"
+ default: null
+ mandatory: false
+compatibility:
+ - "22.04"
+ - "BorgerPC"
+---
+
+## Beskrivelse
+Tilføj ny netværksprinter.
+
+Dette script er blevet testet og virker på Ubuntu 22.04.
+
+BEMÆRK: Medmindre du har særlige grunde, der kræver en PPD, anbefaler vi i stedet at tilføje printere med scriptet "Tilføj netværksprinter", som ikke kræver en PPD.
+
+## Parametre
+* Printernavn - ingen Æ, Ø og Å og ingen mellemrum
+* IP-adresse
+* Beskrivelse / placering - denne kan godt indeholde mellemrum
+* Printer-driver (PPD-fil)
+* Protokol - protokollen "socket", også kaldet "appsocket" og "jetdirect" er forvalgt, da det er den protokol dette script historisk har brugt.
+ Hvis scriptet "Tilføj netværksprinter", som har IPP-protokollen forvalgt, ikke virker for den pågældende printer, anbefaler vi at afprøve at køre dette script med "socket".
+* Sæt som standard? Afgører om printeren også sættes som standard-printer eller ej. Det vil typisk sige, om den er forvalgt i diverse programmer, når der printes.
+
+EFTER kørsel af dette script, kan du evt. ændre indstillinger på printeren med scriptet "Printer - Sæt printer-indstillinger".
+
+NÆRMERE INFO OMKRING PROTOKOLLER:
+Scriptet "Vis printer-liste" kan give en idé om hvilke protokoller en printer understøtter, men det er ikke altid, de er til at identificere. Den sikreste metode for at afgøre hvilke protokoller der understøttes, er derfor at kigge i printerens dokumentation.
+
+IPP:
+IPP kører over TCP og bruger normalt port 631.
+Nærmere info: https://en.wikipedia.org/wiki/Internet_Printing_Protocol
+
+Socket/Appscoket/Jetdirect
+http://www.cups.org/doc/network.html
+https://wiki.debian.org/CUPSPrintQueues#appsock
+
+
diff --git a/scripts/chromium_change_homepage.sh b/scripts/chromium_change_homepage.sh
new file mode 100755
index 0000000..afc6326
--- /dev/null
+++ b/scripts/chromium_change_homepage.sh
@@ -0,0 +1,11 @@
+#! /usr/bin/env sh
+
+NEW_URL="$1"
+
+if ! get_os2borgerpc_config os2_product | grep --quiet kiosk; then
+ echo "Dette script er ikke designet til at blive anvendt på en regulær OS2borgerPC-maskine."
+ exit 1
+fi
+
+CHROMIUM_SCRIPT='/usr/share/os2borgerpc/bin/start_chromium.sh'
+sed --in-place --regexp-extended "s%(IURL=\").*%\1$NEW_URL\"%" $CHROMIUM_SCRIPT
diff --git a/scripts/chromium_delete_profile.sh b/scripts/chromium_delete_profile.sh
new file mode 100755
index 0000000..22685d0
--- /dev/null
+++ b/scripts/chromium_delete_profile.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+if ! get_os2borgerpc_config os2_product | grep --quiet kiosk; then
+ echo "Dette script er ikke designet til at blive anvendt på en regulær OS2borgerPC-maskine."
+ exit 1
+fi
+
+rm -r /home/chrome/snap/chromium/common/chromium/Default
diff --git a/scripts/desktop_program_shortcut.sh b/scripts/desktop_program_shortcut.sh
new file mode 100755
index 0000000..0bf3898
--- /dev/null
+++ b/scripts/desktop_program_shortcut.sh
@@ -0,0 +1,79 @@
+#! /usr/bin/env sh
+
+# Adds/Removes programs from the desktop in Ubuntu 20.04
+# Author: mfm@magenta.dk
+#
+# This script has been updated to automatically detect the name of
+# the 'Desktop' directory in the chosen locale.
+#
+# Arguments:
+# 1: Use a boolean to decide whether to add or remove the program shortcut
+# 2: This argument should specify the name of a program (.desktop-file)
+# under /usr/share/applications/ or /var/lib/snapd/desktop/applications/
+# This parameter IS case-sensitive as some applications have
+# capitalized characters in their filename.
+
+ADD="$1"
+PROGRAM="$2"
+
+if get_os2borgerpc_config os2_product | grep --quiet kiosk; then
+ echo "Dette script er ikke designet til at blive anvendt på en kiosk-maskine."
+ exit 1
+fi
+
+# Determine the name of the user desktop directory. This is done via xdg-user-dir,
+# which checks the /home/user/.config/user-dirs.dirs file. To ensure this file exists,
+# we run xdg-user-dirs-update, which generates it based on the environment variable
+# LANG. This variable is empty in lightdm so we first export it
+# based on the value stored in /etc/default/locale
+export "$(grep LANG= /etc/default/locale | tr -d '"')"
+runuser -u user xdg-user-dirs-update
+DESKTOP=$(basename "$(runuser -u user xdg-user-dir DESKTOP)")
+
+SHADOW_DESKTOP="/home/.skjult/$DESKTOP"
+SNAP_DESKTOP_FILE_PATH="/var/lib/snapd/desktop/applications"
+APT_DESKTOP_FILE_PATH="/usr/share/applications"
+
+# TODO?: Make it replace all desktop icons which are copies with symlinks?
+
+mkdir --parents "$SHADOW_DESKTOP"
+
+# They can type in chrome, but the desktop file is called google-chrome
+# They can type in edge, but the desktop file is called microsoft-edge
+# They can also type in okular, but the desktop file is called okularApplication_kimgio
+if [ "$PROGRAM" = "chrome" ]; then
+ PROGRAM="google-chrome"
+elif [ "$PROGRAM" = "edge" ]; then
+ PROGRAM="microsoft-edge"
+elif [ "$PROGRAM" = "okular" ]; then
+ PROGRAM="okularApplication_kimgio"
+fi
+
+if [ "$ADD" = 'True' ]; then
+ if [ -f "$SNAP_DESKTOP_FILE_PATH/${PROGRAM}_$PROGRAM.desktop" ]; then
+ ORIGINAL_FILE=$SNAP_DESKTOP_FILE_PATH/${PROGRAM}_$PROGRAM.desktop
+ else
+ ORIGINAL_FILE=$APT_DESKTOP_FILE_PATH/$PROGRAM.desktop
+ fi
+ # Check that the program actually exists and exit if it doesn't
+ if [ ! -f "$ORIGINAL_FILE" ]; then
+ echo "The chosen program name did not match any installed programs. Exiting."
+ exit 1
+ fi
+ # Remove it first as it may be a copy and not symlink (ln --force can't overwrite regular files)
+ rm --force "$SHADOW_DESKTOP/$(basename "$ORIGINAL_FILE")"
+
+ # Ensure that the local copy exists
+ LOCAL_FILE_COPY="/home/.skjult/.local/share/applications/$(basename "$ORIGINAL_FILE")"
+ mkdir --parents "$(dirname "$LOCAL_FILE_COPY")"
+ if [ ! -f "$LOCAL_FILE_COPY" ]; then
+ cp "$ORIGINAL_FILE" "$LOCAL_FILE_COPY"
+ fi
+
+ ln --symbolic --force "$LOCAL_FILE_COPY" "$SHADOW_DESKTOP"/
+else
+ if [ -f "$SHADOW_DESKTOP/${PROGRAM}_$PROGRAM.desktop" ]; then
+ PROGRAM=${PROGRAM}_$PROGRAM
+ fi
+ rm --force "$SHADOW_DESKTOP/$PROGRAM.desktop"
+fi
diff --git a/scripts/desktop_shortcut_to_directory.sh b/scripts/desktop_shortcut_to_directory.sh
new file mode 100755
index 0000000..f1bcb9c
--- /dev/null
+++ b/scripts/desktop_shortcut_to_directory.sh
@@ -0,0 +1,39 @@
+#! /usr/bin/env sh
+
+# Places a shortcut on the Desktop to any directory on the file system
+#
+# Parameters:
+# 1: Whether to add or remove the shortcut
+# 2: The path to the directory you want a shortcut to
+# 3: The name of the shortcut on the Desktop
+
+set -ex
+
+if get_os2borgerpc_config os2_product | grep --quiet kiosk; then
+ echo "Dette script er ikke designet til at blive anvendt på en kiosk-maskine."
+ exit 1
+fi
+
+ADD="$1"
+DIRECTORY="$2"
+SHORTCUT_NAME="$3"
+
+# Determine the name of the user desktop directory. This is done via xdg-user-dir,
+# which checks the /home/user/.config/user-dirs.dirs file. To ensure this file exists,
+# we run xdg-user-dirs-update, which generates it based on the environment variable
+# LANG. This variable is empty in lightdm so we first export it
+# based on the value stored in /etc/default/locale
+export "$(grep LANG= /etc/default/locale | tr -d '"')"
+runuser -u user xdg-user-dirs-update
+DESKTOP=$(basename "$(runuser -u user xdg-user-dir DESKTOP)")
+
+SHADOW_DESKTOP="/home/.skjult/$DESKTOP"
+
+mkdir --parents "$SHADOW_DESKTOP"
+
+if [ "$ADD" = "True" ]; then
+ # Note: "ln" doesn't care if the destination ($DIRECTORY) exists
+ ln --symbolic --force "$DIRECTORY" "$SHADOW_DESKTOP/$SHORTCUT_NAME"
+else
+ rm "$SHADOW_DESKTOP/$SHORTCUT_NAME"
+fi
diff --git a/scripts/install_okular_and_set_as_standard_pdf_reader.sh b/scripts/install_okular_and_set_as_standard_pdf_reader.sh
new file mode 100755
index 0000000..327139d
--- /dev/null
+++ b/scripts/install_okular_and_set_as_standard_pdf_reader.sh
@@ -0,0 +1,195 @@
+#!/usr/bin/env bash
+
+ENABLE=$1
+
+set -x
+
+if get_os2borgerpc_config os2_product | grep --quiet kiosk; then
+ echo "Dette script er ikke designet til at blive anvendt på en kiosk-maskine."
+ exit 1
+fi
+
+export DEBIAN_FRONTEND=noninteractive
+GLOBAL_MIME_FILE="/usr/share/applications/defaults.list"
+OKULAR_CONFIG_1="/home/.skjult/.config/okularpartrc"
+OKULAR_CONFIG_2="/home/.skjult/.local/share/kxmlgui5/okular/part.rc"
+
+cleanup_mime_file() {
+ MIME_FILE=$1
+
+ sed --in-place "\@application/pdf@d" "$MIME_FILE"
+ sed --in-place "\@application/x-bzpdf@d" "$MIME_FILE"
+ sed --in-place "\@application/x-gzpdf@d" "$MIME_FILE"
+ sed --in-place "\@application/x-xzpdf@d" "$MIME_FILE"
+}
+
+make_okular_default() {
+
+ cleanup_mime_file $GLOBAL_MIME_FILE
+
+ cat <<- EOF >> $GLOBAL_MIME_FILE
+ application/pdf=okularApplication_kimgio.desktop;
+ application/x-bzpdf=okularApplication_kimgio.desktop;
+ application/x-gzpdf=okularApplication_kimgio.desktop;
+ application/x-xzpdf=okularApplication_kimgio.desktop;
+ EOF
+}
+
+apt-get update --assume-yes
+
+# Clean up from earlier versions of this script
+PREVIOUS_MIME_FILE="/home/.skjult/.config/mimeapps.list"
+[ -f $PREVIOUS_MIME_FILE ] && cleanup_mime_file $PREVIOUS_MIME_FILE
+
+if [ "$ENABLE" = "True" ]; then
+
+ apt-get remove --assume-yes evince # Unfortunately removing this alone does not mean Okular becomes default. Instead LibreOffice Draw becomes default.
+ apt-get install --assume-yes okular
+
+ make_okular_default
+
+ cat <<- EOF > $OKULAR_CONFIG_1
+
+ [General]
+ ttsEngine=flite
+
+ [Reviews]
+ AnnotationTools=1,2,3,4,5,6,7,8,9,
+
+ EOF
+
+ mkdir --parents "$(dirname $OKULAR_CONFIG_2)"
+
+ cat <<- EOF > $OKULAR_CONFIG_2
+
+
+
+
+
+
+
+
+ &Go
+
+
+
+
+
+
+
+
+
+
+
+
+ &Bookmarks
+
+
+
+
+
+
+
+
+ &Tools
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ &Settings
+
+
+
+
+
+
+ &Help
+
+
+
+
+ Main Toolbar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ EOF
+else
+ apt-get remove --assume-yes okular
+ apt-get install --assume-yes evince # Hopefully this means evince is automatically set as the default reader for its types, so we don't have to handle that manually
+ rm --force $OKULAR_CONFIG_1 $OKULAR_CONFIG_2
+fi
diff --git a/scripts/network_printer_add_no_ppd.sh b/scripts/network_printer_add_no_ppd.sh
new file mode 100755
index 0000000..d87a0a4
--- /dev/null
+++ b/scripts/network_printer_add_no_ppd.sh
@@ -0,0 +1,20 @@
+#! /usr/bin/env sh
+
+set -ex
+
+# lpadmin doesn't like spaces
+NAME="$(echo "$1" | tr ' ' '_')"
+HOST="$2"
+DESCRIPTION="$3"
+PROTOCOL="${4:-ipp}"
+SET_STANDARD="$5"
+
+[ "$PROTOCOL" = "ipp" ] && ENABLE_IPP_EVERYWHERE="-m everywhere"
+
+# shellcheck disable=SC2086 # We want word-splitting in the last argument
+lpadmin -p "$NAME" -v "$PROTOCOL://$HOST" -D "$DESCRIPTION" -L "$DESCRIPTION" -E $ENABLE_IPP_EVERYWHERE
+
+if [ "$SET_STANDARD" = "True" ]; then
+ # Set the printer as standard printer
+ lpadmin -d "$NAME" && lpstat -d
+fi
diff --git a/scripts/network_printer_add_ppd.sh b/scripts/network_printer_add_ppd.sh
new file mode 100755
index 0000000..38326bc
--- /dev/null
+++ b/scripts/network_printer_add_ppd.sh
@@ -0,0 +1,18 @@
+#! /usr/bin/env sh
+
+set -ex
+
+# lpadmin doesn't like spaces
+NAME="$(echo "$1" | tr ' ' '_')"
+HOST="$2"
+DESCRIPTION="$3"
+DRIVER="$4"
+PROTOCOL="${5:-socket}"
+SET_STANDARD="$6"
+
+lpadmin -p "$NAME" -v "$PROTOCOL://$HOST" -D "$DESCRIPTION" -E -P "$DRIVER" -L "$DESCRIPTION"
+
+if [ "$SET_STANDARD" = "True" ]; then
+ # Set the printer as standard printer
+ lpadmin -d "$NAME" && lpstat -d
+fi
diff --git a/scripts/wm_keyboard_hide_button.sh b/scripts/wm_keyboard_hide_button.sh
new file mode 100755
index 0000000..a23d905
--- /dev/null
+++ b/scripts/wm_keyboard_hide_button.sh
@@ -0,0 +1,255 @@
+#! /usr/bin/env sh
+
+# DESCRIPTION:
+# Add a button to show/hide the onscreen keyboard
+# ...or more precisely it toggles fullscreen on the browser
+# Intended for OS2borgerPC Kiosk.
+#
+# ARGUMENTS:
+# 1: Whether to install / uninstall the button
+# 2: The name of the process (e.g. a browser) that should be full screened
+# 3: The background image to use for the GTK window (keyboard toggle button)
+#
+# PREREQUISITES:
+# 1. os2borgerpc_kiosk/os2borgerpc_kiosk/chromium_install.sh
+# 2. os2borgerpc_kiosk/os2borgerpc_kiosk/chromium_setup.sh
+# 3. os2borgerpc_kiosk/os2borgerpc_kiosk/wm_keyboard_install.sh
+#
+# AUTHOR: mfm@magenta.dk
+
+set -ex
+
+if ! get_os2borgerpc_config os2_product | grep --quiet kiosk; then
+ echo "Dette script er ikke designet til at blive anvendt på en regulær OS2borgerPC-maskine."
+ exit 1
+fi
+
+### SETTINGS ###
+
+lower() {
+ echo "$@" | tr '[:upper:]' '[:lower:]'
+}
+
+[ $# != 4 ] \
+ && printf "This script needs exactly four arguments which it wasn't given. Exiting." \
+ && exit 1
+
+ACTIVATE=$1
+# Needs to be a valid process name - technically it can be any program
+# Tested values: chromium
+BROWSER="$(lower "$2")"
+BUTTON_ICON_PATH="$3"
+BUTTON_Y_OFFSET="$4"
+
+# The input is just a number, but if it's positive we want a "+" prepended for the calculation
+[ "$BUTTON_Y_OFFSET" -ge 0 ] && BUTTON_Y_OFFSET="+ $BUTTON_Y_OFFSET"
+
+CUSER=chrome
+BSPWM_CONFIG="/home/$CUSER/.config/bspwm/bspwmrc"
+
+SCRIPTS_BASE_PATH=/usr/share/os2borgerpc/bin/keyboard-button
+# Doesn't work if this is lowercase btn.py.
+# The bspc rule supposed to match it no longer matches, so seemingly something uppercases the first letter for window
+# name
+BUTTON_WINDOW_TITLE="Btn.py"
+# Doesn't need to be the same but why not
+BUTTON_SCRIPT="$BUTTON_WINDOW_TITLE"
+BSPWM_ADD_BUTTON_SCRIPT="bspwm_add_button.sh"
+BUTTON_MOVE_SCRIPT="button_move.sh"
+FULLSCREEN_TOGGLE_SCRIPT="toggle_fullscreen.sh"
+BUTTON_STYLING_CSS_FILE="btn.css"
+
+export DEBIAN_FRONTEND=noninteractive
+
+if [ "$ACTIVATE" = 'True' ]; then
+
+ ### SCRIPT PROPER ###
+
+ # Install some dependencies
+
+ # Could also use cut or something so jq isn't needed
+ apt-get install --assume-yes xdotool jq fonts-noto-color-emoji
+
+ # Requirements: python gi
+
+ mkdir --parents "$SCRIPTS_BASE_PATH"
+ cd "$SCRIPTS_BASE_PATH" || printf 'Fejl i initialiseringen' || exit 1
+
+ ### FULLSCREEN TOGGLING BUTTON ###
+
+ # To style a button (e.g. change its background color) we need a CSS file:
+ cat <<- EOF > $SCRIPTS_BASE_PATH/$BUTTON_STYLING_CSS_FILE
+ /* Turn a caret into an arrow down */
+ .our-button { background: transparent; color: white; border: none; font-size: 50px; margin: 0;}
+ .our-window { border: none; margin: 0; opacity: 0.5; background: url("$SCRIPTS_BASE_PATH/bg.png"); background-size: contain; }
+ /*.our-window { border: none; margin: 0; opacity: 0.5; background: black; }*/
+ EOF
+
+ # Note that if the font-size is specified in the CSS, the size here is of
+ # no importance to the button
+ mkdir --parents /home/$CUSER/.config/gtk-3.0
+ cat <<- EOF > /home/$CUSER/.config/gtk-3.0/settings.ini
+ [Settings]
+ gtk-font-name = Noto Color Emoji 15
+ EOF
+
+ cat <<- EOF > /home/$CUSER/.config/gtk-3.0/gtk.css
+ .window-frame {
+ box-shadow: none;
+ margin: 0;
+ }
+ EOF
+
+ # Move the uploaded bg image to the location where we load it from
+ cp "$BUTTON_ICON_PATH" $SCRIPTS_BASE_PATH/bg.png
+
+ cat <<- EOF > "$BUTTON_SCRIPT"
+ #! /usr/bin/env python3
+
+ # "Rules for positioning and sizing floating windows":
+ # https://github.com/baskerville/bspwm/issues/263
+ # Other resources used:
+ # https://www.youtube.com/watch?v=rVjGiOiDl4M
+ # https://wiki.archlinux.org/title/GTK#Basic_theme_configuration
+ # https://mail.gnome.org/archives/gtk-app-devel-list/2016-August/msg00021.html
+
+ # For calling the script that toggles fullscreen for firefox
+ from subprocess import call
+
+ # For the GTK button
+ import gi
+ gi.require_version('Gtk', '3.0')
+ from gi.repository import Gtk, Gdk, Gio # noqa: E402
+
+ WIDTH = 57
+ HEIGHT = 5
+
+
+ # Customize Gtk.window to have our keyboard button
+ class MyWindow(Gtk.Window):
+ # Just a custom function to gather all the logic to actually read a CSS file
+ def setup_css(self):
+ provider = Gtk.CssProvider()
+ provider.load_from_file(Gio.File.new_for_path("$SCRIPTS_BASE_PATH/$BUTTON_STYLING_CSS_FILE"))
+ Gtk.StyleContext.add_provider_for_screen(
+ Gdk.Screen.get_default(),
+ provider,
+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
+
+ def __init__(self):
+ Gtk.Window.__init__(self, title="Hello")
+ self.setup_css()
+ # Text to appear on the button
+ #self.btn = Gtk.Button(label="^")
+ # Note: To support emojis install fx. fonts-noto-color-emoji
+ #self.btn = Gtk.Button(label="🎹")
+ #self.btn = Gtk.Button(label="🔽")
+ #self.btn = Gtk.Button(label="⌨")
+ self.btn = Gtk.Button()
+ self.btn.connect("clicked", self.btn_pressed)
+ self.add(self.btn)
+ # Size of the button, unfortunately GTK doesn't seem to care
+ self.set_size_request(WIDTH, HEIGHT)
+ self.btn.set_size_request(WIDTH, HEIGHT)
+ self.set_default_size(WIDTH, HEIGHT)
+ # Apply the CSS attributes specified in the CSS file above
+ self.get_style_context().add_class('our-window')
+ self.btn.get_style_context().add_class('our-button')
+ # Deprecated way of setting background color
+ # Gtk.Window.override_background_color(self.btn, Gtk.StateType.NORMAL, Gdk.RGBA(255,0,0,0))
+
+ # Button handler
+ def btn_pressed(self, widget):
+ call("$SCRIPTS_BASE_PATH/toggle_fullscreen.sh", shell=True)
+
+
+ # win = Gtk.Window()
+ win = MyWindow()
+ win.show_all()
+ Gtk.main()
+ EOF
+
+ ### BUTTON MOVE SCRIPT ###
+
+ cat <<- EOF > "$BUTTON_MOVE_SCRIPT"
+ #! /usr/bin/env sh
+
+ WINDOW_TO_MOVE="$BUTTON_WINDOW_TITLE"
+
+ # Try to match the black border margin of the keyboard, ish
+ X_OFFSET=16
+
+ # 1. isolate line with the current resolution
+ # 2. isolate resolution
+ # 3. isolate y coordinate
+ Y_OFFSET=\$(xrandr | grep '*' | cut -d' ' -f 4 | cut -d'x' -f 2)
+ # Adjusting Y_OFFSET based off subtracting button height * 2 (set in btn.py)
+ # Update: Would LIKE to adjust based off button height, but GTK/bspwm is not
+ # respecting the sizes I've set, so...
+ Y_OFFSET_ADJUSTED=\$((Y_OFFSET - 26 $BUTTON_Y_OFFSET))
+
+ for line in \$(bspc query -N -n .leaf | xargs -n 1 bspc query -T -n); do
+ if echo "\$line" | grep -q "\$WINDOW_TO_MOVE"; then
+ name=0x"\$(printf "%x\n" \$(echo "\$line" | jq .id))"
+
+ # NOTE: Both of these can move windows off screen, so fx. moving to a
+ # corner other than top left (0, 0) needs exact coordinates?! :/
+ # relative move via bspc (no option for absolute?)
+ #bspc node "\$name" -v -20 0
+ # absolute move via xdotool
+ xdotool windowmove "\$name" \$X_OFFSET "\$Y_OFFSET_ADJUSTED"
+ fi
+ done
+ EOF
+
+ ### FULLSCREEN TOGGLE SCRIPT ###
+
+ cat <<- EOF > "$FULLSCREEN_TOGGLE_SCRIPT"
+ #! /usr/bin/env sh
+
+ # This script is run by the button.
+
+ PROGRAM="$BROWSER"
+
+ # Set the browser to fullscreen
+ for line in \$(bspc query -N -n .leaf | xargs -n 1 bspc query -T -n); do
+ if echo "\$line" | grep -q "\$PROGRAM"; then
+ # Switch out jq with cut or something, to not have that dependency?
+ # Find which one is the dropdown, isolate its ID, which annoyingly is in decimal, so convert it to hex with printf, then at 0x in front as bspc expects
+ name=0x"\$(printf "%x\n" \$(echo "\$line" | jq .id))"
+ bspc node "\$name" -t ~fullscreen # fullscreen. With ~ hopefully it toggles?
+ # OR toggle between monocle/tiling instead (not ideal I think because it monocles
+ # the currently selected window, which will be the keyboard if the keyboard
+ # was pressed most recently rather than the browser?)
+ fi
+ done
+ EOF
+
+ ### BSPWM ADD BUTTON SCRIPT ###
+
+ cat <<- EOF > "$BSPWM_ADD_BUTTON_SCRIPT"
+ # It seems the correct one to target is what's output by xprop as the second
+ # WM_CLASS entry! None of the others seem to work?
+ # WM_CLASS(STRING) = "btn.py", "btn.py"
+
+ bspc rule -a "$BUTTON_WINDOW_TITLE" state=floating layer=above
+ $SCRIPTS_BASE_PATH/$BUTTON_SCRIPT &
+ # Give the button a bit of time to appear before we move it
+ sleep 5
+ $SCRIPTS_BASE_PATH/$BUTTON_MOVE_SCRIPT &
+ EOF
+
+ # Set proper permissions on them all
+ chown root:$CUSER -R .
+ chmod g+rx ./*
+
+ ### APPEND BSPWM ADD BUTTON SCRIPT TO BSPWMRC ###
+
+ # Idempotency: Don't add the button multiple times on multiple runs
+ if ! grep --quiet "$BSPWM_ADD_BUTTON_SCRIPT" $BSPWM_CONFIG; then
+ echo "$SCRIPTS_BASE_PATH/$BSPWM_ADD_BUTTON_SCRIPT &" >> "$BSPWM_CONFIG"
+ fi
+else # CLEANUP
+ # apt-get purge -y xdotool jq
+ sed -i "\,$BSPWM_ADD_BUTTON_SCRIPT,d" "$BSPWM_CONFIG"
+fi
diff --git a/scripts/wm_keyboard_hide_button_image.png b/scripts/wm_keyboard_hide_button_image.png
new file mode 100755
index 0000000..d855354
Binary files /dev/null and b/scripts/wm_keyboard_hide_button_image.png differ
diff --git a/scripts/wm_keyboard_install.sh b/scripts/wm_keyboard_install.sh
new file mode 100755
index 0000000..c302c29
--- /dev/null
+++ b/scripts/wm_keyboard_install.sh
@@ -0,0 +1,377 @@
+#! /usr/bin/env sh
+
+# DESCRIPTION:
+# This script installs, sets up and enables a wm (bspwm)
+# and an on-screen keyboard (onboard).
+# Intended for OS2borgerPC Kiosk.
+#
+# ARGUMENTS:
+# 1: Whether to install / uninstall the wm + onscreen keyboard
+#
+# PREREQUISITES:
+# 1. OS2borgerPC Kiosk - Installer Chromium
+# 2. OS2borgerPC Kiosk - Autostart Chromium
+#
+# Would like to skip installing sxhkd but it's not trivial to do as it's
+# classified as a "required dependency" for bspwm
+#
+# AUTHOR: mfm@magenta.dk
+
+set -ex
+
+if ! get_os2borgerpc_config os2_product | grep --quiet kiosk; then
+ echo "Dette script er ikke designet til at blive anvendt på en regulær OS2borgerPC-maskine."
+ exit 1
+fi
+
+[ -z "$1" ] && exit 1
+
+ACTIVATE=$1
+
+CHROMIUM_SCRIPT='/usr/share/os2borgerpc/bin/start_chromium.sh'
+USER=chrome
+XINITRC="/home/$USER/.xinitrc"
+# Note: Only the Compact keyboard layout is changed to not have Ctrl, Alt etc.
+ONBOARD_OPTIONS="--theme=/usr/share/onboard/themes/HighContrast.theme --layout /usr/share/onboard/layouts/Compact.onboard"
+# For apt installations/removals
+export DEBIAN_FRONTEND=noninteractive
+
+if [ "$ACTIVATE" = 'True' ]; then
+
+ # Keyboard options: onboard (~100 mb incl. dependencies?), xvkbd (almost no
+ # dependencies), florence (~500 mb incl. dependencies?!),
+ # gnome onscreen keyboard, carabou
+ # TODO: language-pack-da is now in install_dependencies.sh but older installs
+ # ran a previous version of that, so keeping it here too
+ apt-get update
+ apt-get install -y language-pack-da bspwm onboard lemonbar- dmenu-
+
+ cd /home/$USER || exit 1
+ # Make the directory for the config
+ # -p is also there to suppress errors in case someone re-runs this script,
+ # and it already exists
+ mkdir -p .config/bspwm
+
+ # onboard: If we want a non-default keyboard theme this is apparently necessary
+ # because it attempts to create a file in there
+ mkdir -p .config/dconf
+ chown $USER:$USER .config/dconf
+
+ # Configure bspwm
+cat << EOF > .config/bspwm/bspwmrc
+#! /bin/sh
+
+bspc monitor -d I
+
+bspc config border_width 0
+bspc config window_gap 0
+bspc config borderless_monocle true
+bspc config gapless_monocle true
+
+# leave 20% space for the keyboard
+bspc config split_ratio 0.80
+
+# Always split downwards/vertically instead of whichever direction there is
+# more space (typically horizontally to begin with)
+bspc rule -a "*" split_dir=south
+
+# Test if no difference?: Don't default to monocle?
+# bspc desktop I --layout tiled
+
+# layer=normal is needed at least, to ensure it doesn't cover the entire
+# screen by default
+bspc rule -a Onboard state=tiled layer=normal
+
+# Onboard preferences shouldn't be shown at all. TODO: Not working, but it also
+# doesn't matter right now because the button to show them is no longer there.
+# bspc rule -a "Onboard Preferences" layer=below flag=hidden
+
+# Launch chromium
+$CHROMIUM_SCRIPT wm &
+
+# we want æøå on the keyboard
+setxkbmap dk
+
+#sleep 5 # Go back to this solution if the below solution fails
+
+# Wait until a window (the browser) exists because onboard needs to be below it
+while ! bspc query -N -n .leaf > /dev/null; do
+ sleep 0.5
+done
+
+# First time setup of onboard. Attempt at solving a bug where the keyboard
+# doesn't appear, seemingly due to first time initialization
+if [ ! -f /home/$USER/.config/dconf/user ]; then
+ onboard $ONBOARD_OPTIONS &
+ # Give it some time to start
+ sleep 3
+ killall onboard
+ sleep 1
+fi
+
+# Not certain setting the options is outright necessary past first time setup
+onboard $ONBOARD_OPTIONS &
+EOF
+
+ # Give it the same permissions as /usr/share/doc/bspwm/examples/bspwmrc
+ chmod 755 .config/bspwm/bspwmrc
+
+ # Don't auto-start chromium from xinitrc
+ sed -i "s,\(.*$CHROMIUM_SCRIPT.*\),#\1," $XINITRC
+
+ # Instead start autostarting bspwm - don't add it multiple times though
+if ! grep -q -- 'exec bspwm' "$XINITRC"; then
+cat << EOF >> "$XINITRC"
+exec bspwm
+EOF
+fi
+
+ # Backup the original Compact layout
+ cp /usr/share/onboard/layouts/Compact.onboard /usr/share/onboard/layouts/Compact_orig.onboard
+
+ # Use our own Onboard model without ctrl, alt, super etc.
+ # This is simply the original file with several sections (keys) commented out.
+cat << EOF > /usr/share/onboard/layouts/Compact.onboard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+EOF
+
+ # Give it the same permission as the file it overwrites
+ chmod 644 /usr/share/onboard/layouts/Compact.onboard
+
+else # Go back to not using a wm or the onscreen keyboard
+
+ apt-get remove -y bspwm onboard
+ apt-get autoremove -y
+
+ # Restore the original Compact layout in case it hasn't been deleted - ignore
+ # errors if fx. the dir no longer exists.
+ # true is here to prevent stopping if set -e is set
+ cp /usr/share/onboard/layouts/Compact_orig.onboard /usr/share/onboard/layouts/Compact.onboard 2>/dev/null || true
+
+ # Start chromium from xinitrc instead of bspwm
+ sed -i "s,#\(.*$CHROMIUM_SCRIPT.*\),\1," $XINITRC
+ sed -i "/\(exec bspwm\)/d" $XINITRC
+fi
diff --git a/wm_keyboard_hide_button.md b/wm_keyboard_hide_button.md
new file mode 100644
index 0000000..5760999
--- /dev/null
+++ b/wm_keyboard_hide_button.md
@@ -0,0 +1,50 @@
+---
+title: "Chromium med onboard-tastatur skjul/vis"
+parent: "Kiosk"
+source: os2borgerpc-scripts/os2borgerpc/os2borgerpc_kiosk/wm_keyboard_hide_button.sh
+parameters:
+ - name: "Tilføj knappen?"
+ type: "boolean"
+ default: null
+ mandatory: false
+ - name: "Hvilken browser/program?"
+ type: "string"
+ default: "chromium"
+ mandatory: true
+ - name: "Knap-ikon"
+ type: "file"
+ default: null
+ mandatory: true
+ - name: "Y-akse-justering"
+ type: "int"
+ default: 0
+ mandatory: true
+compatibility:
+ - "22.04"
+ - "Kiosk"
+---
+
+## Beskrivelse
+Dette script er lavet til at muliggøre at vise/skjule skærmtastaturet pba. en knap,
+der placeres nede i venstre hjørne.
+
+Dette script forudsætter at følgendes scripts allerede er kørt:
+- Chromium Installer
+- Chromium Autostart
+- Chromium med Onboard-tastatur
+
+Det tager først effekt efter genstart.
+
+Dette script er blevet testet og virker på Ubuntu 22.04.
+
+## Parametre
+- 1: Aktiver:
+ Sæt hak: Knappen til at skjule skærmtastaturet vises
+ Lad stå tom: Knappen til at skjule skærmtastaturet fjernes (standard)
+- 2: Hvilken browser/program? - navnet på programmet der kører sideløbende med tastaturet. Eks. "chromium" eller "firefox".
+- 3: Det billede/ikon der skal bruges på knappen til at vise/skjule skærmtastaturet, i PNG-format. Skriv til os hvis du ikke selv har et passende.
+- 4: Y-akse-justering kan bruges til at flytte knappen længere op eller ned. Enheden er i pixels.
+ 0 betyder ingen justering (standard)
+ Positive tal rykker knappen længere ned. (dvs. tættere på kanten og potentielt ud af billedet)
+ Negative tal rykker knappen længere op (dvs. længere væk fra kanten)
+
diff --git a/wm_keyboard_install.md b/wm_keyboard_install.md
new file mode 100644
index 0000000..d080dbf
--- /dev/null
+++ b/wm_keyboard_install.md
@@ -0,0 +1,32 @@
+---
+title: "Chromium med onboard-tastatur"
+parent: "Kiosk"
+source: os2borgerpc-scripts/os2borgerpc/os2borgerpc_kiosk/wm_keyboard_install.sh
+parameters:
+ - name: "Tilføj skærmtastatur?"
+ type: "boolean"
+ default: null
+ mandatory: false
+compatibility:
+ - "22.04"
+ - "Kiosk"
+---
+
+## Beskrivelse
+Sætter billedet op, så det er delt mellem browseren og et virtuelt tastatur.
+
+Dette script forudsætter at følgendes scripts allerede er kørt:
+- Chromium Installer
+- Chromium Autostart
+
+Hvis du oplever, det ikke virker, så genkør scriptet "OS2borgerPC Kiosk - Autostart Chromium", efterfulgt af dette.
+
+Dette script tager først effekt efter genstart.
+
+Dette script er blevet testet og virker på Ubuntu 22.04.
+
+## Parametre
+1: Tilføj skærmtastatur?:
+ Sæt hak: Installerer og slår skærmtastaturet til
+ Lad stå tom: Slår skærmtastatur fra (standard)
+