Best Python code snippet using fMBT_python
mouse_mode.py
Source:mouse_mode.py  
1import os2import json3MOUSE_MODE_KEY = "semicolon"4ACTIVATE_TOGGLE = "m"5DOWN = "j"6UP = "k"7LEFT = "h"8RIGHT = "l"9FAST = "a"10SLOW = "s"11SCROLL = "d"12ARROW = "r"13LEFT_CLICK = "f"14MIDDLE_CLICK = "v"15RIGHT_CLICK = "g"16LEFT_CLICK_2 = "u"17MIDDLE_CLICK_2 = "i"18RIGHT_CLICK_2 = "o"19MOUSE_SCROLL_SPEED = 3220MOUSE_SPEED = 120021MOUSE_SLOW_MULTIPLIER = 0.2522MOUSE_FAST_MULTIPLIER = 223MOUSE_MODE = "jeffwu_mouse_mode"24# ARROW_MODE = "jeffwu_arrow_mode"25SCROLL_MODE = "jeffwu_scroll_mode"26SIMULTANEOUS_THRESHOLD_MS = 10027def var_is_set(var, value=1):28    """ Returns condition that variable is set. """29    return {30        "type": "variable_if",31        "name": var,32        "value": value33    }34def set_var(var, value=1):35    """ Returns condition that variable is set. """36    return {37        "set_variable": {38            "name": var,39            "value": value40        }41    }42def single_key(key_code, modifiers=[]):43    return {44        "key_code": key_code,45        "modifiers": {46            "mandatory": modifiers,47            "optional": [48                "any"49            ]50        }51    }52def simultaneous_keys(key_codes, after_up=None):53    res = {54        "simultaneous": [55            { "key_code": key_code } for key_code in key_codes56        ],57        "simultaneous_options": {58            "key_down_order": "strict",59            "key_up_order": "strict_inverse",60        },61        "modifiers": { "optional": [ "any" ] }62    }63    if after_up is not None:64        res["simultaneous_options"]["to_after_key_up"] = after_up65    return res66def basic_rule(items):67    return {68        "type": "basic",69        # "parameters": { "basic.simultaneous_threshold_milliseconds": SIMULTANEOUS_THRESHOLD_MS },70        **items71    }72def _scroll_combos(key):73    return [74        single_key(key, [ "left_shift" ]),75        single_key(key, [ "right_shift" ]),76        simultaneous_keys([SCROLL, key]),77    ]78def _toggle_combos():79    return [80        single_key(ACTIVATE_TOGGLE, ["left_command"]),81        single_key(ACTIVATE_TOGGLE, ["right_command"]),82        simultaneous_keys([MOUSE_MODE_KEY, ACTIVATE_TOGGLE]),83        # DONT KNOW WHY THIS DOESNT WORK84        simultaneous_keys(["escape", ACTIVATE_TOGGLE]),85    ]86# mouse_mode_rules = [87#     *[88#         basic_rule({89#             "from": fr,90#             "to": [ set_var(MOUSE_MODE, 0) ],91#             "conditions": [ var_is_set(MOUSE_MODE, 1) ]92#         }) for fr in [ single_key("escape"), single_key(MOUSE_MODE_KEY), single_key(ACTIVATE_TOGGLE) ]93#     ],94#     *[95#         basic_rule({96#             "from": fr,97#             "to": [98#                 set_var(MOUSE_MODE, 1),99#             ],100#             "conditions": [101#                 var_is_set(MOUSE_MODE, 0),102#             ],103#             "parameters": { "basic.simultaneous_threshold_milliseconds": SIMULTANEOUS_THRESHOLD_MS },104#         }) for fr in _toggle_combos()105#     ],106#     *[107#         basic_rule({108#             "from": fr,109#             "to": [110#                 set_var(MOUSE_MODE, 0),111#             ],112#             "conditions": [113#                 var_is_set(MOUSE_MODE, 1),114#             ],115#             "parameters": { "basic.simultaneous_threshold_milliseconds": SIMULTANEOUS_THRESHOLD_MS },116#         }) for fr in _toggle_combos()117#     ],118#     # NO-OP TO PREVENT WEIRD BEHAVIOR (sending d while scrolling)119#     basic_rule({120#         "from": single_key(UP),121#         "to": [122#             { "mouse_key": { "vertical_wheel": -MOUSE_SCROLL_SPEED } }123#         ],124#         "conditions": [125#             var_is_set(MOUSE_MODE),126#             var_is_set(SCROLL_MODE),127#         ]128#     }),129#     basic_rule({130#         "from": single_key(DOWN),131#         "to": [132#             { "mouse_key": { "vertical_wheel": MOUSE_SCROLL_SPEED } }133#         ],134#         "conditions": [135#             var_is_set(MOUSE_MODE),136#             var_is_set(SCROLL_MODE),137#         ]138#     }),139#     basic_rule({140#         "from": single_key(RIGHT),141#         "to": [142#             { "mouse_key": { "horizontal_wheel": MOUSE_SCROLL_SPEED } }143#         ],144#         "conditions": [145#             var_is_set(MOUSE_MODE),146#             var_is_set(SCROLL_MODE),147#         ]148#     }),149#     basic_rule({150#         "from": single_key(LEFT),151#         "to": [152#             { "mouse_key": { "horizontal_wheel": -MOUSE_SCROLL_SPEED } }153#         ],154#         "conditions": [155#             var_is_set(MOUSE_MODE),156#             var_is_set(SCROLL_MODE),157#         ]158#     }),159#     *[160#         basic_rule({161#             "from": fr,162#             "to": [163#                 { "mouse_key": { "vertical_wheel": -MOUSE_SCROLL_SPEED } }164#             ],165#             "conditions": [166#                 var_is_set(MOUSE_MODE),167#             ]168#         }) for fr in _scroll_combos(UP)169#     ],170#     *[171#         basic_rule({172#             "from": fr,173#             "to": [174#                 { "mouse_key": { "vertical_wheel": MOUSE_SCROLL_SPEED } }175#             ],176#             "conditions": [177#                 var_is_set(MOUSE_MODE),178#             ]179#         }) for fr in _scroll_combos(DOWN)180#     ],181#     *[182#         basic_rule({183#             "from": fr,184#             "to": [185#                 { "mouse_key": { "horizontal_wheel": MOUSE_SCROLL_SPEED } }186#             ],187#             "conditions": [188#                 var_is_set(MOUSE_MODE),189#             ]190#         }) for fr in _scroll_combos(RIGHT)191#     ],192#     *[193#         basic_rule({194#             "from": fr,195#             "to": [196#                 { "mouse_key": { "horizontal_wheel": -MOUSE_SCROLL_SPEED } }197#             ],198#             "conditions": [199#                 var_is_set(MOUSE_MODE),200#             ]201#         }) for fr in _scroll_combos(LEFT)202#     ],203#     basic_rule({204#         "from": single_key(SCROLL),205#         "to": [206#             set_var(MOUSE_MODE, 1),207#             set_var(SCROLL_MODE, 1),208#         ],209#         "to_after_key_up": [ set_var(SCROLL_MODE, 0) ],210#         "conditions": [211#             var_is_set(MOUSE_MODE, 1),212#         ]213#     }),214#     basic_rule({215#       "from": single_key(DOWN),216#       "to": [217#           { "mouse_key": { "y": MOUSE_SPEED } }218#       ],219#       "conditions": [220#           var_is_set(MOUSE_MODE),221#       ]222#     }),223#     basic_rule({224#       "from": single_key(UP),225#       "to": [226#           { "mouse_key": { "y": -MOUSE_SPEED } }227#       ],228#       "conditions": [229#           var_is_set(MOUSE_MODE),230#       ]231#     }),232#     basic_rule({233#       "from": single_key(LEFT),234#       "to": [235#           { "mouse_key": { "x": -MOUSE_SPEED } }236#       ],237#       "conditions": [238#           var_is_set(MOUSE_MODE),239#       ]240#     }),241#     basic_rule({242#       "from": single_key(RIGHT),243#       "to": [244#           { "mouse_key": { "x": MOUSE_SPEED } }245#       ],246#       "conditions": [247#           var_is_set(MOUSE_MODE),248#       ]249#     }),250#     *[251#         basic_rule({252#             "from": f,253#             "to": [254#                 { "pointing_button": "button1" }255#             ],256#             "conditions": [257#                 var_is_set(MOUSE_MODE),258#             ]259#         }) for f in [single_key(LEFT_CLICK), single_key(LEFT_CLICK_2)]260#     ],261#     *[262#         basic_rule({263#             "from": f,264#             "to": [265#                 { "pointing_button": "button3" }266#             ],267#             "conditions": [268#                 var_is_set(MOUSE_MODE),269#             ]270#         }) for f in [single_key(MIDDLE_CLICK), single_key(MIDDLE_CLICK_2)]271#     ],272#     *[273#         basic_rule({274#             "from": f,275#             "to": [276#                 { "pointing_button": "button2" }277#             ],278#             "conditions": [279#                 var_is_set(MOUSE_MODE),280#             ]281#         }) for f in [single_key(RIGHT_CLICK), single_key(RIGHT_CLICK_2), single_key(LEFT_CLICK, ["left_shift"]), single_key(LEFT_CLICK, ["right_shift"])]282#     ],283#     basic_rule({284#         "from": single_key(SLOW),285#         "to": [286#             { "mouse_key": { "speed_multiplier": MOUSE_SLOW_MULTIPLIER } }287#         ],288#         "conditions": [289#             var_is_set(MOUSE_MODE),290#         ]291#     }),292#     basic_rule({293#         "from": single_key(FAST),294#         "to": [295#             { "mouse_key": { "speed_multiplier": MOUSE_FAST_MULTIPLIER } }296#         ],297#         "conditions": [298#             var_is_set(MOUSE_MODE),299#         ]300#     }),301# ]302caps_lock_rules = [303    basic_rule({304        "from": single_key("caps_lock"),305        "to": [ { "key_code": "left_control" } ],306        "to_if_alone": [ { "key_code": "escape" } ],307    })308]309# NOTE: this is disabled because escape delay is too annoying310# Doing this with a simple rule instead311# right_command_rules = [312#     basic_rule({313#         "from": single_key("right_command"),314#         "to": [ { "key_code": "right_command" } ],315#         "to_if_alone": [ { "key_code": "escape" } ],316#     })317# ]318shift_rules = [319    basic_rule({320        "from": { "key_code": "left_shift" },321        "to": [ { "key_code": "left_shift" } ],322        "to_if_alone": [323            {324                "key_code": "9",325                "modifiers": [ "left_shift" ]326            }327        ]328    }),329    basic_rule({330        "from": { "key_code": "right_shift" },331        "to": [ { "key_code": "right_shift" } ],332        "to_if_alone": [333            {334                "key_code": "0",335                "modifiers": [ "right_shift" ]336            }337        ]338    }),339    # rolls340    basic_rule({341        "from": {342            "key_code": "left_shift",343            "modifiers": {344                "mandatory": [ "right_shift" ]345            }346        },347        "to": [348            { "key_code": "left_shift" },349            { "key_code": "right_shift" }350        ],351        "to_if_alone": [352            {353                "key_code": "0",354                # why both?355                "modifiers": [ "right_shift", "left_shift" ]356            },357            {358                "key_code": "9",359                "modifiers": [ "right_shift", "left_shift" ]360            }361        ]362    }),363    basic_rule({364        "from": {365            "key_code": "right_shift",366            "modifiers": {367                "mandatory": [ "left_shift" ]368            }369        },370        "to": [371            { "key_code": "right_shift" },372            { "key_code": "left_shift" }373        ],374        "to_if_alone": [375            {376                "key_code": "9",377                "modifiers": [ "right_shift" ]378            },379            {380                "key_code": "0",381                "modifiers": [ "right_shift" ]382            }383        ]384    })385]386# TODO: make it so holding works387# arrow_rules = [388#     basic_rule({389#         "from": simultaneous_keys([ARROW, LEFT], after_up=[set_var(ARROW_MODE, 0)]),390#         "to": [ { "key_code": "left_arrow" }, set_var(ARROW_MODE, 1) ],391#         "parameters": { "basic.simultaneous_threshold_milliseconds": SIMULTANEOUS_THRESHOLD_MS },392#     }),393#     basic_rule({394#         "from": simultaneous_keys([ARROW, DOWN], after_up=[set_var(ARROW_MODE, 0)]),395#         "to": [ { "key_code": "down_arrow" }, set_var(ARROW_MODE, 1) ],396#         "parameters": { "basic.simultaneous_threshold_milliseconds": SIMULTANEOUS_THRESHOLD_MS },397#     }),398#     basic_rule({399#         "from": simultaneous_keys([ARROW, RIGHT], after_up=[set_var(ARROW_MODE, 0)]),400#         "to": [ { "key_code": "right_arrow" }, set_var(ARROW_MODE, 1) ],401#         "parameters": { "basic.simultaneous_threshold_milliseconds": SIMULTANEOUS_THRESHOLD_MS },402#     }),403#     basic_rule({404#         "from": simultaneous_keys([ARROW, UP], after_up=[set_var(ARROW_MODE, 0)]),405#         "to": [ { "key_code": "up_arrow" }, set_var(ARROW_MODE, 1) ],406#         "parameters": { "basic.simultaneous_threshold_milliseconds": SIMULTANEOUS_THRESHOLD_MS },407#     }),408#     basic_rule({409#         "from": single_key(LEFT),410#         "to": [ { "key_code": "left_arrow" } ],411#         "conditions": [ var_is_set(ARROW_MODE), ]412#     }),413#     basic_rule({414#         "from": single_key(DOWN),415#         "to": [ { "key_code": "down_arrow" } ],416#         "conditions": [ var_is_set(ARROW_MODE), ]417#     }),418#     basic_rule({419#         "from": single_key(RIGHT),420#         "to": [ { "key_code": "right_arrow" } ],421#         "conditions": [ var_is_set(ARROW_MODE), ]422#     }),423#     basic_rule({424#         "from": single_key(UP),425#         "to": [ { "key_code": "up_arrow" } ],426#         "conditions": [ var_is_set(ARROW_MODE), ]427#     }),428# ]429SIMULTANEOUS_THRESHOLD_MS = 100430SIMULTANEOUS_THRESHOLD_MS_RULE = { "basic.simultaneous_threshold_milliseconds": SIMULTANEOUS_THRESHOLD_MS }431MOUSE_KEYS_MOUSE_MODE = "mouse_keys_mode"432MOUSE_KEYS_SCROLL_MODE = "mouse_keys_mode_scroll"433MOUSE_KEYS_ARROW_MODE = "mouse_keys_mode_arrows"434MOUSE_KEYS_AFTER_UP = [435    set_var(MOUSE_KEYS_MOUSE_MODE, 0),436    set_var(MOUSE_KEYS_SCROLL_MODE, 0),437    set_var(MOUSE_KEYS_ARROW_MODE, 0),438]439mouse_keys_rules = [440    basic_rule({441      "from": single_key(DOWN),442      "to": [443        { "mouse_key": { "vertical_wheel": 32 } }444      ],445      "conditions": [446        var_is_set(MOUSE_KEYS_MOUSE_MODE),447        var_is_set(MOUSE_KEYS_SCROLL_MODE),448      ]449    }),450    basic_rule({451      "from": single_key(DOWN),452      "to": [453        { "key_code": "down_arrow" }454      ],455      "conditions": [456        var_is_set(MOUSE_KEYS_MOUSE_MODE),457        var_is_set(MOUSE_KEYS_ARROW_MODE),458      ]459    }),460    basic_rule({461      "from": single_key(DOWN),462      "to": [463        { "mouse_key": { "y": MOUSE_SPEED } }464      ],465      "conditions": [466        var_is_set(MOUSE_KEYS_MOUSE_MODE),467      ]468    }),469    basic_rule({470        "from": simultaneous_keys([MOUSE_MODE_KEY, DOWN], after_up=MOUSE_KEYS_AFTER_UP),471        "to": [472            set_var(MOUSE_KEYS_MOUSE_MODE, 1),473            { "mouse_key": { "y": MOUSE_SPEED } }474        ],475        "parameters": SIMULTANEOUS_THRESHOLD_MS_RULE476    }),477    basic_rule({478        "from": single_key(UP),479        "to": [480            { "mouse_key": { "vertical_wheel": -MOUSE_SCROLL_SPEED } }481        ],482        "conditions": [483            var_is_set(MOUSE_KEYS_MOUSE_MODE),484            var_is_set(MOUSE_KEYS_SCROLL_MODE),485        ]486    }),487    basic_rule({488        "from": single_key(UP),489        "to": [490            { "key_code": "up_arrow" }491        ],492        "conditions": [493            var_is_set(MOUSE_KEYS_MOUSE_MODE),494            var_is_set(MOUSE_KEYS_ARROW_MODE),495        ]496    }),497    basic_rule({498        "from": single_key(UP),499        "to": [500            { "mouse_key": { "y": -MOUSE_SPEED } }501        ],502        "conditions": [503            var_is_set(MOUSE_KEYS_MOUSE_MODE),504        ]505    }),506    basic_rule({507        "from": simultaneous_keys([MOUSE_MODE_KEY, UP], after_up=MOUSE_KEYS_AFTER_UP),508        "to": [509            set_var(MOUSE_KEYS_MOUSE_MODE, 1),510            { "mouse_key": { "y": -MOUSE_SPEED } }511        ],512        "parameters": SIMULTANEOUS_THRESHOLD_MS_RULE513    }),514    basic_rule({515        "from": single_key(LEFT),516        "to": [517            { "mouse_key": { "horizontal_wheel": MOUSE_SCROLL_SPEED } }518        ],519        "conditions": [520            var_is_set(MOUSE_KEYS_MOUSE_MODE),521            var_is_set(MOUSE_KEYS_SCROLL_MODE),522        ]523    }),524    basic_rule({525        "from": single_key(LEFT),526        "to": [527            { "key_code": "left_arrow" }528        ],529        "conditions": [530            var_is_set(MOUSE_KEYS_MOUSE_MODE),531            var_is_set(MOUSE_KEYS_ARROW_MODE),532        ]533    }),534    basic_rule({535        "from": single_key(LEFT),536        "to": [537            { "mouse_key": { "x": -MOUSE_SPEED } }538        ],539        "conditions": [540            var_is_set(MOUSE_KEYS_MOUSE_MODE),541        ]542    }),543    basic_rule({544        "from": simultaneous_keys([MOUSE_MODE_KEY, LEFT], after_up=MOUSE_KEYS_AFTER_UP),545        "to": [546            set_var(MOUSE_KEYS_MOUSE_MODE, 1),547            { "mouse_key": { "x": -MOUSE_SPEED } }548        ],549        "parameters": SIMULTANEOUS_THRESHOLD_MS_RULE550    }),551    basic_rule({552        "from": single_key(RIGHT),553        "to": [554            { "mouse_key": { "horizontal_wheel": -MOUSE_SCROLL_SPEED } }555        ],556        "conditions": [557            var_is_set(MOUSE_KEYS_MOUSE_MODE),558            var_is_set(MOUSE_KEYS_SCROLL_MODE),559        ]560    }),561    basic_rule({562        "from": single_key(RIGHT),563        "to": [564            { "key_code": "right_arrow" }565        ],566        "conditions": [567            var_is_set(MOUSE_KEYS_MOUSE_MODE),568            var_is_set(MOUSE_KEYS_ARROW_MODE),569        ]570    }),571    basic_rule({572        "from": single_key(RIGHT),573        "to": [574            { "mouse_key": { "x": MOUSE_SPEED } }575        ],576        "conditions": [577            var_is_set(MOUSE_KEYS_MOUSE_MODE),578        ]579    }),580    basic_rule({581        "from": simultaneous_keys([MOUSE_MODE_KEY, RIGHT], after_up=MOUSE_KEYS_AFTER_UP),582        "to": [583            set_var(MOUSE_KEYS_MOUSE_MODE, 1),584            { "mouse_key": { "x": MOUSE_SPEED } }585        ],586        "parameters": SIMULTANEOUS_THRESHOLD_MS_RULE587    }),588    basic_rule({589        "from": single_key(LEFT_CLICK),590        "to": [591            { "pointing_button": "button1" }592        ],593        "conditions": [594            var_is_set(MOUSE_KEYS_MOUSE_MODE),595        ]596    }),597    basic_rule({598        "from": simultaneous_keys([MOUSE_MODE_KEY, LEFT_CLICK], after_up=MOUSE_KEYS_AFTER_UP),599        "to": [600            set_var(MOUSE_KEYS_MOUSE_MODE, 1),601            { "pointing_button": "button1" }602        ],603        "parameters": SIMULTANEOUS_THRESHOLD_MS_RULE604    }),605    basic_rule({606        "from": single_key(MIDDLE_CLICK),607        "to": [608            { "pointing_button": "button3" }609        ],610        "conditions": [611            var_is_set(MOUSE_KEYS_MOUSE_MODE),612        ]613    }),614    basic_rule({615        "from": simultaneous_keys([MOUSE_MODE_KEY, MIDDLE_CLICK], after_up=MOUSE_KEYS_AFTER_UP),616        "to": [617            set_var(MOUSE_KEYS_MOUSE_MODE, 1),618            { "pointing_button": "button3" }619        ],620        "parameters": SIMULTANEOUS_THRESHOLD_MS_RULE621    }),622    basic_rule({623        "from": single_key(RIGHT_CLICK),624        "to": [625            { "pointing_button": "button2" }626        ],627        "conditions": [628            var_is_set(MOUSE_KEYS_MOUSE_MODE),629        ]630    }),631    basic_rule({632        "from": simultaneous_keys([MOUSE_MODE_KEY, RIGHT_CLICK], after_up=MOUSE_KEYS_AFTER_UP),633        "to": [634            set_var(MOUSE_KEYS_MOUSE_MODE, 1),635            { "pointing_button": "button2" }636        ],637        "parameters": SIMULTANEOUS_THRESHOLD_MS_RULE638    }),639    basic_rule({640        "from": single_key(SCROLL),641        "to": [642            set_var(MOUSE_KEYS_SCROLL_MODE, 1),643        ],644        "conditions": [645            var_is_set(MOUSE_KEYS_MOUSE_MODE),646        ],647        "to_after_key_up": [648            set_var(MOUSE_KEYS_SCROLL_MODE, 0),649        ]650    }),651    basic_rule({652        "from": simultaneous_keys([MOUSE_MODE_KEY, SCROLL], after_up=MOUSE_KEYS_AFTER_UP),653        "to": [654            set_var(MOUSE_KEYS_MOUSE_MODE, 1),655            set_var(MOUSE_KEYS_SCROLL_MODE, 1),656        ],657        "parameters": SIMULTANEOUS_THRESHOLD_MS_RULE,658        "to_after_key_up": [659            set_var(MOUSE_KEYS_SCROLL_MODE, 0),660        ]661    }),662    basic_rule({663        "from": single_key(FAST),664        "to": [665            { "mouse_key": { "speed_multiplier": MOUSE_FAST_MULTIPLIER } }666        ],667        "conditions": [668            var_is_set(MOUSE_KEYS_MOUSE_MODE),669        ]670    }),671    basic_rule({672        "from": simultaneous_keys([MOUSE_MODE_KEY, FAST], after_up=MOUSE_KEYS_AFTER_UP),673        "to": [674            set_var(MOUSE_KEYS_MOUSE_MODE, 1),675            { "mouse_key": { "speed_multiplier": MOUSE_FAST_MULTIPLIER } }676        ],677        "parameters": SIMULTANEOUS_THRESHOLD_MS_RULE678    }),679    basic_rule({680        "from": single_key(SLOW),681        "to": [682            { "mouse_key": { "speed_multiplier": MOUSE_SLOW_MULTIPLIER } }683        ],684        "conditions": [685            var_is_set(MOUSE_KEYS_MOUSE_MODE),686        ]687    }),688    basic_rule({689        "from": simultaneous_keys([MOUSE_MODE_KEY, SLOW], after_up=MOUSE_KEYS_AFTER_UP),690        "to": [691            set_var(MOUSE_KEYS_MOUSE_MODE, 1),692            { "mouse_key": { "speed_multiplier": MOUSE_SLOW_MULTIPLIER } }693        ],694        "parameters": SIMULTANEOUS_THRESHOLD_MS_RULE695    }),696    basic_rule({697        "from": single_key(ARROW),698        "to": [699            set_var(MOUSE_KEYS_ARROW_MODE, 1),700        ],701        "conditions": [702            var_is_set(MOUSE_KEYS_MOUSE_MODE),703        ],704        "to_after_key_up": [705            set_var(MOUSE_KEYS_ARROW_MODE, 0),706        ]707    }),708    basic_rule({709        "from": simultaneous_keys([MOUSE_MODE_KEY, ARROW], after_up=MOUSE_KEYS_AFTER_UP),710        "to": [711            set_var(MOUSE_KEYS_MOUSE_MODE, 1),712            set_var(MOUSE_KEYS_ARROW_MODE, 1),713        ],714        "parameters": SIMULTANEOUS_THRESHOLD_MS_RULE,715        "to_after_key_up": [716            set_var(MOUSE_KEYS_SCROLL_MODE, 0),717        ]718    })719]720with open(os.path.realpath(__file__).replace('.py', '.json'), 'w') as f:721    json.dump({722        "title": "Jeff Wu's karabiner settings",723        "rules": [724            # {725            #     "description": "Mouse Mode",726            #     "manipulators": mouse_mode_rules,727            # },728            {729                "description": "Mouse Keys",730                "manipulators": mouse_keys_rules,731            },732            {733                "description": "Caps Lock to Control, Escape on single press.",734                "manipulators": caps_lock_rules,735            },736            # {737            #     "description": "Right Command to Escape.",738            #     "manipulators": right_command_rules,739            # },740            # {741            #     "description": "semicolon = arrows",742            #     "manipulators": arrow_rules,743            # },744            {745                "description": "Better Shifting: Parentheses on shift keys",746                "manipulators": shift_rules,747            },748            {749                "description": "Change caps + space to backspace",750                "manipulators": [751                    basic_rule({752                        # use left control since we map caps to that753                        "from": single_key("spacebar", [ "left_control" ]),754                        "to": [ { "key_code": "delete_or_backspace" } ],755                    }),756                ]757            }758    ],...pyglet_view.py
Source:pyglet_view.py  
1from builtins import object2from pyglet.window import key, mouse3from pyglet.libs.darwin.quartzkey import keymap, charmap4from pyglet.libs.darwin.cocoapy import *5NSTrackingArea = ObjCClass('NSTrackingArea')6# Event data helper functions.7def getMouseDelta(nsevent):8    dx = nsevent.deltaX()9    dy = -nsevent.deltaY()10    return int(round(dx)), int(round(dy))11def getMousePosition(self, nsevent):12    in_window = nsevent.locationInWindow()13    in_window = self.convertPoint_fromView_(in_window, None)14    x = int(in_window.x)15    y = int(in_window.y)16    # Must record mouse position for BaseWindow.draw_mouse_cursor to work.17    self._window._mouse_x = x18    self._window._mouse_y = y19    return x, y20def getModifiers(nsevent):21    modifiers = 022    modifierFlags = nsevent.modifierFlags()23    if modifierFlags & NSAlphaShiftKeyMask:24        modifiers |= key.MOD_CAPSLOCK25    if modifierFlags & NSShiftKeyMask:26        modifiers |= key.MOD_SHIFT27    if modifierFlags & NSControlKeyMask:28        modifiers |= key.MOD_CTRL29    if modifierFlags & NSAlternateKeyMask:30        modifiers |= key.MOD_ALT31        modifiers |= key.MOD_OPTION32    if modifierFlags & NSCommandKeyMask:33        modifiers |= key.MOD_COMMAND34    if modifierFlags & NSFunctionKeyMask:35        modifiers |= key.MOD_FUNCTION36    return modifiers37def getSymbol(nsevent):38    keycode = nsevent.keyCode()39    return keymap[keycode]40class PygletView_Implementation(object):41    PygletView = ObjCSubclass('NSView', 'PygletView')42    @PygletView.method(b'@'+NSRectEncoding+PyObjectEncoding)43    def initWithFrame_cocoaWindow_(self, frame, window):44        # The tracking area is used to get mouseEntered, mouseExited, and cursorUpdate 45        # events so that we can custom set the mouse cursor within the view.46        self._tracking_area = None47        self = ObjCInstance(send_super(self, 'initWithFrame:', frame, argtypes=[NSRect]))48        if not self:49            return None50        # CocoaWindow object.51        self._window = window52        self.updateTrackingAreas()53        # Create an instance of PygletTextView to handle text events. 54        # We must do this because NSOpenGLView doesn't conform to the55        # NSTextInputClient protocol by default, and the insertText: method will56        # not do the right thing with respect to translating key sequences like57        # "Option-e", "e" if the protocol isn't implemented.  So the easiest58        # thing to do is to subclass NSTextView which *does* implement the59        # protocol and let it handle text input.60        PygletTextView = ObjCClass('PygletTextView')61        self._textview = PygletTextView.alloc().initWithCocoaWindow_(window)62        # Add text view to the responder chain.63        self.addSubview_(self._textview)64        return self65    @PygletView.method('v')66    def dealloc(self):67        self._window = None68        #send_message(self.objc_self, 'removeFromSuperviewWithoutNeedingDisplay')69        self._textview.release()70        self._textview = None71        self._tracking_area.release()72        self._tracking_area = None73        send_super(self, 'dealloc')        74    @PygletView.method('v')75    def updateTrackingAreas(self):76        # This method is called automatically whenever the tracking areas need to be77        # recreated, for example when window resizes.78        if self._tracking_area:79            self.removeTrackingArea_(self._tracking_area)80            self._tracking_area.release()81            self._tracking_area = None82        tracking_options = NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp | NSTrackingCursorUpdate83        frame = self.frame()84        self._tracking_area = NSTrackingArea.alloc().initWithRect_options_owner_userInfo_(85            frame,              # rect86            tracking_options,   # options87            self,     # owner88            None)               # userInfo89        self.addTrackingArea_(self._tracking_area)90    91    @PygletView.method('B')92    def canBecomeKeyView(self):93        return True94    @PygletView.method('B')95    def isOpaque(self):96        return True97    ## Event responders.98    # This method is called whenever the view changes size.99    @PygletView.method(b'v'+NSSizeEncoding) 100    def setFrameSize_(self, size):101        send_super(self, 'setFrameSize:', size, argtypes=[NSSize])102        # This method is called when view is first installed as the103        # contentView of window.  Don't do anything on first call.104        # This also helps ensure correct window creation event ordering.105        if not self._window.context.canvas:106            return107        width, height = int(size.width), int(size.height)108        self._window.switch_to()109        self._window.context.update_geometry()110        self._window.dispatch_event("on_resize", width, height)111        self._window.dispatch_event("on_expose")112        # Can't get app.event_loop.enter_blocking() working with Cocoa, because113        # when mouse clicks on the window's resize control, Cocoa enters into a114        # mini-event loop that only responds to mouseDragged and mouseUp events.115        # This means that using NSTimer to call idle() won't work.  Our kludge116        # is to override NSWindow's nextEventMatchingMask_etc method and call117        # idle() from there.118        if self.inLiveResize():119            from pyglet import app120            if app.event_loop is not None:121                app.event_loop.idle()122    @PygletView.method('v@')123    def pygletKeyDown_(self, nsevent):124        symbol = getSymbol(nsevent)125        modifiers = getModifiers(nsevent)126        self._window.dispatch_event('on_key_press', symbol, modifiers)127    @PygletView.method('v@')128    def pygletKeyUp_(self, nsevent):129        symbol = getSymbol(nsevent)130        modifiers = getModifiers(nsevent)131        self._window.dispatch_event('on_key_release', symbol, modifiers)132    @PygletView.method('v@')133    def pygletFlagsChanged_(self, nsevent):134        # Handles on_key_press and on_key_release events for modifier keys.135        # Note that capslock is handled differently than other keys; it acts136        # as a toggle, so on_key_release is only sent when it's turned off.137        # TODO: Move these constants somewhere else.138        # Undocumented left/right modifier masks found by experimentation:139        NSLeftShiftKeyMask      = 1 << 1140        NSRightShiftKeyMask     = 1 << 2141        NSLeftControlKeyMask    = 1 << 0142        NSRightControlKeyMask   = 1 << 13143        NSLeftAlternateKeyMask  = 1 << 5144        NSRightAlternateKeyMask = 1 << 6145        NSLeftCommandKeyMask    = 1 << 3146        NSRightCommandKeyMask   = 1 << 4147        maskForKey = { key.LSHIFT : NSLeftShiftKeyMask,148                       key.RSHIFT : NSRightShiftKeyMask,149                       key.LCTRL : NSLeftControlKeyMask,150                       key.RCTRL : NSRightControlKeyMask,151                       key.LOPTION : NSLeftAlternateKeyMask,152                       key.ROPTION : NSRightAlternateKeyMask,153                       key.LCOMMAND : NSLeftCommandKeyMask,154                       key.RCOMMAND : NSRightCommandKeyMask,155                       key.CAPSLOCK : NSAlphaShiftKeyMask,156                       key.FUNCTION : NSFunctionKeyMask }157        symbol = getSymbol(nsevent)158        # Ignore this event if symbol is not a modifier key.  We must check this159        # because e.g., we receive a flagsChanged message when using CMD-tab to160        # switch applications, with symbol == "a" when command key is released.161        if symbol not in maskForKey: 162            return163        modifiers = getModifiers(nsevent)164        modifierFlags = nsevent.modifierFlags()165        if symbol and modifierFlags & maskForKey[symbol]:166            self._window.dispatch_event('on_key_press', symbol, modifiers)167        else:168            self._window.dispatch_event('on_key_release', symbol, modifiers)169    # Overriding this method helps prevent system beeps for unhandled events.170    @PygletView.method('B@')171    def performKeyEquivalent_(self, nsevent):172        # Let arrow keys and certain function keys pass through the responder173        # chain so that the textview can handle on_text_motion events.174        modifierFlags = nsevent.modifierFlags()175        if modifierFlags & NSNumericPadKeyMask:176            return False177        if modifierFlags & NSFunctionKeyMask:178            ch = cfstring_to_string(nsevent.charactersIgnoringModifiers())179            if ch in (NSHomeFunctionKey, NSEndFunctionKey, 180                      NSPageUpFunctionKey, NSPageDownFunctionKey):181                return False182        # Send the key equivalent to the main menu to perform menu items.183        NSApp = ObjCClass('NSApplication').sharedApplication()184        NSApp.mainMenu().performKeyEquivalent_(nsevent)185        # Indicate that we've handled the event so system won't beep.186        return True187    @PygletView.method('v@')188    def mouseMoved_(self, nsevent):189        if self._window._mouse_ignore_motion:190            self._window._mouse_ignore_motion = False191            return192        # Don't send on_mouse_motion events if we're not inside the content rectangle.193        if not self._window._mouse_in_window:194            return195        x, y = getMousePosition(self, nsevent)196        dx, dy = getMouseDelta(nsevent)197        self._window.dispatch_event('on_mouse_motion', x, y, dx, dy)198    199    @PygletView.method('v@')200    def scrollWheel_(self, nsevent):201        x, y = getMousePosition(self, nsevent)202        scroll_x, scroll_y = getMouseDelta(nsevent)203        self._window.dispatch_event('on_mouse_scroll', x, y, scroll_x, scroll_y)204    205    @PygletView.method('v@')206    def mouseDown_(self, nsevent):207        x, y = getMousePosition(self, nsevent)208        buttons = mouse.LEFT209        modifiers = getModifiers(nsevent)210        self._window.dispatch_event('on_mouse_press', x, y, buttons, modifiers)211    212    @PygletView.method('v@')213    def mouseDragged_(self, nsevent):214        x, y = getMousePosition(self, nsevent)215        dx, dy = getMouseDelta(nsevent)216        buttons = mouse.LEFT217        modifiers = getModifiers(nsevent)218        self._window.dispatch_event('on_mouse_drag', x, y, dx, dy, buttons, modifiers)219    @PygletView.method('v@')220    def mouseUp_(self, nsevent):221        x, y = getMousePosition(self, nsevent)222        buttons = mouse.LEFT223        modifiers = getModifiers(nsevent)224        self._window.dispatch_event('on_mouse_release', x, y, buttons, modifiers)225    226    @PygletView.method('v@')227    def rightMouseDown_(self, nsevent):228        x, y = getMousePosition(self, nsevent)229        buttons = mouse.RIGHT230        modifiers = getModifiers(nsevent)231        self._window.dispatch_event('on_mouse_press', x, y, buttons, modifiers)232    233    @PygletView.method('v@')234    def rightMouseDragged_(self, nsevent):235        x, y = getMousePosition(self, nsevent)236        dx, dy = getMouseDelta(nsevent)237        buttons = mouse.RIGHT238        modifiers = getModifiers(nsevent)239        self._window.dispatch_event('on_mouse_drag', x, y, dx, dy, buttons, modifiers)240    241    @PygletView.method('v@')242    def rightMouseUp_(self, nsevent):243        x, y = getMousePosition(self, nsevent)244        buttons = mouse.RIGHT245        modifiers = getModifiers(nsevent)246        self._window.dispatch_event('on_mouse_release', x, y, buttons, modifiers)247    248    @PygletView.method('v@')249    def otherMouseDown_(self, nsevent):250        x, y = getMousePosition(self, nsevent)251        buttons = mouse.MIDDLE252        modifiers = getModifiers(nsevent)253        self._window.dispatch_event('on_mouse_press', x, y, buttons, modifiers)254    255    @PygletView.method('v@')256    def otherMouseDragged_(self, nsevent):257        x, y = getMousePosition(self, nsevent)258        dx, dy = getMouseDelta(nsevent)259        buttons = mouse.MIDDLE260        modifiers = getModifiers(nsevent)261        self._window.dispatch_event('on_mouse_drag', x, y, dx, dy, buttons, modifiers)262    263    @PygletView.method('v@')264    def otherMouseUp_(self, nsevent):265        x, y = getMousePosition(self, nsevent)266        buttons = mouse.MIDDLE267        modifiers = getModifiers(nsevent)268        self._window.dispatch_event('on_mouse_release', x, y, buttons, modifiers)269    @PygletView.method('v@')270    def mouseEntered_(self, nsevent):271        x, y = getMousePosition(self, nsevent)272        self._window._mouse_in_window = True273        # Don't call self._window.set_mouse_platform_visible() from here.274        # Better to do it from cursorUpdate:275        self._window.dispatch_event('on_mouse_enter', x, y)276    @PygletView.method('v@')277    def mouseExited_(self, nsevent):278        x, y = getMousePosition(self, nsevent)279        self._window._mouse_in_window = False280        if not self._window._is_mouse_exclusive:281            self._window.set_mouse_platform_visible()282        self._window.dispatch_event('on_mouse_leave', x, y)283    @PygletView.method('v@')284    def cursorUpdate_(self, nsevent):285        # Called when mouse cursor enters view.  Unlike mouseEntered:,286        # this method will be called if the view appears underneath a287        # motionless mouse cursor, as can happen during window creation,288        # or when switching into fullscreen mode.  289        # BUG: If the mouse enters the window via the resize control at the290        # the bottom right corner, the resize control will set the cursor291        # to the default arrow and screw up our cursor tracking.292        self._window._mouse_in_window = True293        if not self._window._is_mouse_exclusive:294            self._window.set_mouse_platform_visible()..._mouse_tests.py
Source:_mouse_tests.py  
2import unittest3import time4from ._mouse_event import MoveEvent, ButtonEvent, WheelEvent, LEFT, RIGHT, MIDDLE, X, X2, UP, DOWN, DOUBLE5from keyboard import mouse6class FakeOsMouse(object):7    def __init__(self):8        self.append = None9        self.position = (0, 0)10        self.queue = None11        self.init = lambda: None12    def listen(self, queue):13        self.listening = True14        self.queue = queue15    def press(self, button):16        self.append((DOWN, button))17    def release(self, button):18        self.append((UP, button))19    def get_position(self):20        return self.position21    def move_to(self, x, y):22        self.append(('move', (x, y)))23        self.position = (x, y)24    def wheel(self, delta):25        self.append(('wheel', delta))26    def move_relative(self, x, y):27        self.position = (self.position[0] + x, self.position[1] + y)28class TestMouse(unittest.TestCase):29    @staticmethod30    def setUpClass():31        mouse._os_mouse= FakeOsMouse()32        mouse._listener.start_if_necessary()33        assert mouse._os_mouse.listening34    def setUp(self):35        self.events = []36        mouse._pressed_events.clear()37        mouse._os_mouse.append = self.events.append38    def tearDown(self):39        mouse.unhook_all()40        # Make sure there's no spill over between tests.41        self.wait_for_events_queue()42    def wait_for_events_queue(self):43        mouse._listener.queue.join()44    def flush_events(self):45        self.wait_for_events_queue()...mouse_test.py
Source:mouse_test.py  
1import unittest2class MouseModuleTest(unittest.TestCase):3    def todo_test_get_cursor(self):4        # __doc__ (as of 2008-08-02) for pygame.mouse.get_cursor:5          # pygame.mouse.get_cursor(): return (size, hotspot, xormasks, andmasks)6          # get the image for the system mouse cursor7          #8          # Get the information about the mouse system cursor. The return value9          # is the same data as the arguments passed into10          # pygame.mouse.set_cursor().11          #12        self.fail()13    def todo_test_get_focused(self):14        # __doc__ (as of 2008-08-02) for pygame.mouse.get_focused:15          # pygame.mouse.get_focused(): return bool16          # check if the display is receiving mouse input17          #18          # Returns true when pygame is receiving mouse input events (or, in19          # windowing terminology, is "active" or has the "focus").20          #21          # This method is most useful when working in a window. By contrast, in22          # full-screen mode, this method always returns true.23          #24          # Note: under MS Windows, the window that has the mouse focus also has25          # the keyboard focus. But under X-Windows, one window can receive26          # mouse events and another receive keyboard events.27          # pygame.mouse.get_focused() indicates whether the pygame window28          # receives mouse events.29          #30        self.fail()31    def todo_test_get_pos(self):32        # __doc__ (as of 2008-08-02) for pygame.mouse.get_pos:33          # pygame.mouse.get_pos(): return (x, y)34          # get the mouse cursor position35          #36          # Returns the X and Y position of the mouse cursor. The position is37          # relative the the top-left corner of the display. The cursor position38          # can be located outside of the display window, but is always39          # constrained to the screen.40          #41        self.fail()42    def todo_test_get_pressed(self):43        # __doc__ (as of 2008-08-02) for pygame.mouse.get_pressed:44          # pygame.moouse.get_pressed(): return (button1, button2, button3)45          # get the state of the mouse buttons46          #47          # Returns a sequence of booleans representing the state of all the48          # mouse buttons. A true value means the mouse is currently being49          # pressed at the time of the call.50          #51          # Note, to get all of the mouse events it is better to use either52          #  pygame.event.wait() or pygame.event.get() and check all of those events53          # to see if they are MOUSEBUTTONDOWN, MOUSEBUTTONUP, or MOUSEMOTION.54          # Note, that on X11 some XServers use middle button emulation.  When55          # you click both buttons 1 and 3 at the same time a 2 button event can56          # be emitted.57          #58          # Note, remember to call pygame.event.get() before this function.59          # Otherwise it will not work.60          #61        self.fail()62    def todo_test_get_rel(self):63        # __doc__ (as of 2008-08-02) for pygame.mouse.get_rel:64          # pygame.mouse.get_rel(): return (x, y)65          # get the amount of mouse movement66          #67          # Returns the amount of movement in X and Y since the previous call to68          # this function. The relative movement of the mouse cursor is69          # constrained to the edges of the screen, but see the virtual input70          # mouse mode for a way around this.  Virtual input mode is described71          # at the top of the page.72          #73        self.fail()74    def todo_test_set_cursor(self):75        # __doc__ (as of 2008-08-02) for pygame.mouse.set_cursor:76          # pygame.mouse.set_cursor(size, hotspot, xormasks, andmasks): return None77          # set the image for the system mouse cursor78          #79          # When the mouse cursor is visible, it will be displayed as a black80          # and white bitmap using the given bitmask arrays. The size is a81          # sequence containing the cursor width and height. Hotspot is a82          # sequence containing the cursor hotspot position. xormasks is a83          # sequence of bytes containing the cursor xor data masks. Lastly is84          # andmasks, a sequence of bytes containting the cursor bitmask data.85          #86          # Width must be a multiple of 8, and the mask arrays must be the87          # correct size for the given width and height. Otherwise an exception88          # is raised.89          #90          # See the pygame.cursor module for help creating default and custom91          # masks for the system cursor.92          #93        self.fail()94    def todo_test_set_pos(self):95        # __doc__ (as of 2008-08-02) for pygame.mouse.set_pos:96          # pygame.mouse.set_pos([x, y]): return None97          # set the mouse cursor position98          #99          # Set the current mouse position to arguments given. If the mouse100          # cursor is visible it will jump to the new coordinates. Moving the101          # mouse will generate a new pygaqme.MOUSEMOTION event.102          #103        self.fail()104    def todo_test_set_visible(self):105        # __doc__ (as of 2008-08-02) for pygame.mouse.set_visible:106          # pygame.mouse.set_visible(bool): return bool107          # hide or show the mouse cursor108          #109          # If the bool argument is true, the mouse cursor will be visible. This110          # will return the previous visible state of the cursor.111          #112        self.fail()113################################################################################114if __name__ == '__main__':...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
