One of my biggest gripes while using Piper has always been the lack of automatic profile switching on profile switch. I wanted to implement a band-aid to try and solve this issue, but have been having too many issues to sink more time into this:
Method 1:
- Using a while loop that triggers every couple seconds that gets the active window id and fetches its name for a function that checks it against various regexs.
- Problem? Well, it is rather laggy. I find my mouse stuttering every once in a while, even when using an if statement to only run code when the IDs don’t match.
Method 2:
- Using
xdotool search . behave %@ focus ...
to add event listeners to windows. - This method was WAY better in terms of performance, but doesn’t apply it to windows created after script launch, which is an issue since the script would launch at session startup.
It’s about time I came to the collective hive-mind for ideas, or even a complete solution that someone may have.
Here is my neofetch for system info, since I know that can impact your answers.
OS: EndeavourOS Linux x86_64
Kernel: 6.3.8-arch1-1
Uptime: 1 hour, 5 mins
Packages: 1400 (pacman), 8 (flatpak)
Shell: zsh 5.9
Resolution: 1080x1920, 1920x1080, 1920x1080
DE: Xfce 4.18
WM: Xfwm4
WM Theme: Matcha-dark-sea
Theme: Flat-Remix-GTK-MORALES-Dark [GTK2], Arc-Darker [GTK3]
Icons: Flat-Remix-Red-Dark [GTK2], Qogir [GTK3]
Terminal: xfce4-terminal
Terminal Font: Fira Code 10
CPU: AMD Ryzen 9 5950X (32) @ 3.400GHz
GPU: NVIDIA GeForce RTX 3080 Lite Hash Rate
Memory: 6675MiB / 32006MiB
The results have made me realize that the bash way of doing this is just not worth attempting, and a Python script is much more simple. At the end of the day, I ended up using this GIST with a custom handler function:
https://gist.github.com/dperelman/c1d3c966d397ff884abb8b3baf7990db
class MouseProfile(Enum): DEFAULT = 0 BLOONS = 1 GAMING_COMMON = 2 CALL_OF_DUTY = 3 REALM_GRINDER = 4 def handle_change(new_state: dict): """ Using `libratbag`, switch the profile of the mouse based on the active window title. """ # Get the title of the active window title: str = new_state['title'] profile: MouseProfile = MouseProfile.DEFAULT match title: case "BloonsTD6": profile = MouseProfile.BLOONS case "Realm Grinder": profile = MouseProfile.REALM_GRINDER case _: if title: if search(r"^Call of Duty.*", title): profile = MouseProfile.CALL_OF_DUTY elif search(r"^Deep Rock Galactic.*", title): profile = MouseProfile.GAMING_COMMON # Send the ratbag command to switch the profile run(["ratbagctl", "Logitech", "profile", "active", "set", str(profile.value)], stdout=PIPE, stderr=PIPE)