middleclick-autoscroll(1) # NAME middleclick-autoscroll - middle-click autoscroll in every application that supports it # SYNOPSIS *middleclick-autoscroll* [_command_] # DESCRIPTION Blink, the engine inside Chromium, Electron and CEF, implements Windows-style autoscroll: hold the middle mouse button and the page scrolls with the pointer. On Linux it is switched off, because middle click is taken by primary-selection paste. It can be turned back on with *--enable-blink-features=MiddleClickAutoscroll* on the command line. *middleclick-autoscroll* finds every Chromium-based application on the system and puts that argument somewhere the application will actually read it, then keeps doing so for anything installed later. A browser is given *--enable-features=MiddleClickAutoscroll* instead. It asks for the same feature - Blink generates a feature of that name for each of its runtime flags - but it is not on the list of flags Chromium warns about, so the browser does not put a bar reading "You are using an unsupported command-line flag" above every page. That spelling only works from Chromium 124 onwards, which is why everything else keeps the first one: an application that embeds an older Chromium, such as Steam's CEF, has no such bar to show anyway. Two browsers know the feature under a name of their own and ignore Chromium's: Helium, which is asked for *HeliumMiddleClickAutoscroll* as well, and Brave, which is asked for *MiddelButtonClickAutoscroll* - spelled the way Brave spells 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 assumed from where the launcher came from. 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 edited by hand. Nothing outside the user's home directory is written to, and running it as root is refused. # COMMANDS *enable* Turn autoscroll on, apply it to everything installed, and start watching for new applications. *disable* Turn it off and put every file that was changed back the way it was. *apply* [*--rebuild*] Apply to anything that has appeared since the last run. This is what the watcher calls; running it by hand is only needed when the watcher is off. Entries left behind by an application that has since been uninstalled are removed here too - the entry shadowing it lives in the user's home, where the package manager that removed the application cannot see it. With *--rebuild* everything is taken back first and written again from scratch. That is the repair: it does not care what looks correct already. *status* How many applications are covered, whether Steam is patched, and when the last run was. *list* Every Chromium-based application that was found, and how each one is handled. *-h*, *--help* Show a summary of the commands. *-V*, *--version* Show the version. # HOW THE ARGUMENT GETS IN Two ways, chosen per application. *Flag file* Where the launcher reads extra arguments from _$XDG_CONFIG_HOME/-flags.conf_. This is the preferred route: it is the supported way to pass arguments, it survives package upgrades, and it applies to a launch from a terminal as much as one from the menu. A feature list that is already in the file is extended rather than duplicated - Chromium keeps only the last occurrence of such an option, so a second one would switch the first one off. Arch's Electron and Chromium packages all wrap their binaries this way, and so do a number of individual vendors' launchers elsewhere. Whether a given launcher does is read off the launcher itself, never assumed from the distribution: only one that really names such a file takes this route. *Desktop entry* For applications that ship their own binary with no wrapper, and for everything inside a Flatpak or a snap, a copy of the desktop entry with the argument appended is written to _~/.local/share/applications_, where it shadows the system one. Entries that already live there - AppImages, web app shortcuts - are edited in place, with the original kept. This is the route everything takes on the distributions whose Chromium wrappers keep their equivalent file under _/etc_, where it is the system's to write and not the user's: Debian, Ubuntu, Fedora and openSUSE among them. A generated entry is marked *X-MCA-Generated* and an entry edited in place *X-MCA-Patched*. The two are never confused: the first is deleted when undoing, the second is restored from its backup. An entry with neither marker belongs to somebody else and is left alone. Programs that start themselves at login write their own entry into _~/.config/autostart_ pointing straight at their binary, bypassing the menu entry entirely. Those are patched in place as well. Shortcuts on the desktop itself are patched in place too. Nothing in the XDG search path looks at that folder, so a shortcut that lives only there would otherwise be invisible - and Steam puts one there for every game somebody asks for a shortcut to. The folder's name is translated, and the name in use is read from _~/.config/user-dirs.dirs_ rather than guessed; the watcher is told about it in a drop-in written when autoscroll is turned on. # STEAM Steam's interface is CEF and supports the feature, but Steam builds the command line for its web helper itself. The only way in is the script that starts the helper, inside Steam's own installation: ~/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh Where that installation is depends on how Steam was installed: _~/.local/share/Steam_ for Valve's own package and Arch's, _~/.steam/debian-installation_ for Debian's, and the private tree of the sandbox for the Flatpak and the snap. All of them are looked at. Steam compares the installed files against its manifest at every start - by size and timestamp rather than by content - and restores whatever differs. So the patch is written to look untouched: the bytes the argument costs are taken back out of the script's own comments and the timestamp is put back afterwards, leaving a file exactly as long and exactly as old as Steam left it. A client that checks its files finds nothing to repair, and the argument survives however Steam was started - from the menu, from a game shortcut, from a launcher like Heroic or Lutris, from a terminal. That is what has to work, because it is the only thing that does. A patch that changes the length is never written, whatever else could be done to cover for it: Steam checks its files at the shutdown it runs itself as well as at a start it was given arguments for, and that one carries no arguments of anybody's. One wrong length costs the whole client package downloaded, extracted and installed again, and a client that quits at the end of it instead of coming up. So where the comments cannot pay for the argument, or a client update has changed how the helper is started, nothing is written and the status screen says Steam is not patched. Nothing goes on Steam's launcher entry, its autostart entry or the shortcuts it writes for single games either, and Steam goes on repairing its own installation. An installation patched by an earlier version, which appended where the comments were short, is written again to fit at the next apply, or taken back if it cannot be made to. A client update brings a new version of the script. The watcher notices and patches it again, and the copy kept for undoing is replaced with the new version at the same time, so undoing puts back the script Steam last shipped rather than the one from before the update. # SPOTIFY The official client is CEF rather than Electron. Installed through *spotify-launcher*, it is started by a program that builds its own command line and has a configuration file with a slot for extra arguments; that slot is where the flag goes. Installed as a plain package, a Flatpak or a snap, it is an ordinary desktop entry and needs nothing special. # MIDDLE-CLICK PASTE Inside a Chromium application the argument settles this on its own: with 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, so the desktop's own switch for it is turned off too. KDE has such a switch, and only for a Wayland session, where the paste is a protocol the compositor either offers or does not: ~/.config/kwinrc, [Wayland], EnablePrimarySelection=false It is written with *kwriteconfig6*, the same tool System Settings uses, because kwinrc has a cascade behind it and entries a distribution can mark immutable; an edit that reaches past all that writes something KDE goes on to ignore. KWin reads the key once, while it starts, so the change is true from the next login on rather than straight away. What the key said before is recorded, and *disable* puts that back. A key that already said *false* before any of this is left alone and not recorded either, so a paste the user switched off themselves is never switched back on. On X11 there is nothing to switch. The primary selection is part of X itself and every toolkit reaches for it on its own; no one place can say no. The status screen leaves the row out where there is nothing to report. Turn it off under *Settings* to keep the desktop's middle-click paste. # APPIMAGES An AppImage is the AppImage runtime, an ordinary executable, with a squashfs image appended to it. The payload is compressed, so none of the files that identify Chromium is on disk where it could be found. The names are, though. squashfs keeps the name of everything it holds in one table of its own, a few kilobytes of it, and a name is all this question needs - so that table is read and decompressed in place. Nothing is unpacked, and the image is never run: this can happen from the watcher, and starting a program because it was installed is not something a scan gets to do. Two kinds of image are still out of reach. One is packed with *lzo* or *lz4*, which squashfs stores as bare blocks that neither tool will read without the framing their own file formats add. The other is the original AppImage layout, which is an ISO9660 filesystem rather than a squashfs one. Both are listed as *cannot tell* and left alone until they are switched on from the applications screen. # WHAT HAS NO FLAG AT ALL Autoscroll is a Blink feature, so only an application drawn by Blink can be given it. An application built on WebKitGTK - which is what Tauri uses on Linux, and GNOME Web, and anything else linked against libwebkit2gtk - is not one of those. WebKit has no equivalent feature to ask for, on any command line or in any configuration file. Such an application is identified as what it is and then left out of the list entirely, rather than being offered as something that could be switched on. An application that is absent from *list* is absent because there is nothing this tool could do for it. # FILES _~/.config/middleclick-autoscroll/config_ Written by the program. Every option in it is reachable from the menu. _~/.local/state/middleclick-autoscroll/ledger_ One line per change, so *disable* can undo exactly what was done and nothing else. _~/.local/state/middleclick-autoscroll/backup/_ Copies of the files that are edited in place rather than shadowed. _~/.config/kwinrc_ KDE's own configuration. One key in it, *EnablePrimarySelection*, is written when the desktop's middle-click paste is turned off, and put back by *disable*. _~/.cache/middleclick-autoscroll/detect_ Which programs were found to be Chromium, keyed by size and modification time. Its first line says which version of the program wrote it, and a file from an older one is ignored rather than trusted - an entry for a file that has not changed would otherwise never be looked at again. Safe to delete. # ENVIRONMENT *NO_COLOR* Disables colour. # REQUIREMENTS Bash 4.2 or newer and GNU coreutils. The watcher needs a systemd user session; without one everything else works and applications installed later are picked up at the next *apply* rather than on their own. *gzip* is what reads the name table of an AppImage, and *xz* or *zstd* the ones packed with those instead. None of the three is required: an image whose compressor has no tool installed is listed as *cannot tell*, exactly like the two formats there is no reader for at all. # SEE ALSO *systemctl*(1), *flatpak*(1), *snap*(8), *kwriteconfig6*(1) # AUTHORS Felitendo. Source and issue tracker at https://github.com/LoonixTools/middleclick-autoscroll