Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0 - #173

Merged
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero
Aug 25, 2026
Merged

Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0#173
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero

Conversation

@fdesbiens

@fdesbiensfdesbiens commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Fixes#172

Problem

GUIX Studio emits five static helper functions in the generated specification file as soon as a project uses Screen Flow. Two of them, gx_studio_action_parent_find() and gx_studio_animation_execute(), are reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference the GUIX animation API, which is compiled out when the animation pool is empty:

  • gx_system_animation_get() is only defined under #if (GX_ANIMATION_POOL_SIZE > 0) in gx_api.h.
  • The body of _gx_animation_start() is guarded the same way in gx_animation_start.c, so the reference does not resolve at link time either.

A project that defines GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save resources therefore fails to build, even when it uses no animation action at all.

Reproduced on system_screen_stack_specifications.c with GX_ANIMATION_POOL_SIZE 0:

error C4013: 'gx_system_animation_get' undefined; assuming extern returning int
UNDEF External | _gxe_animation_start <- LNK2019 at link time
UNDEF External | gx_system_animation_get

GCC 14, the default compiler for the project, rejects the implicit declaration outright rather than warning about it.

Fix

screen_generator.cpp now wraps both helpers and the two GX_ACTION_TYPE_ANIMATION dispatch sites (the <= 50402 and the current library version branches) in #if (GX_ANIMATION_POOL_SIZE > 0). Every other action type keeps working with an empty pool, and an animation action simply becomes a no-op at runtime.

The generator also emits forward prototypes for the four static Screen Flow helpers, which addresses the secondary request in the issue. Note that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule 8.4 applies to objects and functions with external linkage, so the static helpers without a visible prototype were not a deviation. The prototypes are still worth having, and they match the declaration the generator already emits for gx_studio_nested_widget_create().

Generated files

All 30 checked-in generated *_specifications.c files were re-synced with the generator, including the three golden files of the Studio view test.

Verified with test_demo/test_main.py -t across all 227 Studio projects: 227 passed, 0 failed, so the updated files match generator output exactly.

Regression test

test/guix_studio_test/test_demo/test_animation_pool_size.py, registered in the demo_compile CTest project so the existing GUIX Studio Demo Compile Test workflow runs it:

  1. Source check — the two helper definitions and the case label must sit inside the guard. Rejects "prototypes only guarded", "definitions unguarded", "case unguarded" and the pre-fix shape.
  2. Compile check — compiles every Screen Flow specification file with GX_ANIMATION_POOL_SIZE 0 and /we4013, so the implicit declaration is an error rather than a warning.

Results on this branch: 27 source-checked, 25 compiled, all passing in about 7 seconds under ctest. Against the pre-fix tree the same test fails 27/28 source checks and 24/26 compiles.

all_widgets_5_4_0 and all_widgets_5_4_1 are excluded from the compile stage because their generated code targets a pre-5.4.2 widget API; the existing demo compile test skips them for the same reason. They are still covered by the source check.

Documentation

Matching documentation update: eclipse-threadx/rtos-docs-asciidoc#42

🤖 Generated with Claude Code


Hotfix release preparation

This PR also carries the version bump for the emergency hotfix release that ships the fix, 6.5.1.202602a.

Release tooling

The tooling could not express a hotfix version at all, so it was fixed first:

  • Get-StudioReleaseVersion rejected anything that was not major.minor.patch.build, and update_studio_release_version.ps1 hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build a hotfix installer was unusable, and running the script after a manual edit would have reset the hotfix constant.
  • prepare_release.sh searched only ports/ for gx_port.h, so it never updated the version string of the GUIX Studio Win32 port in guix_studio/ports/gx_port.h.

Get-StudioReleaseVersion now accepts an optional trailing hotfix letter and exposes it as Hotfix / HotfixDefine. The Win32 and MSIX version formats are strictly numeric and cannot carry the letter, so the revision is offset by the position of the letter in the alphabet instead:

InputFullVersionWin32MSIXRC numericHotfix
6.5.1.2026026.5.1.2026026.5.1.26.5.1.026,5,1,2' '
6.5.1.202602a6.5.1.202602a6.5.1.36.5.1.036,5,1,3'a'
6.5.1.202602b6.5.1.202602b6.5.1.46.5.1.046,5,1,4'b'

That keeps the hotfix installer recognizable as the newer build for Windows upgrade detection and for the Store. Versions without a hotfix letter resolve exactly as before, and 6.5.1, 6.5.1.202602A, 6.5.1.202602ab and 6.5.1.202602-a are all still rejected.

Version constants

Produced by scripts/update_studio_release_version.ps1 -Version 6.5.1.202602a, plus the port strings:

  • common/inc/gx_api.hGUIX_HOTFIX_VERSION 'a'. Major, minor, patch, build and the 6.5.1 banner are unchanged.
  • guix_studio/studiox.rcFileVersion / ProductVersion strings 6.5.1.202602a; FILEVERSION / PRODUCTVERSION6,5,1,3.
  • guix_studio/installer/guix_installer_release.issStudioFullVersion "6.5.1.202602a", StudioVersionInfoVersion "6.5.1.3", so the installer is named guix_studio_setup_version_6.5.1.202602a.exe.
  • guix_studio/build/vs_2022/msix_package_project/Package.appxmanifest — MSIX identity 6.5.1.03.
  • All 47 gx_port.h files, including guix_studio/ports/gx_port.h.

STUDIOX_VERSION_NUMBER deliberately stays at 202602: it stamps the Studio version into .gxp project files, and a hotfix does not change the project file format.

Verified against a rebuilt guix_studio.exe, which reports FileVersion 6.5.1.202602a with a numeric file version of 6.5.1.3 — what verify_studio_installer.ps1 checks.

README.md still points at the current 6.5.1.202602 download, since the v6.5.1.202602a_rel tag and its asset do not exist yet. It should be updated when the release is published.

Re-verified after the bump

  • test_animation_pool_size.py: 27 source-checked, 25 compiled, 0 failures.
  • test_main.py -t: 227 projects, 227 passed, 0 failed.

GUIX Studio emitted five static helper functions in the generated
specification file as soon as a project used Screen Flow. Two of them,
gx_studio_action_parent_find() and gx_studio_animation_execute(), are
reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference
the GUIX animation API, which is compiled out when the animation pool
is empty:
- gx_system_animation_get() is only defined under
"#if (GX_ANIMATION_POOL_SIZE > 0)" in gx_api.h.
- The body of _gx_animation_start() is guarded the same way in
gx_animation_start.c, so the reference does not resolve at link
time either.
A project that defined GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save
resources therefore failed to build even when it used no animation
action at all. GCC 14 rejects the implicit declaration outright, and
MSVC fails on the unresolved external.
The screen generator now wraps both helpers and the two
GX_ACTION_TYPE_ANIMATION dispatch sites in
"#if (GX_ANIMATION_POOL_SIZE > 0)". Every other action type keeps
working with an empty pool, and an animation action simply becomes a
no-op at runtime.
The generator also emits forward prototypes for the four static screen
flow helpers, which addresses the secondary request in the issue. Note
that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule
8.4 applies to objects and functions with external linkage, so static
helpers without a visible prototype were not a deviation. The
prototypes are still worth having and match the declaration the
generator already emits for gx_studio_nested_widget_create().
All the checked-in generated specification files were regenerated so
that they stay in sync with the generator, including the golden files
of the Studio view test.
Added test/guix_studio_test/test_demo/test_animation_pool_size.py as a
regression test, registered in the demo compile CTest project. It
verifies that every checked-in Screen Flow specification file guards
the animation helpers, then compiles them all with
GX_ANIMATION_POOL_SIZE set to 0, promoting the MSVC implicit
declaration warning to an error so the failure mode above is caught.
Fixeseclipse-threadx#172
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fdesbiensand others added 3 commits August 25, 2026 11:10
The release tooling could not express a hotfix version. Two gaps:
- Get-StudioReleaseVersion rejected anything that was not
major.minor.patch.build, and update_studio_release_version.ps1
hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build
a hotfix installer was therefore unusable, and running the script
after a manual edit would have reset the hotfix constant.
- prepare_release.sh looked for gx_port.h under ports only, so it
never updated the version string of the GUIX Studio Win32 port in
guix_studio/ports/gx_port.h.
Get-StudioReleaseVersion now accepts an optional trailing hotfix letter
and exposes it as Hotfix and HotfixDefine. The Win32 and MSIX version
formats are strictly numeric and cannot carry the letter, so the
revision is offset by the position of the letter in the alphabet
instead: 6.5.1.202602 keeps revision 2, and 6.5.1.202602a becomes
revision 3. That keeps the hotfix installer recognizable as the newer
build for Windows upgrade detection and for the Store. Versions without
a hotfix letter resolve exactly as before.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Prepares the emergency hotfix release that carries the Screen Flow fix
for GX_ANIMATION_POOL_SIZE = 0.
Produced by scripts/update_studio_release_version.ps1 -Version
6.5.1.202602a:
- gx_api.h: GUIX_HOTFIX_VERSION is now 'a'. The major, minor, patch
and build constants are unchanged, as is the 6.5.1 banner.
- studiox.rc: FileVersion and ProductVersion strings are
6.5.1.202602a, FILEVERSION and PRODUCTVERSION are 6,5,1,3.
- guix_installer_release.iss: StudioFullVersion is 6.5.1.202602a and
StudioVersionInfoVersion is 6.5.1.3, so the installer is named
guix_studio_setup_version_6.5.1.202602a.exe.
- Package.appxmanifest: the MSIX identity version is 6.5.1.03.
STUDIOX_VERSION_NUMBER stays at 202602. It stamps the Studio version
into .gxp project files, and a hotfix does not change the project file
format.
Verified against a rebuilt guix_studio.exe, which reports FileVersion
6.5.1.202602a with a numeric file version of 6.5.1.3, matching what
verify_studio_installer.ps1 expects.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Updated the _gx_version_id string in all 47 gx_port.h files for the
emergency hotfix release, using the same substitution that
prepare_release.sh performs.
This includes guix_studio/ports/gx_port.h, the GUIX Studio Win32 port,
which the release script previously missed because it only searched the
ports directory. That gap is fixed in the preceding commit, so a future
release picks the file up automatically.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit c179c19 into eclipse-threadx:devAug 25, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fix/issue-172-animation-pool-size-zero branch August 25, 2026 17:10
@fdesbiens

Copy link
Copy Markdown
ContributorAuthor

@parsley This PR should fix your issue. I need to prepare a new installer and release. This should be done tomorrow (Wednesday).

fdesbiens added a commit that referenced this pull request Aug 27, 2026
compare_file() locates the line where comparison should start, so that the
banner GUIX Studio writes into every generated file -- which carries a revision
string and a generation timestamp -- is skipped rather than compared. It looked
that line up correctly in the first file and then looked it up in the first file
again for the second:
for line in list_2:
if compare_start_string in line:
start_row_2 = list_1.index(line)
So the golden was sliced at the *generated* file's offset. While both files
happened to reach "#include" on the same line the mistake was invisible, which
is why it survived since the tests were added in #84.
The offsets diverged when 6ba13db added a ten-line MIT licence header to all
111 golden .c and .h files. GUIX Studio does not emit that header, so every
golden now reaches its first #include ten lines later than the file it is
compared against. The golden was therefore sliced ten lines early and compared
banner text against source.
That made every one of the 107 .c and .h comparisons in the suite fail -- all 29
reported test failures -- while the .csv, .xliff and .xml comparisons passed.
Those use skip_line instead of compare_start_string and never reach this code,
which is exactly the split the failure log shows.
The reported mismatch is the same in all 29: a generated "#include" line against
a golden banner comment. Confirmed arithmetically -- in every case the golden
line reported sits exactly ten lines before that golden's own first #include:
generic_16bpp_resources.c reported idx 13, #include at 23, delta 10
generic_16bpp_resources.h reported idx 16, #include at 26, delta 10
generic_16bpp_specifications.c reported idx 14, #include at 24, delta 10
generic_16bpp_specifications.h reported idx 16, #include at 26, delta 10
compare_output_file() is the only caller that passes compare_start_string, so
the change cannot affect the xliff, xml or plain-file comparisons.
Verified by running the suite locally against a Studio built from this tree.
Seven suites that fail in CI now pass with no mismatches at all, each gaining
exactly the tests it had been failing:
CI (broken) local (fixed)
Font 9 / 1 10 / 0
Multi-Themes 18 / 1 19 / 0
Project Import 10 / 2 12 / 0
Trigger Edit 6 / 1 7 / 0
Trigger Target Rename 1 / 1 2 / 0
Bidi Text 3 / 1 4 / 0
Widget Name 3 / 1 4 / 0
Project Import compares a generated specifications file, so this also shows that
the screen flow prototype block added by #173 does not disturb these goldens:
that block is only emitted for projects that use Screen Flow, and these do not.
No golden file is regenerated. The goldens still carry "GUIX Studio Revision
6.1.12.0" and a 2022 timestamp in their banners, and still name Azure RTOS
rather than Eclipse ThreadX, but the banner is what the comparison is supposed
to skip -- so none of that needs to be touched to make the suite correct.
This workflow had never actually executed before 2026-08-27. Every earlier run
was cancelled after queueing 24 hours for the retired windows-2019 image, or
sat awaiting approval on a fork pull request, including the run for the v6.5.1
release itself. #174 gave it a runner again; this is the first result it has
ever produced, and the defect it found is in the test harness rather than in
GUIX or in Studio.
Note that studio_view_test.yml triggers only on pull requests targeting master,
so this change is not exercised by its own pull request into dev. It is
validated by the release pull request that carries dev to master.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0 - #173

Merged
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero
Aug 25, 2026
Merged

Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0#173
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero

