some fixes for gamepads

pull/14/head
sezanzeb 4 years ago
parent 56b6573d42
commit 1d3a58553d

@ -98,15 +98,14 @@ def ensure_numlock(func):
def is_in_capabilities(key, capabilities):
"""Are this key or all of its sub keys in the capabilities?"""
if isinstance(key[0], tuple):
# it's a key combination
for sub_key in key:
if is_in_capabilities(sub_key, capabilities):
return True
else:
ev_type, code, _ = key
if code in capabilities.get(ev_type, []):
"""Are this key or one of its sub keys in the capabilities?
Parameters
----------
key : Key
"""
for sub_key in key:
if sub_key[1] in capabilities.get(sub_key[0], []):
return True
return False
@ -285,7 +284,7 @@ class KeycodeInjector:
if ecodes.BTN_MOUSE not in capabilities[EV_KEY]:
# to be able to move the cursor, this key capability is
# needed
capabilities[EV_KEY] = [ecodes.BTN_MOUSE]
capabilities[EV_KEY].append(ecodes.BTN_MOUSE)
# just like what python-evdev does in from_device
if ecodes.EV_SYN in capabilities:

@ -223,7 +223,10 @@ class _KeycodeReader:
if event.value == 0:
if without_value in self._unreleased:
del self._unreleased[without_value]
continue
if without_value in self._unreleased:
# no duplicate down events (gamepad triggers)
continue
self._unreleased[without_value] = (

@ -253,10 +253,11 @@ class Row(Gtk.ListBoxRow):
self.keycode_input.set_label(label)
# make the child label widget break lines, important for
# long combinations
self.keycode_input.get_child().set_line_wrap(True)
self.keycode_input.get_child().set_line_wrap_mode(2)
self.keycode_input.get_child().set_max_width_chars(15)
self.keycode_input.get_child().set_justify(Gtk.Justification.CENTER)
label = self.keycode_input.get_child()
label.set_line_wrap(True)
label.set_line_wrap_mode(2)
label.set_max_width_chars(13)
label.set_justify(Gtk.Justification.CENTER)
def put_together(self, character):
"""Create all child GTK widgets and connect their signals."""

@ -348,7 +348,12 @@ class Window:
# the "event" event of Gtk.Window wouldn't trigger on gamepad
# events, so it became a GLib timeout to periodically check kernel
# events.
# letting go of one of the keys of a combination won't just make
# it return the leftover key, it will continue to return None because
# they have already been read.
key = keycode_reader.read()
key and print(key)
if isinstance(focused, Gtk.ToggleButton):
if not keycode_reader.are_keys_pressed():

@ -98,6 +98,7 @@ class Key:
return hash(self.keys)
def __eq__(self, other):
print(self, 'eq', other)
if isinstance(other, tuple):
if isinstance(other[0], tuple):
# a combination ((1, 5, 1), (1, 3, 1))

@ -95,23 +95,34 @@ class TestInjector(unittest.TestCase):
self.injector = KeycodeInjector('foo', mapping)
fake_device = FakeDevice()
capabilities = self.injector._modify_capabilities(
capabilities_1 = self.injector._modify_capabilities(
{60: macro},
fake_device,
abs_to_rel=False
)
self.assertIn(EV_KEY, capabilities)
keys = capabilities[EV_KEY]
self.assertIn(EV_KEY, capabilities_1)
keys = capabilities_1[EV_KEY]
self.assertIn(a, keys)
self.assertIn(one, keys)
self.assertIn(two, keys)
self.assertIn(shift_l, keys)
self.assertNotIn(evdev.ecodes.EV_SYN, capabilities)
self.assertNotIn(evdev.ecodes.EV_FF, capabilities)
self.assertNotIn(evdev.ecodes.EV_REL, capabilities)
self.assertNotIn(evdev.ecodes.EV_ABS, capabilities)
self.assertNotIn(evdev.ecodes.EV_SYN, capabilities_1)
self.assertNotIn(evdev.ecodes.EV_FF, capabilities_1)
self.assertNotIn(evdev.ecodes.EV_REL, capabilities_1)
self.assertNotIn(evdev.ecodes.EV_ABS, capabilities_1)
capabilities_2 = self.injector._modify_capabilities(
{60: macro},
fake_device,
abs_to_rel=True
)
keys = capabilities_2[EV_KEY]
self.assertIn(a, keys)
self.assertIn(one, keys)
self.assertIn(two, keys)
self.assertIn(shift_l, keys)
def test_grab(self):
# path is from the fixtures
@ -485,13 +496,13 @@ class TestInjector(unittest.TestCase):
self.assertEqual(len(injector._key_to_code), 3)
def test_is_in_capabilities(self):
key = (1, 2, 1)
key = Key(1, 2, 1)
capabilities = {
1: [9, 2, 5]
}
self.assertTrue(is_in_capabilities(key, capabilities))
key = ((1, 2, 1), (1, 3, 1))
key = Key((1, 2, 1), (1, 3, 1))
capabilities = {
1: [9, 2, 5]
}
@ -500,7 +511,7 @@ class TestInjector(unittest.TestCase):
# that make up one hardware device
self.assertTrue(is_in_capabilities(key, capabilities))
key = ((1, 2, 1), (1, 5, 1))
key = Key((1, 2, 1), (1, 5, 1))
capabilities = {
1: [9, 2, 5]
}

@ -21,9 +21,10 @@
import unittest
import time
import multiprocessing
from evdev.ecodes import EV_KEY, EV_ABS, ABS_HAT0X, ABS_HAT0Y, KEY_COMMA, \
BTN_LEFT, BTN_TOOL_DOUBLETAP
BTN_LEFT, BTN_TOOL_DOUBLETAP, ABS_Z
from keymapper.dev.reader import keycode_reader
@ -127,6 +128,20 @@ class TestReader(unittest.TestCase):
self.assertEqual(keycode_reader.read(), None)
self.assertEqual(len(keycode_reader._unreleased), 1)
def test_reading_ignore_duplicate_down(self):
pipe = multiprocessing.Pipe()
pipe[1].send(InputEvent(EV_ABS, ABS_Z, 1, 10))
keycode_reader._pipe = pipe
self.assertEqual(keycode_reader.read(), (EV_ABS, ABS_Z, 1))
self.assertEqual(keycode_reader.read(), None)
pipe[1].send(InputEvent(EV_ABS, ABS_Z, 1, 10))
# still none
self.assertEqual(keycode_reader.read(), None)
self.assertEqual(len(keycode_reader._unreleased), 1)
def test_wrong_device(self):
pending_events['device 1'] = [
InputEvent(EV_KEY, CODE_1, 1),

Loading…
Cancel
Save