Files
Sylpheed/docs/re/structures/ui-kind-focus-bit.md
sylph-decoder 126eeec437 re: kind bit 0x2 is the FOCUSABLE flag -- decoded, 0 violations in 15493 entries
The declaration entry's kind word (+0x28) and its focus/nav index (+0x2C) are the
same fact twice: kind & 0x2 is set iff the focus index is >= 0. Checked over 24
UI paks and every parseable build in each -- 1062 focusable elements, 14431 not,
zero exceptions. The test is two-sided, so it would fail if any focusable element
lacked the bit or any non-focusable element carried it.

Consequence: kind == 0x3002 is not the test for a button. It catches 778 of 1062
and misses 284 (26.7 %) at 0x2, 0x2002, 0x3003, 0x73002, 0x73003 -- including
ptbtn00.rat on GP_TITLE's PRESS (A) plate, which is 0x73002. And 0x3000, 817
elements, looks like a button and is not focusable.

This is also the refutation attempt on sylpheed-port's kind census. Their claim
-- every decoration 0x0, every button 0x3002 -- is exactly right on the two
screens they checked, reproduced here independently, and fails one build over on
the title they have not run yet.

The other kind bits are reported as observed structure and explicitly not
claimed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
2026-08-31 06:16:09 +00:00

4.2 KiB
Raw Blame History

kind bit 0x2 is the FOCUSABLE flag — decoded, 0 violations disc-wide

Status: CONFIRMED, classification decoded — the field, plus a disc-wide check. 2026-08-31.

The claim

In the 60-byte UI declaration entry, +0x28 is the kind word and +0x2C is the focus/nav index (1 on anything that cannot take the cursor). They are the same fact twice:

kind & 0x2 is set if and only if the focus index is ≥ 0.

0 violations in 15 493 declaration entries across 24 UI paks — every parseable build in each. 1 062 focusable elements, 14 431 not.

data/kind-focus-bit-census.txt · examples/kind_census_five_screens.rs

kind focus = 1 focus ≥ 0 kind focus = 1 focus ≥ 0
0x0 7 459 0 0x2 0 16
0x1 1 093 0 0x2002 0 16
0x4 2 964 0 0x3002 0 778
0x5 282 0 0x3003 0 192
0x8 650 0 0x73002 0 64
0x9 6 0 0x73003 0 96
0xC 48 0
0x10 329 0
0x14 2 0
0x3000 817 0
0x3001 10 0
0x3004 426 0
0x3008 72 0
0x300C 135 0
0x3010 38 0

Every value in the right-hand column has bit 0x2; no value in the left-hand column does.

🔴 So kind == 0x3002 is not the test for a button

It catches 778 of 1 062 focusable elements and misses 284 — 26.7 %, at 0x2, 0x2002, 0x3003, 0x73002 and 0x73003. And 0x3000, which looks like a button and appears 817 times, is not focusable.

On the screens the port ships this is not hypothetical. GP_TITLE entries 2 and 3 — the PRESS Ⓐ BUTTON plate composited over the title — declare ptbtn00.rat as 0x73002. An equality test drops it. So does the title's ptlogoall_eff.t32 / ptlogoall_eff2.t32 at 0x3000 go the other way: an equality test correctly leaves them out, but a kind >= 0x3000 test would not.

Why this is a decode and not a correlation

The two fields are independent bytes four apart in a record nobody wrote them into together, and the test is two-sided: it would fail if any focusable element lacked the bit or if any non-focusable element carried it. A one-directional check ("every button has the bit") would have been satisfied by the bit simply being common.

⚠️ What is NOT claimed. The other bits look like independent flags — 0x1 where the crate reads "has a parent", 0x4 "a repeated instance of a template", 0x10 a primitive — and 0x2000 / 0x3000 / 0x70000 like a group in the high half. That is observed structure, not decoded: nothing here tests them, and the 0x5/0x9/0xC/0x14/0x3001/0x300C combinations are consistent with flags without establishing them.

⚠️ Reach. Every .pak under dat/ that parse_build accepts — 24 archives. It says nothing about whether a focusable element is reachable by the cursor at run time, only that the declaration marks it.

Refutation attempt on sylpheed-port — survives in its scope, fails past it

Their DECISIONS.md records: "Every sprite decoration on both screens is 0x0ptframe1ptframe4 included — and every button is 0x3002."

On GP_TITLE entries 5 and 6, both halves are exactly right, and this census reproduces them independently — a third reading of the same field after their exporter and my earlier declaration walk.

🔴 One build over, both halves fail. The census above is deliberately wider than the claim in two ways, because a census that only looks where the claim looks cannot fail it: it covers every element rather than only .t32 sprites, and every build rather than the two screens. Entry 4 — the title, which they say they have not run yet — puts ptlogo1/ptlogo2 at 0x4 and ptlogoall_eff/ptlogoall_eff2 at 0x3000, and entries 2/3 put a button at 0x73002.

The claim was true of what it examined. What is refuted is its reach, and the reach is what was about to be used.