Conversation

@fdesbiens

@fdesbiensfdesbiens commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Fixes#172

Problem

GUIX Studio emits five static helper functions in the generated specification file as soon as a project uses Screen Flow. Two of them, gx_studio_action_parent_find() and gx_studio_animation_execute(), are reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference the GUIX animation API, which is compiled out when the animation pool is empty:

  • gx_system_animation_get() is only defined under #if (GX_ANIMATION_POOL_SIZE > 0) in gx_api.h.
  • The body of _gx_animation_start() is guarded the same way in gx_animation_start.c, so the reference does not resolve at link time either.

A project that defines GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save resources therefore fails to build, even when it uses no animation action at all.

Reproduced on system_screen_stack_specifications.c with GX_ANIMATION_POOL_SIZE 0:

error C4013: 'gx_system_animation_get' undefined; assuming extern returning int
UNDEF External | _gxe_animation_start <- LNK2019 at link time
UNDEF External | gx_system_animation_get

GCC 14, the default compiler for the project, rejects the implicit declaration outright rather than warning about it.

Fix

screen_generator.cpp now wraps both helpers and the two GX_ACTION_TYPE_ANIMATION dispatch sites (the <= 50402 and the current library version branches) in #if (GX_ANIMATION_POOL_SIZE > 0). Every other action type keeps working with an empty pool, and an animation action simply becomes a no-op at runtime.

The generator also emits forward prototypes for the four static Screen Flow helpers, which addresses the secondary request in the issue. Note that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule 8.4 applies to objects and functions with external linkage, so the static helpers without a visible prototype were not a deviation. The prototypes are still worth having, and they match the declaration the generator already emits for gx_studio_nested_widget_create().

Generated files

All 30 checked-in generated *_specifications.c files were re-synced with the generator, including the three golden files of the Studio view test.

Verified with test_demo/test_main.py -t across all 227 Studio projects: 227 passed, 0 failed, so the updated files match generator output exactly.

Regression test

test/guix_studio_test/test_demo/test_animation_pool_size.py, registered in the demo_compile CTest project so the existing GUIX Studio Demo Compile Test workflow runs it:

  1. Source check — the two helper definitions and the case label must sit inside the guard. Rejects "prototypes only guarded", "definitions unguarded", "case unguarded" and the pre-fix shape.
  2. Compile check — compiles every Screen Flow specification file with GX_ANIMATION_POOL_SIZE 0 and /we4013, so the implicit declaration is an error rather than a warning.

Results on this branch: 27 source-checked, 25 compiled, all passing in about 7 seconds under ctest. Against the pre-fix tree the same test fails 27/28 source checks and 24/26 compiles.

all_widgets_5_4_0 and all_widgets_5_4_1 are excluded from the compile stage because their generated code targets a pre-5.4.2 widget API; the existing demo compile test skips them for the same reason. They are still covered by the source check.

Documentation

Matching documentation update: eclipse-threadx/rtos-docs-asciidoc#42

🤖 Generated with Claude Code


Hotfix release preparation

This PR also carries the version bump for the emergency hotfix release that ships the fix, 6.5.1.202602a.

Release tooling

The tooling could not express a hotfix version at all, so it was fixed first:

  • Get-StudioReleaseVersion rejected anything that was not major.minor.patch.build, and update_studio_release_version.ps1 hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build a hotfix installer was unusable, and running the script after a manual edit would have reset the hotfix constant.
  • prepare_release.sh searched only ports/ for gx_port.h, so it never updated the version string of the GUIX Studio Win32 port in guix_studio/ports/gx_port.h.

Get-StudioReleaseVersion now accepts an optional trailing hotfix letter and exposes it as Hotfix / HotfixDefine. The Win32 and MSIX version formats are strictly numeric and cannot carry the letter, so the revision is offset by the position of the letter in the alphabet instead:

InputFullVersionWin32MSIXRC numericHotfix
6.5.1.2026026.5.1.2026026.5.1.26.5.1.026,5,1,2' '
6.5.1.202602a6.5.1.202602a6.5.1.36.5.1.036,5,1,3'a'
6.5.1.202602b6.5.1.202602b6.5.1.46.5.1.046,5,1,4'b'

That keeps the hotfix installer recognizable as the newer build for Windows upgrade detection and for the Store. Versions without a hotfix letter resolve exactly as before, and 6.5.1, 6.5.1.202602A, 6.5.1.202602ab and 6.5.1.202602-a are all still rejected.

Version constants

Produced by scripts/update_studio_release_version.ps1 -Version 6.5.1.202602a, plus the port strings:

  • common/inc/gx_api.hGUIX_HOTFIX_VERSION 'a'. Major, minor, patch, build and the 6.5.1 banner are unchanged.
  • guix_studio/studiox.rcFileVersion / ProductVersion strings 6.5.1.202602a; FILEVERSION / PRODUCTVERSION6,5,1,3.
  • guix_studio/installer/guix_installer_release.issStudioFullVersion "6.5.1.202602a", StudioVersionInfoVersion "6.5.1.3", so the installer is named guix_studio_setup_version_6.5.1.202602a.exe.
  • guix_studio/build/vs_2022/msix_package_project/Package.appxmanifest — MSIX identity 6.5.1.03.
  • All 47 gx_port.h files, including guix_studio/ports/gx_port.h.

STUDIOX_VERSION_NUMBER deliberately stays at 202602: it stamps the Studio version into .gxp project files, and a hotfix does not change the project file format.

Verified against a rebuilt guix_studio.exe, which reports FileVersion 6.5.1.202602a with a numeric file version of 6.5.1.3 — what verify_studio_installer.ps1 checks.

README.md still points at the current 6.5.1.202602 download, since the v6.5.1.202602a_rel tag and its asset do not exist yet. It should be updated when the release is published.

Re-verified after the bump

  • test_animation_pool_size.py: 27 source-checked, 25 compiled, 0 failures.
  • test_main.py -t: 227 projects, 227 passed, 0 failed.

GUIX Studio emitted five static helper functions in the generated
specification file as soon as a project used Screen Flow. Two of them,
gx_studio_action_parent_find() and gx_studio_animation_execute(), are
reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference
the GUIX animation API, which is compiled out when the animation pool
is empty:
- gx_system_animation_get() is only defined under
"#if (GX_ANIMATION_POOL_SIZE > 0)" in gx_api.h.
- The body of _gx_animation_start() is guarded the same way in
gx_animation_start.c, so the reference does not resolve at link
time either.
A project that defined GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save
resources therefore failed to build even when it used no animation
action at all. GCC 14 rejects the implicit declaration outright, and
MSVC fails on the unresolved external.
The screen generator now wraps both helpers and the two
GX_ACTION_TYPE_ANIMATION dispatch sites in
"#if (GX_ANIMATION_POOL_SIZE > 0)". Every other action type keeps
working with an empty pool, and an animation action simply becomes a
no-op at runtime.
The generator also emits forward prototypes for the four static screen
flow helpers, which addresses the secondary request in the issue. Note
that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule
8.4 applies to objects and functions with external linkage, so static
helpers without a visible prototype were not a deviation. The
prototypes are still worth having and match the declaration the
generator already emits for gx_studio_nested_widget_create().
All the checked-in generated specification files were regenerated so
that they stay in sync with the generator, including the golden files
of the Studio view test.
Added test/guix_studio_test/test_demo/test_animation_pool_size.py as a
regression test, registered in the demo compile CTest project. It
verifies that every checked-in Screen Flow specification file guards
the animation helpers, then compiles them all with
GX_ANIMATION_POOL_SIZE set to 0, promoting the MSVC implicit
declaration warning to an error so the failure mode above is caught.
Fixeseclipse-threadx#172
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fdesbiensand others added 3 commits August 25, 2026 11:10
The release tooling could not express a hotfix version. Two gaps:
- Get-StudioReleaseVersion rejected anything that was not
major.minor.patch.build, and update_studio_release_version.ps1
hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build
a hotfix installer was therefore unusable, and running the script
after a manual edit would have reset the hotfix constant.
- prepare_release.sh looked for gx_port.h under ports only, so it
never updated the version string of the GUIX Studio Win32 port in
guix_studio/ports/gx_port.h.
Get-StudioReleaseVersion now accepts an optional trailing hotfix letter
and exposes it as Hotfix and HotfixDefine. The Win32 and MSIX version
formats are strictly numeric and cannot carry the letter, so the
revision is offset by the position of the letter in the alphabet
instead: 6.5.1.202602 keeps revision 2, and 6.5.1.202602a becomes
revision 3. That keeps the hotfix installer recognizable as the newer
build for Windows upgrade detection and for the Store. Versions without
a hotfix letter resolve exactly as before.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Prepares the emergency hotfix release that carries the Screen Flow fix
for GX_ANIMATION_POOL_SIZE = 0.
Produced by scripts/update_studio_release_version.ps1 -Version
6.5.1.202602a:
- gx_api.h: GUIX_HOTFIX_VERSION is now 'a'. The major, minor, patch
and build constants are unchanged, as is the 6.5.1 banner.
- studiox.rc: FileVersion and ProductVersion strings are
6.5.1.202602a, FILEVERSION and PRODUCTVERSION are 6,5,1,3.
- guix_installer_release.iss: StudioFullVersion is 6.5.1.202602a and
StudioVersionInfoVersion is 6.5.1.3, so the installer is named
guix_studio_setup_version_6.5.1.202602a.exe.
- Package.appxmanifest: the MSIX identity version is 6.5.1.03.
STUDIOX_VERSION_NUMBER stays at 202602. It stamps the Studio version
into .gxp project files, and a hotfix does not change the project file
format.
Verified against a rebuilt guix_studio.exe, which reports FileVersion
6.5.1.202602a with a numeric file version of 6.5.1.3, matching what
verify_studio_installer.ps1 expects.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Updated the _gx_version_id string in all 47 gx_port.h files for the
emergency hotfix release, using the same substitution that
prepare_release.sh performs.
This includes guix_studio/ports/gx_port.h, the GUIX Studio Win32 port,
which the release script previously missed because it only searched the
ports directory. That gap is fixed in the preceding commit, so a future
release picks the file up automatically.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit c179c19 into eclipse-threadx:devAug 25, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fix/issue-172-animation-pool-size-zero branch August 25, 2026 17:10
@fdesbiens

Copy link
Copy Markdown
ContributorAuthor

@parsley This PR should fix your issue. I need to prepare a new installer and release. This should be done tomorrow (Wednesday).

fdesbiens added a commit that referenced this pull request Aug 27, 2026
compare_file() locates the line where comparison should start, so that the
banner GUIX Studio writes into every generated file -- which carries a revision
string and a generation timestamp -- is skipped rather than compared. It looked
that line up correctly in the first file and then looked it up in the first file
again for the second:
for line in list_2:
if compare_start_string in line:
start_row_2 = list_1.index(line)
So the golden was sliced at the *generated* file's offset. While both files
happened to reach "#include" on the same line the mistake was invisible, which
is why it survived since the tests were added in #84.
The offsets diverged when 6ba13db added a ten-line MIT licence header to all
111 golden .c and .h files. GUIX Studio does not emit that header, so every
golden now reaches its first #include ten lines later than the file it is
compared against. The golden was therefore sliced ten lines early and compared
banner text against source.
That made every one of the 107 .c and .h comparisons in the suite fail -- all 29
reported test failures -- while the .csv, .xliff and .xml comparisons passed.
Those use skip_line instead of compare_start_string and never reach this code,
which is exactly the split the failure log shows.
The reported mismatch is the same in all 29: a generated "#include" line against
a golden banner comment. Confirmed arithmetically -- in every case the golden
line reported sits exactly ten lines before that golden's own first #include:
generic_16bpp_resources.c reported idx 13, #include at 23, delta 10
generic_16bpp_resources.h reported idx 16, #include at 26, delta 10
generic_16bpp_specifications.c reported idx 14, #include at 24, delta 10
generic_16bpp_specifications.h reported idx 16, #include at 26, delta 10
compare_output_file() is the only caller that passes compare_start_string, so
the change cannot affect the xliff, xml or plain-file comparisons.
Verified by running the suite locally against a Studio built from this tree.
Seven suites that fail in CI now pass with no mismatches at all, each gaining
exactly the tests it had been failing:
CI (broken) local (fixed)
Font 9 / 1 10 / 0
Multi-Themes 18 / 1 19 / 0
Project Import 10 / 2 12 / 0
Trigger Edit 6 / 1 7 / 0
Trigger Target Rename 1 / 1 2 / 0
Bidi Text 3 / 1 4 / 0
Widget Name 3 / 1 4 / 0
Project Import compares a generated specifications file, so this also shows that
the screen flow prototype block added by #173 does not disturb these goldens:
that block is only emitted for projects that use Screen Flow, and these do not.
No golden file is regenerated. The goldens still carry "GUIX Studio Revision
6.1.12.0" and a 2022 timestamp in their banners, and still name Azure RTOS
rather than Eclipse ThreadX, but the banner is what the comparison is supposed
to skip -- so none of that needs to be touched to make the suite correct.
This workflow had never actually executed before 2026-08-27. Every earlier run
was cancelled after queueing 24 hours for the retired windows-2019 image, or
sat awaiting approval on a fork pull request, including the run for the v6.5.1
release itself. #174 gave it a runner again; this is the first result it has
ever produced, and the defect it found is in the test harness rather than in
GUIX or in Studio.
Note that studio_view_test.yml triggers only on pull requests targeting master,
so this change is not exercised by its own pull request into dev. It is
validated by the release pull request that carries dev to master.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0 - #173

Merged
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero
Aug 25, 2026
Merged

Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0#173
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero

Conversation

@fdesbiens

