feat(menu): Esc opens the Insert menu by default (Menu shortcut "Insert, F1 or Esc") #2197

Merged
pmwork-personal merged 6 commits from feat/menu-esc-default into main 2026-11-11 21:12:00 +00:00
pmwork-personal commented 2026-11-11 07:11:32 +00:00 (Migrated from github.com)

On PC, Esc is the key that opens a game's menu, and players expect it: after #1998 added Esc as an opt-in Menu shortcut
choice, null asked in #dev-work why Esc closes the Insert menu but doesn't open it. This makes that choice the default,
for existing players too.

What changed

  • gpu/vk/vk_menu.h: menu_shortcut defaults to 2, Insert, F1 or Esc. On a closed menu Esc opens it; while it is
    open Esc still goes back a page or closes it. F1 always works, and the row still offers Insert or F1 and F1 only.
  • Existing options move too (options_version 5). null is an existing player, and so is nearly everyone who would
    notice this. The menu writes every row on save, so the old default, menu_shortcut=0 (Insert or F1), is in every
    options file whether the player chose it or not. A default that only new installs get wouldn't reach them. Like Game
    speed (version 2) and Descriptor reuse (version 4), menu_init now moves an older file's 0 to 2. Only 0 moves:
    • Insert and F1 still open the menu after the move, so nothing is taken away; Esc is added.
    • F1 only (1) can only have been chosen on purpose, so it stays. 2 stays.
    • save() writes options_version=5, so a player who picks Insert or F1 from now on keeps it.
    • #2110 (FSR 3.1 as the default Upscaler without matrix hardware) also takes version 5 for its own move. Whichever
      lands second takes 6; it's a one-line renumber plus its test, and I'll do it here if this one is second.
  • Play is unchanged. Esc still lets a captured mouse go first, and the menu it opens gives the capture back when it
    closes (esc_had_capture, #1998 and #2035, unchanged here). No game control can be bound to Esc (bindable_keys,
    host/nn_hid.c defaults), and a gamepad's back button counts as Esc only while the menu is open.
  • readme.md: the menu keys paragraph (with the move of older options), and the Menu shortcut row's values and default
    in the options table.
  • tests/test_menu_keys.py:
    • It compiles menu_tick's Esc block with the real Options from vk_menu.h and the row's names
      (tx_menu_shortcut). Out of the box the shortcut is "Insert, F1 or Esc", and Esc opens a closed menu without the same
      press going back a page. With Insert or F1 or F1 only, Esc leaves it closed. Both polled and queued presses.
    • It also compiles menu_init's reading of hookshot_options.ini and loads real files through it. From before
      version 5 (versions 2 to 4, or no options_version line): 0 loads as 2, 1 and 2 stay, no line gets 2. At the
      version save() writes now, read from save() itself: 0, 1 and 2 all stay.
    • This replaces the text check that pinned the old default (int menu_shortcut = 0;).

Testing

  • tests/test_menu_keys.py passes, and each part fails without its change:
    • default put back to 0: the "Insert, F1 or Esc" check fails;
    • migration line removed: loaded_as(0, old) == 2 fails;
    • save() left writing options_version=4: loaded_as(mode, 4) == mode fails (a choice made after the change would
      be moved again).
  • The other tests that read the menu's sources, its options or the window's Esc handling pass: test_menu_env_on,
    test_audio_output_menu, test_framegen_preset, test_rumble_menu, test_vsync_row, test_audio_volume,
    test_menu_size, test_stick_dead_zone, test_menu_hit, test_menu_restart, test_menu_restart_slots,
    test_gpu_choice, test_display_pointer, test_screensaver.
  • tests/run_all.py on Windows (llvm-mingw), on main e19d969 with this change: 341 passed, 2 failed, 30 skipped.
    The two failures fail the same way on untouched main on this PC: test_precompile_compute_guard (this toolchain has no
    windows.h for its fixture) and test_recorder_sync (its exit case; its vk_menu.cpp source checks pass).

