Где-то неделю назад я прочитал статью: Индикация раскладки клавиатуры подсветкой — решение для GNOME. И что-то так вдохновился, что решил сделать что-то подобное для себя, у меня KDE. Начал делать, воспроизвёл подсветку одним цветом достаточно быстро, а потом решил, может, улучшить и рисовать прямо флаг страны относительно языка раскладки? И кажется получилось неплохо и весело.
https://github.com/jidckii/kolor-keyboard

⚠️ AI Дисклеймер
Этот проект почти полностью сгенерирован с помощью AI Claude Code.
Использование на свой страх и риск. Автор проекта не несёт ответственности за любые последствия, включая возможные проблемы с вашим аппаратным или программным обеспечением.
Ну во-превых в KDE всё как у людей, есть просто D-BUS на ивенты которого мы подписываемся и получаем Layouts, по сути можно это даже в bash отслеживать индекс лейаута.
$ qdbus6 org.kde.keyboard /Layouts org.kde.KeyboardLayouts.getLayout 0 $ qdbus6 org.kde.keyboard /Layouts org.kde.KeyboardLayouts.getLayout 1

Ну, это было, пожалуй, самым простым, а что там с клавиатурой то самой? Ну естественно умные люди всё там сделали правильно, есть стандартный протокол, есть библиотеки, инструменты, короче никаких велосипедов.
Так что там под капотом?
Да чёрт его знает, я лишь примерно представляю что там за протокол, и не занимался его отладкой, но если сильно интересно, то вот можете почитать )))
Протокол передачи цветов на клавиатуру HID Raw — транспортный уровень Клавиатуры с прошивкой VIA/Vial используют HID Raw interface для обмена данными: Usage Page: 0xFF60 (vendor-defined) Usage: 0x61 Размер пакета: 32 байта Это стандартный интерфейс VIA, который позволяет обходить обычный HID keyboard протокол и напрямую общаться с прошивкой. Два протокола управления RGB 1. VIA RGB Matrix (stock прошивка) Используется для глобального цвета на всех клавишах: Пакет: [0x07, 0x03, cmd, value1, value2, ...] │ │ │ │ │ └── команда (brightness=0x01, effect=0x02, color=0x04) │ └── канал RGB Matrix (0x03) └── id_lighting_set_value Пример установки цвета (protocol.go:111-120): packet[0] = 0x07 // CmdVIASetValue packet[1] = 0x03 // ChannelRGBMatrix packet[2] = 0x04 // RGBMatrixColor packet[3] = hue // H (0-255) packet[4] = sat // S (0-255) 2. Vial RGB Direct (vial прошивка) Позволяет управлять каждым LED отдельно (per-key RGB): Включение режима: [0x07, 0x41, 0x01, 0x00, speed, H, S, V] │ └── mode=1 (Direct) └── vialrgb_set_mode Установка LED: [0x07, 0x42, start_lo, start_hi, count, H,S,V, H,S,V, ...] │ └── начальный индекс LED (16-bit) └── vialrgb_direct_fastset Один пакет вмещает до 9 LED (32-5)/3 = 9 цветов в формате HSV. Цветовая модель Используется HSV (0-255) в стиле QMK/Vial, а не стандартный HSV (0-360, 0-100, 0-100). Автоопределение прошивки При запуске программа отправляет команду vialrgb_get_number_leds (0x08, 0x43). Если ответ содержит количество LED > 0 — это Vial прошивка. Если 0 или ошибка — stock. --- Зачем нужен hidapitester https://github.com/todbot/hidapitester — это CLI утилита для отправки сырых HID пакетов. Он был необходим для reverse engineering и отладки: 1. Проверка доступа к устройству hidapitester --vidpid 3434:0331 --usagePage 0xFF60 --usage 0x61 --open Позволяет убедиться, что HID устройство открывается и udev права настроены правильно. 2. Ручная отправка команд для изучения протокола # Запросить количество LED (проверка Vial) hidapitester --vidpid 3434:0331 --usagePage 0xFF60 --usage 0x61 --open \ --send-output 0x08,0x43 --read-input Это позволяло экспериментировать с командами VIA/Vial протокола: - Понять формат пакетов - Найти правильные command ID - Проверить ответы клавиатуры 3. Отладка проблем Когда Go код не работал, можно было проверить — проблема в коде или в самой клавиатуре: # Установить красный цвет (VIA RGB Matrix) hidapitester --vidpid 3434:0331 --usagePage 0xFF60 --usage 0x61 --open \ --send-output 0x07,0x03,0x04,0x00,0xFF --read-input 4. Документирование протокола Результаты экспериментов с hidapitester помогли создать документацию в docs/FIRMWARE.md:190-193 для проверки работоспособности прошивки. --- Схема взаимодействия ┌─────────────────┐ HID Raw (32 bytes) ┌──────────────────┐ │ kolor-keyboard │ ─────────────────────────▶ │ QMK/Vial │ │ (Go + go-hid) │ │ Firmware │ │ │ ◀───────────────────────── │ │ └─────────────────┘ Response └──────────────────┘ │ │ │ D-Bus │ PWM ▼ ▼ ┌─────────────────┐ ┌──────────────────┐ │ KDE Plasma 6 │ │ RGB LED Matrix │ │ (раскладка) │ │ (per-key) │ └─────────────────┘ └──────────────────┘
Но если вы вдруг решите отлаживать всё руками, то вам определённо понадобится https://github.com/todbot/hidapitester, я начал с него но потом быстро скатился в чат с Claude.
Установка
Тут я постарался заморочиться, так как сам не люблю когда у софта нет нормальной дистрибуции, по этому есть сборки, есть пакеты, есть репозитории под все популярные и не очень дистрибутивы.
Подробнее есть блок про установку тут.
Можете и руками собрать, но тогда не забудьте добавить правила для udev rules (есть в репозитории scripts/udev как инструкция после выполнения discover) и установить зависимости:
deb -
libhidapi-hidraw0suse -
libhidapi-hidraw0rhel -
hidapi(находится в epel)alt linux -
libhidapiarch linux -
hidapi
Настройка
После установки у вас будет по сути только сама программа, но нужно ещё сгенерировать конфиг и создать сервис для работы в фоне.
Генерация конфига
Для генерации конфига есть отдельная команда - kolor-keyboard discover она обнаружит и идентифицирует вашу клавиатуру и сгенерирует пример конфигурации в текущий каталог в папку keyboards , для генерации уже рабочей конфигурации нужно запустить kolor-keyboard discover --global , тогда конфиг сохранится уже в стандартный путь в рабочем каталоге пользователя ~/.config/kolor-keyboard/ .
Конфигурация стоковых прошивок QMK выглядит так:
# kolor-keyboard configuration # Generated for: Keychron Keychron V3 # Keyboard: keychron/v3/ansi_encoder # Device: VID=3434 PID=0331, Firmware: stock mode: mono # Global RGB settings brightness: 200 # 0-255 colors: # Russian - red (flag color) - layout: ru color: {rgb: {r: 255, g: 0, b: 0}} # English - blue - layout: us color: {hsv: {h: 170, s: 255, v: 180}} # Fallback - green - layout: "*" color: {rgb: {r: 0, g: 255, b: 0}}
Стоковые прошивки не поддерживают direct mode и не позволяют управлять цветами отдельных LED по этому mode всегда mono. С помощью brightness задаётся яркость. В блоке colors список из языков с кодом лейаута и задаём цвет в rgb или hsv формате.
Если вы прошили клавиатуру на Vial прошивку, то появляется поддержка direct mode и можно уже отправлять отдельный цвет на каждую клавишу, но чтобы было удобнее рисовать ряды, нужно их разметить, а так как у всех клавиатур количество клавиш и рядов может быть разным, мы размечаем это в ручную. Выглядит это примерно так:

