▲ 1 r/Ubuntu+1 crossposts

Windows-style autoscroll on Linux Xorg, with icon + cancel by left click / right click / middle click

https://streamable.com/e1b9ll if archive didnt work see the vid here

in the embed screen recorded video is there and the cursor isnt visible there but if u use it the cursor will be visible

I wanted the old Windows-style middle-click autoscroll on Linux, so I put together a small Xorg autoscroll script that behaves the way I like. It uses double middle-click to activate, shows an icon while active, and lets me cancel with single middle click, left click, or right click.

What it does

  • Double middle-click activates autoscroll.
  • Moving the mouse up or down controls scrolling.
  • Single middle-click cancels autoscroll.
  • Left click cancels autoscroll.
  • Right click cancels autoscroll.
  • An icon appears while autoscroll is active.
  • Works system-wide on Xorg.

Steps to install

1. Install dependencies

bashsudo apt update
sudo apt install git python3 python3-venv python3-dev xsel

2. Clone the project

bashgit clone https://github.com/TWolczanski/linux-autoscroll.git
cd linux-autoscroll

3. Create a virtual environment

bashpython3 -m venv .autoscroll
source .autoscroll/bin/activate

4. Install Python packages

bash
pip install wheel pynput PyQt5

If you want the no-icon version, you can skip PyQt5 and use the no-icon script instead.

Main script

Replace autoscroll.py with this version:

python
#!/usr/bin/env python3

from functools import partial
from queue import Queue
from pynput.mouse import Button, Controller, Listener
from threading import Event, Thread
from time import sleep, time
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtSvg import QSvgWidget
from pathlib import Path
import subprocess
import sys


class AutoscrollIconSvg(QSvgWidget):
    scroll_mode_entered = pyqtSignal()
    scroll_mode_exited = pyqtSignal()

    def __init__(self, path, size):
        super().__init__(path)
        self.size = size
        self.renderer().setAspectRatioMode(Qt.KeepAspectRatio)
        self.resize(self.size, self.size)
        self.setWindowFlags(
            Qt.WindowStaysOnTopHint
            | Qt.FramelessWindowHint
            | Qt.X11BypassWindowManagerHint
        )
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.scroll_mode_entered.connect(self.show)
        self.scroll_mode_exited.connect(self.close)

    def set_icon(self, path):
        self.load(path)
        self.update()

    def show(self):
        x = self.pos[0] - self.size // 2
        y = self.pos[1] - self.size // 2
        self.move(x, y)
        super().show()


