Support change-host notifications in rules

This commit is contained in:
dafik 2026-06-17 12:25:58 +02:00
parent dadecb772a
commit f8f6a24514
2 changed files with 40 additions and 0 deletions

View File

@ -47,6 +47,7 @@ else:
import evdev
from .common import NamedInt
from .hidpp20 import Hidpp20
from .hidpp20 import SupportedFeature
from .special_keys import CONTROL
@ -1304,6 +1305,11 @@ class Set(Action):
if setting is None:
logger.warning("Set action: setting %s is not the name of a setting for %s", self.args[1], dev.name)
return None
if setting.name == "change-host":
try:
Hidpp20().get_host_names(dev)
except Exception:
logger.debug("Set action: failed to refresh host names before change-host write", exc_info=True)
args = setting.acceptable(self.args[2:], setting.read())
if args is None:
logger.warning(
@ -1487,6 +1493,15 @@ def process_notification(device, notification: HIDPPNotification, feature) -> No
if notification.data[4] <= 0x01: # when wheel starts, zero out last movement
thumb_wheel_displacement = 0
thumb_wheel_displacement += signed(notification.data[0:2])
elif feature == SupportedFeature.CHANGE_HOST and len(notification.data) >= 2:
if 1 <= notification.data[0] <= 3 and notification.data[1] == 0:
host = notification.data[0]
key_down = CONTROL["Host_Switch_Channel_" + str(host)]
logger.debug("mapping change host notification into key %s", key_down)
elif notification.data[0] == 0 and notification.data[1] <= 2:
host = notification.data[1] + 1
key_down = CONTROL["Host_Switch_Channel_" + str(host)]
logger.debug("mapping change host notification into key %s", key_down)
GLib.idle_add(evaluate_rules, feature, notification, device)

View File

@ -111,6 +111,7 @@ def test_feature():
(SupportedFeature.MKEYS, [0x01, 0x02, 0x03, 0x04]),
(SupportedFeature.MR, [0x01, 0x02, 0x03, 0x04]),
(SupportedFeature.THUMB_WHEEL, [0x01, 0x02, 0x03, 0x04, 0x05]),
(SupportedFeature.CHANGE_HOST, [0x00, 0x01, 0x00, 0x00]),
(SupportedFeature.DEVICE_UNIT_ID, [0x01, 0x02, 0x03, 0x04, 0x05]),
],
)
@ -125,3 +126,27 @@ def test_process_notification(feature, data):
)
diversion.process_notification(device_mock, notification, feature)
@pytest.mark.parametrize(
"data, key_name",
[
(b"\x01\x00\x00\x00", "Host Switch Channel 1"),
(b"\x02\x00\x00\x00", "Host Switch Channel 2"),
(b"\x00\x01\x00\x00", "Host Switch Channel 2"),
],
)
def test_process_change_host_notification_maps_to_key_press(data, key_name):
device_mock = mock.Mock()
notification = HIDPPNotification(
report_id=0x01,
devnumber=1,
sub_id=0x13,
address=0x00,
data=data,
)
diversion.process_notification(device_mock, notification, SupportedFeature.CHANGE_HOST)
condition = diversion.Key([key_name, "pressed"])
assert condition.evaluate(SupportedFeature.CHANGE_HOST, notification, device_mock, True)