diff --git a/kmk/handlers/layers.py b/kmk/handlers/layers.py index d436318..06a193f 100644 --- a/kmk/handlers/layers.py +++ b/kmk/handlers/layers.py @@ -3,24 +3,31 @@ from kmk.kmktime import ticks_diff, ticks_ms def df_pressed(key, state, *args, **kwargs): """Switches the default layer""" - state.active_layers[0] = key.meta.layer - state.reversed_active_layers = list(reversed(state.active_layers)) + state.active_layers[-1] = key.meta.layer return state def mo_pressed(key, state, *args, **kwargs): """Momentarily activates layer, switches off when you let go""" - state.active_layers.append(key.meta.layer) - state.reversed_active_layers = list(reversed(state.active_layers)) + state.active_layers.insert(0, key.meta.layer) return state def mo_released(key, state, KC, *args, **kwargs): - state.active_layers = [ - layer for layer in state.active_layers - if layer != key.meta.layer - ] - state.reversed_active_layers = list(reversed(state.active_layers)) + # remove the first instance of the target layer + # from the active list + # under almost all normal use cases, this will + # disable the layer (but preserve it if it was triggered + # as a default layer, etc.) + # this also resolves an issue where using DF() on a layer + # triggered by MO() and then defaulting to the MO()'s layer + # would result in no layers active + try: + del_idx = state.active_layers.index(key.meta.layer) + del state.active_layers[del_idx] + except ValueError: + pass + return state @@ -62,23 +69,21 @@ def lt_released(key, state, *args, **kwargs): def tg_pressed(key, state, *args, **kwargs): """Toggles the layer (enables it if not active, and vise versa)""" - if key.meta.layer in state.active_layers: - state.active_layers = [ - layer for layer in state.active_layers - if layer != key.meta.layer - ] - else: - state.active_layers.append(key.meta.layer) - state.reversed_active_layers = list(reversed(state.active_layers)) + # See mo_released for implementation details around this + try: + del_idx = state.active_layers.index(key.meta.layer) + del state.active_layers[del_idx] + except ValueError: + state.active_layers.insert(0, key.meta.layer) return state def to_pressed(key, state, *args, **kwargs): """Activates layer and deactivates all other layers""" - state.active_layers = [key.meta.layer] - state.reversed_active_layers = list(reversed(state.active_layers)) + state.active_layers.clear() + state.active_layers.insert(0, key.meta.layer) return state diff --git a/kmk/internal_state.py b/kmk/internal_state.py index 8212cbc..292ff11 100644 --- a/kmk/internal_state.py +++ b/kmk/internal_state.py @@ -12,8 +12,12 @@ class InternalState: leader_last_len = 0 hid_pending = False leader_mode_history = [] + + # this should almost always be PREpended to, replaces + # former use of reversed_active_layers which had pointless + # overhead (the underlying list was never used anyway) active_layers = [0] - reversed_active_layers = list(reversed(active_layers)) + start_time = { 'lt': None, 'tg': None, @@ -39,7 +43,6 @@ class InternalState: 'hid_pending={} ' 'leader_mode_history={} ' 'active_layers={} ' - 'reversed_active_layers={} ' 'start_time={} ' 'timeouts={} ' 'tapping={} ' @@ -54,7 +57,6 @@ class InternalState: self.hid_pending, self.leader_mode_history, self.active_layers, - self.reversed_active_layers, self.start_time, self.timeouts, self.tapping, @@ -79,9 +81,7 @@ class InternalState: return None - # Later-added layers have priority. Sift through the layers - # in reverse order until we find a valid keycode object - for layer in self.reversed_active_layers: + for layer in self.active_layers: layer_key = self.config.keymap[layer][idx] if not layer_key or layer_key == KC.TRNS: