Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
7924634
Update header shortcut defaults and orientation-aware top menu sizing.
youyoubilly Apr 29, 2026
a7faecd
Improve connection dialogs in landscape and reduce toast noise.
youyoubilly Apr 29, 2026
4e06e04
Hide IME while drawer is open and restore only on cancel-close.
youyoubilly Apr 29, 2026
ddac487
Allow IME compose send button to stay tappable when blocked.
youyoubilly Apr 29, 2026
8ab5828
Support multiple connection listeners and bridge BLE service state up…
youyoubilly Apr 29, 2026
9dda054
Add BLE RSSI-driven signal indicators and Bluetooth status icons.
youyoubilly Apr 29, 2026
18713b4
Simplify compose success toast and hide top-header signal bars.
youyoubilly Apr 29, 2026
4d2b65b
Refine top-panel modifier keys and align connected tint with theme pr…
youyoubilly Apr 29, 2026
890f5ca
Refactor top shortcut paging to keep rows 2-3 fixed and profile-drive…
youyoubilly Apr 29, 2026
3456585
Normalize shortcut modifiers for macOS and clear fixed row placeholde…
youyoubilly Apr 29, 2026
04bcc65
Add fixed-top local Fn layer and restore directional slot behavior.
youyoubilly Apr 29, 2026
9c86a67
Refine top fixed-row paging and update default shortcut ordering.
youyoubilly Apr 29, 2026
e38a888
Update fixed shortcut row mappings and Fn lock state visuals.
youyoubilly Apr 29, 2026
d1df519
Refine top modifier lock interactions and visual states.
youyoubilly Apr 29, 2026
14cf448
Fixed-top Fn: keep ESC and Alt keys unmapped on Fn layer
youyoubilly Apr 29, 2026
66ebe75
Top strip: page 0 layout, Fn digit row, DISPLAY toggle fix, larger la…
youyoubilly Apr 29, 2026
c224d1e
Add Shortcut Hub profile slots on fixed strip page 2 row 3
youyoubilly Apr 30, 2026
7afd7bf
Improve shortcut hub sync and top-strip My Shortcuts assignment
youyoubilly Apr 30, 2026
8fcc61b
Polish top-strip favorite picker UI and top panel page 2 layout
youyoubilly Apr 30, 2026
8c05769
Refine fixed top-panel layout, DISPLAY/FN behavior, and strip typography
youyoubilly Apr 30, 2026
19463d9
Fix long-press on blank My Shortcuts strip cells
youyoubilly Apr 30, 2026
e06593b
Style Shortcut Hub row-1 strip distinct from fixed rows
youyoubilly Apr 30, 2026
3730b9b
Add My Shortcuts reorder bottom sheet and compact favorite rows
youyoubilly Apr 30, 2026
f9d893d
My shortcuts reorder: Material tabs, bookmark add/remove, My favorite…
youyoubilly Apr 30, 2026
4c1fca5
UX: profile hub slot keycaps and shortcuts reorder help
youyoubilly Apr 30, 2026
0d276ac
Copy: My favorites → Favorites; profile hub slot autosize text
youyoubilly Apr 30, 2026
1f85c80
CustomKeyboardView: center profile hub slot label vertically
youyoubilly Apr 30, 2026
0075d33
Add custom shortcut creation flow and parser/test support.
youyoubilly Apr 30, 2026
594ce89
Add Favorites create/reset actions with category-aware shortcut creat…
youyoubilly Apr 30, 2026
937e878
Improve shortcuts reorder UX: compact rows, section pick, favorite strip
youyoubilly Apr 30, 2026
57ea8e6
Keyboard: Linux Super label, Fn overlays for fixed top strip; documen…
youyoubilly Apr 30, 2026
510c742
Shortcut strip Phase 2: Page 1 Fn grid, Hub DISPLAY/Fn row, docs + plan
youyoubilly Apr 30, 2026
7f387ce
Improve fixed-strip modifier hinting for rapid taps.
youyoubilly Apr 30, 2026
c04b5c2
Update fixed strip Page1/Page2 Fn layouts.
youyoubilly Apr 30, 2026
bb97034
Fix fixed-strip delete key icons on local Fn layer.
youyoubilly Apr 30, 2026
eb5f331
Improve alternate popup geometry and compact hub grid layout
youyoubilly Apr 30, 2026
439dcea
Improve alternate swipe tolerance and popup visibility.
youyoubilly Apr 30, 2026
c380c88
Redesign Shortcut Hub strip Page 2 layout and punctuation rows
youyoubilly Apr 30, 2026
c5ff328
Invert Page 0 strip local Fn: latch shows F-keys, clear shows digits
youyoubilly Apr 30, 2026
23473c1
Polish shortcut strip Fn UX and favorite label toggles.
youyoubilly Apr 30, 2026
8f14f8b
Add diagonal currency alternates on D key (₹₩₽₺)
youyoubilly Apr 30, 2026
16ca5be
feat(keyboard): improve long-press alternate popup for cardinal slots
youyoubilly May 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions .cursor/plans/page2_hub_row_keys_664cc968.plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
name: Shortcut strip Fn layouts
overview: "Authoritative layouts: Page 1 local-Fn overlays (rows 2–3) reorganized into locks/nav/editing; Page 2 hub bottom row punctuation (Fn off) and bracket/shift-symbol row (Fn on). Includes HID notes, locale caveats, and resolver/modifier-lock risks."
todos:
- id: page1-fn-mapping
content: Replace Page 1 resolveFixedTopLocalFnMapping row2/row3 cases per table (ESC→ScrLk … Right→PgDn); IME unchanged
status: pending
- id: page1-fn-modifier-lock
content: Decide long-press on E0/E2/E3 when Fn on shows PRT SC/Space/Pause — Option A lock underlying modifier vs Option B disable lock while Fn on
status: pending
- id: page2-hub-build-static
content: buildFixedTopRowsPage2 Fn off six keys + DISPLAY + Fn; Fn on six keys + Fn (DISPLAY slot becomes sixth symbol cell)
status: pending
- id: page2-fn-sentinel-or-map
content: Implement Page 2 keys via FnMapping + sentinel codes if needed so symbols do not collide with Page 0/1 switch(key.code); wire shift-modifier sends for "?#():@"
status: pending
- id: user-guide-fn-layouts
content: USER_GUIDE — Page 1 Fn cluster + Page 2 quote/hub symbols; note US-QWERTY shift assumptions where relevant
status: pending
isProject: false
---

# Shortcut strip: Page 1 Fn + Page 2 hub row (your arrangement)

## Page 1 — local Fn **on** (physical cells unchanged; only overlay labels / sends change)

Strip is still built in [`buildFixedTopRowsPage1()`](Openterface_KeyMod_Android/app/src/main/java/com/openterface/keymod/CustomKeyboardView.java). Order below matches **column index** 1–7.

### Row 2 (base → Fn on)

| Col | Base (Fn off) | `key.code` | Fn on label | Fn on send |
|-----|----------------|------------|-------------|------------|
| 1 | ESC | `0x29` | SCR LK | `0x47` |
| 2 | SHIFT | `0xE1` | CAPS | `0x39` |
| 3 | DEL | `0x4C` | DEL | `0x4C` (same as base; forward delete) |
| 4 | TAB | `0x2B` | BKSP | `0x2A` |
| 5 | UP | `0x52` | HOME | `0x4A` |
| 6 | ENTER | `0x28` | PGUP | `0x4B` |
| 7 | PH1 / keyboard | `KEY_IME_TOGGLE` | (unchanged) | `null` in resolver — still IME toggle |

### Row 3 (base → Fn on)

| Col | Base (Fn off) | `key.code` | Fn on label | Fn on send |
|-----|----------------|------------|-------------|------------|
| 1 | CTRL | `0xE0` | PRT SC | `0x46` |
| 2 | ALT | `0xE2` | SPACE | `0x2C` |
| 3 | WIN/CMD | `0xE3` | PAUSE / BREAK | `0x48` |
| 4 | LEFT | `0x50` | INS | `0x49` |
| 5 | DOWN | `0x51` | END | `0x4D` |
| 6 | RIGHT | `0x4F` | PGDN | `0x4E` |
| 7 | — | `KEY_FIXED_TOP_LOCAL_FN` | Fn | toggle (unchanged) |

### Analysis — Page 1

- **Coherent story:** Row 2 = scroll/caps + delete/backspace + home/pgup + IME; row 3 = print/space/pause + insert/end/pgdn. This **replaces** the previous Page 1 Fn grid (Home on ESC, `/` on Alt, etc.) entirely; update [`resolveFixedTopLocalFnMapping`](Openterface_KeyMod_Android/app/src/main/java/com/openterface/keymod/CustomKeyboardView.java) cases for `0x29`, `0xE1`, `0x4C`, `0x2B`, `0x52`, `0x28`, and `0xE0`–`0xE3`, `0x50`, `0x51`, `0x4F` accordingly.
- **DEL (col 3):** Fn on and Fn off both forward-delete — resolver can return **`null`** for `0x4C` so the base key path sends `0x4C`, or return an identity mapping; avoid the old `0x4C` → PGUP behavior.
- **Modifier long-press:** Positions `0xE0` / `0xE2` / `0xE3` are still **modifier** keys in the `Key` model when Fn is off. When Fn is on they **look** like PRT SC / SPACE / PAUSE. You must choose: **(A)** long-press still toggles Ctrl/Alt/Win lock using underlying codes (Phase 2 Option 1), or **(B)** disable modifier lock on those three while Fn is on (Option 2). Recommend documenting the choice in USER_GUIDE.
- **CAPS as tap on Shift position:** Single tap sends Caps Lock HID (`0x39`); it does **not** mirror Android “shift” behavior — acceptable if labeled CAPS.

---

## Page 2 — hub bottom row (below profile slots)

Row is built in [`buildFixedTopRowsPage2()`](Openterface_KeyMod_Android/app/src/main/java/com/openterface/keymod/CustomKeyboardView.java): **Fn off** shows **six** character keys + DISPLAY + Fn; **Fn on** shows **six** keys + Fn (DISPLAY slot is repurposed as the sixth key, same as prior hub spec).

### Fn **off**

| Col | Label | Typical HID / modifiers | Notes |
|-----|-------|-------------------------|--------|
| 1 | `"` | `0x34` + `MOD_SHIFT` | Double quote (US: Shift+apostrophe) |
| 2 | `'` | `0x34` | Apostrophe |
| 3 | `.` | `0x37` | Period |
| 4 | `?` | `0x38` + `MOD_SHIFT` | Question (US: Shift+slash) |
| 5 | `#` | `0x20` + `MOD_SHIFT` | Hash (US: Shift+3) |
| 6 | DISPLAY | `KEY_TOP_SHORTCUT_DISPLAY_TOGGLE` | Icon/text mode for strip (existing behavior) |
| 7 | Fn | `KEY_FIXED_TOP_LOCAL_FN` | — |

### Fn **on**

Interpret `[[], []]` as **`[`** and **`]`** in two columns.

| Col | Label | Typical HID / modifiers | Notes |
|-----|-------|-------------------------|--------|
| 1 | `(` | `0x26` + `MOD_SHIFT` | US: Shift+9 |
| 2 | `)` | `0x27` + `MOD_SHIFT` | US: Shift+0 |
| 3 | `[` | `0x2F` | Left bracket |
| 4 | `]` | `0x30` | Right bracket |
| 5 | `@` | `0x1F` + `MOD_SHIFT` | US: Shift+2 |
| 6 | `:` | `0x33` + `MOD_SHIFT` | Shift+semicolon |
| 7 | Fn | `KEY_FIXED_TOP_LOCAL_FN` | — |

