Keep the video rebuild required by HDR formats and the Windows Vulkan fullscreen refresh path without restarting unrelated drivers. Preserve the existing menu command dispatch and dependent HDR row refresh.
Controller reservation changes need input rediscovery, and surface recovery needs video reconstruction. Preserve unrelated drivers and core metadata by using the coupled video/input restart scope for both paths.
Keep the in-place paths first. When a frame format or driver-private OSD font needs a rebuild, preserve audio and core metadata by restarting only video and its coupled input driver.
Reset playback audio only when its effective latency target changes, including the configured floor. Handle enabled microphones independently because their latency also includes the core request. Preserve startup and staged-load deferral.
Keep recording, video, input and unrelated devices alive. A latency request changes no recording parameters and needs no cached-frame replay, aspect update or cursor change. Use the audio-specific reset to avoid repeated menu-audio initialization.
Extend the setting-command regression to cover limits, clearing, floors, microphone-only changes and deferred requests.
Advertise live resizing separately from fullscreen transitions for Windows WGL, Vulkan and D3D10/11/12. Share it between menu and queued scale requests, with video/input-only recovery on unsupported or failed resizing.
Defer resizing during fullscreen, including CLI-forced fullscreen. Avoid exclusive Vulkan renegotiation when fullscreen state does not change. Cover menu, queued, deferred and failed resize requests in the setting-command regression.
Apply menu fullscreen selections through the hotkey transition path and limit failed transitions to video/input reconstruction. Preserve suspended audio, core metadata and unrelated display resources across scoped resets, and avoid reopening menu audio for video-only resets.
Cover menu apply semantics, CLI fullscreen overrides, failed and unsupported transitions, audio retention and scoped metadata lifetime in the setting-command regression.
drivers_init() made the current-core entry anew, blank, every time; the
core's probe in driver and menu init then filled it in again. With the
core opened once, the probe is skipped while a core runs, so the entry
stayed blank: no Core Information in the Information menu, and "No Core
Information Available" from the Quick Menu. A running core's entry now
stays; one freed with the drivers is made anew, and
CMD_EVENT_CORE_INFO_INIT fills it in when it rebuilds the list.
samples/menu/core_info_page boots a core with an info file and checks
the current-core entry, the Information menu and the Core Information
page, once the core is up and again after a driver reinit; it runs in
Linux-menu-harness.yml.
Two of this week's changes did not build where CI builds them: the
setting_command harness used the mobile overlay defaults, which
file_path_special.h defines on mobile only, and the Metal driver
CGSizeZero, which the compile matrix's SDK stand-ins do not declare.
On mobile, config loading fills in the neo-retropad overlay and the
US-101 keyboard when no preset is set, but Start on Overlay Preset or
OSK Overlay Preset cleared the path, leaving touch-only devices with no
on-screen controls until the next restart. Both rows now take a Start
action that restores what a fresh configuration has: the bundled preset
under the overlay directory on mobile, no preset elsewhere.
samples/menu/setting_command presses Start on both rows, and on the OSK
opacity row beside them. CI runs the desktop half; a tree built with
CFLAGS=-DRARCH_MOBILE runs the mobile half.
Fixes#19474
#19730 made a row's command fire once where the row's flags ask for
it, and named what it left:
- A command the change handler picks itself - the audio rows, the
video scale, HDR - is fired whatever the flags say, so hiding the
flags while the row's handler runs did nothing for it. Start resets
such a row and runs the change handler, and menu_setting_generic()
runs it again: Start on Windowed Scale reinitialised the video
driver twice. The change handlers now hold their command for the
row whose handler is running (setting_cmd_held_for), and it fires
from menu_setting_generic() alone, as the flagged ones do.
- A path picked for a setting (set_path_generic()) and text entered
for one (menu_input_st_string_cb()) ran the change handler
themselves and then called menu_setting_generic(), which runs it.
The first call is gone.
samples/menu/setting_command gains a lane: Start on the video scale,
off its default, resets it and initialises the null video driver
once. With the hold taken out it fails, two times for one.
The path and text cases have no lane: both are behind a file browser
or the on-screen keyboard. The change there is the removal of a call
that the next line repeats.
menu_action_handle_setting() calls the row's handler and then
menu_setting_generic(), and both run the change handler. A handler
that runs it itself, as the boolean ones and Start do, fired the
row's command twice: once through SD_FLAG_CMD_APPLY_AUTO, or through
SD_FLAG_CMD_TRIGGER_EVENT_TRIGGERED, which stays set after a row's
first press, and once more from menu_setting_generic(). Toggling a
boolean with CMD_EVENT_REINIT, such as Bilinear Filtering from its
second press on, reinitialised the video driver twice.
The row carries neither flag while its handler runs, so the command
fires from menu_setting_generic() alone.
Still twice: set_path_generic() and menu_input_st_string_cb(), which
run the change handler before menu_setting_generic() themselves, and
the rows general_write_handler() picks the command for, such as the
audio ones.
samples/menu/setting_command presses two such rows on the null video
driver with OK, right, left and Start, and counts its inits.