@fdesbiensfdesbiens commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Fixes#172

Problem

GUIX Studio emits five static helper functions in the generated specification file as soon as a project uses Screen Flow. Two of them, gx_studio_action_parent_find() and gx_studio_animation_execute(), are reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference the GUIX animation API, which is compiled out when the animation pool is empty:

  • gx_system_animation_get() is only defined under #if (GX_ANIMATION_POOL_SIZE > 0) in gx_api.h.
  • The body of _gx_animation_start() is guarded the same way in gx_animation_start.c, so the reference does not resolve at link time either.

A project that defines GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save resources therefore fails to build, even when it uses no animation action at all.

Reproduced on system_screen_stack_specifications.c with GX_ANIMATION_POOL_SIZE 0:

error C4013: 'gx_system_animation_get' undefined; assuming extern returning int
UNDEF External | _gxe_animation_start <- LNK2019 at link time
UNDEF External | gx_system_animation_get

GCC 14, the default compiler for the project, rejects the implicit declaration outright rather than warning about it.

Fix

screen_generator.cpp now wraps both helpers and the two GX_ACTION_TYPE_ANIMATION dispatch sites (the <= 50402 and the current library version branches) in #if (GX_ANIMATION_POOL_SIZE > 0). Every other action type keeps working with an empty pool, and an animation action simply becomes a no-op at runtime.

The generator also emits forward prototypes for the four static Screen Flow helpers, which addresses the secondary request in the issue. Note that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule 8.4 applies to objects and functions with external linkage, so the static helpers without a visible prototype were not a deviation. The prototypes are still worth having, and they match the declaration the generator already emits for gx_studio_nested_widget_create().

Generated files

All 30 checked-in generated *_specifications.c files were re-synced with the generator, including the three golden files of the Studio view test.

Verified with test_demo/test_main.py -t across all 227 Studio projects: 227 passed, 0 failed, so the updated files match generator output exactly.

Regression test

test/guix_studio_test/test_demo/test_animation_pool_size.py, registered in the demo_compile CTest project so the existing GUIX Studio Demo Compile Test workflow runs it:

  1. Source check — the two helper definitions and the case label must sit inside the guard. Rejects "prototypes only guarded", "definitions unguarded", "case unguarded" and the pre-fix shape.
  2. Compile check — compiles every Screen Flow specification file with GX_ANIMATION_POOL_SIZE 0 and /we4013, so the implicit declaration is an error rather than a warning.

Results on this branch: 27 source-checked, 25 compiled, all passing in about 7 seconds under ctest. Against the pre-fix tree the same test fails 27/28 source checks and 24/26 compiles.

all_widgets_5_4_0 and all_widgets_5_4_1 are excluded from the compile stage because their generated code targets a pre-5.4.2 widget API; the existing demo compile test skips them for the same reason. They are still covered by the source check.

Documentation

Matching documentation update: eclipse-threadx/rtos-docs-asciidoc#42

🤖 Generated with Claude Code


Hotfix release preparation

This PR also carries the version bump for the emergency hotfix release that ships the fix, 6.5.1.202602a.

Release tooling

The tooling could not express a hotfix version at all, so it was fixed first:

  • Get-StudioReleaseVersion rejected anything that was not major.minor.patch.build, and update_studio_release_version.ps1 hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build a hotfix installer was unusable, and running the script after a manual edit would have reset the hotfix constant.
  • prepare_release.sh searched only ports/ for gx_port.h, so it never updated the version string of the GUIX Studio Win32 port in guix_studio/ports/gx_port.h.

Get-StudioReleaseVersion now accepts an optional trailing hotfix letter and exposes it as Hotfix / HotfixDefine. The Win32 and MSIX version formats are strictly numeric and cannot carry the letter, so the revision is offset by the position of the letter in the alphabet instead:

InputFullVersionWin32MSIXRC numericHotfix
6.5.1.2026026.5.1.2026026.5.1.26.5.1.026,5,1,2' '
6.5.1.202602a6.5.1.202602a6.5.1.36.5.1.036,5,1,3'a'
6.5.1.202602b6.5.1.202602b6.5.1.46.5.1.046,5,1,4'b'

That keeps the hotfix installer recognizable as the newer build for Windows upgrade detection and for the Store. Versions without a hotfix letter resolve exactly as before, and 6.5.1, 6.5.1.202602A, 6.5.1.202602ab and 6.5.1.202602-a are all still rejected.

Version constants

Produced by scripts/update_studio_release_version.ps1 -Version 6.5.1.202602a, plus the port strings:

  • common/inc/gx_api.hGUIX_HOTFIX_VERSION 'a'. Major, minor, patch, build and the 6.5.1 banner are unchanged.
  • guix_studio/studiox.rcFileVersion / ProductVersion strings 6.5.1.202602a; FILEVERSION / PRODUCTVERSION6,5,1,3.
  • guix_studio/installer/guix_installer_release.issStudioFullVersion "6.5.1.202602a", StudioVersionInfoVersion "6.5.1.3", so the installer is named guix_studio_setup_version_6.5.1.202602a.exe.
  • guix_studio/build/vs_2022/msix_package_project/Package.appxmanifest — MSIX identity 6.5.1.03.
  • All 47 gx_port.h files, including guix_studio/ports/gx_port.h.

STUDIOX_VERSION_NUMBER deliberately stays at 202602: it stamps the Studio version into .gxp project files, and a hotfix does not change the project file format.

Verified against a rebuilt guix_studio.exe, which reports FileVersion 6.5.1.202602a with a numeric file version of 6.5.1.3 — what verify_studio_installer.ps1 checks.

README.md still points at the current 6.5.1.202602 download, since the v6.5.1.202602a_rel tag and its asset do not exist yet. It should be updated when the release is published.

Re-verified after the bump

  • test_animation_pool_size.py: 27 source-checked, 25 compiled, 0 failures.
  • test_main.py -t: 227 projects, 227 passed, 0 failed.

GUIX Studio emitted five static helper functions in the generated
specification file as soon as a project used Screen Flow. Two of them,
gx_studio_action_parent_find() and gx_studio_animation_execute(), are
reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference
the GUIX animation API, which is compiled out when the animation pool
is empty:
- gx_system_animation_get() is only defined under
"#if (GX_ANIMATION_POOL_SIZE > 0)" in gx_api.h.
- The body of _gx_animation_start() is guarded the same way in
gx_animation_start.c, so the reference does not resolve at link
time either.
A project that defined GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save
resources therefore failed to build even when it used no animation
action at all. GCC 14 rejects the implicit declaration outright, and
MSVC fails on the unresolved external.
The screen generator now wraps both helpers and the two
GX_ACTION_TYPE_ANIMATION dispatch sites in
"#if (GX_ANIMATION_POOL_SIZE > 0)". Every other action type keeps
working with an empty pool, and an animation action simply becomes a
no-op at runtime.
The generator also emits forward prototypes for the four static screen
flow helpers, which addresses the secondary request in the issue. Note
that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule
8.4 applies to objects and functions with external linkage, so static
helpers without a visible prototype were not a deviation. The
prototypes are still worth having and match the declaration the
generator already emits for gx_studio_nested_widget_create().
All the checked-in generated specification files were regenerated so
that they stay in sync with the generator, including the golden files
of the Studio view test.
Added test/guix_studio_test/test_demo/test_animation_pool_size.py as a
regression test, registered in the demo compile CTest project. It
verifies that every checked-in Screen Flow specification file guards
the animation helpers, then compiles them all with
GX_ANIMATION_POOL_SIZE set to 0, promoting the MSVC implicit
declaration warning to an error so the failure mode above is caught.
Fixeseclipse-threadx#172
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fdesbiensand others added 3 commits August 25, 2026 11:10
The release tooling could not express a hotfix version. Two gaps:
- Get-StudioReleaseVersion rejected anything that was not
major.minor.patch.build, and update_studio_release_version.ps1
hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build
a hotfix installer was therefore unusable, and running the script
after a manual edit would have reset the hotfix constant.
- prepare_release.sh looked for gx_port.h under ports only, so it
never updated the version string of the GUIX Studio Win32 port in
guix_studio/ports/gx_port.h.
Get-StudioReleaseVersion now accepts an optional trailing hotfix letter
and exposes it as Hotfix and HotfixDefine. The Win32 and MSIX version
formats are strictly numeric and cannot carry the letter, so the
revision is offset by the position of the letter in the alphabet
instead: 6.5.1.202602 keeps revision 2, and 6.5.1.202602a becomes
revision 3. That keeps the hotfix installer recognizable as the newer
build for Windows upgrade detection and for the Store. Versions without
a hotfix letter resolve exactly as before.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Prepares the emergency hotfix release that carries the Screen Flow fix
for GX_ANIMATION_POOL_SIZE = 0.
Produced by scripts/update_studio_release_version.ps1 -Version
6.5.1.202602a:
- gx_api.h: GUIX_HOTFIX_VERSION is now 'a'. The major, minor, patch
and build constants are unchanged, as is the 6.5.1 banner.
- studiox.rc: FileVersion and ProductVersion strings are
6.5.1.202602a, FILEVERSION and PRODUCTVERSION are 6,5,1,3.
- guix_installer_release.iss: StudioFullVersion is 6.5.1.202602a and
StudioVersionInfoVersion is 6.5.1.3, so the installer is named
guix_studio_setup_version_6.5.1.202602a.exe.
- Package.appxmanifest: the MSIX identity version is 6.5.1.03.
STUDIOX_VERSION_NUMBER stays at 202602. It stamps the Studio version
into .gxp project files, and a hotfix does not change the project file
format.
Verified against a rebuilt guix_studio.exe, which reports FileVersion
6.5.1.202602a with a numeric file version of 6.5.1.3, matching what
verify_studio_installer.ps1 expects.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Updated the _gx_version_id string in all 47 gx_port.h files for the
emergency hotfix release, using the same substitution that
prepare_release.sh performs.
This includes guix_studio/ports/gx_port.h, the GUIX Studio Win32 port,
which the release script previously missed because it only searched the
ports directory. That gap is fixed in the preceding commit, so a future
release picks the file up automatically.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit c179c19 into eclipse-threadx:devAug 25, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fix/issue-172-animation-pool-size-zero branch August 25, 2026 17:10
@fdesbiens

Copy link
Copy Markdown
ContributorAuthor

@parsley This PR should fix your issue. I need to prepare a new installer and release. This should be done tomorrow (Wednesday).

fdesbiens added a commit that referenced this pull request Aug 27, 2026
compare_file() locates the line where comparison should start, so that the
banner GUIX Studio writes into every generated file -- which carries a revision
string and a generation timestamp -- is skipped rather than compared. It looked
that line up correctly in the first file and then looked it up in the first file
again for the second:
for line in list_2:
if compare_start_string in line:
start_row_2 = list_1.index(line)
So the golden was sliced at the *generated* file's offset. While both files
happened to reach "#include" on the same line the mistake was invisible, which
is why it survived since the tests were added in #84.
The offsets diverged when 6ba13db added a ten-line MIT licence header to all
111 golden .c and .h files. GUIX Studio does not emit that header, so every
golden now reaches its first #include ten lines later than the file it is
compared against. The golden was therefore sliced ten lines early and compared
banner text against source.
That made every one of the 107 .c and .h comparisons in the suite fail -- all 29
reported test failures -- while the .csv, .xliff and .xml comparisons passed.
Those use skip_line instead of compare_start_string and never reach this code,
which is exactly the split the failure log shows.
The reported mismatch is the same in all 29: a generated "#include" line against
a golden banner comment. Confirmed arithmetically -- in every case the golden
line reported sits exactly ten lines before that golden's own first #include:
generic_16bpp_resources.c reported idx 13, #include at 23, delta 10
generic_16bpp_resources.h reported idx 16, #include at 26, delta 10
generic_16bpp_specifications.c reported idx 14, #include at 24, delta 10
generic_16bpp_specifications.h reported idx 16, #include at 26, delta 10
compare_output_file() is the only caller that passes compare_start_string, so
the change cannot affect the xliff, xml or plain-file comparisons.
Verified by running the suite locally against a Studio built from this tree.
Seven suites that fail in CI now pass with no mismatches at all, each gaining
exactly the tests it had been failing:
CI (broken) local (fixed)
Font 9 / 1 10 / 0
Multi-Themes 18 / 1 19 / 0
Project Import 10 / 2 12 / 0
Trigger Edit 6 / 1 7 / 0
Trigger Target Rename 1 / 1 2 / 0
Bidi Text 3 / 1 4 / 0
Widget Name 3 / 1 4 / 0
Project Import compares a generated specifications file, so this also shows that
the screen flow prototype block added by #173 does not disturb these goldens:
that block is only emitted for projects that use Screen Flow, and these do not.
No golden file is regenerated. The goldens still carry "GUIX Studio Revision
6.1.12.0" and a 2022 timestamp in their banners, and still name Azure RTOS
rather than Eclipse ThreadX, but the banner is what the comparison is supposed
to skip -- so none of that needs to be touched to make the suite correct.
This workflow had never actually executed before 2026-08-27. Every earlier run
was cancelled after queueing 24 hours for the retired windows-2019 image, or
sat awaiting approval on a fork pull request, including the run for the v6.5.1
release itself. #174 gave it a runner again; this is the first result it has
ever produced, and the defect it found is in the test harness rather than in
GUIX or in Studio.
Note that studio_view_test.yml triggers only on pull requests targeting master,
so this change is not exercised by its own pull request into dev. It is
validated by the release pull request that carries dev to master.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0 - #173

Merged
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero
Aug 25, 2026
Merged

Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0#173
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero

Conversation

@fdesbiens

@fdesbiensfdesbiens commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Fixes#172

Problem

