How to rebind button for on-button-scrolling


Is there a workaround to remap the button for the feature “press middle button and move mouse to scroll”?

I have seen a request for this feature on bugs.kde.org
(504013 – Add option to rebind On-Button-Scrolling from middle click to other keys.)

It’s gonna take a long time to get implemented (if it does), so in the meantime, I wish to know if there is a way I can do it on my own.
I have two side buttons on my mouse, and I wish to bind one of them.

System:
  Kernel: 6.14.7-zen2-1-zen arch: x86_64 bits: 64 compiler: gcc v: 15.1.1
    clocksource: hpet avail: acpi_pm
    parameters: BOOT_IMAGE=/@/boot/vmlinuz-linux-zen
    root=UUID=a3ed4574-408f-4802-8fc7-dded1b46b1ac rw rootflags=subvol=@
    resume=UUID=21ea485a-d6f1-4646-b304-bca6967a48e0 loglevel=3
    mitigations=off ibt=off
  Desktop: KDE Plasma v: 6.3.5 tk: Qt v: N/A info: frameworks v: 6.14.0
    wm: kwin_wayland with: krunner vt: 1 dm: SDDM Distro: Garuda
    base: Arch Linux
Machine:
  Type: Laptop System: ASUSTeK product: ROG Strix G713QM_G713QM v: 1.0
    serial: <superuser required>
  Mobo: ASUSTeK model: G713QM v: 1.0 serial: <superuser required>
    uuid: <superuser required> UEFI: American Megatrends LLC. v: G713QM.331
    date: 02/24/2023
Battery:
  ID-1: BAT0 charge: 54.2 Wh (80.1%) condition: 67.7/90.0 Wh (75.2%)
    volts: 15.9 min: 15.9 model: AS3GWAF3KC GA50358 type: Li-ion
    serial: <filter> status: not charging
CPU:
  Info: model: AMD Ryzen 7 5800H with Radeon Graphics bits: 64 type: MT MCP
    arch: Zen 3 gen: 3 level: v3 note: check built: 2021-22
    process: TSMC n7 (7nm) family: 0x19 (25) model-id: 0x50 (80) stepping: 0
    microcode: 0xA500011
  Topology: cpus: 1x dies: 1 clusters: 1 cores: 8 threads: 16 tpc: 2
    smt: enabled cache: L1: 512 KiB desc: d-8x32 KiB; i-8x32 KiB L2: 4 MiB
    desc: 8x512 KiB L3: 16 MiB desc: 1x16 MiB
  Speed (MHz): avg: 400 min/max: 400/3201 boost: enabled scaling:
    driver: amd-pstate-epp governor: powersave cores: 1: 400 2: 400 3: 400
    4: 400 5: 400 6: 400 7: 400 8: 400 9: 400 10: 400 11: 400 12: 400 13: 400
    14: 400 15: 400 16: 400 bogomips: 102218
  Flags: avx avx2 ht lm nx pae sse sse2 sse3 sse4_1 sse4_2 sse4a ssse3 svm
  Vulnerabilities: <filter>