Вывод в консоли kolor-keyboard discover с разметкой рядов.
$ kolor-keyboard discover ╔══════════════════════════════════════════════════════════════╗ ║ kolor-keyboard - Keyboard Discovery ║ ╚══════════════════════════════════════════════════════════════╝ Scanning for VIA/Vial compatible keyboards... Found 1 device(s): [1] Keychron Keychron V3 VID: 0x3434 PID: 0x0331 Using: Keychron Keychron V3 Checking Vial support... ✓ Vial firmware detected! LED count: 87 Do you want to map LED rows for per-key RGB (draw mode)? [Y/n]: ╔══════════════════════════════════════════════════════════════╗ ║ LED Mapping Tour ║ ╠══════════════════════════════════════════════════════════════╣ ║ Detected 87 LEDs (indices 0-86) ║ ║ ║ Commands: ║ ║ Enter/n - next LED (add to current row) ║ ║ r - end row here (add LED and start new row) ║ ║ s - skip this LED (don't add to any row) ║ ║ b - go back (undo last LED) ║ ║ q - quit and save ║ ║ ║ ║ Colors: ║ ║ RED - current LED ║ ║ GREEN - current row LEDs ║ ║ YELLOW - saved rows (different shades per row) ║ ╚══════════════════════════════════════════════════════════════╝ [Row 0] LED 0/86 (row has 0 LEDs) > [Row 0] LED 1/86 (row has 1 LEDs) > [Row 0] LED 2/86 (row has 2 LEDs) > [Row 0] LED 3/86 (row has 3 LEDs) > [Row 0] LED 4/86 (row has 4 LEDs) > [Row 0] LED 5/86 (row has 5 LEDs) > [Row 0] LED 6/86 (row has 6 LEDs) > [Row 0] LED 7/86 (row has 7 LEDs) > [Row 0] LED 8/86 (row has 8 LEDs) > [Row 0] LED 9/86 (row has 9 LEDs) > [Row 0] LED 10/86 (row has 10 LEDs) > [Row 0] LED 11/86 (row has 11 LEDs) > [Row 0] LED 12/86 (row has 12 LEDs) > [Row 0] LED 13/86 (row has 13 LEDs) > [Row 0] LED 14/86 (row has 14 LEDs) > [Row 0] LED 15/86 (row has 15 LEDs) > к [Row 0] LED 15/86 (row has 15 LEDs) > r → Row 0 saved: [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15] (16 LEDs)
На выходе для Vial прошивок используется или такой же mode: mono или уже mode: draw и тут мы можем задавать цвет каждой кнопке отдельно. Вот пример моего конфига:
# kolor-keyboard configuration # Generated for: Keychron Keychron V3 # Keyboard: keychron/v3/ansi_encoder # Device: VID=3434 PID=0331, Firmware: vial mode: draw # Global RGB settings brightness: 180 # 0-255 # LED layout (generated by discover) keyboard: rows: # Row 0 (16 LEDs) - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] # Row 1 (17 LEDs) - [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32] # Row 2 (17 LEDs) - [33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49] # Row 3 (13 LEDs) - [50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62] # Row 4 (13 LEDs) - [63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75] # Row 5 (11 LEDs) - [76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86] draw: # Russian - tricolor flag (white/blue/red) - layout: ru stripes: - rows: [0, 1] color: {rgb: {r: 255, g: 255, b: 255}} # white - rows: [2, 3] color: {rgb: {r: 0, g: 50, b: 255}} # blue - rows: [4, 5] color: {rgb: {r: 255, g: 0, b: 0}} # red # English - blue - layout: us stripes: # Синий canton (левый верхний угол, 3 ряда по 7 клавиш) - leds: [0, 1, 2, 3, 4, 5, 6] # Row 0: ESC, F1-F6 color: {hsv: {h: 170, s: 255, v: 180}} - leds: [16, 17, 18, 19, 20, 21, 22] # Row 1: ~, 1-6 color: {hsv: {h: 170, s: 255, v: 180}} - leds: [33, 34, 35, 36, 37, 38, 39] # Row 2: Tab, Q-Y color: {hsv: {h: 170, s: 255, v: 180}} # Красные полосы (начинаются справа от canton + целые ряды) - leds: [7, 8, 9, 10, 11, 12, 13, 14, 15] # Row 0 right: F7-Light color: {rgb: {r: 255, g: 0, b: 0}} - leds: [40, 41, 42, 43, 44, 45, 46, 47, 48, 49] # Row 2 right: U-PgDn color: {rgb: {r: 255, g: 0, b: 0}} - rows: [4] # Row 4 full: LShift-Up (LED 63-75) color: {rgb: {r: 255, g: 0, b: 0}} # Белые полосы - leds: [23, 24, 25, 26, 27, 28, 29, 30, 31, 32] # Row 1 right: 7-PgUp color: {hsv: {h: 0, s: 0, v: 255}} - rows: [3] # Row 3 full: Caps-Enter (LED 50-62) color: {rgb: {r: 255, g: 255, b: 255}} - rows: [5] # Row 5 full: LCtrl-Right (LED 76-86) color: {rgb: {r: 255, g: 255, b: 255}}
Создание сервиса
Теперь нужно создать сервис для работы в фоне, для этого тоже есть отдельная команда, создаёт локальный systemd unit в рабочем каталоге пользователя без sudo прав.
Просто выполняем kolor-keyboard service install и всё готово, есть аналогичные команды для просмотра логов сервиса, остановки и удаления.
Итого
Когда появится чуть больше времени я хочу вернуться к этому и сделать поддержку GNOME, Sway, а также macOS и Windows. На этом у меня всё 🙃.
Также я записал небольшой видео обзор на всё это дело, можете посмотреть
UPDATE
Забыл ссылку оставить 🙈
https://github.com/jidckii/kolor-keyboard