GUIX Studio emits five static helper functions in the generated specification file as soon as a project uses Screen Flow. Two of them, gx_studio_action_parent_find() and gx_studio_animation_execute(), are reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference the GUIX animation API, which is compiled out when the animation pool is empty:

  • gx_system_animation_get() is only defined under #if (GX_ANIMATION_POOL_SIZE > 0) in gx_api.h.
  • The body of _gx_animation_start() is guarded the same way in gx_animation_start.c, so the reference does not resolve at link time either.

A project that defines GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save resources therefore fails to build, even when it uses no animation action at all.

Reproduced on system_screen_stack_specifications.c with GX_ANIMATION_POOL_SIZE 0:

error C4013: 'gx_system_animation_get' undefined; assuming extern returning int
UNDEF External | _gxe_animation_start <- LNK2019 at link time
UNDEF External | gx_system_animation_get

GCC 14, the default compiler for the project, rejects the implicit declaration outright rather than warning about it.

Fix

screen_generator.cpp now wraps both helpers and the two GX_ACTION_TYPE_ANIMATION dispatch sites (the <= 50402 and the current library version branches) in #if (GX_ANIMATION_POOL_SIZE > 0). Every other action type keeps working with an empty pool, and an animation action simply becomes a no-op at runtime.

The generator also emits forward prototypes for the four static Screen Flow helpers, which addresses the secondary request in the issue. Note that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule 8.4 applies to objects and functions with external linkage, so the static helpers without a visible prototype were not a deviation. The prototypes are still worth having, and they match the declaration the generator already emits for gx_studio_nested_widget_create().

Generated files

All 30 checked-in generated *_specifications.c files were re-synced with the generator, including the three golden files of the Studio view test.

Verified with test_demo/test_main.py -t across all 227 Studio projects: 227 passed, 0 failed, so the updated files match generator output exactly.

Regression test

test/guix_studio_test/test_demo/test_animation_pool_size.py, registered in the demo_compile CTest project so the existing GUIX Studio Demo Compile Test workflow runs it:

  1. Source check — the two helper definitions and the case label must sit inside the guard. Rejects "prototypes only guarded", "definitions unguarded", "case unguarded" and the pre-fix shape.
  2. Compile check — compiles every Screen Flow specification file with GX_ANIMATION_POOL_SIZE 0 and /we4013, so the implicit declaration is an error rather than a warning.

Results on this branch: 27 source-checked, 25 compiled, all passing in about 7 seconds under ctest. Against the pre-fix tree the same test fails 27/28 source checks and 24/26 compiles.

all_widgets_5_4_0 and all_widgets_5_4_1 are excluded from the compile stage because their generated code targets a pre-5.4.2 widget API; the existing demo compile test skips them for the same reason. They are still covered by the source check.

Documentation

Matching documentation update: eclipse-threadx/rtos-docs-asciidoc#42

🤖 Generated with Claude Code


Hotfix release preparation

This PR also carries the version bump for the emergency hotfix release that ships the fix, 6.5.1.202602a.

Release tooling

The tooling could not express a hotfix version at all, so it was fixed first:

  • Get-StudioReleaseVersion rejected anything that was not major.minor.patch.build, and update_studio_release_version.ps1 hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build a hotfix installer was unusable, and running the script after a manual edit would have reset the hotfix constant.
  • prepare_release.sh searched only ports/ for gx_port.h, so it never updated the version string of the GUIX Studio Win32 port in guix_studio/ports/gx_port.h.

Get-StudioReleaseVersion now accepts an optional trailing hotfix letter and exposes it as Hotfix / HotfixDefine. The Win32 and MSIX version formats are strictly numeric and cannot carry the letter, so the revision is offset by the position of the letter in the alphabet instead:

InputFullVersionWin32MSIXRC numericHotfix
6.5.1.2026026.5.1.2026026.5.1.26.5.1.026,5,1,2' '
6.5.1.202602a6.5.1.202602a6.5.1.36.5.1.036,5,1,3'a'
6.5.1.202602b6.5.1.202602b6.5.1.46.5.1.046,5,1,4'b'

That keeps the hotfix installer recognizable as the newer build for Windows upgrade detection and for the Store. Versions without a hotfix letter resolve exactly as before, and 6.5.1, 6.5.1.202602A, 6.5.1.202602ab and 6.5.1.202602-a are all still rejected.

Version constants

Produced by scripts/update_studio_release_version.ps1 -Version 6.5.1.202602a, plus the port strings:

  • common/inc/gx_api.hGUIX_HOTFIX_VERSION 'a'. Major, minor, patch, build and the 6.5.1 banner are unchanged.
  • guix_studio/studiox.rcFileVersion / ProductVersion strings 6.5.1.202602a; FILEVERSION / PRODUCTVERSION6,5,1,3.
  • guix_studio/installer/guix_installer_release.issStudioFullVersion "6.5.1.202602a", StudioVersionInfoVersion "6.5.1.3", so the installer is named guix_studio_setup_version_6.5.1.202602a.exe.
  • guix_studio/build/vs_2022/msix_package_project/Package.appxmanifest — MSIX identity 6.5.1.03.
  • All 47 gx_port.h files, including guix_studio/ports/gx_port.h.

STUDIOX_VERSION_NUMBER deliberately stays at 202602: it stamps the Studio version into .gxp project files, and a hotfix does not change the project file format.

Verified against a rebuilt guix_studio.exe, which reports FileVersion 6.5.1.202602a with a numeric file version of 6.5.1.3 — what verify_studio_installer.ps1 checks.

README.md still points at the current 6.5.1.202602 download, since the v6.5.1.202602a_rel tag and its asset do not exist yet. It should be updated when the release is published.

Re-verified after the bump

  • test_animation_pool_size.py: 27 source-checked, 25 compiled, 0 failures.
  • test_main.py -t: 227 projects, 227 passed, 0 failed.

GUIX Studio emitted five static helper functions in the generated
specification file as soon as a project used Screen Flow. Two of them,
gx_studio_action_parent_find() and gx_studio_animation_execute(), are
reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference
the GUIX animation API, which is compiled out when the animation pool
is empty:
- gx_system_animation_get() is only defined under
"#if (GX_ANIMATION_POOL_SIZE > 0)" in gx_api.h.
- The body of _gx_animation_start() is guarded the same way in
gx_animation_start.c, so the reference does not resolve at link
time either.
A project that defined GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save
resources therefore failed to build even when it used no animation
action at all. GCC 14 rejects the implicit declaration outright, and
MSVC fails on the unresolved external.
The screen generator now wraps both helpers and the two
GX_ACTION_TYPE_ANIMATION dispatch sites in
"#if (GX_ANIMATION_POOL_SIZE > 0)". Every other action type keeps
working with an empty pool, and an animation action simply becomes a
no-op at runtime.
The generator also emits forward prototypes for the four static screen
flow helpers, which addresses the secondary request in the issue. Note
that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule
8.4 applies to objects and functions with external linkage, so static
helpers without a visible prototype were not a deviation. The
prototypes are still worth having and match the declaration the
generator already emits for gx_studio_nested_widget_create().
All the checked-in generated specification files were regenerated so
that they stay in sync with the generator, including the golden files
of the Studio view test.
Added test/guix_studio_test/test_demo/test_animation_pool_size.py as a
regression test, registered in the demo compile CTest project. It
verifies that every checked-in Screen Flow specification file guards
the animation helpers, then compiles them all with
GX_ANIMATION_POOL_SIZE set to 0, promoting the MSVC implicit
declaration warning to an error so the failure mode above is caught.
Fixeseclipse-threadx#172
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fdesbiensand others added 3 commits August 25, 2026 11:10
The release tooling could not express a hotfix version. Two gaps:
- Get-StudioReleaseVersion rejected anything that was not
major.minor.patch.build, and update_studio_release_version.ps1
hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build
a hotfix installer was therefore unusable, and running the script
after a manual edit would have reset the hotfix constant.
- prepare_release.sh looked for gx_port.h under ports only, so it
never updated the version string of the GUIX Studio Win32 port in
guix_studio/ports/gx_port.h.
Get-StudioReleaseVersion now accepts an optional trailing hotfix letter
and exposes it as Hotfix and HotfixDefine. The Win32 and MSIX version
formats are strictly numeric and cannot carry the letter, so the
revision is offset by the position of the letter in the alphabet
instead: 6.5.1.202602 keeps revision 2, and 6.5.1.202602a becomes
revision 3. That keeps the hotfix installer recognizable as the newer
build for Windows upgrade detection and for the Store. Versions without
a hotfix letter resolve exactly as before.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Prepares the emergency hotfix release that carries the Screen Flow fix
for GX_ANIMATION_POOL_SIZE = 0.
Produced by scripts/update_studio_release_version.ps1 -Version
6.5.1.202602a:
- gx_api.h: GUIX_HOTFIX_VERSION is now 'a'. The major, minor, patch
and build constants are unchanged, as is the 6.5.1 banner.
- studiox.rc: FileVersion and ProductVersion strings are
6.5.1.202602a, FILEVERSION and PRODUCTVERSION are 6,5,1,3.
- guix_installer_release.iss: StudioFullVersion is 6.5.1.202602a and
StudioVersionInfoVersion is 6.5.1.3, so the installer is named
guix_studio_setup_version_6.5.1.202602a.exe.
- Package.appxmanifest: the MSIX identity version is 6.5.1.03.
STUDIOX_VERSION_NUMBER stays at 202602. It stamps the Studio version
into .gxp project files, and a hotfix does not change the project file
format.
Verified against a rebuilt guix_studio.exe, which reports FileVersion
6.5.1.202602a with a numeric file version of 6.5.1.3, matching what
verify_studio_installer.ps1 expects.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Updated the _gx_version_id string in all 47 gx_port.h files for the
emergency hotfix release, using the same substitution that
prepare_release.sh performs.
This includes guix_studio/ports/gx_port.h, the GUIX Studio Win32 port,
which the release script previously missed because it only searched the
ports directory. That gap is fixed in the preceding commit, so a future
release picks the file up automatically.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit c179c19 into eclipse-threadx:devAug 25, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fix/issue-172-animation-pool-size-zero branch August 25, 2026 17:10
@fdesbiens

Copy link
Copy Markdown
ContributorAuthor

@parsley This PR should fix your issue. I need to prepare a new installer and release. This should be done tomorrow (Wednesday).

fdesbiens added a commit that referenced this pull request Aug 27, 2026
compare_file() locates the line where comparison should start, so that the
banner GUIX Studio writes into every generated file -- which carries a revision
string and a generation timestamp -- is skipped rather than compared. It looked
that line up correctly in the first file and then looked it up in the first file
again for the second:
for line in list_2:
if compare_start_string in line:
start_row_2 = list_1.index(line)
So the golden was sliced at the *generated* file's offset. While both files
happened to reach "#include" on the same line the mistake was invisible, which
is why it survived since the tests were added in #84.
The offsets diverged when 6ba13db added a ten-line MIT licence header to all
111 golden .c and .h files. GUIX Studio does not emit that header, so every
golden now reaches its first #include ten lines later than the file it is
compared against. The golden was therefore sliced ten lines early and compared
banner text against source.
That made every one of the 107 .c and .h comparisons in the suite fail -- all 29
reported test failures -- while the .csv, .xliff and .xml comparisons passed.
Those use skip_line instead of compare_start_string and never reach this code,
which is exactly the split the failure log shows.
The reported mismatch is the same in all 29: a generated "#include" line against
a golden banner comment. Confirmed arithmetically -- in every case the golden
line reported sits exactly ten lines before that golden's own first #include:
generic_16bpp_resources.c reported idx 13, #include at 23, delta 10
generic_16bpp_resources.h reported idx 16, #include at 26, delta 10
generic_16bpp_specifications.c reported idx 14, #include at 24, delta 10
generic_16bpp_specifications.h reported idx 16, #include at 26, delta 10
compare_output_file() is the only caller that passes compare_start_string, so
the change cannot affect the xliff, xml or plain-file comparisons.
Verified by running the suite locally against a Studio built from this tree.
Seven suites that fail in CI now pass with no mismatches at all, each gaining
exactly the tests it had been failing:
CI (broken) local (fixed)
Font 9 / 1 10 / 0
Multi-Themes 18 / 1 19 / 0
Project Import 10 / 2 12 / 0
Trigger Edit 6 / 1 7 / 0
Trigger Target Rename 1 / 1 2 / 0
Bidi Text 3 / 1 4 / 0
Widget Name 3 / 1 4 / 0
Project Import compares a generated specifications file, so this also shows that
the screen flow prototype block added by #173 does not disturb these goldens:
that block is only emitted for projects that use Screen Flow, and these do not.
No golden file is regenerated. The goldens still carry "GUIX Studio Revision
6.1.12.0" and a 2022 timestamp in their banners, and still name Azure RTOS
rather than Eclipse ThreadX, but the banner is what the comparison is supposed
to skip -- so none of that needs to be touched to make the suite correct.
This workflow had never actually executed before 2026-08-27. Every earlier run
was cancelled after queueing 24 hours for the retired windows-2019 image, or
sat awaiting approval on a fork pull request, including the run for the v6.5.1
release itself. #174 gave it a runner again; this is the first result it has
ever produced, and the defect it found is in the test harness rather than in
GUIX or in Studio.
Note that studio_view_test.yml triggers only on pull requests targeting master,
so this change is not exercised by its own pull request into dev. It is
validated by the release pull request that carries dev to master.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0 - #173

Merged
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero
Aug 25, 2026
Merged

Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0#173
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero

Conversation

@fdesbiens

@fdesbiensfdesbiens commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Fixes#172

Problem