### Analysis — Page 2

- **Layout matches strip spec:** Five “content” keys + DISPLAY + Fn when Fn off; **six** content keys + Fn when Fn on (DISPLAY hidden or inert while Fn on — reuse existing guard so DISPLAY does not toggle action-label mode incorrectly).
- **Locale / keyboard layout:** `( ) @ # "` as **Shift+digit/shift+punctuation** assumes a **US QWERTY–like** host mapping. Other national layouts may produce different glyphs; document briefly in USER_GUIDE.
- **Resolver collisions:** Bare HID codes reused on Page 1 (e.g. `0x34`, `0x37`, …) cannot map to **different** Page 2 Fn-on targets via the **same global** `switch (key.code)` unless Page 2 keys use **distinct** underlying codes. **Recommended:** dedicated **Shortcut Hub sentinel** range (e.g. `0xF015`…) for the six Page 2 cells + explicit `{ baseSend, fnOnSend }` table, **or** only use HID codes **not present** in the Page 0/1 Fn switch — Page 2’s mix of punctuation will likely force **sentinels + small dispatch**.
- **Duplication vs main keyboard:** These are deliberate **strip shortcuts** next to profiles; duplication with the letter grid is acceptable.

---

## Files to touch (implementation phase)

- [`CustomKeyboardView.java`](Openterface_KeyMod_Android/app/src/main/java/com/openterface/keymod/CustomKeyboardView.java) — `resolveFixedTopLocalFnMapping`, `buildFixedTopRowsPage2()`, `handleKeyPress` / DISPLAY guards, modifier long-press behavior on `0xE0`/`0xE2`/`0xE3` when Fn on.
- [`docs/USER_GUIDE.md`](Openterface_KeyMod_Android/docs/USER_GUIDE.md) — replace obsolete Page 1 Fn grid prose with tables above + Page 2 hub row + locale note.

---

## Superseded content

