docs: add claude.md and avoid dashes

This commit is contained in:
Felitendo committed 2026-09-21 14:00:02 +02:00
1 parent ab8c6477cb
commit 1042639a08
23 files changed
+220 -201

No files matched your search

+5 -5
View File
@@ -4,7 +4,7 @@
#
# The routing lives in mca_route and is used twice: once by mca_apply to patch
# and once by the applications screen to show what would happen. Keeping it in
# one function is what makes that screen trustworthy - it is not a description
# one function is what makes that screen trustworthy: it is not a description
# of the behaviour, it is the behaviour.
MCA_CHANGES=0
@@ -56,7 +56,7 @@ mca_route() {
# mca_apply
# Brings everything into line with the current settings. Safe to run as often
# as it likes to be - it writes only what differs, which is what keeps the
# as it likes to be. It writes only what differs, which is what keeps the
# watcher from chasing its own changes.
mca_apply() {
local i id file prog kind packaging route steam_done=0
@@ -114,7 +114,7 @@ mca_apply() {
esac
done
# Steam is worth patching even when its desktop entry is missing - a user
# Steam is worth patching even when its desktop entry is missing. A user
# who starts it from a script or a game launcher still gets the interface.
if [[ $CFG_STEAM == yes ]] && (( ! steam_done )) && mca_steam_installed; then
mca_steam_apply
@@ -191,8 +191,8 @@ mca_watch_enabled() {
# _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
# already right. That is the same contract as mca_write_if_changed, 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
+9 -9
View File
@@ -3,7 +3,7 @@
# Paths, translations, output helpers and the change ledger.
#
# Everything here runs unprivileged. This tool only ever writes inside the
# user's own home - flag files, desktop entries, Steam's own scripts - so there
# user's own home (flag files, desktop entries, Steam's own scripts), so there
# is no system state to guard and nothing that needs root.
MCA_VERSION="@VERSION@"
@@ -19,7 +19,7 @@ MCA_PRETTY="Middle-Click Autoscroll"
#
# --enable-blink-features=MiddleClickAutoscroll is the one that works
# everywhere, and the only one that works in the Chromium versions embedded
# applications ship - Steam's CEF, an Electron a few years old, anything
# applications ship: Steam's CEF, an Electron a few years old, anything
# before Chromium 124. A browser started with it puts a yellow bar above the
# page saying an unsupported command line flag is in use, because Chromium
# keeps a list of flags worth warning about and this is on it.
@@ -27,7 +27,7 @@ MCA_PRETTY="Middle-Click Autoscroll"
# --enable-features=MiddleClickAutoscroll is not on that list, so a browser
# started with it says nothing. Blink generates a feature of the same name
# for every one of its runtime flags, which is what makes the two the same
# request - but only since Chromium 124. Before that the name means nothing
# request. But only since Chromium 124. Before that the name means nothing
# and is ignored without a word.
#
# So a browser, which is the only thing that shows the bar and the one thing
@@ -38,7 +38,7 @@ MCA_FLAG="--enable-blink-features=MiddleClickAutoscroll"
# Two browsers do not answer to the Chromium name. Helium ships the feature
# under its own name and sets the runtime flag from that alone. Brave takes
# the generated feature away and switches the flag on from one of its own,
# spelled MiddelButtonClickAutoscroll - the typo is in Brave's source, and the
# spelled MiddelButtonClickAutoscroll. The typo is in Brave's source, and the
# correct spelling does nothing. So browsers are asked for all three. A name a
# browser does not know is ignored, which is what makes one list safe to hand
# to all of them.
@@ -87,7 +87,7 @@ MCA_BACKUPDIR="${MCA_STATEDIR}/backup"
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
# it, so an entry that lives only there is invisible to a scan. A game
# shortcut dragged onto the desktop is exactly that.
#
# Its name is translated: Schreibtisch, Bureau, Escritorio. The name in use is
@@ -217,8 +217,8 @@ fi
# Set by mca_bad and mca_note. The menu redraws straight after an action, which
# would wipe the screen; this marks that something was printed the user still
# has to read. A plain success needs no acknowledgement - the status block at
# the top of the menu already shows the new state.
# has to read. A plain success needs no acknowledgement, because the status
# block at the top of the menu already shows the new state.
MCA_UI_NEEDS_ACK=''
# --quiet silences progress chatter; errors still go to stderr. Used by the
@@ -275,7 +275,7 @@ mca_state_write() {
# ---------------------------------------------------------------------------
# The change ledger
# ---------------------------------------------------------------------------
# Reverting by pattern - "delete every desktop entry that mentions the flag" -
# Reverting by pattern ("delete every desktop entry that mentions the flag")
# would also delete entries the user wrote by hand. So every change is recorded
# instead, and `revert` replays the ledger backwards.
#
@@ -289,7 +289,7 @@ mca_state_write() {
#
# The kinds differ in how they are undone: a backup is restored wholesale, a
# flag file only loses the one line that was added to it, and kwinrc gets one
# key written back - it is a file KDE writes to itself, and putting a whole
# key written back. It is a file KDE writes to itself, and putting a whole
# copy of it back would take everything else settled since with it.
mca_ledger_add() {
+51 -51
View File
@@ -4,7 +4,7 @@
#
# The detection is deliberately conservative. A wrong "yes" appends an unknown
# argument to something that is not Chromium, and plenty of programs treat an
# unrecognised argument as a file name to open - so every rule here is a
# unrecognised argument as a file name to open. So every rule here is a
# positive one, and anything that cannot be identified is reported as unknown
# rather than guessed at.
@@ -13,7 +13,7 @@
# swiftshader libraries) and plain CEF (libcef).
#
# Deliberately not in here: libEGL.so and libffmpeg.so. Chromium ships both, but
# so does the system - /usr/lib/libEGL.so exists on any machine with Mesa - and
# so does the system (/usr/lib/libEGL.so exists on any machine with Mesa), and
# a marker that can be somebody else's file is not a marker.
MCA_MARKERS=(
chrome_crashpad_handler chrome-sandbox chrome_100_percent.pak
@@ -22,14 +22,14 @@ MCA_MARKERS=(
)
# The markers that still mean something when the whole of a tree is searched
# rather than just the directory the binary sits in - inside a Flatpak, a snap
# or an AppImage, where there is no "next to the binary" to look at.
# rather than just the directory the binary sits in. That is the case inside a
# Flatpak, a snap or an AppImage, where there is no "next to the binary".
#
# Three of the names above are missing here on purpose. icudtl.dat is ICU's
# data file and not Chromium's: a Flutter application ships one in data/, and
# a whole-tree search would find it. snapshot_blob.bin and resources.pak are
# the same kind of shared name. Next to a binary they are still evidence,
# because nothing but Chromium unpacks its payload there - a few directories
# because nothing but Chromium unpacks its payload there. A few directories
# deeper they are not.
MCA_MARKERS_STRICT=(
chrome_crashpad_handler chrome-sandbox chrome_100_percent.pak
@@ -81,7 +81,7 @@ MCA_SCRIPT_HINTS='ELECTRON_|app\.asar|chrome-sandbox|libcef|enable-blink-feature
# ---------------------------------------------------------------------------
# Where Flatpak and snapd put the launchers they export. Both add these to
# XDG_DATA_DIRS themselves, through a file in /etc/profile.d - but only for a
# XDG_DATA_DIRS themselves, through a file in /etc/profile.d. But only for a
# session that was started after they were installed, and only for a session
# manager that reads it at all. They are appended, after everything XDG names,
# so a directory that is already in the search path keeps its own position and
@@ -93,7 +93,7 @@ mca_extra_desktop_dirs() {
/var/lib/snapd/desktop/applications
}
# The directories a desktop entry can come from, most specific first - which is
# The directories a desktop entry can come from, most specific first. This is
# also XDG lookup order, so the first file found for an id is the one that is
# actually used.
mca_desktop_dirs() {
@@ -155,7 +155,7 @@ _mca_desktop_read() {
# mca_exec_program <exec line>
# The program a desktop entry actually starts: the first token that is not an
# environment prefix, resolved to an absolute path. The result is left in
# MCA_PROG rather than printed - the scan calls this for every desktop entry on
# MCA_PROG rather than printed. The scan calls this for every desktop entry on
# the system, and a command substitution each time is a fork each time.
#
# Fails for entries this tool has no safe way to rewrite: anything routed
@@ -231,7 +231,7 @@ mca_exec_flatpak_id() {
# Whether an entry starts something inside Steam rather than starting Steam
# itself: it carries a steam:// address of its own. Steam writes one of those
# for every game somebody asks for a shortcut to, and the client's own entry
# never has one - it takes an address from the outside, through %U.
# never has one. It takes an address from the outside, through %U.
mca_exec_is_steam_link() {
local line="$1" prog="$2"
@@ -251,7 +251,7 @@ _mca_prog_is_steam_name() {
# _mca_prog_is_steam_wrapper <program>
# Whether a script in front of the client is a way of starting Steam. People
# put one there to add a switch of their own, and an entry pointing at it is a
# Steam start like any other - but the script is not named after Steam, so
# Steam start like any other. But the script is not named after Steam, so
# nothing above recognises it.
#
# Getting this wrong is worse than it sounds: such a script tends to mention
@@ -282,8 +282,8 @@ _mca_prog_is_steam_wrapper() {
# 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 answer decides whether an entry gets Steam's own switch. 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.
@@ -328,7 +328,7 @@ _mca_stat_batch() {
# The first line of the cache file, and the reason it is there: the verdicts
# below it are keyed on size and mtime, so an entry for a file that has not
# changed is never looked at again. A cache written when a verdict meant
# something else - before an AppImage could come out as anything but "no" -
# something else (before an AppImage could come out as anything but "no")
# would therefore keep answering the old way forever. Bumping this is how such
# a cache gets dropped instead.
MCA_CACHE_FORMAT='# middleclick-autoscroll detect 2'
@@ -380,7 +380,7 @@ _mca_has_markers() {
[[ $dir == "$s" ]] && return 1
done
for s in "${MCA_SYSTEM_DIR_GLOBS[@]}"; do
# Unquoted on purpose - these are patterns, not names.
# Unquoted on purpose: these are patterns, not names.
# shellcheck disable=SC2053
[[ $dir == $s ]] && return 1
done
@@ -396,7 +396,7 @@ _mca_has_markers() {
# The same question for a whole tree, which is the shape a Flatpak, a snap and
# an unpacked AppImage come in: everything the application ships is somewhere
# under one root and there is no single directory that is "next to the binary".
# Hence the narrower list - see MCA_MARKERS_STRICT.
# Hence the narrower list, see MCA_MARKERS_STRICT.
_mca_find_markers() {
local root="$1" depth="$2" m
local -a names=()
@@ -423,9 +423,9 @@ declare -A MCA_SCRIPT_VARS=()
# The text with $NAME and ${NAME} replaced by what the script assigned to them,
# left in MCA_SUBST.
#
# Fails as soon as something turns up that only a running shell could work out
# - a positional parameter, a name the script never set, a default value. That
# is the point: an unresolvable path has to come out as no path at all, never
# Fails as soon as something turns up that only a running shell could work out,
# like a positional parameter, a name the script never set or a default value.
# That is the point: an unresolvable path has to come out as no path at all, never
# as a wrong one.
MCA_SUBST=''
@@ -465,8 +465,8 @@ _mca_script_subst() {
# openSUSE all set the directory and the program name into variables at the top
# of the script and end on `exec -a "$APPNAME" "$LIBDIR/$APPNAME"`. Without
# resolving those there is nothing to follow, and the answer would have to come
# from the hint scan - a weaker kind of evidence than finding the binary and
# its markers.
# from the hint scan, which is weaker evidence than finding the binary and its
# markers.
_mca_script_target() {
local script="$1" line tok name val skip=0
local -a tokens
@@ -537,10 +537,10 @@ _mca_script_target() {
# mca_flags_candidates <program>
# The flag files a launcher reads, in the order it reads them, taken from the
# launcher itself rather than assumed from the distribution. Where the wrappers
# follow that convention - Arch's Electron and Chromium packages do, and take
# extra arguments from $XDG_CONFIG_HOME/<name>-flags.conf - it is a far better
# place to inject than a desktop entry: it survives package updates and it
# launcher itself rather than assumed from the distribution. Arch's Electron
# and Chromium packages follow that convention and take extra arguments from
# $XDG_CONFIG_HOME/<name>-flags.conf. Where the wrappers do that, it is a far
# better place to inject than a desktop entry: it survives package updates and it
# applies to a launch from the terminal too. Where they do not, this finds
# nothing and the caller falls back to the desktop entry.
mca_flags_candidates() {
@@ -553,7 +553,7 @@ mca_flags_candidates() {
# A wrapper that only execs another wrapper (heroic -> electron43) inherits
# that one's flag files, plus the specific name it builds from a variable
# at runtime and therefore never writes down - which is why that one is
# at runtime and therefore never writes down. That is why that one is
# derived from the target's own name rather than found.
#
# It is derived only once the target has shown that it reads a flag file at
@@ -575,7 +575,7 @@ mca_flags_candidates() {
# Looking inside an AppImage
# ---------------------------------------------------------------------------
#
# An AppImage is the AppImage runtime - an ordinary ELF executable - with a
# An AppImage is the AppImage runtime (an ordinary ELF executable) with a
# squashfs image appended to it. The payload is compressed, so nothing the
# application ships is on disk where the marker check could find it, and for a
# long time that made every AppImage a "cannot tell".
@@ -594,7 +594,7 @@ mca_flags_candidates() {
# _mca_bytes <file> <offset> <count>
# Count bytes from an offset, as numbers, in MCA_BYTES. od rather than a shell
# read because a variable cannot hold a NUL byte and these headers are full of
# them - and a whole header at a time rather than a field at a time, because
# them. And a whole header at a time rather than a field at a time, because
# the first question below is asked about every program on the system and one
# od per field would be four forks per program.
MCA_BYTES=()
@@ -627,7 +627,7 @@ _mca_slice() {
#
# Fails for the all-ones value squashfs writes down for a table that is not in
# the image, which is a case the callers below have to tell from a real offset
# and bash arithmetic - signed, 64-bit - cannot represent.
# and bash arithmetic (signed, 64-bit) cannot represent.
MCA_WORD=0
_mca_word() {
@@ -650,7 +650,7 @@ _mca_word() {
#
# Searching for the squashfs magic instead would not be: the runtime carries a
# copy of it in its own code. Neither is the AppImage magic at byte 8 of the
# ELF header a way in - it is there to be zeroed, and a build pipeline that
# ELF header a way in. It is there to be zeroed, and a build pipeline that
# does not want its image picked up by a desktop integration daemon does
# exactly that. So the offset is computed for any ELF at all and the caller
# finds out whether there is an image at it.
@@ -700,7 +700,7 @@ _mca_inflate() {
1)
# squashfs stores a zlib stream and gzip only reads its own
# container, but underneath both are the same deflate data with a
# different wrapper around it - so the wrapper is swapped: zlib's
# different wrapper around it. So the wrapper is swapped: zlib's
# two header bytes are dropped and a minimal gzip header put in
# front. gzip then writes every byte of the block and complains
# about the trailer it did not get, which is why its status is
@@ -734,10 +734,10 @@ _mca_inflate() {
# describe them, and a name is all the caller is looking for.
#
# Fails unless the walk lands exactly on the end of the table. That is the
# integrity check - the block sizes adding up to the table's own length is
# what says the fields were read from a real superblock and that the output is
# the whole of the names rather than some of them - and it is why the caller
# has to collect this before trusting it, never pipe it.
# integrity check: the block sizes adding up to the table's own length is what
# says the fields were read from a real superblock, and that the output is the
# whole of the names rather than some of them. It is also why the caller has
# to collect this before trusting it, never pipe it.
_mca_squashfs_names() {
local file="$1" base="$2"
local comp dir_start end field header size pos
@@ -750,9 +750,9 @@ _mca_squashfs_names() {
(( dir_start > 0 )) || return 1
# Where the names stop: the first table squashfs writes after them. Which
# one that is depends on the image - there is no fragment table when
# one that is depends on the image. There is no fragment table when
# nothing was packed into a fragment, and no export table unless it was
# asked for - so they are tried in the order they are written and the
# asked for. So they are tried in the order they are written and the
# first one that is actually there wins. bytes_used closes the list for an
# image that has none of them.
end=0
@@ -815,14 +815,14 @@ _mca_appimage_verdict() {
&& MCA_BYTES[2] == 113 && MCA_BYTES[3] == 115 )) || return 0
# From here on there is an image, so the worst this can end on is "cannot
# tell" - never "no", which would be an answer about contents that were
# tell". Never "no", which would be an answer about contents that were
# never read.
MCA_APPIMAGE=unknown
names="$(mktemp "${TMPDIR:-/tmp}/mca-names.XXXXXX")" || return 0
# Nothing at all in the table means every block failed to inflate - a
# compressor whose tool is not installed - which is a "cannot tell" too.
# Nothing at all in the table means every block failed to inflate (a
# compressor whose tool is not installed). That is a "cannot tell" too.
if _mca_squashfs_names "$file" "$base" > "$names" 2>/dev/null \
&& [[ -s $names ]]
then
@@ -900,7 +900,7 @@ mca_detect_verdict() {
# mca_is_chromium <program>
# Succeeds when the program is a Chromium, CEF or Electron process. "Cannot
# tell" is not that, so it fails here - anything that has to treat the two
# tell" is not that, so it fails here. Anything that has to treat the two
# differently asks mca_detect_verdict instead.
mca_is_chromium() {
mca_detect_verdict "$1"
@@ -931,13 +931,13 @@ _mca_detect_uncached() {
fi
# A binary. Everything Chromium ships is unpacked next to it, either in the
# same directory or - for /opt/thing/bin/Thing layouts - one level up.
# same directory or (for /opt/thing/bin/Thing layouts) one level up.
dir="$(dirname -- "$real")"
_mca_has_markers "$dir" && return 0
[[ ${dir##*/} == bin ]] && _mca_has_markers "${dir%/*}" && return 0
# An AppImage keeps all of that inside a filesystem appended to itself, so
# there is nothing next to the binary to find - but the names of everything
# there is nothing next to the binary to find. But the names of everything
# in there can be read, and that settles it either way.
_mca_appimage_verdict "$real"
case "$MCA_APPIMAGE" in
@@ -950,8 +950,8 @@ _mca_detect_uncached() {
grep -qaFm1 -- 'enable-blink-features' "$real" 2>/dev/null && return 0
grep -qaFm1 -- 'CHROME_VERSION_EXTRA' "$real" 2>/dev/null && return 0
# What is left is an image that could not be read - an unsupported
# compressor - or the older AppImage layout, which is an ISO9660 filesystem
# What is left is an image that could not be read (an unsupported
# compressor) or the older AppImage layout, which is an ISO9660 filesystem
# and has no name table of this shape at all. Either way the answer is not
# "no", it is "nobody looked".
if [[ $MCA_APPIMAGE == unknown || $real == *.AppImage || $real == *.appimage ]]; then
@@ -993,7 +993,7 @@ mca_scan() {
MCA_PACKAGING=()
# 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
# they can be asked for all at once.
while IFS= read -r dir; do
[[ -d $dir ]] || continue
@@ -1031,8 +1031,8 @@ mca_scan() {
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
# 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
@@ -1047,8 +1047,8 @@ mca_scan() {
MCA_STAT=()
_mca_stat_batch "${c_stat[@]}"
# Pass two: decide what each one is. What it does - an application or a
# browser - and how it was packaged are two separate questions: a Chromium
# Pass two: decide what each one is. What it does (an application or a
# browser) and how it was packaged are two separate questions: a Chromium
# installed as a snap is still a browser, and somebody who has turned
# browsers off means that one too.
for i in "${!c_ids[@]}"; do
@@ -1131,8 +1131,8 @@ mca_desktop_is_browser() {
}
# mca_snap_name <program>
# The snap an executable belongs to, left in MCA_PROG - assigned rather than
# printed for the same reason mca_exec_program is: the scan asks this about
# The snap an executable belongs to, left in MCA_PROG. It is assigned rather
# than printed for the same reason mca_exec_program is: the scan asks this about
# every desktop entry on the system, and a command substitution per entry is a
# fork per entry.
#
+5 -5
View File
@@ -6,7 +6,7 @@
# autoscroll on, Blink stops pasting the primary selection on middle click,
# because the button is doing something else now. Everywhere else on the
# desktop middle click goes on pasting, which is the behaviour this whole
# program exists to get away from - so the desktop's own switch for it is
# program exists to get away from. So the desktop's own switch for it is
# turned off too.
#
# KWin has such a switch, and only for a Wayland session, where the paste is a
@@ -26,7 +26,7 @@ MCA_KWIN_KEY="EnablePrimarySelection"
# The kconfig command line tools, whichever generation this session has. They
# are what System Settings writes kwinrc with, and worth the fork: the file has
# a cascade behind it - /etc/xdg, the kdedefaults directory - and entries a
# a cascade behind it (/etc/xdg, the kdedefaults directory) and entries a
# distribution can mark immutable, and an edit that reaches past all that with
# sed writes something KDE goes on to ignore.
MCA_KDE_TOOL=''
@@ -81,8 +81,8 @@ mca_kde_read() {
local file="${1:-$MCA_KWINRC}" gen val
gen="$(_mca_kde_tool)" || return 1
# kreadconfig creates the file it is pointed at, and the status screen -
# which asks on every redraw - has no business writing anything. A file
# kreadconfig creates the file it is pointed at, and the status screen
# (which asks on every redraw) has no business writing anything. A file
# that is not there has no value in it to read anyway.
[[ -f $file ]] || return 0
@@ -124,7 +124,7 @@ mca_kde_paste_apply() {
if mca_ledger_has "$MCA_KWINRC"; then
# Ours already. What goes back is the value recorded the first time
# round, not what reading the file now would say - that is false, and
# round, not what reading the file now would say. That is false, and
# false is what is being undone.
previous="$(mca_ledger_detail "$MCA_KWINRC")" || previous=unset
elif [[ $current == false ]]; then
+8 -8
View File
@@ -32,7 +32,7 @@ mca_ui_term_restore() {
}
# Runs an action with the terminal handed back to normal line mode, so anything
# it prints - or prompts for - behaves the way a program expects.
# it prints or prompts for behaves the way a program expects.
mca_ui_cooked() {
mca_ui_term_restore
"$@"
@@ -126,8 +126,8 @@ mca_pause() {
# _mca_row <label> <value>
# printf's %-28s pads by bytes, so a label containing "ü" comes out one column
# short. ${#s} counts characters in a UTF-8 locale, so the padding is computed
# here instead - and applied inline, because command substitution would eat the
# trailing spaces again.
# here instead. It is applied inline, because command substitution would eat
# the trailing spaces again.
_mca_row() {
local label="$1" value="$2" pad
pad=$(( 30 - ${#label} ))
@@ -172,7 +172,7 @@ mca_ui_status() {
if (( MCA_N_UNKNOWN )); then
_mca_row "$(mca_msg "Not identified")" \
"${MCA_C_DIM}$(mca_msg "%d - see the applications list" "$MCA_N_UNKNOWN")${MCA_C_RESET}"
"${MCA_C_DIM}$(mca_msg "%d (see the applications list)" "$MCA_N_UNKNOWN")${MCA_C_RESET}"
fi
if mca_steam_installed; then
@@ -294,7 +294,7 @@ mca_ui_settings() {
local title hint
mca_msg_into "$locale" "Settings"; title="$MCA_MSG_RESULT"
mca_msg_into "$locale" "Up/Down select - Space or Right changes - q goes back"
mca_msg_into "$locale" "Up/Down: select, Space or Right: change, q: back"
hint="$MCA_MSG_RESULT"
local clearseq
@@ -387,11 +387,11 @@ mca_ui_apps() {
local title hint legend warn
mca_msg_into "$locale" "Applications"; title="$MCA_MSG_RESULT"
mca_msg_into "$locale" "Up/Down select - Space turns one on or off - q goes back"
mca_msg_into "$locale" "Up/Down: select, Space: turn on or off, q: back"
hint="$MCA_MSG_RESULT"
mca_msg_into "$locale" "Anything not identified is left alone until it is turned on here."
legend="$MCA_MSG_RESULT"
mca_msg_into "$locale" "Autoscroll is off - this is what would be covered."
mca_msg_into "$locale" "Autoscroll is off. This is what would be covered."
warn="$MCA_MSG_RESULT"
# The per-row labels are resolved once, here. Looking them up inside the
@@ -554,7 +554,7 @@ mca_ui_menu() {
fi
;;
q|Q) mca_ui_term_restore; trap - EXIT INT TERM; return 0 ;;
# Anything else - Enter, arrow keys, stray characters - just
# Anything else (Enter, arrow keys, stray characters) just
# redraws. Escape is deliberately not a quit key, so a mistyped
# arrow key cannot close the menu.
*) ;;
+16 -16
View File
@@ -4,19 +4,19 @@
#
# There are two ways in, and the order matters:
#
# 1. A flag file. Where the distribution wraps Electron and Chromium in a
# 1. A flag file. Some distributions wrap Electron and Chromium in a
# launcher script that reads extra arguments from
# $XDG_CONFIG_HOME/<name>-flags.conf - Arch and its derivatives do, and it
# is the convention their packages follow - this is the good one: it is
# the supported way to pass arguments, it survives package upgrades
# $XDG_CONFIG_HOME/<name>-flags.conf. Arch and its derivatives do, and
# their packages follow that convention. Where it exists, this is the good
# way in: it is the supported way to pass arguments, it survives package upgrades
# untouched, and it applies however the program is started, including from
# a terminal.
#
# Nothing is assumed about which distribution this is. The launcher itself
# is read, and the route is taken only for a launcher that really does
# name such a file. Elsewhere - Debian, Ubuntu, Fedora, openSUSE, where
# the equivalent file lives under /etc and is the system's to write -
# there is no flag file to use and route 2 answers for everything.
# name such a file. On Debian, Ubuntu, Fedora and openSUSE the
# equivalent file lives under /etc and is the system's to write. There is
# no flag file to use there, and route 2 answers for everything.
#
# 2. A desktop entry. For applications that ship their own binary with no
# wrapper, and for everything a Flatpak or a snap contains, there is
@@ -176,8 +176,8 @@ mca_flags_apply() {
done
[[ -n $existing_target ]] && return 0
# None exists yet. The last candidate is the wrapper's own fallback - the
# generic electron-flags.conf rather than electron43-flags.conf - so
# None exists yet. The last candidate is the wrapper's own fallback (the
# generic electron-flags.conf rather than electron43-flags.conf). So
# creating that one also covers every other application using the same
# shared Electron.
target="${candidates[-1]}"
@@ -319,7 +319,7 @@ MCA_MARK_SHADOW='X-MCA-Generated'
MCA_MARK_INPLACE='X-MCA-Patched'
# _mca_desktop_transform <file> <marker> [flags] [position]
# The whole file with every Exec line rewritten - the main one and the one in
# The whole file with every Exec line rewritten: the main one and the one in
# each Desktop Action, because those are the right-click menu entries and a
# user who starts Steam from "Library" expects the same behaviour there.
_mca_desktop_transform() {
@@ -360,8 +360,8 @@ mca_desktop_apply() {
local target="$MCA_APPDIR/$id.desktop" content backup
if [[ "$src" == "$target" ]]; then
# The user's own entry - an AppImage, a web app shortcut, something
# installed by hand. There is nowhere to shadow it from, so it is
# The user's own entry, like an AppImage, a web app shortcut or
# something installed by hand. There is nowhere to shadow it from, so it is
# edited directly and the original is kept.
grep -q "^$MCA_MARK_INPLACE=" "$src" 2>/dev/null && return 0
@@ -383,7 +383,7 @@ mca_desktop_apply() {
mkdir -p "$MCA_APPDIR" 2>/dev/null || return 1
# Something is already shadowing this entry. Unless it is a shadow of ours,
# it is the user's own file - possibly one we edited in place earlier - and
# it is the user's own file (possibly one we edited in place earlier), and
# overwriting it here would lose it.
if [[ -e $target ]] && ! grep -q "^$MCA_MARK_SHADOW=" "$target" 2>/dev/null; then
return 1
@@ -407,8 +407,8 @@ mca_desktop_apply() {
# entry in the menu completely, which is why Discord launched at login used
# to behave differently from Discord launched from the menu.
#
# The desktop folder, where a shortcut somebody dragged out of the menu -
# or asked Steam for - lives and nowhere else.
# The desktop folder, where a shortcut somebody dragged out of the menu
# (or asked Steam for) lives and nowhere else.
#
# Neither can be shadowed from anywhere, so both are edited where they stand,
# with the original kept.
@@ -568,7 +568,7 @@ mca_spotify_apply() {
# 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
# 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. 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.
+11 -11
View File
@@ -2,25 +2,25 @@
#
# Steam.
#
# Steam's interface is CEF, so the feature is there - but Steam builds the
# Steam's interface is CEF, so the feature is there. But Steam builds the
# command line for its web helper itself and offers no way to add to it. The
# only place to get an argument in is the shell script that starts the helper,
# which lives inside Steam's own installation:
#
# ~/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
#
# Steam compares the installed files against its manifest at every start - by
# size and timestamp rather than by content - and restores whatever differs.
# 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
# back out of the script's comments and the timestamp is put back afterwards,
# which leaves a file that is byte-for-byte the size Steam recorded and as old
# 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.
# and the flag survives however Steam was started: from the menu, from a game
# shortcut, from a launcher like Heroic, or from a terminal.
#
# 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
# at the shutdown it runs itself. 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
@@ -114,8 +114,8 @@ _mca_steam_exec_line() {
# The patched script on stdout: the flags appended to the line that starts the
# web helper, and 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.
# Everything else is left alone, like setting up the container runtime or
# deciding whether the sandbox can be used.
#
# 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
@@ -180,8 +180,8 @@ _mca_steam_refresh_backup() {
# The script is already patched. Whether that is a patch Steam can live with is
# a question of length: an earlier version of this program appended the flag
# where the comments could not pay for it, which leaves the script longer than
# the file Steam wrote down - and a client that checks its files reinstalls
# itself over that, then quits instead of starting.
# the file Steam wrote down. A client that checks its files reinstalls itself
# over that, then quits instead of starting.
#
# Rebuilt from the untouched original kept when the script was first patched,
# never from the patched file, the flag either fits this time or the original
@@ -277,7 +277,7 @@ mca_steam_revert() {
return 0
fi
# No backup to fall back on - take the flags back out of the exec line.
# 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
+3 -3
View File
@@ -1,11 +1,11 @@
#!/usr/bin/env bash
#
# middleclick-autoscroll - middle-click autoscroll for Chromium-based
# middleclick-autoscroll: middle-click autoscroll for Chromium-based
# applications on Linux
#
# Blink has had Windows-style autoscroll for years, behind a runtime flag that
# is not turned on for Linux because middle click is taken by primary-selection
# paste there. Turning it on is a matter of one command line argument - the
# paste there. Turning it on is a matter of one command line argument. The
# work is finding every application that needs it, putting the argument
# somewhere it survives an update, and doing the same for the two programs that
# do not take arguments at all.
@@ -50,7 +50,7 @@ mca_do_enable() {
if mca_watch_available; then
mca_watch_enable || mca_note "$(mca_msg "Could not start the watcher for newly installed applications.")"
else
mca_note "$(mca_msg "No systemd user session - newly installed applications will not be picked up on their own.")"
mca_note "$(mca_msg "No systemd user session, so newly installed applications will not be picked up on their own.")"
fi
fi