Skip to content

Commit

Permalink
Merge pull request #2 from quantumsnowball/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
quantumsnowball authored Jun 10, 2022
2 parents 939cbc1 + 0f89494 commit 84e925b
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 24 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
setup(
name='waylandmap',
packages=['waylandmap', ],
version='1.0.0',
version='1.0.1',
description='A keymapper that works under both X11 or Wayland',
long_description=long_description,
long_description_content_type='text/markdown',
Expand Down
3 changes: 3 additions & 0 deletions systemctl/waylandmap.service
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ After=multi-user.target
[Service]
Type=simple
Restart=always
RestartSec=5
ExecStart=/path/to/your/waylandmap -n <your-keyboard-name> /path/to/your/keymaps.yaml
User=root
Group=root

[Install]
WantedBy=multi-user.target
27 changes: 14 additions & 13 deletions waylandmap/filter.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from evdev.ecodes import EV_KEY
import yaml
from waylandmap.constants import name_to_code as ntc

Expand All @@ -13,32 +14,32 @@ def __init__(self, path: str):
for m in keymaps if m['type'] == 'map')
self._combo = tuple((ntc(m['modifier']), ntc(m['source']), ntc(m['target']))
for m in keymaps if m['type'] == 'combo')
self._on_mods = {k[0]:False for k in self._combo}
# self._mod_tree = { for c in self._combo}
d = {}
for c in self._combo:
pth = []
pth.append((c[1], c[2]))
d[c] = pth
# modifier keys states
self._on_modifier = {k[0]:False for k in self._combo}
# mapping path states
self._on_combo = {c:False for c in self._combo}

def target(self, type_in: int, code_in: int, value_in: int) -> tuple | None:
type_out, code_out, value_out = type_in, code_in, value_in
# only interested in key event, ignore sync event
if type_in == 1:
if type_in == EV_KEY:
# check if input is a modifier key
if code_in in self._on_mods:
if code_in in self._on_modifier:
# if confirm, change on_mods state
self._on_mods[code_in] = value_in >= 1
self._on_modifier[code_in] = value_in >= 1
# then issue discard signal
return None
# check all registered mods tree and trigger
for modifier, source, target in self._combo:
# check if modifier is on
if self._on_mods[modifier]:
for remap_path in self._combo:
modifier, source, target = remap_path
# check if modifier is on, or on_mapping flag is on
if self._on_modifier[modifier] or self._on_combo[remap_path]:
# check if key pressed matched source
if code_in == source:
# change output target accordingly
code_out = target
# mark remap path flag to on, only turn off upon key release event
self._on_combo[remap_path] = value_in >= 1
# only need to match the first path
break
# unless is a registered modifier key, always return a valid result
Expand Down
35 changes: 25 additions & 10 deletions waylandmap/keymapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,24 @@
from waylandmap.devices import get_device_path


def log_input_output(input, output=None):
type_in, code_in, value_in = input
name_in = code_to_name(code_in) if type_in == 1 else ''
if output is not None:
(type_out, code_out), value_out = output
name_out = code_to_name(code_out) if type_out == 1 else ''
else:
# if discarded by filter
name_out = type_out = code_out = value_out = ''
# log
if type_in == 0:
logging.info('\t---- SYNC_REPORT ----')
else:
logging.info((
f'\tIN: ({name_in:>15},T={type_in:1},C={code_in:3},V={value_in:6}), '
f'\tOUT: ({name_out:>15},T={type_out:1},C={code_out:3},V={value_out:6})'))


def infinite_retry(sleep, catch):
def wrapper(func):
def wrapped(*args, **kwargs):
Expand Down Expand Up @@ -36,22 +54,19 @@ def run(dev_name, keymaps):
# loop to capture every event
for ev in kb.read_loop():
# each event represented by three ints
type_in, code_in, value_in = ev.type, ev.code, ev.value
type_in, code_in, value_in = input = ev.type, ev.code, ev.value
# ask filter to for correct mapping
result = filter.target(type_in, code_in, value_in)
output = filter.target(type_in, code_in, value_in)
# this key is a registered modifier key
if result is None:
if output is None:
# drop the event and move on to next
log_input_output(input)
continue
# emit the event to OS
vdev.emit(*result)
vdev.emit(*output)
# log
(type_out, code_out), value_out = result
name_in = code_to_name(code_in) if type_in == 1 else ''
name_out = code_to_name(code_out) if type_out == 1 else ''
logging.info((
f'\tIN: ({name_in:>15},T={type_in:1},C={code_in:3},V={value_in:6}), '
f'\tOUT: ({name_out:>15},T={type_out:1},C={code_out:3},V={value_out:6})'))
log_input_output(input, output)

except KeyboardInterrupt:
kb.ungrab()
logging.error('User keyboard interrupted, quitting now.')
Expand Down

0 comments on commit 84e925b

Please sign in to comment.