diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index 4c58a09..262ef7c 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -743,10 +743,10 @@ powershell -ExecutionPolicy Bypass -File scripts\automation\apple-remote-build.p persistent-storage flushing, document browse roots, working-directory picker availability, prepared-file target planning, work-directory collection export policy, PPBR data-directory override policy, SonarPen availability, live - asset reload policy, recording cleanup policy, default canvas resolution, and - canvas tip visibility now live in the tested `platform_policy` catalog and - are consumed by both `WindowsPlatformServices` and the retained non-Windows - fallback; + asset reload policy, native UI/window state saving, recording cleanup policy, + default canvas resolution, and canvas tip visibility now live in the tested + `platform_policy` catalog and are consumed by both `WindowsPlatformServices` + and the retained non-Windows fallback; Windows live app execution now uses injected `WindowsPlatformServices` from @@ -916,8 +916,8 @@ powershell -ExecutionPolicy Bypass -File scripts\automation\apple-remote-build.p - `pp_platform_api_tests` covers service dispatch for clipboard read/write, empty clipboard writes, cursor visibility, virtual-keyboard visibility, external file display, file sharing, VR lifecycle, layout/asset file load - policy, platform-family export/storage/browse/prepared-file/canvas policies, - and picker callbacks without platform SDK headers or a window. + policy, platform-family export/storage/browse/prepared-file/UI-state/canvas + policies, and picker callbacks without platform SDK headers or a window. - `pp_app_core_document_cloud_tests` covers cloud upload no-canvas, new-document warning, clean publish prompt, and dirty save-before-upload decisions, plus cloud browse no-canvas/show-browser and selected-download diff --git a/docs/modernization/debt.md b/docs/modernization/debt.md index 1b1ed37..3492ed7 100644 --- a/docs/modernization/debt.md +++ b/docs/modernization/debt.md @@ -224,14 +224,15 @@ agent or engineer to remove them without reconstructing context from chat. Retained canvas/video export calls, Web prepared-file handoff, picker execution, export-directory creation, and desktop timelapse worker threading remain open. -- 2026-06-05: DEBT-0050, DEBT-0051, DEBT-0053, and DEBT-0057 were narrowed. +- 2026-06-05: DEBT-0050, DEBT-0051, DEBT-0052, DEBT-0053, and DEBT-0057 were narrowed. `pp_platform_api` now owns a tested `platform_policy` catalog for retained platform-family decisions covering iOS exported-image publishing, WebGL persistent-storage flushing, iOS document browse Inbox roots, Windows/macOS working-directory picker availability, iOS/Web prepared-file target selection, iOS collection-export working-directory policy, macOS PPBR data directory override, SonarPen availability, WebGL default canvas resolution, - live asset reload policy, recording cleanup policy, and canvas tip visibility. + native UI/window state saving, live asset reload policy, recording cleanup + policy, and canvas tip visibility. `WindowsPlatformServices` and the non-Windows legacy fallback consume those helpers while SDK-specific execution remains open in platform shells. - 2026-06-04: DEBT-0036 was narrowed again. Canvas stroke commit, @@ -299,7 +300,7 @@ agent or engineer to remove them without reconstructing context from chat. | DEBT-0049 | Open | Modernization | `pp_assets::validate_ppbr_header` intentionally preserves the legacy PPBR version check from `NodePanelBrushPreset::import_ppbr`, which accepts files when either major is `0` or minor is `1` instead of requiring exactly version `0.1` | Avoid rejecting existing brush packages before compatibility fixtures prove the stricter rule is safe | `pp_assets_brush_package_tests`; `pano_cli plan-brush-package-export --path D:/Paint/clouds.ppbr`; `ctest --preset desktop-fast --build-config Debug`; `cmake --build --preset windows-msvc-default --config Debug --target PanoPainter` | Add PPBR compatibility fixtures for accepted/rejected historical package versions, then require canonical `0.1` or an explicit supported-version matrix and update live import accordingly | | DEBT-0050 | Open | Modernization | iOS exported-image photo-library publishing and WebGL persistent-storage flushing now dispatch through `PlatformServices`; the iOS/Web policy decision lives in tested `pp_platform_api::platform_policy`, but non-Windows execution still lives in `src/platform_legacy/legacy_platform_services.*` and forwards to retained `save_image_library`/`webgl_sync` bridges | Preserve current iOS/Web export and save behavior while the Apple/Web platform shells are extracted incrementally | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug`; platform package smoke once Apple/Web root builds exist | Exported-image publishing and persistent-storage flushing are owned by injected Apple/Web `pp_platform_*` services with no legacy adapter branch | | DEBT-0051 | Open | Modernization | Document browser search roots and Browse dialog working-directory picker visibility/path formatting now dispatch through `PlatformServices`; iOS Inbox roots and working-directory picker availability live in tested `pp_platform_api::platform_policy`, but macOS directory picker/display-path execution still lives in `src/platform_legacy/legacy_platform_services.*` | Preserve current iOS document import/browse and desktop browse picker behavior while Apple platform shells are extracted incrementally | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug`; Apple package smoke once root Apple builds exist | Document browse roots and browse-directory picker/display formatting are owned by injected Apple and desktop `pp_platform_*` services with no legacy adapter branch | -| DEBT-0052 | Open | Modernization | Native UI/window state saving now dispatches through `PlatformServices`, but macOS execution still lives in `src/platform_legacy/legacy_platform_services.*` and forwards to the retained Objective-C app bridge | Preserve current Windows/macOS UI persistence while platform shells are extracted incrementally | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug`; Windows app build; Apple package smoke once root Apple builds exist | UI/window state persistence is owned by injected platform services with no legacy adapter branch | +| DEBT-0052 | Open | Modernization | Native UI/window state saving now dispatches through `PlatformServices`; Windows/macOS save policy lives in tested `pp_platform_api::platform_policy`, but macOS execution still lives in `src/platform_legacy/legacy_platform_services.*` and forwards to the retained Objective-C app bridge | Preserve current Windows/macOS UI persistence while platform shells are extracted incrementally | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug`; Windows app build; Apple package smoke once root Apple builds exist | UI/window state persistence is owned by injected platform services with no legacy adapter branch | | DEBT-0053 | Open | Modernization | Prepared-file writable target selection and prepared-file export-dialog policy now dispatch through `PlatformServices`; iOS temporary-file and WebGL data-path target planning live in tested `pp_platform_api::platform_policy`, but retained iOS/Web save/download handoff execution still lives in `src/platform_legacy/legacy_platform_services.*` | Preserve mobile/Web export handoff behavior while platform shells are extracted incrementally | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug`; Windows app build; Apple/Web package smoke once root package builds exist | Prepared-file target selection, export-dialog policy, and save/download handoff are owned by injected platform services with no legacy adapter branch | | DEBT-0054 | Open | Modernization | Layout XML file read/reload decisions now consume `pp_platform_api::plan_asset_file_load`, but that helper still encodes the retained compile-time platform policy: Windows/macOS use `stat` mtime reload checks, while other platforms treat already-loaded layouts as successful no-op loads | Preserve current layout hot-reload and mobile/Web single-load behavior while removing platform guards from the shared `LayoutManager` parser | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug -R pp_platform_api_tests`; Windows app build | Layout reload decisions are owned by injected platform storage/file-watch services or an asset manager boundary with platform-specific file watching removed from compile-time helpers | | DEBT-0055 | Open | Modernization | `src/app.h` now forward-declares retained iOS/macOS/Android/Linux/Web platform handles instead of including platform SDK headers, and full SDK includes are isolated in `src/platform_legacy/legacy_platform_services.cpp`, but the `App` singleton still stores those platform handles directly | Reduce central header platform coupling incrementally without rewriting non-Windows platform entrypoints before Phase 6 | Windows app build; Apple/Android/Linux/Web package smoke once platform root builds are active | Platform handles are owned by injected `pp_platform_*` shell state or services, and `App` has no platform SDK handle fields or platform conditional members | diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index b3e8416..eed8d1c 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -1404,9 +1404,10 @@ both `WindowsPlatformServices` and the retained non-Windows fallback for exported-image publishing, persistent-storage flushing, document browse roots, working-directory picker availability, prepared-file target planning, work-directory collection export policy, PPBR data-directory override policy, -SonarPen availability, live asset reload policy, recording cleanup policy, -default canvas resolution, and canvas tip visibility. Platform SDK calls remain -in the platform shells while those decisions are headless-testable. +SonarPen availability, native UI/window state saving, live asset reload policy, +recording cleanup policy, default canvas resolution, and canvas tip visibility. +Platform SDK calls remain in the platform shells while those decisions are +headless-testable. Implementation tasks: diff --git a/src/platform_api/platform_policy.cpp b/src/platform_api/platform_policy.cpp index 17c1159..d710777 100644 --- a/src/platform_api/platform_policy.cpp +++ b/src/platform_api/platform_policy.cpp @@ -43,6 +43,11 @@ bool platform_enables_live_asset_reloading(PlatformFamily family) noexcept return family == PlatformFamily::windows || family == PlatformFamily::macos; } +bool platform_saves_native_ui_state(PlatformFamily family) noexcept +{ + return family == PlatformFamily::windows || family == PlatformFamily::macos; +} + bool platform_supports_working_directory_picker(PlatformFamily family) noexcept { return family == PlatformFamily::windows || family == PlatformFamily::macos; diff --git a/src/platform_api/platform_policy.h b/src/platform_api/platform_policy.h index 053cde3..ff98a9e 100644 --- a/src/platform_api/platform_policy.h +++ b/src/platform_api/platform_policy.h @@ -23,6 +23,7 @@ enum class PlatformFamily { [[nodiscard]] bool platform_publishes_exported_images(PlatformFamily family) noexcept; [[nodiscard]] bool platform_flushes_persistent_storage(PlatformFamily family) noexcept; [[nodiscard]] bool platform_enables_live_asset_reloading(PlatformFamily family) noexcept; +[[nodiscard]] bool platform_saves_native_ui_state(PlatformFamily family) noexcept; [[nodiscard]] bool platform_supports_working_directory_picker(PlatformFamily family) noexcept; [[nodiscard]] bool platform_uses_prepared_file_writes(PlatformFamily family) noexcept; [[nodiscard]] bool platform_uses_work_directory_document_export_collections(PlatformFamily family) noexcept; diff --git a/src/platform_legacy/legacy_platform_services.cpp b/src/platform_legacy/legacy_platform_services.cpp index 2928f75..5120e2c 100644 --- a/src/platform_legacy/legacy_platform_services.cpp +++ b/src/platform_legacy/legacy_platform_services.cpp @@ -337,6 +337,8 @@ public: void save_ui_state() override { + if (!pp::platform::platform_saves_native_ui_state(pp::platform::current_platform_family())) + return; #ifdef __OSX__ [App::I->osx_app save_ui_state]; #endif diff --git a/src/platform_windows/windows_platform_services.cpp b/src/platform_windows/windows_platform_services.cpp index d283eff..0cdda9a 100644 --- a/src/platform_windows/windows_platform_services.cpp +++ b/src/platform_windows/windows_platform_services.cpp @@ -405,6 +405,8 @@ public: void save_ui_state() override { + if (!pp::platform::platform_saves_native_ui_state(pp::platform::PlatformFamily::windows)) + return; win32_save_window_state(); } diff --git a/tests/platform_api/platform_services_tests.cpp b/tests/platform_api/platform_services_tests.cpp index ab538f8..227609a 100644 --- a/tests/platform_api/platform_services_tests.cpp +++ b/tests/platform_api/platform_services_tests.cpp @@ -929,6 +929,9 @@ void platform_policy_preserves_ui_asset_and_input_rules(pp::tests::Harness& harn PP_EXPECT(harness, pp::platform::platform_enables_live_asset_reloading(pp::platform::PlatformFamily::windows)); PP_EXPECT(harness, pp::platform::platform_enables_live_asset_reloading(pp::platform::PlatformFamily::macos)); PP_EXPECT(harness, !pp::platform::platform_enables_live_asset_reloading(pp::platform::PlatformFamily::ios)); + PP_EXPECT(harness, pp::platform::platform_saves_native_ui_state(pp::platform::PlatformFamily::windows)); + PP_EXPECT(harness, pp::platform::platform_saves_native_ui_state(pp::platform::PlatformFamily::macos)); + PP_EXPECT(harness, !pp::platform::platform_saves_native_ui_state(pp::platform::PlatformFamily::webgl)); PP_EXPECT(harness, pp::platform::platform_uses_ppbr_export_data_directory_override(pp::platform::PlatformFamily::macos)); PP_EXPECT(harness, !pp::platform::platform_uses_ppbr_export_data_directory_override(pp::platform::PlatformFamily::windows)); PP_EXPECT(harness, pp::platform::platform_supports_sonarpen(pp::platform::PlatformFamily::ios));