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

https://github.com/jidckii/kolor-keyboard

Русский и USA флаги относительно layout
Русский и USA флаги относительно layout
⚠️ 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-hidraw0

  • suse - libhidapi-hidraw0

  • rhel - hidapi (находится в epel)

  • alt linux - libhidapi

  • arch 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 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

Реклама

TUNA - сервисы для разработчиков