From bb680e678b3fd2119641e52b59293fd03eb6442a Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Thu, 13 Jul 2023 10:00:02 +0800 Subject: [PATCH 1/4] gui: Check numlock state and add button to toggle Signed-off-by: Daniel Schaefer --- qmk_gui.py | 23 ++++++++++++++++++++++- requirements.txt | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/qmk_gui.py b/qmk_gui.py index b3f0d8c..c87511d 100755 --- a/qmk_gui.py +++ b/qmk_gui.py @@ -5,6 +5,9 @@ import PySimpleGUI as sg import hid +# TODO: Linux +from win32api import GetKeyState, keybd_event +from win32con import VK_NUMLOCK, VK_CAPITAL import uf2conv @@ -115,6 +118,10 @@ def format_fw_ver(fw_ver): fw_ver_patch = (fw_ver & 0x000F) return f"{fw_ver_major}.{fw_ver_minor}.{fw_ver_patch}" +def get_numlock_state(): + # TODO: Handle Linux + return GetKeyState(VK_NUMLOCK) + def main(devices): device_checkboxes = [] for dev in devices: @@ -177,17 +184,26 @@ def main(devices): [sg.Text("RGB Effect")], [sg.Combo(RGB_EFFECTS, k='-RGB-EFFECT-', enable_events=True)], + [sg.HorizontalSeparator()], + + [sg.Text("OS Numlock Setting")], + [sg.Text("State: "), sg.Text("", k='-NUMLOCK-STATE-'), sg.Push() ,sg.Button("Refresh")], + [sg.Button("Send Numlock Toggle", k='-NUMLOCK-TOGGLE-')], [sg.HorizontalSeparator()], [sg.Text("Save Settings")], [sg.Button("Save", k='-SAVE-'), sg.Button("Clear EEPROM", k='-CLEAR-EEPROM-')], [sg.Text(f"Program Version: {PROGRAM_VERSION}")], ] - window = sg.Window("QMK Keyboard Control", layout) + window = sg.Window("QMK Keyboard Control", layout, finalize=True) selected_devices = [] while True: + numlock_on = get_numlock_state() + if numlock_on is not None: + window['-NUMLOCK-STATE-'].update("On (Numbers)" if numlock_on else "Off (Arrows)") + event, values = window.read() #print('Event', event) #print('Values', values) @@ -217,6 +233,11 @@ def main(devices): restart_hint() window['-CHECKBOX-{}-'.format(dev['path'])].update(False, disabled=True) + if event == "-NUMLOCK-TOGGLE-": + # TODO: Linux + keybd_event(VK_NUMLOCK, 0x3A, 0x1, 0) + keybd_event(VK_NUMLOCK, 0x3A, 0x3, 0) + # Run commands on all selected devices for dev in selected_devices: if event == "-BOOTLOADER-": diff --git a/requirements.txt b/requirements.txt index c8e4248..c07f057 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ hidapi==0.14.0 PySimpleGUI==4.60.5 +pywin32 From 60c4d62886310a1fe1a773e1daef6f1de83eb38f Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Thu, 13 Jul 2023 10:55:56 +0800 Subject: [PATCH 2/4] gui: Implement numlock on Linux Signed-off-by: Daniel Schaefer --- qmk_gui.py | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/qmk_gui.py b/qmk_gui.py index c87511d..4de84c9 100755 --- a/qmk_gui.py +++ b/qmk_gui.py @@ -1,13 +1,14 @@ #!/usr/bin/env python3 import os import sys +import subprocess import time import PySimpleGUI as sg import hid -# TODO: Linux -from win32api import GetKeyState, keybd_event -from win32con import VK_NUMLOCK, VK_CAPITAL +if os.name == 'nt': + from win32api import GetKeyState, keybd_event + from win32con import VK_NUMLOCK, VK_CAPITAL import uf2conv @@ -118,9 +119,21 @@ def format_fw_ver(fw_ver): fw_ver_patch = (fw_ver & 0x000F) return f"{fw_ver_major}.{fw_ver_minor}.{fw_ver_patch}" + def get_numlock_state(): - # TODO: Handle Linux - return GetKeyState(VK_NUMLOCK) + if os.name == 'nt': + return GetKeyState(VK_NUMLOCK) + else: + try: + output = subprocess.run(['numlockx', 'status'], stdout=subprocess.PIPE).stdout + if b'on' in output: + return True + elif b'off' in output: + return False + except FileNotFoundError: + # Ignore tool not found, just return None + pass + def main(devices): device_checkboxes = [] @@ -187,8 +200,8 @@ def main(devices): [sg.HorizontalSeparator()], [sg.Text("OS Numlock Setting")], - [sg.Text("State: "), sg.Text("", k='-NUMLOCK-STATE-'), sg.Push() ,sg.Button("Refresh")], - [sg.Button("Send Numlock Toggle", k='-NUMLOCK-TOGGLE-')], + [sg.Text("State: "), sg.Text("", k='-NUMLOCK-STATE-'), sg.Push() ,sg.Button("Refresh", k='-NUMLOCK-REFRESH-', disabled=True)], + [sg.Button("Send Numlock Toggle", k='-NUMLOCK-TOGGLE-', disabled=True)], [sg.HorizontalSeparator()], [sg.Text("Save Settings")], @@ -201,7 +214,11 @@ def main(devices): while True: numlock_on = get_numlock_state() - if numlock_on is not None: + if numlock_on is None and os != 'nt': + window['-NUMLOCK-STATE-'].update("Unknown, please install the 'numlockx' command") + else: + window['-NUMLOCK-REFRESH-'].update(disabled=False) + window['-NUMLOCK-TOGGLE-'].update(disabled=False) window['-NUMLOCK-STATE-'].update("On (Numbers)" if numlock_on else "Off (Arrows)") event, values = window.read() @@ -234,9 +251,11 @@ def main(devices): window['-CHECKBOX-{}-'.format(dev['path'])].update(False, disabled=True) if event == "-NUMLOCK-TOGGLE-": - # TODO: Linux - keybd_event(VK_NUMLOCK, 0x3A, 0x1, 0) - keybd_event(VK_NUMLOCK, 0x3A, 0x3, 0) + if os.name == 'nt': + keybd_event(VK_NUMLOCK, 0x3A, 0x1, 0) + keybd_event(VK_NUMLOCK, 0x3A, 0x3, 0) + else: + out = subprocess.check_output(['numlockx', 'toggle']) # Run commands on all selected devices for dev in selected_devices: From 637117c071bd49711dbd58aba4c9a4f679d36ab9 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Fri, 14 Jul 2023 10:13:08 +0800 Subject: [PATCH 3/4] qmk_gui: Include fw v0.2.0 Signed-off-by: Daniel Schaefer --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dada644..77233d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -117,6 +117,12 @@ jobs: - name: Download releases to bundle run: | mkdir releases + mkdir releases\0.2.0 + Invoke-WebRequest -Uri https://github.com/FrameworkComputer/qmk_firmware/releases/download/v0.2.0/framework_ansi_default_v0.2.0.uf2 -OutFile releases\0.2.0\framework_ansi_default.uf2 + Invoke-WebRequest -Uri https://github.com/FrameworkComputer/qmk_firmware/releases/download/v0.2.0/framework_iso_default_v0.2.0.uf2 -OutFile releases\0.2.0\framework_iso_default.uf2 + Invoke-WebRequest -Uri https://github.com/FrameworkComputer/qmk_firmware/releases/download/v0.2.0/framework_jis_default_v0.2.0.uf2 -OutFile releases\0.2.0\framework_jis_default.uf2 + Invoke-WebRequest -Uri https://github.com/FrameworkComputer/qmk_firmware/releases/download/v0.2.0/framework_numpad_default_v0.2.0.uf2 -OutFile releases\0.2.0\framework_numpad_default.uf2 + Invoke-WebRequest -Uri https://github.com/FrameworkComputer/qmk_firmware/releases/download/v0.2.0/framework_macropad_default_v0.2.0.uf2 -OutFile releases\0.2.0\framework_macropad_default.uf2 mkdir releases\0.1.9 Invoke-WebRequest -Uri https://github.com/FrameworkComputer/qmk_firmware/releases/download/v0.1.9/framework_ansi_default_v0.1.9.uf2 -OutFile releases\0.1.9\framework_ansi_default.uf2 Invoke-WebRequest -Uri https://github.com/FrameworkComputer/qmk_firmware/releases/download/v0.1.9/framework_iso_default_v0.1.9.uf2 -OutFile releases\0.1.9\framework_iso_default.uf2 From 22f297c915dc35e225660402b6b92e5eedb190ed Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Fri, 14 Jul 2023 10:21:58 +0800 Subject: [PATCH 4/4] Update to v0.1.8 Signed-off-by: Daniel Schaefer --- .github/workflows/ci.yml | 2 ++ Cargo.toml | 2 +- qmk_gui.py | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 77233d1..41ebd5f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -148,6 +148,8 @@ jobs: Invoke-WebRequest -Uri https://github.com/FrameworkComputer/qmk_firmware/releases/download/v0.1.6/framework_numpad_default.uf2 -OutFile releases\0.1.6\framework_numpad_default.uf2 Invoke-WebRequest -Uri https://github.com/FrameworkComputer/qmk_firmware/releases/download/v0.1.6/framework_gridpad_default.uf2 -OutFile releases\0.1.6\framework_gridpad_default.uf2 + # To run locally, need to make sure to include the pywin32 DLL + # pyinstaller --onefile, --name "qmk_gui", --windowed, --add-data "releases;releases" --path C:\users\skype\appdata\local\packages\pythonsoftwarefoundation.python.3.11_qbz5n2kfra8p0\localcache\local-packages\Python311\site-packages\pywin32_system32 qmk_gui.py - name: Create Executable uses: JohnAZoidberg/pyinstaller-action@dont-clean with: diff --git a/Cargo.toml b/Cargo.toml index efaee06..11421ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "qmk_hid" -version = "0.1.7" +version = "0.1.8" edition = "2021" license = "BSD-3-Clause" description = "Commandline tool to interact with QMK devices via their raw HID interface" diff --git a/qmk_gui.py b/qmk_gui.py index 4de84c9..a6b9aed 100755 --- a/qmk_gui.py +++ b/qmk_gui.py @@ -20,7 +20,7 @@ # - Show connected devices # - Get firmware version -PROGRAM_VERSION = "0.1.7" +PROGRAM_VERSION = "0.1.8" FWK_VID = 0x32AC QMK_INTERFACE = 0x01