Not tested: in game (no build of this branch was run; the Esc behaviour itself is #1998's, which was played),
Linux.

Screenshots: nothing new on screen. The row and its values are #1998's; it now starts on "Insert, F1 or Esc".

🤖 Generated with Claude Code

On PC, Esc is the key that opens a game's menu, and players expect it: after #1998 added Esc as an opt-in Menu shortcut choice, null asked in #dev-work why Esc closes the Insert menu but doesn't open it. This makes that choice the default, for existing players too. **What changed** - `gpu/vk/vk_menu.h`: `menu_shortcut` defaults to 2, **Insert, F1 or Esc**. On a closed menu Esc opens it; while it is open Esc still goes back a page or closes it. F1 always works, and the row still offers Insert or F1 and F1 only. - **Existing options move too (`options_version` 5).** null is an existing player, and so is nearly everyone who would notice this. The menu writes every row on save, so the old default, `menu_shortcut=0` (Insert or F1), is in every options file whether the player chose it or not. A default that only new installs get wouldn't reach them. Like Game speed (version 2) and Descriptor reuse (version 4), `menu_init` now moves an older file's 0 to 2. Only 0 moves: - Insert and F1 still open the menu after the move, so nothing is taken away; Esc is added. - F1 only (1) can only have been chosen on purpose, so it stays. 2 stays. - `save()` writes `options_version=5`, so a player who picks Insert or F1 from now on keeps it. - #2110 (FSR 3.1 as the default Upscaler without matrix hardware) also takes version 5 for its own move. Whichever lands second takes 6; it's a one-line renumber plus its test, and I'll do it here if this one is second. - Play is unchanged. Esc still lets a captured mouse go first, and the menu it opens gives the capture back when it closes (`esc_had_capture`, #1998 and #2035, unchanged here). No game control can be bound to Esc (`bindable_keys`, `host/nn_hid.c` defaults), and a gamepad's back button counts as Esc only while the menu is open. - `readme.md`: the menu keys paragraph (with the move of older options), and the Menu shortcut row's values and default in the options table. - `tests/test_menu_keys.py`: - It compiles `menu_tick`'s Esc block with the real `Options` from `vk_menu.h` and the row's names (`tx_menu_shortcut`). Out of the box the shortcut is "Insert, F1 or Esc", and Esc opens a closed menu without the same press going back a page. With Insert or F1 or F1 only, Esc leaves it closed. Both polled and queued presses. - It also compiles `menu_init`'s reading of `hookshot_options.ini` and loads real files through it. From before version 5 (versions 2 to 4, or no `options_version` line): 0 loads as 2, 1 and 2 stay, no line gets 2. At the version `save()` writes now, read from `save()` itself: 0, 1 and 2 all stay. - This replaces the text check that pinned the old default (`int menu_shortcut = 0;`). **Testing** - `tests/test_menu_keys.py` passes, and each part fails without its change: - default put back to 0: the "Insert, F1 or Esc" check fails; - migration line removed: `loaded_as(0, old) == 2` fails; - `save()` left writing `options_version=4`: `loaded_as(mode, 4) == mode` fails (a choice made after the change would be moved again). - The other tests that read the menu's sources, its options or the window's Esc handling pass: `test_menu_env_on`, `test_audio_output_menu`, `test_framegen_preset`, `test_rumble_menu`, `test_vsync_row`, `test_audio_volume`, `test_menu_size`, `test_stick_dead_zone`, `test_menu_hit`, `test_menu_restart`, `test_menu_restart_slots`, `test_gpu_choice`, `test_display_pointer`, `test_screensaver`. - `tests/run_all.py` on Windows (llvm-mingw), on main `e19d969` with this change: 341 passed, 2 failed, 30 skipped. The two failures fail the same way on untouched main on this PC: `test_precompile_compute_guard` (this toolchain has no `windows.h` for its fixture) and `test_recorder_sync` (its exit case; its `vk_menu.cpp` source checks pass). **Not tested**: in game (no build of this branch was run; the Esc behaviour itself is #1998's, which was played), Linux. **Screenshots**: nothing new on screen. The row and its values are #1998's; it now starts on "Insert, F1 or Esc". 🤖 Generated with [Claude Code](https://claude.com/claude-code)
hckrman101 commented 2026-11-11 12:16:20 +00:00 (Migrated from github.com)

I think someone is trying to get normal mouse/keyboard working, so Esc should probably open the in-game menu in the future

I think someone is trying to get normal mouse/keyboard working, so Esc should probably open the in-game menu in the future
hckrman101 commented 2026-11-11 15:50:52 +00:00 (Migrated from github.com)

Heads-up: this conflicts with main now. Could you rebase onto main and resolve the conflicts? Thanks!

Heads-up: this conflicts with main now. Could you rebase onto main and resolve the conflicts? Thanks!
pmwork-personal commented 2026-11-11 16:17:11 +00:00 (Migrated from github.com)

Merged main in to clear the conflict with #2181 (no force-push). The FPS counter rows from #2181 are kept as they are, and the Menu shortcut default is 2 again on top. tests/run_all.py on Windows: 342 passed, 30 skipped, 2 failed (test_recorder_sync and test_precompile_compute_guard, which also fail on untouched main here).

On Esc and keyboard play: agreed. Once the game takes keyboard and mouse input, Esc should open the game's own menu. Then the default can move again with the next options_version, the same way this PR moves it. Until then Esc does nothing in game, so opening the Insert menu with it is what players asked for.

(Still open: #2110 also writes options_version 5. Whichever lands second takes 6.)

Merged main in to clear the conflict with #2181 (no force-push). The FPS counter rows from #2181 are kept as they are, and the Menu shortcut default is 2 again on top. `tests/run_all.py` on Windows: 342 passed, 30 skipped, 2 failed (`test_recorder_sync` and `test_precompile_compute_guard`, which also fail on untouched main here). On Esc and keyboard play: agreed. Once the game takes keyboard and mouse input, Esc should open the game's own menu. Then the default can move again with the next `options_version`, the same way this PR moves it. Until then Esc does nothing in game, so opening the Insert menu with it is what players asked for. (Still open: #2110 also writes `options_version` 5. Whichever lands second takes 6.)
Joey-Magnus (Migrated from github.com) approved these changes 2026-11-11 20:07:17 +00:00
Joey-Magnus (Migrated from github.com) left a comment

This looks good. The migration is the right shape: only a pre-version-5 menu_shortcut=0 moves to 2 (gpu/vk/vk_menu.cpp:2956), F1 only is left alone, and save() writes options_version=5 (gpu/vk/vk_menu.cpp:1374), so a player who picks Insert or F1 again keeps it. I checked the places where a new default for Esc could leak into play:

  • The keyboard is polled only while our window has the focus (mine in menu_tick), so Esc pressed in another app doesn't open the menu.
  • The right mouse button and the gamepad's back button only count as Esc while the menu is open (press[5] from the pointer is read only under open_now, and pad_back likewise), so a right click or B in game doesn't open it.
  • esc_opens clears press[5], so the press that opens the menu doesn't also go back a page.

The rewritten tests/test_menu_keys.py is stronger than the text check it replaces: it compiles the real Esc block and menu_init's reader against real files. I ran it at the PR's head, together with test_menu_env_on, test_menu_restart, test_menu_restart_slots and test_display_pointer: all pass. The branch merges cleanly onto current main (still at options_version=4). The two red CI jobs are unrelated: test_native_astc_texture_count.py on Windows, fixed on main by #2397, and a Launchpad PPA timeout in appimage. A re-run or a merge of main should clear them.

One thing to keep in mind rather than change:

  • minor #2110 is still open and also claims options_version 5. Whichever merges second has to renumber both its save() line and its version < N check (and its test's expected version), or the second migration will never run for files the first one already rewrote. You've already said you'll take 6 if this one lands second; just flagging it so the maintainer merging the second one checks it.
This looks good. The migration is the right shape: only a pre-version-5 `menu_shortcut=0` moves to 2 (`gpu/vk/vk_menu.cpp:2956`), F1 only is left alone, and `save()` writes `options_version=5` (`gpu/vk/vk_menu.cpp:1374`), so a player who picks Insert or F1 again keeps it. I checked the places where a new default for Esc could leak into play: - The keyboard is polled only while our window has the focus (`mine` in `menu_tick`), so Esc pressed in another app doesn't open the menu. - The right mouse button and the gamepad's back button only count as Esc while the menu is open (`press[5]` from the pointer is read only under `open_now`, and `pad_back` likewise), so a right click or B in game doesn't open it. - `esc_opens` clears `press[5]`, so the press that opens the menu doesn't also go back a page. The rewritten `tests/test_menu_keys.py` is stronger than the text check it replaces: it compiles the real Esc block and `menu_init`'s reader against real files. I ran it at the PR's head, together with `test_menu_env_on`, `test_menu_restart`, `test_menu_restart_slots` and `test_display_pointer`: all pass. The branch merges cleanly onto current main (still at `options_version=4`). The two red CI jobs are unrelated: `test_native_astc_texture_count.py` on Windows, fixed on main by #2397, and a Launchpad PPA timeout in `appimage`. A re-run or a merge of main should clear them. One thing to keep in mind rather than change: - **minor** #2110 is still open and also claims `options_version` 5. Whichever merges second has to renumber both its `save()` line and its `version < N` check (and its test's expected version), or the second migration will never run for files the first one already rewrote. You've already said you'll take 6 if this one lands second; just flagging it so the maintainer merging the second one checks it.
pmwork-personal commented 2026-11-11 21:09:10 +00:00 (Migrated from github.com)

Merged main: the vk_menu.h conflict with #2378's compact_menu_key is cleared; Menu shortcut stays "Insert, F1 or Esc" by default, with the options_version=5 move of older files.

Merged main: the `vk_menu.h` conflict with #2378's `compact_menu_key` is cleared; Menu shortcut stays "Insert, F1 or Esc" by default, with the `options_version=5` move of older files.
Joey-Magnus (Migrated from github.com) reviewed 2026-11-11 21:25:32 +00:00
Joey-Magnus (Migrated from github.com) left a comment

The conflict is one line (vk_menu.h, main's new compact_menu_key). After resolving it, the rewritten tests/test_menu_keys.py doesn't compile against main, because menu_tick/menu_init now use tune_mode, tune_down, has_memory_budget and has_vram_budget, which the fixture doesn't stub. The red checks are main's old ASTC failure and a PPA timeout.

options_version=5 is also used by #2119 and #2110. Suggested order: this one, then #2177, then #2119 rebased, with later ones renumbering their save() line, version < N check and tests.

The conflict is one line (`vk_menu.h`, main's new `compact_menu_key`). After resolving it, the rewritten `tests/test_menu_keys.py` doesn't compile against main, because `menu_tick`/`menu_init` now use `tune_mode`, `tune_down`, `has_memory_budget` and `has_vram_budget`, which the fixture doesn't stub. The red checks are main's old ASTC failure and a PPA timeout. `options_version=5` is also used by #2119 and #2110. Suggested order: this one, then #2177, then #2119 rebased, with later ones renumbering their `save()` line, `version < N` check and tests.
Commenting is not possible because the repository is archived.
No description provided.