From cc8e5c6fcaa966abb7fd7c78699246d3cb001663 Mon Sep 17 00:00:00 2001 From: Sock Date: Wed, 23 Sep 2026 14:04:18 -0500 Subject: [PATCH] Repository: native/ becomes src/ and tests/ The first step of the C++ rewrite of the app: with the Python on its way out, "native" stops meaning anything. - src/core, src/style, src/tools: the reader and renderer, the style plugin and the tools, unchanged - CMakeLists.txt, build.sh, check-abi.sh, fuzz.sh at the root; build trees in build/-qt/ and build/fuzz/ - tests/core: test-core, the fuzz targets and their vectors - tests/oracle: the XP-VM tooling (styles_matrix, conformance, export_check, the control jobs and the synthetic scheme) - native/README.md folded into the root README, with the new layout Verified from the new places: test-core (Qt 6 and 5), the style matrix (unchanged, 113/120 per visual style, 111/120 Classic), export_check, and a release build through check-abi. Co-Authored-By: Claude Opus 5.5 (1M context) --- .gitignore | 5 +- native/CMakeLists.txt => CMakeLists.txt | 40 +++++++------- README.md | 52 +++++++++++++++--- native/build.sh => build.sh | 16 +++--- native/check-abi.sh => check-abi.sh | 2 +- native/fuzz.sh => fuzz.sh | 18 +++--- native/README.md | 42 -------------- {native => src}/core/dib.cpp | 0 {native => src}/core/dib.h | 0 {native => src}/core/ini.cpp | 0 {native => src}/core/ini.h | 0 {native => src}/core/pe.cpp | 0 {native => src}/core/pe.h | 0 {native => src}/core/render.cpp | 0 {native => src}/core/render.h | 0 {native => src}/core/schema.cpp | 0 {native => src}/core/schema.h | 0 {native => src}/core/theme.cpp | 0 {native => src}/core/theme.h | 0 {native => src}/style/plugin.cpp | 0 {native => src}/style/xplasma.json | 0 {native => src}/style/xplasmastyle.cpp | 0 {native => src}/style/xplasmastyle.h | 0 {native => src}/tools/dump.cpp | 2 +- {native => src}/tools/gallery.cpp | 2 +- {native => src}/tools/probe.cpp | 0 {native => src}/tools/render.cpp | 2 +- {native/tests => tests/core}/fuzz.cpp | 2 +- {native/tests => tests/core}/test_core.cpp | 4 +- .../core}/vectors/dib-huge-rle4.bin | Bin {native/tests => tests/oracle}/conformance.py | 4 +- {native/tests => tests/oracle}/controls-1.job | 0 {native/tests => tests/oracle}/controls-2.job | 0 {native/tests => tests/oracle}/controls-3.job | 0 {native/tests => tests/oracle}/controls-4.job | 0 .../oracle}/controls_compare.py | 0 .../tests => tests/oracle}/export_check.py | 2 +- {native/tests => tests/oracle}/fuzz_seeds.py | 0 .../tests => tests/oracle}/keyboard_cues.py | 0 {native/tests => tests/oracle}/live_reload.py | 0 .../tests => tests/oracle}/oracle_compare.py | 2 +- .../oracle}/schemes/Synthetic.theme | 0 .../tests => tests/oracle}/styles_matrix.py | 12 ++-- {native/tests => tests/oracle}/synth.py | 0 {native/tests => tests/oracle}/text_boxes.py | 0 45 files changed, 100 insertions(+), 107 deletions(-) rename native/CMakeLists.txt => CMakeLists.txt (78%) rename native/build.sh => build.sh (64%) rename native/check-abi.sh => check-abi.sh (97%) rename native/fuzz.sh => fuzz.sh (62%) delete mode 100644 native/README.md rename {native => src}/core/dib.cpp (100%) rename {native => src}/core/dib.h (100%) rename {native => src}/core/ini.cpp (100%) rename {native => src}/core/ini.h (100%) rename {native => src}/core/pe.cpp (100%) rename {native => src}/core/pe.h (100%) rename {native => src}/core/render.cpp (100%) rename {native => src}/core/render.h (100%) rename {native => src}/core/schema.cpp (100%) rename {native => src}/core/schema.h (100%) rename {native => src}/core/theme.cpp (100%) rename {native => src}/core/theme.h (100%) rename {native => src}/style/plugin.cpp (100%) rename {native => src}/style/xplasma.json (100%) rename {native => src}/style/xplasmastyle.cpp (100%) rename {native => src}/style/xplasmastyle.h (100%) rename {native => src}/tools/dump.cpp (98%) rename {native => src}/tools/gallery.cpp (99%) rename {native => src}/tools/probe.cpp (100%) rename {native => src}/tools/render.cpp (99%) rename {native/tests => tests/core}/fuzz.cpp (95%) rename {native/tests => tests/core}/test_core.cpp (97%) rename {native/tests => tests/core}/vectors/dib-huge-rle4.bin (100%) rename {native/tests => tests/oracle}/conformance.py (98%) rename {native/tests => tests/oracle}/controls-1.job (100%) rename {native/tests => tests/oracle}/controls-2.job (100%) rename {native/tests => tests/oracle}/controls-3.job (100%) rename {native/tests => tests/oracle}/controls-4.job (100%) rename {native/tests => tests/oracle}/controls_compare.py (100%) rename {native/tests => tests/oracle}/export_check.py (98%) rename {native/tests => tests/oracle}/fuzz_seeds.py (100%) rename {native/tests => tests/oracle}/keyboard_cues.py (100%) rename {native/tests => tests/oracle}/live_reload.py (100%) rename {native/tests => tests/oracle}/oracle_compare.py (98%) rename {native/tests => tests/oracle}/schemes/Synthetic.theme (100%) rename {native/tests => tests/oracle}/styles_matrix.py (95%) rename {native/tests => tests/oracle}/synth.py (100%) rename {native/tests => tests/oracle}/text_boxes.py (100%) diff --git a/.gitignore b/.gitignore index 736796d..a53c9ff 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,7 @@ iso/ samples/ # Build output -native/build*/ +build/ out/ refharness/build/ @@ -22,5 +22,4 @@ __pycache__/ app/schemes/user/ app/plugins/ refharness/share/ -native/build-fuzz/ -!native/tests/schemes/*.theme +!tests/oracle/schemes/*.theme diff --git a/native/CMakeLists.txt b/CMakeLists.txt similarity index 78% rename from native/CMakeLists.txt rename to CMakeLists.txt index 6ed3069..5ce7b21 100644 --- a/native/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,8 @@ -# XPLasma native: the msstyles core, renderer and Qt style plugin. +# XPLasma: the msstyles core, renderer, Qt style plugin and tools. # -# One source tree, built once per Qt major: -# cmake -S native -B native/build-qt6 -G Ninja -DQT_MAJOR=6 -# cmake -S native -B native/build-qt5 -G Ninja -DQT_MAJOR=5 +# One source tree, built once per Qt major (build.sh does this in podman): +# cmake -S . -B build/dev-qt6 -G Ninja -DQT_MAJOR=6 +# cmake -S . -B build/dev-qt5 -G Ninja -DQT_MAJOR=5 # # Only public Qt API is allowed (no *Private targets, no _p.h headers). That is # what lets a plugin built against the oldest supported Qt of a major load into @@ -32,21 +32,21 @@ add_compile_definitions(QT_NO_KEYWORDS QT_USE_QSTRINGBUILDER) # --- the core: .msstyles in, typed theme data out (QtCore + QtGui only) -------- add_library(xplasma-core STATIC - core/pe.cpp - core/dib.cpp - core/ini.cpp - core/theme.cpp - core/schema.cpp - core/render.cpp + src/core/pe.cpp + src/core/dib.cpp + src/core/ini.cpp + src/core/theme.cpp + src/core/schema.cpp + src/core/render.cpp ) -target_include_directories(xplasma-core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(xplasma-core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) target_link_libraries(xplasma-core PUBLIC ${QT}::Gui) set_target_properties(xplasma-core PROPERTIES POSITION_INDEPENDENT_CODE ON) # --- the style plugin --------------------------------------------------------- add_library(xplasma MODULE - style/plugin.cpp - style/xplasmastyle.cpp + src/style/plugin.cpp + src/style/xplasmastyle.cpp ) # libstdc++ first. Link order decides which library a symbol is bound to, and # the Qt Company's official Qt 5.15 binaries export sized operator delete @@ -60,28 +60,28 @@ set_target_properties(xplasma PROPERTIES PREFIX "lib" OUTPUT_NAME xplasma) install(TARGETS xplasma LIBRARY DESTINATION qt${QT_MAJOR}/styles) # --- tools -------------------------------------------------------------------- -add_executable(xplasma-probe tools/probe.cpp) +add_executable(xplasma-probe src/tools/probe.cpp) target_link_libraries(xplasma-probe PRIVATE ${QT}::Widgets) -add_executable(xplasma-gallery tools/gallery.cpp) +add_executable(xplasma-gallery src/tools/gallery.cpp) target_link_libraries(xplasma-gallery PRIVATE ${QT}::Widgets) -add_executable(xplasma-render tools/render.cpp) +add_executable(xplasma-render src/tools/render.cpp) target_link_libraries(xplasma-render PRIVATE stdc++ xplasma-core) -add_executable(xplasma-dump tools/dump.cpp) +add_executable(xplasma-dump src/tools/dump.cpp) target_link_libraries(xplasma-dump PRIVATE stdc++ xplasma-core) # --- tests ------------------------------------------------------------------------ -add_executable(test-core tests/test_core.cpp) +add_executable(test-core tests/core/test_core.cpp) target_link_libraries(test-core PRIVATE stdc++ xplasma-core) -# --- fuzzing (native/fuzz.sh; clang only) -------------------------------------------- +# --- fuzzing (fuzz.sh; clang only) -------------------------------------------- option(XPLASMA_FUZZ "Build the libFuzzer targets (needs clang)" OFF) if(XPLASMA_FUZZ) foreach(target theme dib ini) string(TOUPPER ${target} TARGET_UPPER) - add_executable(fuzz-${target} tests/fuzz.cpp) + add_executable(fuzz-${target} tests/core/fuzz.cpp) target_compile_definitions(fuzz-${target} PRIVATE FUZZ_TARGET_${TARGET_UPPER}=1) target_link_libraries(fuzz-${target} PRIVATE xplasma-core) target_link_options(fuzz-${target} PRIVATE -fsanitize=fuzzer,address,undefined) diff --git a/README.md b/README.md index 5a929dc..f9a6bda 100644 --- a/README.md +++ b/README.md @@ -8,20 +8,54 @@ it: window decorations, taskbar and Start menu, tray, fonts, colours, wallpaper, icons, and **every Qt application's widgets**, drawn by a native Qt style that reads the `.msstyles` itself. -**Status: early.** The Python app is carried over from xp2plasma and works as -it did. The native style (`native/`) is being built, following -[PLAN.md](PLAN.md). Findings and follow-ups live in [NOTES.md](NOTES.md). +**Status:** the style is done to the pixel against real XP (see PLAN.md and +NOTES.md). The app around it -- the Display Properties editor, the +generators and the CLI -- is being rewritten from the Python carried over from +xp2plasma into C++/Qt 6 on the same core; until that lands, the Python app in +`app/` is what runs. ## Layout | Path | What | | --- | --- | -| `app/` | The Python app: the Display Properties editor, the generators (decorations, panel, Start menu, icons, …) and the CLI. Carried over from xp2plasma. | -| `native/` | The C++ core, renderer and Qt 5/6 style plugin *(in progress)*. | -| `refharness/` | Programs that run inside the Windows XP reference VM and dump what real uxtheme draws *(in progress)*. | -| `containers/` | Build containers: the dev image (host-matched toolchain) and release images (oldest supported Qt). | +| `src/core/` | The `.msstyles` reader (PE, DIB, INI cascade, schema) and the renderer, pixel-exact against XP. | +| `src/style/` | The Qt 5/6 style plugin, drawing every widget from the core. | +| `src/tools/` | `xplasma-render` (oracle renders, `--export`), `xplasma-dump`, `xplasma-gallery`, `xplasma-probe`. | +| `tests/core/` | The core's unit test and fuzz targets, with their vectors. | +| `tests/oracle/` | Dev tooling that holds the style against the Windows XP reference VM (`styles_matrix.py`, …). | +| `refharness/` | The programs that run inside the XP VM and dump what real uxtheme draws. | +| `app/` | The Python app carried over from xp2plasma, being replaced (see above). | +| `containers/` | Build containers: the dev image (host-matched toolchain) and the release image (oldest supported Qt). | | `docs/xp2plasma/` | xp2plasma's README and visual notes, kept for reference. | +## Building + +The host needs no compiler; everything builds in podman. + +```sh +podman build -t xplasma-dev:3.8.1x -f containers/dev.Containerfile containers # once +podman build -t xplasma-release:1 -f containers/release.Containerfile containers # once + +./build.sh dev # host-matched Qt, for iterating: build/dev-qt{6,5}/ +./build.sh release # Qt 6.6.3 / 5.15.2: the portable, shipping build +``` + +Both install the style to `app/plugins/qt{6,5}/styles/libxplasma.so`. + +A plugin built against Qt *6.N* loads into every Qt ≥ *6.N*, **provided** it +uses only public Qt API and binds nothing else to Qt (the 6.6.3 build runs on +the host's 6.9.1 and in PySide6's 6.11.2; the 5.15.2 build on 5.15.17). +`check-abi.sh` enforces that on every release build: no private Qt symbols, no +non-Qt symbol bound to a Qt version (the Qt Company's 5.15 binaries export sized +`operator delete`, which is why libstdc++ is linked first), only the plugin +entry points exported, glibc no newer than 2.34. + +```sh +QT_PLUGIN_PATH=$PWD/app/plugins/qt6 build/dev-qt6/xplasma-probe --out /tmp/probe.png +QT_PLUGIN_PATH=$PWD/app/plugins/qt6 dolphin -style XPLasma +XPLASMA_SAFE=1 … # the plugin draws nothing of its own (classic only) +``` + ## Running from a checkout ```sh @@ -38,7 +72,9 @@ see `app/paths.py`. Nothing Microsoft-copyrighted is in this repository. ## Tests ```sh -for t in app/tests/test_*.py; do QT_QPA_PLATFORM=offscreen .venv/bin/python3 "$t"; done +build/dev-qt6/test-core # the core +tests/oracle/styles_matrix.py OUT # the style against real XP (needs refharness/vm.sh) +for t in app/tests/test_*.py; do QT_QPA_PLATFORM=offscreen .venv/bin/python3 "$t"; done # the Python app ``` Tests that need the official styles or the XP media find them through diff --git a/native/build.sh b/build.sh similarity index 64% rename from native/build.sh rename to build.sh index 8b05ebd..41dcb0e 100755 --- a/native/build.sh +++ b/build.sh @@ -1,16 +1,16 @@ #!/bin/sh # Build the XPLasma style plugins into app/plugins/qt{6,5}/styles/. # -# native/build.sh dev host-matched toolchain and Qt; fastest iteration -# native/build.sh release oldest supported Qt (6.6.3 / 5.15.2); portable, -# and gated by check-abi.sh +# ./build.sh dev host-matched toolchain and Qt; fastest iteration +# ./build.sh release oldest supported Qt (6.6.3 / 5.15.2); portable, +# and gated by check-abi.sh # # Both run in podman (the containers/ images), so the host needs no compiler. # `dev` output loads only into Qt >= the host's own; `release` output is what # ships, and loads into every Qt >= 6.6 / 5.15. set -eu mode="${1:-dev}" -root="$(cd "$(dirname "$0")/.." && pwd)" +root="$(cd "$(dirname "$0")" && pwd)" case "$mode" in dev) image=localhost/xplasma-dev:3.8.1x; prefix6=; prefix5= ;; release) image=localhost/xplasma-release:1; prefix6='$QT6_DIR'; prefix5='$QT5_DIR' ;; @@ -19,13 +19,13 @@ esac podman run --rm -v "$root:/src" -w /src "$image" sh -ec " for m in 6 5; do if [ \$m = 6 ]; then qt=$prefix6; else qt=$prefix5; fi - cmake -S native -B native/build-$mode-qt\$m -G Ninja -DQT_MAJOR=\$m \ + cmake -S . -B build/$mode-qt\$m -G Ninja -DQT_MAJOR=\$m \ -DCMAKE_BUILD_TYPE=$( [ "$mode" = release ] && echo Release || echo RelWithDebInfo ) \ \${qt:+-DCMAKE_PREFIX_PATH=\$qt} -DCMAKE_INSTALL_PREFIX=/src/app/plugins >/dev/null - cmake --build native/build-$mode-qt\$m - cmake --install native/build-$mode-qt\$m >/dev/null + cmake --build build/$mode-qt\$m + cmake --install build/$mode-qt\$m >/dev/null done" if [ "$mode" = release ]; then - for m in 6 5; do "$root/native/check-abi.sh" "$root/app/plugins/qt$m/styles/libxplasma.so"; done + for m in 6 5; do "$root/check-abi.sh" "$root/app/plugins/qt$m/styles/libxplasma.so"; done fi echo "installed into app/plugins ($mode)" diff --git a/native/check-abi.sh b/check-abi.sh similarity index 97% rename from native/check-abi.sh rename to check-abi.sh index ce2c75c..5e302ae 100755 --- a/native/check-abi.sh +++ b/check-abi.sh @@ -1,7 +1,7 @@ #!/bin/sh # Release gate for a built style plugin: is it really portable? # -# native/check-abi.sh path/to/libxplasma.so [max-glibc] +# ./check-abi.sh path/to/libxplasma.so [max-glibc] # # A plugin that passes loads into every Qt of its major at or above its build # floor, on any distribution with at least `max-glibc` (default 2.34, the same diff --git a/native/fuzz.sh b/fuzz.sh similarity index 62% rename from native/fuzz.sh rename to fuzz.sh index 5ef38c8..68923e4 100755 --- a/native/fuzz.sh +++ b/fuzz.sh @@ -1,23 +1,23 @@ #!/bin/sh # Fuzz the core's parsers: PE/theme, DIB and INI, each under ASan + UBSan. # -# native/fuzz.sh [SECONDS] default 600 per target, all three in parallel +# ./fuzz.sh [SECONDS] default 600 per target, all three in parallel # -# Seeds come from native/tests/synth.py (always) plus, when the corpus is on +# Seeds come from tests/oracle/synth.py (always) plus, when the corpus is on # this machine, real resources extracted from it (seeds stay local: they are -# derived from Microsoft's files). Crashes land in native/build-fuzz/crashes/. +# derived from Microsoft's files). Crashes land in build/fuzz/crashes/. set -eu -root="$(cd "$(dirname "$0")/.." && pwd)" +root="$(cd "$(dirname "$0")" && pwd)" seconds="${1:-600}" -work="$root/native/build-fuzz" +work="$root/build/fuzz" mkdir -p "$work/seeds/theme" "$work/seeds/dib" "$work/seeds/ini" "$work/crashes" -"$root/.venv/bin/python3" "$root/native/tests/fuzz_seeds.py" "$work/seeds" +"$root/.venv/bin/python3" "$root/tests/oracle/fuzz_seeds.py" "$work/seeds" podman run --rm -v "$root:/src" -w /src localhost/xplasma-dev:3.8.1x sh -ec ' -cmake -S native -B native/build-fuzz/build -G Ninja -DQT_MAJOR=6 -DXPLASMA_FUZZ=ON \ +cmake -S . -B build/fuzz/build -G Ninja -DQT_MAJOR=6 -DXPLASMA_FUZZ=ON \ -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ -DCMAKE_CXX_FLAGS="-fsanitize=fuzzer-no-link,address,undefined -fno-sanitize-recover=undefined" >/dev/null -cmake --build native/build-fuzz/build --target fuzz-theme fuzz-dib fuzz-ini >/dev/null' -podman run --rm -v "$root:/src" -w /src/native/build-fuzz localhost/xplasma-dev:3.8.1x sh -c " +cmake --build build/fuzz/build --target fuzz-theme fuzz-dib fuzz-ini >/dev/null' +podman run --rm -v "$root:/src" -w /src/build/fuzz localhost/xplasma-dev:3.8.1x sh -c " for t in theme dib ini; do ( mkdir -p corpus/\$t && ./build/fuzz-\$t corpus/\$t seeds/\$t -max_total_time=$seconds -max_len=4194304 \ -rss_limit_mb=4096 -timeout=10 -artifact_prefix=crashes/\$t- -print_final_stats=1 > log-\$t.txt 2>&1; diff --git a/native/README.md b/native/README.md deleted file mode 100644 index e4a62aa..0000000 --- a/native/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# native/ - -XPLasma's C++ side: the Qt style plugin that draws widgets straight from a -`.msstyles`, and the tools around it. One source tree, built once per Qt major. -PLAN.md describes the architecture (§3) and the phases (§8). - -## Building - -The host needs no compiler; everything builds in podman. - -```sh -podman build -t xplasma-dev:3.8.1x -f containers/dev.Containerfile containers # once -podman build -t xplasma-release:1 -f containers/release.Containerfile containers # once - -native/build.sh dev # host-matched Qt, for iterating -native/build.sh release # Qt 6.6.3 / 5.15.2: the portable, shipping build -``` - -Both install to `app/plugins/qt{6,5}/styles/libxplasma.so`, which is where -`app/widget_style.py` picks the plugins up from. - -## The portability rules - -A plugin built against Qt *6.N* loads into every Qt ≥ *6.N*, **provided** it -uses only public Qt API and binds nothing else to Qt. Measured (PLAN.md §11): -the Qt 6.6.3 build runs on the host's 6.9.1 and in PySide6's 6.11.2; the -5.15.2 build runs on 5.15.17. `check-abi.sh` enforces the rules on every -release build: - -- no `*_PRIVATE_API` Qt symbols (no `_p.h` headers, no `Qt::*Private` targets); -- no non-Qt symbol bound to a Qt version. The Qt Company's 5.15 binaries export - sized `operator delete`, which is why libstdc++ is linked first; -- only `qt_plugin_instance` / `qt_plugin_query_metadata*` exported; -- glibc no newer than 2.34. - -## Trying it - -```sh -QT_PLUGIN_PATH=$PWD/app/plugins/qt6 native/build-dev-qt6/xplasma-probe --out /tmp/probe.png -QT_PLUGIN_PATH=$PWD/app/plugins/qt6 dolphin -style XPLasma -XPLASMA_SAFE=1 … # the plugin draws nothing of its own (classic only) -``` diff --git a/native/core/dib.cpp b/src/core/dib.cpp similarity index 100% rename from native/core/dib.cpp rename to src/core/dib.cpp diff --git a/native/core/dib.h b/src/core/dib.h similarity index 100% rename from native/core/dib.h rename to src/core/dib.h diff --git a/native/core/ini.cpp b/src/core/ini.cpp similarity index 100% rename from native/core/ini.cpp rename to src/core/ini.cpp diff --git a/native/core/ini.h b/src/core/ini.h similarity index 100% rename from native/core/ini.h rename to src/core/ini.h diff --git a/native/core/pe.cpp b/src/core/pe.cpp similarity index 100% rename from native/core/pe.cpp rename to src/core/pe.cpp diff --git a/native/core/pe.h b/src/core/pe.h similarity index 100% rename from native/core/pe.h rename to src/core/pe.h diff --git a/native/core/render.cpp b/src/core/render.cpp similarity index 100% rename from native/core/render.cpp rename to src/core/render.cpp diff --git a/native/core/render.h b/src/core/render.h similarity index 100% rename from native/core/render.h rename to src/core/render.h diff --git a/native/core/schema.cpp b/src/core/schema.cpp similarity index 100% rename from native/core/schema.cpp rename to src/core/schema.cpp diff --git a/native/core/schema.h b/src/core/schema.h similarity index 100% rename from native/core/schema.h rename to src/core/schema.h diff --git a/native/core/theme.cpp b/src/core/theme.cpp similarity index 100% rename from native/core/theme.cpp rename to src/core/theme.cpp diff --git a/native/core/theme.h b/src/core/theme.h similarity index 100% rename from native/core/theme.h rename to src/core/theme.h diff --git a/native/style/plugin.cpp b/src/style/plugin.cpp similarity index 100% rename from native/style/plugin.cpp rename to src/style/plugin.cpp diff --git a/native/style/xplasma.json b/src/style/xplasma.json similarity index 100% rename from native/style/xplasma.json rename to src/style/xplasma.json diff --git a/native/style/xplasmastyle.cpp b/src/style/xplasmastyle.cpp similarity index 100% rename from native/style/xplasmastyle.cpp rename to src/style/xplasmastyle.cpp diff --git a/native/style/xplasmastyle.h b/src/style/xplasmastyle.h similarity index 100% rename from native/style/xplasmastyle.h rename to src/style/xplasmastyle.h diff --git a/native/tools/dump.cpp b/src/tools/dump.cpp similarity index 98% rename from native/tools/dump.cpp rename to src/tools/dump.cpp index db9a287..2005061 100644 --- a/native/tools/dump.cpp +++ b/src/tools/dump.cpp @@ -2,7 +2,7 @@ // // xplasma-dump FILE.msstyles [--variant NAME_INI | --all-variants] [--no-bitmaps] // -// The conformance test (native/tests/conformance.py) compares this with +// The conformance test (tests/oracle/conformance.py) compares this with // xp2plasma's Python parser over the whole corpus: variant tables, every INI // section (headers canonicalised to sub::class.part(state)), and a SHA-256 of // every bitmap's decoded RGBA pixels. diff --git a/native/tools/gallery.cpp b/src/tools/gallery.cpp similarity index 99% rename from native/tools/gallery.cpp rename to src/tools/gallery.cpp index 3c6408f..0438ad8 100644 --- a/native/tools/gallery.cpp +++ b/src/tools/gallery.cpp @@ -5,7 +5,7 @@ // // --controls reads uxdump's `control` lines and grabs the same Qt widget at // the same size into OUTDIR/control___x.png, for -// native/tests/controls_compare.py to hold against XP's own. +// tests/oracle/controls_compare.py to hold against XP's own. // // The same layout as refharness's refdialog.exe (the Win32 twin, drawn by // real XP), so the two can be compared side by side. With --out it renders diff --git a/native/tools/probe.cpp b/src/tools/probe.cpp similarity index 100% rename from native/tools/probe.cpp rename to src/tools/probe.cpp diff --git a/native/tools/render.cpp b/src/tools/render.cpp similarity index 99% rename from native/tools/render.cpp rename to src/tools/render.cpp index 191ef8c..6112d95 100644 --- a/native/tools/render.cpp +++ b/src/tools/render.cpp @@ -8,7 +8,7 @@ // For every `part` line, writes s____x_black.png // and _white.png (the render composited over opaque black / white, exactly // how uxdump captures real uxtheme) and a metrics.txt line in uxdump's -// format. native/tests/oracle_compare.py puts the two side by side. +// format. tests/oracle/oracle_compare.py puts the two side by side. // `style -` (whatever style XP has applied) has no meaning here; parts under // it are skipped. #include "core/render.h" diff --git a/native/tests/fuzz.cpp b/tests/core/fuzz.cpp similarity index 95% rename from native/tests/fuzz.cpp rename to tests/core/fuzz.cpp index 6fb319e..81362ab 100644 --- a/native/tests/fuzz.cpp +++ b/tests/core/fuzz.cpp @@ -1,6 +1,6 @@ // libFuzzer targets for everything that parses untrusted bytes. // -// Built three times with -DFUZZ_TARGET=theme|dib|ini (see native/fuzz.sh). +// Built three times with -DFUZZ_TARGET=theme|dib|ini (see fuzz.sh). // The plugin is loaded into plasmashell and every Qt app, so a crash here is // a crashed desktop: nothing a .msstyles contains may crash, hang or read out // of bounds. AddressSanitizer and UBSan run underneath. diff --git a/native/tests/test_core.cpp b/tests/core/test_core.cpp similarity index 97% rename from native/tests/test_core.cpp rename to tests/core/test_core.cpp index 516e70f..4d2abdd 100644 --- a/native/tests/test_core.cpp +++ b/tests/core/test_core.cpp @@ -31,12 +31,12 @@ static QString get(const Ini &ini, const char *sub, const char *cls, const char .value_or(QStringLiteral("")); } -// Test vectors live in native/tests/vectors; build trees sit in native/build-*/. +// Test vectors live in tests/core/vectors; build trees sit in build/-qt/. static QString vectors; int main(int, char **argv) { - vectors = QFileInfo(QString::fromLocal8Bit(argv[0])).absolutePath() + QLatin1String("/../tests/vectors"); + vectors = QFileInfo(QString::fromLocal8Bit(argv[0])).absolutePath() + QLatin1String("/../../tests/core/vectors"); // Headers: every piece but the class is optional; a trailing state // belongs to the part, or to the class when there's no part. diff --git a/native/tests/vectors/dib-huge-rle4.bin b/tests/core/vectors/dib-huge-rle4.bin similarity index 100% rename from native/tests/vectors/dib-huge-rle4.bin rename to tests/core/vectors/dib-huge-rle4.bin diff --git a/native/tests/conformance.py b/tests/oracle/conformance.py similarity index 98% rename from native/tests/conformance.py rename to tests/oracle/conformance.py index 027d8c6..99705e3 100644 --- a/native/tests/conformance.py +++ b/tests/oracle/conformance.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """The C++ core must read every .msstyles exactly as xp2plasma's parser does. - native/tests/conformance.py [--dump PATH/TO/xplasma-dump] [--jobs N] [STYLE ...] + tests/oracle/conformance.py [--dump PATH/TO/xplasma-dump] [--jobs N] [STYLE ...] Compares, per style: the variant tables, the default variant, every layout INI's sections (both sides canonicalised to sub::class.part(state)) and the @@ -30,7 +30,7 @@ sys.path.insert(0, str(ROOT / "app" / "tests")) FAN_CORPUS = Path(os.environ.get("XPLASMA_FAN_CORPUS", Path.home() / "clod/xp2plasma/parked/ultimate/extracted")) -DUMP = ROOT / "native/build-dev-qt6/xplasma-dump" +DUMP = ROOT / "build/dev-qt6/xplasma-dump" def canonical(header: str) -> str: diff --git a/native/tests/controls-1.job b/tests/oracle/controls-1.job similarity index 100% rename from native/tests/controls-1.job rename to tests/oracle/controls-1.job diff --git a/native/tests/controls-2.job b/tests/oracle/controls-2.job similarity index 100% rename from native/tests/controls-2.job rename to tests/oracle/controls-2.job diff --git a/native/tests/controls-3.job b/tests/oracle/controls-3.job similarity index 100% rename from native/tests/controls-3.job rename to tests/oracle/controls-3.job diff --git a/native/tests/controls-4.job b/tests/oracle/controls-4.job similarity index 100% rename from native/tests/controls-4.job rename to tests/oracle/controls-4.job diff --git a/native/tests/controls_compare.py b/tests/oracle/controls_compare.py similarity index 100% rename from native/tests/controls_compare.py rename to tests/oracle/controls_compare.py diff --git a/native/tests/export_check.py b/tests/oracle/export_check.py similarity index 98% rename from native/tests/export_check.py rename to tests/oracle/export_check.py index eaeafab..373f9e3 100644 --- a/native/tests/export_check.py +++ b/tests/oracle/export_check.py @@ -24,7 +24,7 @@ from pathlib import Path from PIL import Image ROOT = Path(__file__).resolve().parents[2] -RENDER = ROOT / "native/build-dev-qt6/xplasma-render" +RENDER = ROOT / "build/dev-qt6/xplasma-render" STYLES = [ ("Luna/luna.msstyles", "NORMALBLUE_INI"), ("Luna/luna.msstyles", "NORMALMETALLIC_INI"), diff --git a/native/tests/fuzz_seeds.py b/tests/oracle/fuzz_seeds.py similarity index 100% rename from native/tests/fuzz_seeds.py rename to tests/oracle/fuzz_seeds.py diff --git a/native/tests/keyboard_cues.py b/tests/oracle/keyboard_cues.py similarity index 100% rename from native/tests/keyboard_cues.py rename to tests/oracle/keyboard_cues.py diff --git a/native/tests/live_reload.py b/tests/oracle/live_reload.py similarity index 100% rename from native/tests/live_reload.py rename to tests/oracle/live_reload.py diff --git a/native/tests/oracle_compare.py b/tests/oracle/oracle_compare.py similarity index 98% rename from native/tests/oracle_compare.py rename to tests/oracle/oracle_compare.py index cea3bfd..bcda793 100644 --- a/native/tests/oracle_compare.py +++ b/tests/oracle/oracle_compare.py @@ -24,7 +24,7 @@ from pathlib import Path from PIL import Image, ImageChops ROOT = Path(__file__).resolve().parents[2] -RENDER = ROOT / "native/build-dev-qt6/xplasma-render" +RENDER = ROOT / "build/dev-qt6/xplasma-render" sys.path.insert(0, str(ROOT / "refharness")) diff --git a/native/tests/schemes/Synthetic.theme b/tests/oracle/schemes/Synthetic.theme similarity index 100% rename from native/tests/schemes/Synthetic.theme rename to tests/oracle/schemes/Synthetic.theme diff --git a/native/tests/styles_matrix.py b/tests/oracle/styles_matrix.py similarity index 95% rename from native/tests/styles_matrix.py rename to tests/oracle/styles_matrix.py index 6747adf..ca2f847 100644 --- a/native/tests/styles_matrix.py +++ b/tests/oracle/styles_matrix.py @@ -5,7 +5,7 @@ For each style below, XP applies it for real (uxdump's `apply`: the visual style and its system colours, as Display Properties would), captures -native/tests/controls-*.job, then puts Luna Silver back; xplasma-gallery +tests/oracle/controls-*.job, then puts Luna Silver back; xplasma-gallery renders the same controls from the same .msstyles. Prints a table of exact controls and differing pixels per style; OUTDIR/