From b9fe674a715e658eccf54419a378094efea63971 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Thu, 19 Aug 2021 14:45:33 -0400 Subject: [PATCH] Fix HID on Linux (#852) * Filter hid devices down to usage page * Avoid throwing exceptions on missing fields * Force hid4java to use libusb on Linux Closes #853 Co-authored-by: Berenz --- src/qz/communication/H4J_HidUtilities.java | 8 +++++++- src/qz/utils/SystemUtilities.java | 11 +++++++++++ src/qz/ws/SocketConnection.java | 4 +++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/qz/communication/H4J_HidUtilities.java b/src/qz/communication/H4J_HidUtilities.java index e868e0a79..989d678a2 100644 --- a/src/qz/communication/H4J_HidUtilities.java +++ b/src/qz/communication/H4J_HidUtilities.java @@ -10,6 +10,7 @@ import qz.utils.SystemUtilities; import javax.usb.util.UsbUtil; +import java.util.HashSet; import java.util.List; public class H4J_HidUtilities { @@ -32,6 +33,7 @@ public static JSONArray getHidDevicesJSON() throws JSONException { List devices = getHidDevices(); JSONArray devicesJSON = new JSONArray(); + HashSet unique = new HashSet<>(); for(HidDevice device : devices) { JSONObject deviceJSON = new JSONObject(); @@ -42,7 +44,11 @@ public static JSONArray getHidDevicesJSON() throws JSONException { .put("manufacturer", device.getManufacturer()) .put("product", device.getProduct()); - devicesJSON.put(deviceJSON); + String uid = String.format("v%sp%su%ss%s", deviceJSON.optString("vendorId"), deviceJSON.optString("productId"), deviceJSON.optString("usagePage"), deviceJSON.optString("serial")); + if (!unique.contains(uid)) { + devicesJSON.put(deviceJSON); + unique.add(uid); + } } return devicesJSON; diff --git a/src/qz/utils/SystemUtilities.java b/src/qz/utils/SystemUtilities.java index 61fd3f35d..a85e1037e 100644 --- a/src/qz/utils/SystemUtilities.java +++ b/src/qz/utils/SystemUtilities.java @@ -13,6 +13,8 @@ import com.github.zafarkhaja.semver.Version; import org.apache.commons.lang3.StringUtils; import org.apache.commons.ssl.Base64; +import org.joor.Reflect; +import org.joor.ReflectException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import qz.common.Constants; @@ -48,6 +50,15 @@ public class SystemUtilities { private static final Logger log = LoggerFactory.getLogger(TrayManager.class); private static final Locale defaultLocale = Locale.getDefault(); + static { + if(!isWindows() && !isMac()) { + // Force hid4java to use libusb: https://github.com/qzind/tray/issues/853 + try { + Reflect.on("org.hid4java.jna.HidApi").set("useLibUsbVariant", true); + } catch(ReflectException ignore) {} + } + } + private static Boolean darkDesktop; private static Boolean darkTaskbar; private static Boolean hasMonocle; diff --git a/src/qz/ws/SocketConnection.java b/src/qz/ws/SocketConnection.java index 0352ced3e..b9af87186 100644 --- a/src/qz/ws/SocketConnection.java +++ b/src/qz/ws/SocketConnection.java @@ -143,7 +143,9 @@ public void removeDevice(DeviceOptions dOpts) { public synchronized void openDevice(DeviceIO device, DeviceOptions dOpts) throws DeviceException { device.open(); - addDevice(dOpts, device); + if (device.isOpen()) { + addDevice(dOpts, device); + } } /**