├── .gitignore ├── hook.c └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | hook.so 2 | -------------------------------------------------------------------------------- /hook.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | 5 | typedef const char* (*orig_get_name_t)(struct libinput_device *device); 6 | 7 | const char* libinput_device_get_name(struct libinput_device *device) { 8 | set_scroll_emulation(device); // Inject the code to set scrolling emulation 9 | orig_get_name_t orig_get_name; 10 | orig_get_name = (orig_get_name_t) dlsym(RTLD_NEXT, "libinput_device_get_name"); 11 | return orig_get_name(device); 12 | } 13 | 14 | void set_scroll_emulation(struct libinput_device *device) { 15 | libinput_device_config_middle_emulation_set_enabled(device, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED); 16 | libinput_device_config_scroll_set_method(device, LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN); 17 | libinput_device_config_scroll_set_button(device, 273); 18 | } 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | A simple hack to use middle button scrolling emulation under GNOME Wayland (and other Wayland compositors that do not expose `libinput` configuration). This is tested with my GPD Pocket, whose trackpoint does not have a middle button thus cannot scroll by default (after applying this hook, I can use right button + cursor to emulate scrolling) 2 | 3 | Simply clone this repo and run 4 | 5 | ```bash 6 | gcc -shared -ldl -linput -fPIC hook.c -o hook.so 7 | ``` 8 | 9 | which will generate a `hook.so` in the current directory. 10 | 11 | Then add this `hook.so` to your LD\_PRELOAD (use `/etc/profile.d` or `/etc/profile` in order to make it usable to GNOME Wayland) 12 | 13 | e.g. You could add content like this to `/etc/profile.d/libinput.sh` 14 | 15 | ```bash 16 | export LD_PRELOAD="$LD_PRELOAD /path/to/your/hook.so" 17 | ``` 18 | 19 | replace `/path/to/your/hook.so` with the __absolute path__ to your `hook.so`. 20 | 21 | Reboot and enjoy. (Press right button and move the cursor = scrolling) 22 | 23 | How does it work 24 | === 25 | 26 | It is very simple. The `libinput` library itself already contains code to emulate scrolling. Under Xorg we can use configuration like this 27 | 28 | ``` 29 | Driver "libinput" 30 | Option "MiddleEmulation" "1" 31 | Option "ScrollButton" "3" 32 | Option "ScrollMethod" "button" 33 | ``` 34 | 35 | To enable this built-in feature. Even if some Wayland compositors do not expose such configuration, the functionality is still available thanks to `libinput`. All we need to do is to find a way to force apply these options to the devices. 36 | 37 | Therefore, I tried to find a function that has `libinput_device` as a parameter and will be always called. One of them is `libinput_device_get_name`. This is what `hook.c` does: hook into this function and force set the needed configuration on every possible device. Since the compositors will load `/etc/profile` regardlessly, we will now have working scrolling emulation. 38 | 39 | It might be better if something could be done to force expose those configuration options through `LD_PRELOAD`. This is not difficult, but I'm not doing it now because it seems enough for me right now :). 40 | --------------------------------------------------------------------------------