From 1da404c299256213bfed63e5377e67dce5bdf6d8 Mon Sep 17 00:00:00 2001 From: christian Date: Thu, 8 Oct 2026 09:44:03 -0400 Subject: [PATCH] Only the page number key follows the ALL button; UP and DOWN are normal again. New config setting nav_keys (now ["pagenum"]) picks which nav keys are coloured; nav_keys.py restores the built-in key for any kind not listed. Co-Authored-By: Claude Opus 5.5 --- config.json | 1 + make_page.py | 3 +- nav_keys.py | 38 ++++--- nav_locations.json | 194 +----------------------------------- status-page.companionconfig | Bin 6361 -> 5099 bytes tests/test_status_panel.py | 6 +- 6 files changed, 32 insertions(+), 210 deletions(-) diff --git a/config.json b/config.json index e1fcd3b..bdd5a8e 100644 --- a/config.json +++ b/config.json @@ -2,6 +2,7 @@ "companion": { "host": "127.0.0.1", "port": 8000 }, "page": 19, "page_name": "19\\nStatus", + "nav_keys": ["pagenum"], "variables": { "state": "sp_state", "heartbeat": "sp_hb", "command": "sp_cmd" }, "service_windows": [ diff --git a/make_page.py b/make_page.py index 27c9155..b458607 100644 --- a/make_page.py +++ b/make_page.py @@ -162,8 +162,9 @@ def nav_key(kind, names): def build(cfg): controls = {} + coloured = cfg.get("nav_keys", list(NAV_LOCATIONS)) # which nav keys follow the ALL button for kind, (r, c) in NAV_LOCATIONS.items(): - controls.setdefault(r, {})[c] = nav_key(kind, cfg["variables"]) + controls.setdefault(r, {})[c] = nav_key(kind, cfg["variables"]) if kind in coloured else {"type": kind} for tile in cfg["tiles"]: if "pos" not in tile: continue diff --git a/nav_keys.py b/nav_keys.py index cc5289b..a885f72 100644 --- a/nav_keys.py +++ b/nav_keys.py @@ -1,10 +1,12 @@ #!/usr/bin/env python3 -"""Make the UP / page number / DOWN keys on every page follow the status page's ALL button. +"""Make the page nav keys on every page follow the status page's ALL button. +Which keys follow it is "nav_keys" in config.json (now just the page number). The status page (page 19) carries coloured copies of Companion's own nav keys -(see make_page.py and nav_templates.json). This copies them over the built-in -nav keys on every other page, wherever those sit, using the same "copy button" -call as the Companion UI. Each key keeps its normal press action. +(see make_page.py and nav_templates.json). This copies those over the built-in +keys on every other page, using the same "copy button" call as the Companion UI, +and puts back the built-in key for any kind no longer listed. Each key keeps +its normal press action. python3 nav_keys.py --dry-run list what would change python3 nav_keys.py apply (also refreshes keys already converted) @@ -52,8 +54,12 @@ def nav_kind(control): return None +def is_ours(control): + return (control.get("options", {}).get("notes", "") or "").startswith(NAV_MARKER) + + def find_nav_keys(host, port, status_page): - """[(page, row, column, kind)] for every nav key outside the status page.""" + """[(page, row, column, kind, ours)] for every nav key outside the status page.""" found, page = [], 1 while True: export = page_export(host, port, page) @@ -64,7 +70,7 @@ def find_nav_keys(host, port, status_page): for c, control in cols.items(): kind = nav_kind(control or {}) if kind: - found.append((page, int(r), int(c), kind)) + found.append((page, int(r), int(c), kind, is_ours(control))) page += 1 return found @@ -79,24 +85,28 @@ def main(): args = ap.parse_args() status_page = cfg["page"] + coloured = cfg.get("nav_keys", list(NAV_LOCATIONS)) record = json.load(open(RECORD)) if os.path.exists(RECORD) else {} + found = find_nav_keys(args.host, args.port, status_page) if args.revert: - targets = [(int(k.split("/")[0]), int(k.split("/")[1]), int(k.split("/")[2]), v) for k, v in record.items()] + work = [(p, r, c, k, "restore") for p, r, c, k, ours in found if ours] else: - targets = find_nav_keys(args.host, args.port, status_page) - print("%d nav keys on %d pages" % (len(targets), len({t[0] for t in targets}))) + work = [(p, r, c, k, "colour") for p, r, c, k, ours in found if k in coloured] + work += [(p, r, c, k, "restore") for p, r, c, k, ours in found if ours and k not in coloured] + print("%d nav keys to colour, %d to restore, on %d pages" % ( + sum(1 for w in work if w[4] == "colour"), sum(1 for w in work if w[4] == "restore"), len({w[0] for w in work}))) if args.dry_run: - for t in targets: - print(" page %d row %d col %d: %s" % t) + for w in work: + print(" page %d row %d col %d: %s -> %s" % w) return ws = WebSocket(args.host, args.port, "/trpc") done = 0 try: api = Trpc(ws) - for page, row, col, kind in targets: + for page, row, col, kind, what in work: location = {"pageNumber": page, "row": row, "column": col} - if args.revert: + if what == "restore": api.mutation("controls.resetControl", {"location": location, "newType": kind}) record.pop("%d/%d/%d" % (page, row, col), None) else: @@ -109,7 +119,7 @@ def main(): finally: ws.close() json.dump(record, open(RECORD, "w"), indent=1, sort_keys=True) - print("%s %d nav keys" % ("restored" if args.revert else "coloured", done)) + print("done: %d nav keys changed" % done) if __name__ == "__main__": diff --git a/nav_locations.json b/nav_locations.json index 6aed03b..4bcc570 100644 --- a/nav_locations.json +++ b/nav_locations.json @@ -1,290 +1,98 @@ { - "1/0/0": "pageup", "1/1/0": "pagenum", - "1/2/0": "pagedown", - "10/0/0": "pageup", "10/1/0": "pagenum", - "10/2/0": "pagedown", - "11/0/0": "pageup", "11/1/0": "pagenum", - "11/2/0": "pagedown", - "12/0/0": "pageup", "12/1/0": "pagenum", - "12/2/0": "pagedown", - "13/0/0": "pageup", "13/1/0": "pagenum", - "13/2/0": "pagedown", - "14/0/0": "pageup", "14/1/0": "pagenum", - "14/2/0": "pagedown", - "15/0/0": "pageup", "15/0/1": "pagenum", "15/1/0": "pagenum", - "15/2/0": "pagedown", - "16/0/0": "pageup", "16/1/0": "pagenum", - "16/2/0": "pagedown", - "17/0/0": "pageup", "17/1/0": "pagenum", - "17/2/0": "pagedown", - "18/0/0": "pageup", "18/1/0": "pagenum", - "18/2/0": "pagedown", - "2/0/0": "pageup", "2/1/0": "pagenum", - "2/2/0": "pagedown", - "20/0/0": "pageup", "20/1/0": "pagenum", - "20/2/0": "pagedown", - "21/0/0": "pageup", "21/1/0": "pagenum", - "21/2/0": "pagedown", - "22/0/0": "pageup", "22/1/0": "pagenum", - "22/2/0": "pagedown", - "23/0/0": "pageup", "23/1/0": "pagenum", - "23/2/0": "pagedown", - "24/0/0": "pageup", "24/1/0": "pagenum", - "24/2/0": "pagedown", - "25/0/0": "pageup", "25/1/0": "pagenum", - "25/2/0": "pagedown", - "26/0/0": "pageup", "26/1/0": "pagenum", - "26/2/0": "pagedown", - "27/0/0": "pageup", "27/1/0": "pagenum", - "27/2/0": "pagedown", - "28/0/0": "pageup", "28/1/0": "pagenum", - "28/2/0": "pagedown", - "29/0/0": "pageup", "29/1/0": "pagenum", - "29/2/0": "pagedown", - "3/0/0": "pageup", "3/1/0": "pagenum", - "3/2/0": "pagedown", - "30/0/0": "pageup", "30/1/0": "pagenum", - "30/2/0": "pagedown", - "31/0/0": "pageup", "31/1/0": "pagenum", - "31/2/0": "pagedown", - "32/0/0": "pageup", "32/1/0": "pagenum", - "32/2/0": "pagedown", - "33/0/0": "pageup", "33/1/0": "pagenum", - "33/2/0": "pagedown", - "34/0/0": "pageup", "34/1/0": "pagenum", - "34/2/0": "pagedown", - "35/0/0": "pageup", "35/1/0": "pagenum", - "35/2/0": "pagedown", - "36/0/0": "pageup", "36/1/0": "pagenum", - "36/2/0": "pagedown", - "37/0/0": "pageup", "37/1/0": "pagenum", - "37/2/0": "pagedown", - "38/0/0": "pageup", "38/1/0": "pagenum", - "38/2/0": "pagedown", - "39/0/0": "pageup", "39/1/0": "pagenum", - "39/2/0": "pagedown", - "4/0/0": "pageup", "4/1/0": "pagenum", - "4/2/0": "pagedown", - "40/0/0": "pageup", "40/1/0": "pagenum", - "40/2/0": "pagedown", - "41/0/0": "pageup", "41/1/0": "pagenum", - "41/2/0": "pagedown", - "42/0/0": "pageup", "42/1/0": "pagenum", - "42/2/0": "pagedown", - "43/0/0": "pageup", "43/1/0": "pagenum", - "43/2/0": "pagedown", - "44/0/0": "pageup", "44/1/0": "pagenum", - "44/2/0": "pagedown", - "45/0/0": "pageup", "45/1/0": "pagenum", - "45/2/0": "pagedown", - "46/0/0": "pageup", "46/1/0": "pagenum", - "46/2/0": "pagedown", - "47/0/0": "pageup", "47/1/0": "pagenum", - "47/2/0": "pagedown", - "48/0/0": "pageup", "48/1/0": "pagenum", - "48/2/0": "pagedown", - "49/0/0": "pageup", "49/1/0": "pagenum", - "49/2/0": "pagedown", - "5/0/0": "pageup", "5/1/0": "pagenum", - "5/2/0": "pagedown", - "50/0/0": "pageup", "50/1/0": "pagenum", - "50/2/0": "pagedown", - "51/0/0": "pageup", "51/1/0": "pagenum", - "51/2/0": "pagedown", - "52/0/0": "pageup", "52/1/0": "pagenum", - "52/2/0": "pagedown", - "53/0/0": "pageup", "53/1/0": "pagenum", - "53/2/0": "pagedown", - "54/0/0": "pageup", "54/1/0": "pagenum", - "54/2/0": "pagedown", - "55/0/0": "pageup", "55/1/0": "pagenum", - "55/2/0": "pagedown", - "56/0/0": "pageup", "56/1/0": "pagenum", - "56/2/0": "pagedown", - "57/0/0": "pageup", "57/1/0": "pagenum", - "57/2/0": "pagedown", - "58/0/0": "pageup", "58/1/0": "pagenum", - "58/2/0": "pagedown", - "59/0/0": "pageup", "59/1/0": "pagenum", - "59/2/0": "pagedown", - "6/0/0": "pageup", "6/1/0": "pagenum", - "6/2/0": "pagedown", - "60/0/0": "pageup", "60/1/0": "pagenum", - "60/2/0": "pagedown", - "61/0/0": "pageup", "61/1/0": "pagenum", - "61/2/0": "pagedown", - "62/0/0": "pageup", "62/1/0": "pagenum", - "62/2/0": "pagedown", - "63/0/0": "pageup", "63/1/0": "pagenum", - "63/2/0": "pagedown", - "64/0/0": "pageup", "64/1/0": "pagenum", - "64/2/0": "pagedown", - "65/0/0": "pageup", "65/1/0": "pagenum", - "65/2/0": "pagedown", - "66/0/0": "pageup", "66/1/0": "pagenum", - "66/2/0": "pagedown", - "67/0/0": "pageup", "67/1/0": "pagenum", - "67/2/0": "pagedown", - "68/0/0": "pageup", "68/1/0": "pagenum", - "68/2/0": "pagedown", - "69/0/0": "pageup", "69/1/0": "pagenum", - "69/2/0": "pagedown", - "7/0/0": "pageup", "7/1/0": "pagenum", - "7/2/0": "pagedown", - "70/0/0": "pageup", "70/1/0": "pagenum", - "70/2/0": "pagedown", - "71/0/0": "pageup", "71/1/0": "pagenum", - "71/2/0": "pagedown", - "72/0/0": "pageup", "72/1/0": "pagenum", - "72/2/0": "pagedown", - "73/0/0": "pageup", "73/1/0": "pagenum", - "73/2/0": "pagedown", - "74/0/0": "pageup", "74/1/0": "pagenum", - "74/2/0": "pagedown", - "75/0/0": "pageup", "75/1/0": "pagenum", - "75/2/0": "pagedown", - "76/0/0": "pageup", "76/1/0": "pagenum", - "76/2/0": "pagedown", - "77/0/0": "pageup", "77/1/0": "pagenum", - "77/2/0": "pagedown", - "78/0/0": "pageup", "78/1/0": "pagenum", - "78/2/0": "pagedown", - "79/0/0": "pageup", "79/1/0": "pagenum", - "79/2/0": "pagedown", - "8/0/0": "pageup", "8/1/0": "pagenum", - "8/2/0": "pagedown", - "80/0/0": "pageup", "80/1/0": "pagenum", - "80/2/0": "pagedown", - "81/0/0": "pageup", "81/1/0": "pagenum", - "81/2/0": "pagedown", - "82/0/0": "pageup", "82/1/0": "pagenum", - "82/2/0": "pagedown", - "83/0/0": "pageup", "83/1/0": "pagenum", - "83/2/0": "pagedown", - "84/0/0": "pageup", "84/1/0": "pagenum", - "84/2/0": "pagedown", - "85/0/0": "pageup", "85/1/0": "pagenum", - "85/2/0": "pagedown", - "86/0/0": "pageup", "86/1/0": "pagenum", - "86/2/0": "pagedown", - "87/0/0": "pageup", "87/1/0": "pagenum", - "87/2/0": "pagedown", - "88/0/0": "pageup", "88/1/0": "pagenum", - "88/2/0": "pagedown", - "89/0/0": "pageup", "89/1/0": "pagenum", - "89/2/0": "pagedown", - "9/0/0": "pageup", "9/1/0": "pagenum", - "9/2/0": "pagedown", - "90/0/0": "pageup", "90/1/0": "pagenum", - "90/2/0": "pagedown", - "91/0/0": "pageup", "91/1/0": "pagenum", - "91/2/0": "pagedown", - "92/0/0": "pageup", "92/1/0": "pagenum", - "92/2/0": "pagedown", - "93/0/0": "pageup", "93/1/0": "pagenum", - "93/2/0": "pagedown", - "94/0/0": "pageup", "94/1/0": "pagenum", - "94/2/0": "pagedown", - "95/0/0": "pageup", "95/1/0": "pagenum", - "95/2/0": "pagedown", - "96/0/0": "pageup", - "96/2/0": "pagedown", - "97/0/0": "pageup", - "97/1/0": "pagenum", - "97/2/0": "pagedown" + "97/1/0": "pagenum" } \ No newline at end of file diff --git a/status-page.companionconfig b/status-page.companionconfig index a395e4c0004c9f46b118b9489cbaf715f68192af..09bc048c22ea8a41329fbee85123ab21ab044cfa 100644 GIT binary patch literal 5099 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 literal 6361 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 BKxzO0 diff --git a/tests/test_status_panel.py b/tests/test_status_panel.py index c7fcd27..62c7952 100644 --- a/tests/test_status_panel.py +++ b/tests/test_status_panel.py @@ -555,7 +555,9 @@ class TestPage(unittest.TestCase): def test_layout(self): self.assertEqual(self.export["type"], "page") self.assertEqual(self.export["oldPageNumber"], 19) - for (r, kind, action) in (("0", "pageup", "inc_page"), ("1", "pagenum", "set_page"), ("2", "pagedown", "dec_page")): + self.assertEqual(self.controls["0"]["0"], {"type": "pageup"}) # only the page number follows ALL + self.assertEqual(self.controls["2"]["0"], {"type": "pagedown"}) + for (r, kind, action) in (("1", "pagenum", "set_page"),): key = self.controls[r]["0"] self.assertEqual(key["type"], "button-layered") self.assertTrue(key["options"]["notes"].startswith("STATUS nav key (%s)" % kind)) @@ -565,7 +567,7 @@ class TestPage(unittest.TestCase): self.assertIn("'$.all.b'", box["color"]["value"]) # follows the ALL button positioned = [t for t in CONFIG["tiles"] if "pos" in t] n = sum(1 for r in self.controls.values() for c in r.values() if c["type"] == "button-layered") - self.assertEqual(n, len(positioned) + 3) # + the three nav keys + self.assertEqual(n, len(positioned) + 1) # + the page number key # The master is where the smallest Stream Deck can see it. self.assertEqual(CONFIG["tiles"][0]["pos"], [0, 1])