mirror of
https://github.com/sezanzeb/input-remapper
synced 2024-11-08 07:10:36 +00:00
some fixes for gamepads
This commit is contained in:
parent
56b6573d42
commit
1d3a58553d
@ -98,15 +98,14 @@ def ensure_numlock(func):
|
|||||||
|
|
||||||
|
|
||||||
def is_in_capabilities(key, capabilities):
|
def is_in_capabilities(key, capabilities):
|
||||||
"""Are this key or all of its sub keys in the capabilities?"""
|
"""Are this key or one of its sub keys in the capabilities?
|
||||||
if isinstance(key[0], tuple):
|
|
||||||
# it's a key combination
|
Parameters
|
||||||
|
----------
|
||||||
|
key : Key
|
||||||
|
"""
|
||||||
for sub_key in key:
|
for sub_key in key:
|
||||||
if is_in_capabilities(sub_key, capabilities):
|
if sub_key[1] in capabilities.get(sub_key[0], []):
|
||||||
return True
|
|
||||||
else:
|
|
||||||
ev_type, code, _ = key
|
|
||||||
if code in capabilities.get(ev_type, []):
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
@ -285,7 +284,7 @@ class KeycodeInjector:
|
|||||||
if ecodes.BTN_MOUSE not in capabilities[EV_KEY]:
|
if ecodes.BTN_MOUSE not in capabilities[EV_KEY]:
|
||||||
# to be able to move the cursor, this key capability is
|
# to be able to move the cursor, this key capability is
|
||||||
# needed
|
# needed
|
||||||
capabilities[EV_KEY] = [ecodes.BTN_MOUSE]
|
capabilities[EV_KEY].append(ecodes.BTN_MOUSE)
|
||||||
|
|
||||||
# just like what python-evdev does in from_device
|
# just like what python-evdev does in from_device
|
||||||
if ecodes.EV_SYN in capabilities:
|
if ecodes.EV_SYN in capabilities:
|
||||||
|
@ -223,7 +223,10 @@ class _KeycodeReader:
|
|||||||
if event.value == 0:
|
if event.value == 0:
|
||||||
if without_value in self._unreleased:
|
if without_value in self._unreleased:
|
||||||
del self._unreleased[without_value]
|
del self._unreleased[without_value]
|
||||||
|
continue
|
||||||
|
|
||||||
|
if without_value in self._unreleased:
|
||||||
|
# no duplicate down events (gamepad triggers)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self._unreleased[without_value] = (
|
self._unreleased[without_value] = (
|
||||||
|
@ -253,10 +253,11 @@ class Row(Gtk.ListBoxRow):
|
|||||||
self.keycode_input.set_label(label)
|
self.keycode_input.set_label(label)
|
||||||
# make the child label widget break lines, important for
|
# make the child label widget break lines, important for
|
||||||
# long combinations
|
# long combinations
|
||||||
self.keycode_input.get_child().set_line_wrap(True)
|
label = self.keycode_input.get_child()
|
||||||
self.keycode_input.get_child().set_line_wrap_mode(2)
|
label.set_line_wrap(True)
|
||||||
self.keycode_input.get_child().set_max_width_chars(15)
|
label.set_line_wrap_mode(2)
|
||||||
self.keycode_input.get_child().set_justify(Gtk.Justification.CENTER)
|
label.set_max_width_chars(13)
|
||||||
|
label.set_justify(Gtk.Justification.CENTER)
|
||||||
|
|
||||||
def put_together(self, character):
|
def put_together(self, character):
|
||||||
"""Create all child GTK widgets and connect their signals."""
|
"""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
|
# the "event" event of Gtk.Window wouldn't trigger on gamepad
|
||||||
# events, so it became a GLib timeout to periodically check kernel
|
# events, so it became a GLib timeout to periodically check kernel
|
||||||
# events.
|
# 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 = keycode_reader.read()
|
||||||
|
key and print(key)
|
||||||
|
|
||||||
if isinstance(focused, Gtk.ToggleButton):
|
if isinstance(focused, Gtk.ToggleButton):
|
||||||
if not keycode_reader.are_keys_pressed():
|
if not keycode_reader.are_keys_pressed():
|
||||||
|
@ -98,6 +98,7 @@ class Key:
|
|||||||
return hash(self.keys)
|
return hash(self.keys)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
|
print(self, 'eq', other)
|
||||||
if isinstance(other, tuple):
|
if isinstance(other, tuple):
|
||||||
if isinstance(other[0], tuple):
|
if isinstance(other[0], tuple):
|
||||||
# a combination ((1, 5, 1), (1, 3, 1))
|
# a combination ((1, 5, 1), (1, 3, 1))
|
||||||
|
@ -95,23 +95,34 @@ class TestInjector(unittest.TestCase):
|
|||||||
|
|
||||||
self.injector = KeycodeInjector('foo', mapping)
|
self.injector = KeycodeInjector('foo', mapping)
|
||||||
fake_device = FakeDevice()
|
fake_device = FakeDevice()
|
||||||
capabilities = self.injector._modify_capabilities(
|
capabilities_1 = self.injector._modify_capabilities(
|
||||||
{60: macro},
|
{60: macro},
|
||||||
fake_device,
|
fake_device,
|
||||||
abs_to_rel=False
|
abs_to_rel=False
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertIn(EV_KEY, capabilities)
|
self.assertIn(EV_KEY, capabilities_1)
|
||||||
keys = capabilities[EV_KEY]
|
keys = capabilities_1[EV_KEY]
|
||||||
self.assertIn(a, keys)
|
self.assertIn(a, keys)
|
||||||
self.assertIn(one, keys)
|
self.assertIn(one, keys)
|
||||||
self.assertIn(two, keys)
|
self.assertIn(two, keys)
|
||||||
self.assertIn(shift_l, keys)
|
self.assertIn(shift_l, keys)
|
||||||
|
|
||||||
self.assertNotIn(evdev.ecodes.EV_SYN, capabilities)
|
self.assertNotIn(evdev.ecodes.EV_SYN, capabilities_1)
|
||||||
self.assertNotIn(evdev.ecodes.EV_FF, capabilities)
|
self.assertNotIn(evdev.ecodes.EV_FF, capabilities_1)
|
||||||
self.assertNotIn(evdev.ecodes.EV_REL, capabilities)
|
self.assertNotIn(evdev.ecodes.EV_REL, capabilities_1)
|
||||||
self.assertNotIn(evdev.ecodes.EV_ABS, capabilities)
|
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):
|
def test_grab(self):
|
||||||
# path is from the fixtures
|
# path is from the fixtures
|
||||||
@ -485,13 +496,13 @@ class TestInjector(unittest.TestCase):
|
|||||||
self.assertEqual(len(injector._key_to_code), 3)
|
self.assertEqual(len(injector._key_to_code), 3)
|
||||||
|
|
||||||
def test_is_in_capabilities(self):
|
def test_is_in_capabilities(self):
|
||||||
key = (1, 2, 1)
|
key = Key(1, 2, 1)
|
||||||
capabilities = {
|
capabilities = {
|
||||||
1: [9, 2, 5]
|
1: [9, 2, 5]
|
||||||
}
|
}
|
||||||
self.assertTrue(is_in_capabilities(key, capabilities))
|
self.assertTrue(is_in_capabilities(key, capabilities))
|
||||||
|
|
||||||
key = ((1, 2, 1), (1, 3, 1))
|
key = Key((1, 2, 1), (1, 3, 1))
|
||||||
capabilities = {
|
capabilities = {
|
||||||
1: [9, 2, 5]
|
1: [9, 2, 5]
|
||||||
}
|
}
|
||||||
@ -500,7 +511,7 @@ class TestInjector(unittest.TestCase):
|
|||||||
# that make up one hardware device
|
# that make up one hardware device
|
||||||
self.assertTrue(is_in_capabilities(key, capabilities))
|
self.assertTrue(is_in_capabilities(key, capabilities))
|
||||||
|
|
||||||
key = ((1, 2, 1), (1, 5, 1))
|
key = Key((1, 2, 1), (1, 5, 1))
|
||||||
capabilities = {
|
capabilities = {
|
||||||
1: [9, 2, 5]
|
1: [9, 2, 5]
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,10 @@
|
|||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
import time
|
import time
|
||||||
|
import multiprocessing
|
||||||
|
|
||||||
from evdev.ecodes import EV_KEY, EV_ABS, ABS_HAT0X, ABS_HAT0Y, KEY_COMMA, \
|
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
|
from keymapper.dev.reader import keycode_reader
|
||||||
|
|
||||||
@ -127,6 +128,20 @@ class TestReader(unittest.TestCase):
|
|||||||
self.assertEqual(keycode_reader.read(), None)
|
self.assertEqual(keycode_reader.read(), None)
|
||||||
self.assertEqual(len(keycode_reader._unreleased), 1)
|
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):
|
def test_wrong_device(self):
|
||||||
pending_events['device 1'] = [
|
pending_events['device 1'] = [
|
||||||
InputEvent(EV_KEY, CODE_1, 1),
|
InputEvent(EV_KEY, CODE_1, 1),
|
||||||
|
Loading…
Reference in New Issue
Block a user