Older “avoid duplicates with legacy Page 1 Fn” constraints and the previous Page 2 proposal (Caps/Num/PrtSc/Bksp/` grave row) are **superseded** by this document.
107 changes: 107 additions & 0 deletions .cursor/plans/shortcut-strip-phase2-layout_52b0b3c3.plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
name: shortcut-strip-phase2-layout
overview: "Consolidated build plan after Phase 1 (modifier tap/Fn alignment, docs, Linux Super text): redesign Page 1 local Fn overlays for navigation and symbols, evolve Page 2 row 3 placeholder/DISPLAY behavior, defer media keys until Consumer HID is proven, and prioritize keyboard-page keys (Caps, PrtSc, Menu) with clear HID/firmware checks."
todos:
- id: page1-fn-map
content: Extend resolveFixedTopLocalFnMapping for Page 1 row2/row3 to navigation + symbol grid; compact labels/icons
status: pending
- id: modifier-lock-fn-on
content: Decide and implement Option 1 (long-press lock uses base modifier code) or Option 2 (disable lock when Fn on) for E0/E2/E3 cells
status: pending
- id: page2-display-fn
content: "When Fn on Page 2 strip: six placeholder slots + Fn; DISPLAY hidden or inert per spec; handle handleKeyPress/display toggle edge cases"
status: pending
- id: menu-hid-verify
content: Firmware QA Application key 0x65; if OK add CH9329MSKBMap + optional strip slot
status: pending
- id: docs-phase2
content: "USER_GUIDE: Page 1 Fn grid, Page 2 row, media deferred, Menu/Caps/PrtSc notes"
status: pending
isProject: false
---

# Shortcut strip Phase 2: Page 1 Fn redesign + Page 2 row 3 + key priorities

## Context (already shipped in Phase 1)

The following are **done** in the repo and supersede the “TAB/ENTER label mismatch” section of the older analysis plan:

- [`CustomKeyboardView.sendMomentaryModifierClick`](Openterface_KeyMod_Android/app/src/main/java/com/openterface/keymod/CustomKeyboardView.java) respects `resolveFixedTopLocalFnMapping` so **Fn-on modifier caps match HID**.
- [`docs/USER_GUIDE.md`](Openterface_KeyMod_Android/docs/USER_GUIDE.md) explains target OS vs local Fn on the fixed strip.
- `shortcutModifierText` uses **Super** on Linux for `MOD_WIN`.

Treat [`shortcut_strip_modifier_analysis_00078086.plan.md`](/Users/billywang/.cursor/plans/shortcut_strip_modifier_analysis_00078086.plan.md) as **historical** except for the layout reference for Page 0/1/2 structure.

---

## Target behavior to build (Phase 2)

### A. Page 1 — local Fn “overlay” rows

**Base (Fn off)** — unchanged from today [`buildFixedTopRowsPage1()`](Openterface_KeyMod_Android/app/src/main/java/com/openterface/keymod/CustomKeyboardView.java):

- Row 2: ESC, Shift, DEL, TAB, Up, Enter, IME toggle
- Row 3: Ctrl, Alt, Win/Cmd/Super (labels OS-aware), Left, Down, Right, local Fn toggle

**Fn on — proposed layout** (replace current Ctrl→Tab / Win→Enter overlays on row 3 cols 1–3):

- Row 2 → **navigation cluster:** Home `0x4A`, End `0x4D`, PgUp `0x4B`, PgDn `0x4E`, Insert `0x49`, Scroll Lock `0x47`, IME toggle (unchanged slot; no duplicate of keys elsewhere if possible).
- Row 3 → **symbols / system:** Pause/Break `0x48` (validate behavior vs Pause+Ctrl on hosts), `/` `0x38`, `\` `0x31`, `|` via existing map pattern (e.g. `0x64` as in [`CH9329MSKBMap`](Openterface_KeyMod_Android/app/src/main/java/com/openterface/target/CH9329MSKBMap.java)), `"` with shift+apostrophe if needed, `-` `0x2D`, local Fn toggle (fixed).

**Implementation approach:** extend [`resolveFixedTopLocalFnMapping(Key)`](Openterface_KeyMod_Android/app/src/main/java/com/openterface/keymod/CustomKeyboardView.java) with explicit cases for **each base `key.code`** on Page 1 row 2 and row 3 (match the building order in `buildFixedTopRowsPage1`). Use compact labels (`PGUP`, `SCR LK`, `PAUSE`) where UI space is tight. Reuse [`sendMomentaryModifierClick`](Openterface_KeyMod_Android/app/src/main/java/com/openterface/keymod/CustomKeyboardView.java) / normal `handleKeyPress` paths so Fn-mapped sends stay consistent with locked modifiers.

**Long-press modifier lock:** row 3 base keys `0xE0`/`0xE2`/`0xE3` keep lock semantics; when Fn is on, either (pick one and document):

- **Option 1 (recommended):** Fn-on shows non-modifier legends on those cells but **short tap** sends the Fn action; **long-press** still toggles lock using underlying modifier `key.code` (requires touch listener branch: if Fn on, long-press uses `key.code` for lock only).
- **Option 2:** Fn-on disables modifier lock on those three cells (simpler logic, weaker power-user story).

### B. Page 2 — Shortcut Hub profile row + bottom row

**Current:** [`buildFixedTopRowsPage2()`](Openterface_KeyMod_Android/app/src/main/java/com/openterface/keymod/CustomKeyboardView.java): row 1 = seven profile slots; row 2 = **five** no-ops + DISPLAY + Fn.

**Target:**

| State | Row under profiles (7 cols) |
|--------|------------------------------|
| Fn **off** | `[ ] [ ] [ ] [ ] [ ]` + **DISPLAY** + **Fn** |
| Fn **on** | `[ ] [ ] [ ] [ ] [ ] [ ]` + **Fn** (six assignable; DISPLAY slot becomes sixth blank or alternate action) |

**Implementation sketch:**

- Add Fn-specific **visual + hit** handling for the DISPLAY key when `fixedTopLocalFnLocked` on Page 2: either rebind col 6 to `KEY_NOOP_PLACEHOLDER` or a dedicated `KEY_TOP_SHORTCUT_DISPLAY_TOGGLE` branch in `resolveFixedTopLocalFnMapping` that returns **no toggle** (dead/blank) so the user sees six equal slots.
- Ensure `KEY_TOP_SHORTCUT_DISPLAY_TOGGLE` handler in [`handleKeyPress`](Openterface_KeyMod_Android/app/src/main/java/com/openterface/keymod/CustomKeyboardView.java) does not flip action-label mode when Fn is on for Page 2 if col 6 is repurposed (mirror existing guard for DISPLAY under Fn on F-row strip).

**Future:** the five/six placeholder slots are candidates for **user-assigned shortcuts** or static keys; today they are no-ops—Phase 2 can keep no-ops or add a minimal static set if product asks.

### C. Media keys — defer as Phase 3

- Current transport [`sendKeyData`](Openterface_KeyMod_Android/app/src/main/java/com/openterface/keymod/CustomKeyboardView.java) only emits **keyboard** CH9329 frames (`57AB000208…`). **Consumer/media** HID is **not** implemented in this path.
- **Do not** promise “all target OS” media until: firmware supports consumer reports + app encodes them + QA on USB and BLE.

### D. Application / Menu vs laptop “Fn”

- **Application (context menu):** standard keyboard usage **0x65** in HID; **not** Windows-only—verify CH9329 accepts it, add to [`CH9329MSKBMap`](Openterface_KeyMod_Android/app/src/main/java/com/openterface/target/CH9329MSKBMap.java), wire one slot if firmware OK. **Medium–high value.**
- **Laptop Fn:** not a reliable host-visible scancode; **do not** expose as “HID Fn” to the target. App’s **local Fn toggle** is the right abstraction.

### E. Caps Lock, Scroll Lock, and “what’s missing”

Already mappable via same map: **Caps `0x39`**, **Scroll `0x47`**, **PrtSc `0x46`**, **Num Lock `0x53`**.

**Slot priority** (when forced to choose): Caps Lock and PrtSc > Scroll Lock > Pause/Break edge cases > media (deferred).

---

## Files to touch (implementation pass)

- [`CustomKeyboardView.java`](Openterface_KeyMod_Android/app/src/main/java/com/openterface/keymod/CustomKeyboardView.java) — `resolveFixedTopLocalFnMapping`, optional touch/long-press split for Fn-on modifiers, Page 2 DISPLAY behavior under Fn.
- [`CH9329MSKBMap.java`](Openterface_KeyMod_Android/app/src/main/java/com/openterface/target/CH9329MSKBMap.java) — `MENU` / `APPLICATION` → `65` if firmware confirmed.
- [`docs/USER_GUIDE.md`](Openterface_KeyMod_Android/docs/USER_GUIDE.md) — document new Page 1 Fn grid and Page 2 six-slot Fn row; note media deferral.

---

## Validation checklist

- Page 1: Fn off matches current; Fn on sends correct HID for every overlay (spot-check with host or logging).
- Modifier long-press lock: behavior matches chosen Option 1 or 2.
- Page 2: Fn off shows DISPLAY; Fn on shows six blanks + Fn and DISPLAY does not trap users.
- Regressions: F-row page (`buildFixedTopRowsPage0`) Fn mappings remain unchanged.
Loading
Loading