Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15a7cb9cf9 | ||
|
|
0234e81811 | ||
|
|
6f62c7f21c | ||
|
|
3c000b8a6e | ||
|
|
0f9b041b20 | ||
|
|
98f6ac9c48 | ||
|
|
9861d24c2a | ||
|
|
f74fc3e8ca |
No files matched your search
+1
-1
@@ -1 +1 @@
|
||||
buy_me_a_coffee: felitendo
|
||||
ko_fi: felitendo
|
||||
@@ -0,0 +1,35 @@
|
||||
name: 💡 Feature request
|
||||
description: An idea to make middleclick-autoscroll better.
|
||||
labels:
|
||||
- enhancement
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: Before you start
|
||||
options:
|
||||
- label: I searched the issues and this is not requested yet.
|
||||
required: true
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: What problem would this solve?
|
||||
description: What are you trying to do, and what gets in the way?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: idea
|
||||
attributes:
|
||||
label: What would you like?
|
||||
description: How it could work. A rough idea is fine.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: alternatives
|
||||
attributes:
|
||||
label: Other ways you thought of
|
||||
- type: textarea
|
||||
id: more
|
||||
attributes:
|
||||
label: Anything else?
|
||||
description: Mockups, screenshots, or other tools that do it well.
|
||||
@@ -0,0 +1,85 @@
|
||||
name: 🐛 Bug report
|
||||
description: Something does not work as it should.
|
||||
labels:
|
||||
- bug
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: Thanks for taking the time! The more you fill in, the faster it can be fixed.
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: Before you start
|
||||
options:
|
||||
- label: I searched the issues and this is not reported yet.
|
||||
required: true
|
||||
- label: I use the latest version.
|
||||
required: true
|
||||
- type: textarea
|
||||
id: what
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: What did you do, and what went wrong?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
placeholder: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: What did you expect?
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: app
|
||||
attributes:
|
||||
label: App
|
||||
description: 'Which app, and how it is installed: native package, Flatpak, Snap or AppImage.'
|
||||
placeholder: Discord, Flatpak
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: The output of `middleclick-autoscroll --version`.
|
||||
placeholder: middleclick-autoscroll 1.6.0
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: install
|
||||
attributes:
|
||||
label: How did you install it?
|
||||
options:
|
||||
- AUR (Arch, CachyOS, EndeavourOS, Manjaro)
|
||||
- Fedora package
|
||||
- Bazzite
|
||||
- Debian or Ubuntu package
|
||||
- openSUSE package
|
||||
- Built from source
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: system
|
||||
attributes:
|
||||
label: System
|
||||
description: Distribution, desktop and session (Wayland or X11).
|
||||
placeholder: CachyOS, KDE Plasma 6.4, Wayland
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Status and logs
|
||||
description: The output of `middleclick-autoscroll status` and `middleclick-autoscroll list`.
|
||||
render: shell
|
||||
- type: textarea
|
||||
id: more
|
||||
attributes:
|
||||
label: Anything else?
|
||||
description: Screenshots, videos or anything else that could help.
|
||||
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
||||
@@ -125,7 +125,7 @@ $entry
|
||||
|
||||
If $name is useful to you, you can buy me a coffee. It keeps these tools going. Found a bug or have an idea? Tell me in the [issues](https://github.com/$repo/issues).
|
||||
|
||||
<a href="https://buymeacoffee.com/felitendo"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="48"></a>
|
||||
<a href="https://ko-fi.com/felitendo"><img src="https://storage.ko-fi.com/cdn/kofi5.png?v=6" alt="Buy me a coffee on Ko-fi" height="48"></a>
|
||||
|
||||
----
|
||||
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
What each release brings, newest first. The [GitHub releases](https://github.com/LoonixTools/middleclick-autoscroll/releases) add every commit that went into it. Versions before `v1.1.0` came without notes.
|
||||
|
||||
## v1.6.1
|
||||
|
||||
_2026-09-29_
|
||||
|
||||
A small patch. Autoscroll now works in Steam with **Use experimental SteamRT3 Steam Client** turned on. And apps that start at login through a link, like Mullvad VPN, get autoscroll now instead of an error.
|
||||
|
||||
## v1.6.0
|
||||
|
||||
_2026-09-24_
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
- Body only when something genuinely cannot be inferred from the diff.
|
||||
- Never add `Co-Authored-By`, "Generated with" or any other AI attribution to commits or PR descriptions.
|
||||
- Do not commit or push before I have checked the changes locally and said they are fine. Then
|
||||
commit the result once and push. No commits for attempts that did not work. This also goes for
|
||||
commit and push. Several attempts at the same thing make one commit, and attempts that did not
|
||||
work make none. Different things done in one session get a commit each. This also goes for
|
||||
releases and tags.
|
||||
|
||||
## Releases
|
||||
@@ -67,3 +68,9 @@ when you press Enter." The list of commits follows on its own.
|
||||
- Commands and settings they type go in backticks, buttons and labels in bold.
|
||||
- To change an old release: edit its entry, commit, then
|
||||
`gh release edit <tag> --title <tag> --notes "$(.github/release-notes.sh <tag>)"`.
|
||||
|
||||
## README
|
||||
|
||||
- New UI (a window, a screen, a menu, a setting, a notification) gets a screenshot in the README,
|
||||
next to the text about it. Like for releases: a real screenshot of it running, in English.
|
||||
- When a screen changes, take its screenshot again. The README never shows an old one.
|
||||
@@ -8,7 +8,7 @@
|
||||
# Overridable so a packager can pass the version it is actually building
|
||||
# (`make VERSION=$pkgver`). The literal below is the fallback for builds
|
||||
# straight from a checkout, and is what a release tag has to carry.
|
||||
VERSION ?= 1.6.0
|
||||
VERSION ?= 1.6.1
|
||||
|
||||
PREFIX ?= /usr
|
||||
DESTDIR ?=
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</h5>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://buymeacoffee.com/felitendo"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="48"></a>
|
||||
<a href="https://ko-fi.com/felitendo"><img src="https://storage.ko-fi.com/cdn/kofi5.png?v=6" alt="Buy me a coffee on Ko-fi" height="48"></a>
|
||||
</p>
|
||||
|
||||
## Install
|
||||
|
||||
@@ -116,7 +116,9 @@ Two ways, chosen per application.
|
||||
Programs that start themselves at login write their own entry into
|
||||
_~/.config/autostart_ pointing straight at their binary, bypassing the menu
|
||||
entry entirely. Those are patched in place as well, unless the application is
|
||||
turned off in the applications list.
|
||||
turned off in the applications list. An entry that is a symlink, often to an
|
||||
application's entry in _/usr/share/applications_, is replaced by a patched
|
||||
file rather than written through, and undoing puts the link back.
|
||||
|
||||
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
|
||||
@@ -133,6 +135,12 @@ helper, inside Steam's own installation:
|
||||
|
||||
~/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||
|
||||
The steamrt3 client, a beta for now, has a script of its own:
|
||||
|
||||
~/.local/share/Steam/steamrt64/steamwebhelper.sh
|
||||
|
||||
Both are patched where both are there, so switching clients keeps autoscroll.
|
||||
|
||||
Where that installation is depends on how Steam was installed:
|
||||
_~/.local/share/Steam_ for Valve's own package and Arch's,
|
||||
_~/.steam/debian-installation_ for Debian's, and the private tree of the
|
||||
@@ -154,11 +162,16 @@ 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.
|
||||
|
||||
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.
|
||||
The steamrt3 script has no comments to pay with. So it is copied aside as
|
||||
_steamwebhelper.sh.orig_, and a stub of the same size takes its place. The stub
|
||||
runs the copy with the argument added. Steam only checks the files it knows,
|
||||
and the copy is not one of them.
|
||||
|
||||
So where neither fits, 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
|
||||
|
||||
@@ -30,12 +30,17 @@ PathModified=%h/.guix-profile/share/applications
|
||||
|
||||
# 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
|
||||
# Steam was installed.
|
||||
# Steam was installed. The steamrt3 client has a script of its own.
|
||||
PathChanged=%h/.local/share/Steam/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/data/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||
PathChanged=%h/snap/steam/common/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||
PathChanged=%h/.local/share/Steam/steamrt64/steamwebhelper.sh
|
||||
PathChanged=%h/.steam/debian-installation/steamrt64/steamwebhelper.sh
|
||||
PathChanged=%h/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamrt64/steamwebhelper.sh
|
||||
PathChanged=%h/.var/app/com.valvesoftware.Steam/data/Steam/steamrt64/steamwebhelper.sh
|
||||
PathChanged=%h/snap/steam/common/.local/share/Steam/steamrt64/steamwebhelper.sh
|
||||
|
||||
Unit=middleclick-autoscroll.service
|
||||
|
||||
|
||||
+7
-1
@@ -343,12 +343,18 @@ mca_backup_name() {
|
||||
# copy was stored under. Existing backups are never overwritten: the first copy
|
||||
# is the pristine one, and a second apply must not replace it with an already
|
||||
# patched version.
|
||||
#
|
||||
# A symlink is kept as a symlink, so undo can put the link back. It is taken
|
||||
# again every time: this program never writes a link, so one is always pristine.
|
||||
mca_backup() {
|
||||
local file="$1" name
|
||||
name="$(mca_backup_name "$file")"
|
||||
|
||||
mkdir -p "$MCA_BACKUPDIR" 2>/dev/null || return 1
|
||||
if [[ ! -e "$MCA_BACKUPDIR/$name" ]]; then
|
||||
if [[ -L $file ]]; then
|
||||
rm -f -- "$MCA_BACKUPDIR/$name"
|
||||
cp -P -p -- "$file" "$MCA_BACKUPDIR/$name" 2>/dev/null || return 1
|
||||
elif [[ ! -e "$MCA_BACKUPDIR/$name" && ! -L "$MCA_BACKUPDIR/$name" ]]; then
|
||||
cp -p -- "$file" "$MCA_BACKUPDIR/$name" 2>/dev/null || return 1
|
||||
fi
|
||||
printf '%s\n' "$name"
|
||||
|
||||
+33
-6
@@ -375,7 +375,7 @@ mca_desktop_apply() {
|
||||
[[ "$content" == "$(< "$src")" ]] && return 0
|
||||
|
||||
backup="$(mca_backup "$src")" || return 1
|
||||
if mca_write_if_changed "$src" "$content"$'\n'; then
|
||||
if _mca_entry_write "$src" "$content"$'\n'; then
|
||||
MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
||||
fi
|
||||
mca_ledger_add inplace "$src" "$backup"
|
||||
@@ -418,6 +418,30 @@ mca_desktop_apply() {
|
||||
# Neither can be shadowed from anywhere, so both are edited where they stand,
|
||||
# with the original kept.
|
||||
|
||||
# _mca_entry_write <file> <content>
|
||||
# Writes an entry edited in place, like mca_write_if_changed. A symlink is
|
||||
# replaced by the edited file instead of written through: it usually points at
|
||||
# a package's entry in /usr, which is not ours to change. Undo puts the link
|
||||
# back from the backup.
|
||||
_mca_entry_write() {
|
||||
local file="$1" content="$2" tmp
|
||||
|
||||
[[ -L $file ]] || { mca_write_if_changed "$file" "$content"; return; }
|
||||
|
||||
tmp="$(mktemp "$file.XXXXXX")" || return 2
|
||||
chmod --reference="$file" -- "$tmp" 2>/dev/null || chmod 644 -- "$tmp"
|
||||
|
||||
# A link into /usr/share/applications is trusted for where it points. A
|
||||
# copy on the desktop is only trusted by KDE when it can be run.
|
||||
chmod u+x -- "$tmp" 2>/dev/null || true
|
||||
|
||||
if printf '%s' "$content" > "$tmp" && mv -f -- "$tmp" "$file"; then
|
||||
return 0
|
||||
fi
|
||||
rm -f -- "$tmp"
|
||||
return 2
|
||||
}
|
||||
|
||||
# _mca_entry_patch_inplace <file>
|
||||
# One desktop entry that lives outside the XDG search path, edited where it is
|
||||
# because there is nowhere to shadow it from. It follows the applications list
|
||||
@@ -482,7 +506,7 @@ _mca_entry_patch_inplace() {
|
||||
[[ "$content" == "$(< "$file")" ]] && return 0
|
||||
|
||||
backup="$(mca_backup "$file")" || return 0
|
||||
if mca_write_if_changed "$file" "$content"$'\n'; then
|
||||
if _mca_entry_write "$file" "$content"$'\n'; then
|
||||
MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
||||
fi
|
||||
mca_ledger_add inplace "$file" "$backup"
|
||||
@@ -607,7 +631,7 @@ mca_prune_orphans() {
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
mca_revert_all() {
|
||||
local kind path detail
|
||||
local kind path detail backup
|
||||
|
||||
[[ -f $MCA_LEDGER ]] || return 0
|
||||
|
||||
@@ -623,12 +647,15 @@ mca_revert_all() {
|
||||
fi
|
||||
;;
|
||||
inplace)
|
||||
if [[ -n $detail && -f "$MCA_BACKUPDIR/$detail" ]]; then
|
||||
backup="$MCA_BACKUPDIR/$detail"
|
||||
if [[ -n $detail ]] && [[ -f $backup || -L $backup ]]; then
|
||||
if [[ -e $path ]] || [[ -d "$(dirname -- "$path")" ]]; then
|
||||
cp -p -- "$MCA_BACKUPDIR/$detail" "$path" 2>/dev/null \
|
||||
# A link goes back as a link, not written through.
|
||||
[[ -L $backup ]] && rm -f -- "$path"
|
||||
cp -P -p -- "$backup" "$path" 2>/dev/null \
|
||||
&& MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
||||
fi
|
||||
rm -f -- "$MCA_BACKUPDIR/$detail"
|
||||
rm -f -- "$backup"
|
||||
elif [[ -f $path ]]; then
|
||||
# No backup: the file did not exist before we wrote it.
|
||||
rm -f -- "$path"
|
||||
|
||||
+138
-45
@@ -9,6 +9,10 @@
|
||||
#
|
||||
# ~/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||
#
|
||||
# The steamrt3 client, a beta for now, has a script of its own:
|
||||
#
|
||||
# ~/.local/share/Steam/steamrt64/steamwebhelper.sh
|
||||
#
|
||||
# Steam compares the installed files against its manifest at every start (by
|
||||
# size and timestamp, not by content) and restores whatever differs.
|
||||
# So the patch is written to look untouched: the bytes the flag costs are taken
|
||||
@@ -28,6 +32,10 @@
|
||||
# all: no autoscroll in the interface is a smaller thing than a client that
|
||||
# reinstalls itself.
|
||||
#
|
||||
# The steamrt3 script has no comments to give back. So it is copied aside, as
|
||||
# it is, and replaced by a stub of the same size that runs the copy with the
|
||||
# flag. See _mca_steam_stub.
|
||||
#
|
||||
# The file comes back on every client update, and the watcher re-applies the
|
||||
# patch when that happens.
|
||||
|
||||
@@ -60,24 +68,28 @@ mca_steam_roots() {
|
||||
done
|
||||
}
|
||||
|
||||
# The script to patch inside a Steam installation. Newer clients start the
|
||||
# helper through a wrapper inside the container runtime; older ones exec it
|
||||
# from steamwebhelper.sh directly, and that one forwards its arguments too.
|
||||
mca_steam_script() {
|
||||
local root="$1" f
|
||||
# The scripts to patch inside a Steam installation, one per client. The default
|
||||
# client starts the helper through a wrapper inside the container runtime;
|
||||
# older ones exec it from steamwebhelper.sh directly, and that one forwards its
|
||||
# arguments too. The steamrt3 client has its own. Both clients are patched
|
||||
# where both are there, so switching between them keeps autoscroll.
|
||||
mca_steam_scripts() {
|
||||
local root="$1" f found=1
|
||||
for f in \
|
||||
"$root/ubuntu12_64/steamwebhelper_sniper_wrap.sh" \
|
||||
"$root/ubuntu12_64/steamwebhelper.sh"
|
||||
do
|
||||
[[ -f $f && -w $f ]] && { printf '%s\n' "$f"; return 0; }
|
||||
[[ -f $f && -w $f ]] && { printf '%s\n' "$f"; found=0; break; }
|
||||
done
|
||||
return 1
|
||||
f="$root/steamrt64/steamwebhelper.sh"
|
||||
[[ -f $f && -w $f ]] && { printf '%s\n' "$f"; found=0; }
|
||||
return "$found"
|
||||
}
|
||||
|
||||
mca_steam_installed() {
|
||||
local root
|
||||
while IFS= read -r root; do
|
||||
mca_steam_script "$root" > /dev/null && return 0
|
||||
mca_steam_scripts "$root" > /dev/null && return 0
|
||||
done < <(mca_steam_roots)
|
||||
return 1
|
||||
}
|
||||
@@ -87,13 +99,17 @@ mca_steam_script_patched() {
|
||||
grep -q -- "$MCA_FEATURE" "$1" 2>/dev/null
|
||||
}
|
||||
|
||||
# Whether every script there is patched. One that is not is a client that
|
||||
# starts without autoscroll.
|
||||
mca_steam_patched() {
|
||||
local root script
|
||||
local root script found=0
|
||||
while IFS= read -r root; do
|
||||
script="$(mca_steam_script "$root")" || continue
|
||||
mca_steam_script_patched "$script" && return 0
|
||||
while IFS= read -r script; do
|
||||
mca_steam_script_patched "$script" || return 1
|
||||
found=1
|
||||
done < <(mca_steam_scripts "$root")
|
||||
done < <(mca_steam_roots)
|
||||
return 1
|
||||
(( found ))
|
||||
}
|
||||
|
||||
# _mca_steam_exec_line <script>
|
||||
@@ -163,6 +179,81 @@ _mca_steam_same_size() {
|
||||
(( $(wc -c < "$script") == $(printf '%s\n' "$content" | wc -c) ))
|
||||
}
|
||||
|
||||
# Where a stub keeps Steam's own script, and the line that runs it from there.
|
||||
MCA_STEAM_ORIG=.orig
|
||||
MCA_STEAM_STUB="exec \"\$0$MCA_STEAM_ORIG\" \"\$@\""
|
||||
|
||||
# _mca_steam_stub <script> <flags>
|
||||
# The stub on stdout, for a script with no comments to pay for the flags. It
|
||||
# is exactly as long as the script and runs Steam's own script, kept next to
|
||||
# it, with the flags added. That script hands its arguments on to the helper.
|
||||
# Steam only checks the files in its manifest, and the copy is not one of them.
|
||||
# Fails when the script does not hand its arguments on, has no #! line, or is
|
||||
# too short to hold the stub.
|
||||
_mca_steam_stub() {
|
||||
local script="$1" flags="$2" head body pad
|
||||
|
||||
[[ -n "$(_mca_steam_exec_line "$script")" ]] || return 1
|
||||
head="$(head -n 1 -- "$script")"
|
||||
[[ $head == '#!'* ]] || return 1
|
||||
|
||||
body="$MCA_STEAM_STUB $flags"
|
||||
pad=$(( $(wc -c < "$script") - $(printf '%s\n%s\n' "$head" "$body" | wc -c) ))
|
||||
(( pad >= 0 )) || return 1
|
||||
|
||||
# The bytes left over go into a comment line.
|
||||
printf '%s\n' "$head"
|
||||
if (( pad == 1 )); then
|
||||
printf '\n'
|
||||
elif (( pad > 1 )); then
|
||||
printf '#%*s\n' $(( pad - 2 )) ''
|
||||
fi
|
||||
printf '%s' "$body"
|
||||
}
|
||||
|
||||
# _mca_steam_is_stub <script>
|
||||
_mca_steam_is_stub() {
|
||||
grep -qF -- "$MCA_STEAM_STUB" "$1" 2>/dev/null
|
||||
}
|
||||
|
||||
# _mca_steam_text <script> <flags>
|
||||
# The patched script on stdout: from the comments if they can pay for the
|
||||
# flags, as a stub if not. Fails when neither keeps the size.
|
||||
_mca_steam_text() {
|
||||
local script="$1" flags="$2" out
|
||||
|
||||
if ! { out="$(_mca_steam_build "$script" "$flags")" \
|
||||
&& _mca_steam_same_size "$script" "$out"; }
|
||||
then
|
||||
out="$(_mca_steam_stub "$script" "$flags")" \
|
||||
&& _mca_steam_same_size "$script" "$out" || return 1
|
||||
fi
|
||||
printf '%s' "$out"
|
||||
}
|
||||
|
||||
# _mca_steam_write <script> <backup> <content>
|
||||
# Writes the patched script. <backup> is the untouched copy kept for undoing.
|
||||
_mca_steam_write() {
|
||||
local script="$1" backup="$2" content="$3"
|
||||
|
||||
# A stub needs Steam's script next to it before it can start anything.
|
||||
if [[ $content == *"$MCA_STEAM_STUB"* ]]; then
|
||||
cp -p -- "$backup" "$script$MCA_STEAM_ORIG" 2>/dev/null || return 1
|
||||
chmod +x -- "$script$MCA_STEAM_ORIG" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if mca_write_if_changed "$script" "$content"$'\n'; then
|
||||
MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
||||
fi
|
||||
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 "$backup" -- "$script" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# _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
|
||||
@@ -195,15 +286,18 @@ _mca_steam_settle() {
|
||||
# Nothing to compare against, so nothing can be said about the length.
|
||||
[[ -f $copy ]] || return 0
|
||||
|
||||
# Already the length Steam expects: the patch is a good one.
|
||||
(( $(wc -c < "$script") == $(wc -c < "$copy") )) && return 0
|
||||
|
||||
if out="$(_mca_steam_build "$copy" "$flags")" && _mca_steam_same_size "$copy" "$out"; then
|
||||
if mca_write_if_changed "$script" "$out"$'\n'; then
|
||||
MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
||||
# Already the length Steam expects: the patch is a good one. Unless it is
|
||||
# a stub that lost Steam's script next to it, and would start nothing.
|
||||
if (( $(wc -c < "$script") == $(wc -c < "$copy") )); then
|
||||
if _mca_steam_is_stub "$script" && [[ ! -f $script$MCA_STEAM_ORIG ]]; then
|
||||
cp -p -- "$copy" "$script$MCA_STEAM_ORIG" 2>/dev/null || true
|
||||
fi
|
||||
chmod +x -- "$script" 2>/dev/null || true
|
||||
touch -r "$copy" -- "$script" 2>/dev/null || true
|
||||
return 0
|
||||
fi
|
||||
|
||||
if out="$(_mca_steam_text "$copy" "$flags")" \
|
||||
&& _mca_steam_write "$script" "$copy" "$out"
|
||||
then
|
||||
mca_ledger_add steam "$script" "$name"
|
||||
return 0
|
||||
fi
|
||||
@@ -224,7 +318,7 @@ mca_steam_apply() {
|
||||
flags="$(mca_flags)"
|
||||
|
||||
while IFS= read -r root; do
|
||||
script="$(mca_steam_script "$root")" || continue
|
||||
while IFS= read -r script; do
|
||||
found=1
|
||||
|
||||
if mca_steam_script_patched "$script"; then
|
||||
@@ -234,31 +328,21 @@ mca_steam_apply() {
|
||||
|
||||
_mca_steam_refresh_backup "$script"
|
||||
|
||||
# Either the comments can pay for the flag or nothing is written.
|
||||
# A longer file is one Steam reinstalls itself over; a client update
|
||||
# that changed how the helper is started leaves no line to patch at
|
||||
# all. Both end here, and this script is what starts Steam's entire
|
||||
# interface, so leaving it alone is the only safe answer to either.
|
||||
if ! { out="$(_mca_steam_build "$script" "$flags")" \
|
||||
&& _mca_steam_same_size "$script" "$out"; }
|
||||
then
|
||||
# Either the file keeps its length or nothing is written. A
|
||||
# longer file is one Steam reinstalls itself over; a client
|
||||
# update that changed how the helper is started leaves no line
|
||||
# to patch at all. Both end here, and this script is what starts
|
||||
# Steam's entire interface, so leaving it alone is the only safe
|
||||
# answer to either.
|
||||
if ! out="$(_mca_steam_text "$script" "$flags")"; then
|
||||
mca_note "$(mca_msg "Steam starts its interface in a way this version cannot change without Steam noticing; leaving it alone.")"
|
||||
continue
|
||||
fi
|
||||
|
||||
backup="$(mca_backup "$script")" || continue
|
||||
if mca_write_if_changed "$script" "$out"$'\n'; then
|
||||
MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
||||
fi
|
||||
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_steam_write "$script" "$MCA_BACKUPDIR/$backup" "$out" || continue
|
||||
mca_ledger_add steam "$script" "$backup"
|
||||
done < <(mca_steam_scripts "$root")
|
||||
done < <(mca_steam_roots)
|
||||
|
||||
(( found ))
|
||||
@@ -266,7 +350,9 @@ mca_steam_apply() {
|
||||
|
||||
# mca_steam_revert <script> <backup name>
|
||||
mca_steam_revert() {
|
||||
local script="$1" backup="$2"
|
||||
local script="$1" backup="$2" orig="$1$MCA_STEAM_ORIG" stub=1 tmp
|
||||
|
||||
_mca_steam_is_stub "$script" || stub=0
|
||||
|
||||
if [[ -n $backup && -f "$MCA_BACKUPDIR/$backup" ]]; then
|
||||
if [[ -e $script ]]; then
|
||||
@@ -274,14 +360,21 @@ mca_steam_revert() {
|
||||
chmod +x -- "$script" 2>/dev/null || true
|
||||
fi
|
||||
rm -f -- "$MCA_BACKUPDIR/$backup"
|
||||
return 0
|
||||
fi
|
||||
|
||||
elif (( stub )) && [[ -f $orig ]]; then
|
||||
# No backup, but a stub keeps Steam's own script right next to it.
|
||||
cp -p -- "$orig" "$script" 2>/dev/null || return 1
|
||||
else
|
||||
# No backup to fall back on, so take the flags back out of the exec line.
|
||||
[[ -f $script ]] || return 1
|
||||
local tmp
|
||||
tmp="$(mktemp "${script}.XXXXXX")" || return 1
|
||||
sed "s| $MCA_FLAG||g" "$script" > "$tmp" && mv -f "$tmp" "$script" || { rm -f "$tmp"; return 1; }
|
||||
chmod +x -- "$script" 2>/dev/null || true
|
||||
return 0
|
||||
fi
|
||||
|
||||
# The copy goes once the stub that ran it is gone.
|
||||
if (( stub )) && ! _mca_steam_is_stub "$script"; then
|
||||
rm -f -- "$orig"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
Reference in new issue
Block a user