75 lines
2.1 KiB
Text
75 lines
2.1 KiB
Text
|
|
#!/bin/sh
|
||
|
|
|
||
|
|
# Restart `gnome-shell` in place,
|
||
|
|
# preserving the session and all windows
|
||
|
|
#
|
||
|
|
# Usually survives, but treat it like a logout:
|
||
|
|
# save your work first, because a crash on the way down can end the session
|
||
|
|
#
|
||
|
|
# Debian normally forbids starting/stopping this unit by hand;
|
||
|
|
# we allow it via a user-level drop-in (installed on first run)
|
||
|
|
|
||
|
|
set -eu
|
||
|
|
|
||
|
|
|
||
|
|
if [ "${XDG_SESSION_TYPE:-}" != "x11" ]; then
|
||
|
|
echo "gnome-shell-restart: only works on X11, not on ${XDG_SESSION_TYPE:-unknown}" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
|
||
|
|
_UNIT="org.gnome.Shell@x11.service"
|
||
|
|
|
||
|
|
_DROPIN_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user/$_UNIT.d"
|
||
|
|
_DROPIN_FILE="$_DROPIN_DIR/allow-restart.conf"
|
||
|
|
|
||
|
|
|
||
|
|
if [ ! -f "$_DROPIN_FILE" ] || ! grep -q "SuccessExitStatus" "$_DROPIN_FILE"; then
|
||
|
|
|
||
|
|
mkdir -p "$_DROPIN_DIR"
|
||
|
|
|
||
|
|
cat > "$_DROPIN_FILE" << 'EOF'
|
||
|
|
# Written by ~/.local/bin/gnome-shell-restart
|
||
|
|
|
||
|
|
# Debian forbids starting and stopping this unit by hand
|
||
|
|
# to protect Wayland sessions, where the shell cannot restart in place
|
||
|
|
# => We are on X11
|
||
|
|
[Unit]
|
||
|
|
RefuseManualStart=no
|
||
|
|
RefuseManualStop=no
|
||
|
|
|
||
|
|
# The old shell sometimes crashes while shutting down.
|
||
|
|
#
|
||
|
|
# Without this line, `systemd` treats that crash as a real failure
|
||
|
|
# and ends the whole session (i.e., logs us out)
|
||
|
|
#
|
||
|
|
# => We count a segfault as a normal exit
|
||
|
|
#
|
||
|
|
# If the shell truly keeps crashing, the start limit still ends the session
|
||
|
|
[Service]
|
||
|
|
SuccessExitStatus=1 SEGV
|
||
|
|
EOF
|
||
|
|
|
||
|
|
systemctl --user daemon-reload
|
||
|
|
fi
|
||
|
|
|
||
|
|
|
||
|
|
# The unit allows at most 3 starts per 15 seconds
|
||
|
|
# and one restart too many counts as a failure and logs us out
|
||
|
|
# => Refuse to restart again too soon after the last one
|
||
|
|
_STARTED="$(systemctl --user show -p ActiveEnterTimestamp --value "$_UNIT")"
|
||
|
|
if [ -n "$_STARTED" ]; then
|
||
|
|
_AGE=$(( $(date +%s) - $(date -d "$_STARTED" +%s) ))
|
||
|
|
if [ "$_AGE" -lt 20 ]; then
|
||
|
|
echo "gnome-shell-restart: last shell start was only ${_AGE}s ago" >&2
|
||
|
|
echo "gnome-shell-restart: refusing to trip the start limit (wait $(( 20 - _AGE ))s)" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
|
||
|
|
# Forget any earlier failure, so it does not block this restart
|
||
|
|
systemctl --user reset-failed "$_UNIT" 2> /dev/null || true
|
||
|
|
|
||
|
|
|
||
|
|
exec systemctl --user restart "$_UNIT"
|