diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dada644..41ebd5f 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 @@ -142,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 b3f0d8c..a6b9aed 100755 --- a/qmk_gui.py +++ b/qmk_gui.py @@ -1,10 +1,14 @@ #!/usr/bin/env python3 import os import sys +import subprocess import time import PySimpleGUI as sg import hid +if os.name == 'nt': + from win32api import GetKeyState, keybd_event + from win32con import VK_NUMLOCK, VK_CAPITAL import uf2conv @@ -16,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 @@ -115,6 +119,22 @@ 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(): + 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 = [] for dev in devices: @@ -177,17 +197,30 @@ 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", k='-NUMLOCK-REFRESH-', disabled=True)], + [sg.Button("Send Numlock Toggle", k='-NUMLOCK-TOGGLE-', disabled=True)], [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 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() #print('Event', event) #print('Values', values) @@ -217,6 +250,13 @@ def main(devices): restart_hint() window['-CHECKBOX-{}-'.format(dev['path'])].update(False, disabled=True) + if event == "-NUMLOCK-TOGGLE-": + 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: 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