fix(engine): close Settings, Help, Leaderboard, and theme store on Esc
Test / test (pull_request) Successful in 10m16s
Test / test (pull_request) Successful in 10m16s
Phase C dismissal audit: Esc / scrim-tap / Done must behave the same on every modal. Stragglers found and fixed — none of these had any Esc path (pause's toggle guard swallowed the key while they were open): - Settings: Esc clears SettingsScreen, gated on being the topmost modal so a stacked sync-setup / theme-store dialog owns Esc - Help: Esc closes alongside F1/Done (the code comment already claimed an Esc path existed — now it does) - Leaderboard: Esc closes when topmost; the display-name dialog stacked above it now Esc-cancels like sync-setup's dialog - Theme store: Esc closes (always topmost when open) Scrim-tap opt-ins are unchanged — ui_modal documents which modals deliberately stay non-dismissible on outside clicks. Tests: escape_closes_help_screen, escape_closes_settings_screen_flag. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -343,13 +343,21 @@ fn scroll_leaderboard_panel(
|
||||
}
|
||||
}
|
||||
|
||||
/// Done click or Esc dismisses the leaderboard (Phase C dismissal
|
||||
/// audit). Esc only fires when the leaderboard is the topmost modal —
|
||||
/// with the display-name dialog stacked on top, that dialog owns Esc.
|
||||
fn handle_leaderboard_close_button(
|
||||
mut commands: Commands,
|
||||
keys: Res<ButtonInput<KeyCode>>,
|
||||
close_buttons: Query<&Interaction, (With<LeaderboardCloseButton>, Changed<Interaction>)>,
|
||||
screens: Query<Entity, With<LeaderboardScreen>>,
|
||||
other_modal_scrims: Query<(), (With<ModalScrim>, Without<LeaderboardScreen>)>,
|
||||
mut closed_flag: ResMut<ClosedThisFrame>,
|
||||
) {
|
||||
if !close_buttons.iter().any(|i| *i == Interaction::Pressed) {
|
||||
let clicked = close_buttons.iter().any(|i| *i == Interaction::Pressed);
|
||||
let esc =
|
||||
keys.just_pressed(KeyCode::Escape) && !screens.is_empty() && other_modal_scrims.is_empty();
|
||||
if !clicked && !esc {
|
||||
return;
|
||||
}
|
||||
for entity in &screens {
|
||||
@@ -888,12 +896,18 @@ fn handle_display_name_confirm(
|
||||
}
|
||||
|
||||
/// Discards any typed text and closes the display-name editor modal.
|
||||
/// Cancel click or Esc dismisses the display-name dialog without
|
||||
/// saving (Phase C dismissal audit — same contract as the sync-setup
|
||||
/// dialog's Cancel/Esc pair).
|
||||
fn handle_display_name_cancel(
|
||||
button_q: Query<&Interaction, (Changed<Interaction>, With<DisplayNameCancelButton>)>,
|
||||
keys: Res<ButtonInput<KeyCode>>,
|
||||
screens: Query<Entity, With<DisplayNameModal>>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
if !button_q.iter().any(|i| *i == Interaction::Pressed) {
|
||||
let clicked = button_q.iter().any(|i| *i == Interaction::Pressed);
|
||||
let esc = keys.just_pressed(KeyCode::Escape) && !screens.is_empty();
|
||||
if !clicked && !esc {
|
||||
return;
|
||||
}
|
||||
for entity in &screens {
|
||||
|
||||
Reference in New Issue
Block a user