#!/bin/sh # Install the GDM greeter's `dconf` settings into /etc/dconf/db/gdm.d/ # # The keys listed in `$MIRROR_PATHS` below are read from # the live user session and written as one keyfile # # The greeter runs as the `Debian-gdm` user and never sees # the user-level settings in ~/.config/gnome-settings/*.ini # # The keyfile is written, not symlinked, # so that the greeter does not depend on ~/ being readable # # Without root privileges, this script only checks and reports # => Run with `sudo` to install set -eu SELF_DIR=$(cd "$(dirname "$0")" && pwd) TARGET_DIR=/etc/dconf/db/gdm.d COMPILED_DB=/etc/dconf/db/gdm # Only files with this prefix are managed (and pruned) here PREFIX=90-dotfiles- MIRRORED=mirrored # Keys mirrored from the live user session into the GDM greeter # # One absolute `dconf` path per line # => Unset keys are skipped, so the greeter keeps its defaults MIRROR_PATHS=' # Idle and power # # Only the AC keys => On battery, the greeter keeps suspending /org/gnome/desktop/session/idle-delay /org/gnome/settings-daemon/plugins/power/idle-brightness /org/gnome/settings-daemon/plugins/power/idle-dim /org/gnome/settings-daemon/plugins/power/power-saver-profile-on-low-battery /org/gnome/settings-daemon/plugins/power/sleep-inactive-ac-timeout /org/gnome/settings-daemon/plugins/power/sleep-inactive-ac-type # Would disarm the physical power button at the greeter as well # /org/gnome/settings-daemon/plugins/power/power-button-action # Keyboard (e.g., Caps Lock as Control while typing the password) /org/gnome/desktop/input-sources/sources /org/gnome/desktop/input-sources/xkb-options /org/gnome/desktop/peripherals/keyboard/numlock-state # Touchpad and mouse /org/gnome/desktop/peripherals/mouse/natural-scroll /org/gnome/desktop/peripherals/touchpad/natural-scroll /org/gnome/desktop/peripherals/touchpad/tap-to-click # Top bar /org/gnome/desktop/interface/accent-color /org/gnome/desktop/interface/clock-format /org/gnome/desktop/interface/clock-show-date /org/gnome/desktop/interface/clock-show-seconds /org/gnome/desktop/interface/clock-show-weekday /org/gnome/desktop/interface/show-battery-percentage ' if ! command -v gdm3 >/dev/null 2>&1 && [ ! -d /etc/gdm3 ]; then echo "GDM is not installed => Nothing to do" exit 0 fi if ! command -v dconf >/dev/null 2>&1; then echo "dconf is not installed" >&2 exit 1 fi # As root, the live settings must come from the invoking user if [ "$(id -u)" = 0 ] && [ "${SUDO_USER:-root}" = "root" ]; then echo "Run via sudo from the user whose settings to mirror" >&2 exit 1 fi # The mirrored paths, without comments and blank lines _mirror_paths() { printf '%s\n' "$MIRROR_PATHS" | grep -Ev '^[[:space:]]*(#|$)' | sort -u } # `dconf read` as the session user, also when run via `sudo` # (reads need no D-Bus, only the user's database file) _dconf_read() { if [ "$(id -u)" = 0 ]; then _home=$(getent passwd "$SUDO_USER" | cut -d: -f6) runuser -u "$SUDO_USER" -- env \ HOME="$_home" \ XDG_CONFIG_HOME="$_home/.config" \ XDG_RUNTIME_DIR="/run/user/$(id -u "$SUDO_USER")" \ dconf read "$1" else dconf read "$1" fi } _render_mirrored() { echo "# Written by gdm-settings-install from the live user session - do not edit" _mirror_paths | while IFS= read -r path; do _value=$(_dconf_read "$path") [ -n "$_value" ] || continue # Unset => Keep the greeter's default _dir=${path%/*} _dir=${_dir#/} if [ "$_dir" != "${_last:-}" ]; then printf '\n[%s]\n' "$_dir" _last=$_dir fi printf '%s=%s\n' "${path##*/}" "$_value" done } _in_sync() { [ -f "$COMPILED_DB" ] || return 1 _render_mirrored | cmp -s - "$TARGET_DIR/$PREFIX$MIRRORED" || return 1 # No other managed file may be left over (e.g., from older versions) for dst in "$TARGET_DIR/$PREFIX"*; do [ -e "$dst" ] || continue [ "${dst##*/$PREFIX}" = "$MIRRORED" ] || return 1 done # The compiled database must be newer than the keyfiles [ -z "$(find "$TARGET_DIR" -newer "$COMPILED_DB" 2>/dev/null)" ] } if _in_sync; then echo "GDM settings are up to date" exit 0 fi if [ "$(id -u)" != 0 ]; then echo "" >&2 echo "GDM settings are not installed or outdated" >&2 echo "" >&2 echo "Fix with: sudo $SELF_DIR/$(basename "$0")" >&2 echo "" >&2 exit 1 fi mkdir -p "$TARGET_DIR" for dst in "$TARGET_DIR/$PREFIX"*; do [ -e "$dst" ] || continue [ "${dst##*/$PREFIX}" = "$MIRRORED" ] || rm -v -- "$dst" done _rendered=$(mktemp) trap 'rm -f "$_rendered"' EXIT _render_mirrored > "$_rendered" install -v -m 644 -- "$_rendered" "$TARGET_DIR/$PREFIX$MIRRORED" dconf update # Debian's `gdm` profile must read the "gdm" system database if ! grep -qs '^system-db:gdm$' /etc/dconf/profile/gdm /usr/share/dconf/profile/gdm; then echo "WARN: no dconf profile for gdm reads system-db:gdm" >&2 fi echo "Installed the GDM settings into: $TARGET_DIR" echo "They take effect at the next start of the greeter (e.g., reboot)"