diff --git a/action/action_type.py b/action/action_type.py index c6b85c8..5fedb74 100644 --- a/action/action_type.py +++ b/action/action_type.py @@ -2,6 +2,7 @@ class ActionType(Enum): - ModifiedKeyAction = 1 + ModKeyAction = 1 ModTapAction = 2 LayerOnAction = 3 + LayerModAction = 4 diff --git a/action/layer_mod_action.py b/action/layer_mod_action.py new file mode 100644 index 0000000..450e003 --- /dev/null +++ b/action/layer_mod_action.py @@ -0,0 +1,33 @@ +from typing import Tuple + +from evdev.events import KeyEvent + +import host +import mapper +from action.action_type import ActionType +from action.mod_key_action import ModKeyAction +from log import debug + + +class LayerModAction: + type: ActionType + layer: int + modifiers: Tuple[int, ...] + + def __init__(self, layer, *modifiers): + self.type = ActionType.LayerOnAction + self.layer = layer + self.modifiers = modifiers + + def handle(self, ui, e, config, *args): + debug('-- handling layer mod action --') + for m in self.modifiers: + host.write_code(ui, m, e.value) + if e.value == KeyEvent.key_down: + mapper.enable_layer(self.layer, self, config) + else: + mapper.disable_layer(ui, self.layer, config) + + def handle_layer_key(self, ui, key, e, *args): + debug('-- handling LM layer key --') + ModKeyAction(key, *self.modifiers).handle(ui, e) diff --git a/action/layer_on_action.py b/action/layer_on_action.py index c117926..c0d04fc 100644 --- a/action/layer_on_action.py +++ b/action/layer_on_action.py @@ -13,9 +13,9 @@ def __init__(self, layer): self.type = ActionType.LayerOnAction self.layer = layer - def handle(self, _, e, *args): + def handle(self, ui, e, config, *args): debug('-- handling layer on action --') if e.value == KeyEvent.key_up: - mapper.enable_layer(self.layer) + mapper.enable_layer(self.layer, self, config) else: - mapper.disable_layer(self.layer) + mapper.disable_layer(ui, self.layer, config) diff --git a/action/modified_key_action.py b/action/mod_key_action.py similarity index 84% rename from action/modified_key_action.py rename to action/mod_key_action.py index 50f40e0..9f9c993 100644 --- a/action/modified_key_action.py +++ b/action/mod_key_action.py @@ -4,20 +4,21 @@ import host from action.action_type import ActionType +from log import debug -class ModifiedKeyAction: +class ModKeyAction: type: ActionType key: int modifiers: Tuple[int, ...] def __init__(self, key, *modifiers): - self.type = ActionType.ModifiedKeyAction + self.type = ActionType.ModKeyAction self.modifiers = modifiers self.key = key def handle(self, ui, e, *args): - debug('-- handling modified key action --') + debug('-- handling mod key action --') if e.value == KeyEvent.key_down: for m in self.modifiers: host.write_code(ui, m, e.value) diff --git a/example/config.py b/example/config.py index 0453d31..9d3ad66 100644 --- a/example/config.py +++ b/example/config.py @@ -1,13 +1,12 @@ from layout import * from key import * -T______ = KC_TRANSPARENT physical_layout = laptop keymaps = [ [ KC_ESC , KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 , KC_F11 , KC_F12 , KC_PSCR, KC_INS , KC_DEL , - KC_GRV , KC_2 , KC_1 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , KC_MINS, KC_EQL , KC_BSPC, + KC_GRV , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , KC_MINS, KC_EQL , KC_BSPC, KC_TAB , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , KC_LBRC, KC_RBRC, KC_BSLS, KC_CAPS, KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN, KC_QUOT, KC_ENT , KC_LSFT, KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM, KC_DOT , KC_SLSH, KC_RSFT, KC_UP , @@ -19,7 +18,7 @@ T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, - T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, + T______, T______, T______, T______, T______, T______, T______, T______, T______, T______, ] ] diff --git a/key.py b/key.py index a5f463e..fd178b0 100644 --- a/key.py +++ b/key.py @@ -1,8 +1,9 @@ from evdev.ecodes import * +from action.layer_mod_action import LayerModAction from action.layer_on_action import LayerOnAction +from action.mod_key_action import ModKeyAction from action.mod_tap_action import ModTapAction -from action.modified_key_action import ModifiedKeyAction # special keys @@ -525,75 +526,75 @@ # modifier key actions def MK(key, modifiers): - return ModifiedKeyAction(key, modifiers) + return ModKeyAction(key, modifiers) def LCTL(key): - return ModifiedKeyAction(key, KC_LCTL) + return ModKeyAction(key, KC_LCTL) def LSFT(key): - return ModifiedKeyAction(key, KC_LSFT) + return ModKeyAction(key, KC_LSFT) def LALT(key): - return ModifiedKeyAction(key, KC_LALT) + return ModKeyAction(key, KC_LALT) def LGUI(key): - return ModifiedKeyAction(key, KC_LGUI) + return ModKeyAction(key, KC_LGUI) def RCTL(key): - return ModifiedKeyAction(key, KC_RCTL) + return ModKeyAction(key, KC_RCTL) def RSFT(key): - return ModifiedKeyAction(key, KC_RSFT) + return ModKeyAction(key, KC_RSFT) def RALT(key): - return ModifiedKeyAction(key, KC_RALT) + return ModKeyAction(key, KC_RALT) def RGUI(key): - return ModifiedKeyAction(key, KC_RGUI) + return ModKeyAction(key, KC_RGUI) def SGUI(key): - return ModifiedKeyAction(key, KC_LSFT, KC_LGUI) + return ModKeyAction(key, KC_LSFT, KC_LGUI) def LCA(key): - return ModifiedKeyAction(key, KC_LCTL, KC_LALT) + return ModKeyAction(key, KC_LCTL, KC_LALT) def LSA(key): - return ModifiedKeyAction(key, KC_LSFT, KC_LALT) + return ModKeyAction(key, KC_LSFT, KC_LALT) def RSA(key): - return ModifiedKeyAction(key, KC_RSFT, KC_RALT) + return ModKeyAction(key, KC_RSFT, KC_RALT) def RCS(key): - return ModifiedKeyAction(key, KC_RCTL, KC_RSFT) + return ModKeyAction(key, KC_RCTL, KC_RSFT) def LCAG(key): - return ModifiedKeyAction(key, KC_LCTL, KC_LALT, KC_LGUI) + return ModKeyAction(key, KC_LCTL, KC_LALT, KC_LGUI) def MEH(key): - return ModifiedKeyAction(key, KC_LCTL, KC_LSHIFT, KC_LALT) + return ModKeyAction(key, KC_LCTL, KC_LSHIFT, KC_LALT) def HYPR(key): - return ModifiedKeyAction(key, KC_LCTL, KC_LSHIFT, KC_LALT, KC_LGUI) + return ModKeyAction(key, KC_LCTL, KC_LSHIFT, KC_LALT, KC_LGUI) -KC_MEH = ModifiedKeyAction(None, KC_LCTL, KC_LSHIFT, KC_LALT) -KC_HYPR = ModifiedKeyAction(None, KC_LCTL, KC_LSHIFT, KC_LALT, KC_LGUI) +KC_MEH = ModKeyAction(None, KC_LCTL, KC_LSHIFT, KC_LALT) +KC_HYPR = ModKeyAction(None, KC_LCTL, KC_LSHIFT, KC_LALT, KC_LGUI) C = LCTL S = LSFT @@ -700,3 +701,7 @@ def HYPR_T(key): def MO(layer): return LayerOnAction(layer) + + +def LM(layer, *modifiers): + return LayerModAction(layer, *modifiers) diff --git a/layer.py b/layer.py new file mode 100644 index 0000000..2496fe6 --- /dev/null +++ b/layer.py @@ -0,0 +1,10 @@ +from typing import List + + +class Layer: + keymap: List[int] + activator: object + + def __init__(self, keymap, activator): + self.keymap = keymap + self.activator = activator diff --git a/mapper.py b/mapper.py index 1c30fcb..3d59985 100644 --- a/mapper.py +++ b/mapper.py @@ -1,5 +1,6 @@ import importlib import importlib.util +from typing import List import click from evdev import UInput, ecodes @@ -8,11 +9,12 @@ import host import key import keyboard +from layer import Layer from log import debug -last_press_timestamps = [] -active_layers = [] -layers_keys_pressed = [] +last_press_timestamps: List[float] = [] +active_layers: List[Layer] = [] +layers_keys_pressed: List[List[int]] = [] def load_config(path): @@ -38,9 +40,9 @@ def map_device(config_path, kb_name, ui_name='kbmap'): global last_press_timestamps last_press_timestamps = [None for _ in range(len(config.physical_layout))] global active_layers - active_layers = [False for _ in range(len(config.keymaps))] + active_layers = [None for _ in range(len(config.keymaps))] # base layer is always active - active_layers[0] = True + active_layers[0] = Layer(config.keymaps[0], None) global layers_keys_pressed layers_keys_pressed = [[] for _ in range(len(active_layers))] for i in range(len(active_layers)): @@ -77,7 +79,7 @@ def handle_event(e, kb, ui, config): key.handle(ui, e, config, pos) else: debug(f'key is mapped to key: {ecodes.KEY[key]} ({key}) at {pos}') - host.write_code(ui, key, e.value) + write_key(ui, key, e, layer_index, config) update_timestamps(pos, e) @@ -115,12 +117,21 @@ def find_key(pos, config): return layer_key, layer_index -def enable_layer(layer): +def write_key(ui, key, e, layer, config): + global active_layers + active_layer = active_layers[layer] + if active_layer and active_layer.activator: + active_layer.activator.handle_layer_key(ui, key, e, config) + else: + host.write_code(ui, key, e.value) + + +def enable_layer(layer, activator, config): global active_layers - active_layers[layer] = True + active_layers[layer] = Layer(config.keymaps[layer], activator) -def disable_layer(layer): +def disable_layer(ui, layer, config): global active_layers - active_layers[layer] = False - host.release_layer_keys(ui, self.layer, config) + active_layers[layer] = None + host.release_layer_keys(ui, layer, config)