GUIX Studio emits five static helper functions in the generated specification file as soon as a project uses Screen Flow. Two of them, gx_studio_action_parent_find() and gx_studio_animation_execute(), are reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference the GUIX animation API, which is compiled out when the animation pool is empty:

  • gx_system_animation_get() is only defined under #if (GX_ANIMATION_POOL_SIZE > 0) in gx_api.h.
  • The body of _gx_animation_start() is guarded the same way in gx_animation_start.c, so the reference does not resolve at link time either.

A project that defines GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save resources therefore fails to build, even when it uses no animation action at all.

Reproduced on system_screen_stack_specifications.c with GX_ANIMATION_POOL_SIZE 0:

error C4013: 'gx_system_animation_get' undefined; assuming extern returning int
UNDEF External | _gxe_animation_start <- LNK2019 at link time
UNDEF External | gx_system_animation_get

GCC 14, the default compiler for the project, rejects the implicit declaration outright rather than warning about it.

Fix

screen_generator.cpp now wraps both helpers and the two GX_ACTION_TYPE_ANIMATION dispatch sites (the <= 50402 and the current library version branches) in #if (GX_ANIMATION_POOL_SIZE > 0). Every other action type keeps working with an empty pool, and an animation action simply becomes a no-op at runtime.

The generator also emits forward prototypes for the four static Screen Flow helpers, which addresses the secondary request in the issue. Note that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule 8.4 applies to objects and functions with external linkage, so the static helpers without a visible prototype were not a deviation. The prototypes are still worth having, and they match the declaration the generator already emits for gx_studio_nested_widget_create().

Generated files

All 30 checked-in generated *_specifications.c files were re-synced with the generator, including the three golden files of the Studio view test.

Verified with test_demo/test_main.py -t across all 227 Studio projects: 227 passed, 0 failed, so the updated files match generator output exactly.

Regression test

test/guix_studio_test/test_demo/test_animation_pool_size.py, registered in the demo_compile CTest project so the existing GUIX Studio Demo Compile Test workflow runs it:

  1. Source check — the two helper definitions and the case label must sit inside the guard. Rejects "prototypes only guarded", "definitions unguarded", "case unguarded" and the pre-fix shape.
  2. Compile check — compiles every Screen Flow specification file with GX_ANIMATION_POOL_SIZE 0 and /we4013, so the implicit declaration is an error rather than a warning.

Results on this branch: 27 source-checked, 25 compiled, all passing in about 7 seconds under ctest. Against the pre-fix tree the same test fails 27/28 source checks and 24/26 compiles.

all_widgets_5_4_0 and all_widgets_5_4_1 are excluded from the compile stage because their generated code targets a pre-5.4.2 widget API; the existing demo compile test skips them for the same reason. They are still covered by the source check.

Documentation

Matching documentation update: eclipse-threadx/rtos-docs-asciidoc#42

🤖 Generated with Claude Code


Hotfix release preparation

This PR also carries the version bump for the emergency hotfix release that ships the fix, 6.5.1.202602a.

Release tooling

The tooling could not express a hotfix version at all, so it was fixed first:

  • Get-StudioReleaseVersion rejected anything that was not major.minor.patch.build, and update_studio_release_version.ps1 hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build a hotfix installer was unusable, and running the script after a manual edit would have reset the hotfix constant.
  • prepare_release.sh searched only ports/ for gx_port.h, so it never updated the version string of the GUIX Studio Win32 port in guix_studio/ports/gx_port.h.

Get-StudioReleaseVersion now accepts an optional trailing hotfix letter and exposes it as Hotfix / HotfixDefine. The Win32 and MSIX version formats are strictly numeric and cannot carry the letter, so the revision is offset by the position of the letter in the alphabet instead:

InputFullVersionWin32MSIXRC numericHotfix
6.5.1.2026026.5.1.2026026.5.1.26.5.1.026,5,1,2' '
6.5.1.202602a6.5.1.202602a6.5.1.36.5.1.036,5,1,3'a'
6.5.1.202602b6.5.1.202602b6.5.1.46.5.1.046,5,1,4'b'

That keeps the hotfix installer recognizable as the newer build for Windows upgrade detection and for the Store. Versions without a hotfix letter resolve exactly as before, and 6.5.1, 6.5.1.202602A, 6.5.1.202602ab and 6.5.1.202602-a are all still rejected.

Version constants

Produced by scripts/update_studio_release_version.ps1 -Version 6.5.1.202602a, plus the port strings:

  • common/inc/gx_api.hGUIX_HOTFIX_VERSION 'a'. Major, minor, patch, build and the 6.5.1 banner are unchanged.
  • guix_studio/studiox.rcFileVersion / ProductVersion strings 6.5.1.202602a; FILEVERSION / PRODUCTVERSION6,5,1,3.
  • guix_studio/installer/guix_installer_release.issStudioFullVersion "6.5.1.202602a", StudioVersionInfoVersion "6.5.1.3", so the installer is named guix_studio_setup_version_6.5.1.202602a.exe.
  • guix_studio/build/vs_2022/msix_package_project/Package.appxmanifest — MSIX identity 6.5.1.03.
  • All 47 gx_port.h files, including guix_studio/ports/gx_port.h.

STUDIOX_VERSION_NUMBER deliberately stays at 202602: it stamps the Studio version into .gxp project files, and a hotfix does not change the project file format.

Verified against a rebuilt guix_studio.exe, which reports FileVersion 6.5.1.202602a with a numeric file version of 6.5.1.3 — what verify_studio_installer.ps1 checks.

README.md still points at the current 6.5.1.202602 download, since the v6.5.1.202602a_rel tag and its asset do not exist yet. It should be updated when the release is published.

Re-verified after the bump

  • test_animation_pool_size.py: 27 source-checked, 25 compiled, 0 failures.
  • test_main.py -t: 227 projects, 227 passed, 0 failed.

GUIX Studio emitted five static helper functions in the generated
specification file as soon as a project used Screen Flow. Two of them,
gx_studio_action_parent_find() and gx_studio_animation_execute(), are
reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference
the GUIX animation API, which is compiled out when the animation pool
is empty:
- gx_system_animation_get() is only defined under
"#if (GX_ANIMATION_POOL_SIZE > 0)" in gx_api.h.
- The body of _gx_animation_start() is guarded the same way in
gx_animation_start.c, so the reference does not resolve at link
time either.
A project that defined GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save
resources therefore failed to build even when it used no animation
action at all. GCC 14 rejects the implicit declaration outright, and
MSVC fails on the unresolved external.
The screen generator now wraps both helpers and the two
GX_ACTION_TYPE_ANIMATION dispatch sites in
"#if (GX_ANIMATION_POOL_SIZE > 0)". Every other action type keeps
working with an empty pool, and an animation action simply becomes a
no-op at runtime.
The generator also emits forward prototypes for the four static screen
flow helpers, which addresses the secondary request in the issue. Note
that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule
8.4 applies to objects and functions with external linkage, so static
helpers without a visible prototype were not a deviation. The
prototypes are still worth having and match the declaration the
generator already emits for gx_studio_nested_widget_create().
All the checked-in generated specification files were regenerated so
that they stay in sync with the generator, including the golden files
of the Studio view test.
Added test/guix_studio_test/test_demo/test_animation_pool_size.py as a
regression test, registered in the demo compile CTest project. It
verifies that every checked-in Screen Flow specification file guards
the animation helpers, then compiles them all with
GX_ANIMATION_POOL_SIZE set to 0, promoting the MSVC implicit
declaration warning to an error so the failure mode above is caught.
Fixeseclipse-threadx#172
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fdesbiensand others added 3 commits August 25, 2026 11:10
The release tooling could not express a hotfix version. Two gaps:
- Get-StudioReleaseVersion rejected anything that was not
major.minor.patch.build, and update_studio_release_version.ps1
hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build
a hotfix installer was therefore unusable, and running the script
after a manual edit would have reset the hotfix constant.
- prepare_release.sh looked for gx_port.h under ports only, so it
never updated the version string of the GUIX Studio Win32 port in
guix_studio/ports/gx_port.h.
Get-StudioReleaseVersion now accepts an optional trailing hotfix letter
and exposes it as Hotfix and HotfixDefine. The Win32 and MSIX version
formats are strictly numeric and cannot carry the letter, so the
revision is offset by the position of the letter in the alphabet
instead: 6.5.1.202602 keeps revision 2, and 6.5.1.202602a becomes
revision 3. That keeps the hotfix installer recognizable as the newer
build for Windows upgrade detection and for the Store. Versions without
a hotfix letter resolve exactly as before.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Prepares the emergency hotfix release that carries the Screen Flow fix
for GX_ANIMATION_POOL_SIZE = 0.
Produced by scripts/update_studio_release_version.ps1 -Version
6.5.1.202602a:
- gx_api.h: GUIX_HOTFIX_VERSION is now 'a'. The major, minor, patch
and build constants are unchanged, as is the 6.5.1 banner.
- studiox.rc: FileVersion and ProductVersion strings are
6.5.1.202602a, FILEVERSION and PRODUCTVERSION are 6,5,1,3.
- guix_installer_release.iss: StudioFullVersion is 6.5.1.202602a and
StudioVersionInfoVersion is 6.5.1.3, so the installer is named
guix_studio_setup_version_6.5.1.202602a.exe.
- Package.appxmanifest: the MSIX identity version is 6.5.1.03.
STUDIOX_VERSION_NUMBER stays at 202602. It stamps the Studio version
into .gxp project files, and a hotfix does not change the project file
format.
Verified against a rebuilt guix_studio.exe, which reports FileVersion
6.5.1.202602a with a numeric file version of 6.5.1.3, matching what
verify_studio_installer.ps1 expects.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Updated the _gx_version_id string in all 47 gx_port.h files for the
emergency hotfix release, using the same substitution that
prepare_release.sh performs.
This includes guix_studio/ports/gx_port.h, the GUIX Studio Win32 port,
which the release script previously missed because it only searched the
ports directory. That gap is fixed in the preceding commit, so a future
release picks the file up automatically.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit c179c19 into eclipse-threadx:devAug 25, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fix/issue-172-animation-pool-size-zero branch August 25, 2026 17:10
@fdesbiens

Copy link
Copy Markdown
ContributorAuthor

@parsley This PR should fix your issue. I need to prepare a new installer and release. This should be done tomorrow (Wednesday).

fdesbiens added a commit that referenced this pull request Aug 27, 2026
compare_file() locates the line where comparison should start, so that the
banner GUIX Studio writes into every generated file -- which carries a revision
string and a generation timestamp -- is skipped rather than compared. It looked
that line up correctly in the first file and then looked it up in the first file
again for the second:
for line in list_2:
if compare_start_string in line:
start_row_2 = list_1.index(line)
So the golden was sliced at the *generated* file's offset. While both files
happened to reach "#include" on the same line the mistake was invisible, which
is why it survived since the tests were added in #84.
The offsets diverged when 6ba13db added a ten-line MIT licence header to all
111 golden .c and .h files. GUIX Studio does not emit that header, so every
golden now reaches its first #include ten lines later than the file it is
compared against. The golden was therefore sliced ten lines early and compared
banner text against source.
That made every one of the 107 .c and .h comparisons in the suite fail -- all 29
reported test failures -- while the .csv, .xliff and .xml comparisons passed.
Those use skip_line instead of compare_start_string and never reach this code,
which is exactly the split the failure log shows.
The reported mismatch is the same in all 29: a generated "#include" line against
a golden banner comment. Confirmed arithmetically -- in every case the golden
line reported sits exactly ten lines before that golden's own first #include:
generic_16bpp_resources.c reported idx 13, #include at 23, delta 10
generic_16bpp_resources.h reported idx 16, #include at 26, delta 10
generic_16bpp_specifications.c reported idx 14, #include at 24, delta 10
generic_16bpp_specifications.h reported idx 16, #include at 26, delta 10
compare_output_file() is the only caller that passes compare_start_string, so
the change cannot affect the xliff, xml or plain-file comparisons.
Verified by running the suite locally against a Studio built from this tree.
Seven suites that fail in CI now pass with no mismatches at all, each gaining
exactly the tests it had been failing:
CI (broken) local (fixed)
Font 9 / 1 10 / 0
Multi-Themes 18 / 1 19 / 0
Project Import 10 / 2 12 / 0
Trigger Edit 6 / 1 7 / 0
Trigger Target Rename 1 / 1 2 / 0
Bidi Text 3 / 1 4 / 0
Widget Name 3 / 1 4 / 0
Project Import compares a generated specifications file, so this also shows that
the screen flow prototype block added by #173 does not disturb these goldens:
that block is only emitted for projects that use Screen Flow, and these do not.
No golden file is regenerated. The goldens still carry "GUIX Studio Revision
6.1.12.0" and a 2022 timestamp in their banners, and still name Azure RTOS
rather than Eclipse ThreadX, but the banner is what the comparison is supposed
to skip -- so none of that needs to be touched to make the suite correct.
This workflow had never actually executed before 2026-08-27. Every earlier run
was cancelled after queueing 24 hours for the retired windows-2019 image, or
sat awaiting approval on a fork pull request, including the run for the v6.5.1
release itself. #174 gave it a runner again; this is the first result it has
ever produced, and the defect it found is in the test harness rather than in
GUIX or in Studio.
Note that studio_view_test.yml triggers only on pull requests targeting master,
so this change is not exercised by its own pull request into dev. It is
validated by the release pull request that carries dev to master.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0 - #173

Merged
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero
Aug 25, 2026
Merged

Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0#173
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero

Conversation

@fdesbiens

@fdesbiensfdesbiens commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Fixes#172

Problem

