# QMKonnect - Complete Documentation ## Overview QMKonnect is a cross-platform window activity notifier for QMK keyboards that enables context-aware keyboard behavior. It monitors active window changes and communicates with your QMK keyboard via Raw HID, allowing your keyboard to automatically switch layers or execute commands based on what application you're using. ### Key Features - **Cross-Platform Support**: Works on Windows, Linux, and macOS - **Real-time Detection**: Detects window focus changes instantly - **QMK Integration**: Communicates with QMK keyboards via Raw HID - **Low Resource Usage**: Runs efficiently in the background - **Easy Configuration**: Simple setup with vendor ID and product ID ### How It Works 1. **Window Monitoring**: Watches for active window changes across your system 2. **Data Processing**: Extracts application class and window title information 3. **QMK Communication**: Sends window data to your QMK keyboard via Raw HID 4. **Layer Switching**: Your keyboard responds based on your firmware configuration ### Ecosystem Components QMKonnect works alongside other tools in the QMK notification ecosystem: - **qmk-notifier**: QMK firmware module for handling notifications - **qmk_notifier**: Core library for Raw HID communication - **QMKonnect**: This application for cross-platform window detection ## Installation Guide QMKonnect has different installation methods for each supported platform. ### Windows Installation #### MSI Installer (Recommended) 1. Download the latest MSI installer from GitHub releases 2. Run the installer as Administrator 3. The application starts automatically and is added to Windows startup The MSI installer automatically: - Installs to Program Files - Adds to Windows startup - Sets up system tray icon - Enables normal uninstallation #### Build from Source (Windows) ```bash git clone https://github.com/dabstractor/qmkonnect.git cd qmkonnect/packaging/windows ./build-installer.ps1 ``` ### Linux Installation (Hyprland Only) **Important**: QMKonnect currently only supports Hyprland window manager on Linux. Support for other window managers is not yet available. #### Arch Linux Install from AUR or build the package: ```bash git clone https://github.com/dabstractor/qmkonnect.git cd qmkonnect/packaging/linux/arch makepkg -si systemctl --user enable --now qmkonnect ``` #### Other Linux Distributions 1. Download the release binary from GitHub 2. Install the binary: ```bash chmod +x qmkonnect sudo cp qmkonnect /usr/local/bin/ ``` 3. Set up systemd service: ```bash curl https://raw.githubusercontent.com/dabstractor/qmkonnect/refs/heads/main/packaging/linux/systemd/qmkonnect.service.template | sudo tee /usr/lib/systemd/user/qmkonnect.service systemctl --user enable --now qmkonnect.service ``` 4. Set up udev rules for automatic keyboard detection: ```bash curl https://raw.githubusercontent.com/dabstractor/qmkonnect/refs/heads/main/packaging/linux/udev/99-qmkonnect.rules.template | sudo tee /etc/udev/rules.d/99-qmkonnect.rules.template qmkonnect -c sudo qmkonnect -r sudo udevadm control --reload && sudo udevadm trigger ``` ### macOS Installation #### Application Bundle 1. Download QMKonnect.app from the GitHub releases page 2. Copy QMKonnect.app to your Applications folder 3. Launch QMKonnect from Applications folder #### Build from Source (macOS) ```bash git clone https://github.com/dabstractor/qmkonnect.git cd qmkonnect/packaging/macos ./build.sh ``` Copy the generated QMKonnect.app to your /Applications folder. ### Installation Verification After installation, verify QMKonnect is working: 1. **Check if running**: - Windows: Look for system tray icon - Linux: `systemctl --user status qmkonnect` - macOS: Check menu bar icon 2. **Test configuration**: Access settings through system tray/menu bar 3. **Check logs**: - Windows/macOS: System tray interface - Linux: `journalctl --user -u qmkonnect` ## QMK Integration Guide Learn how to integrate QMKonnect with your QMK keyboard firmware to enable layer switching and context-aware features. ### Integration Overview QMKonnect communicates with QMK through Raw HID: 1. **QMKonnect** detects window changes 2. **qmk_notifier library** handles Raw HID communication 3. **qmk-notifier QMK module** receives and processes notifications 4. **Your QMK keymap** responds to window change events ### Step 1: Add QMK Notifier Module In your QMK keymap directory: ```bash git submodule add https://github.com/dabstractor/qmk-notifier.git lib/qmk-notifier ``` ### Step 2: Update rules.mk Add to your keymap's `rules.mk`: ```make # Enable Raw HID support RAW_ENABLE = yes # Include the notifier module SRC += lib/qmk-notifier/qmk_notifier.c ``` ### Step 3: Update config.h Add to your keymap's `config.h`: ```c #define VENDOR_ID 0xFEED // Your vendor ID #define PRODUCT_ID 0x0001 // Your product ID #define DEVICE_VER 0x0001 // Device version // Enable Raw HID #define RAW_USAGE_PAGE 0xFF60 #define RAW_USAGE_ID 0x61 ``` ### Step 4: Basic keymap.c Setup ```c #include QMK_KEYBOARD_H #include "raw_hid.h" #include "./qmk-notifier/notifier.h" // Forward Raw HID data to the notifier void raw_hid_receive(uint8_t *data, uint8_t length) { hid_notify(data, length); } // Define your layers #define _QWERTY 0 #define _BROWSER 1 #define _TERMINAL 2 #define _GAMING 3 // Your keymap definitions here... const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // Your layer definitions }; ``` ### Configuring Window-Based Behavior The qmk-notifier framework provides two main configuration macros: #### Layer Switching with DEFINE_SERIAL_LAYERS Automatically switch layers based on active windows: ```c DEFINE_SERIAL_LAYERS({ // Basic application matching { "*calculator*", _NUMPAD }, { "*chrome*", _BROWSER }, { "*terminal*", _TERMINAL }, // Specific window title matching { WT("*chrome*", "*jitsi*"), _JITSI }, { WT("alacritty", "terminal"), _TERMINAL }, // Gaming applications { "steam_app*", _GAMING }, { WT("cs2", "Counter-Strike 2"), _GAMING }, }); ``` #### Custom Commands with DEFINE_SERIAL_COMMANDS Execute custom functions based on window changes: ```c DEFINE_SERIAL_COMMANDS({ // Disable vim mode for specific applications { "neovide", &disable_vim_mode }, { "alacritty", &disable_vim_mode }, // Multiple commands for AI chat interfaces { WT("*chrome*", "*claude*"), &vim_insert, &disable_vim_mode }, { WT("*chrome*", "*chatgpt*"), &vim_insert, &disable_vim_mode }, // Gaming applications { WT("steam_app*", "*"), &disable_vim_mode }, }); ``` ### Framework Elements #### Available Macros - **`DEFINE_SERIAL_LAYERS`**: Maps window patterns to keyboard layers - **`DEFINE_SERIAL_COMMANDS`**: Maps window patterns to command functions - **`WT(class, title)`**: Helper macro to match both window class and title - **Wildcard matching**: Use `*` for pattern matching (e.g., `"*chrome*"`) #### Understanding Window Matching QMKonnect sends window information in this format: ``` {application_class}{GS}{window_title} ``` Where `{GS}` is the Group Separator character (ASCII 0x1D). Examples: - VS Code: `code{GS}main.rs - qmkonnect` - Firefox: `firefox{GS}GitHub - Mozilla Firefox` - Terminal: `terminal{GS}~/projects/qmkonnect` ### Pattern Matching Examples ```c // Match any calculator app { "*calculator", _NUMPAD } // Match specific browser with specific site { WT("*chrome*", "*jitsi*"), _JITSI } // Match terminal with specific title { WT("alacritty", "terminal"), _TERMINAL } // Match any Steam game { "steam_app*", _GAMING } // Match specific game by both class and title { WT("cs2", "Counter-Strike 2"), _GAMING } ``` ### Compiling Your Firmware After adding the qmk-notifier integration: ```bash # In your QMK firmware directory qmk compile -kb your_keyboard -km your_keymap # Flash to keyboard qmk flash -kb your_keyboard -km your_keymap ``` ### Testing Your Integration #### Basic Verification 1. **Compile and flash** your firmware with the integration 2. **Install and configure** QMKonnect with your keyboard's vendor/product IDs 3. **Test communication** by switching between different applications #### Debug Output Add console output to your keymap for debugging: ```c #ifdef CONSOLE_ENABLE void qmk_notifier_notify(const char* app_class, const char* window_title) { printf("App: %s, Title: %s\n", app_class, window_title); // Your layer switching logic here } #endif ``` Then monitor QMK console output: ```bash qmk console ``` ## Configuration Guide This guide covers configuring QMKonnect to communicate with your keyboard. You only need to provide two values: your keyboard's vendor ID and product ID. ### Windows & macOS Configuration Both Windows and macOS use a settings dialog through the system tray: 1. **Find the system tray icon** (QMKonnect icon in your system tray/menu bar) 2. **Right-click the icon** and select "Settings" 3. **Enter your keyboard IDs**: - **Vendor ID**: Your keyboard's vendor ID in hex format (e.g., `feed`) - **Product ID**: Your keyboard's product ID in hex format (e.g., `0000`) 4. **Click OK** to save Settings are saved automatically and work immediately - no restart needed. ### Linux Configuration Linux uses a TOML configuration file located at `~/.config/qmk-notifier/config.toml`. #### Creating the Configuration File ```bash qmkonnect -c ``` This creates a default configuration file: ```toml # QMKonnect Configuration # Your QMK keyboard's vendor ID (in hex) vendor_id = 0xfeed # Your QMK keyboard's product ID (in hex) product_id = 0x0000 # Add any other configuration options here ``` #### Editing the Configuration ```bash # Using your preferred editor nano ~/.config/qmk-notifier/config.toml ``` Update the values: ```toml vendor_id = 0x1234 # Replace with your keyboard's vendor ID product_id = 0x5678 # Replace with your keyboard's product ID ``` #### Reloading Configuration (Linux Only) After editing the configuration file: ```bash qmkonnect -r ``` This updates system configuration (udev rules) and reloads settings. ### Finding Your Keyboard IDs #### Method 1: QMK Configuration Check your QMK `config.h`: ```c #define VENDOR_ID 0xFEED #define PRODUCT_ID 0x0000 ``` #### Method 2: System Tools **Windows (PowerShell):** ```powershell Get-WmiObject -Class Win32_USBHub | Where-Object {$_.Name -like "*keyboard*"} ``` **Linux:** ```bash lsusb lsusb -v | grep -A 5 -B 5 "keyboard\|Keyboard" cat /sys/class/hidraw/hidraw*/device/uevent ``` **macOS:** ```bash system_profiler SPUSBDataType | grep -A 10 -B 10 "keyboard\|Keyboard" ioreg -p IOUSB | grep -A 10 -B 10 "keyboard\|Keyboard" ``` ### Configuration Examples #### Basic Configuration (Linux) ```toml # Minimal configuration - just keyboard IDs vendor_id = 0xfeed product_id = 0x0000 ``` #### Custom Keyboard IDs (Linux) ```toml # Example with different keyboard IDs vendor_id = 0x1234 product_id = 0x5678 ``` ### Validation After configuration, test that QMKonnect can detect your keyboard: #### Windows & macOS Check the system tray/menu bar icon - it should show as connected. #### Linux ```bash # Test with verbose output to see if keyboard is detected qmkonnect -v ``` If you see "Keyboard detected" messages, you're ready to use QMKonnect. ## Usage Guide QMKonnect runs in the background, automatically detecting window changes and communicating with your QMK keyboard. Here's how to start, stop, and manage the application. ### Starting QMKonnect #### Windows - **Automatic startup**: If installed via MSI, starts automatically with Windows - **Manual start**: Find "QMKonnect" in Start Menu or double-click desktop shortcut - **System tray**: Look for the QMKonnect icon in your system tray when running #### Linux - **Automatic startup**: `systemctl --user enable qmkonnect` (runs on login) - **Manual start**: `qmkonnect` or `systemctl --user start qmkonnect` - **Check status**: `systemctl --user status qmkonnect` #### macOS - **Manual start**: Launch QMKonnect.app from Applications folder - **Menu bar**: Look for the QMKonnect icon in your menu bar when running ### Stopping QMKonnect #### Windows Right-click the system tray icon and select "Quit" #### Linux ```bash systemctl --user stop qmkonnect ``` #### macOS Quit from the menu bar icon or application menu ### Auto-Start on Boot #### Windows Auto-start is automatically configured when using the MSI installer. To disable: 1. Open Task Manager → Startup tab 2. Find "QMKonnect" and disable it #### Linux ```bash # Enable auto-start on login systemctl --user enable qmkonnect # Disable auto-start systemctl --user disable qmkonnect ``` #### macOS 1. System Preferences → Users & Groups → Login Items 2. Add QMKonnect.app to start automatically ### How It Works Once running, QMKonnect automatically: 1. **Monitors window changes** - detects when you switch between applications 2. **Extracts window information** - gets the application name and window title 3. **Sends data to your keyboard** - your QMK firmware receives this information 4. **Triggers layer changes** - your keyboard responds based on your configuration The magic happens in your QMK firmware configuration - QMKonnect just provides the window information your keyboard needs to make intelligent decisions. ### System Integration #### Windows - **System tray integration**: Right-click the tray icon for settings and status - **Runs in background**: Minimal resource usage - **Auto-updates**: Receives automatic updates when available #### Linux - **Systemd service**: Integrates with your system's service management - **Hyprland support**: Currently supports Hyprland window manager only - **Lightweight**: Designed for minimal system impact #### macOS - **Menu bar integration**: Access settings and status from the menu bar - **Accessibility permissions**: Requires one-time setup for window monitoring - **Native app bundle**: Standard macOS application behavior ### What QMKonnect Enables With QMKonnect running, your keyboard becomes context-aware: - **Development environments**: Automatically switch to coding-focused layouts when opening IDEs - **Gaming**: Enter gaming mode when launching games - **Browser work**: Activate browser-specific shortcuts and layers - **Terminal usage**: Switch to terminal-optimized layouts - **Media control**: Enable media keys when using music/video applications The behavior is entirely customized in your QMK firmware - QMKonnect just provides the window information your keyboard needs. ### Status and Monitoring #### Check if QMKonnect is Running - **Windows**: Look for the QMKonnect icon in your system tray - **Linux**: `systemctl --user status qmkonnect` - **macOS**: Look for the QMKonnect icon in your menu bar #### Verify Keyboard Connection If your layers aren't switching as expected: 1. Check that QMKonnect shows as "connected" in the system tray/menu bar 2. Verify your QMK firmware is properly configured with the qmk-notifier module 3. Test by switching between different applications ## Real-World Examples Complete examples showing how to configure QMKonnect and QMK firmware for different use cases. ### Example 1: Developer Setup **Scenario**: A developer who uses VS Code, Terminal, and browsers, wanting different layouts for each context. #### QMK Keymap Configuration ```c #include QMK_KEYBOARD_H #include "raw_hid.h" #include "./lib/qmk-notifier/notifier.h" void raw_hid_receive(uint8_t *data, uint8_t length) { hid_notify(data, length); } // Layer definitions #define _QWERTY 0 #define _CODE 1 #define _TERMINAL 2 #define _BROWSER 3 DEFINE_SERIAL_LAYERS({ // Development environments { "*code*", _CODE }, // VS Code, VSCodium { "*neovim*", _CODE }, // Neovim { "*jetbrains*", _CODE }, // IntelliJ, PyCharm, etc. // Terminal applications { "*terminal*", _TERMINAL }, // Generic terminal { "*alacritty*", _TERMINAL }, // Alacritty { "*iterm*", _TERMINAL }, // iTerm (macOS) // Browsers { "*chrome*", _BROWSER }, // Chrome { "*firefox*", _BROWSER }, // Firefox { "*safari*", _BROWSER }, // Safari }); const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_QWERTY] = LAYOUT( // Your standard QWERTY layout ), [_CODE] = LAYOUT( // Coding-optimized layout with easy access to: // - Brackets, braces, parentheses // - Common programming symbols // - Function keys for debugging ), [_TERMINAL] = LAYOUT( // Terminal-focused layout: // - Easy access to Ctrl combinations // - Arrow keys, Page Up/Down // - Common shell shortcuts ), [_BROWSER] = LAYOUT( // Browser navigation layout: // - Tab management shortcuts // - Bookmarks, history navigation // - Zoom controls ), }; ``` **Result**: Your keyboard automatically switches to the appropriate layer when you switch between VS Code (coding layer), Terminal (terminal layer), and your browser (browser layer). ### Example 2: Gaming & Productivity **Scenario**: A user who games and does office work, wanting to disable certain keys during games. #### QMK Keymap Configuration ```c #include QMK_KEYBOARD_H #include "raw_hid.h" #include "./lib/qmk-notifier/notifier.h" void raw_hid_receive(uint8_t *data, uint8_t length) { hid_notify(data, length); } #define _QWERTY 0 #define _GAMING 1 #define _OFFICE 2 // Custom functions void enable_gaming_mode(void) { // Disable Windows key, Alt-Tab, etc. // Implementation depends on your needs } void disable_gaming_mode(void) { // Re-enable all keys } DEFINE_SERIAL_LAYERS({ // Gaming applications { "steam_app*", _GAMING }, // Any Steam game { "*minecraft*", _GAMING }, // Minecraft { WT("cs2", "*"), _GAMING }, // Counter-Strike 2 { "*valorant*", _GAMING }, // Valorant // Office applications { "*word*", _OFFICE }, // Microsoft Word { "*excel*", _OFFICE }, // Microsoft Excel { "*powerpoint*", _OFFICE }, // PowerPoint { "*outlook*", _OFFICE }, // Outlook }); DEFINE_SERIAL_COMMANDS({ // Enable gaming mode for any game { "steam_app*", &enable_gaming_mode }, { "*minecraft*", &enable_gaming_mode }, { WT("cs2", "*"), &enable_gaming_mode }, // Disable gaming mode for productivity apps { "*word*", &disable_gaming_mode }, { "*excel*", &disable_gaming_mode }, }); const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_QWERTY] = LAYOUT( // Standard layout ), [_GAMING] = LAYOUT( // Gaming layout: // - WASD optimized positioning // - Easy access to F1-F12 // - Disabled Windows key // - Gaming-specific macros ), [_OFFICE] = LAYOUT( // Office productivity: // - Common shortcuts (Ctrl+C, Ctrl+V, etc.) // - Number row easily accessible // - Office-specific function keys ), }; ``` **Result**: When you launch any Steam game, your keyboard switches to gaming mode and disables problematic keys. When you switch to office applications, it switches to a productivity-focused layout. ### Example 3: Content Creation Setup **Scenario**: A content creator using different applications for video editing, streaming, and social media. #### QMK Keymap Configuration ```c #include QMK_KEYBOARD_H #include "raw_hid.h" #include "./lib/qmk-notifier/notifier.h" void raw_hid_receive(uint8_t *data, uint8_t length) { hid_notify(data, length); } #define _QWERTY 0 #define _VIDEO 1 #define _STREAMING 2 #define _SOCIAL 3 DEFINE_SERIAL_LAYERS({ // Video editing { "*premiere*", _VIDEO }, // Adobe Premiere Pro { "*davinci*", _VIDEO }, // DaVinci Resolve { "*final*cut*", _VIDEO }, // Final Cut Pro // Streaming software { "*obs*", _STREAMING }, // OBS Studio { "*streamlabs*", _STREAMING }, // Streamlabs // Social media & communication { "*discord*", _SOCIAL }, // Discord { "*slack*", _SOCIAL }, // Slack { "*twitter*", _SOCIAL }, // Twitter/X { WT("*chrome*", "*youtube*"), _SOCIAL }, // YouTube in browser }); const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_QWERTY] = LAYOUT( // Standard layout ), [_VIDEO] = LAYOUT( // Video editing shortcuts: // - Timeline navigation // - Cut, copy, paste optimized // - Playback controls // - Common effects shortcuts ), [_STREAMING] = LAYOUT( // Streaming controls: // - Scene switching // - Mute/unmute shortcuts // - Stream start/stop // - Chat interaction keys ), [_SOCIAL] = LAYOUT( // Social media optimized: // - Emoji shortcuts // - Quick reactions // - Navigation shortcuts // - Typing-focused layout ), }; ``` **Result**: Your keyboard adapts to your workflow - switching to video editing shortcuts in Premiere Pro, streaming controls in OBS, and social media optimizations in Discord or when managing YouTube. ### Pattern Matching Tips #### Understanding Window Matching - **Wildcards**: Use `*` to match partial strings - `"*chrome*"` matches Google Chrome, Chromium, Chrome Canary - `"steam_app*"` matches any Steam game - **Window Title Matching**: Use `WT(class, title)` for specific windows - `WT("*chrome*", "*youtube*")` - YouTube in Chrome - `WT("*code*", "*.rs")` - Rust files in VS Code #### Common Patterns ```c // Match any calculator app { "*calc*", _NUMPAD } // Match specific browser + website { WT("*chrome*", "*github*"), _CODING } // Match file manager { "*nautilus*", _FILES } { "*finder*", _FILES } { "*explorer*", _FILES } // Match any terminal { "*term*", _TERMINAL } // Match specific game by exact title { WT("cs2", "Counter-Strike 2"), _GAMING } ``` ### Testing Your Configuration 1. **Compile and flash** your firmware 2. **Configure QMKonnect** with your keyboard's vendor/product IDs 3. **Test layer switching** by switching between applications 4. **Check QMK console** output for debugging: ```bash qmk console ``` ## Troubleshooting Guide Common issues and solutions for QMKonnect across different platforms. ### Debugging Tools Before diving into specific issues, familiarize yourself with these debugging tools: #### Linux Command Line Options ```bash qmkonnect [OPTIONS] Options: -c, --config Create a default configuration file -r, --reload Reload configuration from file -v, --verbose Enable verbose logging --debug Maximum verbosity for debugging --test-connection Test keyboard connection -h, --help Show help information -V, --version Show version information ``` #### Verbose Logging Run with verbose logging to see all activity: ```bash # Linux qmkonnect -v # Shows: # - Window change events # - Application detection # - Data sent to keyboard # - Connection status # - Error messages ``` #### Debug Mode (Linux) For detailed troubleshooting: ```bash qmkonnect --debug # Shows: # - Raw window data # - Filtering decisions # - Communication protocol details # - Timing information ``` #### View Logs **Linux (systemd):** ```bash # View logs journalctl --user -u qmkonnect -f # Check service status systemctl --user status qmkonnect ``` **Windows & macOS:** Access logs through the system tray/menu bar interface. ### General Issues #### QMKonnect Won't Start **Symptoms**: App doesn't start or exits immediately **Solutions**: 1. **Check configuration file**: ```bash qmkonnect -c # Create default config qmkonnect -v # Run with verbose output ``` 2. **Check dependencies**: Make sure required libraries are installed 3. **Run with debug output**: ```bash qmkonnect --debug ``` 4. **Check permissions**: - Linux: User in `input` and `plugdev` groups - macOS: Accessibility permissions granted - Windows: Run as Administrator if needed #### Keyboard Not Detected **Symptoms**: QMKonnect runs but doesn't communicate with keyboard, layers don't switch **Quick Diagnosis**: ```bash # Linux - test keyboard connection qmkonnect --test-connection # Check if keyboard shows up in verbose mode qmkonnect -v | grep -i "keyboard\|detect\|connect" ``` **Find Available HID Devices**: ```bash # Linux: ls -la /dev/hidraw* cat /sys/class/hidraw/hidraw*/device/uevent | grep -E "HID_ID|HID_NAME" # Windows (PowerShell): Get-WmiObject -Class Win32_USBHub | Where-Object {$_.Name -like "*keyboard*"} # macOS: system_profiler SPUSBDataType | grep -A 10 -B 10 -i keyboard ``` **Solutions**: 1. **Verify keyboard configuration**: - Check vendor_id and product_id in config - Ensure Raw HID is enabled in QMK firmware - Confirm qmk-notifier module is included 2. **Check QMK firmware**: ```c // In rules.mk RAW_ENABLE = yes // In config.h #define RAW_USAGE_PAGE 0xFF60 #define RAW_USAGE_ID 0x61 ``` 3. **Permission issues (Linux)**: ```bash # Add user to groups sudo usermod -a -G input,plugdev $USER # Install udev rules sudo cp packaging/linux/udev/99-qmkonnect.rules.template /etc/udev/rules.d/99-qmkonnect.rules sudo udevadm control --reload && sudo udevadm trigger ``` #### Window Detection Not Working **Symptoms**: QMKonnect runs but doesn't detect window changes, keyboard doesn't switch layers when changing applications **Debugging Steps**: 1. **Check verbose output for window events**: ```bash # Linux qmkonnect -v | grep -i "window\|app\|title" # You should see messages like: # "Window changed: firefox -> Visual Studio Code" # "Sending: code{GS}main.rs - qmkonnect" ``` 2. **Test window information format**: QMKonnect sends data in this format: `{application_class}{GS}{window_title}` Where `{GS}` is Group Separator (ASCII 0x1D). Examples: - VS Code: `code{GS}main.rs - qmkonnect` - Firefox: `firefox{GS}GitHub - Mozilla Firefox` - Terminal: `terminal{GS}~/projects/qmkonnect` **Platform-specific solutions**: **Windows** ```bash # Check if window hooks are working qmkonnect -v # Look for "Window changed" messages ``` **Linux (Hyprland Only)** ```bash # Check Hyprland integration echo $HYPRLAND_INSTANCE_SIGNATURE # Test Hyprland socket manually socat -u UNIX-CONNECT:/tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock - | head -10 # Should show window events when you switch applications ``` **Note**: Only Hyprland is supported on Linux. Other window managers are not supported yet. **macOS** 1. **Grant Accessibility permissions** (required for window monitoring): - System Preferences → Security & Privacy → Privacy - Select "Accessibility" from left panel - Add QMKonnect to allowed applications 2. **Test window detection**: ```bash # Run from terminal to see debug output ./QMKonnect.app/Contents/MacOS/qmkonnect -v ``` ### Communication Issues #### Data Not Reaching Keyboard **Symptoms**: Window detection works, but keyboard layers don't change **Debug QMKonnect → Keyboard Communication**: 1. **Verify data is being sent** (Linux): ```bash # Show what data is being sent to keyboard qmkonnect --debug | grep -i "sending\|data" # Test connection specifically qmkonnect --test-connection ``` 2. **Check QMK firmware side**: Add debug output to your QMK keymap: ```c #ifdef CONSOLE_ENABLE void qmk_notifier_notify(const char* app_class, const char* window_title) { printf("Received: app='%s', title='%s'\n", app_class, window_title); // Your layer switching logic here } #endif ``` Then monitor QMK console: ```bash qmk console ``` 3. **Verify Raw HID setup**: Ensure your QMK firmware has: ```make # In rules.mk RAW_ENABLE = yes ``` ```c // In config.h #define RAW_USAGE_PAGE 0xFF60 #define RAW_USAGE_ID 0x61 ``` ### Platform-Specific Issues #### Windows Issues **System Tray Icon Missing** Solutions: 1. Check if running as tray app 2. Restart Windows Explorer 3. Check system tray settings in Windows settings **Multiple Instances Running** Solutions: 1. Kill all instances: `taskkill /f /im qmkonnect.exe` 2. Start single instance 3. Check startup folder for duplicates #### Linux Issues **Systemd Service Fails** Check service status: ```bash systemctl --user status qmkonnect journalctl --user -u qmkonnect -f ``` Common fixes: 1. Reinstall service file 2. Update binary path in service file 3. Check dependencies **Hyprland Integration Issues** Check Hyprland socket: ```bash # Verify socket exists ls -la /tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/ # Test socket communication socat -u UNIX-CONNECT:/tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock - | head -10 ``` #### macOS Issues **Accessibility Permissions** Grant permissions: 1. System Preferences → Security & Privacy → Privacy 2. Select "Accessibility" from left panel 3. Add QMKonnect to allowed applications **Application Bundle Issues** Solutions: 1. Rebuild application bundle 2. Check code signing 3. Reset application permissions ### Performance Issues #### High CPU Usage Monitor CPU usage and check for: 1. Increased polling interval 2. Application filtering 3. Infinite loops in logs #### Memory Leaks Monitor memory usage and check for memory leaks using system tools. ### Getting Debug Information When reporting issues, include: 1. **System information**: OS version, architecture 2. **QMKonnect version**: `qmkonnect --version` 3. **Debug output**: `qmkonnect --debug > debug.log 2>&1` 4. **Configuration file**: Content (remove sensitive data) 5. **Steps to reproduce**: Clear reproduction steps 6. **Expected vs actual behavior**: What should happen vs what happens ### Where to Get Help - **GitHub Issues**: https://github.com/dabstractor/qmkonnect/issues - **QMK Discord**: #help channel - **Documentation**: This guide and README files --- This comprehensive guide covers all aspects of QMKonnect from installation through advanced troubleshooting. For the most up-to-date information, always refer to the official documentation and GitHub repository.