Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af82ffec78 | ||
|
|
b7e0ff6fd1 |
No files matched your search
@@ -8,7 +8,7 @@
|
|||||||
# Overridable so a packager can pass the version it is actually building
|
# Overridable so a packager can pass the version it is actually building
|
||||||
# (`make VERSION=$pkgver`). The literal below is the fallback for builds
|
# (`make VERSION=$pkgver`). The literal below is the fallback for builds
|
||||||
# straight from a checkout, and is what a release tag has to carry.
|
# straight from a checkout, and is what a release tag has to carry.
|
||||||
VERSION ?= 1.1.0
|
VERSION ?= 1.2.0
|
||||||
|
|
||||||
PREFIX ?= /usr
|
PREFIX ?= /usr
|
||||||
DESTDIR ?=
|
DESTDIR ?=
|
||||||
|
|||||||
@@ -73,9 +73,17 @@ same thing manually.
|
|||||||
## Steam
|
## Steam
|
||||||
|
|
||||||
Steam's web UI supports autoscroll but has no way to pass extra arguments to its
|
Steam's web UI supports autoscroll but has no way to pass extra arguments to its
|
||||||
helper. The program patches the helper launch script and adds `-noverifyfiles`
|
helper, so the program patches the script that starts it. Steam checks its own
|
||||||
to Steam's launcher so the patch sticks. That means Steam won't auto-repair
|
files at every start and repairs whatever looks changed, so the patch is written
|
||||||
damaged files on its own — you can turn this off separately in the settings.
|
to look unchanged: the bytes the argument costs come back out of the script's
|
||||||
|
comments and the timestamp is restored, leaving a file exactly as long and as old
|
||||||
|
as Steam left it. It survives however you start Steam — the menu, a desktop
|
||||||
|
shortcut, a game launcher, a terminal.
|
||||||
|
|
||||||
|
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 — you can turn it off separately in the settings.
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,13 @@ Programs that start themselves at login write their own entry into
|
|||||||
_~/.config/autostart_ pointing straight at their binary, bypassing the menu
|
_~/.config/autostart_ pointing straight at their binary, bypassing the menu
|
||||||
entry entirely. Those are patched in place as well.
|
entry entirely. Those are patched in place as well.
|
||||||
|
|
||||||
|
Shortcuts on the desktop itself are patched in place too. Nothing in the XDG
|
||||||
|
search path looks at that folder, so a shortcut that lives only there would
|
||||||
|
otherwise be invisible - and Steam puts one there for every game somebody asks
|
||||||
|
for a shortcut to. The folder's name is translated, and the name in use is read
|
||||||
|
from _~/.config/user-dirs.dirs_ rather than guessed; the watcher is told about
|
||||||
|
it in a drop-in written when autoscroll is turned on.
|
||||||
|
|
||||||
# STEAM
|
# STEAM
|
||||||
|
|
||||||
Steam's interface is CEF and supports the feature, but Steam builds the command
|
Steam's interface is CEF and supports the feature, but Steam builds the command
|
||||||
@@ -116,26 +123,36 @@ _~/.steam/debian-installation_ for Debian's, and the private tree of the
|
|||||||
sandbox for the Flatpak and the snap. All of them are looked at.
|
sandbox for the Flatpak and the snap. All of them are looked at.
|
||||||
|
|
||||||
Steam compares the installed files against its manifest at every start - by
|
Steam compares the installed files against its manifest at every start - by
|
||||||
size, not by content - and restores whatever differs, so its launcher entry
|
size and timestamp rather than by content - and restores whatever differs. So
|
||||||
gets *-noverifyfiles*. So does its entry in _~/.config/autostart_, which Steam
|
the patch is written to look untouched: the bytes the argument costs are taken
|
||||||
writes as soon as it is set to run at login: that entry bypasses the menu one
|
back out of the script's own comments and the timestamp is put back afterwards,
|
||||||
entirely, and without the switch a Steam started at login spends the session in
|
leaving a file exactly as long and exactly as old as Steam left it. A client
|
||||||
an update dialog. The trade-off is that Steam no longer repairs a damaged
|
that checks its files finds nothing to repair, and the argument survives
|
||||||
installation on its own; that is why Steam is a switch of its own in the
|
however Steam was started - from the menu, from a game shortcut, from a
|
||||||
settings.
|
launcher like Heroic or Lutris, from a terminal.
|
||||||
|
|
||||||
The shortcuts Steam writes for single games carry the switch too. A game is not
|
That is what has to work, because there is no way to make every possible way of
|
||||||
an application this program has anything to offer and none of them is listed
|
starting Steam carry an argument. *-noverifyfiles* is the second line rather
|
||||||
under *Applications*, but starting one with Steam closed is a Steam start like
|
than the first: it covers the case where the script has no comments left to pay
|
||||||
any other, and without the switch it costs the interface its autoscroll for the
|
for the argument and the patch has to grow the file. It goes on Steam's
|
||||||
rest of the session.
|
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.
|
||||||
|
|
||||||
Starting Steam some other way - from a terminal, from a script - leaves the
|
A patch that does change the size is still held back while the client is
|
||||||
switch out, and Steam puts its own copy of the script back for that session.
|
running: Steam puts its own copy back, the two would only undo each other, and
|
||||||
The patch returns at the next apply with Steam closed. It is deliberately not
|
the helper is started once, at the start, so patching again would not help that
|
||||||
repeated while the client is running: the two would only undo each other, and
|
session anyway. It goes in at the next apply with Steam closed. A patch that
|
||||||
the helper is started once, at the start, so it would not help that session
|
keeps the size has nothing to wait for and goes in either way.
|
||||||
anyway.
|
|
||||||
|
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
|
||||||
|
version at the same time, so undoing puts back the script Steam last shipped
|
||||||
|
rather than the one from before the update.
|
||||||
|
|
||||||
# SPOTIFY
|
# SPOTIFY
|
||||||
|
|
||||||
|
|||||||
@@ -23,12 +23,18 @@ PathModified=/run/current-system/sw/share/applications
|
|||||||
PathModified=%h/.nix-profile/share/applications
|
PathModified=%h/.nix-profile/share/applications
|
||||||
PathModified=%h/.guix-profile/share/applications
|
PathModified=%h/.guix-profile/share/applications
|
||||||
|
|
||||||
|
# The desktop folder is watched too - Steam writes a shortcut there for every
|
||||||
|
# game somebody asks for one, and starting a game is a Steam start - but its
|
||||||
|
# name is translated and cannot be written down here. `enable` adds it in a
|
||||||
|
# drop-in, from the name this system uses.
|
||||||
|
|
||||||
# Steam replaces the script that starts its interface on every client update,
|
# Steam replaces the script that starts its interface on every client update,
|
||||||
# which takes the patch with it. Where that installation lives depends on how
|
# which takes the patch with it. Where that installation lives depends on how
|
||||||
# Steam was installed.
|
# Steam was installed.
|
||||||
PathChanged=%h/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
PathChanged=%h/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||||
PathChanged=%h/.steam/debian-installation/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
PathChanged=%h/.steam/debian-installation/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||||
PathChanged=%h/.var/app/com.valvesoftware.Steam/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
PathChanged=%h/.var/app/com.valvesoftware.Steam/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||||
|
PathChanged=%h/.var/app/com.valvesoftware.Steam/data/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||||
PathChanged=%h/snap/steam/common/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
PathChanged=%h/snap/steam/common/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||||
|
|
||||||
Unit=middleclick-autoscroll.service
|
Unit=middleclick-autoscroll.service
|
||||||
|
|||||||
+56
-2
@@ -93,7 +93,7 @@ mca_apply() {
|
|||||||
mca_desktop_apply "$id" "$file"
|
mca_desktop_apply "$id" "$file"
|
||||||
;;
|
;;
|
||||||
steam)
|
steam)
|
||||||
mca_steam_desktop_apply "$id" "$file"
|
mca_steam_desktop_apply "$id" "$file" "$packaging"
|
||||||
if (( ! steam_done )); then
|
if (( ! steam_done )); then
|
||||||
mca_steam_apply
|
mca_steam_apply
|
||||||
steam_done=1
|
steam_done=1
|
||||||
@@ -115,7 +115,8 @@ mca_apply() {
|
|||||||
# autoscroll for the rest of the session.
|
# autoscroll for the rest of the session.
|
||||||
if [[ $CFG_STEAM == yes ]]; then
|
if [[ $CFG_STEAM == yes ]]; then
|
||||||
for i in "${!MCA_STEAM_LINKS[@]}"; do
|
for i in "${!MCA_STEAM_LINKS[@]}"; do
|
||||||
mca_steam_desktop_apply "${MCA_STEAM_LINKS[i]}" "${MCA_STEAM_LINK_FILES[i]}"
|
mca_steam_desktop_apply "${MCA_STEAM_LINKS[i]}" \
|
||||||
|
"${MCA_STEAM_LINK_FILES[i]}" "${MCA_STEAM_LINK_PACK[i]}"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -125,6 +126,14 @@ mca_apply() {
|
|||||||
if [[ $CFG_AUTOSTART == yes || $CFG_STEAM == yes ]]; then
|
if [[ $CFG_AUTOSTART == yes || $CFG_STEAM == yes ]]; then
|
||||||
mca_autostart_apply
|
mca_autostart_apply
|
||||||
fi
|
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.
|
||||||
|
mca_shortcuts_apply
|
||||||
|
|
||||||
[[ $CFG_SPOTIFY == yes ]] && mca_spotify_apply
|
[[ $CFG_SPOTIFY == yes ]] && mca_spotify_apply
|
||||||
|
|
||||||
mca_prune_orphans
|
mca_prune_orphans
|
||||||
@@ -161,6 +170,12 @@ mca_revert() {
|
|||||||
MCA_UNIT_PATH="middleclick-autoscroll.path"
|
MCA_UNIT_PATH="middleclick-autoscroll.path"
|
||||||
MCA_UNIT_SERVICE="middleclick-autoscroll.service"
|
MCA_UNIT_SERVICE="middleclick-autoscroll.service"
|
||||||
|
|
||||||
|
# The desktop folder is watched like every other directory an entry can turn up
|
||||||
|
# in, but its name is translated and the unit that ships with the package
|
||||||
|
# cannot know it. So that one path is written here, into a drop-in, from the
|
||||||
|
# name this system actually uses.
|
||||||
|
MCA_UNIT_DROPIN="${MCA_XDG_CONFIG}/systemd/user/${MCA_UNIT_PATH}.d"
|
||||||
|
|
||||||
mca_watch_available() {
|
mca_watch_available() {
|
||||||
mca_have systemctl && [[ -n ${XDG_RUNTIME_DIR:-} || -S "/run/user/$(id -u)/bus" ]]
|
mca_have systemctl && [[ -n ${XDG_RUNTIME_DIR:-} || -S "/run/user/$(id -u)/bus" ]]
|
||||||
}
|
}
|
||||||
@@ -170,17 +185,56 @@ mca_watch_enabled() {
|
|||||||
systemctl --user is-enabled --quiet "$MCA_UNIT_PATH" 2>/dev/null
|
systemctl --user is-enabled --quiet "$MCA_UNIT_PATH" 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# _mca_watch_dropin_write
|
||||||
|
# Returns 0 when the drop-in changed and systemd has to be told, 1 when it was
|
||||||
|
# already right - the same contract as mca_write_if_changed, and for the same
|
||||||
|
# reason: the watcher runs after every desktop entry that appears anywhere on
|
||||||
|
# the system, and a daemon-reload each time would be absurd.
|
||||||
|
_mca_watch_dropin_write() {
|
||||||
|
local dir file="$MCA_UNIT_DROPIN/desktop.conf" content
|
||||||
|
|
||||||
|
dir="$(mca_desktop_folder)"
|
||||||
|
[[ -d $dir ]] || { _mca_watch_dropin_remove; return $?; }
|
||||||
|
|
||||||
|
# A per cent sign starts a specifier in a unit file and has to be doubled
|
||||||
|
# to mean itself. Rare in a folder name, fatal when it happens.
|
||||||
|
content="[Path]"$'\n'"PathModified=${dir//%/%%}"$'\n'
|
||||||
|
|
||||||
|
mca_write_if_changed "$file" "$content"
|
||||||
|
}
|
||||||
|
|
||||||
|
_mca_watch_dropin_remove() {
|
||||||
|
[[ -e "$MCA_UNIT_DROPIN/desktop.conf" ]] || return 1
|
||||||
|
rm -f -- "$MCA_UNIT_DROPIN/desktop.conf"
|
||||||
|
rmdir "$MCA_UNIT_DROPIN" 2>/dev/null || true
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
mca_watch_enable() {
|
mca_watch_enable() {
|
||||||
mca_watch_available || return 1
|
mca_watch_available || return 1
|
||||||
|
_mca_watch_dropin_write
|
||||||
|
systemctl --user daemon-reload > /dev/null 2>&1 || true
|
||||||
systemctl --user enable --now "$MCA_UNIT_PATH" > /dev/null 2>&1 || return 1
|
systemctl --user enable --now "$MCA_UNIT_PATH" > /dev/null 2>&1 || return 1
|
||||||
systemctl --user enable "$MCA_UNIT_SERVICE" > /dev/null 2>&1 || true
|
systemctl --user enable "$MCA_UNIT_SERVICE" > /dev/null 2>&1 || true
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# mca_watch_refresh
|
||||||
|
# Keeps a running watcher in step with a desktop folder that has been renamed,
|
||||||
|
# which is what a change of session language does to it.
|
||||||
|
mca_watch_refresh() {
|
||||||
|
mca_watch_available || return 0
|
||||||
|
_mca_watch_dropin_write || return 0
|
||||||
|
systemctl --user daemon-reload > /dev/null 2>&1 || true
|
||||||
|
systemctl --user restart "$MCA_UNIT_PATH" > /dev/null 2>&1 || true
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
mca_watch_disable() {
|
mca_watch_disable() {
|
||||||
mca_watch_available || return 0
|
mca_watch_available || return 0
|
||||||
systemctl --user disable --now "$MCA_UNIT_PATH" > /dev/null 2>&1 || true
|
systemctl --user disable --now "$MCA_UNIT_PATH" > /dev/null 2>&1 || true
|
||||||
systemctl --user disable "$MCA_UNIT_SERVICE" > /dev/null 2>&1 || true
|
systemctl --user disable "$MCA_UNIT_SERVICE" > /dev/null 2>&1 || true
|
||||||
|
_mca_watch_dropin_remove && systemctl --user daemon-reload > /dev/null 2>&1
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,29 @@ MCA_BACKUPDIR="${MCA_STATEDIR}/backup"
|
|||||||
# else. See mca_ledger_add.
|
# else. See mca_ledger_add.
|
||||||
MCA_LEDGER="${MCA_STATEDIR}/ledger"
|
MCA_LEDGER="${MCA_STATEDIR}/ledger"
|
||||||
|
|
||||||
|
# The folder the desktop itself shows. Nothing in the XDG search path looks at
|
||||||
|
# it, so an entry that lives only there is invisible to a scan - and a game
|
||||||
|
# shortcut dragged onto the desktop is exactly that.
|
||||||
|
#
|
||||||
|
# Its name is translated: Schreibtisch, Bureau, Escritorio. The name in use is
|
||||||
|
# in the file xdg-user-dirs writes, so it is read rather than guessed, and
|
||||||
|
# ~/Desktop is only the fallback for a system that has no such file.
|
||||||
|
mca_desktop_folder() {
|
||||||
|
local file="$MCA_XDG_CONFIG/user-dirs.dirs" line dir=''
|
||||||
|
|
||||||
|
if [[ -r $file ]]; then
|
||||||
|
while IFS= read -r line; do
|
||||||
|
[[ $line == XDG_DESKTOP_DIR=* ]] || continue
|
||||||
|
dir="${line#XDG_DESKTOP_DIR=}"
|
||||||
|
dir="${dir%\"}"; dir="${dir#\"}"
|
||||||
|
done < "$file"
|
||||||
|
dir="${dir/#\$HOME/$HOME}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ $dir == /* ]] || dir="$HOME/Desktop"
|
||||||
|
printf '%s\n' "${dir%/}"
|
||||||
|
}
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Translations
|
# Translations
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
+32
-17
@@ -99,17 +99,6 @@ mca_desktop_dirs() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
# mca_desktop_get <file> <key>
|
|
||||||
# A single value from the [Desktop Entry] group. Desktop Action groups repeat
|
|
||||||
# the same keys, and reading past the first group would pick up the wrong one.
|
|
||||||
mca_desktop_get() {
|
|
||||||
local file="$1" key="$2"
|
|
||||||
awk -v key="$key" '
|
|
||||||
/^[[:space:]]*\[/ { inentry = ($0 ~ /^[[:space:]]*\[Desktop Entry\][[:space:]]*$/); next }
|
|
||||||
inentry && index($0, key "=") == 1 { print substr($0, length(key) + 2); exit }
|
|
||||||
' "$file" 2>/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# _mca_desktop_read <file>
|
# _mca_desktop_read <file>
|
||||||
# Every key the scan needs, in one pass and without a single fork. There are a
|
# Every key the scan needs, in one pass and without a single fork. There are a
|
||||||
# couple of hundred desktop entries on an ordinary system, and doing this with
|
# couple of hundred desktop entries on an ordinary system, and doing this with
|
||||||
@@ -231,8 +220,22 @@ mca_exec_is_steam_link() {
|
|||||||
local line="$1" prog="$2"
|
local line="$1" prog="$2"
|
||||||
|
|
||||||
[[ $line == *steam://* ]] || return 1
|
[[ $line == *steam://* ]] || return 1
|
||||||
|
mca_prog_is_steam "$prog"
|
||||||
|
}
|
||||||
|
|
||||||
|
# mca_prog_is_steam <program>
|
||||||
|
# Whether running this program starts the Steam client. Every packaging is in
|
||||||
|
# here and every name Valve and the distributions give the launcher, because
|
||||||
|
# the answer decides whether an entry gets Steam's own switch - and an entry
|
||||||
|
# that starts Steam without it undoes the web helper patch on the way up.
|
||||||
|
#
|
||||||
|
# The program is what a scan leaves behind: an absolute path for a native
|
||||||
|
# install, flatpak:<id> or snap:<name> for the other two.
|
||||||
|
mca_prog_is_steam() {
|
||||||
|
local prog="$1"
|
||||||
|
|
||||||
case "${prog##*/}" in
|
case "${prog##*/}" in
|
||||||
steam|steam-runtime) return 0 ;;
|
steam|steam-runtime|steam-native|steam-jupiter) return 0 ;;
|
||||||
esac
|
esac
|
||||||
[[ $prog == flatpak:com.valvesoftware.Steam || $prog == snap:steam ]]
|
[[ $prog == flatpak:com.valvesoftware.Steam || $prog == snap:steam ]]
|
||||||
}
|
}
|
||||||
@@ -580,6 +583,8 @@ MCA_PACKAGING=() # native | flatpak | snap
|
|||||||
# kept at all: the Steam module gives them Steam's own switch.
|
# kept at all: the Steam module gives them Steam's own switch.
|
||||||
MCA_STEAM_LINKS=() # desktop file id
|
MCA_STEAM_LINKS=() # desktop file id
|
||||||
MCA_STEAM_LINK_FILES=() # the entry that is in effect for it
|
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
|
# 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
|
# then redraws from what it found. Applying rescans on its own, so nothing else
|
||||||
@@ -598,7 +603,7 @@ mca_scan() {
|
|||||||
|
|
||||||
MCA_IDS=(); MCA_FILES=(); MCA_NAMES=(); MCA_PROGS=(); MCA_KINDS=()
|
MCA_IDS=(); MCA_FILES=(); MCA_NAMES=(); MCA_PROGS=(); MCA_KINDS=()
|
||||||
MCA_PACKAGING=()
|
MCA_PACKAGING=()
|
||||||
MCA_STEAM_LINKS=(); MCA_STEAM_LINK_FILES=()
|
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
|
# 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
|
# detection yet - that needs a stat per program, and those are collected so
|
||||||
@@ -641,6 +646,13 @@ mca_scan() {
|
|||||||
if mca_exec_is_steam_link "$exec_line" "$prog"; then
|
if mca_exec_is_steam_link "$exec_line" "$prog"; then
|
||||||
MCA_STEAM_LINKS+=("$id")
|
MCA_STEAM_LINKS+=("$id")
|
||||||
MCA_STEAM_LINK_FILES+=("$file")
|
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
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -664,10 +676,13 @@ mca_scan() {
|
|||||||
packaging=native
|
packaging=native
|
||||||
|
|
||||||
if [[ $prog == flatpak:* ]]; then
|
if [[ $prog == flatpak:* ]]; then
|
||||||
prog="${prog#flatpak:}"
|
|
||||||
packaging=flatpak
|
packaging=flatpak
|
||||||
mca_flatpak_is_chromium "$prog" \
|
if mca_prog_is_steam "$prog"; then
|
||||||
&& { (( c_browser[i] )) && kind=browser || kind=app; }
|
kind=steam
|
||||||
|
elif mca_flatpak_is_chromium "${prog#flatpak:}"; then
|
||||||
|
(( c_browser[i] )) && kind=browser || kind=app
|
||||||
|
fi
|
||||||
|
prog="${prog#flatpak:}"
|
||||||
elif [[ $prog == snap:* ]]; then
|
elif [[ $prog == snap:* ]]; then
|
||||||
prog="${prog#snap:}"
|
prog="${prog#snap:}"
|
||||||
packaging=snap
|
packaging=snap
|
||||||
@@ -676,7 +691,7 @@ mca_scan() {
|
|||||||
elif mca_snap_is_chromium "$prog"; then
|
elif mca_snap_is_chromium "$prog"; then
|
||||||
(( c_browser[i] )) && kind=browser || kind=app
|
(( c_browser[i] )) && kind=browser || kind=app
|
||||||
fi
|
fi
|
||||||
elif [[ ${prog##*/} == steam || ${prog##*/} == steam-runtime ]]; then
|
elif mca_prog_is_steam "$prog"; then
|
||||||
# Steam is Chromium inside, but nothing about it can be changed
|
# Steam is Chromium inside, but nothing about it can be changed
|
||||||
# from a command line argument; it has its own module.
|
# from a command line argument; it has its own module.
|
||||||
kind=steam
|
kind=steam
|
||||||
|
|||||||
+114
-35
@@ -349,51 +349,117 @@ mca_desktop_apply() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Autostart entries
|
# Entries outside the search path
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Applications that start themselves at login write their own entry into
|
# Two directories hold desktop entries that no part of the XDG search path
|
||||||
# ~/.config/autostart, pointing straight at their binary. Those bypass the
|
# looks at, so nothing the scan does can reach them:
|
||||||
# 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
|
# ~/.config/autostart, where applications that start themselves at login
|
||||||
# needs -noverifyfiles exactly like the menu one, and it is the entry most
|
# write their own entry, pointing straight at their binary. Those bypass the
|
||||||
# likely to exist, because Steam writes it as soon as "run at startup" is
|
# entry in the menu completely, which is why Discord launched at login used
|
||||||
# ticked. Without it, a Steam started at login restores the patched web helper
|
# to behave differently from Discord launched from the menu.
|
||||||
# script and the watcher patches it back, over and over.
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# _mca_entry_patch_inplace <file> <gate: autostart|apps>
|
||||||
|
# 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.
|
||||||
|
_mca_entry_patch_inplace() {
|
||||||
|
local file="$1" gate="$2"
|
||||||
|
local id prog packaging=native content backup kind
|
||||||
|
|
||||||
|
grep -q "^$MCA_MARK_INPLACE=" "$file" 2>/dev/null && return 0
|
||||||
|
|
||||||
|
_mca_desktop_read "$file"
|
||||||
|
[[ -n $DE_EXEC ]] || return 0
|
||||||
|
[[ $DE_HIDDEN == true ]] && return 0
|
||||||
|
|
||||||
|
mca_exec_program "$DE_EXEC" || return 0
|
||||||
|
prog="$MCA_PROG"
|
||||||
|
|
||||||
|
# A Flatpak or a snap entry names the wrapper rather than the application.
|
||||||
|
# The scan resolves those into an id; outside the scan the same has to
|
||||||
|
# happen here, or every Flatpak looks like the flatpak program itself.
|
||||||
|
if [[ ${prog##*/} == flatpak ]]; then
|
||||||
|
mca_exec_flatpak_id "$DE_EXEC" || return 0
|
||||||
|
prog="flatpak:$MCA_PROG"
|
||||||
|
packaging=flatpak
|
||||||
|
elif mca_snap_name "$prog"; then
|
||||||
|
prog="snap:$MCA_PROG"
|
||||||
|
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")")"
|
||||||
|
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
|
||||||
|
|
||||||
|
if [[ $gate == autostart ]]; then
|
||||||
|
[[ $CFG_AUTOSTART == yes ]] || return 0
|
||||||
|
else
|
||||||
|
id="${file##*/}"; id="${id%.desktop}"
|
||||||
|
mca_desktop_is_browser && kind=browser || kind=app
|
||||||
|
mca_kind_wanted "$kind" "$id" "$packaging" || return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
content="$(_mca_desktop_transform "$file" "$MCA_MARK_INPLACE")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -n $content ]] || return 0
|
||||||
|
[[ "$content" == "$(< "$file")" ]] && return 0
|
||||||
|
|
||||||
|
backup="$(mca_backup "$file")" || return 0
|
||||||
|
if mca_write_if_changed "$file" "$content"$'\n'; then
|
||||||
|
MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
||||||
|
fi
|
||||||
|
mca_ledger_add inplace "$file" "$backup"
|
||||||
|
}
|
||||||
|
|
||||||
mca_autostart_apply() {
|
mca_autostart_apply() {
|
||||||
local dir="$MCA_XDG_CONFIG/autostart" file exec_line prog content backup
|
local dir="$MCA_XDG_CONFIG/autostart" file
|
||||||
|
|
||||||
[[ -d $dir ]] || return 0
|
[[ -d $dir ]] || return 0
|
||||||
|
|
||||||
for file in "$dir"/*.desktop; do
|
for file in "$dir"/*.desktop; do
|
||||||
[[ -f $file ]] || continue
|
[[ -f $file ]] || continue
|
||||||
grep -q "^$MCA_MARK_INPLACE=" "$file" 2>/dev/null && continue
|
_mca_entry_patch_inplace "$file" autostart
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
exec_line="$(mca_desktop_get "$file" Exec)"
|
mca_shortcuts_apply() {
|
||||||
[[ -n $exec_line ]] || continue
|
local dir file
|
||||||
|
dir="$(mca_desktop_folder)"
|
||||||
|
|
||||||
mca_exec_program "$exec_line" || continue
|
[[ -d $dir ]] || return 0
|
||||||
prog="$MCA_PROG"
|
|
||||||
|
|
||||||
if [[ ${prog##*/} == steam || ${prog##*/} == steam-runtime ]]; then
|
for file in "$dir"/*.desktop; do
|
||||||
[[ $CFG_STEAM == yes ]] || continue
|
[[ -f $file ]] || continue
|
||||||
content="$(_mca_desktop_transform "$file" "$MCA_MARK_INPLACE" \
|
_mca_entry_patch_inplace "$file" apps
|
||||||
"$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
|
|
||||||
|
|
||||||
backup="$(mca_backup "$file")" || continue
|
|
||||||
if mca_write_if_changed "$file" "$content"$'\n'; then
|
|
||||||
MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
|
||||||
fi
|
|
||||||
mca_ledger_add inplace "$file" "$backup"
|
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,13 +512,15 @@ mca_spotify_apply() {
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
# mca_prune_orphans
|
# mca_prune_orphans
|
||||||
# Removes generated entries whose application is gone.
|
# Forgets changes there is no longer anything to undo.
|
||||||
#
|
#
|
||||||
# Uninstalling something deletes its entry from /usr/share/applications, but the
|
# Uninstalling something deletes its entry from /usr/share/applications, but the
|
||||||
# copy shadowing it is in the user's home and pacman knows nothing about it. It
|
# copy shadowing it is in the user's home and pacman knows nothing about it. It
|
||||||
# would sit in the menu forever, offering to start a program that is no longer
|
# would sit in the menu forever, offering to start a program that is no longer
|
||||||
# installed - and the watcher would not notice, because a plain apply only ever
|
# installed - and the watcher would not notice, because a plain apply only ever
|
||||||
# looks at what is there now.
|
# looks at what is there now. A file that was edited where it stood and has
|
||||||
|
# since been deleted is the same problem from the other side: its record would
|
||||||
|
# have `disable` put the file back.
|
||||||
mca_prune_orphans() {
|
mca_prune_orphans() {
|
||||||
local kind path source line
|
local kind path source line
|
||||||
local -a lines=()
|
local -a lines=()
|
||||||
@@ -462,6 +530,17 @@ mca_prune_orphans() {
|
|||||||
|
|
||||||
for line in "${lines[@]}"; do
|
for line in "${lines[@]}"; do
|
||||||
IFS=$'\t' read -r kind path source <<< "$line"
|
IFS=$'\t' read -r kind path source <<< "$line"
|
||||||
|
|
||||||
|
# An entry that was edited where it stood and has since been deleted -
|
||||||
|
# a game shortcut dragged to the wastebasket, an autostart entry the
|
||||||
|
# application removed. There is nothing left to put back, and keeping
|
||||||
|
# the record would have `disable` recreate a file the user threw away.
|
||||||
|
if [[ $kind == inplace && ! -e $path ]]; then
|
||||||
|
[[ -n $source ]] && rm -f -- "$MCA_BACKUPDIR/$source"
|
||||||
|
mca_ledger_forget "$path"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
[[ $kind == shadow && -n $source ]] || continue
|
[[ $kind == shadow && -n $source ]] || continue
|
||||||
[[ -e $source ]] && continue
|
[[ -e $source ]] && continue
|
||||||
|
|
||||||
|
|||||||
+175
-38
@@ -10,18 +10,27 @@
|
|||||||
# ~/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
# ~/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||||
#
|
#
|
||||||
# Steam compares the installed files against its manifest at every start - by
|
# Steam compares the installed files against its manifest at every start - by
|
||||||
# size, not by content - and restores whatever differs, which is why the
|
# size and timestamp rather than by content - and restores whatever differs.
|
||||||
# launcher gets -noverifyfiles as well. The trade-off is real and belongs to
|
# So the patch is written to look untouched: the bytes the flag costs are taken
|
||||||
# the user, so this is a switch of its own rather than part of the general
|
# back out of the script's comments and the timestamp is put back afterwards,
|
||||||
# application handling: with verification off, Steam no longer repairs a
|
# which leaves a file that is byte-for-byte the size Steam recorded and as old
|
||||||
# damaged installation by itself.
|
# as Steam left it. A client that verifies its files finds nothing to repair
|
||||||
|
# and the flag survives however Steam was started - from the menu, from a game
|
||||||
|
# shortcut, from a launcher like Heroic, from a terminal.
|
||||||
#
|
#
|
||||||
# Every way of starting Steam has to carry that switch, or the two programs
|
# That is the part that has to work, because there is no way to make every
|
||||||
# spend the session undoing each other: Steam restores the script, the watcher
|
# possible way of starting Steam carry an argument. -noverifyfiles on the
|
||||||
# patches it again, Steam restores it again, and the client never gets past its
|
# launcher entries is the second line rather than the first: it covers the case
|
||||||
# update dialog. So the autostart entry gets it as well as the menu one (see
|
# where the script has no comments left to pay for the flag and the patch has
|
||||||
# mca_autostart_apply), and the patch below stays out of the way of a client
|
# to grow the file. The trade-off is real and belongs to the user, so it is a
|
||||||
# that is already running.
|
# 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.
|
||||||
#
|
#
|
||||||
# The file comes back on every client update, and the watcher re-applies the
|
# The file comes back on every client update, and the watcher re-applies the
|
||||||
# patch when that happens.
|
# patch when that happens.
|
||||||
@@ -145,12 +154,112 @@ _mca_steam_exec_line() {
|
|||||||
' "$1" 2>/dev/null
|
' "$1" 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# _mca_steam_build <script> <flags> <reclaim: 0|1>
|
||||||
|
# The patched script on stdout: the flags appended to the line that starts the
|
||||||
|
# web helper, and - when asked for - the same number of bytes taken back out of
|
||||||
|
# the script's comments, so that the file Steam finds is the length Steam wrote
|
||||||
|
# down. Everything else - setting up the container runtime, deciding whether
|
||||||
|
# the sandbox can be used - is left alone.
|
||||||
|
#
|
||||||
|
# Comments are eaten from the bottom up, so the header that says what the
|
||||||
|
# script is for is the last thing to lose anything, and the '#' itself always
|
||||||
|
# stays: a line that loses it stops being a comment and starts being a command.
|
||||||
|
# Fails when the comments are too short to pay for the flags.
|
||||||
|
_mca_steam_build() {
|
||||||
|
local script="$1" flags="$2" reclaim="$3" lineno need=0
|
||||||
|
|
||||||
|
lineno="$(_mca_steam_exec_line "$script")"
|
||||||
|
[[ -n $lineno ]] || return 1
|
||||||
|
|
||||||
|
if (( reclaim )); then
|
||||||
|
need="$(printf '%s' " $flags" | wc -c)"
|
||||||
|
need="${need//[^0-9]/}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# LC_ALL=C so awk counts bytes: a comment with an accent in it is shorter
|
||||||
|
# in characters than it is on disk, and it is the disk that Steam measures.
|
||||||
|
LC_ALL=C awk -v n="$lineno" -v f=" $flags" -v need="$need" '
|
||||||
|
{ lines[NR] = (NR == n ? $0 f : $0) }
|
||||||
|
END {
|
||||||
|
for (i = NR; i >= 2 && need > 0; i--) {
|
||||||
|
if (i == n) continue
|
||||||
|
p = index(lines[i], "#")
|
||||||
|
if (p == 0) continue
|
||||||
|
# Only a line that is nothing but a comment; a trailing one
|
||||||
|
# sits behind a command that has to stay intact.
|
||||||
|
if (substr(lines[i], 1, p - 1) ~ /[^ \t]/) continue
|
||||||
|
can = length(lines[i]) - p
|
||||||
|
if (can <= 0) continue
|
||||||
|
if (can > need) can = need
|
||||||
|
lines[i] = substr(lines[i], 1, length(lines[i]) - can)
|
||||||
|
need -= can
|
||||||
|
}
|
||||||
|
if (need > 0) exit 1
|
||||||
|
for (i = 1; i <= NR; i++) print lines[i]
|
||||||
|
}
|
||||||
|
' "$script"
|
||||||
|
}
|
||||||
|
|
||||||
|
# _mca_steam_same_size <script> <content>
|
||||||
|
# Whether writing that content leaves the file at the size it has now. Measured
|
||||||
|
# rather than worked out: a script without a final newline gains one on the way
|
||||||
|
# through awk, and one byte is all it takes for Steam to notice.
|
||||||
|
_mca_steam_same_size() {
|
||||||
|
local script="$1" content="$2"
|
||||||
|
(( $(wc -c < "$script") == $(printf '%s\n' "$content" | wc -c) ))
|
||||||
|
}
|
||||||
|
|
||||||
|
# _mca_steam_refresh_backup <script>
|
||||||
|
# A client update brings a new version of the script, and the copy kept from
|
||||||
|
# before it is no longer what putting it back means. Only ever done while the
|
||||||
|
# script is unpatched, so the copy that replaces it is Steam's own.
|
||||||
|
_mca_steam_refresh_backup() {
|
||||||
|
local script="$1" name
|
||||||
|
name="$(mca_backup_name "$script")"
|
||||||
|
|
||||||
|
[[ -e "$MCA_BACKUPDIR/$name" ]] || return 0
|
||||||
|
cmp -s -- "$script" "$MCA_BACKUPDIR/$name" && return 0
|
||||||
|
cp -p -- "$script" "$MCA_BACKUPDIR/$name" 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# _mca_steam_reneutralise <script> <flags>
|
||||||
|
# An earlier version of this program patched by appending and left the script
|
||||||
|
# longer than Steam expects, which is a patch that only survives because
|
||||||
|
# -noverifyfiles is there to stop Steam looking. If the same flags can be made
|
||||||
|
# to fit, they are: the file goes back to the length and the timestamp Steam
|
||||||
|
# wrote down and stops depending on that switch.
|
||||||
|
#
|
||||||
|
# The new copy is built from the untouched original that was kept when the
|
||||||
|
# script was first patched, never from the patched file - patching a patched
|
||||||
|
# file is how a flag ends up in there twice.
|
||||||
|
_mca_steam_reneutralise() {
|
||||||
|
local script="$1" flags="$2" name copy out
|
||||||
|
|
||||||
|
name="$(mca_backup_name "$script")"
|
||||||
|
copy="$MCA_BACKUPDIR/$name"
|
||||||
|
[[ -f $copy ]] || return 1
|
||||||
|
|
||||||
|
# Already the length Steam expects: there is nothing to gain.
|
||||||
|
(( $(wc -c < "$script") == $(wc -c < "$copy") )) && return 1
|
||||||
|
|
||||||
|
out="$(_mca_steam_build "$copy" "$flags" 1)" || return 1
|
||||||
|
_mca_steam_same_size "$copy" "$out" || return 1
|
||||||
|
|
||||||
|
if mca_write_if_changed "$script" "$out"$'\n'; then
|
||||||
|
MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
||||||
|
fi
|
||||||
|
chmod +x -- "$script" 2>/dev/null || true
|
||||||
|
touch -r "$copy" -- "$script" 2>/dev/null || true
|
||||||
|
mca_ledger_add steam "$script" "$name"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
# mca_steam_apply
|
# mca_steam_apply
|
||||||
# Appends the flags to the line that starts the web helper. Everything else in
|
# Puts the flags into every Steam installation that has the script, preferring
|
||||||
# the script - setting up the container runtime, deciding whether the sandbox
|
# the patch that keeps the file's size and falling back to the one that does
|
||||||
# can be used - is left alone.
|
# not. Returns 1 when there is no Steam to patch at all.
|
||||||
mca_steam_apply() {
|
mca_steam_apply() {
|
||||||
local root script backup flags lineno found=0 out
|
local root script backup flags found=0 out neutral
|
||||||
|
|
||||||
flags="$(mca_flags)"
|
flags="$(mca_flags)"
|
||||||
|
|
||||||
@@ -158,34 +267,51 @@ mca_steam_apply() {
|
|||||||
script="$(mca_steam_script "$root")" || continue
|
script="$(mca_steam_script "$root")" || continue
|
||||||
found=1
|
found=1
|
||||||
|
|
||||||
mca_steam_script_patched "$script" && continue
|
if mca_steam_script_patched "$script"; then
|
||||||
|
_mca_steam_reneutralise "$script" "$flags" || true
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
# Not patched now, but patched before: Steam has just put its own copy
|
_mca_steam_refresh_backup "$script"
|
||||||
# back. Patching it again while the client watches is what turns one
|
|
||||||
# size mismatch into an endless update dialog, and it would not help
|
neutral=1
|
||||||
# this session anyway - the helper is started once, at the start. The
|
if ! { out="$(_mca_steam_build "$script" "$flags" 1)" \
|
||||||
# patch waits for the next apply with Steam closed.
|
&& _mca_steam_same_size "$script" "$out"; }
|
||||||
if mca_steam_deferred "$script"; then
|
then
|
||||||
|
neutral=0
|
||||||
|
out="$(_mca_steam_build "$script" "$flags" 0)" || {
|
||||||
|
# A client update changed how the helper is started. Leaving
|
||||||
|
# the file alone is the only safe answer: this script is what
|
||||||
|
# starts Steam's entire interface.
|
||||||
|
mca_note "$(mca_msg "Steam starts its interface in a way this version does not recognise; leaving it alone.")"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The patch has to grow the file, and it is not patched now but was
|
||||||
|
# before: Steam has just put its own copy back. Patching it again
|
||||||
|
# while the client watches is what turns one size mismatch into an
|
||||||
|
# endless update dialog, and it would not help this session anyway -
|
||||||
|
# the helper is started once, at the start. The patch waits for the
|
||||||
|
# next apply with Steam closed. A patch that keeps the size has
|
||||||
|
# nothing to wait for.
|
||||||
|
if (( ! neutral )) && mca_steam_deferred "$script"; then
|
||||||
mca_note "$(mca_msg "Steam is running and has put its own file back; the change waits until Steam is closed.")"
|
mca_note "$(mca_msg "Steam is running and has put its own file back; the change waits until Steam is closed.")"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
lineno="$(_mca_steam_exec_line "$script")"
|
|
||||||
if [[ -z $lineno ]]; then
|
|
||||||
# A client update changed how the helper is started. Leaving the
|
|
||||||
# file alone is the only safe answer: this script is what starts
|
|
||||||
# Steam's entire interface.
|
|
||||||
mca_note "$(mca_msg "Steam starts its interface in a way this version does not recognise; leaving it alone.")"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
out="$(awk -v n="$lineno" -v f=" $flags" 'NR == n { $0 = $0 f } { print }' "$script")" || continue
|
|
||||||
|
|
||||||
backup="$(mca_backup "$script")" || continue
|
backup="$(mca_backup "$script")" || continue
|
||||||
if mca_write_if_changed "$script" "$out"$'\n'; then
|
if mca_write_if_changed "$script" "$out"$'\n'; then
|
||||||
MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
||||||
fi
|
fi
|
||||||
chmod +x -- "$script" 2>/dev/null || true
|
chmod +x -- "$script" 2>/dev/null || true
|
||||||
|
|
||||||
|
# Steam looks at when the file was last written as well as at how big
|
||||||
|
# it is, and the copy taken before the edit still carries the original
|
||||||
|
# timestamp. Putting it back costs nothing and removes the other half
|
||||||
|
# of what the client would notice.
|
||||||
|
touch -r "$MCA_BACKUPDIR/$backup" -- "$script" 2>/dev/null || true
|
||||||
|
|
||||||
mca_ledger_add steam "$script" "$backup"
|
mca_ledger_add steam "$script" "$backup"
|
||||||
done < <(mca_steam_roots)
|
done < <(mca_steam_roots)
|
||||||
|
|
||||||
@@ -214,11 +340,22 @@ mca_steam_revert() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# mca_steam_desktop_apply <id> <source entry>
|
# mca_steam_flag_position <packaging>
|
||||||
|
# Where Steam's own switch goes on a command line. Straight after the program
|
||||||
|
# for a native or snap entry, because Steam reads its options before the
|
||||||
|
# steam:// argument that the right-click actions pass. For a Flatpak the first
|
||||||
|
# token is flatpak itself, which would take the switch for one of its own and
|
||||||
|
# refuse to start, so there it goes at the end of the arguments - after the
|
||||||
|
# application id, where flatpak hands everything on to Steam.
|
||||||
|
mca_steam_flag_position() {
|
||||||
|
[[ ${1:-native} == flatpak ]] && { printf 'before-fields\n'; return; }
|
||||||
|
printf 'after-program\n'
|
||||||
|
}
|
||||||
|
|
||||||
|
# mca_steam_desktop_apply <id> <source entry> [packaging]
|
||||||
# Steam restores its own files at every start unless it is told not to verify
|
# Steam restores its own files at every start unless it is told not to verify
|
||||||
# them, so the launcher entry carries that switch. It goes directly after the
|
# them, so the launcher entry carries that switch.
|
||||||
# program because Steam reads its options before the steam:// argument that the
|
|
||||||
# right-click actions pass.
|
|
||||||
mca_steam_desktop_apply() {
|
mca_steam_desktop_apply() {
|
||||||
mca_desktop_apply "$1" "$2" "$MCA_STEAM_LAUNCH_FLAG" after-program
|
mca_desktop_apply "$1" "$2" "$MCA_STEAM_LAUNCH_FLAG" \
|
||||||
|
"$(mca_steam_flag_position "${3:-native}")"
|
||||||
}
|
}
|
||||||
@@ -119,8 +119,12 @@ mca_do_apply() {
|
|||||||
mca_ok "$(mca_msg "Already applied to %d applications." "$MCA_N_ON")"
|
mca_ok "$(mca_msg "Already applied to %d applications." "$MCA_N_ON")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $CFG_WATCH == yes ]] && mca_watch_available && ! mca_watch_enabled; then
|
if [[ $CFG_WATCH == yes ]] && mca_watch_available; then
|
||||||
|
if mca_watch_enabled; then
|
||||||
|
mca_watch_refresh
|
||||||
|
else
|
||||||
mca_watch_enable || true
|
mca_watch_enable || true
|
||||||
|
fi
|
||||||
elif [[ $CFG_WATCH != yes ]] && mca_watch_enabled; then
|
elif [[ $CFG_WATCH != yes ]] && mca_watch_enabled; then
|
||||||
mca_watch_disable
|
mca_watch_disable
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in new issue
Block a user