Graphics:
  Device-1: NVIDIA GA106M [GeForce RTX 3060 Mobile / Max-Q] vendor: ASUSTeK
    driver: nvidia v: 570.153.02 alternate: nouveau,nvidia_drm
    non-free: 550-570.xx+ status: current (as of 2025-04; EOL~2026-12-xx)
    arch: Ampere code: GAxxx process: TSMC n7 (7nm) built: 2020-2023 pcie:
    gen: 1 speed: 2.5 GT/s lanes: 8 link-max: gen: 4 speed: 16 GT/s lanes: 16
    ports: active: none off: DP-1 empty: none bus-ID: 01:00.0
    chip-ID: 10de:2520 class-ID: 0300
  Device-2: Advanced Micro Devices [AMD/ATI] Cezanne [Radeon Vega Series /
    Radeon Mobile Series] vendor: ASUSTeK driver: amdgpu v: kernel arch: GCN-5
    code: Vega process: GF 14nm built: 2017-20 pcie: gen: 3 speed: 8 GT/s
    lanes: 16 ports: active: none off: eDP-1 empty: HDMI-A-1 bus-ID: 06:00.0
    chip-ID: 1002:1638 class-ID: 0300 temp: 60.0 C
  Display: wayland server: X.org v: 1.21.1.16 with: Xwayland v: 24.1.6
    compositor: kwin_wayland driver: X: loaded: amdgpu,nvidia
    unloaded: modesetting,nouveau alternate: fbdev,nv,vesa dri: radeonsi
    gpu: amdgpu,nvidia,nvidia-nvswitch display-ID: 0
  Monitor-1: DP-1 model: Acer B246WL serial: <filter> built: 2020 res:
    mode: 1920x1200 hz: 60 scale: 100% (1) dpi: 94 gamma: 1.2
    size: 518x324mm (20.39x12.76") diag: 611mm (24.1") ratio: 16:10 modes:
    max: 1920x1200 min: 640x480
  Monitor-2: eDP-1 model: AU Optronics 0x8294 built: 2020 res: 1920x1080
    dpi: 128 gamma: 1.2 size: 382x215mm (15.04x8.46") diag: 438mm (17.3")
    ratio: 16:9 modes: max: 1920x1080 min: 640x480
  API: EGL v: 1.5 hw: drv: nvidia nouveau drv: nvidia drv: amd radeonsi
    platforms: device: 0 drv: nvidia device: 1 drv: radeonsi device: 2
    drv: nouveau device: 3 drv: swrast gbm: drv: zink surfaceless: drv: nvidia
    wayland: drv: radeonsi x11: drv: radeonsi
  API: OpenGL v: 4.6.0 compat-v: 4.5 vendor: amd mesa v: 25.1.1-arch1.1
    glx-v: 1.4 direct-render: yes renderer: AMD Radeon Graphics (radeonsi
    renoir ACO DRM 3.61 6.14.7-zen2-1-zen) device-ID: 1002:1638
    memory: 500 MiB unified: no display-ID: :1.0
  API: Vulkan v: 1.4.313 layers: 15 device: 0 type: integrated-gpu name: AMD
    Radeon Graphics (RADV RENOIR) driver: mesa radv v: 25.1.1-arch1.1
    device-ID: 1002:1638 surfaces: N/A device: 1 type: discrete-gpu
    name: NVIDIA GeForce RTX 3060 Laptop GPU driver: nvidia v: 570.153.02
    device-ID: 10de:2520 surfaces: N/A device: 2 type: cpu name: llvmpipe
    (LLVM 19.1.7 256 bits) driver: mesa llvmpipe v: 25.1.1-arch1.1 (LLVM
    19.1.7) device-ID: 10005:0000 surfaces: N/A
  Info: Tools: api: clinfo, eglinfo, glxinfo, vulkaninfo
    de: kscreen-console,kscreen-doctor gpu: corectrl, lact, nvidia-settings,
    nvidia-smi, radeontop wl: wayland-info x11: xdpyinfo, xprop, xrandr
Audio:
  Device-1: NVIDIA GA106 High Definition Audio vendor: ASUSTeK
    driver: snd_hda_intel v: kernel pcie: gen: 3 speed: 8 GT/s lanes: 8
    link-max: gen: 4 speed: 16 GT/s lanes: 16 bus-ID: 01:00.1
    chip-ID: 10de:228e class-ID: 0403
  Device-2: Advanced Micro Devices [AMD/ATI] Renoir Radeon High Definition
    Audio vendor: ASUSTeK driver: snd_hda_intel v: kernel pcie: gen: 3
    speed: 8 GT/s lanes: 16 bus-ID: 06:00.1 chip-ID: 1002:1637 class-ID: 0403
  Device-3: Advanced Micro Devices [AMD] ACP/ACP3X/ACP6x Audio Coprocessor
    vendor: ASUSTeK driver: N/A alternate: snd_pci_acp3x, snd_rn_pci_acp3x,
    snd_pci_acp5x, snd_pci_acp6x, snd_acp_pci, snd_rpl_pci_acp6x, snd_pci_ps,
    snd_sof_amd_renoir, snd_sof_amd_rembrandt, snd_sof_amd_vangogh,
    snd_sof_amd_acp63, snd_sof_amd_acp70 pcie: gen: 3 speed: 8 GT/s lanes: 16
    bus-ID: 06:00.5 chip-ID: 1022:15e2 class-ID: 0480
  Device-4: Advanced Micro Devices [AMD] Family 17h/19h/1ah HD Audio
    vendor: ASUSTeK driver: snd_hda_intel v: kernel pcie: gen: 3 speed: 8 GT/s
    lanes: 16 bus-ID: 06:00.6 chip-ID: 1022:15e3 class-ID: 0403
  API: ALSA v: k6.14.7-zen2-1-zen status: kernel-api with: aoss
    type: oss-emulator tools: N/A
  Server-1: PipeWire v: 1.4.2 status: active with: 1: pipewire-pulse
    status: active 2: wireplumber status: active 3: pipewire-alsa type: plugin
    4: pw-jack type: plugin tools: pactl,pw-cat,pw-cli,wpctl
