feat(validation+app): real Secure Boot VFR validation, CJK widget fix, Gate 4 closure, mouse support#43
Merged
Merged
Conversation
Add MODERN_SETUP_SECURE_BOOT=1 to Scripts/build-ovmf-x64.sh: passes -D SECURE_BOOT_ENABLE=TRUE through to the upstream OVMF DSC/FDF !if blocks so SecurityPkg's real Secure Boot Configuration formset (SecureBootConfigDxe) is included. This gives the App Devices page and the modern DisplayEngine a production VFR surface (not just DriverSampleDxe). Display-only validation aid, off by default, no upstream edits -- the define flows through the overlay's preserved !if conditions. Also fix MODERN_SETUP_DEMO_DRIVER_SAMPLE so it combines with MODERN_SETUP_REPLACE_UIAPP: the DriverSample DSC/FDF insertion now anchors on QemuKernelLoaderFsDxe (stable; same anchor BootManagerMenuApp uses) instead of the UiApp component that REPLACE_UIAPP may have already replaced. The smoke OVMF fixture gains the matching anchor component/INF. Verified under QEMU (lvgl backend, app front page): Devices page lists the real formsets (32 entries / 10 HII: Secure Boot, RAM Disk, OVMF Platform Configuration, Driver Health, File Explorer, DriverSample) with the read-only preview; Enter opens the real Secure Boot Configuration form through native FormBrowser -- checkbox, mode dropdown, goto row, context-help rail all render modern. Evidence captures committed as Assets/Screenshots/modern-ovmf-x64-devices-real-hii.png and modern-ovmf-x64-secureboot-form.png. Smoke PASS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Run the LVGL productization Gate 4 resolution matrix on OVMF X64 (lvgl backend, app front page) and record the evidence: - 1920x1080: kept (above floor) -- full 13-tab nav row, 3-column quick cards with detail lines, Display row reads 1920 x 1080; no clipping/overlap. - 1024x768: kept (equals floor) -- tab scroll chevron, compact quick-card reflow (height guard drops detail lines), ellipsis truncation on long values. - 800x600: auto-promoted to 1024x768 by SelectPreferredGopMode (smallest qualifying mode); render identical to the native 1024x768 case. Method finding recorded in both the validation matrix and the build script: OVMF's QemuVideoDxe adopts the QEMU EDID preferred mode and overwrites the display PCDs at runtime (PcdVideoResolutionSource==0), so the DSC PCD default is not the effective lever under modern QEMU -- the matrix is driven with `-vga none -device VGA,edid=on,xres=<W>,yres=<H>`. Add an optional MODERN_SETUP_VIDEO_RES=<W>x<H> switch to Scripts/build-ovmf-x64.sh that rewrites the overlay's display-PCD include inline (overlay-only; upstream untouched) for the edid=off case. Evidence tables added to Docs/ProductizationValidationMatrix.md (+ zh mirror) under Phase32; Gate 4 marked closed in Docs/LvglProductizationPlan.md. Smoke PASS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
User-reported: the language dropdown showed "中文" as "??" on the LoongArch REPLACE_UIAPP firmware. Root cause: the LVGL backend's widget label path (LvglAsciiLabel) ASCII-folded every non-ASCII code point to '?', so any CJK value text in the lv_dropdown/checkbox/textarea/ordered-list widgets degraded to question marks. (The standalone ESP app links the GOP renderer, which is why the same dropdown rendered correctly there -- the bug only shows when the app renders through ModernUiLvglRendererLib, e.g. REPLACE_UIAPP lvgl firmware.) Fix at the font level rather than per-widget special cases: - Register a custom lv_font_t (LvglCjkFont) whose get_glyph_dsc/get_glyph_bitmap callbacks serve the embedded Noto Sans CJK SC 18x18 A8 subset (ModernUiFindBuiltinGlyph -- the same bitmaps the primitive text path composites), copying rows into the renderer draw buffer with the A8 stride per the upstream fmt_txt contract. The stock Latin font (LV_FONT_DEFAULT) is the fallback, so ASCII keeps the stock widget look. - Apply the font in LvglStyleControl (single shared styling point for all five widget paths). - Replace LvglAsciiLabel with LvglWidgetLabel: UTF-8 emission for subset-covered CJK; anything outside the subset still degrades to '?' so LVGL never draws a placeholder/tofu box (graceful-fallback policy). Verified under QEMU on the REPLACE_UIAPP lvgl firmware (the exact reported surface): the Exit-page language dropdown renders 中文 in both the value box and the open option list. Smoke PASS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the end-to-end interaction evidence table (EN + zh mirror): one-of popup select/commit with live IFR conditional re-evaluation on the real Secure Boot form; F10 save dialog + Y; native-vs-modern A/B proving the Secure Boot Mode revert is SecureBootConfigDxe's own RouteConfig semantics (persists only AttemptSecureBoot; CustomMode written only by key-enrollment flows), identical under both engines; grayed-control fidelity (Attempt checkbox, no PK); and the full NV persistence proof on DriverSampleDxe -- change one-of, F10/Y, cold reboot (RESET_VARS=0), value persists and dependent grayoutif/suppressif re-evaluate correctly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…t evidence
Extend the VFR write-chain table (EN + zh) with the complete Secure Boot
enablement flow driven end-to-end through the modern LVGL engine under QEMU:
Custom mode -> Custom Secure Boot Options -> PK Options -> Enroll PK -> file
explorer (volume -> root -> DER X509 pk.cer from the ESP) -> Commit Changes and
Exit. Same boot: Current Secure Boot State flips Enabled and the Attempt Secure
Boot checkbox un-grays/checks. Cold reboot: Secure Boot actively enforces --
the unsigned ESP BOOTX64.EFI is rejected ("Access Denied -- rejected probably
by Secure Boot" in serial) and BDS falls back to the FV-embedded app.
This exercises the deepest remaining VFR surfaces: nested goto subform
navigation, the dynamic file-explorer formset, action gotos with
RESET_REQUIRED, conditional un-graying on SetupMode transition, and real
security enforcement across reboot. Test PK is an openssl self-signed cert;
QEMU-only.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…r QEMU Wire the existing (but never consumed) pointer pipeline end to end and validate it under QEMU: - App main loop handles ModernUiInputPointer: scales the absolute report into framebuffer pixels via the device Mode range, tracks the cursor, throttles motion repaints (>=6px), and routes clicks. A successful hit updates the selection state and synthesizes an Enter event so the existing keyboard Enter handling stays the single owner of activation semantics. - Hit-test helpers share the painters' layout math (single source of truth): ModernSetupHitTestTab reuses a new ModernSetupGetTabWindow extracted from ModernSetupDrawTabs (scroll window + chevron inset identical); the dashboard card test reuses the quick-grid contract and the platform-visible card count (hidden cards are unclickable); the Exit-row/dropdown test shares new MODERN_SETUP_EXIT_ROW_* constants with DrawExit. - Original arrow cursor (two ModernUiFillTriangle primitives) composites last on every frame. - Fix ModernUiReadInput losing pointer reports to double-waiting: poll GetState non-blocking first, so the App's tick pre-wait consuming the WaitForInput signal no longer swallows the report. Keyboard was unaffected (buffered). - OVMF X64 overlay now always includes upstream UsbMouseAbsolutePointerDxe (upstream OVMF ships no pointer driver). Note: that edk2 driver integrates relative HID mice into its own 0..1024 absolute space -- QEMU validation uses `-device usb-mouse`; a usb-tablet's absolute reports are not understood by it. Validated end-to-end under QEMU via monitor mouse injection: cursor renders and follows; clicking a dashboard card routes to Devices; clicking tabs switches pages (scrolled-window hit-testing correct); clicking the Exit Language row opens the dropdown; clicking "English" commits and the live UI switches language. X64 + AARCH64 app builds -Werror clean; smoke PASS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Mirror the OVMF X64 change: the LoongArchVirtQemu overlay now adds upstream UsbMouseAbsolutePointerDxe next to UsbKbDxe (the platform ships only the keyboard driver), so the app's mouse support has EFI_ABSOLUTE_POINTER on LoongArch too. Anchored replacements no-op gracefully when absent. Smoke PASS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
User-reported: moving the mouse flickered the screen. Pointer motion previously set Redraw and repainted the whole frame per event -- through the LVGL backend that is a full-canvas composite + full-screen Blt each time. Replace it with classic save-under cursor compositing: - New additive renderer API pair, implemented by both backends per the ModernUiRenderer.h contract: ModernUiCaptureRect (GOP: EfiBltVideoToBltBuffer read-back; LVGL: shadow-canvas rows) and ModernUiRestoreRect (GOP: BufferToVideo; LVGL: canvas rows + BltCanvasRegion re-flush so later partial flushes cannot resurrect the overlay). - The app cursor becomes a save-under manager (ModernSetupMovePointerCursor / ModernSetupInvalidatePointerCursor in Chrome.c): restore the previous 16x16 rect, capture the new one, draw the arrow; position clamped so the fixed-size capture stays on screen. Motion events now touch only that rectangle -- no full-frame repaint, no flicker. Full repaints (clicks, page switches) invalidate the saved pixels first and re-composite with a fresh capture. Verified under QEMU (GOP path): multi-hop motion leaves a single cursor with no trails, including across click-driven full repaints. X64 + AARCH64 builds -Werror clean; smoke PASS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
User-reported: on the validation FD the Boot ("启动项") page rows could not be
operated with the mouse. The first mouse pass only hit-tested tabs, dashboard
cards, and the Exit rows -- the list pages were never wired.
Add ModernSetupHitTestPageListRow (Actions.c): it looks up the page's layout
with the exact ModernSetupGetPageListLayout parameters the page draws with
(Boot: MAX_BOOT_ROWS + native tools, no preview; Devices: MAX_DEVICE_ROWS,
preview pane; Preferences: row count), bounds the click to the page's
selectable count, and maps Y to a visible row via the row stride so a click
anywhere on a row line selects it. The App click router sets the page's
selection to the hit row and synthesizes Enter, so activation stays single-owner
(launch boot option / SendForm the HII formset / open the preference popup).
Verified under QEMU: click the Boot tab, click a boot row -> it launches through
the same path as keyboard Enter. X64 + AARCH64 builds -Werror clean; smoke PASS.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per user feedback, a single click launching a Boot entry is too eager. Make the Boot / Devices / Preferences list rows two-stage: the first click on a row only selects it (focus to content + highlight); a second click on the already-selected row activates it (the existing Enter path: launch boot option, SendForm the HII formset, or open the preference popup). A stray click can no longer launch anything. Tabs, dashboard cards, and Exit rows keep single-click navigation. Verified under QEMU: first click on a Boot row highlights it and stays on the page (no boot); second click on the same row launches it. X64 + AARCH64 builds -Werror clean; smoke PASS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Accumulated batch on
feat/real-hii-validation: real-platform VFR validation(through actually enabling Secure Boot), the CJK widget fix it surfaced, Gate 4
closure, and full mouse support for the front-page App.
Real-VFR validation (and what it proved)
MODERN_SETUP_SECURE_BOOT=1onbuild-ovmf-x64.shpasses-D SECURE_BOOT_ENABLE=TRUEthrough the overlay's preserved!ifblocks, sothe real SecurityPkg Secure Boot Configuration formset exercises the App
Devices page and the modern DisplayEngine (not just DriverSampleDxe). Also
fixes
MODERN_SETUP_DEMO_DRIVER_SAMPLE+MODERN_SETUP_REPLACE_UIAPPcombining (DriverSample re-anchored on
QemuKernelLoaderFsDxe).ProductizationValidationMatrix.md+ zh): one-ofpopup select/commit with live suppressif re-evaluation; F10 save dialog;
native-vs-modern A/B proving the Mode revert is the driver's own RouteConfig
semantics; NV persistence across cold reboot on DriverSample.
Enroll PK -> file explorer -> Commit. Same boot: Secure Boot state flips
Enabled; cold reboot: enforcement -- the unsigned ESP
BOOTX64.EFIisrejected (
Access Denied -- rejected probably by Secure Boot).Fixes the validation surfaced
?(user-reported "中文" -> "??" in thelanguage dropdown on REPLACE_UIAPP lvgl firmware). Fixed at the font level: a
custom
lv_font_tserves the embedded Noto Sans CJK SC A8 subset with thestock Latin font as fallback; out-of-subset code points still degrade to
?(never an LVGL tofu box).
ModernUiReadInputlost pointer reports to double-waiting (the tick pre-waitconsumed the
WaitForInputsignal); it now pollsGetStatenon-blockingfirst.
Gate 4 closure
Resolution matrix validated on OVMF X64 (1920x1080 / 1024x768 kept; 800x600
auto-promoted by
SelectPreferredGopMode). Method finding recorded: OVMFQemuVideoDxeadopts the QEMU EDID over the DSC display PCDs, so the matrix isdriven via
-device VGA,edid=on,xres=,yres=; a newMODERN_SETUP_VIDEO_RESswitch covers the
edid=offcase. Gate 4 marked closed inLvglProductizationPlan.md.Mouse support (IBV parity item)
cursor, and click-to-operate across all interactive surfaces --
ModernSetupGetTabWindow),unclickable),
MODERN_SETUP_EXIT_ROW_*),ModernSetupHitTestPageListRowreuses each page's
ModernSetupGetPageListLayout+ selectable count).Clicks reuse the keyboard Enter handling (single-owner activation).
click on the selected row activates -- a stray click never launches a boot
entry. Tabs/cards/Exit keep single-click navigation.
renderer API pair
ModernUiCaptureRect/ModernUiRestoreRectimplemented byboth backends (GOP framebuffer read-back; LVGL shadow-canvas + region
re-flush). Motion touches a 16x16 rect, never the full frame.
UsbMouseAbsolutePointerDxeon OVMF X64 andLoongArchVirt (upstream platforms ship no pointer driver). The edk2 driver
integrates relative HID mice (QEMU
-device usb-mouse) into its own 0..1024space; usb-tablet absolute reports are not understood by it.
Validation
QEMU end-to-end with screendump evidence at every step (incl. monitor mouse
injection: card/tab/list-row clicks route correctly, dropdown click switches the
live UI language, first-click-selects / second-click-launches on Boot rows, and
multi-hop motion leaves no trails). X64 + AARCH64 app builds -Werror clean; OVMF
modern+lvgl and LoongArch firmware build; smoke (CI gate) PASS throughout.
User-validated on LoongArch QEMU (language dropdown fix, mouse function, flicker
fix, list-row clicks, two-stage activation).
🤖 Generated with Claude Code