Created
September 27, 2019 07:56
-
-
Save Versatilus/ebbd8ccc00be35b02f2200255edf2d70 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import print_function, unicode_literals | |
from ctypes import windll | |
from dragonfly import (ActionBase, Choice, Grammar, IntegerRef, Key, | |
MappingRule, Mouse, Pause, Repeat) | |
from dragonfly.actions.keyboard import Keyboard, KeySymbols | |
KEYBOARD = Keyboard() | |
GET_ASYNC_KEY_STATE = windll.user32.GetAsyncKeyState | |
class ModifierAction(ActionBase): | |
""" | |
Wrap arbitrary actions within keyboard presses. | |
Currently Windows-only. | |
""" | |
def __init__(self, action, modifiers=None): | |
""" | |
Set `Action` instance to execute and prime modifiers list. | |
`modifiers` must be a sequence of valid Windows keyboard codes. | |
""" | |
super(ModifierAction, self).__init__() | |
self.action = action | |
if not (isinstance(modifiers, (list, tuple)) or modifiers is None): | |
raise TypeError("`modifiers` must be a list, tuple, or `None`.") | |
self._modifiers = tuple(modifiers) if modifiers else [] | |
def _execute(self, data=None): | |
modifiers = list(self._modifiers) | |
for key, value in data.items(): | |
if "modifier_" in key: | |
modifiers.append(value) | |
# Only activate modifier keys which aren't currently being held down, | |
# the assumption being the keys are being held down for a reason. | |
modifiers_down = [(modifier, True, .1) | |
for modifier in modifiers | |
if GET_ASYNC_KEY_STATE(modifier) & 0x8000 == 0] | |
KEYBOARD.send_keyboard_events(modifiers_down) | |
self.action.execute(data) | |
# Similar to before, only release keys that are being held and | |
# we are responsible for pressing. | |
modifiers_up = [(modifier, False, .1) | |
for (modifier, i, j) in modifiers_down | |
if (GET_ASYNC_KEY_STATE(modifier) & 0x8000) != 0] | |
KEYBOARD.send_keyboard_events(modifiers_up) | |
GRAMMAR = Grammar("Modifier Action example") | |
SHIFT_KEY = KeySymbols.SHIFT | |
SUPER_KEY = KeySymbols.LSUPER | |
ALT_KEY = KeySymbols.ALT | |
CONTROL_KEY = KeySymbols.CONTROL | |
MODIFIERS = { | |
"[left] alt": ALT_KEY, | |
"[left] shift": SHIFT_KEY, | |
"[left] control": CONTROL_KEY, | |
"[left] (windows|super)": SUPER_KEY, | |
} | |
class ExampleRule(MappingRule): | |
mapping = { | |
"[<modifier_1>][<modifier_2>][<modifier_3>] extended <fkey>": | |
ModifierAction(Key("f%(fkey)d")), | |
"after [this] tab [<n>]": | |
ModifierAction(Key("tab/10:%(n)d"), modifiers=[CONTROL_KEY]), | |
"before [this] tab [<n>]": | |
ModifierAction( | |
Key("tab/10:%(n)d"), modifiers=[CONTROL_KEY, SHIFT_KEY]), | |
"[<modifier_1>][<modifier_2>][<modifier_3>] punch [<n>]": | |
ModifierAction( | |
(Mouse("left:down") + Pause("10") + Mouse("left:up") + | |
Pause("10")) * Repeat(extra="n")), | |
} | |
extras = [ | |
IntegerRef("n", 1, 10), | |
IntegerRef("fkey", 1, 25), | |
Choice("modifier_1", MODIFIERS), | |
Choice("modifier_2", MODIFIERS), | |
Choice("modifier_3", MODIFIERS), | |
] | |
defaults = {"n": 1} | |
GRAMMAR.add_rule(ExampleRule()) | |
GRAMMAR.load() | |
def unload(): | |
global GRAMMAR | |
if GRAMMAR: | |
GRAMMAR.unload() | |
GRAMMAR = None |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment