Compare commits

..

2 Commits

Author SHA1 Message Date
nearxos
2d6e5aa009 Enhance GTK theme configuration and taskbar setup in cloud-init scripts</message>
<message>Update the cloud-init scripts to improve GTK theme settings by enforcing dark mode through gsettings and preserving the icon theme for a cohesive user experience. Additionally, enhance the first-boot script to install a Chromium kiosk launcher icon on the desktop and in the application menu, along with a five-tap close functionality for Chromium. These changes streamline the user interface and ensure a consistent dark theme across applications and the taskbar.
2026-02-23 15:07:31 +02:00
nearxos
f42700848a Enhance first-boot script to support dynamic dark theme selection and taskbar configuration</message>
<message>Update the first-boot.sh script to dynamically select a dark theme based on the availability of PiXnoir or Adwaita-dark. Implement functionality to deploy a dark-themed taskbar configuration for wf-panel-pi, ensuring a cohesive user interface. Additionally, improve logging for theme settings and taskbar installations, enhancing the overall user experience during the first boot process.
2026-02-23 11:16:02 +02:00
12 changed files with 277 additions and 43 deletions

View File

@@ -28,7 +28,7 @@ profile {
EOF EOF
log "kanshi config written to $KANSHI_CONFIG" log "kanshi config written to $KANSHI_CONFIG"
# Set GTK dark theme (same as first-boot step 08) # Set GTK dark theme (same as first-boot step 08) and force dark mode via gsettings
GTK_THEME_NAME="PiXnoir" GTK_THEME_NAME="PiXnoir"
[[ -d /usr/share/themes/Adwaita-dark ]] && ! [[ -d /usr/share/themes/PiXnoir ]] && GTK_THEME_NAME="Adwaita-dark" [[ -d /usr/share/themes/Adwaita-dark ]] && ! [[ -d /usr/share/themes/PiXnoir ]] && GTK_THEME_NAME="Adwaita-dark"
GTK_SETTINGS="$HOME/.config/gtk-3.0/settings.ini" GTK_SETTINGS="$HOME/.config/gtk-3.0/settings.ini"
@@ -39,6 +39,13 @@ else
grep -q '^gtk-application-prefer-dark-theme=' "$GTK_SETTINGS" && sed -i 's/^gtk-application-prefer-dark-theme=.*/gtk-application-prefer-dark-theme=1/' "$GTK_SETTINGS" || echo 'gtk-application-prefer-dark-theme=1' >> "$GTK_SETTINGS" grep -q '^gtk-application-prefer-dark-theme=' "$GTK_SETTINGS" && sed -i 's/^gtk-application-prefer-dark-theme=.*/gtk-application-prefer-dark-theme=1/' "$GTK_SETTINGS" || echo 'gtk-application-prefer-dark-theme=1' >> "$GTK_SETTINGS"
grep -q '^gtk-theme-name=' "$GTK_SETTINGS" && sed -i "s/^gtk-theme-name=.*/gtk-theme-name=$GTK_THEME_NAME/" "$GTK_SETTINGS" || echo "gtk-theme-name=$GTK_THEME_NAME" >> "$GTK_SETTINGS" grep -q '^gtk-theme-name=' "$GTK_SETTINGS" && sed -i "s/^gtk-theme-name=.*/gtk-theme-name=$GTK_THEME_NAME/" "$GTK_SETTINGS" || echo "gtk-theme-name=$GTK_THEME_NAME" >> "$GTK_SETTINGS"
fi fi
if [[ -d /usr/share/icons/PiXtrix ]]; then
grep -q '^gtk-icon-theme-name=' "$GTK_SETTINGS" && sed -i 's/^gtk-icon-theme-name=.*/gtk-icon-theme-name=PiXtrix/' "$GTK_SETTINGS" || echo 'gtk-icon-theme-name=PiXtrix' >> "$GTK_SETTINGS"
fi
if command -v gsettings >/dev/null 2>&1; then
gsettings set org.gnome.desktop.interface gtk-theme "$GTK_THEME_NAME" 2>/dev/null || true
gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark' 2>/dev/null || true
fi
log "Set dark theme ($GTK_THEME_NAME) in gtk-3.0/settings.ini" log "Set dark theme ($GTK_THEME_NAME) in gtk-3.0/settings.ini"
log "removing one-shot desktop and script" log "removing one-shot desktop and script"

View File

@@ -12,3 +12,6 @@ first-boot.sh downloads these from `FILE_SERVER` (e.g. `http://10.20.50.1:5000/f
| 02-set-wallpaper-once.desktop | /home/pi/.config/autostart/02-set-wallpaper-once.desktop (with 02-set-wallpaper-once.sh). Wallpaper is also set during first-boot via pcmanfm. | | 02-set-wallpaper-once.desktop | /home/pi/.config/autostart/02-set-wallpaper-once.desktop (with 02-set-wallpaper-once.sh). Wallpaper is also set during first-boot via pcmanfm. |
| wf-panel-pi.ini | Optional: /home/pi/.config/wf-panel-pi/wf-panel-pi.ini (custom taskbar layout and css_path). See TASKBAR-THEME.md. | | wf-panel-pi.ini | Optional: /home/pi/.config/wf-panel-pi/wf-panel-pi.ini (custom taskbar layout and css_path). See TASKBAR-THEME.md. |
| panel-theme.css | Optional: /home/pi/.config/wf-panel-pi/panel-theme.css (custom taskbar CSS). Deploy with wf-panel-pi.ini; see TASKBAR-THEME.md. | | panel-theme.css | Optional: /home/pi/.config/wf-panel-pi/panel-theme.css (custom taskbar CSS). Deploy with wf-panel-pi.ini; see TASKBAR-THEME.md. |
| gtk.css | /home/pi/.config/gtk-3.0/gtk.css (user GTK3 override; forces start menu dropdown and all menus/popovers to full dark). |
| chromium-kiosk-launcher.desktop | Desktop icon + application menu: "Start Chromium Kiosk" (run start-chromium.sh when browser was closed). |
| five-tap-close-chromium.desktop | /home/pi/.config/autostart/ (with five-tap-close-chromium.py). 5 taps in top-right corner close Chromium. |

View File

@@ -0,0 +1,9 @@
[Desktop Entry]
Type=Application
Name=Start Chromium Kiosk
Comment=Start Chromium in kiosk mode (use if the browser was closed)
Exec=/home/pi/start-chromium.sh
Icon=chromium-browser
Terminal=false
Categories=Utility;Kiosk;
StartupNotify=false

View File

@@ -0,0 +1,8 @@
[Desktop Entry]
Type=Application
Name=Five-tap close Chromium
Comment=5 taps in top-right corner close Chromium kiosk (hidden at startup)
Exec=/home/pi/five-tap-close-chromium.py
Hidden=false
NoDisplay=true
X-GNOME-Autostart-enabled=true

View File

@@ -0,0 +1,49 @@
/* User GTK3 override: force start menu and all menus/popovers to full dark.
* Colors match Adwaita-dark (menu/popover #2d2d2d, text #e0e0e0).
* Placed in ~/.config/gtk-3.0/gtk.css.
*/
/* Adwaita-dark menu/popover background */
menu,
.menu,
menubar,
.menubar,
popover,
.popover,
popover.menu {
background-color: #2d2d2d !important;
background: #2d2d2d !important;
color: #e0e0e0 !important;
}
/* Inner content (often the cause of light background) */
menu contents,
.menu contents,
popover contents,
popover list,
popover flowbox,
popover box {
background-color: #2d2d2d !important;
background: #2d2d2d !important;
color: #e0e0e0 !important;
}
menu menuitem,
.menu menuitem,
menubar menuitem,
popover modelbutton,
popover menuitem {
background-color: transparent !important;
background: transparent !important;
color: #e0e0e0 !important;
}
menu menuitem:hover,
.menu menuitem:hover,
menubar menuitem:hover,
popover modelbutton:hover,
popover menuitem:hover {
background-color: rgba(255, 255, 255, 0.1) !important;
background: rgba(255, 255, 255, 0.1) !important;
color: #ffffff !important;
}

View File

@@ -1,31 +1,30 @@
/* Custom wf-panel-pi theme dark, rounded panel /* Minimal dark taskbar flat, touch-friendly
* Place at ~/.config/wf-panel-pi/panel-theme.css * Colors match Adwaita-dark (window bg #242424) so taskbar fits dark mode.
* Set css_path in wf-panel-pi.ini to this file (absolute path). * Icon theme PiXtrix (start-here) set in gtk-3.0/settings.ini.
*/ */
/* Panel window */
window { window {
background-color: transparent; background-color: transparent;
} }
/* Main panel box dark with slight rounding and shadow */ /* Flat bar: Adwaita-dark window bg so theme is consistent */
window box { window box {
background-color: rgba(45, 45, 45, 0.96); background-color: #242424;
border-radius: 10px; border-radius: 0;
margin: 4px; margin: 0;
padding: 2px 8px; padding: 4px 8px;
border: 1px solid rgba(255, 255, 255, 0.06); border: none;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35); box-shadow: none;
} }
/* Plugin / launcher buttons */ /* Touch-friendly buttons: min 32px, clear hit area */
button, button {
button:hover,
button:active {
background: transparent; background: transparent;
border: none; border: none;
border-radius: 6px; border-radius: 4px;
padding: 4px; padding: 6px;
min-width: 32px;
min-height: 32px;
color: #e0e0e0; color: #e0e0e0;
} }
@@ -37,7 +36,6 @@ button:active {
background: rgba(255, 255, 255, 0.12); background: rgba(255, 255, 255, 0.12);
} }
/* Labels (e.g. clock text) */
label { label {
color: #e0e0e0; color: #e0e0e0;
font-size: 11pt; font-size: 11pt;

View File

@@ -1,21 +1,20 @@
# wf-panel-pi custom theme example # wf-panel-pi minimal dark taskbar, touch-friendly
# Copy to ~/.config/wf-panel-pi/wf-panel-pi.ini (user pi) # Copy to ~/.config/wf-panel-pi/wf-panel-pi.ini (user pi)
# Optional: copy panel-theme.css to ~/.config/wf-panel-pi/panel-theme.css # Set css_path to panel-theme.css. Restart panel: pkill wf-panel-pi
# and ensure css_path below points to it. Restart panel: pkill wf-panel-pi # Icon theme (start-here) is set in gtk-3.0/settings.ini (PiXtrix) so custom icon from first-boot is used.
[panel] [panel]
# Custom CSS (use absolute path; replace /home/pi with actual $PI_HOME if different)
css_path = /home/pi/.config/wf-panel-pi/panel-theme.css css_path = /home/pi/.config/wf-panel-pi/panel-theme.css
# Layout # Left: start menu (uses start-here from PiXtrix), launchers, window list
widgets_left = smenu spacing0 spacing4 launchers spacing8 window-list widgets_left = smenu spacing0 spacing2 launchers spacing4 window-list
widgets_center = none widgets_center = none
widgets_right = tray power ejecter updater spacing2 connect spacing2 bluetooth spacing2 netman spacing2 volumepulse spacing2 clock spacing2 batt spacing2 squeek # Right: tray, network, volume, clock, power (minimal set, touch-friendly)
# Size and position widgets_right = tray spacing2 netman spacing2 volumepulse spacing2 clock spacing2 power
icon_size = 28 # Touch-friendly size (32px min target)
minimal_height = 28 icon_size = 32
minimal_height = 36
position = top position = top
# Dark background (ARGB) # Match Adwaita-dark window bg (#242424) so taskbar fits dark theme
background_color = #2D2D2DFF background_color = #242424FF
# Optional: autohide
autohide = false autohide = false
autohide_duration = 300 autohide_duration = 300

View File

@@ -17,7 +17,7 @@ PI_USER="${PI_USER:-pi}"
LOGFILE="${LOGFILE:-/var/log/first-boot.log}" LOGFILE="${LOGFILE:-/var/log/first-boot.log}"
PLYMOUTH_DIR="${PLYMOUTH_DIR:-/usr/share/plymouth/themes/custom}" PLYMOUTH_DIR="${PLYMOUTH_DIR:-/usr/share/plymouth/themes/custom}"
WALLPAPER_PATH="${WALLPAPER_PATH:-/usr/share/rpd-wallpaper/splash.png}" WALLPAPER_PATH="${WALLPAPER_PATH:-/usr/share/rpd-wallpaper/splash.png}"
PACKAGES="${PACKAGES:-git chromium wmctrl openssh-server swaybg wlr-randr maliit-keyboard xinput-calibrator}" PACKAGES="${PACKAGES:-git chromium wmctrl openssh-server swaybg wlr-randr maliit-keyboard xinput-calibrator python3-gi python3-gi-cairo}"
LIGHTDM_SESSION="${LIGHTDM_SESSION:-rpd-labwc}" LIGHTDM_SESSION="${LIGHTDM_SESSION:-rpd-labwc}"
GTK_THEME_NAME="${GTK_THEME_NAME:-PiXnoir}" GTK_THEME_NAME="${GTK_THEME_NAME:-PiXnoir}"
WALLPAPER_MODE="${WALLPAPER_MODE:-crop}" WALLPAPER_MODE="${WALLPAPER_MODE:-crop}"
@@ -156,13 +156,33 @@ step_03_reterminal_drivers() {
# --- Step 04: Kiosk files from file server --- # --- Step 04: Kiosk files from file server ---
step_04_kiosk_files() { step_04_kiosk_files() {
log "Creating $AUTOSTART" log "Creating $AUTOSTART"
mkdir -p "$AUTOSTART" mkdir -p "$AUTOSTART" "$PI_HOME/Desktop" "$PI_HOME/.local/share/applications"
log "Downloading start-chromium.sh from ${FILE_SERVER}/start-chromium.sh" log "Downloading start-chromium.sh from ${FILE_SERVER}/start-chromium.sh"
curl -fsSL "${FILE_SERVER}/start-chromium.sh" -o "$PI_HOME/start-chromium.sh" curl -fsSL "${FILE_SERVER}/start-chromium.sh" -o "$PI_HOME/start-chromium.sh"
log "Downloading chromium-kiosk.desktop from ${FILE_SERVER}/chromium-kiosk.desktop" log "Downloading chromium-kiosk.desktop from ${FILE_SERVER}/chromium-kiosk.desktop"
curl -fsSL "${FILE_SERVER}/chromium-kiosk.desktop" -o "$AUTOSTART/chromium-kiosk.desktop" curl -fsSL "${FILE_SERVER}/chromium-kiosk.desktop" -o "$AUTOSTART/chromium-kiosk.desktop"
chmod 755 "$PI_HOME/start-chromium.sh" && chmod 644 "$AUTOSTART/chromium-kiosk.desktop" chmod 755 "$PI_HOME/start-chromium.sh" && chmod 644 "$AUTOSTART/chromium-kiosk.desktop"
chown -R "$PI_USER:$PI_USER" "$PI_HOME/start-chromium.sh" "$AUTOSTART/chromium-kiosk.desktop" chown -R "$PI_USER:$PI_USER" "$PI_HOME/start-chromium.sh" "$AUTOSTART/chromium-kiosk.desktop"
# Launcher icon: desktop + application menu (start Chromium when killed)
if curl -fsSL "${FILE_SERVER}/chromium-kiosk-launcher.desktop" -o "$PI_HOME/chromium-kiosk-launcher.desktop" 2>/dev/null; then
sed "s|/home/pi|$PI_HOME|g" "$PI_HOME/chromium-kiosk-launcher.desktop" > "$PI_HOME/Desktop/Chromium Kiosk.desktop"
cp "$PI_HOME/chromium-kiosk-launcher.desktop" "$PI_HOME/.local/share/applications/"
sed -i "s|/home/pi|$PI_HOME|g" "$PI_HOME/.local/share/applications/chromium-kiosk-launcher.desktop"
chmod 755 "$PI_HOME/Desktop/Chromium Kiosk.desktop"
chmod 644 "$PI_HOME/.local/share/applications/chromium-kiosk-launcher.desktop"
chown "$PI_USER:$PI_USER" "$PI_HOME/Desktop/Chromium Kiosk.desktop" "$PI_HOME/.local/share/applications/chromium-kiosk-launcher.desktop"
log "Chromium kiosk launcher icon installed on desktop and in application menu"
fi
# 5 taps in top-right corner close Chromium (Python + Gtk)
if curl -fsSL "${FILE_SERVER}/five-tap-close-chromium.py" -o "$PI_HOME/five-tap-close-chromium.py" 2>/dev/null; then
chmod 755 "$PI_HOME/five-tap-close-chromium.py"
if curl -fsSL "${FILE_SERVER}/five-tap-close-chromium.desktop" -o "$AUTOSTART/five-tap-close-chromium.desktop" 2>/dev/null; then
sed -i "s|/home/pi|$PI_HOME|g" "$AUTOSTART/five-tap-close-chromium.desktop"
chmod 644 "$AUTOSTART/five-tap-close-chromium.desktop"
chown "$PI_USER:$PI_USER" "$PI_HOME/five-tap-close-chromium.py" "$AUTOSTART/five-tap-close-chromium.desktop"
log "5-tap top-right close Chromium installed (autostart)"
fi
fi
log "Kiosk files installed under $PI_HOME and $AUTOSTART" log "Kiosk files installed under $PI_HOME and $AUTOSTART"
} }
@@ -190,10 +210,11 @@ step_05_splash_wallpaper() {
PCMANFM_DESKTOP="$PI_HOME/.config/pcmanfm/$PROFILE/desktop-items-0.conf" PCMANFM_DESKTOP="$PI_HOME/.config/pcmanfm/$PROFILE/desktop-items-0.conf"
mkdir -p "$(dirname "$PCMANFM_DESKTOP")" mkdir -p "$(dirname "$PCMANFM_DESKTOP")"
if [[ ! -f "$PCMANFM_DESKTOP" ]]; then if [[ ! -f "$PCMANFM_DESKTOP" ]]; then
printf '%s\n' '[*]' "wallpaper=$WALLPAPER_PATH" "wallpaper_mode=$WALLPAPER_MODE" 'wallpaper_common=1' > "$PCMANFM_DESKTOP" printf '%s\n' '[*]' "wallpaper=$WALLPAPER_PATH" "wallpaper_mode=$WALLPAPER_MODE" 'wallpaper_common=1' 'show_trash=0' > "$PCMANFM_DESKTOP"
else else
grep -q '^wallpaper=' "$PCMANFM_DESKTOP" && sed -i "s|^wallpaper=.*|wallpaper=$WALLPAPER_PATH|" "$PCMANFM_DESKTOP" || echo "wallpaper=$WALLPAPER_PATH" >> "$PCMANFM_DESKTOP" grep -q '^wallpaper=' "$PCMANFM_DESKTOP" && sed -i "s|^wallpaper=.*|wallpaper=$WALLPAPER_PATH|" "$PCMANFM_DESKTOP" || echo "wallpaper=$WALLPAPER_PATH" >> "$PCMANFM_DESKTOP"
grep -q '^wallpaper_mode=' "$PCMANFM_DESKTOP" && sed -i "s/^wallpaper_mode=.*/wallpaper_mode=$WALLPAPER_MODE/" "$PCMANFM_DESKTOP" || echo "wallpaper_mode=$WALLPAPER_MODE" >> "$PCMANFM_DESKTOP" grep -q '^wallpaper_mode=' "$PCMANFM_DESKTOP" && sed -i "s/^wallpaper_mode=.*/wallpaper_mode=$WALLPAPER_MODE/" "$PCMANFM_DESKTOP" || echo "wallpaper_mode=$WALLPAPER_MODE" >> "$PCMANFM_DESKTOP"
grep -q '^show_trash=' "$PCMANFM_DESKTOP" && sed -i 's/^show_trash=.*/show_trash=0/' "$PCMANFM_DESKTOP" || echo 'show_trash=0' >> "$PCMANFM_DESKTOP"
fi fi
chown -R "$PI_USER:$PI_USER" "$(dirname "$PCMANFM_DESKTOP")" chown -R "$PI_USER:$PI_USER" "$(dirname "$PCMANFM_DESKTOP")"
done done
@@ -267,17 +288,58 @@ step_07_maliit() {
curl -fsSL "${FILE_SERVER}/maliit-keyboard.desktop" -o "$AUTOSTART/maliit-keyboard.desktop" 2>/dev/null && log "maliit-keyboard.desktop installed" || log "WARNING: Could not download maliit-keyboard.desktop" curl -fsSL "${FILE_SERVER}/maliit-keyboard.desktop" -o "$AUTOSTART/maliit-keyboard.desktop" 2>/dev/null && log "maliit-keyboard.desktop installed" || log "WARNING: Could not download maliit-keyboard.desktop"
} }
# --- Step 08: Dark theme (GTK) --- # --- Step 08: Dark theme (GTK + taskbar) ---
step_08_dark_theme() { step_08_dark_theme() {
# Use Adwaita-dark if PiXnoir is not installed (e.g. some Raspberry Pi OS images)
local theme_name="$GTK_THEME_NAME"
if [[ ! -d "/usr/share/themes/${theme_name}" ]]; then
if [[ -d /usr/share/themes/Adwaita-dark ]]; then
theme_name="Adwaita-dark"
log "PiXnoir not found; using Adwaita-dark for dark theme"
fi
fi
GTK_SETTINGS="$PI_HOME/.config/gtk-3.0/settings.ini" GTK_SETTINGS="$PI_HOME/.config/gtk-3.0/settings.ini"
mkdir -p "$(dirname "$GTK_SETTINGS")" mkdir -p "$(dirname "$GTK_SETTINGS")"
# PiXtrix holds the custom start-here icon (installed in step 05); set so taskbar shows it
local icon_theme="PiXtrix"
[[ ! -d /usr/share/icons/PiXtrix ]] && icon_theme=""
if [[ ! -f "$GTK_SETTINGS" ]]; then if [[ ! -f "$GTK_SETTINGS" ]]; then
printf '%s\n' '[Settings]' 'gtk-application-prefer-dark-theme=1' "gtk-theme-name=$GTK_THEME_NAME" > "$GTK_SETTINGS" { printf '%s\n' '[Settings]' 'gtk-application-prefer-dark-theme=1' "gtk-theme-name=$theme_name"
[[ -n "$icon_theme" ]] && echo "gtk-icon-theme-name=$icon_theme"
} > "$GTK_SETTINGS"
else else
grep -q '^gtk-application-prefer-dark-theme=' "$GTK_SETTINGS" && sed -i 's/^gtk-application-prefer-dark-theme=.*/gtk-application-prefer-dark-theme=1/' "$GTK_SETTINGS" || echo 'gtk-application-prefer-dark-theme=1' >> "$GTK_SETTINGS" grep -q '^gtk-application-prefer-dark-theme=' "$GTK_SETTINGS" && sed -i 's/^gtk-application-prefer-dark-theme=.*/gtk-application-prefer-dark-theme=1/' "$GTK_SETTINGS" || echo 'gtk-application-prefer-dark-theme=1' >> "$GTK_SETTINGS"
grep -q '^gtk-theme-name=' "$GTK_SETTINGS" && sed -i "s/^gtk-theme-name=.*/gtk-theme-name=$GTK_THEME_NAME/" "$GTK_SETTINGS" || echo "gtk-theme-name=$GTK_THEME_NAME" >> "$GTK_SETTINGS" grep -q '^gtk-theme-name=' "$GTK_SETTINGS" && sed -i "s/^gtk-theme-name=.*/gtk-theme-name=$theme_name/" "$GTK_SETTINGS" || echo "gtk-theme-name=$theme_name" >> "$GTK_SETTINGS"
if [[ -n "$icon_theme" ]]; then
grep -q '^gtk-icon-theme-name=' "$GTK_SETTINGS" && sed -i "s/^gtk-icon-theme-name=.*/gtk-icon-theme-name=$icon_theme/" "$GTK_SETTINGS" || echo "gtk-icon-theme-name=$icon_theme" >> "$GTK_SETTINGS"
fi
fi
log "Set dark theme ($theme_name) in gtk-3.0/settings.ini" && [[ -n "$icon_theme" ]] && log "Icon theme $icon_theme (custom start-here from step 05)"
# Ensure .profile exports prefer-dark for Libadwaita/GTK4 apps (session dark mode)
if [[ -f "$PI_HOME/.profile" ]] && ! grep -q 'ADW_DEBUG_COLOR_SCHEME\|COLOR_SCHEME.*prefer-dark' "$PI_HOME/.profile" 2>/dev/null; then
echo '' >> "$PI_HOME/.profile"
echo '# Prefer dark mode for GTK4/Libadwaita apps (cm4-provisioning first-boot)' >> "$PI_HOME/.profile"
echo 'export ADW_DEBUG_COLOR_SCHEME=prefer-dark' >> "$PI_HOME/.profile"
chown "$PI_USER:$PI_USER" "$PI_HOME/.profile"
log "Added prefer-dark export to .profile"
fi
# User GTK CSS: force start menu dropdown and all menus/popovers to full dark (matches Adwaita-dark palette)
if curl -fsSL "${FILE_SERVER}/gtk.css" -o "$PI_HOME/.config/gtk-3.0/gtk.css" 2>/dev/null; then
log "gtk.css installed (dark menu/popover override)"
fi
# Deploy dark taskbar (wf-panel-pi) so panel is dark and matches theme
local panel_conf="$PI_HOME/.config/wf-panel-pi"
mkdir -p "$panel_conf"
if curl -fsSL "${FILE_SERVER}/wf-panel-pi.ini" -o "$panel_conf/wf-panel-pi.ini" 2>/dev/null; then
sed -i "s|/home/pi|$PI_HOME|g" "$panel_conf/wf-panel-pi.ini"
if curl -fsSL "${FILE_SERVER}/panel-theme.css" -o "$panel_conf/panel-theme.css" 2>/dev/null; then
log "Taskbar theme (wf-panel-pi.ini, panel-theme.css) installed"
else
log "WARNING: Could not download panel-theme.css"
fi
else
log "WARNING: Could not download wf-panel-pi.ini (taskbar will use defaults)"
fi fi
log "Set dark theme ($GTK_THEME_NAME) in gtk-3.0/settings.ini"
chown -R "$PI_USER:$PI_USER" "$PI_HOME/.config" chown -R "$PI_USER:$PI_USER" "$PI_HOME/.config"
} }

View File

@@ -0,0 +1,89 @@
#!/usr/bin/env python3
# 5 taps in the top-right corner of the screen close Chromium (kiosk).
# Run from session autostart. Requires: python3, PyGObject (Gtk), Wayland or X11.
import subprocess
import sys
try:
import gi
gi.require_version("Gdk", "3.0")
gi.require_version("Gtk", "3.0")
from gi.repository import Gdk, Gtk, GLib
except Exception as e:
sys.stderr.write("five-tap-close-chromium: need PyGObject Gtk: %s\n" % e)
sys.exit(1)
CORNER_SIZE = 80
TAP_WINDOW_SEC = 2.0
CHROMIUM_KILL_CMD = ["pkill", "-f", "chromium"]
def get_screen_size():
display = Gdk.Display.get_default()
if not display:
return 800, 1280
monitor = display.get_monitor(0) if display.get_n_monitors() else None
if monitor:
geom = monitor.get_geometry()
return geom.width, geom.height
return 800, 1280
def on_button_press(widget, event, data):
count, reset_timer = data
count[0] += 1
if reset_timer[0]:
GLib.source_remove(reset_timer[0])
if count[0] >= 5:
count[0] = 0
try:
subprocess.run(CHROMIUM_KILL_CMD, timeout=2, capture_output=True)
except Exception:
pass
if reset_timer[0]:
GLib.source_remove(reset_timer[0])
reset_timer[0] = None
return
def reset():
count[0] = 0
reset_timer[0] = None
return False
reset_timer[0] = GLib.timeout_add(int(TAP_WINDOW_SEC * 1000), reset)
return False
def main():
win = Gtk.Window()
win.set_decorated(False)
win.set_resizable(False)
win.set_default_size(CORNER_SIZE, CORNER_SIZE)
win.set_skip_taskbar_hint(True)
win.set_skip_pager_hint(True)
win.set_keep_above(True)
win.set_opacity(0.01)
win.set_accept_focus(False)
win.set_focus_on_map(False)
# Allow closing from compositor / taskbar
win.connect("destroy", Gtk.main_quit)
# Count 5 taps
count = [0]
reset_timer = [None]
win.connect("button-press-event", on_button_press, (count, reset_timer))
# Touch events often come as button-press with button=1
win.set_events(
win.get_events()
| Gdk.EventMask.BUTTON_PRESS_MASK
| Gdk.EventMask.TOUCH_MASK
)
win.realize()
# Position top-right (after realization so we have a display)
w, h = get_screen_size()
x = max(0, w - CORNER_SIZE)
win.move(x, 0)
win.show_all()
Gtk.main()
if __name__ == "__main__":
main()

View File

@@ -19,7 +19,7 @@ profile {
} }
EOF EOF
# Set GTK dark theme (same as first-boot step 08) # Set GTK dark theme (same as first-boot step 08) and force dark mode via gsettings
GTK_THEME_NAME="PiXnoir" GTK_THEME_NAME="PiXnoir"
[[ -d /usr/share/themes/Adwaita-dark ]] && ! [[ -d /usr/share/themes/PiXnoir ]] && GTK_THEME_NAME="Adwaita-dark" [[ -d /usr/share/themes/Adwaita-dark ]] && ! [[ -d /usr/share/themes/PiXnoir ]] && GTK_THEME_NAME="Adwaita-dark"
GTK_SETTINGS="$HOME/.config/gtk-3.0/settings.ini" GTK_SETTINGS="$HOME/.config/gtk-3.0/settings.ini"
@@ -30,3 +30,12 @@ else
grep -q '^gtk-application-prefer-dark-theme=' "$GTK_SETTINGS" && sed -i 's/^gtk-application-prefer-dark-theme=.*/gtk-application-prefer-dark-theme=1/' "$GTK_SETTINGS" || echo 'gtk-application-prefer-dark-theme=1' >> "$GTK_SETTINGS" grep -q '^gtk-application-prefer-dark-theme=' "$GTK_SETTINGS" && sed -i 's/^gtk-application-prefer-dark-theme=.*/gtk-application-prefer-dark-theme=1/' "$GTK_SETTINGS" || echo 'gtk-application-prefer-dark-theme=1' >> "$GTK_SETTINGS"
grep -q '^gtk-theme-name=' "$GTK_SETTINGS" && sed -i "s/^gtk-theme-name=.*/gtk-theme-name=$GTK_THEME_NAME/" "$GTK_SETTINGS" || echo "gtk-theme-name=$GTK_THEME_NAME" >> "$GTK_SETTINGS" grep -q '^gtk-theme-name=' "$GTK_SETTINGS" && sed -i "s/^gtk-theme-name=.*/gtk-theme-name=$GTK_THEME_NAME/" "$GTK_SETTINGS" || echo "gtk-theme-name=$GTK_THEME_NAME" >> "$GTK_SETTINGS"
fi fi
# Force dark mode system-wide (GNOME/GTK apps that read gsettings)
if command -v gsettings >/dev/null 2>&1; then
gsettings set org.gnome.desktop.interface gtk-theme "$GTK_THEME_NAME" 2>/dev/null || true
gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark' 2>/dev/null || true
fi
# Preserve icon theme (PiXtrix = custom start-here)
if [[ -d /usr/share/icons/PiXtrix ]]; then
grep -q '^gtk-icon-theme-name=' "$GTK_SETTINGS" && sed -i 's/^gtk-icon-theme-name=.*/gtk-icon-theme-name=PiXtrix/' "$GTK_SETTINGS" || echo 'gtk-icon-theme-name=PiXtrix' >> "$GTK_SETTINGS"
fi

View File

@@ -2,7 +2,7 @@
# Revision: 2 # Revision: 2
# Start Chromium in app mode. Optional env vars: # Start Chromium in app mode. Optional env vars:
# CHROMIUM_APP_URL - URL to open (default: http://127.0.0.1:8080) # CHROMIUM_APP_URL - URL to open (default: http://127.0.0.1:8080)
# CHROMIUM_MODE - "fullscreen" or "kiosk" (default: fullscreen) # CHROMIUM_MODE - "kiosk" (default, fills whole screen) or "fullscreen"
# #
# Touch long-press → right-click: In Chromium on Wayland, long-press often does *not* # Touch long-press → right-click: In Chromium on Wayland, long-press often does *not*
# open the context menu (Chromium handles touch itself). Elsewhere (e.g. desktop) it may # open the context menu (Chromium handles touch itself). Elsewhere (e.g. desktop) it may
@@ -26,8 +26,8 @@ done
#CHROMIUM_APP_URL="${CHROMIUM_APP_URL:-http://127.0.0.1:8080}" #CHROMIUM_APP_URL="${CHROMIUM_APP_URL:-http://127.0.0.1:8080}"
CHROMIUM_APP_URL="${CHROMIUM_APP_URL:-https://tototheo.com}" CHROMIUM_APP_URL="${CHROMIUM_APP_URL:-https://tototheo.com}"
# Mode: "fullscreen" or "kiosk" # Mode: "kiosk" (fills whole screen, no taskbar gap) or "fullscreen"
CHROMIUM_MODE="${CHROMIUM_MODE:-fullscreen}" CHROMIUM_MODE="${CHROMIUM_MODE:-kiosk}"
CHROMIUM_OPTS="--noerrdialogs --disable-infobars --disable-session-crashed-bubble --disable-restore-session-state --no-first-run --password-store=basic --use-mock-keychain --ozone-platform=wayland --enable-features=WaylandWindowDecorations --disable-features=UseChromeOSDirectVideoDecoder --app=${CHROMIUM_APP_URL}" CHROMIUM_OPTS="--noerrdialogs --disable-infobars --disable-session-crashed-bubble --disable-restore-session-state --no-first-run --password-store=basic --use-mock-keychain --ozone-platform=wayland --enable-features=WaylandWindowDecorations --disable-features=UseChromeOSDirectVideoDecoder --app=${CHROMIUM_APP_URL}"

View File

@@ -51,6 +51,7 @@ rsync -avz --exclude='README.md' \
# Kiosk and scripts # Kiosk and scripts
rsync -avz \ rsync -avz \
"$CLOUDINIT_DIR/start-chromium.sh" \ "$CLOUDINIT_DIR/start-chromium.sh" \
"$CLOUDINIT_DIR/five-tap-close-chromium.py" \
"$CLOUDINIT_DIR/01-set-rotation-once.sh" \ "$CLOUDINIT_DIR/01-set-rotation-once.sh" \
"$CLOUDINIT_DIR/02-set-wallpaper-once.sh" \ "$CLOUDINIT_DIR/02-set-wallpaper-once.sh" \
"$CLOUDINIT_DIR/set-rotation-at-login.sh" \ "$CLOUDINIT_DIR/set-rotation-at-login.sh" \