Skip to content
This repository was archived by the owner on Apr 18, 2026. It is now read-only.

Commit d6da4b2

Browse files
jack-arturoclaude
andauthored
fix(profile): correct Stream Deck + XL keypad layout to 9x4 (verygoodplugins#18)
## Summary - Empirical hardware probe on a physical Stream Deck + XL showed the device has **9 keypad columns**, not 8. Writing to `position: 7,0` left the rightmost physical column unused; `8,0` lands at the true right edge. - `MODEL_LAYOUTS["20GBX9901"]` bumped from `KEYPAD: (8, 4)` → `(9, 4)`; comment updated from 32 → 36 keys. - Plus XL test fixture and layout assertions updated to 9×4. ## How we confirmed Wrote a probe page directly to the profile manifest with buttons `0..8` across the top row (col 8 colored red). On-device, the red "8" tile rendered at the rightmost physical column and "0" at the leftmost — confirming 9 columns. ## Test plan - [x] `uv run pytest tests/` — 51 passed - [x] `uv run ruff check .` — clean - [ ] Visually re-verify corners on-device after this lands (write corners at `0,0 / 8,0 / 0,3 / 8,3`) ## Out of scope Touchstrip rendering (per-encoder `TouchDisplay` feedback) is still unhandled — deferred to the upcoming dynamic-icon-URL feature pass, where it's a natural fit. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent e1cb4e3 commit d6da4b2

2 files changed

Lines changed: 5 additions & 5 deletions

File tree

profile_manager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@
6565
MODEL_LAYOUTS: dict[str, dict[str, tuple[int, int]]] = {
6666
# Stream Deck (Original)
6767
"20GBA9901": {KEYPAD: (5, 3)},
68-
# Stream Deck + XL (32 keys, 6 dials with 1200x100 touchstrip)
69-
"20GBX9901": {KEYPAD: (8, 4), ENCODER: (6, 1)},
68+
# Stream Deck + XL (36 keys, 6 dials with 1200x100 touchstrip)
69+
"20GBX9901": {KEYPAD: (9, 4), ENCODER: (6, 1)},
7070
# Emulator used by the Elgato desktop app
7171
"UI Stream Deck": {KEYPAD: (4, 2)},
7272
}

tests/test_profile_manager.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ def test_read_page_requires_locator(sample_profiles_v3: Path, tmp_path: Path) ->
382382

383383
@pytest.fixture
384384
def sample_profiles_plus_xl(tmp_path: Path) -> Path:
385-
"""Profile shaped like a Stream Deck + XL: Keypad 8x4 + Encoder 6x1 on the same page."""
385+
"""Profile shaped like a Stream Deck + XL: Keypad 9x4 + Encoder 6x1 on the same page."""
386386

387387
profiles_dir = tmp_path / "ProfilesV3"
388388
profile_dir = profiles_dir / "PLUSXL.sdProfile"
@@ -449,9 +449,9 @@ def test_read_page_returns_both_controllers(sample_profiles_plus_xl: Path, tmp_p
449449

450450
page = manager.read_page(profile_name="Plus XL", page_index=0)
451451

452-
assert page["layout"] == {"columns": 8, "rows": 4}
452+
assert page["layout"] == {"columns": 9, "rows": 4}
453453
assert page["layouts"] == {
454-
"keypad": {"columns": 8, "rows": 4},
454+
"keypad": {"columns": 9, "rows": 4},
455455
"encoder": {"columns": 6, "rows": 1},
456456
}
457457
controllers = {button["controller"] for button in page["buttons"]}

0 commit comments

Comments
 (0)