Skip to content

Add imgui_bundle package#116

Merged
ryanking13 merged 1 commit into
pyodide:mainfrom
pthom:add_imgui_bundle
Jul 1, 2025
Merged

Add imgui_bundle package#116
ryanking13 merged 1 commit into
pyodide:mainfrom
pthom:add_imgui_bundle

Conversation

@pthom

@pthom pthom commented Jun 20, 2025

Copy link
Copy Markdown
Contributor

Description

Dear ImGui Bundle provides python bindings for Dear ImGui and lots of related libraries.

This PR adds support for the imgui_bundle package to Pyodide. It enables high-performance interactive GUIs (including 3D plotting, Markdown rendering, and immediate mode controls) directly in the browser using pure Python (no need for JavaScript, CSS, or WebAssembly glue code outside Pyodide’s core).

Demo

I prepared two demonstrations in order to showcase what is possible:

Discussion and related PR

This recipe requires a change inside pyodide/Makefile.envs (see technical note below: add -sMAX_WEBGL_VERSION=2).

A related PR was posted to the main pyodide repo, to add this flag.

The test for this new recipe will fail if this change is not applied.

Technical Notes:

  1. Build configuration for Pyodide: -sMAX_WEBGL_VERSION=2

  2. Link with SDL2 (fPIC):

meta.yaml/build will trigger the build of SDL2 and libtml5 with -fPIC

  1. Running the tests
  • the test need to be run via a browser (not via node). For example:
   pytest pyodide-recipes/packages/imgui-bundle --runtime chrome

@pthom pthom force-pushed the add_imgui_bundle branch from 790c1c7 to 1462b5b Compare June 20, 2025 16:59
@pthom pthom force-pushed the add_imgui_bundle branch 2 times, most recently from bbe1484 to 3a31fb1 Compare June 28, 2025 22:48
@pthom

pthom commented Jun 28, 2025

Copy link
Copy Markdown
Contributor Author

Hello @ryanking13 ,

Following the merge of the WebGL2 PR, I rebased this PR.
It also now uses the latest release of imgui bundle (v1.92.0).

@pthom pthom force-pushed the add_imgui_bundle branch 2 times, most recently from a556bf7 to da1475e Compare June 29, 2025 13:27
@github-actions

github-actions Bot commented Jun 29, 2025

Copy link
Copy Markdown
Contributor

Package Build Results

Total packages built: 35
Total build time: 0:09:53

Package Build Times (click to expand)
Package Build Time
imgui-bundle 5m 48s
openssl 5m 12s
numpy 4m 42s
pydantic_core 3m 54s
sqlite3 2m 37s
liblzma 1m 5s
test 25s
regex 12s
ssl 12s
hashlib 10s
pydecimal 8s
pydoc_data 5s
lzma 5s
MarkupSafe 4s
atomicwrites 3s
pytz 3s
pydantic 2s
packaging 2s
Jinja2 2s
setuptools 1s
pyparsing 1s
pluggy 1s
six 1s
pytest-asyncio 1s
typing-extensions 1s
annotated-types 1s
micropip 1s
py 1s
exceptiongroup 1s
tblib 1s
attrs 1s
iniconfig 1s
pytest 1s
munch 0s
more-itertools 0s

Longest build: imgui-bundle (5m 48s)
Packages built in more than 10 minutes: 0

@pthom pthom force-pushed the add_imgui_bundle branch from 9aae7a0 to a36d932 Compare June 29, 2025 16:18
@pthom

pthom commented Jun 29, 2025

Copy link
Copy Markdown
Contributor Author

I had to do some modifications in order to correct the test. Sorry for force-pushing several times today.

  • The test runs now correctly in Chrome.

  • The test is expected to fail in Firefox Headless because Firefox Headless does not support WebGL unless a virtual display is set up.
    For info, Xvfb + GL drivers might be installed by adding this into the build.yml CI workflow

    - name: Start virtual display (for WebGL tests)
      run: |
        sudo apt-get update
        sudo apt-get install -y xvfb libgl1-mesa-dri
        Xvfb :99 -screen 0 1280x720x24 -ac &
        echo "DISPLAY=:99.0" >> $GITHUB_ENV
    

However, even with a virtual display headless there are remaining issues around requestAnimationFrame in Firefox, so the test is still expected to fail.

Of course when deployed, the package and the apps developed with it will work on Safari / Firefox / Chrome (this was tested on Windows, Linux, macOS and iOS).

@agriyakhetarpal agriyakhetarpal left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this work, @pthom! I am onboard with the testing criteria you proposed; I think it's a unique approach. Even if the tests work only for Chrome and not Firefox Headless, that is fine with me. I will wait for @ryanking13's comments/approval here.

@ryanking13 ryanking13 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test runs now correctly in Chrome.

Yeah, I think it is okay to test it only in Chrome. We don't expect to test the full functionality of the packages in this repository anyways. If we have more packages that require WebGL, let's consider including it in our CI environment, for now it looks okay.

Comment thread packages/imgui-bundle/meta.yaml
Comment thread packages/imgui-bundle/meta.yaml Outdated
Comment thread packages/imgui-bundle/demo_imgui_bundle.html
Comment thread packages/imgui-bundle/test_imgui_bundle.py Outdated
import time
deadline = time.time() + 6.0 # 6-second safety net (requestAnimationFrame may run slowly in headless mode)
while not done and time.time() < deadline:
time.sleep(0.05) # yields to JS -> lets requestAnimationFrame run

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yields to JS

It won't. When JSPI is not enabled, time.sleep is busy wait.

You can use asyncio.sleep instead to ensure yielding to JS.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

I replaced this with

    import asyncio, time
    deadline = time.time() + 6.0      # 6-second safety net (requestAnimationFrame may run slowly in headless mode)

    async def _wait_until_done():
        while not done and time.time() < deadline:
            await asyncio.sleep(0.05)

    asyncio.run(_wait_until_done())

@pthom pthom force-pushed the add_imgui_bundle branch from a36d932 to 68ee746 Compare June 30, 2025 14:21
Build notes:
------------

meta.yaml/build will trigger the build of SDL2 and libtml5 with -fPIC

Test notes:
-----------
* The test runs correctly in Chrome.

* The test is expected to fail in Firefox Headless because:
  * Firefox Headless does not support WebGL unless a virtual display is set up.
    This might be solved by adding a step in the GitHub Actions workflow to install xvfb + GL drivers.
  * However, even with a virtual display headless there are remaining issues around requestAnimationFrame
    so the test is still expected to fail.

For info, Xvfb + GL drivers might be installed by adding this into the build.yml CI workflow

      - name: Start virtual display (for WebGL tests)
        run: |
          sudo apt-get update
          sudo apt-get install -y xvfb libgl1-mesa-dri
          Xvfb :99 -screen 0 1280x720x24 -ac &
          echo "DISPLAY=:99.0" >> $GITHUB_ENV
@pthom pthom force-pushed the add_imgui_bundle branch 2 times, most recently from 7e56e1a to 67af758 Compare June 30, 2025 14:58
@pthom

pthom commented Jun 30, 2025

Copy link
Copy Markdown
Contributor Author

@ryanking13 : I did all the changes you asked for.

@ryanking13 ryanking13 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @pthom!

Comment on lines +69 to +73
async def _wait_until_done():
while not done and time.time() < deadline:
await asyncio.sleep(0.05)

asyncio.run(_wait_until_done())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is worth noting that aysncio.run also works only if the JSPI is enabled.

So a safer way would be changing the test function to async, and simply using await asyncio.sleep(0.05). But we enable JSPI in our CI anyways, so probably it is okay.

@ryanking13 ryanking13 merged commit 46fcca5 into pyodide:main Jul 1, 2025
8 checks passed
@pthom

pthom commented Jul 1, 2025

Copy link
Copy Markdown
Contributor Author

Thank you!

Sign up for free to 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.

3 participants