Network:
  Device-1: Realtek RTL8111/8168/8211/8411 PCI Express Gigabit Ethernet
    vendor: ASUSTeK driver: r8169 v: kernel pcie: gen: 1 speed: 2.5 GT/s
    lanes: 1 port: e000 bus-ID: 02:00.0 chip-ID: 10ec:8168 class-ID: 0200
  IF: enp2s0 state: up speed: 1000 Mbps duplex: full mac: <filter>
  Device-2: Intel Wi-Fi 6 AX200 driver: iwlwifi v: kernel pcie: gen: 2
    speed: 5 GT/s lanes: 1 bus-ID: 03:00.0 chip-ID: 8086:2723 class-ID: 0280
  IF: wlp3s0 state: down mac: <filter>
  Info: services: NetworkManager, smbd, systemd-timesyncd
Bluetooth:
  Device-1: Intel AX200 Bluetooth driver: btusb v: 0.8 type: USB rev: 2.0
    speed: 12 Mb/s lanes: 1 mode: 1.1 bus-ID: 3-4:3 chip-ID: 8087:0029
    class-ID: e001
  Report: btmgmt ID: hci0 rfk-id: 0 state: up address: <filter> bt-v: 5.2
    lmp-v: 11 status: discoverable: no pairing: no class-ID: 6c010c
Drives:
  Local Storage: total: 3.21 TiB used: 1.5 TiB (46.8%)
  SMART Message: Unable to run smartctl. Root privileges required.
  ID-1: /dev/nvme0n1 maj-min: 259:0 vendor: Seagate
    model: XPG GAMMIX S70 BLADE size: 1.86 TiB block-size: physical: 512 B
    logical: 512 B speed: 63.2 Gb/s lanes: 4 tech: SSD serial: <filter>
    fw-rev: 3.2.F.83 temp: 53.9 C scheme: GPT
  ID-2: /dev/nvme1n1 maj-min: 259:3 vendor: Samsung model: SSD 980 1TB
    size: 931.51 GiB block-size: physical: 512 B logical: 512 B speed: 31.6 Gb/s
    lanes: 4 tech: SSD serial: <filter> fw-rev: 3B4QFXO7 temp: 51.9 C
    scheme: GPT
  ID-3: /dev/sda maj-min: 8:0 vendor: Western Digital
    model: WDS480G2G0A-00JH30 size: 447.14 GiB block-size: physical: 512 B
    logical: 512 B type: USB rev: 3.0 spd: 5 Gb/s lanes: 1 mode: 3.2 gen-1x1
    tech: SSD serial: <filter> scheme: MBR
Partition:
  ID-1: / raw-size: 897.37 GiB size: 897.37 GiB (100.00%)
    used: 656.05 GiB (73.1%) fs: btrfs dev: /dev/nvme1n1p2 maj-min: 259:5
  ID-2: /boot/efi raw-size: 300 MiB size: 299.4 MiB (99.80%)
    used: 620 KiB (0.2%) fs: vfat dev: /dev/nvme1n1p1 maj-min: 259:4
  ID-3: /home raw-size: 897.37 GiB size: 897.37 GiB (100.00%)
    used: 656.05 GiB (73.1%) fs: btrfs dev: /dev/nvme1n1p2 maj-min: 259:5
  ID-4: /var/log raw-size: 897.37 GiB size: 897.37 GiB (100.00%)
    used: 656.05 GiB (73.1%) fs: btrfs dev: /dev/nvme1n1p2 maj-min: 259:5
  ID-5: /var/tmp raw-size: 897.37 GiB size: 897.37 GiB (100.00%)
    used: 656.05 GiB (73.1%) fs: btrfs dev: /dev/nvme1n1p2 maj-min: 259:5
Swap:
  Kernel: swappiness: 133 (default 60) cache-pressure: 100 (default) zswap: no
  ID-1: swap-1 type: zram size: 30.76 GiB used: 0 KiB (0.0%) priority: 100
    comp: zstd avail: lzo-rle,lzo,lz4,lz4hc,deflate,842 max-streams: 16
    dev: /dev/zram0
  ID-2: swap-2 type: partition size: 33.85 GiB used: 0 KiB (0.0%)
    priority: -2 dev: /dev/nvme1n1p4 maj-min: 259:6
Sensors:
  System Temperatures: cpu: 63.9 C mobo: N/A gpu: amdgpu temp: 60.0 C
  Fan Speeds (rpm): N/A
