Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,18 @@ def get_device_handle(keyboard_name: str) -> libevdev.Device:
finally:
fd.close()


def parse_keys(keys_str):
"""Parse a comma-separated list of keys into a list of integers."""
return [key.strip() for key in keys_str.split(',')]

if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('-k', '--keyboard', type=str, default=str(),
help=f"Name of your chattering keyboard device as listed in {INPUT_DEVICES_PATH}. "
f"If left unset, will be attempted to be retrieved automatically.")
parser.add_argument('-t', '--threshold', type=int, default=30, help="Filter time threshold in milliseconds. "
"Default=30ms.")
parser.add_argument('--keys', type=parse_keys, default=[], help="Comma-separated list of keys to filter. Default All. e.g KEY_A,KEY_B")
parser.add_argument('-v', '--verbosity', type=int, default=1, choices=[0, 1, 2])
args = parser.parse_args()

Expand All @@ -46,5 +50,8 @@ def get_device_handle(keyboard_name: str) -> libevdev.Device:
datefmt="%H:%M:%S"
)

# Convert them to libevdev.EventCode
keys = [libevdev.evbit(key) for key in args.keys]

with get_device_handle(args.keyboard or retrieve_keyboard_name()) as device:
filter_chattering(device, args.threshold)
filter_chattering(device, args.threshold, keys)
10 changes: 7 additions & 3 deletions src/filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import libevdev


def filter_chattering(evdev: libevdev.Device, threshold: int) -> NoReturn:
def filter_chattering(evdev: libevdev.Device, threshold: int, keys:libevdev.EventCode) -> NoReturn:
# grab the device - now only we see the events it emits
evdev.grab()
# create a copy of the device that we can write to - this will emit the filtered events to anyone who listens
Expand All @@ -16,18 +16,22 @@ def filter_chattering(evdev: libevdev.Device, threshold: int) -> NoReturn:
while True:
# since the descriptor is blocking, this blocks until there are events available
for e in evdev.events():
if _from_keystroke(e, threshold):
if _from_keystroke(e, threshold, keys):
ui_dev.send_events([e, libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0)])


def _from_keystroke(event: libevdev.InputEvent, threshold: int) -> bool:
def _from_keystroke(event: libevdev.InputEvent, threshold: int, keys:libevdev.EventCode) -> bool:
# no need to relay those - we are going to emit our own
if event.matches(libevdev.EV_SYN) or event.matches(libevdev.EV_MSC):
return False

# some events we don't want to filter, like EV_LED for toggling NumLock and the like, and also key hold events
if not event.matches(libevdev.EV_KEY) or event.value > 1:
logging.debug(f'FORWARDING {event.code}')

# If the event is not in the list of keys to filter, return True
if event.code not in keys:
logging.debug(f'Skipping {event.code} since it is not requested by user')
return True

# the values are 0 for up, 1 for down and 2 for hold
Expand Down