Chromium med skærmtastatur skjul/vis (onboard)


Source: Download script

Last Updated: 4. December 2024 by Agnete Moos (agms@sonderborg.dk)

Parameters:

Navn Type Standardværdi Påkrævet
Click to see the source code
#! /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

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:

  • Installer Chromium på kiosk
  • Autostart Chromium på Kiosk
  • Chromium med skærmtastatur (onboard)

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.
  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)\

This site uses Just the Docs, a documentation theme for Jekyll.