fix(engine): Android HUD QA — glyph, avatar, toggle, modal-dismiss safety
Bug A: Replace U+21C4 (tofu on FiraMono) with plain ASCII "M" on the Modes action button. Bug B: HudAvatar disc was invisible against BG_HUD_BAND (same dark grey). Switch background to ACCENT_PRIMARY and text to TEXT_PRIMARY so the disc is clearly visible. Bug C/D: toggle_hud_on_tap improvements: - Drain buffered TouchInput events in the early-return path (scrim present or paused) so the modal-dismiss frame does not replay the button tap's Started+Ended pair as a spurious toggle. - Stop clearing start_pos on TouchPhase::Moved — Android fires Moved even for clean taps (jitter), and the distance check at Ended already rejects real drags via drag.is_idle(). Clearing it silently swallowed toggle attempts on physical devices. - Increase HUD_TAP_SLOP_PX from 15 → 25 for better tap recognition. Also reduces Android HUD_BAND_HEIGHT from 128 → 80 px now that action buttons live in the bottom bar rather than the top band. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -51,12 +51,25 @@ pub struct SafeAreaAnchoredTop {
|
||||
pub base_top: f32,
|
||||
}
|
||||
|
||||
/// Marker for `Node` entities whose `bottom` offset should be re-applied
|
||||
/// as `base_bottom + SafeAreaInsets::bottom / scale`.
|
||||
///
|
||||
/// Use this for elements anchored to the bottom edge (e.g. a bottom action
|
||||
/// bar) so they clear the Android gesture-navigation zone automatically.
|
||||
#[derive(Component, Debug, Clone, Copy)]
|
||||
pub struct SafeAreaAnchoredBottom {
|
||||
pub base_bottom: f32,
|
||||
}
|
||||
|
||||
pub struct SafeAreaInsetsPlugin;
|
||||
|
||||
impl Plugin for SafeAreaInsetsPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<SafeAreaInsets>()
|
||||
.add_systems(Update, (apply_safe_area_anchors, apply_safe_area_to_modal_scrims));
|
||||
.add_systems(
|
||||
Update,
|
||||
(apply_safe_area_anchors, apply_safe_area_bottom_anchors, apply_safe_area_to_modal_scrims),
|
||||
);
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
app.add_systems(Update, android::refresh_insets);
|
||||
@@ -89,6 +102,23 @@ fn apply_safe_area_anchors(
|
||||
}
|
||||
}
|
||||
|
||||
/// Re-applies `base_bottom + insets.bottom / scale` to every entity carrying
|
||||
/// [`SafeAreaAnchoredBottom`] whenever [`SafeAreaInsets`] changes.
|
||||
fn apply_safe_area_bottom_anchors(
|
||||
insets: Res<SafeAreaInsets>,
|
||||
windows: Query<&Window>,
|
||||
mut q: Query<(&SafeAreaAnchoredBottom, &mut Node)>,
|
||||
) {
|
||||
if !insets.is_changed() {
|
||||
return;
|
||||
}
|
||||
let scale = windows.iter().next().map_or(1.0, |w| w.scale_factor());
|
||||
let bottom_logical = insets.bottom / scale;
|
||||
for (anchor, mut node) in &mut q {
|
||||
node.bottom = Val::Px(anchor.base_bottom + bottom_logical);
|
||||
}
|
||||
}
|
||||
|
||||
/// Pads the bottom of every [`ModalScrim`] by the logical bottom inset so
|
||||
/// modal cards don't extend into the Android gesture-navigation zone.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user