diff --git a/README.md b/README.md index f415ec3..ff58773 100644 --- a/README.md +++ b/README.md @@ -122,13 +122,18 @@ same thing manually. Steam's web UI supports autoscroll but has no way to pass extra arguments to its helper, so the program patches the script that starts it. Steam checks its own -files at every start and repairs whatever looks changed, so the patch is written -to look unchanged. +files against its manifest - by size and timestamp - and reinstalls the whole +client package over anything that differs, so the patch is written to look +unchanged: the bytes the argument costs are taken back out of the script's +comments and the timestamp is put back. -As a fallback, for the case where that isn't possible, `-noverifyfiles` goes on -everything that starts Steam: its launcher, its autostart entry, and the -shortcuts it writes for single games. That one means Steam won't auto-repair -damaged files on its own just so you're aware of that. +If that can't be done - a script with no comments left to pay for the argument, +or one this version doesn't recognise - nothing is written and Steam is left +alone. A file of the wrong length costs the client package downloaded and +installed again, and a Steam that quits at the end of it instead of coming up; +no autoscroll in Steam is the smaller problem. Nothing is added to Steam's +launcher entry or to the shortcuts it writes for games, and Steam keeps +repairing its own installation. ## Commands diff --git a/doc/middleclick-autoscroll.1.scd b/doc/middleclick-autoscroll.1.scd index 5ca85f0..d937eef 100644 --- a/doc/middleclick-autoscroll.1.scd +++ b/doc/middleclick-autoscroll.1.scd @@ -142,23 +142,22 @@ that checks its files finds nothing to repair, and the argument survives however Steam was started - from the menu, from a game shortcut, from a launcher like Heroic or Lutris, from a terminal. -That is what has to work, because there is no way to make every possible way of -starting Steam carry an argument. *-noverifyfiles* is the second line rather -than the first: it covers the case where the script has no comments left to pay -for the argument and the patch has to grow the file. It goes on Steam's -launcher entry, on its entry in _~/.config/autostart_, which Steam writes as -soon as it is set to run at login, and on the shortcuts Steam writes for single -games, on the desktop and in the menu alike. A game is not an application this -program has anything to offer and none of them is listed under *Applications*, -but starting one is a Steam start like any other. The trade-off of the switch -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. +That is what has to work, because it is the only thing that does. A patch that +changes the length is never written, whatever else could be done to cover for +it: Steam checks its files at the shutdown it runs itself as well as at a start +it was given arguments for, and that one carries no arguments of anybody's. One +wrong length costs the whole client package downloaded, extracted and installed +again, and a client that quits at the end of it instead of coming up. -A patch that does change the size is still held back while the client is -running: Steam puts its own copy back, the two would only undo each other, and -the helper is started once, at the start, so patching again would not help that -session anyway. It goes in at the next apply with Steam closed. A patch that -keeps the size has nothing to wait for and goes in either way. +So where the comments cannot pay for the argument, or a client update has +changed how the helper is started, nothing is written and the status screen +says Steam is not patched. Nothing goes on Steam's launcher entry, its +autostart entry or the shortcuts it writes for single games either, and Steam +goes on repairing its own installation. + +An installation patched by an earlier version, which appended where the +comments were short, is written again to fit at the next apply, or taken back +if it cannot be made to. A client update brings a new version of the script. The watcher notices and patches it again, and the copy kept for undoing is replaced with the new diff --git a/po/de.po b/po/de.po index 4bc0922..3574900 100644 --- a/po/de.po +++ b/po/de.po @@ -43,9 +43,6 @@ 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" @@ -155,9 +152,6 @@ msgstr "Autoscroll ist für %d Anwendungen an." msgid "Applications that are already running pick this up when they are restarted." msgstr "Bereits laufende Anwendungen übernehmen das nach einem Neustart." -msgid "Steam's launcher now skips its file check, which is what keeps the change from being undone at every start." -msgstr "Steams Startereintrag überspringt jetzt die Dateiprüfung – nur so bleibt die Änderung bei jedem Start erhalten." - msgid "Could not start the watcher for newly installed applications." msgstr "Die Überwachung neu installierter Anwendungen konnte nicht gestartet werden." @@ -179,11 +173,11 @@ msgstr "Auf %d Anwendungen angewendet." msgid "Already applied to %d applications." 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 starts its interface in a way this version cannot change without Steam noticing; leaving it alone." +msgstr "Steam startet seine Oberfläche auf eine Art, die diese Version nicht ändern kann, ohne dass Steam es merkt; 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." +msgid "Steam's interface cannot be given the flag without leaving a file Steam would reinstall; the change has been taken back." +msgstr "Steams Oberfläche lässt sich das Flag nicht geben, ohne eine Datei zu hinterlassen, die Steam neu installieren würde; die Änderung wurde zurückgenommen." #. Help diff --git a/po/middleclick-autoscroll.pot b/po/middleclick-autoscroll.pot index 45cd735..924a4f4 100644 --- a/po/middleclick-autoscroll.pot +++ b/po/middleclick-autoscroll.pot @@ -43,9 +43,6 @@ msgstr "" msgid "not patched yet" msgstr "" -msgid "waiting until Steam is closed" -msgstr "" - #. Status block msgid "Autoscroll" @@ -155,9 +152,6 @@ msgstr "" msgid "Applications that are already running pick this up when they are restarted." msgstr "" -msgid "Steam's launcher now skips its file check, which is what keeps the change from being undone at every start." -msgstr "" - msgid "Could not start the watcher for newly installed applications." msgstr "" @@ -179,10 +173,10 @@ msgstr "" msgid "Already applied to %d applications." msgstr "" -msgid "Steam starts its interface in a way this version does not recognise; leaving it alone." +msgid "Steam starts its interface in a way this version cannot change without Steam noticing; leaving it alone." msgstr "" -msgid "Steam is running and has put its own file back; the change waits until Steam is closed." +msgid "Steam's interface cannot be given the flag without leaving a file Steam would reinstall; the change has been taken back." msgstr "" diff --git a/src/lib/apply.sh b/src/lib/apply.sh index 91e78c1..85df233 100644 --- a/src/lib/apply.sh +++ b/src/lib/apply.sh @@ -103,7 +103,9 @@ mca_apply() { mca_desktop_apply "$id" "$file" "$(mca_flags "$kind")" ;; steam) - mca_steam_desktop_apply "$id" "$file" "$packaging" + # Nothing is done to the entry itself: what Steam needs is + # in its own installation, and the same patch serves every + # way of starting the client. if (( ! steam_done )); then mca_steam_apply steam_done=1 @@ -118,30 +120,16 @@ mca_apply() { mca_steam_apply fi - # The shortcuts Steam writes for single games. They are not applications - # and are not offered as ones, but starting a game with Steam closed is a - # Steam start like any other: without the switch the client finds the - # patched helper script, puts its own back, and the interface loses - # autoscroll for the rest of the session. - if [[ $CFG_STEAM == yes ]]; then - for i in "${!MCA_STEAM_LINKS[@]}"; do - mca_steam_desktop_apply "${MCA_STEAM_LINKS[i]}" \ - "${MCA_STEAM_LINK_FILES[i]}" "${MCA_STEAM_LINK_PACK[i]}" - done - fi - - # 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 + # Autostart entries. A Chromium application that starts itself at login + # points straight at its binary and never reads the entry in the menu, so + # Discord at login used to behave differently from Discord from the menu. + if [[ $CFG_AUTOSTART == yes ]]; then mca_autostart_apply fi - # Shortcuts on the desktop itself. Nothing above has seen them - the XDG - # search path does not go there - and a game started from one starts Steam - # without its switch, which is the difference between autoscroll working - # and autoscroll working most of the time. Each entry is gated on its own, - # so there is nothing to check out here. + # Shortcuts on the desktop itself, which nothing above has seen: the XDG + # search path does not go there. Each entry is gated on its own, so there is + # nothing to check out here. mca_shortcuts_apply [[ $CFG_SPOTIFY == yes ]] && mca_spotify_apply diff --git a/src/lib/common.sh b/src/lib/common.sh index 63887c3..570dfa2 100644 --- a/src/lib/common.sh +++ b/src/lib/common.sh @@ -45,10 +45,14 @@ MCA_BROWSER_FLAG="--enable-features=MiddleClickAutoscroll,HeliumMiddleClickAutos MCA_FEATURE="MiddleClickAutoscroll" MCA_BROWSER_FEATURES="MiddleClickAutoscroll,HeliumMiddleClickAutoscroll" -# Bumped when the flags above change. An installation that was set up by a -# version with a different answer is taken back and done again once, because a -# file that is already patched is otherwise left alone. See mca_apply. -MCA_FLAG_SCHEME=2 +# Bumped when the flags above change, and when what gets written where does. +# An installation that was set up by a version with a different answer is taken +# back and done again once, because a file that is already patched is otherwise +# left alone. See mca_apply. +# +# 3 is what takes -noverifyfiles back out of the Steam entries an older version +# put it in. +MCA_FLAG_SCHEME=3 MCA_LIBDIR="${MCA_LIBDIR:-@LIBDIR@}" MCA_LOCALEDIR="${MCA_LOCALEDIR:-@LOCALEDIR@}" diff --git a/src/lib/detect.sh b/src/lib/detect.sh index 2a79dc1..9b41f2c 100644 --- a/src/lib/detect.sh +++ b/src/lib/detect.sh @@ -615,16 +615,6 @@ MCA_PROGS=() # resolved program, or a Flatpak app id or a snap name MCA_KINDS=() # app | browser | steam | unknown | no MCA_PACKAGING=() # native | flatpak | snap -# The shortcuts Steam writes for single games. Not applications of their own - a -# game is whatever engine it was built with, and none of those reads a Chromium -# argument - so they are kept apart from the list rather than listed as -# something that got switched on. They do start Steam, which is why they are -# kept at all: the Steam module gives them Steam's own switch. -MCA_STEAM_LINKS=() # desktop file id -MCA_STEAM_LINK_FILES=() # the entry that is in effect for it -MCA_STEAM_LINK_PACK=() # native | flatpak | snap, which decides where the - # switch goes on the command line - # A scan reads every desktop entry on the system, so the menu does it once and # then redraws from what it found. Applying rescans on its own, so nothing else # has to remember to invalidate this. @@ -642,7 +632,6 @@ mca_scan() { MCA_IDS=(); MCA_FILES=(); MCA_NAMES=(); MCA_PROGS=(); MCA_KINDS=() MCA_PACKAGING=() - MCA_STEAM_LINKS=(); MCA_STEAM_LINK_FILES=(); MCA_STEAM_LINK_PACK=() # Pass one: read the entries and work out what each of them starts. No # detection yet - that needs a stat per program, and those are collected so @@ -682,18 +671,12 @@ mca_scan() { prog="snap:$MCA_PROG" fi - if mca_exec_is_steam_link "$exec_line" "$prog"; then - MCA_STEAM_LINKS+=("$id") - MCA_STEAM_LINK_FILES+=("$file") - if [[ $prog == flatpak:* ]]; then - MCA_STEAM_LINK_PACK+=(flatpak) - elif [[ $prog == snap:* ]]; then - MCA_STEAM_LINK_PACK+=(snap) - else - MCA_STEAM_LINK_PACK+=(native) - fi - continue - fi + # The shortcuts Steam writes for single games are not + # applications of their own - a game is whatever engine it was + # built with, and none of those reads a Chromium argument - and + # starting the client through one needs nothing on its command + # line either. + mca_exec_is_steam_link "$exec_line" "$prog" && continue c_ids+=("$id"); c_files+=("$file"); c_names+=("$name") c_progs+=("$prog") diff --git a/src/lib/menu.sh b/src/lib/menu.sh index e6a433a..7d3d8cc 100644 --- a/src/lib/menu.sh +++ b/src/lib/menu.sh @@ -178,9 +178,6 @@ 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 3a01e42..11d8948 100644 --- a/src/lib/patch.sh +++ b/src/lib/patch.sh @@ -410,15 +410,6 @@ mca_desktop_apply() { # The desktop folder, where a shortcut somebody dragged out of the menu - # or asked Steam for - lives and nowhere else. # -# Steam is in both, even though it is not a Chromium process itself: its -# entries need -noverifyfiles exactly like the menu one. The autostart entry is -# the one 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. The desktop -# ones are the gap behind "autoscroll works, except sometimes": starting a game -# from the desktop is a Steam start like any other, and a Steam start without -# the switch costs the interface its autoscroll for the rest of the session. -# # Neither can be shadowed from anywhere, so both are edited where they stand, # with the original kept. @@ -426,11 +417,10 @@ mca_desktop_apply() { # One desktop entry that lives outside the XDG search path, edited where it is # because there is nowhere to shadow it from. # -# Anything that starts Steam gets Steam's own switch; a Chromium application -# gets the flag. What decides whether a Chromium application here is in scope -# differs by where the entry came from, which is what the gate says: an -# autostart entry follows the autostart setting, a shortcut follows the same -# rules as the application it is a shortcut to. +# What decides whether an application here is in scope differs by where the +# entry came from, which is what the gate says: an autostart entry follows the +# autostart setting, a shortcut follows the same rules as the application it is +# a shortcut to. _mca_entry_patch_inplace() { local file="$1" gate="$2" local id prog packaging=native content backup kind @@ -456,30 +446,29 @@ _mca_entry_patch_inplace() { packaging=snap fi - if mca_prog_is_steam "$prog"; then - [[ $CFG_STEAM == yes ]] || return 0 - content="$(_mca_desktop_transform "$file" "$MCA_MARK_INPLACE" \ - "$MCA_STEAM_LAUNCH_FLAG" "$(mca_steam_flag_position "$packaging")")" + # An entry that starts Steam is left where it is. Steam takes nothing + # from a command line that would help, and what it does take belongs to + # the web helper script in its own installation. + mca_prog_is_steam "$prog" && return 0 + + case "$packaging" in + flatpak) mca_flatpak_is_chromium "${prog#flatpak:}" || return 0 ;; + snap) mca_snap_is_chromium "${prog#snap:}" || return 0 ;; + *) mca_is_chromium "$prog" || return 0 ;; + esac + + mca_desktop_is_browser && kind=browser || kind=app + + if [[ $gate == autostart ]]; then + [[ $CFG_AUTOSTART == yes ]] || return 0 else - case "$packaging" in - flatpak) mca_flatpak_is_chromium "${prog#flatpak:}" || return 0 ;; - snap) mca_snap_is_chromium "${prog#snap:}" || return 0 ;; - *) mca_is_chromium "$prog" || return 0 ;; - esac - - mca_desktop_is_browser && kind=browser || kind=app - - if [[ $gate == autostart ]]; then - [[ $CFG_AUTOSTART == yes ]] || return 0 - else - id="${file##*/}"; id="${id%.desktop}" - mca_kind_wanted "$kind" "$id" "$packaging" || return 0 - fi - - content="$(_mca_desktop_transform "$file" "$MCA_MARK_INPLACE" \ - "$(mca_flags "$kind")")" + id="${file##*/}"; id="${id%.desktop}" + mca_kind_wanted "$kind" "$id" "$packaging" || return 0 fi + content="$(_mca_desktop_transform "$file" "$MCA_MARK_INPLACE" \ + "$(mca_flags "$kind")")" + [[ -n $content ]] || return 0 [[ "$content" == "$(< "$file")" ]] && return 0 diff --git a/src/lib/steam.sh b/src/lib/steam.sh index 02602b0..9123a08 100644 --- a/src/lib/steam.sh +++ b/src/lib/steam.sh @@ -18,25 +18,19 @@ # and the flag survives however Steam was started - from the menu, from a game # shortcut, from a launcher like Heroic, from a terminal. # -# That is the part that has to work, because there is no way to make every -# possible way of starting Steam carry an argument. -noverifyfiles on the -# launcher entries is the second line rather than the first: it covers the case -# where the script has no comments left to pay for the flag and the patch has -# to grow the file. The trade-off is real and belongs to the user, so it 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. -# -# A patch that does change the size still has to stay out of the way of a -# client that is already running, 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. A patch -# that keeps the size is invisible to that check and goes in either way. +# A patch that changes the length is not an option, and no switch covers for +# one. Steam checks its files at a start it was given arguments for, but also +# at the shutdown it runs itself - and that one has no -noverifyfiles on its +# command line, whatever the session was started with. What a single wrong +# length costs is the whole client package downloaded, extracted and installed +# again, and a client that quits at the end of it instead of coming up. So the +# flag either fits in the space the comments give back, or it is not written at +# all: no autoscroll in the interface is a smaller thing than a client that +# reinstalls itself. # # The file comes back on every client update, and the watcher re-applies the # patch when that happens. -MCA_STEAM_LAUNCH_FLAG='-noverifyfiles' - # Every place a Steam installation is known to live, resolved and de-duplicated # because ~/.steam/steam is normally a symlink into ~/.local/share. # @@ -88,24 +82,6 @@ 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" \ - "$HOME/snap/steam/common/.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