diff --git a/README.md b/README.md index 8a58d41..ec1850c 100644 --- a/README.md +++ b/README.md @@ -118,17 +118,26 @@ Steam's own installation: ~/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh ``` -Steam checksums that script at every start and restores it when it differs, so -its launcher entry also gets `-noverifyfiles`. **The trade-off is real**: with -verification off, Steam no longer repairs a damaged installation by itself. That -is why Steam is a switch of its own rather than part of the general handling — -turn it off in the settings and Steam is left completely alone. +Steam compares the installed files against its manifest at every start — by +size, not by content — and restores whatever differs, so its launcher entry gets +`-noverifyfiles`. So does its entry in `~/.config/autostart`, which Steam writes +as soon as it is set to run at login: that one bypasses the menu entry entirely, +and without the switch a Steam started at login finds the patched script, +restores it, gets patched again, and never gets past its update dialog. + +**The trade-off is real**: with verification off, Steam no longer repairs a +damaged installation by itself. That is why Steam is a switch of its own rather +than part of the general handling — turn it off in the settings and Steam is +left completely alone. The script comes back on every client update. The watcher notices and puts the patch back. -Starting Steam from a terminal without `-noverifyfiles` undoes it for that one -session; the next start from the menu has it again. +Starting Steam some other way — from a terminal, from a script — leaves the +switch out and Steam puts its own copy back for that session. The patch returns +at the next apply with Steam closed; it is deliberately not repeated while the +client is running, because the two would only undo each other and the helper is +started once, at the start. ## Applications installed later diff --git a/doc/middleclick-autoscroll.1.scd b/doc/middleclick-autoscroll.1.scd index 9118368..961e371 100644 --- a/doc/middleclick-autoscroll.1.scd +++ b/doc/middleclick-autoscroll.1.scd @@ -98,14 +98,21 @@ helper, inside Steam's own installation: ~/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh -Steam checksums that script at every start and restores it when it differs, so -its launcher entry also gets *-noverifyfiles*. The trade-off is that Steam no -longer repairs a damaged installation on its own; that is why Steam is a switch -of its own in the settings. +Steam compares the installed files against its manifest at every start - by +size, not by content - and restores whatever differs, so its launcher entry +gets *-noverifyfiles*. So does its entry in _~/.config/autostart_, which Steam +writes as soon as it is set to run at login: that entry bypasses the menu one +entirely, and without the switch a Steam started at login spends the session in +an update dialog. The trade-off is that Steam no longer repairs a damaged +installation on its own; that is why Steam is a switch of its own in the +settings. -Starting Steam from a terminal without *-noverifyfiles* undoes the patch for -that session. The watcher notices and puts it back, so the next start has it -again. +Starting Steam some other way - from a terminal, from a script - leaves the +switch out, and Steam puts its own copy of the script back for that session. +The patch returns at the next apply with Steam closed. It is deliberately not +repeated while the client is running: the two would only undo each other, and +the helper is started once, at the start, so it would not help that session +anyway. # SPOTIFY diff --git a/po/de.po b/po/de.po index e10d616..c8edeb1 100644 --- a/po/de.po +++ b/po/de.po @@ -43,6 +43,9 @@ msgstr "nicht erkennbar" msgid "not patched yet" msgstr "noch nicht gepatcht" +msgid "waiting until Steam is closed" +msgstr "wartet, bis Steam geschlossen ist" + #. Status block msgid "Autoscroll" @@ -176,6 +179,9 @@ msgstr "Bereits auf %d Anwendungen angewendet." msgid "Steam starts its interface in a way this version does not recognise; leaving it alone." msgstr "Steam startet seine Oberfläche auf eine Art, die diese Version nicht kennt; Steam bleibt unangetastet." +msgid "Steam is running and has put its own file back; the change waits until Steam is closed." +msgstr "Steam läuft und hat seine eigene Datei wiederhergestellt; die Änderung wird nachgeholt, sobald Steam geschlossen ist." + #. Help msgid "Usage: middleclick-autoscroll [command]" diff --git a/po/middleclick-autoscroll.pot b/po/middleclick-autoscroll.pot index 0cab8d1..48ec7d2 100644 --- a/po/middleclick-autoscroll.pot +++ b/po/middleclick-autoscroll.pot @@ -43,6 +43,9 @@ msgstr "" msgid "not patched yet" msgstr "" +msgid "waiting until Steam is closed" +msgstr "" + #. Status block msgid "Autoscroll" @@ -176,6 +179,9 @@ msgstr "" msgid "Steam starts its interface in a way this version does not recognise; leaving it alone." msgstr "" +msgid "Steam is running and has put its own file back; the change waits until Steam is closed." +msgstr "" + #. Help msgid "Usage: middleclick-autoscroll [command]" diff --git a/src/lib/apply.sh b/src/lib/apply.sh index fa58873..25d0f3c 100644 --- a/src/lib/apply.sh +++ b/src/lib/apply.sh @@ -107,7 +107,12 @@ mca_apply() { mca_steam_apply fi - [[ $CFG_AUTOSTART == yes ]] && mca_autostart_apply + # Steam's autostart entry carries Steam's own switch and follows the Steam + # setting, not this one - leaving it out while Steam is patched is what puts + # the client in an update loop - so both are checked inside. + if [[ $CFG_AUTOSTART == yes || $CFG_STEAM == yes ]]; then + mca_autostart_apply + fi [[ $CFG_SPOTIFY == yes ]] && mca_spotify_apply mca_prune_orphans diff --git a/src/lib/common.sh b/src/lib/common.sh index afcabfb..e833c8f 100644 --- a/src/lib/common.sh +++ b/src/lib/common.sh @@ -239,6 +239,14 @@ mca_ledger_forget() { } +# mca_backup_name +# The name a backup copy of that file is stored under. Derived from the path +# rather than remembered, so a caller can ask whether a file has been backed up +# before without reading the ledger. +mca_backup_name() { + printf '%s' "$1" | sed 's|/|%|g' +} + # mca_backup # Copies a file aside before it is edited in place, and prints the name the # copy was stored under. Existing backups are never overwritten: the first copy @@ -246,7 +254,7 @@ mca_ledger_forget() { # patched version. mca_backup() { local file="$1" name - name="$(printf '%s' "$file" | sed 's|/|%|g')" + name="$(mca_backup_name "$file")" mkdir -p "$MCA_BACKUPDIR" 2>/dev/null || return 1 if [[ ! -e "$MCA_BACKUPDIR/$name" ]]; then diff --git a/src/lib/menu.sh b/src/lib/menu.sh index d55da2a..888fbaf 100644 --- a/src/lib/menu.sh +++ b/src/lib/menu.sh @@ -178,6 +178,9 @@ mca_ui_status() { if mca_steam_installed; then if mca_steam_patched; then _mca_row "$(mca_msg "Steam")" "$(_mca_onoff yes)" + elif [[ $CFG_STEAM == yes && $CFG_ENABLED == yes ]] && mca_steam_waiting; then + _mca_row "$(mca_msg "Steam")" \ + "${MCA_C_DIM}$(mca_msg "waiting until Steam is closed")${MCA_C_RESET}" elif [[ $CFG_STEAM == yes && $CFG_ENABLED == yes ]]; then _mca_row "$(mca_msg "Steam")" \ "${MCA_C_YELLOW}$(mca_msg "not patched yet")${MCA_C_RESET}" diff --git a/src/lib/patch.sh b/src/lib/patch.sh index 1597698..d556c4b 100644 --- a/src/lib/patch.sh +++ b/src/lib/patch.sh @@ -345,6 +345,12 @@ mca_desktop_apply() { # ~/.config/autostart, pointing straight at their binary. Those bypass the # desktop entry in the menu completely, which is why Discord launched at login # used to behave differently from Discord launched from the menu. +# +# Steam is here too, even though it is not a Chromium process itself: its entry +# needs -noverifyfiles exactly like the menu one, and it is the entry most +# likely to exist, because Steam writes it as soon as "run at startup" is +# ticked. Without it, a Steam started at login restores the patched web helper +# script and the watcher patches it back, over and over. mca_autostart_apply() { local dir="$MCA_XDG_CONFIG/autostart" file exec_line prog content backup @@ -360,9 +366,16 @@ mca_autostart_apply() { mca_exec_program "$exec_line" || continue prog="$MCA_PROG" - mca_is_chromium "$prog" || continue - content="$(_mca_desktop_transform "$file" "$MCA_MARK_INPLACE")" + if [[ ${prog##*/} == steam || ${prog##*/} == steam-runtime ]]; then + [[ $CFG_STEAM == yes ]] || continue + content="$(_mca_desktop_transform "$file" "$MCA_MARK_INPLACE" \ + "$MCA_STEAM_LAUNCH_FLAG" after-program)" + else + [[ $CFG_AUTOSTART == yes ]] || continue + mca_is_chromium "$prog" || continue + content="$(_mca_desktop_transform "$file" "$MCA_MARK_INPLACE")" + fi [[ -n $content ]] || continue [[ "$content" == "$(< "$file")" ]] && continue diff --git a/src/lib/steam.sh b/src/lib/steam.sh index 09c31f7..e7bce3c 100644 --- a/src/lib/steam.sh +++ b/src/lib/steam.sh @@ -9,11 +9,19 @@ # # ~/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh # -# Steam checksums that script at every start and restores it when it differs, -# which is why the launcher gets -noverifyfiles as well. The trade-off is real -# and belongs to the user, so this is a switch of its own rather than part of -# the general application handling: with verification off, Steam no longer -# repairs a damaged installation by itself. +# Steam compares the installed files against its manifest at every start - by +# size, not by content - and restores whatever differs, which is why the +# launcher gets -noverifyfiles as well. The trade-off is real and belongs to +# the user, so this is a switch of its own rather than part of the general +# application handling: with verification off, Steam no longer repairs a +# damaged installation by itself. +# +# Every way of starting Steam has to carry that switch, or the two programs +# spend the session undoing each other: Steam restores the script, the watcher +# patches it again, Steam restores it again, and the client never gets past its +# update dialog. So the autostart entry gets it as well as the menu one (see +# mca_autostart_apply), and the patch below stays out of the way of a client +# that is already running. # # The file comes back on every client update, and the watcher re-applies the # patch when that happens. @@ -64,6 +72,23 @@ mca_steam_installed() { return 1 } +# mca_steam_running +# Steam records its own process id beside its installation while it runs. The +# file outlives a crash, so the id is checked rather than believed. +mca_steam_running() { + local f pid + for f in \ + "$HOME/.steam/steam.pid" \ + "$HOME/.var/app/com.valvesoftware.Steam/.steam/steam.pid" + do + [[ -r $f ]] || continue + pid="$(< "$f")" + [[ $pid =~ ^[0-9]+$ ]] || continue + kill -0 "$pid" 2>/dev/null && return 0 + done + return 1 +} + # mca_steam_script_patched