applets-frontend (batch 2026-10-27-b6): AppKit UI for the library applets¶
The portable applets (controller 0xc, error 0xe, player select 0x10, web 0x13/0x17, album 0x15) had no UI: they always confirmed, logged or left at once. They now show real sheets in window mode; headless runs keep their scripted answers.
What changed¶
frontend/src/applet_sheets.m(macOS only, new):napple_frontend_sheet_controller / _player_select / _error / _web / _image(declared innapple_frontend.h). Each blocks the guest thread until the user answers. Alerts (controller, player select, error) useNSAlertin a modal loop; the web (WKWebView, http(s) andfile://offline documents, back / forward / address / Done) and album (image, Select / Next / Close album) sheets are plain windows finished by a semaphore: a modal loop does not service the dispatch queues WebKit needs (the page never committed underrunModalForWindow).file://pages may read the title's HTML root (applet_web_html_root()).- Hooks (portable,
runtime/src/services):applet_set_controller_ui/applet_controller_ask,applet_set_player_select_ui/applet_player_select_ask(applet_lib_core),applet_ui_album_selecting(is the album in select mode), album hook answer-1closes the album (album_runstops walking),applet_web_html_root.runtime/src/app.mregisters all five sheets with the existingapplet_set_error_hook,applet_ui_set_open_web,applet_ui_set_show_imageonce the window exists (register_applet_sheets, not in headless runs, not on iOS). - Scripted answers, checked before any sheet or hook so e2e can drive them:
NAPPLE_CONTROLLER_SUPPORT(cancel / strict, existing),NAPPLE_PLAYER_SELECT(<index>/cancel, existing), newNAPPLE_WEB_ANSWER(back | closed | requested | error | <exit reason number>, leaves on the page it opened), newNAPPLE_ALBUM_PICK(<index> | first | next | none), existingNAPPLE_SWKBD_ANSWER. - The controller sheet shows what the game asked (min..max, single mode), the connected pads (
frontend_connected_pads) and a players popup; cancel reports 0 players, selected id0xffffffff, result 2. The player select sheet listsapplet_profiles()(the account service's lister when one is registered, else the one local user) and cancels with result 2. The error sheet shows the error code and description. - The software keyboard already runs for real in window mode (the text bar,
frontend_text_input); nothing changed there. - Test aids:
NAPPLE_SHEET_AUTO=<action>[:ms]presses a sheet's button by itself (confirm / cancel / next / leave),NAPPLE_SHEET_SHOT=<dir>writes<sheet>.pngof the sheet window with screencapture (works in the sandboxed shell).make -C frontend test-sheetsruns all five sheets that way (12 checks, opens real windows for about 10 s); screenshots indocs/screenshots/applets-frontend/.
Verified here (Mac, audio off)¶
make -C frontend test(77 + 13 checks),make -C frontend test-sheets(12 checks, every sheet answered and its answer asserted, screenshots written),make -C runtime test test-services test-hostall green; new checks intest_svc_applet_libs(sheet answers, cancel, scripted-over-sheet, error hook),test_svc_applet_album(script values, leave, selecting flag),test_svc_applet_web(script values, html root getter).- Not verified: a sheet raised by a running title (none of the four reference titles opens these applets in the e2e path); the sheets' behaviour over a fullscreen game window; gamepad navigation of the sheets (mouse / keyboard only).
Files¶
frontend/src/applet_sheets.m, frontend/include/napple_frontend.h, frontend/Makefile (WebKit link, test-sheets), frontend/tests/test_sheets.m, runtime/src/app.m, runtime/src/services/{applet.c, applet_lib_core., applet_ui.h, applet_web_core., applet_album_core.c}, three runtime tests.