Add G522 headset layout to per-key painter
Wire the per-key painter UI to the G522's per-zone lighting setting and
ship a layout file matching the eight-LED earcup arrangement.
- lib/solaar/ui/perkey/layouts/headset_g522.py (new): 2x5 layout, four
LEDs per earcup in a 2x2 grid with a gap column between, viewed from
outside. Zone IDs used as labels (Logitech firmware numbering).
- lib/solaar/ui/perkey/layouts/__init__.py: register layout against
feature 0x0620 (HEADSET_RGB_HOSTMODE) via name-substring match on
"G522".
- lib/logitech_receiver/settings_templates.py: switch
HeadsetPerZoneLighting from ChoicesMapValidator (limited to the
COLORSPLUS named-color palette) to MapRangeValidator (any 24-bit
RGB). Set editor_class so the painter UI takes over from the old
MapChoice dropdowns. Drops choices_universe; matches the
PerKeyLighting pattern.
LED positions per tester's reference:
Left earcup Right earcup
| 8 | 7 | | 6 | 5 |
| 4 | 3 | | 2 | 1 |
This commit is contained in:
parent
e34bcbe0b8
commit
f3af38862d
|
|
@ -2265,10 +2265,9 @@ class HeadsetLEDsPrimary(settings.Setting):
|
|||
class HeadsetPerZoneLighting(settings.Settings):
|
||||
"""Per-zone LED color overrides.
|
||||
|
||||
Mirrors `PerKeyLighting`'s `Settings` + `ChoicesMapValidator` style —
|
||||
one dropdown per discovered zone with the `COLORSPLUS` palette. The
|
||||
"No change" entry means "inherit the current `LEDs Primary` color",
|
||||
so users can paint individual zones without losing the base setup.
|
||||
Mirrors `PerKeyLighting` — keys are firmware zone IDs, values are
|
||||
24-bit RGB ints with the `-1` sentinel meaning "inherit the current
|
||||
`LEDs Primary` color." Surfaces in the UI via the per-key painter.
|
||||
"""
|
||||
|
||||
name = "headset_per_zone_lighting"
|
||||
|
|
@ -2279,20 +2278,20 @@ class HeadsetPerZoneLighting(settings.Settings):
|
|||
)
|
||||
feature = _F.HEADSET_RGB_HOSTMODE
|
||||
persist = True
|
||||
choices_universe = special_keys.COLORSPLUS
|
||||
editor_class = "solaar.ui.perkey.control:PerKeyControl"
|
||||
|
||||
class rw_class(settings.FeatureRWMap):
|
||||
pass
|
||||
|
||||
class validator_class(settings_validator.ChoicesMapValidator):
|
||||
class validator_class(settings_validator.MapRangeValidator):
|
||||
_COLOR_RANGE = settings_validator.Range(min=0, max=0xFFFFFF, byte_count=3)
|
||||
|
||||
@classmethod
|
||||
def build(cls, setting_class, device):
|
||||
zones = headset_rgb.discover_zones(device)
|
||||
if not zones:
|
||||
return None
|
||||
choices_map = {
|
||||
common.NamedInt(int(z), _("Zone") + " " + str(int(z))): setting_class.choices_universe for z in zones
|
||||
}
|
||||
choices_map = {common.NamedInt(int(z), _("Zone") + " " + str(int(z))): cls._COLOR_RANGE for z in zones}
|
||||
return cls(choices_map) if choices_map else None
|
||||
|
||||
def read(self, cached=True):
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ from __future__ import annotations
|
|||
from collections.abc import Callable
|
||||
|
||||
from ..layout import Layout
|
||||
from . import headset_g522
|
||||
from . import keyboard_ansi
|
||||
from . import keyboard_iso_azerty
|
||||
from . import keyboard_iso_qwerty
|
||||
|
|
@ -140,3 +141,5 @@ for _family, (_full, _tkl) in _FAMILY_LAYOUTS.items():
|
|||
register_layout(0x8081, _keyboard_matcher(_family, full_size=False), _tkl)
|
||||
|
||||
register_layout(0x8081, _name_contains("G502 X"), mouse_g502x.LAYOUT)
|
||||
# HEADSET_RGB_HOSTMODE = 0x0620
|
||||
register_layout(0x0620, _name_contains("G522"), headset_g522.LAYOUT)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
## Copyright (C) 2026 Solaar Contributors https://pwr-solaar.github.io/Solaar/
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; either version 2 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License along
|
||||
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
"""LED layout for the G522 LIGHTSPEED headset.
|
||||
|
||||
Eight LEDs in two 2×2 grids — one per earcup, viewed from outside:
|
||||
|
||||
Left earcup Right earcup
|
||||
┌─────┬─────┐ ┌─────┬─────┐
|
||||
│ 8 │ 7 │ │ 6 │ 5 │
|
||||
├─────┼─────┤ ├─────┼─────┤
|
||||
│ 4 │ 3 │ │ 2 │ 1 │
|
||||
└─────┴─────┘ └─────┴─────┘
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from ..layout import Cell
|
||||
from ..layout import Layout
|
||||
|
||||
_CELLS: tuple[Cell, ...] = (
|
||||
# Left earcup (cols 0-1, outer view): top-left=8, top-right=7, bottom-left=4, bottom-right=3
|
||||
Cell(zone_id=8, row=0, col=0, group="main", label="8"),
|
||||
Cell(zone_id=7, row=0, col=1, group="main", label="7"),
|
||||
Cell(zone_id=4, row=1, col=0, group="main", label="4"),
|
||||
Cell(zone_id=3, row=1, col=1, group="main", label="3"),
|
||||
# Right earcup (cols 3-4, outer view): top-left=6, top-right=5, bottom-left=2, bottom-right=1
|
||||
Cell(zone_id=6, row=0, col=3, group="main", label="6"),
|
||||
Cell(zone_id=5, row=0, col=4, group="main", label="5"),
|
||||
Cell(zone_id=2, row=1, col=3, group="main", label="2"),
|
||||
Cell(zone_id=1, row=1, col=4, group="main", label="1"),
|
||||
)
|
||||
|
||||
|
||||
LAYOUT: Layout = Layout(
|
||||
cells=_CELLS,
|
||||
rows=2,
|
||||
cols=5,
|
||||
description="Logitech G522 LIGHTSPEED headset (8 LEDs, 4 per earcup)",
|
||||
)
|
||||
Loading…
Reference in New Issue