From 6cd1a8e12f90fb5c78025d6686f7d334e865f691 Mon Sep 17 00:00:00 2001 From: Alfredo Monclus Date: Wed, 3 Apr 2024 14:32:32 -0300 Subject: [PATCH] Add an alternative to X close #1289 (#1306) * Changes to allow using cage-kiosk Wayland support close #1289 * installer: many improvements * installer: add notes about wayland status * deps: don't pull xserver with updates --- scripts/KlipperScreen-install.sh | 151 ++++++++++++++++++------------- scripts/KlipperScreen-start.sh | 15 ++- scripts/KlipperScreen.service | 6 +- scripts/system-dependencies.json | 12 --- 4 files changed, 103 insertions(+), 81 deletions(-) diff --git a/scripts/KlipperScreen-install.sh b/scripts/KlipperScreen-install.sh index 134b9f36..cec6bd3a 100755 --- a/scripts/KlipperScreen-install.sh +++ b/scripts/KlipperScreen-install.sh @@ -1,10 +1,11 @@ #!/bin/bash -SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" -KSPATH=$(sed 's/\/scripts//g' <<< $SCRIPTPATH) +SCRIPTPATH=$(dirname -- "$(readlink -f -- "$0")") +KSPATH=$(dirname "$SCRIPTPATH") KSENV="${KLIPPERSCREEN_VENV:-${HOME}/.KlipperScreen-env}" XSERVER="xinit xinput x11-xserver-utils xserver-xorg-input-evdev xserver-xorg-input-libinput xserver-xorg-legacy xserver-xorg-video-fbdev" +CAGE="cage seatd xwayland" PYTHON="python3-virtualenv virtualenv python3-distutils" PYGOBJECT="libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev gir1.2-gtk-3.0" MISC="librsvg2-common libopenjp2-7 wireless-tools libdbus-glib-1-dev autoconf" @@ -30,18 +31,49 @@ echo_ok () printf "${Green}$1${Normal}\n" } +install_graphical_backend() +{ + while true; do + if [ -z "$BACKEND" ]; then + echo_ok "Default is Xserver" + echo_text "Wayland is EXPERIMENTAL needs kms/drm drivers doesn't support DPMS and may need autologin" + read -r -e -p "Backend Xserver or Wayland (cage)? [X/w]" BACKEND + if [[ "$BACKEND" =~ ^[wW]$ ]]; then + echo_text "Installing Wayland Cage Kiosk" + if sudo apt install -y $CAGE; then + echo_ok "Installed Cage" + BACKEND="W" + break + else + echo_error "Installation of Cage dependencies failed ($CAGE)" + exit 1 + fi + else + echo_text "Installing Xserver" + if sudo apt install -y $XSERVER; then + echo_ok "Installed X" + update_x11 + BACKEND="X" + break + else + echo_error "Installation of X-server dependencies failed ($XSERVER)" + exit 1 + fi + fi + fi + done +} + install_packages() { echo_text "Update package data" - sudo apt-get update + sudo apt update echo_text "Checking for broken packages..." - output=$(dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' | grep -E ^.[^nci]) - if [ $? -eq 0 ]; then + if dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' | grep -E "^.[^nci]"; then echo_text "Detected broken packages. Attempting to fix" - sudo apt-get -f install - output=$(dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' | grep -E ^.[^nci]) - if [ $? -eq 0 ]; then + sudo apt -f install + if dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' | grep -E "^.[^nci]"; then echo_error "Unable to fix broken packages. These must be fixed before KlipperScreen can be installed" exit 1 fi @@ -50,31 +82,22 @@ install_packages() fi echo_text "Installing KlipperScreen dependencies" - sudo apt-get install -y $XSERVER - if [ $? -eq 0 ]; then - echo_ok "Installed X" - else - echo_error "Installation of X-server dependencies failed ($XSERVER)" - exit 1 - fi - sudo apt-get install -y $OPTIONAL - echo $_ - sudo apt-get install -y $PYTHON - if [ $? -eq 0 ]; then + sudo apt install -y $OPTIONAL + echo "$_" + if sudo apt install -y $PYTHON; then echo_ok "Installed Python dependencies" else echo_error "Installation of Python dependencies failed ($PYTHON)" exit 1 fi - sudo apt-get install -y $PYGOBJECT - if [ $? -eq 0 ]; then + + if sudo apt install -y $PYGOBJECT; then echo_ok "Installed PyGobject dependencies" else echo_error "Installation of PyGobject dependencies failed ($PYGOBJECT)" exit 1 fi - sudo apt-get install -y $MISC - if [ $? -eq 0 ]; then + if sudo apt install -y $MISC; then echo_ok "Installed Misc packages" else echo_error "Installation of Misc packages failed ($MISC)" @@ -109,7 +132,7 @@ create_virtualenv() if [ $? -gt 0 ]; then echo_error "Error: pip install exited with status code $?" echo_text "Trying again with new tools..." - sudo apt-get install -y build-essential cmake + sudo apt install -y build-essential cmake if [[ "$(uname -m)" =~ armv[67]l ]]; then echo_text "Adding piwheels.org as extra index..." pip install --extra-index-url https://www.piwheels.org/simple --upgrade pip setuptools @@ -132,20 +155,18 @@ install_systemd_service() { echo_text "Installing KlipperScreen unit file" - SERVICE=$(<$SCRIPTPATH/KlipperScreen.service) - KSPATH_ESC=$(sed "s/\//\\\\\//g" <<< $KSPATH) - KSENV_ESC=$(sed "s/\//\\\\\//g" <<< $KSENV) - - SERVICE=$(sed "s/KS_USER/$USER/g" <<< $SERVICE) - SERVICE=$(sed "s/KS_ENV/$KSENV_ESC/g" <<< $SERVICE) - SERVICE=$(sed "s/KS_DIR/$KSPATH_ESC/g" <<< $SERVICE) + SERVICE=$(cat "$SCRIPTPATH"/KlipperScreen.service) + SERVICE=${SERVICE//KS_USER/$USER} + SERVICE=${SERVICE//KS_ENV/$KSENV} + SERVICE=${SERVICE//KS_DIR/$KSPATH} + SERVICE=${SERVICE//KS_BACKEND/$BACKEND} echo "$SERVICE" | sudo tee /etc/systemd/system/KlipperScreen.service > /dev/null sudo systemctl unmask KlipperScreen.service sudo systemctl daemon-reload sudo systemctl enable KlipperScreen sudo systemctl set-default multi-user.target - sudo adduser $USER tty + sudo adduser "$USER" tty } create_policy() @@ -155,7 +176,7 @@ create_policy() echo_text "Installing KlipperScreen PolicyKit Rules" sudo groupadd -f klipperscreen - sudo adduser $USER netdev + sudo adduser "$USER" netdev if [ ! -x "$(command -v pkaction)" ]; then echo "PolicyKit not installed" return @@ -181,7 +202,7 @@ create_policy() echo_text "Installing PolicyKit Rules to ${RULE_FILE}..." KS_GID=$( getent group klipperscreen | awk -F: '{printf "%d", $3}' ) - sudo /bin/sh -c "cat > ${RULE_FILE}" << EOF + sudo tee ${RULE_FILE} > /dev/null << EOF // Allow KlipperScreen to reboot, shutdown, etc polkit.addRule(function(action, subject) { if ((action.id == "org.freedesktop.login1.power-off" || @@ -210,25 +231,23 @@ EOF create_policy_legacy() { RULE_FILE="/etc/polkit-1/localauthority/50-local.d/20-klipperscreen.pkla" - ACTIONS="org.freedesktop.login1.power-off" - ACTIONS="${ACTIONS};org.freedesktop.login1.power-off-multiple-sessions" - ACTIONS="${ACTIONS};org.freedesktop.login1.reboot" - ACTIONS="${ACTIONS};org.freedesktop.login1.reboot-multiple-sessions" - ACTIONS="${ACTIONS};org.freedesktop.login1.halt" - ACTIONS="${ACTIONS};org.freedesktop.login1.halt-multiple-sessions" - ACTIONS="${ACTIONS};org.freedesktop.NetworkManager.*" - sudo /bin/sh -c "cat > ${RULE_FILE}" << EOF + sudo tee ${RULE_FILE} > /dev/null << EOF [KlipperScreen] Identity=unix-user:$USER -Action=$ACTIONS +Action=org.freedesktop.login1.power-off; + org.freedesktop.login1.power-off-multiple-sessions; + org.freedesktop.login1.reboot; + org.freedesktop.login1.reboot-multiple-sessions; + org.freedesktop.login1.halt; + org.freedesktop.login1.halt-multiple-sessions; + org.freedesktop.NetworkManager.* ResultAny=yes EOF } update_x11() { - echo_text "Adding X11 Xwrapper" - sudo /bin/sh -c "cat > /etc/X11/Xwrapper.config" << EOF + sudo tee /etc/X11/Xwrapper.config > /dev/null << EOF allowed_users=anybody needs_root_rights=yes EOF @@ -236,11 +255,9 @@ EOF fix_fbturbo() { - if [ $(dpkg-query -W -f='${Status}' xserver-xorg-video-fbturbo 2>/dev/null | grep -c "ok installed") -eq 0 ]; - then + if [ "$(dpkg-query -W -f='${Status}' xserver-xorg-video-fbturbo 2>/dev/null | grep -c "ok installed")" -eq 0 ]; then FBCONFIG="/usr/share/X11/xorg.conf.d/99-fbturbo.conf" - if [ -e $FBCONFIG ] - then + if [ -e $FBCONFIG ]; then echo_text "FBturbo not installed, but the configuration file exists" echo_text "This will fail if the config is not removed or the package installed" echo_text "moving the config to the home folder" @@ -251,34 +268,46 @@ fix_fbturbo() add_desktop_file() { - DESKTOP=$(<$SCRIPTPATH/KlipperScreen.desktop) - mkdir -p $HOME/.local/share/applications/ - echo "$DESKTOP" | tee $HOME/.local/share/applications/KlipperScreen.desktop > /dev/null - sudo cp $SCRIPTPATH/../styles/icon.svg /usr/share/icons/hicolor/scalable/apps/KlipperScreen.svg + mkdir -p "$HOME"/.local/share/applications/ + cp "$SCRIPTPATH"/KlipperScreen.desktop "$HOME"/.local/share/applications/KlipperScreen.desktop + sudo cp "$SCRIPTPATH"/../styles/icon.svg /usr/share/icons/hicolor/scalable/apps/KlipperScreen.svg } start_KlipperScreen() { echo_text "Starting service..." - sudo systemctl stop KlipperScreen - sudo systemctl start KlipperScreen + sudo systemctl restart KlipperScreen } + + +# Script start if [ "$EUID" == 0 ] then echo_error "Please do not run this script as root" exit 1 fi -install_packages check_requirements + +if [ -z "$SERVICE" ]; then + read -r -e -p "Install as a service? (This will enable boot to console) [Y/n]" SERVICE + if [[ $SERVICE =~ ^[nN]$ ]]; then + echo_text "Not installing the service" + echo_text "The graphical backend will NOT be installed" + else + install_graphical_backend + install_systemd_service + if [ -z "$START" ]; then + START=1 + fi + fi +fi + +install_packages create_virtualenv create_policy -update_x11 fix_fbturbo add_desktop_file -read -r -e -p "Install as a service? (This will enable boot to console) [Y/n]" choice -if [[ $choice =~ ^[nN]$ ]]; then - echo_text "Not installing the service, KlipperScreen will need to be manually started" +if [ -z "$START" ] || [ "$START" -eq 0 ]; then echo_ok "KlipperScreen was installed" else - install_systemd_service start_KlipperScreen fi diff --git a/scripts/KlipperScreen-start.sh b/scripts/KlipperScreen-start.sh index 70968586..32b25118 100755 --- a/scripts/KlipperScreen-start.sh +++ b/scripts/KlipperScreen-start.sh @@ -1,12 +1,21 @@ #!/bin/sh +XDG_RUNTIME_DIR=/run/user/$(id -u) +export XDG_RUNTIME_DIR + SCRIPTPATH=$(dirname $(realpath $0)) if [ -f $SCRIPTPATH/launch_KlipperScreen.sh ] then -echo "Running "$SCRIPTPATH"/launch_KlipperScreen.sh" +echo "Running $SCRIPTPATH/launch_KlipperScreen.sh" $SCRIPTPATH/launch_KlipperScreen.sh exit $? fi -echo "Running KlipperScreen on X in display :0 by default" -/usr/bin/xinit $KS_XCLIENT +if [[ "$BACKEND" =~ ^[wW]$ ]]; then + echo "Running KlipperScreen on Cage" + /usr/bin/cage -ds $KS_XCLIENT + +else + echo "Running KlipperScreen on X in display :0 by default" + /usr/bin/xinit $KS_XCLIENT +fi diff --git a/scripts/KlipperScreen.service b/scripts/KlipperScreen.service index 3579ceb4..cd76cc77 100644 --- a/scripts/KlipperScreen.service +++ b/scripts/KlipperScreen.service @@ -9,10 +9,6 @@ ConditionPathExists=/dev/tty0 # D-Bus is necessary for contacting logind, which is required. Wants=dbus.socket systemd-logind.service After=dbus.socket systemd-logind.service -# Replace any (a)getty that may have spawned, since we log in -# automatically. -Conflicts=getty@%i.service -After=getty@%i.service [Service] Type=simple @@ -21,7 +17,7 @@ RestartSec=2 User=KS_USER SupplementaryGroups=klipperscreen WorkingDirectory=KS_DIR -Environment="KS_XCLIENT=KS_ENV/bin/python KS_DIR/screen.py" +Environment="KS_XCLIENT=KS_ENV/bin/python KS_DIR/screen.py" BACKEND=KS_BACKEND ExecStart="KS_DIR/scripts/KlipperScreen-start.sh" # Log this user with utmp, letting it show up with commands 'w' and diff --git a/scripts/system-dependencies.json b/scripts/system-dependencies.json index 9e2f720e..b8fe8dd8 100644 --- a/scripts/system-dependencies.json +++ b/scripts/system-dependencies.json @@ -9,13 +9,6 @@ "pkg-config", "python3-dev", "gir1.2-gtk-3.0", - "xinit", - "xinput", - "x11-xserver-utils", - "xserver-xorg-input-evdev", - "xserver-xorg-input-libinput", - "xserver-xorg-video-fbdev", - "xserver-xorg-legacy", "fonts-nanum", "fonts-ipafont", "libmpv-dev", @@ -32,11 +25,6 @@ "pkgconf", "gobject-introspection", "gtk3", - "xorg-xinit", - "xorg-server", - "xf86-input-evdev", - "xf86-input-libinput", - "xf86-video-fbdev", "ttf-nanum", "otf-ipafont", "mpv",