GUIX Studio emits five static helper functions in the generated specification file as soon as a project uses Screen Flow. Two of them, gx_studio_action_parent_find() and gx_studio_animation_execute(), are reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference the GUIX animation API, which is compiled out when the animation pool is empty:

  • gx_system_animation_get() is only defined under #if (GX_ANIMATION_POOL_SIZE > 0) in gx_api.h.
  • The body of _gx_animation_start() is guarded the same way in gx_animation_start.c, so the reference does not resolve at link time either.

A project that defines GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save resources therefore fails to build, even when it uses no animation action at all.

Reproduced on system_screen_stack_specifications.c with GX_ANIMATION_POOL_SIZE 0:

error C4013: 'gx_system_animation_get' undefined; assuming extern returning int
UNDEF External | _gxe_animation_start <- LNK2019 at link time
UNDEF External | gx_system_animation_get

GCC 14, the default compiler for the project, rejects the implicit declaration outright rather than warning about it.

Fix

screen_generator.cpp now wraps both helpers and the two GX_ACTION_TYPE_ANIMATION dispatch sites (the <= 50402 and the current library version branches) in #if (GX_ANIMATION_POOL_SIZE > 0). Every other action type keeps working with an empty pool, and an animation action simply becomes a no-op at runtime.

The generator also emits forward prototypes for the four static Screen Flow helpers, which addresses the secondary request in the issue. Note that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule 8.4 applies to objects and functions with external linkage, so the static helpers without a visible prototype were not a deviation. The prototypes are still worth having, and they match the declaration the generator already emits for gx_studio_nested_widget_create().

Generated files

All 30 checked-in generated *_specifications.c files were re-synced with the generator, including the three golden files of the Studio view test.

Verified with test_demo/test_main.py -t across all 227 Studio projects: 227 passed, 0 failed, so the updated files match generator output exactly.

Regression test

test/guix_studio_test/test_demo/test_animation_pool_size.py, registered in the demo_compile CTest project so the existing GUIX Studio Demo Compile Test workflow runs it:

  1. Source check — the two helper definitions and the case label must sit inside the guard. Rejects "prototypes only guarded", "definitions unguarded", "case unguarded" and the pre-fix shape.
  2. Compile check — compiles every Screen Flow specification file with GX_ANIMATION_POOL_SIZE 0 and /we4013, so the implicit declaration is an error rather than a warning.

Results on this branch: 27 source-checked, 25 compiled, all passing in about 7 seconds under ctest. Against the pre-fix tree the same test fails 27/28 source checks and 24/26 compiles.

all_widgets_5_4_0 and all_widgets_5_4_1 are excluded from the compile stage because their generated code targets a pre-5.4.2 widget API; the existing demo compile test skips them for the same reason. They are still covered by the source check.

Documentation

Matching documentation update: eclipse-threadx/rtos-docs-asciidoc#42

🤖 Generated with Claude Code


Hotfix release preparation

This PR also carries the version bump for the emergency hotfix release that ships the fix, 6.5.1.202602a.

Release tooling

The tooling could not express a hotfix version at all, so it was fixed first:

  • Get-StudioReleaseVersion rejected anything that was not major.minor.patch.build, and update_studio_release_version.ps1 hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build a hotfix installer was unusable, and running the script after a manual edit would have reset the hotfix constant.
  • prepare_release.sh searched only ports/ for gx_port.h, so it never updated the version string of the GUIX Studio Win32 port in guix_studio/ports/gx_port.h.

Get-StudioReleaseVersion now accepts an optional trailing hotfix letter and exposes it as Hotfix / HotfixDefine. The Win32 and MSIX version formats are strictly numeric and cannot carry the letter, so the revision is offset by the position of the letter in the alphabet instead:

InputFullVersionWin32MSIXRC numericHotfix
6.5.1.2026026.5.1.2026026.5.1.26.5.1.026,5,1,2' '
6.5.1.202602a6.5.1.202602a6.5.1.36.5.1.036,5,1,3'a'
6.5.1.202602b6.5.1.202602b6.5.1.46.5.1.046,5,1,4'b'

That keeps the hotfix installer recognizable as the newer build for Windows upgrade detection and for the Store. Versions without a hotfix letter resolve exactly as before, and 6.5.1, 6.5.1.202602A, 6.5.1.202602ab and 6.5.1.202602-a are all still rejected.

Version constants

Produced by scripts/update_studio_release_version.ps1 -Version 6.5.1.202602a, plus the port strings:

  • common/inc/gx_api.hGUIX_HOTFIX_VERSION 'a'. Major, minor, patch, build and the 6.5.1 banner are unchanged.
  • guix_studio/studiox.rcFileVersion / ProductVersion strings 6.5.1.202602a; FILEVERSION / PRODUCTVERSION6,5,1,3.
  • guix_studio/installer/guix_installer_release.issStudioFullVersion "6.5.1.202602a", StudioVersionInfoVersion "6.5.1.3", so the installer is named guix_studio_setup_version_6.5.1.202602a.exe.
  • guix_studio/build/vs_2022/msix_package_project/Package.appxmanifest — MSIX identity 6.5.1.03.
  • All 47 gx_port.h files, including guix_studio/ports/gx_port.h.

STUDIOX_VERSION_NUMBER deliberately stays at 202602: it stamps the Studio version into .gxp project files, and a hotfix does not change the project file format.

Verified against a rebuilt guix_studio.exe, which reports FileVersion 6.5.1.202602a with a numeric file version of 6.5.1.3 — what verify_studio_installer.ps1 checks.

README.md still points at the current 6.5.1.202602 download, since the v6.5.1.202602a_rel tag and its asset do not exist yet. It should be updated when the release is published.

Re-verified after the bump

  • test_animation_pool_size.py: 27 source-checked, 25 compiled, 0 failures.
  • test_main.py -t: 227 projects, 227 passed, 0 failed.

GUIX Studio emitted five static helper functions in the generated
specification file as soon as a project used Screen Flow. Two of them,
gx_studio_action_parent_find() and gx_studio_animation_execute(), are
reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference
the GUIX animation API, which is compiled out when the animation pool
is empty:
- gx_system_animation_get() is only defined under
"#if (GX_ANIMATION_POOL_SIZE > 0)" in gx_api.h.
- The body of _gx_animation_start() is guarded the same way in
gx_animation_start.c, so the reference does not resolve at link
time either.
A project that defined GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save
resources therefore failed to build even when it used no animation
action at all. GCC 14 rejects the implicit declaration outright, and
MSVC fails on the unresolved external.
The screen generator now wraps both helpers and the two
GX_ACTION_TYPE_ANIMATION dispatch sites in
"#if (GX_ANIMATION_POOL_SIZE > 0)". Every other action type keeps
working with an empty pool, and an animation action simply becomes a
no-op at runtime.
The generator also emits forward prototypes for the four static screen
flow helpers, which addresses the secondary request in the issue. Note
that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule
8.4 applies to objects and functions with external linkage, so static
helpers without a visible prototype were not a deviation. The
prototypes are still worth having and match the declaration the
generator already emits for gx_studio_nested_widget_create().
All the checked-in generated specification files were regenerated so
that they stay in sync with the generator, including the golden files
of the Studio view test.
Added test/guix_studio_test/test_demo/test_animation_pool_size.py as a
regression test, registered in the demo compile CTest project. It
verifies that every checked-in Screen Flow specification file guards
the animation helpers, then compiles them all with
GX_ANIMATION_POOL_SIZE set to 0, promoting the MSVC implicit
declaration warning to an error so the failure mode above is caught.
Fixeseclipse-threadx#172
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fdesbiensand others added 3 commits August 25, 2026 11:10
The release tooling could not express a hotfix version. Two gaps:
- Get-StudioReleaseVersion rejected anything that was not
major.minor.patch.build, and update_studio_release_version.ps1
hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build
a hotfix installer was therefore unusable, and running the script
after a manual edit would have reset the hotfix constant.
- prepare_release.sh looked for gx_port.h under ports only, so it
never updated the version string of the GUIX Studio Win32 port in
guix_studio/ports/gx_port.h.
Get-StudioReleaseVersion now accepts an optional trailing hotfix letter
and exposes it as Hotfix and HotfixDefine. The Win32 and MSIX version
formats are strictly numeric and cannot carry the letter, so the
revision is offset by the position of the letter in the alphabet
instead: 6.5.1.202602 keeps revision 2, and 6.5.1.202602a becomes
revision 3. That keeps the hotfix installer recognizable as the newer
build for Windows upgrade detection and for the Store. Versions without
a hotfix letter resolve exactly as before.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Prepares the emergency hotfix release that carries the Screen Flow fix
for GX_ANIMATION_POOL_SIZE = 0.
Produced by scripts/update_studio_release_version.ps1 -Version
6.5.1.202602a:
- gx_api.h: GUIX_HOTFIX_VERSION is now 'a'. The major, minor, patch
and build constants are unchanged, as is the 6.5.1 banner.
- studiox.rc: FileVersion and ProductVersion strings are
6.5.1.202602a, FILEVERSION and PRODUCTVERSION are 6,5,1,3.
- guix_installer_release.iss: StudioFullVersion is 6.5.1.202602a and
StudioVersionInfoVersion is 6.5.1.3, so the installer is named
guix_studio_setup_version_6.5.1.202602a.exe.
- Package.appxmanifest: the MSIX identity version is 6.5.1.03.
STUDIOX_VERSION_NUMBER stays at 202602. It stamps the Studio version
into .gxp project files, and a hotfix does not change the project file
format.
Verified against a rebuilt guix_studio.exe, which reports FileVersion
6.5.1.202602a with a numeric file version of 6.5.1.3, matching what
verify_studio_installer.ps1 expects.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Updated the _gx_version_id string in all 47 gx_port.h files for the
emergency hotfix release, using the same substitution that
prepare_release.sh performs.
This includes guix_studio/ports/gx_port.h, the GUIX Studio Win32 port,
which the release script previously missed because it only searched the
ports directory. That gap is fixed in the preceding commit, so a future
release picks the file up automatically.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit c179c19 into eclipse-threadx:devAug 25, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fix/issue-172-animation-pool-size-zero branch August 25, 2026 17:10
@fdesbiens

Copy link
Copy Markdown
ContributorAuthor

@parsley This PR should fix your issue. I need to prepare a new installer and release. This should be done tomorrow (Wednesday).

fdesbiens added a commit that referenced this pull request Aug 27, 2026
compare_file() locates the line where comparison should start, so that the
banner GUIX Studio writes into every generated file -- which carries a revision
string and a generation timestamp -- is skipped rather than compared. It looked
that line up correctly in the first file and then looked it up in the first file
again for the second:
for line in list_2:
if compare_start_string in line:
start_row_2 = list_1.index(line)
So the golden was sliced at the *generated* file's offset. While both files
happened to reach "#include" on the same line the mistake was invisible, which
is why it survived since the tests were added in #84.
The offsets diverged when 6ba13db added a ten-line MIT licence header to all
111 golden .c and .h files. GUIX Studio does not emit that header, so every
golden now reaches its first #include ten lines later than the file it is
compared against. The golden was therefore sliced ten lines early and compared
banner text against source.
That made every one of the 107 .c and .h comparisons in the suite fail -- all 29
reported test failures -- while the .csv, .xliff and .xml comparisons passed.
Those use skip_line instead of compare_start_string and never reach this code,
which is exactly the split the failure log shows.
The reported mismatch is the same in all 29: a generated "#include" line against
a golden banner comment. Confirmed arithmetically -- in every case the golden
line reported sits exactly ten lines before that golden's own first #include:
generic_16bpp_resources.c reported idx 13, #include at 23, delta 10
generic_16bpp_resources.h reported idx 16, #include at 26, delta 10
generic_16bpp_specifications.c reported idx 14, #include at 24, delta 10
generic_16bpp_specifications.h reported idx 16, #include at 26, delta 10
compare_output_file() is the only caller that passes compare_start_string, so
the change cannot affect the xliff, xml or plain-file comparisons.
Verified by running the suite locally against a Studio built from this tree.
Seven suites that fail in CI now pass with no mismatches at all, each gaining
exactly the tests it had been failing:
CI (broken) local (fixed)
Font 9 / 1 10 / 0
Multi-Themes 18 / 1 19 / 0
Project Import 10 / 2 12 / 0
Trigger Edit 6 / 1 7 / 0
Trigger Target Rename 1 / 1 2 / 0
Bidi Text 3 / 1 4 / 0
Widget Name 3 / 1 4 / 0
Project Import compares a generated specifications file, so this also shows that
the screen flow prototype block added by #173 does not disturb these goldens:
that block is only emitted for projects that use Screen Flow, and these do not.
No golden file is regenerated. The goldens still carry "GUIX Studio Revision
6.1.12.0" and a 2022 timestamp in their banners, and still name Azure RTOS
rather than Eclipse ThreadX, but the banner is what the comparison is supposed
to skip -- so none of that needs to be touched to make the suite correct.
This workflow had never actually executed before 2026-08-27. Every earlier run
was cancelled after queueing 24 hours for the retired windows-2019 image, or
sat awaiting approval on a fork pull request, including the run for the v6.5.1
release itself. #174 gave it a runner again; this is the first result it has
ever produced, and the defect it found is in the test harness rather than in
GUIX or in Studio.
Note that studio_view_test.yml triggers only on pull requests targeting master,
so this change is not exercised by its own pull request into dev. It is
validated by the release pull request that carries dev to master.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0 - #173

Merged
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero
Aug 25, 2026
Merged

Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0#173
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero

Conversation

@fdesbiens

@fdesbiensfdesbiens commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Fixes#172

Problem

GUIX Studio emits five static helper functions in the generated specification file as soon as a project uses Screen Flow. Two of them, gx_studio_action_parent_find() and gx_studio_animation_execute(), are reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference the GUIX animation API, which is compiled out when the animation pool is empty:

  • gx_system_animation_get() is only defined under #if (GX_ANIMATION_POOL_SIZE > 0) in gx_api.h.
  • The body of _gx_animation_start() is guarded the same way in gx_animation_start.c, so the reference does not resolve at link time either.