Info:
  Memory: total: 32 GiB note: est. available: 30.76 GiB used: 7.81 GiB (25.4%)
  Processes: 440 Power: uptime: 56m states: freeze,mem,disk suspend: s2idle
    wakeups: 0 hibernate: platform avail: shutdown, reboot, suspend, test_resume
    image: 12.23 GiB services: org_kde_powerdevil, power-profiles-daemon,
    upowerd Init: systemd v: 257 default: graphical tool: systemctl
  Packages: pm: pacman pkgs: 2444 libs: 606 tools: octopi,paru pm: rpm
    pkgs: 0 pm: flatpak pkgs: 0 Compilers: clang: 19.1.7 gcc: 15.1.1 alt: 13/14
    Shell: garuda-inxi default: fish v: 4.0.2 running-in: konsole inxi: 3.3.38
Garuda (2.7.2-1):
  System install date:     2024-03-16
  Last full system update: 2025-05-30 ↻
  Is partially upgraded:   No
  Relevant software:       snapper NetworkManager dracut nvidia-dkms
  Windows dual boot:       Probably (Run as root to verify)
  Failed units:            

Maybe something like piper (in the extra repo) would work to put a middle mouse click action somewhere else?

Piper doesn’t work for me. It says “cannot find any device”.
Trouble shooting guide says to check if ratbagd service is running and updated (it is).

piper only supports a select list of mice, sadly.

A more generic approach would be using input-remapper-git from the Chaotic-AUR. With that, you can pretty much remap whatever you want, however you want.

Example of mapping the side button of the mouse to the middle mouse button:

Select the device you want to remap on the first tab of the window (Devices). Then go the the Editor tab. In the left field (under Input), hit the Add button then the Record button and then you can press the side mouse button you want to map. Hit the Record button again to stop recording inputs.

On the Output side, Select the “Key or Macro” type. Target the mouse. In the field under that drop-down for the Target, start typing “BTN” and you will see selections; select “BTN_MIDDLE”. After that, you can Apply and save the config, and even toggle the Autoload.

Additional reading on Input Remapper if you are interested:

2 Likes

Seems like it will remap the side button, to act as middle button.
The thing is many applications have different feature when you hold down middle mouse button. If I turn on scroll-with-mouse, those features get suppressed.

On other note, I did receive a reply from someone at bugs.kde.org, they said the following:

Libinput has this feature: https://wayland.freedesktop.org/libinput/doc/1.11.3/group__config.html#gac95a25055b22c3631e3c10c0463ca332

This link leads to this section of the page,

So, I now one more piece to the puzzle.

Could you link the bug report URL (as that lists the bug number)? I would like to see it.

1 Like

Here you go

1 Like

Ya… that makes things a bit difficult if it isn’t exposed in a GUI of some kind… not to mention, the libinput feature is disabled by default (and I’m not sure how to even enable that).

Looks like developers will have to fix this. I’m not sure of any workaround that can fix something like this, as like you said the middle mouse button usually gets intercepted by other commands from other programs for that button.

2 Likes

ARCH WIKI COMING IN CLUTCH!!!

  1. install libinput-config
    paru -S libinput-config
    Arch Wiki adviced to install libinput-config-git, but it didn’t work for me.

  2. Create a file, /etc/libinput.conf

  3. Put the following in the file,

override-compositor=enabled
scroll-button=0x114
  1. Reboot

Also, the first time I rebooted the PC, I was playing around with my scroll wheel, and for some reason, the PC got stuck in a loop between black screen and the SDDM. After a force shutdown, it’s now working fine.

Also, you can check the input codes from here, linux/include/uapi/linux/input-event-codes.h at bb7c241fae6228e89c0286ffd6f249b3b0dea225 · torvalds/linux · GitHub

3 Likes

I’m surprised libinput-config worked considering the package is an orphan in the AUR from a few years back. It is however slightly more recent than the also orphaned git variant though, which is probably why that other one worked better (seems the git variant is marked out of date). Thanks a ton for that information that you actually got it working!

3 Likes

We need to find someone to maintain it now, otherwise my workaround will need a workaround lol

It isn’t just the AUR packages, but actually upstream. The developer is unable to maintain it alone, so even if packaged properly, it will eventually fail:

Maintainer needed
Back when I made this hack, I didn’t expect so many people to actually use it. Unfortunately, I’m no longer able to maintain it on my own. Your help is always welcome.

That notice was added June 25, 2023

3 Likes

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.