d00c4aa371
Add a Rust daemon that connects to QMK keyboards over their Raw HID interface (VID 0x3434, usage page 0xFF60 / usage 0x0061) and provides: - Bi-directional layer sync: CMD_LAYER_SYNC (0x40) packets are bridged between all connected keyboards so their active layers stay in sync. On connect, a FLAG_QUERY packet requests the current state from each keyboard. A second keyboard (numpad) is stubbed and ready to enable. - Volume monitoring: polls `pactl get-sink-volume @DEFAULT_SINK@` every 2 s and pushes CMD_VOLUME (0x41) packets on change. Compatible with both PulseAudio and PipeWire on KDE6/Wayland. - Brightness monitoring: polls /sys/class/backlight on the same interval and pushes CMD_BRIGHTNESS (0x42) packets on change. - Active-app stub: CMD_ACTIVE_APP (0x43) is reserved with detailed notes on KDE6/Wayland implementation approaches (KWin D-Bus, foreign toplevel protocol) for a future commit. Each keyboard runs a single combined read/write IO thread using a 10 ms read timeout to interleave HID reads and queued writes without needing two file handles. Protocol constants in src/protocol.rs mirror hid_protocol.h in the QMK firmware exactly. Licensed under GPL-3.0-or-later.
47 lines
1.9 KiB
Rust
47 lines
1.9 KiB
Rust
// Copyright 2026 rootiest
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
//! Active application / window monitor — **reserved, not yet implemented**.
|
|
//!
|
|
//! When implemented this module will detect the active window on a KDE6
|
|
//! Wayland desktop and send `CMD_ACTIVE_APP` (0x43) packets containing the
|
|
//! application name (null-terminated UTF-8, max 28 bytes) to all connected
|
|
//! keyboards.
|
|
//!
|
|
//! # Implementation notes for KDE6 / Wayland
|
|
//!
|
|
//! Candidate approaches (to evaluate during the brainstorming phase):
|
|
//!
|
|
//! 1. **KWin D-Bus interface** — `org.kde.KWin` exposes `activeWindow()` on
|
|
//! the scripting API. The window object has `resourceName` / `caption`
|
|
//! properties. Can subscribe to `windowActivated` signal.
|
|
//! → easiest; requires D-Bus session access.
|
|
//!
|
|
//! 2. **KWin Script** — inject a tiny `.kwinscript` that emits a custom
|
|
//! D-Bus signal or writes to a FIFO on `windowActivated`.
|
|
//! → portable across KWin versions; slightly invasive.
|
|
//!
|
|
//! 3. **`xdg-foreign` / `wlr-foreign-toplevel`** — Wayland protocols for
|
|
//! enumerating toplevels. KWin supports `ext-foreign-toplevel-list-v1`.
|
|
//! → protocol-level, no D-Bus, but requires a Wayland client loop.
|
|
//!
|
|
//! 4. **`qdbus6` / `busctl` polling** — parse output of
|
|
//! `busctl call org.kde.KWin /KWin org.kde.KWin activeWindow`
|
|
//! in a poll loop. Simple but coarse.
|
|
//!
|
|
//! The chosen approach will be implemented here once the brainstorming is
|
|
//! complete. The `Packet::active_app()` constructor in `protocol.rs` is
|
|
//! already in place.
|
|
|
|
use log::info;
|
|
|
|
use crate::keyboard::Keyboard;
|
|
|
|
/// Monitor the active application and notify keyboards.
|
|
/// Currently a no-op stub — safe to call, does nothing.
|
|
pub fn monitor(_keyboards: Vec<Keyboard>) {
|
|
info!("Active-application monitor: not yet implemented (stub)");
|
|
// Future: block here in an event loop and send Packet::active_app()
|
|
// packets to keyboards whenever the active window changes.
|
|
}
|