Refactor: Remove all GDK dependencies from hidapi package
The hidapi hardware layer must not know or depend on any UI libraries. Removes all GDK dependencies from the hidapi packages, which makes testing of these modules easier and removes unwanted cross-dependencies. Related #2480
This commit is contained in:
parent
70def31942
commit
ea0eb66f39
|
@ -23,10 +23,13 @@ Parts of this code are adapted from https://github.com/apmorton/pyhidapi
|
||||||
which is MIT licensed.
|
which is MIT licensed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import atexit
|
import atexit
|
||||||
import ctypes
|
import ctypes
|
||||||
import logging
|
import logging
|
||||||
import platform
|
import platform
|
||||||
|
import typing
|
||||||
|
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
@ -35,8 +38,9 @@ import gi
|
||||||
|
|
||||||
from hidapi.common import DeviceInfo
|
from hidapi.common import DeviceInfo
|
||||||
|
|
||||||
gi.require_version("Gdk", "3.0")
|
if typing.TYPE_CHECKING:
|
||||||
from gi.repository import GLib # NOQA: E402
|
gi.require_version("Gdk", "3.0")
|
||||||
|
from gi.repository import GLib # NOQA: E402
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -311,13 +315,21 @@ def find_paired_node_wpid(receiver_path, index):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def monitor_glib(callback, filterfn):
|
def monitor_glib(glib: GLib, callback, filterfn):
|
||||||
|
"""Monitor GLib.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
glib
|
||||||
|
GLib instance.
|
||||||
|
"""
|
||||||
|
|
||||||
def device_callback(action, device):
|
def device_callback(action, device):
|
||||||
# print(f"device_callback({action}): {device}")
|
# print(f"device_callback({action}): {device}")
|
||||||
if action == "add":
|
if action == "add":
|
||||||
d_info = _match(action, device, filterfn)
|
d_info = _match(action, device, filterfn)
|
||||||
if d_info:
|
if d_info:
|
||||||
GLib.idle_add(callback, action, d_info)
|
glib.idle_add(callback, action, d_info)
|
||||||
elif action == "remove":
|
elif action == "remove":
|
||||||
# Removed devices will be detected by Solaar directly
|
# Removed devices will be detected by Solaar directly
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -23,9 +23,12 @@ The docstrings are mostly copied from the hidapi API header, with changes where
|
||||||
necessary.
|
necessary.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import errno
|
import errno
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import typing
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,8 +42,9 @@ import pyudev
|
||||||
|
|
||||||
from hidapi.common import DeviceInfo
|
from hidapi.common import DeviceInfo
|
||||||
|
|
||||||
gi.require_version("Gdk", "3.0")
|
if typing.TYPE_CHECKING:
|
||||||
from gi.repository import GLib # NOQA: E402
|
gi.require_version("Gdk", "3.0")
|
||||||
|
from gi.repository import GLib # NOQA: E402
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -213,13 +217,20 @@ def find_paired_node_wpid(receiver_path, index):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def monitor_glib(callback, filterfn):
|
def monitor_glib(glib: GLib, callback, filterfn):
|
||||||
|
"""Monitor GLib.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
glib
|
||||||
|
GLib instance.
|
||||||
|
"""
|
||||||
c = pyudev.Context()
|
c = pyudev.Context()
|
||||||
m = pyudev.Monitor.from_netlink(c)
|
m = pyudev.Monitor.from_netlink(c)
|
||||||
m.filter_by(subsystem="hidraw")
|
m.filter_by(subsystem="hidraw")
|
||||||
|
|
||||||
def _process_udev_event(monitor, condition, cb, filterfn):
|
def _process_udev_event(monitor, condition, cb, filterfn):
|
||||||
if condition == GLib.IO_IN:
|
if condition == glib.IO_IN:
|
||||||
event = monitor.receive_device()
|
event = monitor.receive_device()
|
||||||
if event:
|
if event:
|
||||||
action, device = event
|
action, device = event
|
||||||
|
@ -227,7 +238,7 @@ def monitor_glib(callback, filterfn):
|
||||||
if action == "add":
|
if action == "add":
|
||||||
d_info = _match(action, device, filterfn)
|
d_info = _match(action, device, filterfn)
|
||||||
if d_info:
|
if d_info:
|
||||||
GLib.idle_add(cb, action, d_info)
|
glib.idle_add(cb, action, d_info)
|
||||||
elif action == "remove":
|
elif action == "remove":
|
||||||
# the GLib notification does _not_ match!
|
# the GLib notification does _not_ match!
|
||||||
pass
|
pass
|
||||||
|
@ -235,13 +246,13 @@ def monitor_glib(callback, filterfn):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# io_add_watch_full may not be available...
|
# io_add_watch_full may not be available...
|
||||||
GLib.io_add_watch_full(m, GLib.PRIORITY_LOW, GLib.IO_IN, _process_udev_event, callback, filterfn)
|
glib.io_add_watch_full(m, glib.PRIORITY_LOW, glib.IO_IN, _process_udev_event, callback, filterfn)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
try:
|
||||||
# and the priority parameter appeared later in the API
|
# and the priority parameter appeared later in the API
|
||||||
GLib.io_add_watch(m, GLib.PRIORITY_LOW, GLib.IO_IN, _process_udev_event, callback, filterfn)
|
glib.io_add_watch(m, glib.PRIORITY_LOW, glib.IO_IN, _process_udev_event, callback, filterfn)
|
||||||
except Exception:
|
except Exception:
|
||||||
GLib.io_add_watch(m, GLib.IO_IN, _process_udev_event, callback, filterfn)
|
glib.io_add_watch(m, glib.IO_IN, _process_udev_event, callback, filterfn)
|
||||||
|
|
||||||
if logger.isEnabledFor(logging.DEBUG):
|
if logger.isEnabledFor(logging.DEBUG):
|
||||||
logger.debug("Starting dbus monitoring")
|
logger.debug("Starting dbus monitoring")
|
||||||
|
|
|
@ -29,6 +29,7 @@ from random import getrandbits
|
||||||
from time import time
|
from time import time
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
import gi
|
||||||
import hidapi
|
import hidapi
|
||||||
|
|
||||||
from . import base_usb
|
from . import base_usb
|
||||||
|
@ -41,6 +42,9 @@ from . import hidpp20_constants
|
||||||
from .common import LOGITECH_VENDOR_ID
|
from .common import LOGITECH_VENDOR_ID
|
||||||
from .common import BusID
|
from .common import BusID
|
||||||
|
|
||||||
|
gi.require_version("Gdk", "3.0")
|
||||||
|
from gi.repository import GLib # NOQA: E402
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
_hidpp20 = hidpp20.Hidpp20()
|
_hidpp20 = hidpp20.Hidpp20()
|
||||||
|
@ -176,7 +180,7 @@ def receivers_and_devices():
|
||||||
|
|
||||||
def notify_on_receivers_glib(callback):
|
def notify_on_receivers_glib(callback):
|
||||||
"""Watch for matching devices and notifies the callback on the GLib thread."""
|
"""Watch for matching devices and notifies the callback on the GLib thread."""
|
||||||
return hidapi.monitor_glib(callback, filter)
|
return hidapi.monitor_glib(GLib, callback, filter)
|
||||||
|
|
||||||
|
|
||||||
def open_path(path):
|
def open_path(path):
|
||||||
|
|
Loading…
Reference in New Issue