diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3ed0a54ed..f23a61cd2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -656,7 +656,7 @@ jobs: key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/dist.txt', 'reqs/dist_extra_gui_qt.txt', 'reqs/test.txt') }} - name: Install system dependencies - run: apt_get_install cmake libdbus-1-dev libdbus-glib-1-dev libudev-dev libusb-1.0-0-dev libegl-dev libxkbcommon-x11-0 + run: apt_get_install libdbus-1-dev libdbus-glib-1-dev libudev-dev libegl-dev libxkbcommon-x11-0 - name: Setup Python environment run: setup_python_env -c reqs/constraints.txt -r reqs/dist.txt -r reqs/dist_extra_gui_qt.txt -r reqs/test.txt @@ -862,7 +862,7 @@ jobs: key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/build.txt', 'reqs/setup.txt', 'reqs/dist_*.txt', 'linux/appimage/deps.sh') }} - name: Install system dependencies - run: apt_get_install cmake libdbus-1-dev libdbus-glib-1-dev libudev-dev libusb-1.0-0-dev libegl-dev libxkbcommon-x11-0 + run: apt_get_install libdbus-1-dev libdbus-glib-1-dev libudev-dev libegl-dev libxkbcommon-x11-0 - name: Setup Python environment run: setup_python_env -c reqs/constraints.txt -r reqs/build.txt -r reqs/setup.txt diff --git a/.github/workflows/ci/workflow_template.yml b/.github/workflows/ci/workflow_template.yml index ba9756543..7d6df7e85 100644 --- a/.github/workflows/ci/workflow_template.yml +++ b/.github/workflows/ci/workflow_template.yml @@ -146,7 +146,7 @@ jobs: <% endif %> <% if j.type in ['build', 'test_gui_qt'] and j.os == 'Linux' %> - name: Install system dependencies - run: apt_get_install cmake libdbus-1-dev libdbus-glib-1-dev libudev-dev libusb-1.0-0-dev libegl-dev libxkbcommon-x11-0 + run: apt_get_install libdbus-1-dev libdbus-glib-1-dev libudev-dev libegl-dev libxkbcommon-x11-0 <% endif %> <% if j.type != 'notarize' %> diff --git a/MANIFEST.in b/MANIFEST.in index 57ff66b51..88398ea4a 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -34,7 +34,6 @@ include test/*.py include test/gui_qt/*.py include tox.ini include windows/* -exclude dev/* exclude .pre-commit-config.yaml # without first including it, exluding .readthedocs.yml results in a warning when running locally include .readthedocs.yml diff --git a/dev/build_hidapi.sh b/dev/build_hidapi.sh deleted file mode 100644 index c209b64ca..000000000 --- a/dev/build_hidapi.sh +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# Build hidapi library locally for development. -# -# Usage: -# ./dev/macos_dev_setup.sh -# MACOS_UNIVERSAL2=0 ./dev/build_hidapi.sh # macOS: don't build universal2 -# -# Resulting libs: -# macOS: build/local-hidapi/macos/lib/libhidapi*.dylib -# Linux: build/local-hidapi/linux/lib/libhidapi-hidraw.so -# Windows: build/local-hidapi/windows/bin/hidapi.dll - -. ./plover_build_utils/deps.sh -. ./plover_build_utils/functions.sh - -python='python' - -MACOS_UNIVERSAL2="${MACOS_UNIVERSAL2:-1}" - -# Resolve repo root relative to this script -SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" -REPO_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)" - -WORK_DIR="${REPO_ROOT}/build/local-hidapi" -SRC_DIR="${WORK_DIR}/src" -BUILD_DIR="${WORK_DIR}/build" -OUT_LIB_DIR_MAC="${WORK_DIR}/macos/lib" -OUT_LIB_DIR_LNX="${WORK_DIR}/linux/lib" -OUT_BIN_DIR_WIN="${WORK_DIR}/windows/bin" - -# Clean and prep -# Prepare directories -mkdir -p "${SRC_DIR}" "${BUILD_DIR}" - -OS="$(uname -s || true)" -# If outputs already exist for the current platform, skip rebuilding. -if [[ "${OS}" == "Darwin" ]]; then - if ls "${OUT_LIB_DIR_MAC}"/libhidapi*.dylib >/dev/null 2>&1; then - echo "hidapi found at ${OUT_LIB_DIR_MAC}; skipping build." - exit 0 - fi -elif [[ "${OS}" == "Linux" ]]; then - if ls "${OUT_LIB_DIR_LNX}"/libhidapi-hidraw.so* >/dev/null 2>&1; then - echo "hidapi found at ${OUT_LIB_DIR_LNX}; skipping build." - exit 0 - fi -elif [[ "${OS}" == MINGW* || "${OS}" == MSYS* || "${OS}" == CYGWIN* || "${OS}" == "Windows_NT" ]]; then - if [ -f "${OUT_BIN_DIR_WIN}/hidapi.dll" ]; then - echo "hidapi found at ${OUT_BIN_DIR_WIN}/hidapi.dll; skipping build." - exit 0 - fi -fi - -# Clean and prep for a fresh build -rm -rf "${SRC_DIR}" "${BUILD_DIR}" -mkdir -p "${SRC_DIR}" "${BUILD_DIR}" - -echo "==> Downloading & unpacking hidapi ${hidapi_version}" -fetch_hidapi "${SRC_DIR}" "${WORK_DIR}" - - -if [[ "${OS}" == "Darwin" ]]; then - echo "==> Configuring (macOS, IOHIDManager backend)" - - # Shared fetch/build helpers (macOS) - # shellcheck disable=SC1091 - . "${REPO_ROOT}/osx/build_hidapi.sh" - - mkdir -p "${OUT_LIB_DIR_MAC}" - # Architectures - if [[ "${MACOS_UNIVERSAL2}" == "1" ]]; then - OSX_ARCHES="x86_64;arm64" - else - ARCH="$(uname -m || true)" - if [[ "${ARCH}" == "arm64" || "${ARCH}" == "aarch64" ]]; then - OSX_ARCHES="arm64" - else - OSX_ARCHES="x86_64" - fi - fi - - cmake_build_macos "${SRC_DIR}" "${BUILD_DIR}" "${OSX_ARCHES}" "RelWithDebInfo" - - # Find produced dylib - DYLIB="$(/usr/bin/find "${BUILD_DIR}" -type f -name 'libhidapi*.dylib' -print -quit || true)" - if [[ -z "${DYLIB}" ]]; then - echo "Error: libhidapi*.dylib not found in build output." >&2 - exit 3 - fi - - BASENAME="$(basename "${DYLIB}")" - echo "==> Staging ${BASENAME}" - cp -f "${DYLIB}" "${OUT_LIB_DIR_MAC}/${BASENAME}" - - pushd "${OUT_LIB_DIR_MAC}" >/dev/null - ln -sf "${BASENAME}" libhidapi.dylib || true - popd >/dev/null - - echo - echo "✅ Built macOS hidapi at: ${OUT_LIB_DIR_MAC}/${BASENAME}" - -elif [[ "${OS}" == "Linux" ]]; then - echo "==> Configuring (Linux, hidraw backend)" - mkdir -p "${OUT_LIB_DIR_LNX}" - - # Shared fetch/build helpers (Linux) - # shellcheck disable=SC1091 - . "${REPO_ROOT}/linux/build_hidapi.sh" - - cmake_build_linux "${SRC_DIR}" "${BUILD_DIR}" "RelWithDebInfo" - - SO="$(/usr/bin/find "${BUILD_DIR}" -type f -name 'libhidapi-hidraw.so*' -print -quit || true)" - if [[ -z "${SO}" ]]; then - echo "Error: libhidapi-hidraw.so not found in build output." >&2 - exit 3 - fi - - BASENAME="$(basename "${SO}")" - echo "==> Staging ${BASENAME}" - cp -f "${SO}" "${OUT_LIB_DIR_LNX}/${BASENAME}" - - pushd "${OUT_LIB_DIR_LNX}" >/dev/null - [[ -e libhidapi-hidraw.so ]] || ln -sf "${BASENAME}" libhidapi-hidraw.so || true - popd >/dev/null - - echo - echo "✅ Built Linux hidapi at: ${OUT_LIB_DIR_LNX}/${BASENAME}" - -elif [[ "${OS}" == MINGW* || "${OS}" == MSYS* || "${OS}" == CYGWIN* || "${OS}" == "Windows_NT" ]]; then - echo "==> Configuring (Windows, WinAPI backend)" - mkdir -p "${OUT_BIN_DIR_WIN}" - - # Shared fetch/build helpers (Windows) - # shellcheck disable=SC1091 - . "${REPO_ROOT}/windows/build_hidapi.sh" - - # Build shared DLL - cmake_build_windows "${SRC_DIR}" "${BUILD_DIR}" "Release" - - # Find the produced DLL (varies by generator) - DLL="$(/usr/bin/find "${BUILD_DIR}" -type f \( -iname 'hidapi*.dll' -o -iname 'libhidapi*.dll' \) -print -quit 2>/dev/null || true)" - if [[ -z "${DLL}" ]]; then - echo "Error: hidapi DLL not found in build output." >&2 - exit 3 - fi - - BASENAME="$(basename "${DLL}")" - echo "==> Staging ${BASENAME}" - cp -f "${DLL}" "${OUT_BIN_DIR_WIN}/hidapi.dll" - - echo - echo "✅ Built Windows hidapi at: ${OUT_BIN_DIR_WIN}/hidapi.dll" -else - echo "Unsupported OS: ${OS}. This helper currently supports macOS, Linux, and Windows." >&2 - exit 4 -fi diff --git a/dev/write_hidapi_pth.py b/dev/write_hidapi_pth.py deleted file mode 100644 index a8513c396..000000000 --- a/dev/write_hidapi_pth.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python3 -""" -Write a .pth into site-packages that adds the local hidapi bin dir -to the DLL search path on Windows via os.add_dll_directory. - -Usage (optional): write_hidapi_pth.py -""" - -import sys -from pathlib import Path - - -def main(argv: list[str]) -> int: - if sys.platform != "win32": - # No-op outside Windows. - return 0 - - if len(argv) >= 3: - repo_dir = Path(argv[1]).resolve() - site_packages = Path(argv[2]).resolve() - else: - repo_dir = Path.cwd() - site_packages = Path(sys.prefix, "Lib", "site-packages") - - dll_dir = repo_dir / "build" / "local-hidapi" / "windows" / "bin" - if not dll_dir.is_dir(): - print(f"[hidapi .pth] skip: {dll_dir} does not exist", file=sys.stderr) - return 0 - - site_packages.mkdir(parents=True, exist_ok=True) - pth_path = site_packages / "plover_hidapi_add_dll_dir.pth" - - # Keep it one line: .pth executes arbitrary Python on import. - # Include defensive checks for directory existence and DLL loading - code = ( - "import os,sys;" - "p=r%r;" - "os.add_dll_directory(p) if sys.platform=='win32' and hasattr(os,'add_dll_directory') and os.path.isdir(p) else None\n" - % (str(dll_dir),) - ) - - try: - pth_path.write_text(code, encoding="utf-8") - print(f"[hidapi .pth] wrote {pth_path}") - return 0 - except Exception as e: - print(f"[hidapi .pth] failed to write {pth_path}: {e}", file=sys.stderr) - return 2 - - -if __name__ == "__main__": - sys.exit(main(sys.argv)) diff --git a/linux/README.md b/linux/README.md index 17f90702b..85ffb1d55 100644 --- a/linux/README.md +++ b/linux/README.md @@ -5,8 +5,6 @@ To be able to setup a complete development environment, you'll need to manually install some system libraries (including the development version of your distribution corresponding packages): -- Treal support: `libusb` (1.0) and `libudev` are needed by - the [`hidapi` package](https://pypi.org/project/hidapi/). - log / notifications support: `libdbus` is needed. For the rest of the steps, follow the [developer guide](../doc/developer_guide.md). diff --git a/linux/appimage/build.sh b/linux/appimage/build.sh index cdb2210b5..8fd71fe59 100755 --- a/linux/appimage/build.sh +++ b/linux/appimage/build.sh @@ -2,7 +2,6 @@ set -e -. ./plover_build_utils/deps.sh . ./plover_build_utils/functions.sh topdir="$PWD" @@ -197,33 +196,10 @@ run "$linuxdeploy" \ # Install Plover and dependencies. bootstrap_dist "$wheel" -# ------- Start: Build & bundle hidapi from source ------- -hidapi_src="$builddir/hidapi-src" -hidapi_bld="$builddir/hidapi-build" - -. ./linux/build_hidapi.sh - -echo "Downloading and unpacking hidapi ${hidapi_version}…" -fetch_hidapi "$hidapi_src" "$builddir" - -echo "Building hidapi…" -cmake_build_linux "$hidapi_src" "$hidapi_bld" "Release" - -# Locate the produced .so -hidapi_so="$(find "$hidapi_bld" -name 'libhidapi-hidraw.so*' -type f -print -quit)" -if [ -z "$hidapi_so" ] || [ ! -f "$hidapi_so" ]; then - echo "Error: built libhidapi-hidraw.so not found." >&2 - exit 3 -fi - -# Bundle into the AppDir's lib directory -run cp -v "$hidapi_so" "$appdir/usr/lib/" -base="$(basename "$hidapi_so")" -# Add symlink for unversioned .so if needed -if [ ! -e "$appdir/usr/lib/libhidapi-hidraw.so" ]; then - ln -s "$base" "$appdir/usr/lib/libhidapi-hidraw.so" -fi -# ------- End: Build & bundle hidapi from source ------- +# Reinstall hidapi with the hidraw backend; libusb reports usage/usage_page as 0, +# which results in HID keyboards not being detected by Plover. +run "$python" -m pip uninstall -y hidapi || true +run_eval "HIDAPI_WITH_HIDRAW=1 HIDAPI_WITH_LIBUSB=0 $python -m pip install --no-binary :all: --no-cache-dir hidapi" # Trim the fat, second pass. run "$python" -m plover_build_utils.trim "$appdir" "$builddir/blacklist.txt" diff --git a/linux/build_hidapi.sh b/linux/build_hidapi.sh deleted file mode 100644 index 264b8e64d..000000000 --- a/linux/build_hidapi.sh +++ /dev/null @@ -1,8 +0,0 @@ -cmake_build_linux() { - local src="$1" bld="$2" config="${3:-Release}" - rm -rf "$bld" - cmake -S "$src" -B "$bld" \ - -DBUILD_SHARED_LIBS=ON \ - -DCMAKE_BUILD_TYPE="$config" - cmake --build "$bld" --config "$config" --parallel -} diff --git a/news.d/api/1812.core.md b/news.d/api/1812.core.md new file mode 100644 index 000000000..c7d320d99 --- /dev/null +++ b/news.d/api/1812.core.md @@ -0,0 +1 @@ +Migrate HID library to cython-hidapi. diff --git a/osx/build_hidapi.sh b/osx/build_hidapi.sh deleted file mode 100644 index 3e629c76b..000000000 --- a/osx/build_hidapi.sh +++ /dev/null @@ -1,9 +0,0 @@ -cmake_build_macos() { - local src="$1" bld="$2" arches="$3" config="${4:-Release}" - rm -rf "$bld" - cmake -S "$src" -B "$bld" \ - -DBUILD_SHARED_LIBS=ON \ - -DCMAKE_BUILD_TYPE="$config" \ - -DCMAKE_OSX_ARCHITECTURES="$arches" - cmake --build "$bld" --config "$config" --parallel -} diff --git a/osx/make_app.sh b/osx/make_app.sh index d40b32560..f406ef605 100644 --- a/osx/make_app.sh +++ b/osx/make_app.sh @@ -2,7 +2,6 @@ set -e -. ./plover_build_utils/deps.sh . ./plover_build_utils/functions.sh topdir="$PWD" @@ -66,37 +65,6 @@ python='appdir_python' # Install Plover and dependencies. bootstrap_dist "$plover_wheel" -# ------- Start: Build & bundle hidapi from source ------- -. ./osx/build_hidapi.sh - -hidapi_src="$builddir/hidapi-src" -hidapi_bld="$builddir/hidapi-build" - -echo "Downloading and unpacking hidapi ${hidapi_version}…" -fetch_hidapi "$hidapi_src" "$builddir" - -echo "Building hidapi…" -cmake_build_macos "$hidapi_src" "$hidapi_bld" "x86_64;arm64" "Release" - -# Locate the produced dylib -hidapi_dylib="$(/usr/bin/find "$hidapi_bld" -name 'libhidapi*.dylib' -type f -print -quit)" -if [ -z "$hidapi_dylib" ] || [ ! -f "$hidapi_dylib" ]; then - echo "Error: built libhidapi*.dylib not found." >&2 - exit 3 -fi - -# Bundle into the app's Frameworks directory -run cp "$hidapi_dylib" "$frameworks_dir/" -base="$(basename "$hidapi_dylib")" - -# Add alias to Frameworks dir -ln -sfn "$base" "$frameworks_dir/libhidapi.dylib" - -# Add RPATH to the Python binary itself and re-sign it -run install_name_tool -add_rpath "@executable_path/../../../../../Frameworks" "$py_binary" -run /usr/bin/codesign -f -s - "$py_binary" -# ------- End: Build & bundle hidapi from source ------- - # Create launcher. run gcc -Wall -O2 -arch x86_64 -arch arm64 'osx/app_resources/plover_launcher.c' -o "$macos_dir/Plover" diff --git a/plover/machine/plover_hid.py b/plover/machine/plover_hid.py index 77e5ad860..27019454e 100644 --- a/plover/machine/plover_hid.py +++ b/plover/machine/plover_hid.py @@ -15,21 +15,36 @@ import hid import time import platform -import ctypes import threading +import ctypes from queue import Queue, Empty -from typing import Dict +from typing import Any, Dict from dataclasses import dataclass -def _darwin_disable_exclusive_open(): - lib = getattr(hid, "hidapi", None) - if lib is not None: - func = getattr(lib, "hid_darwin_set_open_exclusive") - func.argtypes = (ctypes.c_int,) - func.restype = None +def _darwin_disable_exclusive_open() -> None: + """Disable macOS exclusive HID opens while cython-hidapi lacks a Python API. + + Keep this workaround until https://github.com/trezor/cython-hidapi/issues/178 + is resolved. + """ + lib_path = getattr(hid, "__file__", None) + if not lib_path: + log.warning("hidapi extension path not found; HID may open exclusively") + return + try: + lib = ctypes.CDLL(lib_path) + func = ctypes.CFUNCTYPE(None, ctypes.c_int)( + ("hid_darwin_set_open_exclusive", lib) + ) + except Exception: + log.warning( + "failed to load hid_darwin_set_open_exclusive; HID may open exclusively" + ) + return + try: func(0) - else: + except Exception: log.warning( "could not call hid_darwin_set_open_exclusive; HID may open exclusively" ) @@ -69,7 +84,7 @@ class InvalidReport(Exception): @dataclass class HidDeviceRecord: - device: hid.Device + device: hid.device thread: threading.Thread @@ -86,18 +101,19 @@ class PloverHid(ThreadedStenotypeBase): ''' # fmt: on - def __init__(self, params): + def __init__(self, params: Dict[str, Any]) -> None: super().__init__() self._params = params - self._devices: Dict[str, HidDeviceRecord] = {} + self._devices: Dict[bytes, HidDeviceRecord] = {} self._report_queue: Queue[bytes] = Queue() self._lock: threading.Lock = threading.Lock() self._device_watcher: threading.Thread | None = None - def _add_device(self, path): + def _add_device(self, path: bytes) -> bool: """Open a HID device at `path`, start its reader, and mark ready if first.""" try: - device = hid.Device(path=path) + device = hid.device() + device.open_path(path) except Exception as e: log.debug(f"open failed for {path!r}: {e}") return False @@ -112,7 +128,7 @@ def _add_device(self, path): self._ready() return True - def _remove_device(self, path): + def _remove_device(self, path: bytes) -> None: """Close and forget a HID device by path; if none remain, mark disconnected.""" with self._lock: entry = self._devices.pop(path, None) @@ -137,7 +153,7 @@ def _remove_device(self, path): if not self._devices and not self.finished.is_set(): self._error() - def _scan_device_loop(self): + def _scan_device_loop(self) -> None: """Scan for new matching HID devices and start readers for them.""" scan_ms = self._params["device_scan_interval_ms"] while not self.finished.is_set(): @@ -145,7 +161,7 @@ def _scan_device_loop(self): paths = [ d["path"] for d in hid.enumerate() - if d.get("usage_page") == USAGE_PAGE and d.get("usage") == USAGE + if (d.get("usage_page") == USAGE_PAGE and d.get("usage") == USAGE) ] except Exception as e: log.debug(f"device scan enumerate failed: {e}") @@ -166,7 +182,7 @@ def _scan_device_loop(self): if self.finished.wait(scan_ms / 1000.0): break - def _read_from_device_loop(self, path: str, device: hid.Device) -> None: + def _read_from_device_loop(self, path: bytes, device: hid.device) -> None: """Per-device reader thread: blocking read, push reports to the report queue.""" slice_ms = self._params["repeat_interval_ms"] while not self.finished.is_set(): @@ -177,13 +193,18 @@ def _read_from_device_loop(self, path: str, device: hid.Device) -> None: break if report: try: - self._report_queue.put_nowait(report) + report_bytes = ( + report + if isinstance(report, (bytes, bytearray)) + else bytes(report) + ) + self._report_queue.put_nowait(report_bytes) except Exception: log.debug("failed to put report in queue") pass self._remove_device(path) - def _parse(self, report): + def _parse(self, report: bytes) -> int: # The first byte is the report id, and due to idiosyncrasies # in how HID-apis work on different operating system we can't # map the report id to the contents in a good way, so we force @@ -193,14 +214,14 @@ def _parse(self, report): else: raise InvalidReport() - def _send(self, key_state): + def _send(self, key_state: int) -> None: steno_actions = self.keymap.keys_to_actions( [key for i, key in enumerate(STENO_KEY_CHART) if key_state >> (63 - i) & 1] ) if steno_actions: self._notify(steno_actions) - def run(self): + def run(self) -> None: key_state = 0 current = 0 last_sent = 0 @@ -248,13 +269,13 @@ def run(self): last_sent = key_state key_state = 0 - def start_capture(self): + def start_capture(self) -> None: self.finished.clear() self._initializing() # Enumerate all hid devices on the machine and if we find one with our # usage page and usage we try to connect to it. try: - devices = [ + devices: list[bytes] = [ device["path"] for device in hid.enumerate() if device["usage_page"] == USAGE_PAGE and device["usage"] == USAGE @@ -278,7 +299,7 @@ def start_capture(self): return self.start() - def stop_capture(self): + def stop_capture(self) -> None: super().stop_capture() # Stop device watcher t_watch = getattr(self, "_device_watcher", None) diff --git a/plover_build_utils/deps.sh b/plover_build_utils/deps.sh deleted file mode 100644 index 4d82e557a..000000000 --- a/plover_build_utils/deps.sh +++ /dev/null @@ -1,2 +0,0 @@ -hidapi_version=0.15.0 -hidapi_sha1='3bed4e9a3b523d998a96f2ec52824bc69422c222' diff --git a/plover_build_utils/functions.sh b/plover_build_utils/functions.sh index c8b7918e2..d5b2b3b26 100644 --- a/plover_build_utils/functions.sh +++ b/plover_build_utils/functions.sh @@ -239,17 +239,6 @@ osx_standalone_python() run rm -rf "$reloc_py_dir" } -fetch_hidapi() { - local src_dir="$1" download_dir="$2" - local file_name="hidapi-${hidapi_version}.tar.gz" - local url="https://github.com/libusb/hidapi/archive/refs/tags/${file_name}" - run "$python" -m plover_build_utils.download "$url" "$hidapi_sha1" "$file_name" "$download_dir" - hidapi_tar="$download_dir/$file_name" - rm -rf "$src_dir" - mkdir -p "$src_dir" - tar -xzf "$hidapi_tar" -C "$src_dir" --strip-components=1 -} - packaging_checks() { run rm -rf dist diff --git a/reqs/constraints.txt b/reqs/constraints.txt index 812e72a57..3667d80da 100644 --- a/reqs/constraints.txt +++ b/reqs/constraints.txt @@ -19,7 +19,7 @@ dmgbuild==1.6.5 docutils==0.21.2 ds-store==1.3.1 evdev==1.9.1 -hid==1.0.8 +hidapi==0.15.0 idna==3.10 importlib-metadata==8.6.1 incremental==24.7.2 diff --git a/reqs/dist.txt b/reqs/dist.txt index d0a44a42b..eeafe5a2e 100644 --- a/reqs/dist.txt +++ b/reqs/dist.txt @@ -1,6 +1,6 @@ appdirs appnope; "darwin" in sys_platform -hid +hidapi pkginfo plover-stroke plyer; "win32" in sys_platform diff --git a/tox.ini b/tox.ini index 2cf3edb9e..e736e3c01 100644 --- a/tox.ini +++ b/tox.ini @@ -22,10 +22,6 @@ install_command = # Default, Python 3 based, environment. [testenv] -commands_pre = - bash {toxinidir}/dev/build_hidapi.sh - {envpython} {toxinidir}/dev/write_hidapi_pth.py "{toxinidir}" "{envsitepackagesdir}" - envdir = {toxworkdir}/dev extras = gui_qt @@ -50,18 +46,6 @@ passenv = setenv = SSL_CERT_FILE={envsitepackagesdir}/certifi/cacert.pem - # Repo-relative folders where dev/build_hidapi.sh drops the libs - HIDAPI_DEV_LIB_MAC = {toxinidir}/build/local-hidapi/macos/lib - HIDAPI_DEV_LIB_LNX = {toxinidir}/build/local-hidapi/linux/lib - - # macOS: add to library path so ctypes can find hidapi libraries - DYLD_FALLBACK_LIBRARY_PATH = {env:HIDAPI_DEV_LIB_MAC}{:}{env:DYLD_FALLBACK_LIBRARY_PATH:} - - # Linux: add to library path so ctypes can find hidapi libraries - LD_LIBRARY_PATH = {env:HIDAPI_DEV_LIB_LNX}{:}{env:LD_LIBRARY_PATH:} - - # Windows: not done via path; see dev/write_hidapi_pth.py - # Lightweight tests only environments. [testenv:py3{,6,7,8,9,10,11,12,13}] description = run tests using {envname} diff --git a/windows/build_hidapi.sh b/windows/build_hidapi.sh deleted file mode 100644 index 155cb117e..000000000 --- a/windows/build_hidapi.sh +++ /dev/null @@ -1,19 +0,0 @@ -cmake_build_windows() { - local src="$1" bld="$2" config="${3:-RelWithDebInfo}" - rm -rf "$bld" - - # Architecture override: WIN_ARCH=Win32|x64|ARM64 (default x64) - local arch="${WIN_ARCH:-x64}" - - local -a cmake_args=( - -A "$arch" - -DBUILD_SHARED_LIBS=ON - -DHIDAPI_BUILD_HIDTEST=OFF - -DHIDAPI_BUILD_TESTS=OFF - -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL - ) - - echo "==> running cmake (arch: $arch, config: $config)" - cmake -S "$src" -B "$bld" "${cmake_args[@]}" - cmake --build "$bld" --config "$config" --parallel -} diff --git a/windows/dist_build.sh b/windows/dist_build.sh index cd14151e3..e87970cbe 100755 --- a/windows/dist_build.sh +++ b/windows/dist_build.sh @@ -2,7 +2,6 @@ set -e -. ./plover_build_utils/deps.sh . ./plover_build_utils/functions.sh opt_incremental=0 @@ -74,29 +73,6 @@ build_dist() # Install Plover and dependencies. bootstrap_dist "$wheel" --no-warn-script-location - # ------- Start: Build & bundle hidapi from source ------- - . ./windows/build_hidapi.sh - - hidapi_src="$builddir/hidapi-src" - hidapi_bld="$builddir/hidapi-build" - - echo "Downloading and unpacking hidapi ${hidapi_version}..." - fetch_hidapi "$hidapi_src" "$builddir" - - echo "Building hidapi…" - cmake_build_windows "$hidapi_src" "$hidapi_bld" "Release" - - # Find the built DLL - should be in Release/ subdirectory - hidapi_dll="$(/usr/bin/find "$hidapi_bld" -name 'hidapi.dll' -type f -print -quit)" - if [ -z "$hidapi_dll" ] || [ ! -f "$hidapi_dll" ]; then - echo "Error: built hidapi.dll not found." >&2 - exit 3 - fi - - # Copy hidapi.dll to distribution directory where the exe will find it - run cp "$hidapi_dll" "$dist_data/" - # ------- End: Build & bundle hidapi from source ------- - # Trim the fat... if [ $opt_trim -eq 1 ] then