Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de6cf98dcc | ||
|
|
95d602e1c4 | ||
|
|
9b6c64bd97 | ||
|
|
8a7e67b1f9 | ||
|
|
c0fca75cbc |
No files matched your search
@@ -0,0 +1,23 @@
|
|||||||
|
name: 🧩 App does not work
|
||||||
|
description: Autoscroll does not work in an app. Just tell us which one.
|
||||||
|
title: 'App: '
|
||||||
|
labels:
|
||||||
|
- app
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: Just add the app's name to the title. The rest is optional.
|
||||||
|
- type: dropdown
|
||||||
|
id: install
|
||||||
|
attributes:
|
||||||
|
label: How is it installed?
|
||||||
|
description: Skip it if you are not sure.
|
||||||
|
options:
|
||||||
|
- Native package
|
||||||
|
- Flatpak
|
||||||
|
- Snap
|
||||||
|
- AppImage
|
||||||
|
- type: textarea
|
||||||
|
id: more
|
||||||
|
attributes:
|
||||||
|
label: More info
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
name: issues
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [labeled]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# The "fixed" and "not chromium" labels answer and close the issue.
|
||||||
|
close:
|
||||||
|
name: close on label
|
||||||
|
if: >-
|
||||||
|
github.event.issue.state == 'open'
|
||||||
|
&& (github.event.label.name == 'fixed' || github.event.label.name == 'not chromium')
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
LABEL: ${{ github.event.label.name }}
|
||||||
|
NUMBER: ${{ github.event.issue.number }}
|
||||||
|
run: |
|
||||||
|
if [ "$LABEL" = fixed ]; then
|
||||||
|
reason=completed
|
||||||
|
comment='Fixed, thanks for the report! The fix comes with the next release.'
|
||||||
|
else
|
||||||
|
reason='not planned'
|
||||||
|
comment='Thanks for the report! This app is not built on Chromium, Electron or CEF. So it has no autoscroll built in that this tool could turn on.'
|
||||||
|
fi
|
||||||
|
gh issue close "$NUMBER" --repo "$GITHUB_REPOSITORY" --reason "$reason" --comment "$comment"
|
||||||
@@ -2,6 +2,19 @@
|
|||||||
|
|
||||||
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.
|
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.7.0
|
||||||
|
|
||||||
|
_2026-10-01_
|
||||||
|
|
||||||
|
Welcome to middleclick-autoscroll `v1.7.0`! Firefox gets autoscroll now, and so do LibreWolf, Zen, Floorp, Waterfox and Thunderbird. It starts working after your next login, or right away with **Re-apply everything**. Then restart Firefox.
|
||||||
|
|
||||||
|
### Highlights
|
||||||
|
|
||||||
|
- Autoscroll in Firefox
|
||||||
|
- LibreWolf, Zen, Floorp, Waterfox and Thunderbird too
|
||||||
|
- Flatpak and snap included
|
||||||
|
- New Firefox profiles get it on their own
|
||||||
|
|
||||||
## v1.6.1
|
## v1.6.1
|
||||||
|
|
||||||
_2026-09-29_
|
_2026-09-29_
|
||||||
|
|||||||
@@ -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.6.1
|
VERSION ?= 1.7.0
|
||||||
|
|
||||||
PREFIX ?= /usr
|
PREFIX ?= /usr
|
||||||
DESTDIR ?=
|
DESTDIR ?=
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<h3 align="center">Middle-click autoscroll in every app that supports it.</h3>
|
<h3 align="center">Middle-click autoscroll in every app that supports it.</h3>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
Browsers, Electron apps like Discord and Spotify, Steam and anything else built on Chromium.
|
Firefox, Chromium browsers, Electron apps like Discord and Spotify, Steam and anything else built on Chromium.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h5 align="center">
|
<h5 align="center">
|
||||||
@@ -126,6 +126,9 @@ Adding it to every app by hand is a pain, and updates can undo it. This tool doe
|
|||||||
**Browsers** get a spelling of the flag that shows no warning bar. Brave and Helium also get their
|
**Browsers** get a spelling of the flag that shows no warning bar. Brave and Helium also get their
|
||||||
own name for the feature. A browser ignores names it does not know.
|
own name for the feature. A browser ignores names it does not know.
|
||||||
|
|
||||||
|
**Firefox** has autoscroll too, but as a setting, not a flag. It goes into the `user.js` of each
|
||||||
|
profile. The same works for LibreWolf, Zen, Floorp, Waterfox and Thunderbird.
|
||||||
|
|
||||||
**Steam** builds its own command line and repairs any file that looks changed. So the flag goes into
|
**Steam** builds its own command line and repairs any file that looks changed. So the flag goes into
|
||||||
the script that starts its web helper, and the file keeps the size and date Steam expects. Steam
|
the script that starts its web helper, and the file keeps the size and date Steam expects. Steam
|
||||||
finds nothing to repair, and autoscroll works in the store and the library. After a Steam update,
|
finds nothing to repair, and autoscroll works in the store and the library. After a Steam update,
|
||||||
|
|||||||
@@ -34,10 +34,13 @@ it). A name a browser does not know is ignored. It works on any distribution:
|
|||||||
which of the routes below an application takes is read off its launcher, not
|
which of the routes below an application takes is read off its launcher, not
|
||||||
assumed from where the launcher came from.
|
assumed from where the launcher came from.
|
||||||
|
|
||||||
|
Firefox and everything else built on Gecko has autoscroll as well, behind a
|
||||||
|
setting rather than a flag. See *FIREFOX*.
|
||||||
|
|
||||||
Run without a command it shows an interactive menu. Everything it can be told
|
Run without a command it shows an interactive menu. Everything it can be told
|
||||||
is reachable from there; the configuration file behind it does not need to be
|
is reachable from there; the configuration file behind it does not need to be
|
||||||
edited by hand. Its applications list turns single applications on or off,
|
edited by hand. Its applications list turns single applications on or off,
|
||||||
Steam and Spotify included. Its settings hold the rest: the desktop's
|
Steam, Spotify and Firefox included. Its settings hold the rest: the desktop's
|
||||||
middle-click paste, the watcher, and more Chromium arguments for every
|
middle-click paste, the watcher, and more Chromium arguments for every
|
||||||
application.
|
application.
|
||||||
|
|
||||||
@@ -69,8 +72,7 @@ is refused.
|
|||||||
last run was.
|
last run was.
|
||||||
|
|
||||||
*list*
|
*list*
|
||||||
Every Chromium-based application that was found, and how each one is
|
Every application that was found, and how each one is handled.
|
||||||
handled.
|
|
||||||
|
|
||||||
*-h*, *--help*
|
*-h*, *--help*
|
||||||
Show a summary of the commands.
|
Show a summary of the commands.
|
||||||
@@ -191,6 +193,29 @@ where the flag goes, and the launcher shows up in the applications list like
|
|||||||
any other application. Installed as a plain package, a Flatpak or a snap, it is
|
any other application. Installed as a plain package, a Flatpak or a snap, it is
|
||||||
an ordinary desktop entry and needs nothing special.
|
an ordinary desktop entry and needs nothing special.
|
||||||
|
|
||||||
|
# FIREFOX
|
||||||
|
|
||||||
|
Firefox has autoscroll of its own, switched off on Linux. There is no flag for
|
||||||
|
it, only a setting: *general.autoScroll*. It goes into _user.js_ in every
|
||||||
|
profile, as a marked block, and Firefox reads that file at every start. The
|
||||||
|
same goes for everything built on Gecko: LibreWolf, Zen, Floorp, Waterfox and
|
||||||
|
Thunderbird.
|
||||||
|
|
||||||
|
Where the profiles are is read from the application's own _application.ini_,
|
||||||
|
the way Firefox works it out: _~/.mozilla/firefox_, or
|
||||||
|
_~/.config/mozilla/firefox_ for a new install of Firefox 147 or later. A Flatpak
|
||||||
|
or a snap has the same inside its own folder. Every profile in _profiles.ini_
|
||||||
|
is covered. The watcher looks at that file too, so a new profile is covered
|
||||||
|
from its second start on.
|
||||||
|
|
||||||
|
A profile where the setting is already on, in Firefox's own settings or in
|
||||||
|
_user.js_, is left alone and not recorded.
|
||||||
|
|
||||||
|
Firefox copies the setting into _prefs.js_, so *disable* takes it out of both
|
||||||
|
files. A Firefox that is still open would write it back when it quits. So for
|
||||||
|
that profile _user.js_ says *false* instead, and the next *disable* or
|
||||||
|
*enable* clears it up.
|
||||||
|
|
||||||
# MIDDLE-CLICK PASTE
|
# MIDDLE-CLICK PASTE
|
||||||
|
|
||||||
Inside a Chromium application the argument settles this on its own: with
|
Inside a Chromium application the argument settles this on its own: with
|
||||||
@@ -269,8 +294,12 @@ _~/.config/kwinrc_
|
|||||||
written when the desktop's middle-click paste is turned off, and put
|
written when the desktop's middle-click paste is turned off, and put
|
||||||
back by *disable*.
|
back by *disable*.
|
||||||
|
|
||||||
|
_user.js_ in every Firefox profile
|
||||||
|
Gets a block between *// >>> middleclick-autoscroll* and
|
||||||
|
*// <<< middleclick-autoscroll*. Nothing else in the file is touched.
|
||||||
|
|
||||||
_~/.cache/middleclick-autoscroll/detect_
|
_~/.cache/middleclick-autoscroll/detect_
|
||||||
Which programs were found to be Chromium, keyed by size and modification
|
Which programs were found to be Chromium or Gecko, keyed by size and modification
|
||||||
time. Its first line says which version of the program wrote it, and a
|
time. Its first line says which version of the program wrote it, and a
|
||||||
file from an older one is ignored rather than trusted. Otherwise an entry
|
file from an older one is ignored rather than trusted. Otherwise an entry
|
||||||
for a file that has not changed would never be looked at again.
|
for a file that has not changed would never be looked at again.
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ msgstr "soubor s příznaky"
|
|||||||
msgid "launcher"
|
msgid "launcher"
|
||||||
msgstr "spouštěč"
|
msgstr "spouštěč"
|
||||||
|
|
||||||
|
msgid "profile"
|
||||||
|
msgstr "profil"
|
||||||
|
|
||||||
msgid "cannot tell"
|
msgid "cannot tell"
|
||||||
msgstr "nelze určit"
|
msgstr "nelze určit"
|
||||||
|
|
||||||
@@ -131,8 +134,8 @@ msgstr "Nastavení se nepodařilo uložit."
|
|||||||
msgid "Looking at the installed applications..."
|
msgid "Looking at the installed applications..."
|
||||||
msgstr "Procházím nainstalované aplikace..."
|
msgstr "Procházím nainstalované aplikace..."
|
||||||
|
|
||||||
msgid "No Chromium-based applications found."
|
msgid "No supported applications found."
|
||||||
msgstr "Nenalezeny žádné aplikace založené na Chromiu."
|
msgstr "Nenalezeny žádné podporované aplikace."
|
||||||
|
|
||||||
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
||||||
msgstr "Co je označeno „nelze určit“, zůstane vypnuté, dokud to tu nezapnete."
|
msgstr "Co je označeno „nelze určit“, zůstane vypnuté, dokud to tu nezapnete."
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ msgstr "Flag-Datei"
|
|||||||
msgid "launcher"
|
msgid "launcher"
|
||||||
msgstr "Startereintrag"
|
msgstr "Startereintrag"
|
||||||
|
|
||||||
|
msgid "profile"
|
||||||
|
msgstr "Profil"
|
||||||
|
|
||||||
msgid "cannot tell"
|
msgid "cannot tell"
|
||||||
msgstr "nicht erkennbar"
|
msgstr "nicht erkennbar"
|
||||||
|
|
||||||
@@ -131,8 +134,8 @@ msgstr "Einstellung konnte nicht gespeichert werden."
|
|||||||
msgid "Looking at the installed applications..."
|
msgid "Looking at the installed applications..."
|
||||||
msgstr "Installierte Anwendungen werden durchgesehen …"
|
msgstr "Installierte Anwendungen werden durchgesehen …"
|
||||||
|
|
||||||
msgid "No Chromium-based applications found."
|
msgid "No supported applications found."
|
||||||
msgstr "Keine Chromium-basierten Anwendungen gefunden."
|
msgstr "Keine unterstützten Anwendungen gefunden."
|
||||||
|
|
||||||
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
||||||
msgstr "Was „nicht erkennbar“ ist, bleibt aus, bis es hier eingeschaltet wird."
|
msgstr "Was „nicht erkennbar“ ist, bleibt aus, bis es hier eingeschaltet wird."
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ msgstr "archivo de flags"
|
|||||||
msgid "launcher"
|
msgid "launcher"
|
||||||
msgstr "lanzador"
|
msgstr "lanzador"
|
||||||
|
|
||||||
|
msgid "profile"
|
||||||
|
msgstr "perfil"
|
||||||
|
|
||||||
msgid "cannot tell"
|
msgid "cannot tell"
|
||||||
msgstr "no se sabe"
|
msgstr "no se sabe"
|
||||||
|
|
||||||
@@ -132,8 +135,8 @@ msgstr "No se pudo guardar el ajuste."
|
|||||||
msgid "Looking at the installed applications..."
|
msgid "Looking at the installed applications..."
|
||||||
msgstr "Revisando las aplicaciones instaladas..."
|
msgstr "Revisando las aplicaciones instaladas..."
|
||||||
|
|
||||||
msgid "No Chromium-based applications found."
|
msgid "No supported applications found."
|
||||||
msgstr "No se encontraron aplicaciones basadas en Chromium."
|
msgstr "No se encontraron aplicaciones compatibles."
|
||||||
|
|
||||||
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
||||||
msgstr "Lo marcado como «no se sabe» sigue desactivado hasta activarlo aquí."
|
msgstr "Lo marcado como «no se sabe» sigue desactivado hasta activarlo aquí."
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ msgstr "fichier de flags"
|
|||||||
msgid "launcher"
|
msgid "launcher"
|
||||||
msgstr "lanceur"
|
msgstr "lanceur"
|
||||||
|
|
||||||
|
msgid "profile"
|
||||||
|
msgstr "profil"
|
||||||
|
|
||||||
msgid "cannot tell"
|
msgid "cannot tell"
|
||||||
msgstr "indéterminé"
|
msgstr "indéterminé"
|
||||||
|
|
||||||
@@ -132,8 +135,8 @@ msgstr "Impossible d'enregistrer le paramètre."
|
|||||||
msgid "Looking at the installed applications..."
|
msgid "Looking at the installed applications..."
|
||||||
msgstr "Examen des applications installées..."
|
msgstr "Examen des applications installées..."
|
||||||
|
|
||||||
msgid "No Chromium-based applications found."
|
msgid "No supported applications found."
|
||||||
msgstr "Aucune application basée sur Chromium trouvée."
|
msgstr "Aucune application prise en charge trouvée."
|
||||||
|
|
||||||
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ msgstr "file di flag"
|
|||||||
msgid "launcher"
|
msgid "launcher"
|
||||||
msgstr "lanciatore"
|
msgstr "lanciatore"
|
||||||
|
|
||||||
|
msgid "profile"
|
||||||
|
msgstr "profilo"
|
||||||
|
|
||||||
msgid "cannot tell"
|
msgid "cannot tell"
|
||||||
msgstr "incerto"
|
msgstr "incerto"
|
||||||
|
|
||||||
@@ -132,8 +135,8 @@ msgstr "Impossibile salvare l'impostazione."
|
|||||||
msgid "Looking at the installed applications..."
|
msgid "Looking at the installed applications..."
|
||||||
msgstr "Esame delle applicazioni installate..."
|
msgstr "Esame delle applicazioni installate..."
|
||||||
|
|
||||||
msgid "No Chromium-based applications found."
|
msgid "No supported applications found."
|
||||||
msgstr "Nessuna applicazione basata su Chromium trovata."
|
msgstr "Nessuna applicazione supportata trovata."
|
||||||
|
|
||||||
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ msgstr ""
|
|||||||
msgid "launcher"
|
msgid "launcher"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "profile"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "cannot tell"
|
msgid "cannot tell"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -130,7 +133,7 @@ msgstr ""
|
|||||||
msgid "Looking at the installed applications..."
|
msgid "Looking at the installed applications..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "No Chromium-based applications found."
|
msgid "No supported applications found."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ msgstr "flagbestand"
|
|||||||
msgid "launcher"
|
msgid "launcher"
|
||||||
msgstr "starter"
|
msgstr "starter"
|
||||||
|
|
||||||
|
msgid "profile"
|
||||||
|
msgstr "profiel"
|
||||||
|
|
||||||
msgid "cannot tell"
|
msgid "cannot tell"
|
||||||
msgstr "onbekend"
|
msgstr "onbekend"
|
||||||
|
|
||||||
@@ -132,8 +135,8 @@ msgstr "De instelling kon niet worden opgeslagen."
|
|||||||
msgid "Looking at the installed applications..."
|
msgid "Looking at the installed applications..."
|
||||||
msgstr "Geïnstalleerde toepassingen worden bekeken..."
|
msgstr "Geïnstalleerde toepassingen worden bekeken..."
|
||||||
|
|
||||||
msgid "No Chromium-based applications found."
|
msgid "No supported applications found."
|
||||||
msgstr "Geen op Chromium gebaseerde toepassingen gevonden."
|
msgstr "Geen ondersteunde toepassingen gevonden."
|
||||||
|
|
||||||
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ msgstr "plik flag"
|
|||||||
msgid "launcher"
|
msgid "launcher"
|
||||||
msgstr "skrót"
|
msgstr "skrót"
|
||||||
|
|
||||||
|
msgid "profile"
|
||||||
|
msgstr "profil"
|
||||||
|
|
||||||
msgid "cannot tell"
|
msgid "cannot tell"
|
||||||
msgstr "nie wiadomo"
|
msgstr "nie wiadomo"
|
||||||
|
|
||||||
@@ -131,8 +134,8 @@ msgstr "Nie udało się zapisać ustawienia."
|
|||||||
msgid "Looking at the installed applications..."
|
msgid "Looking at the installed applications..."
|
||||||
msgstr "Przeglądanie zainstalowanych aplikacji..."
|
msgstr "Przeglądanie zainstalowanych aplikacji..."
|
||||||
|
|
||||||
msgid "No Chromium-based applications found."
|
msgid "No supported applications found."
|
||||||
msgstr "Nie znaleziono aplikacji opartych na Chromium."
|
msgstr "Nie znaleziono obsługiwanych aplikacji."
|
||||||
|
|
||||||
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
+5
-2
@@ -39,6 +39,9 @@ msgstr "arquivo de flags"
|
|||||||
msgid "launcher"
|
msgid "launcher"
|
||||||
msgstr "lançador"
|
msgstr "lançador"
|
||||||
|
|
||||||
|
msgid "profile"
|
||||||
|
msgstr "perfil"
|
||||||
|
|
||||||
msgid "cannot tell"
|
msgid "cannot tell"
|
||||||
msgstr "indeterminado"
|
msgstr "indeterminado"
|
||||||
|
|
||||||
@@ -132,8 +135,8 @@ msgstr "Não foi possível salvar a configuração."
|
|||||||
msgid "Looking at the installed applications..."
|
msgid "Looking at the installed applications..."
|
||||||
msgstr "Verificando os aplicativos instalados..."
|
msgstr "Verificando os aplicativos instalados..."
|
||||||
|
|
||||||
msgid "No Chromium-based applications found."
|
msgid "No supported applications found."
|
||||||
msgstr "Nenhum aplicativo baseado em Chromium encontrado."
|
msgstr "Nenhum aplicativo compatível encontrado."
|
||||||
|
|
||||||
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ msgstr "файл флагов"
|
|||||||
msgid "launcher"
|
msgid "launcher"
|
||||||
msgstr "ярлык"
|
msgstr "ярлык"
|
||||||
|
|
||||||
|
msgid "profile"
|
||||||
|
msgstr "профиль"
|
||||||
|
|
||||||
msgid "cannot tell"
|
msgid "cannot tell"
|
||||||
msgstr "неизвестно"
|
msgstr "неизвестно"
|
||||||
|
|
||||||
@@ -132,8 +135,8 @@ msgstr "Не удалось сохранить настройку."
|
|||||||
msgid "Looking at the installed applications..."
|
msgid "Looking at the installed applications..."
|
||||||
msgstr "Просмотр установленных приложений..."
|
msgstr "Просмотр установленных приложений..."
|
||||||
|
|
||||||
msgid "No Chromium-based applications found."
|
msgid "No supported applications found."
|
||||||
msgstr "Приложения на основе Chromium не найдены."
|
msgstr "Поддерживаемые приложения не найдены."
|
||||||
|
|
||||||
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ msgstr "bayrak dosyası"
|
|||||||
msgid "launcher"
|
msgid "launcher"
|
||||||
msgstr "başlatıcı"
|
msgstr "başlatıcı"
|
||||||
|
|
||||||
|
msgid "profile"
|
||||||
|
msgstr "profil"
|
||||||
|
|
||||||
msgid "cannot tell"
|
msgid "cannot tell"
|
||||||
msgstr "belirsiz"
|
msgstr "belirsiz"
|
||||||
|
|
||||||
@@ -132,8 +135,8 @@ msgstr "Ayar kaydedilemedi."
|
|||||||
msgid "Looking at the installed applications..."
|
msgid "Looking at the installed applications..."
|
||||||
msgstr "Kurulu uygulamalara bakılıyor..."
|
msgstr "Kurulu uygulamalara bakılıyor..."
|
||||||
|
|
||||||
msgid "No Chromium-based applications found."
|
msgid "No supported applications found."
|
||||||
msgstr "Chromium tabanlı uygulama bulunamadı."
|
msgstr "Desteklenen uygulama bulunamadı."
|
||||||
|
|
||||||
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
||||||
msgstr "\"belirsiz\" olarak işaretlenenler burada açılana kadar kapalı kalır."
|
msgstr "\"belirsiz\" olarak işaretlenenler burada açılana kadar kapalı kalır."
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ msgstr "файл прапорців"
|
|||||||
msgid "launcher"
|
msgid "launcher"
|
||||||
msgstr "ярлик"
|
msgstr "ярлик"
|
||||||
|
|
||||||
|
msgid "profile"
|
||||||
|
msgstr "профіль"
|
||||||
|
|
||||||
msgid "cannot tell"
|
msgid "cannot tell"
|
||||||
msgstr "невідомо"
|
msgstr "невідомо"
|
||||||
|
|
||||||
@@ -131,8 +134,8 @@ msgstr "Не вдалося зберегти налаштування."
|
|||||||
msgid "Looking at the installed applications..."
|
msgid "Looking at the installed applications..."
|
||||||
msgstr "Перегляд встановлених застосунків..."
|
msgstr "Перегляд встановлених застосунків..."
|
||||||
|
|
||||||
msgid "No Chromium-based applications found."
|
msgid "No supported applications found."
|
||||||
msgstr "Застосунків на основі Chromium не знайдено."
|
msgstr "Підтримуваних застосунків не знайдено."
|
||||||
|
|
||||||
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
msgid "Anything marked \"cannot tell\" stays off until it is turned on here."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Watch for newly installed Chromium-based applications
|
Description=Watch for newly installed applications
|
||||||
Documentation=man:middleclick-autoscroll(1)
|
Documentation=man:middleclick-autoscroll(1)
|
||||||
|
|
||||||
[Path]
|
[Path]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Apply middle-click autoscroll to Chromium-based applications
|
Description=Apply middle-click autoscroll
|
||||||
Documentation=man:middleclick-autoscroll(1)
|
Documentation=man:middleclick-autoscroll(1)
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
|
|||||||
+45
-13
@@ -16,6 +16,7 @@ MCA_ROUTES=()
|
|||||||
# desktop - no flag file; shadow or edit the desktop entry
|
# desktop - no flag file; shadow or edit the desktop entry
|
||||||
# steam - Steam's own two-part treatment
|
# steam - Steam's own two-part treatment
|
||||||
# spotify - the flag goes into spotify-launcher's configuration file
|
# spotify - the flag goes into spotify-launcher's configuration file
|
||||||
|
# gecko - a setting in each of the application's profiles
|
||||||
# unknown - cannot tell what engine this is (an AppImage), so nothing is done
|
# unknown - cannot tell what engine this is (an AppImage), so nothing is done
|
||||||
# off - detected, but switched off
|
# off - detected, but switched off
|
||||||
#
|
#
|
||||||
@@ -27,7 +28,7 @@ MCA_ROUTE=''
|
|||||||
mca_route() {
|
mca_route() {
|
||||||
local kind="$1" id="$2" prog="$3" packaging="${4:-native}"
|
local kind="$1" id="$2" prog="$3" packaging="${4:-native}"
|
||||||
|
|
||||||
if [[ $kind == steam || $kind == spotify ]]; then
|
if [[ $kind == steam || $kind == spotify || $kind == gecko ]]; then
|
||||||
if mca_config_list_has Skip "$id"; then
|
if mca_config_list_has Skip "$id"; then
|
||||||
MCA_ROUTE=off
|
MCA_ROUTE=off
|
||||||
else
|
else
|
||||||
@@ -65,6 +66,7 @@ mca_apply() {
|
|||||||
MCA_CHANGES=0
|
MCA_CHANGES=0
|
||||||
MCA_ROUTES=()
|
MCA_ROUTES=()
|
||||||
MCA_N_ON=0; MCA_N_OFF=0; MCA_N_UNKNOWN=0
|
MCA_N_ON=0; MCA_N_OFF=0; MCA_N_UNKNOWN=0
|
||||||
|
MCA_GECKO_SEEN=(); MCA_GECKO_WATCH=()
|
||||||
|
|
||||||
mca_config_load
|
mca_config_load
|
||||||
|
|
||||||
@@ -116,6 +118,9 @@ mca_apply() {
|
|||||||
(( spotify_done )) || mca_spotify_apply
|
(( spotify_done )) || mca_spotify_apply
|
||||||
spotify_done=1
|
spotify_done=1
|
||||||
;;
|
;;
|
||||||
|
gecko)
|
||||||
|
mca_gecko_apply "${MCA_PROFILES[i]}" "$packaging" "$prog"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -178,7 +183,8 @@ MCA_UNIT_SERVICE="middleclick-autoscroll.service"
|
|||||||
# The desktop folder is watched like every other directory an entry can turn up
|
# 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
|
# 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
|
# cannot know it. So that one path is written here, into a drop-in, from the
|
||||||
# name this system actually uses.
|
# name this system actually uses. The same goes for where Firefox and its forks
|
||||||
|
# keep their profiles, which depends on what is installed.
|
||||||
MCA_UNIT_DROPIN="${MCA_XDG_CONFIG}/systemd/user/${MCA_UNIT_PATH}.d"
|
MCA_UNIT_DROPIN="${MCA_XDG_CONFIG}/systemd/user/${MCA_UNIT_PATH}.d"
|
||||||
|
|
||||||
mca_watch_available() {
|
mca_watch_available() {
|
||||||
@@ -196,23 +202,47 @@ mca_watch_enabled() {
|
|||||||
# same reason: the watcher runs after every desktop entry that appears anywhere on
|
# same reason: the watcher runs after every desktop entry that appears anywhere on
|
||||||
# the system, and a daemon-reload each time would be absurd.
|
# the system, and a daemon-reload each time would be absurd.
|
||||||
_mca_watch_dropin_write() {
|
_mca_watch_dropin_write() {
|
||||||
local dir file="$MCA_UNIT_DROPIN/desktop.conf" content
|
local dir path content='' changed=1
|
||||||
|
|
||||||
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
|
# 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.
|
# to mean itself. Rare in a folder name, fatal when it happens.
|
||||||
content="[Path]"$'\n'"PathModified=${dir//%/%%}"$'\n'
|
dir="$(mca_desktop_folder)"
|
||||||
|
[[ -d $dir ]] && content="[Path]"$'\n'"PathModified=${dir//%/%%}"$'\n'
|
||||||
|
_mca_watch_conf desktop.conf "$content" && changed=0
|
||||||
|
|
||||||
mca_write_if_changed "$file" "$content"
|
# Filled by the apply that ran just before. A new profile is added there.
|
||||||
|
content=''
|
||||||
|
for path in "${MCA_GECKO_WATCH[@]}"; do
|
||||||
|
content+="PathChanged=${path//%/%%}"$'\n'
|
||||||
|
done
|
||||||
|
[[ -n $content ]] && content="[Path]"$'\n'"$content"
|
||||||
|
_mca_watch_conf profiles.conf "$content" && changed=0
|
||||||
|
|
||||||
|
return "$changed"
|
||||||
|
}
|
||||||
|
|
||||||
|
# _mca_watch_conf <name> <content>
|
||||||
|
# Writes one drop-in, or removes it when the content is empty. Returns 0 when
|
||||||
|
# it changed.
|
||||||
|
_mca_watch_conf() {
|
||||||
|
local file="$MCA_UNIT_DROPIN/$1"
|
||||||
|
|
||||||
|
if [[ -n $2 ]]; then
|
||||||
|
mca_write_if_changed "$file" "$2"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -e $file ]] || return 1
|
||||||
|
rm -f -- "$file"
|
||||||
|
rmdir "$MCA_UNIT_DROPIN" 2>/dev/null || true
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
_mca_watch_dropin_remove() {
|
_mca_watch_dropin_remove() {
|
||||||
[[ -e "$MCA_UNIT_DROPIN/desktop.conf" ]] || return 1
|
local changed=1
|
||||||
rm -f -- "$MCA_UNIT_DROPIN/desktop.conf"
|
_mca_watch_conf desktop.conf '' && changed=0
|
||||||
rmdir "$MCA_UNIT_DROPIN" 2>/dev/null || true
|
_mca_watch_conf profiles.conf '' && changed=0
|
||||||
return 0
|
return "$changed"
|
||||||
}
|
}
|
||||||
|
|
||||||
mca_watch_enable() {
|
mca_watch_enable() {
|
||||||
@@ -226,7 +256,8 @@ mca_watch_enable() {
|
|||||||
|
|
||||||
# mca_watch_refresh
|
# mca_watch_refresh
|
||||||
# Keeps a running watcher in step with a desktop folder that has been renamed,
|
# 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.
|
# which is what a change of session language does to it, and with the Firefox
|
||||||
|
# profiles there are now.
|
||||||
mca_watch_refresh() {
|
mca_watch_refresh() {
|
||||||
mca_watch_available || return 0
|
mca_watch_available || return 0
|
||||||
_mca_watch_dropin_write || return 0
|
_mca_watch_dropin_write || return 0
|
||||||
@@ -295,6 +326,7 @@ mca_route_label() {
|
|||||||
desktop) mca_msg "launcher" ;;
|
desktop) mca_msg "launcher" ;;
|
||||||
steam) mca_msg "Steam" ;;
|
steam) mca_msg "Steam" ;;
|
||||||
spotify) printf 'spotify-launcher' ;;
|
spotify) printf 'spotify-launcher' ;;
|
||||||
|
gecko) mca_msg "profile" ;;
|
||||||
unknown) mca_msg "cannot tell" ;;
|
unknown) mca_msg "cannot tell" ;;
|
||||||
*) mca_msg "off" ;;
|
*) mca_msg "off" ;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
+3
-1
@@ -283,11 +283,13 @@ mca_state_write() {
|
|||||||
# inplace <edited file> <basename of its backup copy>
|
# inplace <edited file> <basename of its backup copy>
|
||||||
# flags <flag file> created | appended | merged
|
# flags <flag file> created | appended | merged
|
||||||
# kwin <kwinrc> what EnablePrimarySelection said before
|
# kwin <kwinrc> what EnablePrimarySelection said before
|
||||||
|
# gecko <user.js in a profile> created | block
|
||||||
#
|
#
|
||||||
# The kinds differ in how they are undone: a backup is restored wholesale, a
|
# 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
|
# 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.
|
# copy of it back would take everything else settled since with it. A user.js
|
||||||
|
# loses its block, and prefs.js the line Firefox copied out of it.
|
||||||
|
|
||||||
mca_ledger_add() {
|
mca_ledger_add() {
|
||||||
local kind="$1" path="$2" detail="${3:-}"
|
local kind="$1" path="$2" detail="${3:-}"
|
||||||
|
|||||||
+53
-8
@@ -343,7 +343,9 @@ _mca_stat_batch() {
|
|||||||
# taught the hint scan about Discord's launcher, and Discord stayed out of the
|
# taught the hint scan about Discord's launcher, and Discord stayed out of the
|
||||||
# list anyway, because /usr/bin/discord had not changed and its old "no" was
|
# list anyway, because /usr/bin/discord had not changed and its old "no" was
|
||||||
# still in here.
|
# still in here.
|
||||||
MCA_CACHE_FORMAT="# middleclick-autoscroll detect 2 $MCA_VERSION"
|
#
|
||||||
|
# 3 adds the gecko verdict.
|
||||||
|
MCA_CACHE_FORMAT="# middleclick-autoscroll detect 3 $MCA_VERSION"
|
||||||
|
|
||||||
_mca_cache_load() {
|
_mca_cache_load() {
|
||||||
local path stamp verdict first=1
|
local path stamp verdict first=1
|
||||||
@@ -862,6 +864,8 @@ _mca_appimage_verdict() {
|
|||||||
# no - something else
|
# no - something else
|
||||||
# unknown - an image whose payload could not be read, so neither answer has
|
# unknown - an image whose payload could not be read, so neither answer has
|
||||||
# been earned and the applications screen offers it as a choice
|
# been earned and the applications screen offers it as a choice
|
||||||
|
# gecko:<rel> - Firefox or another Gecko application, which keeps its
|
||||||
|
# profiles in <rel>. See gecko.sh.
|
||||||
#
|
#
|
||||||
# Assigns rather than returns three states through an exit code, and is the one
|
# Assigns rather than returns three states through an exit code, and is the one
|
||||||
# place the memo and the on-disk cache are consulted.
|
# place the memo and the on-disk cache are consulted.
|
||||||
@@ -900,8 +904,11 @@ mca_detect_verdict() {
|
|||||||
real="$(readlink -f -- "$prog" 2>/dev/null)" || real="$prog"
|
real="$(readlink -f -- "$prog" 2>/dev/null)" || real="$prog"
|
||||||
|
|
||||||
MCA_DETECT_UNSURE=0
|
MCA_DETECT_UNSURE=0
|
||||||
|
MCA_DETECT_GECKO=''
|
||||||
if _mca_detect_uncached "$real"; then
|
if _mca_detect_uncached "$real"; then
|
||||||
MCA_VERDICT=yes
|
MCA_VERDICT=yes
|
||||||
|
elif [[ -n $MCA_DETECT_GECKO ]]; then
|
||||||
|
MCA_VERDICT="gecko:$MCA_DETECT_GECKO"
|
||||||
elif (( MCA_DETECT_UNSURE )); then
|
elif (( MCA_DETECT_UNSURE )); then
|
||||||
MCA_VERDICT=unknown
|
MCA_VERDICT=unknown
|
||||||
else
|
else
|
||||||
@@ -930,6 +937,10 @@ mca_is_chromium() {
|
|||||||
# was nothing there. Only mca_detect_verdict reads it, straight after the call.
|
# was nothing there. Only mca_detect_verdict reads it, straight after the call.
|
||||||
MCA_DETECT_UNSURE=0
|
MCA_DETECT_UNSURE=0
|
||||||
|
|
||||||
|
# Set by _mca_detect_uncached to where the profiles are, when the program turned
|
||||||
|
# out to be Gecko rather than Chromium.
|
||||||
|
MCA_DETECT_GECKO=''
|
||||||
|
|
||||||
_mca_detect_uncached() {
|
_mca_detect_uncached() {
|
||||||
local real="$1" depth="${2:-0}" dir target
|
local real="$1" depth="${2:-0}" dir target
|
||||||
|
|
||||||
@@ -943,6 +954,7 @@ _mca_detect_uncached() {
|
|||||||
if target="$(_mca_script_target "$real")" && [[ -n $target ]]; then
|
if target="$(_mca_script_target "$real")" && [[ -n $target ]]; then
|
||||||
_mca_detect_uncached "$(readlink -f -- "$target" 2>/dev/null || printf '%s' "$target")" \
|
_mca_detect_uncached "$(readlink -f -- "$target" 2>/dev/null || printf '%s' "$target")" \
|
||||||
$(( depth + 1 )) && return 0
|
$(( depth + 1 )) && return 0
|
||||||
|
[[ -n $MCA_DETECT_GECKO ]] && return 1
|
||||||
fi
|
fi
|
||||||
grep -qE "$MCA_SCRIPT_HINTS" -- "$real" 2>/dev/null && return 0
|
grep -qE "$MCA_SCRIPT_HINTS" -- "$real" 2>/dev/null && return 0
|
||||||
return 1
|
return 1
|
||||||
@@ -954,6 +966,14 @@ _mca_detect_uncached() {
|
|||||||
_mca_has_markers "$dir" && return 0
|
_mca_has_markers "$dir" && return 0
|
||||||
[[ ${dir##*/} == bin ]] && _mca_has_markers "${dir%/*}" && return 0
|
[[ ${dir##*/} == bin ]] && _mca_has_markers "${dir%/*}" && return 0
|
||||||
|
|
||||||
|
# Not Chromium but Gecko, which has autoscroll of its own.
|
||||||
|
if _mca_gecko_rel "$dir" \
|
||||||
|
|| { [[ ${dir##*/} == bin ]] && _mca_gecko_rel "${dir%/*}"; }
|
||||||
|
then
|
||||||
|
MCA_DETECT_GECKO="$MCA_GECKO_REL"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
# An AppImage keeps all of that inside a filesystem appended to itself, so
|
# 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.
|
# in there can be read, and that settles it either way.
|
||||||
@@ -989,8 +1009,9 @@ MCA_IDS=() # desktop file id, without the .desktop suffix
|
|||||||
MCA_FILES=() # the desktop entry that is in effect for that id
|
MCA_FILES=() # the desktop entry that is in effect for that id
|
||||||
MCA_NAMES=() # display name
|
MCA_NAMES=() # display name
|
||||||
MCA_PROGS=() # resolved program, or a Flatpak app id or a snap name
|
MCA_PROGS=() # resolved program, or a Flatpak app id or a snap name
|
||||||
MCA_KINDS=() # app | browser | steam | spotify | unknown | no
|
MCA_KINDS=() # app | browser | steam | spotify | gecko | unknown | no
|
||||||
MCA_PACKAGING=() # native | flatpak | snap
|
MCA_PACKAGING=() # native | flatpak | snap
|
||||||
|
MCA_PROFILES=() # where a Gecko application keeps its profiles, see gecko.sh
|
||||||
|
|
||||||
# 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
|
||||||
@@ -1003,12 +1024,12 @@ mca_scan_once() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mca_scan() {
|
mca_scan() {
|
||||||
local dir file id name exec_line prog kind packaging i
|
local dir file id name exec_line prog kind packaging profiles i
|
||||||
local -A seen=()
|
local -A seen=()
|
||||||
local -a c_ids=() c_files=() c_names=() c_progs=() c_browser=() c_stat=()
|
local -a c_ids=() c_files=() c_names=() c_progs=() c_browser=() c_stat=()
|
||||||
|
|
||||||
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_PROFILES=()
|
||||||
|
|
||||||
# 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
|
||||||
@@ -1073,6 +1094,7 @@ mca_scan() {
|
|||||||
prog="${c_progs[i]}"
|
prog="${c_progs[i]}"
|
||||||
kind=no
|
kind=no
|
||||||
packaging=native
|
packaging=native
|
||||||
|
profiles=''
|
||||||
|
|
||||||
if [[ $prog == flatpak:* ]]; then
|
if [[ $prog == flatpak:* ]]; then
|
||||||
packaging=flatpak
|
packaging=flatpak
|
||||||
@@ -1080,6 +1102,8 @@ mca_scan() {
|
|||||||
kind=steam
|
kind=steam
|
||||||
elif mca_flatpak_is_chromium "${prog#flatpak:}"; then
|
elif mca_flatpak_is_chromium "${prog#flatpak:}"; then
|
||||||
(( c_browser[i] )) && kind=browser || kind=app
|
(( c_browser[i] )) && kind=browser || kind=app
|
||||||
|
elif mca_flatpak_gecko "${prog#flatpak:}"; then
|
||||||
|
kind=gecko profiles="$MCA_GECKO_REL"
|
||||||
fi
|
fi
|
||||||
prog="${prog#flatpak:}"
|
prog="${prog#flatpak:}"
|
||||||
elif [[ $prog == snap:* ]]; then
|
elif [[ $prog == snap:* ]]; then
|
||||||
@@ -1089,6 +1113,8 @@ mca_scan() {
|
|||||||
kind=steam
|
kind=steam
|
||||||
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
|
||||||
|
elif mca_snap_gecko "$prog"; then
|
||||||
|
kind=gecko profiles="$MCA_GECKO_REL"
|
||||||
fi
|
fi
|
||||||
elif mca_prog_is_steam "$prog"; 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
|
||||||
@@ -1103,6 +1129,7 @@ mca_scan() {
|
|||||||
case "$MCA_VERDICT" in
|
case "$MCA_VERDICT" in
|
||||||
yes) (( c_browser[i] )) && kind=browser || kind=app ;;
|
yes) (( c_browser[i] )) && kind=browser || kind=app ;;
|
||||||
unknown) kind=unknown ;;
|
unknown) kind=unknown ;;
|
||||||
|
gecko:*) kind=gecko profiles="${MCA_VERDICT#gecko:}" ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -1114,6 +1141,7 @@ mca_scan() {
|
|||||||
MCA_PROGS+=("$prog")
|
MCA_PROGS+=("$prog")
|
||||||
MCA_KINDS+=("$kind")
|
MCA_KINDS+=("$kind")
|
||||||
MCA_PACKAGING+=("$packaging")
|
MCA_PACKAGING+=("$packaging")
|
||||||
|
MCA_PROFILES+=("$profiles")
|
||||||
done
|
done
|
||||||
|
|
||||||
mca_cache_flush
|
mca_cache_flush
|
||||||
@@ -1211,16 +1239,14 @@ mca_snap_is_chromium() {
|
|||||||
# Flatpak keeps every application in its own tree, so the marker check works the
|
# Flatpak keeps every application in its own tree, so the marker check works the
|
||||||
# same way once that tree has been located.
|
# same way once that tree has been located.
|
||||||
mca_flatpak_is_chromium() {
|
mca_flatpak_is_chromium() {
|
||||||
local id="$1" loc
|
local id="$1"
|
||||||
mca_have flatpak || return 1
|
|
||||||
|
|
||||||
if [[ -n ${MCA_DETECT_MEMO[flatpak:$id]+set} ]]; then
|
if [[ -n ${MCA_DETECT_MEMO[flatpak:$id]+set} ]]; then
|
||||||
[[ ${MCA_DETECT_MEMO[flatpak:$id]} == yes ]]
|
[[ ${MCA_DETECT_MEMO[flatpak:$id]} == yes ]]
|
||||||
return $?
|
return $?
|
||||||
fi
|
fi
|
||||||
|
|
||||||
loc="$(flatpak info --show-location "$id" 2>/dev/null)"
|
if mca_flatpak_location "$id" && _mca_find_markers "$MCA_FLATPAK_AT/files" 4; then
|
||||||
if [[ -n $loc ]] && _mca_find_markers "$loc/files" 4; then
|
|
||||||
MCA_DETECT_MEMO[flatpak:$id]=yes
|
MCA_DETECT_MEMO[flatpak:$id]=yes
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@@ -1229,6 +1255,25 @@ mca_flatpak_is_chromium() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# mca_flatpak_location <app id>
|
||||||
|
# Where Flatpak keeps the application, in MCA_FLATPAK_AT. Assigned rather than
|
||||||
|
# printed so the memo survives: both the Chromium and the Gecko check ask.
|
||||||
|
declare -A MCA_FLATPAK_LOC=()
|
||||||
|
MCA_FLATPAK_AT=''
|
||||||
|
|
||||||
|
mca_flatpak_location() {
|
||||||
|
local id="$1"
|
||||||
|
|
||||||
|
if [[ -z ${MCA_FLATPAK_LOC[$id]+set} ]]; then
|
||||||
|
MCA_FLATPAK_LOC[$id]=''
|
||||||
|
mca_have flatpak \
|
||||||
|
&& MCA_FLATPAK_LOC[$id]="$(flatpak info --show-location "$id" 2>/dev/null)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
MCA_FLATPAK_AT="${MCA_FLATPAK_LOC[$id]}"
|
||||||
|
[[ -n $MCA_FLATPAK_AT ]]
|
||||||
|
}
|
||||||
|
|
||||||
# mca_kind_wanted <kind> <id>
|
# mca_kind_wanted <kind> <id>
|
||||||
# Whether this entry should be patched. Skip beats everything, an explicit
|
# Whether this entry should be patched. Skip beats everything, an explicit
|
||||||
# include beats detection, and detection beats nothing.
|
# include beats detection, and detection beats nothing.
|
||||||
|
|||||||
@@ -0,0 +1,254 @@
|
|||||||
|
# shellcheck shell=bash
|
||||||
|
#
|
||||||
|
# Firefox, and everything else built on Gecko: LibreWolf, Zen, Floorp,
|
||||||
|
# Waterfox, Thunderbird.
|
||||||
|
#
|
||||||
|
# Gecko has autoscroll of its own, off on Linux. There is no command line flag
|
||||||
|
# for it, only a setting: general.autoScroll. Settings live in each profile, so
|
||||||
|
# the line goes into the profile's user.js, which Gecko reads at every start.
|
||||||
|
#
|
||||||
|
# Gecko copies what user.js sets into prefs.js. So undoing takes the line out
|
||||||
|
# of prefs.js as well. A browser that is still open would write it back when it
|
||||||
|
# quits, so for that profile user.js says false instead, and the record stays
|
||||||
|
# until the next undo can finish the job.
|
||||||
|
|
||||||
|
MCA_GECKO_BEGIN='// >>> middleclick-autoscroll'
|
||||||
|
MCA_GECKO_END='// <<< middleclick-autoscroll'
|
||||||
|
MCA_GECKO_ON='user_pref("general.autoScroll", true);'
|
||||||
|
MCA_GECKO_OFF='user_pref("general.autoScroll", false);'
|
||||||
|
|
||||||
|
# The profile folders one apply has done already, and the profiles.ini files
|
||||||
|
# the watcher should look at. Both are filled by mca_gecko_apply.
|
||||||
|
declare -A MCA_GECKO_SEEN=()
|
||||||
|
MCA_GECKO_WATCH=()
|
||||||
|
|
||||||
|
# Set by mca_gecko_revert when a profile is still open and has to be undone
|
||||||
|
# again later.
|
||||||
|
MCA_GECKO_PENDING=0
|
||||||
|
|
||||||
|
# _mca_gecko_rel <directory>
|
||||||
|
# Whether a Gecko application is installed there. If so, where it keeps its
|
||||||
|
# profiles, relative to the home or config folder, in MCA_GECKO_REL. Read from
|
||||||
|
# application.ini the way Gecko does it: [App] Profile= when it is set, else
|
||||||
|
# Vendor/Name, in lowercase.
|
||||||
|
MCA_GECKO_REL=''
|
||||||
|
|
||||||
|
_mca_gecko_rel() {
|
||||||
|
local dir="$1" line group='' vendor='' name='' profile='' rel=''
|
||||||
|
|
||||||
|
MCA_GECKO_REL=''
|
||||||
|
[[ -e $dir/libxul.so && -r $dir/application.ini ]] || return 1
|
||||||
|
|
||||||
|
while IFS= read -r line || [[ -n $line ]]; do
|
||||||
|
line="${line%$'\r'}"
|
||||||
|
case "$line" in
|
||||||
|
'['*) group="$line" ;;
|
||||||
|
Vendor=*) [[ $group == '[App]' ]] && vendor="${line#*=}" ;;
|
||||||
|
Name=*) [[ $group == '[App]' ]] && name="${line#*=}" ;;
|
||||||
|
Profile=*) [[ $group == '[App]' ]] && profile="${line#*=}" ;;
|
||||||
|
esac
|
||||||
|
done < "$dir/application.ini"
|
||||||
|
|
||||||
|
if [[ -n $profile ]]; then
|
||||||
|
rel="${profile//\\//}"
|
||||||
|
while [[ $rel == /* ]]; do rel="${rel#/}"; done
|
||||||
|
rel="${rel#.}"
|
||||||
|
elif [[ -n $name ]]; then
|
||||||
|
rel="${vendor:+$vendor/}$name"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Gecko lowercases in ASCII. A Turkish locale turns I into a dotless ı.
|
||||||
|
rel="${rel,,}"
|
||||||
|
rel="${rel//ı/i}"
|
||||||
|
|
||||||
|
[[ -n $rel && /$rel/ != */../* ]] || return 1
|
||||||
|
MCA_GECKO_REL="$rel"
|
||||||
|
}
|
||||||
|
|
||||||
|
# _mca_gecko_tree <root> <depth>
|
||||||
|
# The same for a Flatpak or a snap, where libxul.so is somewhere in the tree.
|
||||||
|
_mca_gecko_tree() {
|
||||||
|
local lib
|
||||||
|
|
||||||
|
MCA_GECKO_REL=''
|
||||||
|
[[ -d $1 ]] || return 1
|
||||||
|
lib="$(find "$1" -maxdepth "$2" -name libxul.so -print -quit 2>/dev/null)"
|
||||||
|
[[ -n $lib ]] && _mca_gecko_rel "${lib%/*}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# mca_flatpak_gecko <app id> / mca_snap_gecko <snap name>
|
||||||
|
# Whether it is Gecko, with the folder in MCA_GECKO_REL. Memoized like the
|
||||||
|
# Chromium check, and an empty answer means no.
|
||||||
|
declare -A MCA_GECKO_MEMO=()
|
||||||
|
|
||||||
|
mca_flatpak_gecko() {
|
||||||
|
local key="flatpak:$1"
|
||||||
|
|
||||||
|
if [[ -z ${MCA_GECKO_MEMO[$key]+set} ]]; then
|
||||||
|
MCA_GECKO_REL=''
|
||||||
|
mca_flatpak_location "$1" && _mca_gecko_tree "$MCA_FLATPAK_AT/files" 4
|
||||||
|
MCA_GECKO_MEMO[$key]="$MCA_GECKO_REL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
MCA_GECKO_REL="${MCA_GECKO_MEMO[$key]}"
|
||||||
|
[[ -n $MCA_GECKO_REL ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
mca_snap_gecko() {
|
||||||
|
local key="snap:$1" d
|
||||||
|
|
||||||
|
if [[ -z ${MCA_GECKO_MEMO[$key]+set} ]]; then
|
||||||
|
MCA_GECKO_REL=''
|
||||||
|
for d in "${MCA_SNAP_DIRS[@]}"; do
|
||||||
|
_mca_gecko_tree "$d/$1/current" 5 && break
|
||||||
|
done
|
||||||
|
MCA_GECKO_MEMO[$key]="$MCA_GECKO_REL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
MCA_GECKO_REL="${MCA_GECKO_MEMO[$key]}"
|
||||||
|
[[ -n $MCA_GECKO_REL ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
# mca_gecko_roots <rel> <packaging> <name>
|
||||||
|
# Every folder that can hold the application's profiles.ini. An older install
|
||||||
|
# uses ~/.<rel>. A new one (Firefox 147 and later) uses $XDG_CONFIG_HOME/<rel>,
|
||||||
|
# or ~/<rel> for a fork with a profile name of its own. A Flatpak or a snap has
|
||||||
|
# the same inside its own folder.
|
||||||
|
mca_gecko_roots() {
|
||||||
|
local rel="$1" packaging="$2" name="$3" d
|
||||||
|
|
||||||
|
case "$packaging" in
|
||||||
|
flatpak)
|
||||||
|
printf '%s\n' "$HOME/.var/app/$name/.$rel" "$HOME/.var/app/$name/config/$rel"
|
||||||
|
;;
|
||||||
|
snap)
|
||||||
|
for d in common current; do
|
||||||
|
printf '%s\n' "$HOME/snap/$name/$d/.$rel" "$HOME/snap/$name/$d/.config/$rel"
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
printf '%s\n' "$HOME/.$rel" "$MCA_XDG_CONFIG/$rel"
|
||||||
|
[[ $rel == */* ]] || printf '%s\n' "$HOME/$rel"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# mca_gecko_profiles <root>
|
||||||
|
# Every profile folder that profiles.ini there lists.
|
||||||
|
mca_gecko_profiles() {
|
||||||
|
local root="$1" line path='' relative=1 inprofile=0
|
||||||
|
|
||||||
|
[[ -r $root/profiles.ini ]] || return 0
|
||||||
|
|
||||||
|
while IFS= read -r line || [[ -n $line ]]; do
|
||||||
|
line="${line%$'\r'}"
|
||||||
|
case "$line" in
|
||||||
|
'['*)
|
||||||
|
_mca_gecko_profile_emit
|
||||||
|
[[ $line == '[Profile'* ]] && inprofile=1 || inprofile=0
|
||||||
|
path='' relative=1
|
||||||
|
;;
|
||||||
|
Path=*) path="${line#Path=}" ;;
|
||||||
|
IsRelative=*) relative="${line#IsRelative=}" ;;
|
||||||
|
esac
|
||||||
|
done < "$root/profiles.ini"
|
||||||
|
_mca_gecko_profile_emit
|
||||||
|
}
|
||||||
|
|
||||||
|
_mca_gecko_profile_emit() {
|
||||||
|
(( inprofile )) && [[ -n $path ]] || return 0
|
||||||
|
[[ $relative == 1 ]] && path="$root/$path"
|
||||||
|
[[ -d $path ]] && printf '%s\n' "$path"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# _mca_gecko_write <user.js> <line>
|
||||||
|
# Puts the line into user.js as a marked block, replacing an older block.
|
||||||
|
# Returns like mca_write_if_changed.
|
||||||
|
_mca_gecko_write() {
|
||||||
|
local file="$1" line="$2" content=''
|
||||||
|
|
||||||
|
[[ -f $file ]] && content="$(_mca_flags_drop_block "$file" "$MCA_GECKO_BEGIN" "$MCA_GECKO_END")"
|
||||||
|
content="${content:+$content$'\n'}$MCA_GECKO_BEGIN"$'\n'"$line"$'\n'"$MCA_GECKO_END"
|
||||||
|
mca_write_if_changed "$file" "$content"$'\n'
|
||||||
|
}
|
||||||
|
|
||||||
|
# mca_gecko_apply <rel> <packaging> <name>
|
||||||
|
# Turns autoscroll on in every profile of the application.
|
||||||
|
mca_gecko_apply() {
|
||||||
|
local root profile
|
||||||
|
|
||||||
|
while IFS= read -r root; do
|
||||||
|
[[ -n ${MCA_GECKO_SEEN[$root]+set} ]] && continue
|
||||||
|
MCA_GECKO_SEEN[$root]=1
|
||||||
|
|
||||||
|
# A new profile is written into profiles.ini, so the watcher can pick
|
||||||
|
# it up.
|
||||||
|
MCA_GECKO_WATCH+=("$root/profiles.ini")
|
||||||
|
|
||||||
|
while IFS= read -r profile; do
|
||||||
|
_mca_gecko_profile_apply "$profile"
|
||||||
|
done < <(mca_gecko_profiles "$root")
|
||||||
|
done < <(mca_gecko_roots "$@")
|
||||||
|
}
|
||||||
|
|
||||||
|
_mca_gecko_profile_apply() {
|
||||||
|
local dir="$1" file="$1/user.js" detail=created
|
||||||
|
|
||||||
|
# A user.js that links somewhere else is part of a setup of its own.
|
||||||
|
[[ -L $file ]] && return 0
|
||||||
|
[[ -f $file ]] && detail=block
|
||||||
|
|
||||||
|
if ! grep -qxF -- "$MCA_GECKO_BEGIN" "$file" 2>/dev/null; then
|
||||||
|
# Set by the user already, in user.js or in the browser's own
|
||||||
|
# settings. Their choice: nothing is written and nothing recorded.
|
||||||
|
grep -qE '^[[:space:]]*user_pref\([[:space:]]*"general\.autoScroll"' \
|
||||||
|
-- "$file" 2>/dev/null && return 0
|
||||||
|
grep -qxF -- "$MCA_GECKO_ON" "$dir/prefs.js" 2>/dev/null && return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
_mca_gecko_write "$file" "$MCA_GECKO_ON"
|
||||||
|
case $? in
|
||||||
|
0) MCA_CHANGES=$(( MCA_CHANGES + 1 )) ;;
|
||||||
|
2) return 0 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# A file this program created stays one it created.
|
||||||
|
mca_ledger_has "$file" && detail="$(mca_ledger_detail "$file")"
|
||||||
|
mca_ledger_add gecko "$file" "$detail"
|
||||||
|
}
|
||||||
|
|
||||||
|
# mca_gecko_revert <user.js> <created|block>
|
||||||
|
# Returns 0 when something changed. Sets MCA_GECKO_PENDING when the profile is
|
||||||
|
# open and the record has to stay.
|
||||||
|
mca_gecko_revert() {
|
||||||
|
local file="$1" detail="$2" dir="${1%/*}" prefs content tmp rc=0
|
||||||
|
|
||||||
|
MCA_GECKO_PENDING=0
|
||||||
|
[[ -f $file && ! -L $file ]] || return 1
|
||||||
|
grep -qxF -- "$MCA_GECKO_BEGIN" "$file" 2>/dev/null || return 1
|
||||||
|
|
||||||
|
# The lock link only exists while the profile is open.
|
||||||
|
if [[ -L $dir/lock ]]; then
|
||||||
|
MCA_GECKO_PENDING=1
|
||||||
|
_mca_gecko_write "$file" "$MCA_GECKO_OFF"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
content="$(_mca_flags_drop_block "$file" "$MCA_GECKO_BEGIN" "$MCA_GECKO_END")"
|
||||||
|
if [[ $detail == created && -z ${content//[[:space:]]/} ]]; then
|
||||||
|
rm -f -- "$file"
|
||||||
|
else
|
||||||
|
printf '%s\n' "$content" > "$file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
prefs="$dir/prefs.js"
|
||||||
|
if [[ -f $prefs && ! -L $prefs ]] && grep -qxF -- "$MCA_GECKO_ON" "$prefs"; then
|
||||||
|
tmp="$(mktemp "$prefs.XXXXXX")" || return 0
|
||||||
|
chmod --reference="$prefs" -- "$tmp" 2>/dev/null || chmod 600 -- "$tmp"
|
||||||
|
# grep says 1 when no line is left, which is fine here.
|
||||||
|
grep -vxF -- "$MCA_GECKO_ON" "$prefs" > "$tmp" || rc=$?
|
||||||
|
if (( rc <= 1 )); then mv -f -- "$tmp" "$prefs"; else rm -f -- "$tmp"; fi
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
+5
-2
@@ -419,13 +419,14 @@ mca_ui_apps() {
|
|||||||
# The per-row labels are resolved once, here. Looking them up inside the
|
# The per-row labels are resolved once, here. Looking them up inside the
|
||||||
# drawing loop is a fork per row per keypress, and that is enough to make
|
# drawing loop is a fork per row per keypress, and that is enough to make
|
||||||
# the arrow keys feel like the screen is reloading.
|
# the arrow keys feel like the screen is reloading.
|
||||||
local l_off l_cannot l_on l_steam l_flagfile l_launcher
|
local l_off l_cannot l_on l_steam l_flagfile l_launcher l_profile
|
||||||
mca_msg_into "$locale" "off"; l_off="$MCA_MSG_RESULT"
|
mca_msg_into "$locale" "off"; l_off="$MCA_MSG_RESULT"
|
||||||
mca_msg_into "$locale" "cannot tell"; l_cannot="$MCA_MSG_RESULT"
|
mca_msg_into "$locale" "cannot tell"; l_cannot="$MCA_MSG_RESULT"
|
||||||
mca_msg_into "$locale" "on"; l_on="$MCA_MSG_RESULT"
|
mca_msg_into "$locale" "on"; l_on="$MCA_MSG_RESULT"
|
||||||
mca_msg_into "$locale" "Steam"; l_steam="$MCA_MSG_RESULT"
|
mca_msg_into "$locale" "Steam"; l_steam="$MCA_MSG_RESULT"
|
||||||
mca_msg_into "$locale" "flag file"; l_flagfile="$MCA_MSG_RESULT"
|
mca_msg_into "$locale" "flag file"; l_flagfile="$MCA_MSG_RESULT"
|
||||||
mca_msg_into "$locale" "launcher"; l_launcher="$MCA_MSG_RESULT"
|
mca_msg_into "$locale" "launcher"; l_launcher="$MCA_MSG_RESULT"
|
||||||
|
mca_msg_into "$locale" "profile"; l_profile="$MCA_MSG_RESULT"
|
||||||
|
|
||||||
local s_off="${MCA_C_DIM}${l_off}${MCA_C_RESET}"
|
local s_off="${MCA_C_DIM}${l_off}${MCA_C_RESET}"
|
||||||
local s_cannot="${MCA_C_DIM}${l_cannot}${MCA_C_RESET}"
|
local s_cannot="${MCA_C_DIM}${l_cannot}${MCA_C_RESET}"
|
||||||
@@ -434,6 +435,7 @@ mca_ui_apps() {
|
|||||||
local s_flags="${s_on} ${MCA_C_DIM}(${l_flagfile})${MCA_C_RESET}"
|
local s_flags="${s_on} ${MCA_C_DIM}(${l_flagfile})${MCA_C_RESET}"
|
||||||
local s_desktop="${s_on} ${MCA_C_DIM}(${l_launcher})${MCA_C_RESET}"
|
local s_desktop="${s_on} ${MCA_C_DIM}(${l_launcher})${MCA_C_RESET}"
|
||||||
local s_spotify="${s_on} ${MCA_C_DIM}(spotify-launcher)${MCA_C_RESET}"
|
local s_spotify="${s_on} ${MCA_C_DIM}(spotify-launcher)${MCA_C_RESET}"
|
||||||
|
local s_gecko="${s_on} ${MCA_C_DIM}(${l_profile})${MCA_C_RESET}"
|
||||||
|
|
||||||
local clearseq
|
local clearseq
|
||||||
clearseq="$(clear 2>/dev/null)" || clearseq=$'\033[H\033[2J'
|
clearseq="$(clear 2>/dev/null)" || clearseq=$'\033[H\033[2J'
|
||||||
@@ -444,7 +446,7 @@ mca_ui_apps() {
|
|||||||
count=${#MCA_IDS[@]}
|
count=${#MCA_IDS[@]}
|
||||||
|
|
||||||
if (( count == 0 )); then
|
if (( count == 0 )); then
|
||||||
MCA_UI_MSG="$(mca_msg "No Chromium-based applications found.")"
|
MCA_UI_MSG="$(mca_msg "No supported applications found.")"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -526,6 +528,7 @@ mca_ui_apps() {
|
|||||||
steam) shown="$s_steam" ;;
|
steam) shown="$s_steam" ;;
|
||||||
flags) shown="$s_flags" ;;
|
flags) shown="$s_flags" ;;
|
||||||
spotify) shown="$s_spotify" ;;
|
spotify) shown="$s_spotify" ;;
|
||||||
|
gecko) shown="$s_gecko" ;;
|
||||||
*) shown="$s_desktop" ;;
|
*) shown="$s_desktop" ;;
|
||||||
esac
|
esac
|
||||||
pad=$(( 34 - ${#labels[idx]} ))
|
pad=$(( 34 - ${#labels[idx]} ))
|
||||||
|
|||||||
+10
-1
@@ -260,8 +260,9 @@ _mca_flags_write() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# _mca_flags_drop_block <file> [begin marker] [end marker]
|
||||||
_mca_flags_drop_block() {
|
_mca_flags_drop_block() {
|
||||||
awk -v b="$MCA_MARK_BEGIN" -v e="$MCA_MARK_END" '
|
awk -v b="${2:-$MCA_MARK_BEGIN}" -v e="${3:-$MCA_MARK_END}" '
|
||||||
$0 == b { skip = 1; next }
|
$0 == b { skip = 1; next }
|
||||||
$0 == e { skip = 0; next }
|
$0 == e { skip = 0; next }
|
||||||
!skip
|
!skip
|
||||||
@@ -632,6 +633,7 @@ mca_prune_orphans() {
|
|||||||
|
|
||||||
mca_revert_all() {
|
mca_revert_all() {
|
||||||
local kind path detail backup
|
local kind path detail backup
|
||||||
|
local -a keep=()
|
||||||
|
|
||||||
[[ -f $MCA_LEDGER ]] || return 0
|
[[ -f $MCA_LEDGER ]] || return 0
|
||||||
|
|
||||||
@@ -674,10 +676,17 @@ mca_revert_all() {
|
|||||||
mca_kde_paste_revert "$path" "$detail" \
|
mca_kde_paste_revert "$path" "$detail" \
|
||||||
&& MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
&& MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
||||||
;;
|
;;
|
||||||
|
gecko)
|
||||||
|
mca_gecko_revert "$path" "$detail" \
|
||||||
|
&& MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
||||||
|
# Still open, so not done yet. See gecko.sh.
|
||||||
|
(( MCA_GECKO_PENDING )) && keep+=("$kind"$'\t'"$path"$'\t'"$detail")
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
done < <(tac "$MCA_LEDGER" 2>/dev/null)
|
done < <(tac "$MCA_LEDGER" 2>/dev/null)
|
||||||
|
|
||||||
rm -f -- "$MCA_LEDGER"
|
rm -f -- "$MCA_LEDGER"
|
||||||
|
(( ${#keep[@]} )) && printf '%s\n' "${keep[@]}" > "$MCA_LEDGER"
|
||||||
rmdir "$MCA_BACKUPDIR" 2>/dev/null || true
|
rmdir "$MCA_BACKUPDIR" 2>/dev/null || true
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
#
|
#
|
||||||
# middleclick-autoscroll: middle-click autoscroll for Chromium-based
|
# middleclick-autoscroll: middle-click autoscroll for Chromium-based
|
||||||
# applications on Linux
|
# applications and Firefox on Linux
|
||||||
#
|
#
|
||||||
# Blink has had Windows-style autoscroll for years, behind a runtime flag that
|
# 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
|
# 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
|
# 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
|
# somewhere it survives an update, and doing the same for the two programs that
|
||||||
# do not take arguments at all.
|
# do not take arguments at all. Firefox has the same feature behind a setting.
|
||||||
#
|
#
|
||||||
# Copyright (C) 2026 Felitendo
|
# Copyright (C) 2026 Felitendo
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
@@ -17,7 +17,7 @@ set -uo pipefail
|
|||||||
|
|
||||||
MCA_LIBDIR="${MCA_LIBDIR:-@LIBDIR@}"
|
MCA_LIBDIR="${MCA_LIBDIR:-@LIBDIR@}"
|
||||||
|
|
||||||
for _mod in common config detect patch steam kde apply menu; do
|
for _mod in common config detect patch steam gecko kde apply menu; do
|
||||||
# shellcheck source=/dev/null
|
# shellcheck source=/dev/null
|
||||||
if ! source "$MCA_LIBDIR/$_mod.sh"; then
|
if ! source "$MCA_LIBDIR/$_mod.sh"; then
|
||||||
printf 'middleclick-autoscroll: cannot load %s/%s.sh\n' "$MCA_LIBDIR" "$_mod" >&2
|
printf 'middleclick-autoscroll: cannot load %s/%s.sh\n' "$MCA_LIBDIR" "$_mod" >&2
|
||||||
@@ -144,7 +144,7 @@ mca_do_list() {
|
|||||||
mca_count_routes
|
mca_count_routes
|
||||||
|
|
||||||
if (( ${#MCA_IDS[@]} == 0 )); then
|
if (( ${#MCA_IDS[@]} == 0 )); then
|
||||||
mca_note "$(mca_msg "No Chromium-based applications found.")"
|
mca_note "$(mca_msg "No supported applications found.")"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user