class Autoscroll:
    def __init__(self):
        self.DELAY = 5
        self.BUTTON_START = Button.middle
        self.DEAD_AREA = 30
        self.TRIGGER_DELAY = 0
        self.CLEAR_CLIPBOARD = False
        self.ICON_SIZE = 30
        self.DOUBLE_CLICK_INTERVAL = 0.4
        self._last_middle_press = 0

        base = Path(__file__).resolve().parent
        self.NEUTRAL_ICON = str(base / "icon_neutral.svg")
        self.UP_ICON = str(base / "icon_up.svg")
        self.DOWN_ICON = str(base / "icon_down.svg")
        self.current_icon_state = "neutral"

        self.icon = AutoscrollIconSvg(self.NEUTRAL_ICON, self.ICON_SIZE)

        self.mouse = Controller()
        self.scroll_mode = Event()
        self.queue = Queue()
        self.cancelled = Event()
        self.listener = Listener(on_move=self.on_move, on_click=self.on_click)
        self.looper = Thread(target=self.loop)
        self.consumer = Thread(target=self.consume)

    def set_icon_state(self, state):
        if state == self.current_icon_state:
            return

        self.current_icon_state = state

        if state == "up":
            self.icon.set_icon(self.UP_ICON)
        elif state == "down":
            self.icon.set_icon(self.DOWN_ICON)
        else:
            self.icon.set_icon(self.NEUTRAL_ICON)

    def on_move(self, x, y):
        if self.scroll_mode.is_set():
            self.queue.put((self.mouse.position[1] - self.icon.pos[1]) // self.DELAY)

    def on_click(self, x, y, button, pressed):
        if not pressed:
            return

        now = time()

        if self.scroll_mode.is_set():
            if button in (Button.left, Button.right, Button.middle):
                self.stop_scroll_mode()
            return

        if button == self.BUTTON_START:
            if now - self._last_middle_press < self.DOUBLE_CLICK_INTERVAL:
                self._last_middle_press = 0
                self.start_scroll_mode(x, y)
            else:
                self._last_middle_press = now

    def start_scroll_mode(self, x, y):
        self.icon.pos = (x, y)
        self.icon.scroll_mode_entered.emit()
        self.set_icon_state("neutral")
        self.scroll_mode.set()

        if self.CLEAR_CLIPBOARD:
            subprocess.run(["xsel", "-bc"], check=False)

    def stop_scroll_mode(self):
        self.scroll_mode.clear()
        self.set_icon_state("neutral")
        self.icon.scroll_mode_exited.emit()

        while not self.queue.empty():
            try:
                self.queue.get_nowait()
            except Exception:
                break

        if self.CLEAR_CLIPBOARD:
            subprocess.run(["xsel", "-bc"], check=False)

    def loop(self):
        while not self.cancelled.is_set():
            if self.scroll_mode.is_set() and not self.queue.empty():
                amount = self.queue.get()

                if abs(amount) < self.DEAD_AREA // self.DELAY:
                    self.set_icon_state("neutral")
                    sleep(0.01)
                    continue

                if amount < 0:
                    self.set_icon_state("up")
                else:
                    self.set_icon_state("down")

                self.mouse.scroll(0, -amount)
            sleep(0.01)

    def consume(self):
        self.listener.start()
        self.looper.start()
        self.listener.join()
        self.looper.join()

    def run(self):
        self.consumer.start()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    autoscroll = Autoscroll()
    autoscroll.run()
    sys.exit(app.exec())

Add the icons

Neutral icon

bashcat > icon_neutral.svg << 'EOF'
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96">
  <circle cx="48" cy="48" r="38" fill="white" fill-opacity="0.92" stroke="#333" stroke-width="4"/>
  <path d="M48 22 L30 42 H40 V52 H56 V42 H66 Z" fill="#222"/>
  <path d="M30 54 H40 V44 H56 V54 H66 L48 74 Z" fill="#222"/>
</svg>
EOF

Up icon

bashcat > icon_up.svg << 'EOF'
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96">
  <circle cx="48" cy="48" r="38" fill="white" fill-opacity="0.92" stroke="#333" stroke-width="4"/>
  <path d="M48 24 L28 48 H40 V70 H56 V48 H68 Z" fill="#222"/>
</svg>
EOF

Down icon

bashcat > icon_down.svg << 'EOF'
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96">
  <circle cx="48" cy="48" r="38" fill="white" fill-opacity="0.92" stroke="#333" stroke-width="4"/>
  <path d="M28 46 H40 V24 H56 V46 H68 L48 72 Z" fill="#222"/>
</svg>
EOF

Run it

bash
/home/YOUR_USERNAME/linux-autoscroll/.autoscroll/bin/python /home/YOUR_USERNAME/linux-autoscroll/autoscroll.py

Replace YOUR_USERNAME with your Linux username.

Optional autostart

If you want it to start on login:

bashmkdir -p ~/.config/autostart
cat > ~/.config/autostart/linux-autoscroll.desktop << 'EOF'
[Desktop Entry]
Type=Application
Name=Linux Autoscroll
Exec=/home/YOUR_USERNAME/linux-autoscroll/.autoscroll/bin/python /home/YOUR_USERNAME/linux-autoscroll/autoscroll.py
Path=/home/YOUR_USERNAME/linux-autoscroll
Terminal=false
X-GNOME-Autostart-enabled=true
EOF

Notes

  • This is for Xorg.
  • The icon version uses PyQt5.
  • The no-icon version is simpler if you don’t want the overlay.
  • If you enable clipboard clearing, install xsel.
  • Double middle-click activates autoscroll in this version.
  • Single middle-click, left click, or right click cancels it.

I’m sharing this in case anyone else wants a Windows-like autoscroll experience on Linux with a visible icon and cleaner cancel behavior. this is checked and re worked with claude so no worries probably for you

archive.org
u/AgentNo716 — 13 days ago

33rd re watch

Still depressing and unbearable.but eventhough watched 33 time after release it still haunts and teachs but still we dont learn or understand it . Most of the anime reactors asked if theres going to be new anime after watching the ending where they showed the cycle repeating but fail to understand what it taught. Will those who need to understand it understand? Or not? Will people realise attack on titan is not a source of entertainment but also a medium to convey that understanding and introspection might save us .but we never see past it as a anime .what we learn from it is a story not a lesson that is crucial. We show our hate to some character and express it ultimately isayama wanted to unite people in some way and he tried atlast attack titan united us to express some way commonly. We try to understand everyone. Will learning from it change world? It is simply no.we will all be still at war at neck and neck kill ourselves just because some want money ,standing in world order,power These are not necessary but this is what i define humans.greed and self destruction.

Atleast let us understand attack on titan beyond a anime .see into it what it really wanted to convey ourselves.

reddit.com
u/AgentNo716 — 26 days ago

my passage question answers align with marking scheme but still reduced marks

check q1 roman no 7 and 8 and next check q2 roman no 3. should i apply for re val.

u/AgentNo716 — 1 month ago

i currently shifted from windows 10 to xubuntu . but xubuntu lacks many graphical settings and requires lot of terminal knowledge. tell me other linux os to shift. btw i have hdd so something that doesn't hang the device .

  • Upto 2.7GHz Intel Core i7-7500U 7th Gen processor
  • 8GB DDR4 RAM
  • 1TB 5400rpm Serial ATA hard drive
  • Radeon 530 4GB Graphics
reddit.com
u/AgentNo716 — 1 month ago

Have u tried any kind of exotic meat?

Im from tamilnadu i recently came across a video of nagaland cuisine showing some exotic meat like dogs, some kind of monkeys rats etc . Have u ever tried any exotic meat or is it very limited to certain places. Im planning to try something genuinely. But here in tn have tried one exotic meat of monitor lizard or udumbu a large reptile once .

reddit.com
u/AgentNo716 — 1 month ago