A Computer Scientist alumnus with a passion for the open-source community… no wonder I’m here!

  • 1 Post
  • 4 Comments
Joined 1 year ago
cake
Cake day: June 12th, 2023

help-circle

  • I have been tinkering with my script some more and figured I would post an update:

    • As I have been experimenting with the script, I have noticed some weird window dragging issues. I have learned that, if you switch a profile, your mouse is temporarily interrupted, even when switching to the same profile. So, I have added a variable that stores the profile to ensure that you only switch when actually needed.

    GIST with source code used: https://gist.github.com/dperelman/c1d3c966d397ff884abb8b3baf7990db

    from enum import Enum
    from re import search
    from subprocess import run, PIPE
    
    # Code from the GIST
    ... 
    
    class MouseProfile(Enum):
        DEFAULT = 0
        BLOONS = 1
        GAMING_COMMON = 2
        CALL_OF_DUTY = 3
        REALM_GRINDER = 4
    
    current_profile: MouseProfile = MouseProfile.DEFAULT
    
    def handle_change(new_state: dict):
        """
        Using `libratbag`, switch the profile of the mouse
        based on the active window title.
        """
        global current_profile
    
        # 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
        if profile != current_profile:
            run([
                "ratbagctl", "Logitech", "profile", "active", "set", str(profile.value)
            ], stdout=PIPE, stderr=PIPE)
            current_profile = profile
    
    
    if __name__ == '__main__':
        # Get the current mouse profile and set it as the current profile
        result = run(
            ["ratbagctl", "Logitech", "profile", "active", "get"],
            stdout=PIPE, stderr=PIPE
        )
        current_profile = MouseProfile(int(result.stdout)) if result.returncode == 0 else MouseProfile.DEFAULT
    
        # Listen for _NET_ACTIVE_WINDOW changes
        root.change_attributes(event_mask=X.PropertyChangeMask)
    
        # Prime last_seen with whatever window was active when we started this
        get_window_name(get_active_window()[0])
        handle_change(last_seen)
    
        while True:
            handle_xevent(display.next_event())
    

  • 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)