From aa1ac7368c57768d07b82a41bfd1d366d465e0f6 Mon Sep 17 00:00:00 2001 From: saphid <4596216+saphid@users.noreply.github.com> Date: Tue, 29 Sep 2026 10:13:09 +1000 Subject: [PATCH] frame_touch: any event that goes through clears the stale flag A trackpad move names no panel, so waiting for an aimed event could leave the page re-reading panels for the rest of the session; a release still aimed at the old panel doesn't count. Co-Authored-By: Claude Opus 5.5 (1M context) --- tests/test_touch.py | 9 +++++++++ ui/frame_touch.py | 5 +++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/test_touch.py b/tests/test_touch.py index a257152..2319589 100644 --- a/tests/test_touch.py +++ b/tests/test_touch.py @@ -138,6 +138,15 @@ class Apply(unittest.TestCase): self.assertEqual(self.said, [("ready", {"focus": 7, "display": ":1", "stale": True}), ("ready", {"focus": 7, "display": ":1"})]) + def test_stale_clears_on_a_trackpad_move_but_not_on_a_stale_release(self): + gs = FakeGamescope() + panel = self.t.apply(gs, {"fx": 0.5, "fy": 0.5, "window": 99, "display": ":1"}, None) + panel = self.t.apply(gs, {"button": "left", "down": False, "window": 99, "display": ":1"}, panel) + self.assertTrue(self.t.STALE[0]) # that release was still aimed at the old panel + self.t.apply(gs, {"dx": 3, "dy": 0}, panel) + self.assertFalse(self.t.STALE[0]) + self.assertEqual(self.said[-1][1].get("stale"), None) + def test_same_window_id_on_the_other_display_is_another_panel(self): gs = FakeGamescope() self.t.apply(gs, {"fx": 0.5, "fy": 0.5, "window": 7, "display": ":0"}, None) diff --git a/ui/frame_touch.py b/ui/frame_touch.py index cf06d79..867f492 100644 --- a/ui/frame_touch.py +++ b/ui/frame_touch.py @@ -369,9 +369,10 @@ def apply(gs, event, panel): say("ready", focus=panel.get("window"), display=panel.get("display"), stale=True) # the page re-syncs STALE[0] = True return panel - if "window" in event and STALE[0]: + if STALE[0] and not stale: + # Anything that goes through (a trackpad move names no panel) means caught up: stop re-syncing. STALE[0] = False - say("ready", focus=panel.get("window"), display=panel.get("display")) # caught up: stop re-syncing + say("ready", focus=(panel or {}).get("window"), display=(panel or {}).get("display")) if "fx" in event and panel and panel.get("window"): gs.move_to(*to_root(panel, number(event["fx"], 1), number(event["fy"], 1))) if "dx" in event or "dy" in event: