forked from vial-kb/vial-gui
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
autorefresh: Use usb events instead of polling on windows
it was noticed that polling may still cause lag, and affect other devices
- Loading branch information
Showing
5 changed files
with
134 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import sys | ||
|
||
from PyQt5.QtCore import QObject, pyqtSignal | ||
|
||
|
||
class AutorefreshLocker: | ||
|
||
def __init__(self, autorefresh): | ||
self.autorefresh = autorefresh | ||
|
||
def __enter__(self): | ||
self.autorefresh._lock() | ||
|
||
def __exit__(self): | ||
self.autorefresh._unlock() | ||
|
||
|
||
class Autorefresh(QObject): | ||
|
||
instance = None | ||
devices_updated = pyqtSignal(object, bool) | ||
|
||
def __init__(self): | ||
super().__init__() | ||
|
||
self.devices = [] | ||
self.current_device = None | ||
|
||
Autorefresh.instance = self | ||
|
||
if sys.platform.startswith("win"): | ||
from autorefresh.autorefresh_thread_win import AutorefreshThreadWin | ||
|
||
self.thread = AutorefreshThreadWin() | ||
else: | ||
from autorefresh.autorefresh_thread import AutorefreshThread | ||
|
||
self.thread = AutorefreshThread() | ||
|
||
self.thread.devices_updated.connect(self.on_devices_updated) | ||
self.thread.start() | ||
|
||
def _lock(self): | ||
self.thread.lock() | ||
|
||
def _unlock(self): | ||
self.thread.unlock() | ||
|
||
@classmethod | ||
def lock(cls): | ||
return AutorefreshLocker(cls.instance) | ||
|
||
def load_dummy(self, data): | ||
self.thread.load_dummy(data) | ||
|
||
def sideload_via_json(self, data): | ||
self.thread.sideload_via_json(data) | ||
|
||
def load_via_stack(self, data): | ||
self.thread.load_via_stack(data) | ||
|
||
def select_device(self, idx): | ||
if self.current_device is not None: | ||
self.current_device.close() | ||
self.current_device = None | ||
if idx >= 0: | ||
self.current_device = self.devices[idx] | ||
|
||
if self.current_device is not None: | ||
if self.current_device.sideload: | ||
self.current_device.open(self.thread.sideload_json) | ||
elif self.current_device.via_stack: | ||
self.current_device.open(self.thread.via_stack_json["definitions"][self.current_device.via_id]) | ||
else: | ||
self.current_device.open(None) | ||
self.thread.set_device(self.current_device) | ||
|
||
def on_devices_updated(self, devices, changed): | ||
self.devices = devices | ||
self.devices_updated.emit(devices, changed) | ||
|
||
def update(self, quiet=True, hard=False): | ||
self.thread.update(quiet, hard) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import time | ||
import win32gui, win32con, win32api | ||
import win32gui_struct | ||
|
||
from autorefresh.autorefresh_thread import AutorefreshThread | ||
|
||
|
||
GUID_DEVINTERFACE_USB_DEVICE = "{A5DCBF10-6530-11D2-901F-00C04FB951ED}" | ||
DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 4 | ||
|
||
g_device_changes = 0 | ||
|
||
|
||
def device_changed(hwnd, msg, wp, lp): | ||
global g_device_changes | ||
if wp in [win32con.DBT_DEVICEARRIVAL, win32con.DBT_DEVICEREMOVECOMPLETE]: | ||
g_device_changes += 1 | ||
|
||
|
||
class AutorefreshThreadWin(AutorefreshThread): | ||
|
||
def run(self): | ||
global g_device_changes | ||
|
||
# code based on: | ||
# - https://github.com/libsdl-org/SDL/blob/7b3449b89f0625e4603f5d8681e2bac1f51a9386/src/hidapi/SDL_hidapi.c | ||
# - https://github.com/vmware-archive/salt-windows-install/blob/master/deps/salt/python/App/Lib/site-packages/win32/Demos/win32gui_devicenotify.py | ||
wc = win32gui.WNDCLASS() | ||
wc.hInstance = win32api.GetModuleHandle(None) | ||
wc.lpszClassName = "VIAL_DEVICE_DETECTION" | ||
wc.lpfnWndProc = { win32con.WM_DEVICECHANGE: device_changed } | ||
class_atom = win32gui.RegisterClass(wc) | ||
hwnd = win32gui.CreateWindowEx(0, "VIAL_DEVICE_DETECTION", None, 0, 0, 0, 0, 0, win32con.HWND_MESSAGE, None, None, None) | ||
|
||
hdev = win32gui.RegisterDeviceNotification( | ||
hwnd, | ||
win32gui_struct.PackDEV_BROADCAST_DEVICEINTERFACE(GUID_DEVINTERFACE_USB_DEVICE), | ||
win32con.DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES | ||
) | ||
|
||
while True: | ||
for x in range(100): | ||
win32gui.PumpWaitingMessages() | ||
time.sleep(0.01) | ||
|
||
if g_device_changes > 0: | ||
g_device_changes = 0 | ||
self.update() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters