From d7966c178047d190faba7100a40385eb00f5894b Mon Sep 17 00:00:00 2001 From: idatui Date: Sun, 9 Aug 2026 13:55:31 +0200 Subject: Graph: fix the triskel fallbacks, and say why when it still falls back "engine triskel -> native+triskel-failed" was unreadable and, worse, gave no reason: the cause went to a logger a TUI user never sees. Dumped all 400 functions of bin/ls (echo's 128 were not enough) and swept them at three zoom levels: 6 of 1200 layouts fell back, all of them my own _verify tripping over a detour that could not be placed. - the detour jumped to the nearest side of the FIRST box in the way, which in a dense layout is usually inside the next box along. It now collects every box the run passes and picks the nearest genuinely free line. - it skipped the first and last segments because they carry the port and the arrowhead. But that is exactly where the failures were: triskel is happy to park a block directly above its successor and drive the final approach straight through it. Those segments may now move ALONG their own box's border, which is free almost every time. - repairs are swept to a fixed point: moving one segment stretches its neighbours, which can push those into a box. 0/1200 fallbacks after that. Then the bigger corpus turned up a second, genuinely upstream defect: superimposing SESE regions can leave two blocks a couple of columns into each other (2 of ls's 400 functions, in float space, before rounding). Cosmetic in a PNG; here the boxes are made of text, so one block's disassembly overwrites another's. _verify now checks it and falls back, which is the right trade. Reporting, so this is never mute again: - stats["engine_error"] carries the reason, the status line shows it, and the label is "native (triskel failed)". - the corpus test asserts fallbacks are rare AND explained, rather than asserting they never happen. Also lowered AUTO_TRISKEL_MAX_BLOCKS 250 -> 180. Layout runs on every zoom keypress and triskel knees hard past ~175 blocks (174: 66ms, 233: 489ms, 329: 555ms). The old cap allowed a 489ms stall. The corpus timing check now measures only sizes `auto` can actually reach, plus a 5s ceiling so nothing blows up quadratically when forced. --- idatui/app.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'idatui/app.py') diff --git a/idatui/app.py b/idatui/app.py index b2b1722..4b3d5fb 100644 --- a/idatui/app.py +++ b/idatui/app.py @@ -2685,6 +2685,9 @@ class GraphView(NavMixin, ScrollView, can_focus=True): # installed" on its own sends people to check the wrong python. note = ("" if graph_triskel.available() else f" (no pytriskel in {sys.executable})") + # A fallback with no reason is a bug report nobody can file. + if self.lay and self.lay.stats.get("engine_error"): + note = f" \u2014 {self.lay.stats['engine_error']}" self.app._status(f"graph: engine {self._engine} \u2192 {got}{note}") def action_center(self) -> None: -- cgit v1.3.1-sl0p