A project that defines GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save resources therefore fails to build, even when it uses no animation action at all.

Reproduced on system_screen_stack_specifications.c with GX_ANIMATION_POOL_SIZE 0:

error C4013: 'gx_system_animation_get' undefined; assuming extern returning int
UNDEF External | _gxe_animation_start <- LNK2019 at link time
UNDEF External | gx_system_animation_get

GCC 14, the default compiler for the project, rejects the implicit declaration outright rather than warning about it.

Fix

screen_generator.cpp now wraps both helpers and the two GX_ACTION_TYPE_ANIMATION dispatch sites (the <= 50402 and the current library version branches) in #if (GX_ANIMATION_POOL_SIZE > 0). Every other action type keeps working with an empty pool, and an animation action simply becomes a no-op at runtime.

The generator also emits forward prototypes for the four static Screen Flow helpers, which addresses the secondary request in the issue. Note that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule 8.4 applies to objects and functions with external linkage, so the static helpers without a visible prototype were not a deviation. The prototypes are still worth having, and they match the declaration the generator already emits for gx_studio_nested_widget_create().

Generated files

All 30 checked-in generated *_specifications.c files were re-synced with the generator, including the three golden files of the Studio view test.

Verified with test_demo/test_main.py -t across all 227 Studio projects: 227 passed, 0 failed, so the updated files match generator output exactly.

Regression test

test/guix_studio_test/test_demo/test_animation_pool_size.py, registered in the demo_compile CTest project so the existing GUIX Studio Demo Compile Test workflow runs it:

  1. Source check — the two helper definitions and the case label must sit inside the guard. Rejects "prototypes only guarded", "definitions unguarded", "case unguarded" and the pre-fix shape.
  2. Compile check — compiles every Screen Flow specification file with GX_ANIMATION_POOL_SIZE 0 and /we4013, so the implicit declaration is an error rather than a warning.

Results on this branch: 27 source-checked, 25 compiled, all passing in about 7 seconds under ctest. Against the pre-fix tree the same test fails 27/28 source checks and 24/26 compiles.

all_widgets_5_4_0 and all_widgets_5_4_1 are excluded from the compile stage because their generated code targets a pre-5.4.2 widget API; the existing demo compile test skips them for the same reason. They are still covered by the source check.

Documentation

Matching documentation update: eclipse-threadx/rtos-docs-asciidoc#42

🤖 Generated with Claude Code


Hotfix release preparation

This PR also carries the version bump for the emergency hotfix release that ships the fix, 6.5.1.202602a.

Release tooling

The tooling could not express a hotfix version at all, so it was fixed first:

  • Get-StudioReleaseVersion rejected anything that was not major.minor.patch.build, and update_studio_release_version.ps1 hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build a hotfix installer was unusable, and running the script after a manual edit would have reset the hotfix constant.
  • prepare_release.sh searched only ports/ for gx_port.h, so it never updated the version string of the GUIX Studio Win32 port in guix_studio/ports/gx_port.h.

Get-StudioReleaseVersion now accepts an optional trailing hotfix letter and exposes it as Hotfix / HotfixDefine. The Win32 and MSIX version formats are strictly numeric and cannot carry the letter, so the revision is offset by the position of the letter in the alphabet instead:

InputFullVersionWin32MSIXRC numericHotfix
6.5.1.2026026.5.1.2026026.5.1.26.5.1.026,5,1,2' '
6.5.1.202602a6.5.1.202602a6.5.1.36.5.1.036,5,1,3'a'
6.5.1.202602b6.5.1.202602b6.5.1.46.5.1.046,5,1,4'b'

That keeps the hotfix installer recognizable as the newer build for Windows upgrade detection and for the Store. Versions without a hotfix letter resolve exactly as before, and 6.5.1, 6.5.1.202602A, 6.5.1.202602ab and 6.5.1.202602-a are all still rejected.

Version constants

Produced by scripts/update_studio_release_version.ps1 -Version 6.5.1.202602a, plus the port strings:

  • common/inc/gx_api.hGUIX_HOTFIX_VERSION 'a'. Major, minor, patch, build and the 6.5.1 banner are unchanged.
  • guix_studio/studiox.rcFileVersion / ProductVersion strings 6.5.1.202602a; FILEVERSION / PRODUCTVERSION6,5,1,3.
  • guix_studio/installer/guix_installer_release.issStudioFullVersion "6.5.1.202602a", StudioVersionInfoVersion "6.5.1.3", so the installer is named guix_studio_setup_version_6.5.1.202602a.exe.
  • guix_studio/build/vs_2022/msix_package_project/Package.appxmanifest — MSIX identity 6.5.1.03.
  • All 47 gx_port.h files, including guix_studio/ports/gx_port.h.

STUDIOX_VERSION_NUMBER deliberately stays at 202602: it stamps the Studio version into .gxp project files, and a hotfix does not change the project file format.

Verified against a rebuilt guix_studio.exe, which reports FileVersion 6.5.1.202602a with a numeric file version of 6.5.1.3 — what verify_studio_installer.ps1 checks.

README.md still points at the current 6.5.1.202602 download, since the v6.5.1.202602a_rel tag and its asset do not exist yet. It should be updated when the release is published.

Re-verified after the bump

  • test_animation_pool_size.py: 27 source-checked, 25 compiled, 0 failures.
  • test_main.py -t: 227 projects, 227 passed, 0 failed.

GUIX Studio emitted five static helper functions in the generated
specification file as soon as a project used Screen Flow. Two of them,
gx_studio_action_parent_find() and gx_studio_animation_execute(), are
reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference
the GUIX animation API, which is compiled out when the animation pool
is empty:
- gx_system_animation_get() is only defined under
"#if (GX_ANIMATION_POOL_SIZE > 0)" in gx_api.h.
- The body of _gx_animation_start() is guarded the same way in
gx_animation_start.c, so the reference does not resolve at link
time either.
A project that defined GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save
resources therefore failed to build even when it used no animation
action at all. GCC 14 rejects the implicit declaration outright, and
MSVC fails on the unresolved external.
The screen generator now wraps both helpers and the two
GX_ACTION_TYPE_ANIMATION dispatch sites in
"#if (GX_ANIMATION_POOL_SIZE > 0)". Every other action type keeps
working with an empty pool, and an animation action simply becomes a
no-op at runtime.
The generator also emits forward prototypes for the four static screen
flow helpers, which addresses the secondary request in the issue. Note
that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule
8.4 applies to objects and functions with external linkage, so static
helpers without a visible prototype were not a deviation. The
prototypes are still worth having and match the declaration the
generator already emits for gx_studio_nested_widget_create().
All the checked-in generated specification files were regenerated so
that they stay in sync with the generator, including the golden files
of the Studio view test.
Added test/guix_studio_test/test_demo/test_animation_pool_size.py as a
regression test, registered in the demo compile CTest project. It
verifies that every checked-in Screen Flow specification file guards
the animation helpers, then compiles them all with
GX_ANIMATION_POOL_SIZE set to 0, promoting the MSVC implicit
declaration warning to an error so the failure mode above is caught.
Fixeseclipse-threadx#172
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fdesbiensand others added 3 commits August 25, 2026 11:10
The release tooling could not express a hotfix version. Two gaps:
- Get-StudioReleaseVersion rejected anything that was not
major.minor.patch.build, and update_studio_release_version.ps1
hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build
a hotfix installer was therefore unusable, and running the script
after a manual edit would have reset the hotfix constant.
- prepare_release.sh looked for gx_port.h under ports only, so it
never updated the version string of the GUIX Studio Win32 port in
guix_studio/ports/gx_port.h.
Get-StudioReleaseVersion now accepts an optional trailing hotfix letter
and exposes it as Hotfix and HotfixDefine. The Win32 and MSIX version
formats are strictly numeric and cannot carry the letter, so the
revision is offset by the position of the letter in the alphabet
instead: 6.5.1.202602 keeps revision 2, and 6.5.1.202602a becomes
revision 3. That keeps the hotfix installer recognizable as the newer
build for Windows upgrade detection and for the Store. Versions without
a hotfix letter resolve exactly as before.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Prepares the emergency hotfix release that carries the Screen Flow fix
for GX_ANIMATION_POOL_SIZE = 0.
Produced by scripts/update_studio_release_version.ps1 -Version
6.5.1.202602a:
- gx_api.h: GUIX_HOTFIX_VERSION is now 'a'. The major, minor, patch
and build constants are unchanged, as is the 6.5.1 banner.
- studiox.rc: FileVersion and ProductVersion strings are
6.5.1.202602a, FILEVERSION and PRODUCTVERSION are 6,5,1,3.
- guix_installer_release.iss: StudioFullVersion is 6.5.1.202602a and
StudioVersionInfoVersion is 6.5.1.3, so the installer is named
guix_studio_setup_version_6.5.1.202602a.exe.
- Package.appxmanifest: the MSIX identity version is 6.5.1.03.
STUDIOX_VERSION_NUMBER stays at 202602. It stamps the Studio version
into .gxp project files, and a hotfix does not change the project file
format.
Verified against a rebuilt guix_studio.exe, which reports FileVersion
6.5.1.202602a with a numeric file version of 6.5.1.3, matching what
verify_studio_installer.ps1 expects.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Updated the _gx_version_id string in all 47 gx_port.h files for the
emergency hotfix release, using the same substitution that
prepare_release.sh performs.
This includes guix_studio/ports/gx_port.h, the GUIX Studio Win32 port,
which the release script previously missed because it only searched the
ports directory. That gap is fixed in the preceding commit, so a future
release picks the file up automatically.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit c179c19 into eclipse-threadx:devAug 25, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fix/issue-172-animation-pool-size-zero branch August 25, 2026 17:10
@fdesbiens

Copy link
Copy Markdown
ContributorAuthor

@parsley This PR should fix your issue. I need to prepare a new installer and release. This should be done tomorrow (Wednesday).

fdesbiens added a commit that referenced this pull request Aug 27, 2026
compare_file() locates the line where comparison should start, so that the
banner GUIX Studio writes into every generated file -- which carries a revision
string and a generation timestamp -- is skipped rather than compared. It looked
that line up correctly in the first file and then looked it up in the first file
again for the second:
for line in list_2:
if compare_start_string in line:
start_row_2 = list_1.index(line)
So the golden was sliced at the *generated* file's offset. While both files
happened to reach "#include" on the same line the mistake was invisible, which
is why it survived since the tests were added in #84.
The offsets diverged when 6ba13db added a ten-line MIT licence header to all
111 golden .c and .h files. GUIX Studio does not emit that header, so every
golden now reaches its first #include ten lines later than the file it is
compared against. The golden was therefore sliced ten lines early and compared
banner text against source.
That made every one of the 107 .c and .h comparisons in the suite fail -- all 29
reported test failures -- while the .csv, .xliff and .xml comparisons passed.
Those use skip_line instead of compare_start_string and never reach this code,
which is exactly the split the failure log shows.
The reported mismatch is the same in all 29: a generated "#include" line against
a golden banner comment. Confirmed arithmetically -- in every case the golden
line reported sits exactly ten lines before that golden's own first #include:
generic_16bpp_resources.c reported idx 13, #include at 23, delta 10
generic_16bpp_resources.h reported idx 16, #include at 26, delta 10
generic_16bpp_specifications.c reported idx 14, #include at 24, delta 10
generic_16bpp_specifications.h reported idx 16, #include at 26, delta 10
compare_output_file() is the only caller that passes compare_start_string, so
the change cannot affect the xliff, xml or plain-file comparisons.
Verified by running the suite locally against a Studio built from this tree.
Seven suites that fail in CI now pass with no mismatches at all, each gaining
exactly the tests it had been failing:
CI (broken) local (fixed)
Font 9 / 1 10 / 0
Multi-Themes 18 / 1 19 / 0
Project Import 10 / 2 12 / 0
Trigger Edit 6 / 1 7 / 0
Trigger Target Rename 1 / 1 2 / 0
Bidi Text 3 / 1 4 / 0
Widget Name 3 / 1 4 / 0
Project Import compares a generated specifications file, so this also shows that
the screen flow prototype block added by #173 does not disturb these goldens:
that block is only emitted for projects that use Screen Flow, and these do not.
No golden file is regenerated. The goldens still carry "GUIX Studio Revision
6.1.12.0" and a 2022 timestamp in their banners, and still name Azure RTOS
rather than Eclipse ThreadX, but the banner is what the comparison is supposed
to skip -- so none of that needs to be touched to make the suite correct.
This workflow had never actually executed before 2026-08-27. Every earlier run
was cancelled after queueing 24 hours for the retired windows-2019 image, or
sat awaiting approval on a fork pull request, including the run for the v6.5.1
release itself. #174 gave it a runner again; this is the first result it has
ever produced, and the defect it found is in the test harness rather than in
GUIX or in Studio.
Note that studio_view_test.yml triggers only on pull requests targeting master,
so this change is not exercised by its own pull request into dev. It is
validated by the release pull request that carries dev to master.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0 - #173

Merged
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero
Aug 25, 2026
Merged

Fixed Screen Flow code generation with GX_ANIMATION_POOL_SIZE = 0#173
fdesbiens merged 4 commits into
eclipse-threadx:devfrom
fdesbiens:fix/issue-172-animation-pool-size-zero

Conversation

@fdesbiens

@fdesbiensfdesbiens commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Fixes#172

Problem

