fix: enable adv_hittest on dial arcs so touch respects each ring's own radius

Root cause of 'only the cool/blue knob drags, regardless of where you
tap': LVGL's default arc hit-testing just uses each widget's full
bounding square (whichever topmost widget's box contains the touch
point wins), not the precise ring geometry. Since cool_arc's 360x360
box is entirely contained within heat_arc's 400x400 box, cool_arc (on
top in z-order) claimed every touch inside its own square, including
touches physically on heat_arc's outer ring, which sits outside
cool_arc's box but still within heat_arc's simple bounding-box test.

Confirmed via lv_arc.c: LVGL has a precise ring-based hit test
(LV_EVENT_HIT_TEST, respects each widget's own radius and angular
span) but it's opt-in via the ADV_HITTEST flag; without it, LVGL
falls back to the simple bounding-box test. Verified the adv_hittest:
true YAML property generates lv_obj_add_flag(..., LV_OBJ_FLAG_ADV_HITTEST)
via an isolated test compile before applying to both arcs.

The differing radii (400/360) from the previous fix are still useful
for visual separation but were never sufficient on their own — this
flag is what actually makes hit-testing respect the radius difference.
This commit is contained in:
pyr0ball 2026-07-12 10:45:52 -07:00
parent 60f133bfa3
commit 434ceda91a

View file

@ -109,6 +109,12 @@ lvgl:
max_value: 90
value: 70
adjustable: true
adv_hittest: true # LVGL's default touch hit-test just uses each widget's full
# bounding square (any topmost widget under the touch point
# wins), which is why the radius difference alone didn't fix
# touch disambiguation. adv_hittest switches to LVGL's precise
# ring-based hit test (see LV_EVENT_HIT_TEST in lv_arc.c),
# which actually respects each arc's own radius.
arc_opa: transp # flattened, see dial_bg_arc comment above
indicator:
arc_color: 0xFF3B30
@ -129,11 +135,11 @@ lvgl:
id: cool_arc
align: center
y: -20
width: 360px # smaller radius than heat_arc (400px) so the two rings occupy
height: 360px # different physical pixels — LVGL hit-tests arcs by distance
# from center, and two arcs at the same radius are touch-ambiguous;
# the topmost one (this one, declared last) always wins regardless
# of where along the ring you actually tap
width: 360px # smaller radius than heat_arc (400px) so the two rings are visually
height: 360px # distinct; touch disambiguation itself comes from adv_hittest below,
# not from this size difference alone (a same-radius pair would also
# work correctly with adv_hittest on both, but differing radii keeps
# the two rings visually separable too)
start_angle: 315
end_angle: 225
mode: REVERSE
@ -141,6 +147,7 @@ lvgl:
max_value: 90
value: 75
adjustable: true
adv_hittest: true # see heat_arc comment above — precise ring-based hit test
arc_opa: transp # flattened, see dial_bg_arc comment above
indicator:
arc_color: 0x0A84FF