GUIX Studio emits five static helper functions in the generated specification file as soon as a project uses Screen Flow. Two of them, gx_studio_action_parent_find() and gx_studio_animation_execute(), are reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference the GUIX animation API, which is compiled out when the animation pool is empty:

  • gx_system_animation_get() is only defined under #if (GX_ANIMATION_POOL_SIZE > 0) in gx_api.h.
  • The body of _gx_animation_start() is guarded the same way in gx_animation_start.c, so the reference does not resolve at link time either.

A project that defines GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save resources therefore fails to build, even when it uses no animation action at all.

Reproduced on system_screen_stack_specifications.c with GX_ANIMATION_POOL_SIZE 0:

error C4013: 'gx_system_animation_get' undefined; assuming extern returning int
UNDEF External | _gxe_animation_start <- LNK2019 at link time
UNDEF External | gx_system_animation_get

GCC 14, the default compiler for the project, rejects the implicit declaration outright rather than warning about it.

Fix

screen_generator.cpp now wraps both helpers and the two GX_ACTION_TYPE_ANIMATION dispatch sites (the <= 50402 and the current library version branches) in #if (GX_ANIMATION_POOL_SIZE > 0). Every other action type keeps working with an empty pool, and an animation action simply becomes a no-op at runtime.

The generator also emits forward prototypes for the four static Screen Flow helpers, which addresses the secondary request in the issue. Note that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule 8.4 applies to objects and functions with external linkage, so the static helpers without a visible prototype were not a deviation. The prototypes are still worth having, and they match the declaration the generator already emits for gx_studio_nested_widget_create().

Generated files

All 30 checked-in generated *_specifications.c files were re-synced with the generator, including the three golden files of the Studio view test.

Verified with test_demo/test_main.py -t across all 227 Studio projects: 227 passed, 0 failed, so the updated files match generator output exactly.

Regression test

test/guix_studio_test/test_demo/test_animation_pool_size.py, registered in the demo_compile CTest project so the existing GUIX Studio Demo Compile Test workflow runs it:

  1. Source check — the two helper definitions and the case label must sit inside the guard. Rejects "prototypes only guarded", "definitions unguarded", "case unguarded" and the pre-fix shape.
  2. Compile check — compiles every Screen Flow specification file with GX_ANIMATION_POOL_SIZE 0 and /we4013, so the implicit declaration is an error rather than a warning.

Results on this branch: 27 source-checked, 25 compiled, all passing in about 7 seconds under ctest. Against the pre-fix tree the same test fails 27/28 source checks and 24/26 compiles.

all_widgets_5_4_0 and all_widgets_5_4_1 are excluded from the compile stage because their generated code targets a pre-5.4.2 widget API; the existing demo compile test skips them for the same reason. They are still covered by the source check.

Documentation

Matching documentation update: eclipse-threadx/rtos-docs-asciidoc#42

🤖 Generated with Claude Code


Hotfix release preparation

This PR also carries the version bump for the emergency hotfix release that ships the fix, 6.5.1.202602a.

Release tooling

The tooling could not express a hotfix version at all, so it was fixed first:

  • Get-StudioReleaseVersion rejected anything that was not major.minor.patch.build, and update_studio_release_version.ps1 hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build a hotfix installer was unusable, and running the script after a manual edit would have reset the hotfix constant.
  • prepare_release.sh searched only ports/ for gx_port.h, so it never updated the version string of the GUIX Studio Win32 port in guix_studio/ports/gx_port.h.

Get-StudioReleaseVersion now accepts an optional trailing hotfix letter and exposes it as Hotfix / HotfixDefine. The Win32 and MSIX version formats are strictly numeric and cannot carry the letter, so the revision is offset by the position of the letter in the alphabet instead:

InputFullVersionWin32MSIXRC numericHotfix
6.5.1.2026026.5.1.2026026.5.1.26.5.1.026,5,1,2' '
6.5.1.202602a6.5.1.202602a6.5.1.36.5.1.036,5,1,3'a'
6.5.1.202602b6.5.1.202602b6.5.1.46.5.1.046,5,1,4'b'

That keeps the hotfix installer recognizable as the newer build for Windows upgrade detection and for the Store. Versions without a hotfix letter resolve exactly as before, and 6.5.1, 6.5.1.202602A, 6.5.1.202602ab and 6.5.1.202602-a are all still rejected.

Version constants

Produced by scripts/update_studio_release_version.ps1 -Version 6.5.1.202602a, plus the port strings:

  • common/inc/gx_api.hGUIX_HOTFIX_VERSION 'a'. Major, minor, patch, build and the 6.5.1 banner are unchanged.
  • guix_studio/studiox.rcFileVersion / ProductVersion strings 6.5.1.202602a; FILEVERSION / PRODUCTVERSION6,5,1,3.
  • guix_studio/installer/guix_installer_release.issStudioFullVersion "6.5.1.202602a", StudioVersionInfoVersion "6.5.1.3", so the installer is named guix_studio_setup_version_6.5.1.202602a.exe.
  • guix_studio/build/vs_2022/msix_package_project/Package.appxmanifest — MSIX identity 6.5.1.03.
  • All 47 gx_port.h files, including guix_studio/ports/gx_port.h.

STUDIOX_VERSION_NUMBER deliberately stays at 202602: it stamps the Studio version into .gxp project files, and a hotfix does not change the project file format.

Verified against a rebuilt guix_studio.exe, which reports FileVersion 6.5.1.202602a with a numeric file version of 6.5.1.3 — what verify_studio_installer.ps1 checks.

README.md still points at the current 6.5.1.202602 download, since the v6.5.1.202602a_rel tag and its asset do not exist yet. It should be updated when the release is published.

Re-verified after the bump

  • test_animation_pool_size.py: 27 source-checked, 25 compiled, 0 failures.
  • test_main.py -t: 227 projects, 227 passed, 0 failed.

GUIX Studio emitted five static helper functions in the generated
specification file as soon as a project used Screen Flow. Two of them,
gx_studio_action_parent_find() and gx_studio_animation_execute(), are
reachable only from the GX_ACTION_TYPE_ANIMATION handler and reference
the GUIX animation API, which is compiled out when the animation pool
is empty:
- gx_system_animation_get() is only defined under
"#if (GX_ANIMATION_POOL_SIZE > 0)" in gx_api.h.
- The body of _gx_animation_start() is guarded the same way in
gx_animation_start.c, so the reference does not resolve at link
time either.
A project that defined GX_ANIMATION_POOL_SIZE as 0 in gx_user.h to save
resources therefore failed to build even when it used no animation
action at all. GCC 14 rejects the implicit declaration outright, and
MSVC fails on the unresolved external.
The screen generator now wraps both helpers and the two
GX_ACTION_TYPE_ANIMATION dispatch sites in
"#if (GX_ANIMATION_POOL_SIZE > 0)". Every other action type keeps
working with an empty pool, and an animation action simply becomes a
no-op at runtime.
The generator also emits forward prototypes for the four static screen
flow helpers, which addresses the secondary request in the issue. Note
that MISRA C:2012 Rule 8.1 covers explicitly specified types and Rule
8.4 applies to objects and functions with external linkage, so static
helpers without a visible prototype were not a deviation. The
prototypes are still worth having and match the declaration the
generator already emits for gx_studio_nested_widget_create().
All the checked-in generated specification files were regenerated so
that they stay in sync with the generator, including the golden files
of the Studio view test.
Added test/guix_studio_test/test_demo/test_animation_pool_size.py as a
regression test, registered in the demo compile CTest project. It
verifies that every checked-in Screen Flow specification file guards
the animation helpers, then compiles them all with
GX_ANIMATION_POOL_SIZE set to 0, promoting the MSVC implicit
declaration warning to an error so the failure mode above is caught.
Fixeseclipse-threadx#172
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fdesbiensand others added 3 commits August 25, 2026 11:10
The release tooling could not express a hotfix version. Two gaps:
- Get-StudioReleaseVersion rejected anything that was not
major.minor.patch.build, and update_studio_release_version.ps1
hard-coded GUIX_HOTFIX_VERSION as ' '. The documented path to build
a hotfix installer was therefore unusable, and running the script
after a manual edit would have reset the hotfix constant.
- prepare_release.sh looked for gx_port.h under ports only, so it
never updated the version string of the GUIX Studio Win32 port in
guix_studio/ports/gx_port.h.
Get-StudioReleaseVersion now accepts an optional trailing hotfix letter
and exposes it as Hotfix and HotfixDefine. The Win32 and MSIX version
formats are strictly numeric and cannot carry the letter, so the
revision is offset by the position of the letter in the alphabet
instead: 6.5.1.202602 keeps revision 2, and 6.5.1.202602a becomes
revision 3. That keeps the hotfix installer recognizable as the newer
build for Windows upgrade detection and for the Store. Versions without
a hotfix letter resolve exactly as before.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Prepares the emergency hotfix release that carries the Screen Flow fix
for GX_ANIMATION_POOL_SIZE = 0.
Produced by scripts/update_studio_release_version.ps1 -Version
6.5.1.202602a:
- gx_api.h: GUIX_HOTFIX_VERSION is now 'a'. The major, minor, patch
and build constants are unchanged, as is the 6.5.1 banner.
- studiox.rc: FileVersion and ProductVersion strings are
6.5.1.202602a, FILEVERSION and PRODUCTVERSION are 6,5,1,3.
- guix_installer_release.iss: StudioFullVersion is 6.5.1.202602a and
StudioVersionInfoVersion is 6.5.1.3, so the installer is named
guix_studio_setup_version_6.5.1.202602a.exe.
- Package.appxmanifest: the MSIX identity version is 6.5.1.03.
STUDIOX_VERSION_NUMBER stays at 202602. It stamps the Studio version
into .gxp project files, and a hotfix does not change the project file
format.
Verified against a rebuilt guix_studio.exe, which reports FileVersion
6.5.1.202602a with a numeric file version of 6.5.1.3, matching what
verify_studio_installer.ps1 expects.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Updated the _gx_version_id string in all 47 gx_port.h files for the
emergency hotfix release, using the same substitution that
prepare_release.sh performs.
This includes guix_studio/ports/gx_port.h, the GUIX Studio Win32 port,
which the release script previously missed because it only searched the
ports directory. That gap is fixed in the preceding commit, so a future
release picks the file up automatically.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit c179c19 into eclipse-threadx:devAug 25, 2026
1 check passed
@fdesbiens
fdesbiens deleted the fix/issue-172-animation-pool-size-zero branch August 25, 2026 17:10
@fdesbiens

Copy link
Copy Markdown
ContributorAuthor

@parsley This PR should fix your issue. I need to prepare a new installer and release. This should be done tomorrow (Wednesday).

fdesbiens added a commit that referenced this pull request Aug 27, 2026
compare_file() locates the line where comparison should start, so that the
banner GUIX Studio writes into every generated file -- which carries a revision
string and a generation timestamp -- is skipped rather than compared. It looked
that line up correctly in the first file and then looked it up in the first file
again for the second:
for line in list_2:
if compare_start_string in line:
start_row_2 = list_1.index(line)
So the golden was sliced at the *generated* file's offset. While both files
happened to reach "#include" on the same line the mistake was invisible, which
is why it survived since the tests were added in #84.
The offsets diverged when 6ba13db added a ten-line MIT licence header to all
111 golden .c and .h files. GUIX Studio does not emit that header, so every
golden now reaches its first #include ten lines later than the file it is
compared against. The golden was therefore sliced ten lines early and compared
banner text against source.
That made every one of the 107 .c and .h comparisons in the suite fail -- all 29
reported test failures -- while the .csv, .xliff and .xml comparisons passed.
Those use skip_line instead of compare_start_string and never reach this code,
which is exactly the split the failure log shows.
The reported mismatch is the same in all 29: a generated "#include" line against
a golden banner comment. Confirmed arithmetically -- in every case the golden
line reported sits exactly ten lines before that golden's own first #include:
generic_16bpp_resources.c reported idx 13, #include at 23, delta 10
generic_16bpp_resources.h reported idx 16, #include at 26, delta 10
generic_16bpp_specifications.c reported idx 14, #include at 24, delta 10
generic_16bpp_specifications.h reported idx 16, #include at 26, delta 10
compare_output_file() is the only caller that passes compare_start_string, so
the change cannot affect the xliff, xml or plain-file comparisons.
Verified by running the suite locally against a Studio built from this tree.
Seven suites that fail in CI now pass with no mismatches at all, each gaining
exactly the tests it had been failing:
CI (broken) local (fixed)
Font 9 / 1 10 / 0
Multi-Themes 18 / 1 19 / 0
Project Import 10 / 2 12 / 0
Trigger Edit 6 / 1 7 / 0
Trigger Target Rename 1 / 1 2 / 0
Bidi Text 3 / 1 4 / 0
Widget Name 3 / 1 4 / 0
Project Import compares a generated specifications file, so this also shows that
the screen flow prototype block added by #173 does not disturb these goldens:
that block is only emitted for projects that use Screen Flow, and these do not.
No golden file is regenerated. The goldens still carry "GUIX Studio Revision
6.1.12.0" and a 2022 timestamp in their banners, and still name Azure RTOS
rather than Eclipse ThreadX, but the banner is what the comparison is supposed
to skip -- so none of that needs to be touched to make the suite correct.
This workflow had never actually executed before 2026-08-27. Every earlier run
was cancelled after queueing 24 hours for the retired windows-2019 image, or
sat awaiting approval on a fork pull request, including the run for the v6.5.1
release itself. #174 gave it a runner again; this is the first result it has
ever produced, and the defect it found is in the test harness rather than in
GUIX or in Studio.
Note that studio_view_test.yml triggers only on pull requests targeting master,
so this change is not exercised by its own pull request into dev. It is
validated by the release pull request that carries dev to master.
Assisted-by: Claude Code (Opus 5)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@fdesbiens