Skip to content

Latest commit

 

History

History
1449 lines (1104 loc) · 82.6 KB

File metadata and controls

1449 lines (1104 loc) · 82.6 KB

Version scheme: ImGui Bundle uses major.minor.patch where patch = ImGui_patch × 100 + bundle_release. For example, ImGui v1.92.6 → Bundle v1.92.600, and a bugfix becomes v1.92.601.

Ongoing changes

Touch screens: the gestures of a phone

On a touch screen (a phone running the explorer or the playground, a tablet), Hello ImGui turns a finger into what its user expects, with nothing to write in the app:

  • a swipe scrolls the content of a window, with inertia and a bounce at the end, even when the drag starts on a button or on a markdown text; a tap still clicks (when the finger lifts), two taps are a double click, and a short hold then a drag goes to the widget under the finger (a slider, a text selection; a ring around the finger shows when the hold took effect);
  • a finger still for half a second is a right click (the context menus), except on a widget that acted on the press already (a button that repeats while held);
  • two fingers that pinch scale the app (its font); two fingers that move together are a right drag (the pan of a node editor, the box selection of a plot);
  • a text widget that is active shows a keyboard button next to it: a tap opens the phone's keyboard, and what is typed goes to the widget.

hello_imgui.RunnerParams.touch_scroll_mode (auto: when the input is a touch screen; always: also with the mouse, to try it on a desktop; disabled), touch_long_press_is_right_click, touch_pinch_mode. In the browser with GLFW (the explorers), ImGui now knows whether the pointer is a mouse, a finger or a pen. ImPlot's drag tools (the guide lines, the boxes) get finger-sized grabs on a touch screen.

The demo "Touch screens (phones, tablets)" (demo_touch_screen, in "In the browser") shows every gesture on a phone-shaped page; on a desktop, its "Simulate a touch source" checkbox plays the finger with the mouse. The playground has a phone layout: one pane at a time, Demo or Code, from a switch in its toolbar.

Mouse wheel: a wheel that started on the page keeps scrolling it

On a desktop, a wheel that started on the content of a window keeps scrolling it when the mouse travels over a plot or an image that zooms with the wheel: the item sees no wheel until the session ends (0.7 s without an event, ImGui's own lock of the scrolled window, applied to items). A wheel that starts on the item is the item's.

ImmVision: a negative display size is the remaining width

ImageParams.image_display_size, the size of image_display() and the in/out size of image_display_resizable() accept a negative width or height: the window's remaining space minus its absolute value, as ImGui's item widths ((-1, 0): the width of the window, the height from the aspect ratio).

ImGui Explorer: an API tab

The code viewer of the ImGui Explorer (the interactive manuals of ImGui, ImPlot, ImPlot3D and ImAnim) gets an "API" tab, built from the same index as the book's API pages:

  • click an identifier in the code, then the book button (or Ctrl+Shift+F, or the right-click menu): the card of the entry, with its Python and C++ names and signatures, its doc, the members of a struct or the values of an enum, "Go to declaration" (the line in the header or in the stub), links to its online pages, and "In the demo": the lines of the demo that use it, one click away;
  • a tooltip with the API of the identifier under the mouse ("API tooltips" in the toolbar);
  • the list of all the entries by section, with a filter on the Python and C++ names.

The index (just api_pages) must be generated before the explorer is configured; otherwise the tab links to the online pages.

immapp: downloads that do not block the GUI

immapp.start_download(url, method, json_body, timeout_s, headers) starts an HTTP request in the background, from a GUI function: a thread on the desktop, a fetch in the browser (Pyodide). The GUI looks at the result's done at each frame, then at its status, data and error (the HTTP status with the start of the body, where web APIs explain their errors).

  • GET, or POST with a JSON body; more headers, e.g. an API key ({"Authorization": "Bearer <key>"}); a time limit for the answer.
  • download_url_bytes() and download_url_bytes_async() gain timeout_s.
  • Doc: the book's page on async Python, "Downloads that do not block the GUI". Demos: "An image from a prompt", the Julia map.

The Julia map: values of c shared by its users

The Julia map explorable (playground: "Interactive exploration of the Mandelbrot set") lets its users share the places they find:

  • "Copy" copies c and the zoom of the map; a field under the map takes a pasted value, and the map flies there.
  • The tab "Found by users" lists the values of c that users shared, with a filter, a sort (name, votes, author, date), a vote per user, and "Share the current c...".
  • On a narrow window (a phone), the three columns become rows.

The points live in a Cloudflare Worker with a database (cloudflare/julia_points), deployed apart from the site: see cloudflare_deploy.md. The demo is now a folder, explorables/julia_map/, and its address in the playground changed.

Markdown renderer:

Fully rewritten imgui_md, which is now imgui_rich_md

imgui_md becomes rich_md (library imgui_rich_md)

The markdown stack (renderer, wrapper, LaTeX backend) is now imgui_rich_md, a standalone library that works on stock Dear ImGui.

  • Existing code keeps working:
    • Python: the module is imgui_bundle.rich_md; imgui_bundle.imgui_md is the same module and stays as an alias.
    • C++: the API is RichMd:: in imgui_rich_md/rich_md.h; the former imgui_md_wrapper/imgui_md_wrapper.h include and the ImGuiMd namespace stay as aliases (ImGuiMicroTeX likewise, for RichMd::Latex).
    • CMake: the option IMGUI_BUNDLE_WITH_IMGUI_MD becomes IMGUI_BUNDLE_WITH_IMGUI_RICH_MD; the former name still works, with a deprecation warning.

What else rich_md brings:

  • Narrative programming: a source file can carry its own narrative. ::md Name sections in comments or strings, ::code regions, and transclusions (![[file#Name]], ![[#Name#code]]) resolved by Render(); rich_md.render_this_file("Name") (C++: RICHMD_RENDER_THIS_FILE) renders a section of the calling file, and follows the file when it changes. Spec: imgui_rich_md's docs/narrative_programming. Example: the Julia map explorable (playground).
  • Selectable text: select with the mouse (double click: a word, triple click: a paragraph), copy with Ctrl+C / Cmd+C; a right click opens a menu (Copy, Copy as Markdown, Select All, Copy Link). MarkdownOptions.selectable_text, push_selectable_text() / pop_selectable_text(), set_selectable_text_default() turn it off. Links open on release.
  • Mermaid diagrams, drawn natively (a subset of Mermaid: flowcharts, sequence and class diagrams).
  • Widgets in the text: register_fenced_block_renderer("lang", fn) draws a fenced block of that language.
  • Layout: a gap between paragraphs; <br/> and <br />; HTML comments are not shown; code blocks follow the indent of quotes and lists; long code blocks can be scrolled.
  • Browser (Emscripten, Pyodide): on a Mac, Cmd acts as Ctrl (Cmd+C copies), in every widget (hello_imgui).

Test engine in the browser (Pyodide):

The ImGui Test Engine now runs in Pyodide, with the same Python API as on the desktop: the engine's coroutine is a WebAssembly stack switch (JSPI) instead of a thread. It needs Chrome 137, Firefox 153 or Safari 27; in an older browser the app runs without the engine and says so. immapp.testing.run() in the browser returns at once, keeps the app open after the test, and prints the result. The playground lists the test engine demo (greyed in a browser without JSPI), and its error window now shows whole tracebacks, across the bottom of the page. The demo of scripted runs, demo_testapp, is renamed demo_immapp_testing (desktop only: its output is files); it writes its pictures to a temporary folder. The playground's menu now lists the desktop-only demos too, after the others of their category, with a "Desktop only" tag: a click stops the running demo and shows their code, their picture and a notice on how to run them on a machine (the Python backends: a chip per backend).

ImmVision:

  • RGB is the default color order. Calling immvision.use_rgb_color_order() (C++: ImmVision::UseRgbColorOrder()) at startup is not required anymore. Images in BGR order (OpenCV) still need immvision.use_bgr_color_order().

Breaking change (C++): ImmVision never links OpenCV, cv::Mat interop is an application choice

  • ImmVision does not look for OpenCV at configure time anymore, and never links it: the cv:: conversions are now header-only. C++ applications that pass cv::Mat to ImmVision define IMMVISION_HAS_OPENCV and link OpenCV by themselves:
find_package(OpenCV REQUIRED)
target_compile_definitions(my_app PRIVATE IMMVISION_HAS_OPENCV)
target_link_libraries(my_app PRIVATE opencv_core)
  • IMMVISION_FETCH_OPENCV is now only a convenience that provides a minimal OpenCV to find_package(OpenCV): it does not enable the interop by itself.

Updated Dear ImGui to v1.93.0 WIP

Dear ImGui is updated to the tip of its docking branch (v1.93.0 WIP), and ImGui Test Engine to the tip of its main branch. See upstream's changelog.

Breaking change: style.curve_tessellation_tol becomes style.curve_tessellation_max_error

The new field is expressed in pixels (the old one was in squared pixels), so that it can scale with the screen density: curve_tessellation_max_error = sqrt(curve_tessellation_tol) (default: 1.12, was 1.25).

imgui.get_style().curve_tessellation_max_error = 1.12   # was: curve_tessellation_tol = 1.25

Other changes

  • Ongoing drags and slider edits can be cancelled with a right-click or Escape: the value reverts to its initial value.
  • New imgui.ItemFlags_.mixed_value: displays a mixed / indeterminate value in checkboxes, radio buttons, drags, sliders, inputs, color widgets and combos (for property editors; see "Widgets / Mixed Values" in the demo).
  • On high density screens (Apple Retina), anti-aliasing and the tessellation of circles and curves follow the framebuffer scale: shapes look slightly crisper.
  • Disabled color buttons keep the same color as enabled ones.
  • Test Engine: new TestContext.item_drag_to_pos(), TestContext.item_make_visible() and TestOpFlags_.no_wait_when_moving.

Behavior change: StackLayout clips the content of fixed-size layouts

BeginHorizontal / BeginVertical (StackLayout, by thedmd) now clip their content on the axes where they were given a fixed size. ImGui Bundle had disabled thedmd's clipping since 2024, because it hid the content submitted after a nested layout.

Visible effect: a layout created with a fixed width or height cuts the content that overflows it, instead of letting it draw over its neighbors. Axes with an automatic size (the default) are not clipped, so layouts created without a size are not affected. (This differs from thedmd's implementation, which also clips auto-sized layouts to their measured size: that cuts selection highlights and user-drawn decorations, and costs one draw command per layout.)

imgui.begin_horizontal("row", hello_imgui.em_to_vec2(12, 0))  # fixed width: 12 em
imgui.text("A long text which does not fit in 12 em")         # now cut at 12 em
imgui.end_horizontal()

imgui-node-editor: widgets inside nodes, and a fork that works with a stock Dear ImGui

The fork of imgui-node-editor was reorganised. It does not contain anything specific to ImGui Bundle anymore, it builds against a stock Dear ImGui, and it has automated tests (run in CI) and its own documentation. Dear ImGui itself does not know about the node editor anymore: it only provides two generic hooks that the editor uses.

  • Popups, combos, color pickers, tooltips and context menus opened from inside the editor work without suspend() / resume(), now also between nodes (a background context menu, for example). Code that calls suspend() / resume() keeps working.
  • New imgui_node_editor.Style.angled_links (default: True): set it to False to always draw links as a single curve.
  • get_selected_nodes(), get_selected_links(), get_action_context_nodes(), get_action_context_links() and get_ordered_node_ids() were silently limited to 1000 elements: not anymore.
  • imgui_node_editor.Config.settings_file is an Optional[str]: None means "no settings file".
  • New imgui_md.MarkdownCallbacks.can_use_child_windows. Markdown code blocks use a child window, which cannot work inside a node: they are rendered as inline code there. ImmApp sets this callback for you. If you initialize the markdown renderer without ImmApp and render code blocks inside a node, set it yourself.
  • C++: new ed::InputTextMultiline() (a multiline text field that works inside a node; ImGui::InputTextMultiline() is redirected to it inside a node, as before) and ImGuiEx::IsInsideCanvas().

Breaking change (C++): ed::Config::SettingsFile is a const char* again, as in upstream imgui-node-editor (it was astd::string). The editor keeps the pointer: keep your string alive, and assign its c_str(). String literals are not concerned, neither is Python. The hidden functions Priv_ImGuiNodeEditor_EnterCanvas() / ExitCanvas() / IsInCanvas() were removed from Dear ImGui: use ImGuiEx::IsInsideCanvas().

static std::string settingsFile = MySettingsFolder() + "/nodes.json";   // must outlive the editor
config.SettingsFile = settingsFile.c_str();                             // was: config.SettingsFile = settingsFile;

Behavior change: ImVec in, ImVec out for the multi-float widgets

slider_float2/4, input_float2/4, color_edit3/4 and color_picker3/4 now return an ImVec2 / ImVec4 when they are given one, as the stubs always said. Until now they returned a list in that case. Lists and tuples still return a list.

color = imgui.ImVec4(1, 0, 0, 1)
changed, color = imgui.color_edit4("color", color)   # color is still an ImVec4 (was a list)

Breaking changes

  • C++: ed::Config::SettingsFile is a const char* again (see the imgui-node-editor section above).
  • imgui.set_drag_drop_payload(type, data, sz) was removed: it took a raw buffer and was not usable from Python. Use imgui.set_drag_drop_payload_py_id() (see demo_drag_and_drop.py).
  • Some errors are now reported with a more specific exception (ValueError, IndexError) where they used to raise a RuntimeError coming from an IM_ASSERT (for example ImVec2.from_dict() with a missing key, or an out-of-range color index).

Updated bundled libraries

  • ImGuiColorTextEdit: updated to upstream's master branch (the future branch is now merged there). East Asian wide glyphs (CJK characters take two grid cells), custom line number rendering (set_custom_line_number_renderer() with the new TextEditor.CustomLineNumber), set_text() from a list of lines, find_word_start() / find_word_end() plus a whole_word option on add_next_occurrence() / select_all_occurrences(), is_mouse_pos_over_text_area(), a default align_middle alignment for scroll_to_line(), and clear_change_callback() / clear_transaction_callback() to deactivate a callback (passing None was documented but never worked from Python). Upstream fixes: crash on empty text, double click word selection, autocomplete window scrolling, and more editing shortcuts. Upstream's unicode set_text() / get_text_as_*() overloads (std::wstring, std::u16string) are not bound: Python str already goes through the UTF-8 API.
  • ImAnim: updated to upstream's main branch. Grid stagger (stagger_grid_opts, stagger_grid_delay(), stagger_grid_delay_index(), with the new stagger_from and stagger_axis enums), play_with_delay(), clip.set_stagger_ease() and clip.set_loop_delay(), new clip callbacks clip.on_loop() (receives the instance id and the loop index) and clip.on_pause(), instance.restart() / reset() / refresh(), and two new tween policies (policy.additive, policy.multiply).

Fixes

  • Hello ImGui: hello_imgui.load_user_pref() gives back the value as saved by save_user_pref(). It came back with a trailing newline from the second run on: each write of the ini file added a newline to its last part.
  • ImDrawData.cmd_lists_count is back, as a read-only property. Dear ImGui 1.92.9 made CmdListsCount obsolete, and it had disappeared from the bindings in v1.92.900, which broke third party renderers such as wgpu's imgui backend (AttributeError: 'ImDrawData' object has no attribute 'cmd_lists_count'). New code should use len(draw_data.cmd_lists).
  • imgui.set_window_focus("window name") crashed; imgui.set_window_focus(None) removes the focus.
  • imgui.color_picker4() did not accept a list.
  • ImColor.to_dict() returned the red component for all keys; ImColor.from_dict() returned an ImVec4.
  • imgui.internal.input_text_ex() rejected every call ("incompatible function arguments").
  • Pure Python pygame backend (python_backends/pygame_backend.py): copy / cut / paste / select all / undo / redo work (their keys were not forwarded to imgui), the system clipboard is used (via pygame.scrap), and double clicks are detected (imgui's clock ran faster than the wall clock at high frame rates).
  • imgui.get_clipboard_text() crashed when the clipboard was empty and no backend was installed; it always returns a str ("" when empty).
  • imgui.color_picker4() with a list: ref_col is a list of 4 floats (it was declared as a single float, and read out of bounds).
  • An exception raised inside a Python clipboard / open-in-shell callback is reported ("Exception ignored in...") instead of unwinding through Dear ImGui.
  • ImFont.calc_word_wrap_position_python() returns an index in the str (so that text[:index] is what fits). It returned an offset in the UTF-8 bytes, which was wrong for any non-ASCII text.
  • Stubs: the default of format arguments reads "%.3f" (it was truncated to "%.3"; the runtime default was always right).
  • imgui.internal.get_current_window() raises an exception instead of crashing when called without a context or outside a frame.
  • Hello ImGui, Vulkan backend:
    • a texture is destroyed only once the device is idle (at exit, the app could end with VK_ERROR_DEVICE_LOST); the surface is destroyed at exit; VK_KHR_portability_subset is enabled when available (MoltenVK); textures do not keep their staging buffer.
    • fps_idling.vsync_to_monitor is implemented (it was only implemented with OpenGL).
    • screenshots are implemented (hello_imgui.final_app_window_screenshot(); C++: FinalAppWindowScreenshotRgbBuffer(), AppWindowScreenshotRgbBuffer()).
    • Vulkan errors raise an exception with the name of the VkResult (they called abort()).
    • new CMake option HELLOIMGUI_VULKAN_VALIDATION: enables the validation layers.

C++: installable CMake package, and notes for packagers

  • The CMake package is now named imgui_bundle (was imgui-bundle): find_package(imgui_bundle CONFIG REQUIRED) then imgui_bundle_add_app(...) or target_link_libraries(app PRIVATE imgui_bundle::imgui_bundle). cmake --install produces a single relocatable package (lib/cmake/imgui_bundle/) which includes hello_imgui and all bundled libraries under the imgui_bundle:: namespace. Likewise, hello_imgui's own CMake package is now hello_imgui (was hello-imgui; the former name still works through a deprecated shim).
  • plutovg and plutosvg are now git submodules of hello_imgui (external/hello_imgui/hello_imgui/external/plutosvg), no longer downloaded at configure time; they are included in the srcs-full release archive.
  • Packagers (conda, vcpkg, distributions): set HELLOIMGUI_USE_SYSTEM_PLUTOSVG=ON to link an installed plutosvg (with freetype support) instead of the submodule. It is ON automatically when IMGUI_BUNDLE_PYTHON_USE_SYSTEM_LIBS is set (i.e. under CONDA_BUILD), so the conda-forge patch that swapped in the system plutovg/plutosvg is no longer needed.

v1.92.900

Updated Dear ImGui to v1.92.9b

See release info for v1.92.9 and v1.92.9b (includes the post-release fix for ImDrawData::CmdListsCount).

Behavior change: keyboard edits of scalar widgets apply on validation

Typing a value into InputInt, InputFloat, DragXXX or SliderXXX no longer writes intermediate values to the backing variable at each keystroke: typing "123" now yields a single change to 123 on Enter / tab-out / deactivation, instead of 1, then 12, then 123. In Python:

changed, value = imgui.input_int("int", value)  # changed becomes True on validation only

Text inputs keep the previous behavior. Both are configurable via the new imgui.ItemFlags_.live_edit_on_input_scalar / live_edit_on_input_text with imgui.push_item_flag(); see "Widgets/Live Edit Flags" in the demo.

Breaking changes

  • imgui.set_color_edit_options(flags) was removed: write imgui.get_io().config_color_edit_flags = flags instead.
  • imgui.DragDropFlags_.source_auto_expire_payload (obsoleted in 2024) was removed: use payload_auto_expire.

Other additions

  • imgui.open_popup() and imgui.open_popup_on_item_click() now return a bool (True when the popup was just opened).
  • imgui.get_item_clicked_count_with_single_click_delay() and io.mouse_single_click_delay: disambiguate single-click from double-click.
  • imgui.ColorEditFlags_.picker_no_rotate: fix the S/V triangle in the hue-wheel picker.
  • Settings aging: ini entries record their last-used date; io.config_ini_settings_auto_discard_months can discard stale ones (see also io.config_ini_settings_save_last_used_date).

New: terminal emulator widget for Python (imgui_bundle.imgui_terminal)

A pyte-based terminal emulator widget, usable in any ImGui Bundle app:

  • TerminalView renders a VT100 screen and handles keyboard and mouse input: word/line selection, right-click paste, Alt as Meta, and correct handling of modified keys (Shift-Tab, Ctrl-Space, modified arrows).
  • A transport feeds bytes to the view: LocalShellTransport runs a local shell behind a pty (POSIX); the demos add SSH and websocket transports implementing the same two-method TerminalTransport protocol.
  • Requires the pyte package: pip install "imgui-bundle[terminal]".
  • See demo_terminal.py in the demo launcher (tab bar with multiple sessions, confirm-exit dialog), and demos_python/demos_terminal/ for the local shell, SSH and websocket variants.

New: context managers for ImPlot (imgui_bundle.implot_ctx)

Python-only, in the same spirit as imgui_ctx: implot_ctx wraps the begin/end and push/pop pairs of ImPlot, so the matching end_*()/pop_*() is called automatically.

from imgui_bundle import implot, implot_ctx

with implot_ctx.begin_plot("My Plot") as plot:
    if plot:  # the plot may be collapsed or clipped
        implot.plot_line("cos", x, y)

with implot_ctx.push_colormap(implot.Colormap_.cool):
    ...  # no need to test the value of the push_* context managers

Available for create_context, begin_plot, begin_subplots, push_style_color, push_style_var, push_colormap and push_plot_clip_rect. See demo_python_context_manager in the demo launcher. Contributed by @zaicruvoir1rominet (#473).

Updated bundled libraries

  • ImGuiColorTextEdit: followed upstream's merge of its future branch. Breaking: render() lost its border: bool parameter, replaced by child_flags: ImGuiChildFlags and window_flags: ImGuiWindowFlags (a former render(id, size, False) call becomes render(id, size)). Also adds configurable left margins (set_line_number_left_margin, set_decoration_left_margin, set_text_left_margin), quieter autocomplete, and improved minimap rendering (width is now automatic, tunable via set_mini_map_columns).
  • imgui-node-editor: configurable background grid size via StyleVar.grid_size (#470); fixed incomplete rendering of popups. Via the bundled ImGui patch, multiline text inputs inside the editor now render a preview box with a resizable edit popup.
  • Hello ImGui:
    • new runner_params.callbacks.confirm_exit (return False to cancel an exit request);
    • HighDPI font scaling now goes through style.font_scale_dpi instead of multiplying font sizes at load time (finalizes the ImGui 1.92 transition);
    • asset_file_full_path also searches the current folder.
    • added BeforeSwap callback
  • imspinner: updated to the 2026 version, with many new spinners (#483).
  • ImGuizmo: upstream bug fixes (gizmo jitter, multi-view, is_over for SCALEU, disappearing translation axis).
  • ImPlot3D: legend scrolling.
  • imgui_toggle: build fix against recent ImGui merged upstream (our fork now carries no patches).
  • ImGui Test Engine: updated (test-suite amendments for the LiveEdit change).
  • ImmVision: added ImageInterpolationMode setting

Python API: behavior changes and fixes

  • ImPlot / ImPlot3D: mismatched dtypes now raise. Plot functions that take several numeric arrays (e.g. implot.plot_scatter(xs, ys)) now raise a clear error when the arrays have different dtypes, instead of silently reinterpreting one array's bytes (an int64 index plotted against float64 values used to collapse to x=0). The error names both dtypes and suggests .astype(...) (#467).
  • ImPlotSpec / ImPlot3DSpec array fields fixed (#484): the line_colors, fill_colors and marker_* setters stored only a raw pointer, so a temporary array could be garbage-collected before rendering (wrong colors or crash), and the getter returned a pointer address instead of the array. Arrays are now kept alive for the Spec's lifetime, and the getter returns the ndarray.
  • imgui_ctx.push_font: the font_size_base_unscaled parameter is now mandatory, in line with imgui.push_font since ImGui 1.92.
  • immapp.testing.run: test engine failures (e.g. "Unable to locate item") now raise a RuntimeError carrying the engine log, instead of being silently swallowed (new raise_on_error=True parameter); engine errors are also printed live to the terminal.
  • imgui_fig (matplotlib figures): works with any matplotlib backend (no need to call matplotlib.use("Agg") anymore), fixes a crash with animated figures on matplotlib 3.11, and captures HiDPI/retina figures at the correct size.

musllinux wheels: fixed ImportError

  • musllinux (Alpine) wheels could not be imported at all (Error relocating ...: glPopAttrib: symbol not found): musl's loader resolves all symbols at import time, and the wheel was missing its libGL link. musllinux wheels are now built without the legacy OpenGL2 python backend (ImGui_ImplOpenGL2_* bindings), removing the link-time OpenGL dependency; the OpenGL3 backend is unaffected.

Pyodide: switched to Pyodide 314 (Python 3.14); wheels now published on PyPI

  • The Pyodide wheel now targets Pyodide 314.x: Python 3.14, Emscripten 5.0.3, wheel tag cp314-cp314-pyemscripten_2026_0_wasm32.
  • Thanks to PEP 783, Pyodide wheels are now published on PyPI (starting with v1.92.801): in a Pyodide 314+ environment, micropip.install("imgui-bundle") installs imgui_bundle directly from PyPI.
  • The playground and the minimal sample were updated accordingly.

Demos

  • demo_chinese_font (Python + C++): how to display non-Latin text (Chinese glyphs, font loading).
  • demo_glfw_window_manip (Python): manipulate the native GLFW window of an immapp application (maximize, center, opacity, request attention).

v1.92.800

Updated Dear ImGui to v1.92.8

See release info for v1.92.8.

Breaking changes: add_rect, add_polyline, path_stroke argument order

Dear ImGui v1.92.8 swapped the last two arguments of three ImDrawList drawing functions so that thickness (which is set explicitly far more often than flags) comes first. The bindings track this change.

For Python users — the affected methods on imgui.ImDrawList:

Method Old signature New signature
add_rect (p_min, p_max, col, rounding, flags, thickness) (p_min, p_max, col, rounding, thickness, flags)
add_polyline (points, col, flags, thickness) (points, col, thickness, flags)
path_stroke (col, flags, thickness) (col, thickness, flags)

If you use only positional arguments and pass 5+ of them, swap the last two:

# Before
draw_list.add_rect(p0, p1, col, rounding, imgui.ImDrawFlags_.none.value, 1.5)
draw_list.path_stroke(col, imgui.ImDrawFlags_.closed.value, thickness)

# After
draw_list.add_rect(p0, p1, col, rounding, 1.5, imgui.ImDrawFlags_.none.value)
draw_list.path_stroke(col, thickness, imgui.ImDrawFlags_.closed.value)

Old-order calls will not silently misrender — they are caught by one of three mechanisms:

  1. Static type-check (recommended). Running mypy or pyright once after upgrading flags every call that passes a float literal where the new signature expects flags: int:
    Argument of type "float" cannot be assigned to parameter "flags" of type
    "ImDrawFlags" in function "add_rect"
    
  2. Runtime, float thickness. pybind11 refuses to convert float→int, so add_rect(..., flags=ALL, thickness=2.0) written in the old order raises TypeError immediately.
  3. Runtime, int thickness. When both arguments are ints (e.g. thickness=2), the swapped value lands in flags and trips ImGui's own guard (flags & ImDrawFlags_InvalidMask_) == 0, raising:
    RuntimeError: IM_ASSERT(... "Incorrect parameter. Did you swapped
    'thickness' and 'flags'?")
    
    The mask reserves bits 0-3 specifically to catch this swap: any small integer thickness ends up with bits 0-3 set, while every valid flag uses only bits 4-9.

In practice this covers every realistic old-order call site, so no extra detection layer is added on the Python side.

For C++ users — same swap on ImDrawList::AddRect, ImDrawList::AddPolyline and ImDrawList::PathStroke. See the upstream ImGui v1.92.8 changelog for the full rationale; the short version is that the typical call site changes from:

// Before
draw_list->AddRect(p_min, p_max, col, rounding, ImDrawFlags_None, border_size);
// After
draw_list->AddRect(p_min, p_max, col, rounding, border_size);

When IMGUI_DISABLE_OBSOLETE_FUNCTIONS is off (the default), ImGui keeps an inline redirection so old call sites still compile; with it on (as in the ImGui Bundle Python build), the old overloads are =delete, surfacing mistakes at compile time.

Updated ImGuiColorTextEdit (architecture refactor)

ImGuiColorTextEdit was rebased on its upstream future branch, which introduces a layered architecture (Document / TypeSetter / Colorizer / Bracketeer / LineFold / MiniMap / AutoComplete overlays) and lays the groundwork for word wrap, line folding, and a VSCode-style minimap.

The public C++ API changed in ways that propagate to the Python bindings. All cursor/selection coordinates now go through dedicated structs instead of (line, column) integer pairs, and column is renamed to index in the document-coordinate struct (rows differ from lines once word-wrap is enabled).

Breaking changes: TextEditor API

For Python users — the most common call sites:

Before After
editor.get_main_cursor_position().column editor.get_main_cursor_position().index
editor.set_cursor(line, col) editor.set_cursor(TextEditor.DocPos(line, col))
editor.select_region(sl, sc, el, ec) editor.select_region(TextEditor.DocPos(sl, sc), TextEditor.DocPos(el, ec))
editor.get_word_at_screen_pos(pos) editor.get_word_at_mouse_pos(pos)
editor.grow_selections_to_curly_brackets() editor.grow_selections()
editor.shrink_selections_to_curly_brackets() editor.shrink_selections()
editor.get_first_visible_line() / get_last_visible_line() editor.get_first_visible_row() / get_last_visible_row()

Context-menu and hover callbacks now receive a PopupData object instead of (line, column) integers:

# Before
def text_context_menu(line: int, column: int):
    ...
editor.set_text_context_menu_callback(text_context_menu)

def line_number_context_menu(line: int):
    ...
editor.set_line_number_context_menu_callback(line_number_context_menu)

# After
def text_context_menu(data: TextEditor.PopupData):
    line, column = data.pos.line, data.pos.index
    ...

def line_number_context_menu(data: TextEditor.PopupData):
    line = data.pos.line
    ...

For C++ users — same shape, with TextEditor::DocPos{line, index} and TextEditor::PopupData& data. Line/column counters are now size_t (use %zu in printf-style format strings).

Test Engine: safer Python integration

  • Catch Python exceptions in test_func / gui_func / teardown_func. Previously a Python exception in one of these callbacks propagated as nanobind::python_error on the engine's coroutine thread, hit std::terminate, and killed the process (taking remaining queued tests with it). Exceptions are now printed as a traceback, reported via ImGuiTestEngine_Error (test marked as TestStatus.error), and swallowed so the engine continues.
  • imgui_test_engine CrashHandler: install SA_RESETHAND on *nix to avoid abort() reentry spam.
  • Fix imgui_bundle.imgui.<submodule> imports (e.g. imgui.test_engine).

imgui-node-editor

  • Suppress hover/active for widgets inside a node that is covered by another node.
  • Fix popup position for Combo and ColorEdit inside the node editor canvas (three coords needed canvas→screen translation; the right guard is NextWindowData.HasFlags, not WindowFlags).
  • Link color now automatic, based on light vs dark theme.
  • UpdateNodeEditorColorsFromImguiColors(): improve colors, especially selection colors.
  • README: documented keyboard/mouse interactions; added doc in the header.

ImmVision

  • Clamp images so their texture does not bleed when dragged completely outside the viewport.
  • Improved resize: widget size, contrast, and behavior in a zoomed node editor.

ImGui (StackLayout patch)

  • StackLayout: don't inflate measured_size when the layout has no springs (fixes fractional-height alignment drift in some layouts).

Pyodide / Playground

  • Switched to pyodide 0.29.4.
  • New WebGL binding for Pyodide: webgl.register_texture / webgl.unregister_texture. Use it inside HelloImGui's custom_background to upload textures produced from JS-side WebGL2RenderingContext. See pyodide_projects/projects/playground/examples for documented examples.
  • Playground: added documented WebGL examples, source link on the minimal example, and restore the landing page on browser back-to-root.
  • Added implot_demo, implot3d_demo, and imgui_demo to the playground.
  • New "WebAudio minimal beep" example demonstrating browser audio from Python.
  • Save Python code to a file before running it (for nicer tracebacks).
  • Per-file deployment of demo source into the Emscripten FS (imgui_bundle_add_demo.cmake).
  • Non-blocking loading banner over the canvas, with explanatory text, smooth time-based progress, rotating tips, and a lazy pendulum video.
  • Smooth progress bar for per-demo wheel installs; snap back to 0 when the banner reopens.
  • Pyodide + LaTeX: fix issues on consecutive runs.
  • min_pyodide_app: log errors to the JS console.

Demos

  • demos_implot, demos_imgui, demos_implot3d: use a handmade window where appropriate.
  • Pendulum demo: smaller trails for better FPS.

Python backends

  • Fix SDL python backends on Wayland (#463).
  • Move the PyOpenGL Wayland workaround out of imgui_bundle/__init__.py (#321, #463): applied only by the affected backends.

v1.92.700

Updated Dear ImGui to v1.92.7

See release info for v1.92.7.

imgui-bundle.pages.dev: a new website to host the doc & demos

The docs and demos were relocated to a new and faster server, with new URL addresses. The new URL are also much easier to remember.

(Note: all previous url will now automatically redirect to the new urls)

ImPlot v1.0 - Per-index color/size support

  • Updated ImPlot to v1.0
  • ImPlotSpec: numpy array support for per-index color/size fields (fill_colors, line_colors, marker_fill_colors, marker_line_colors, marker_sizes)

ImPlot3D v0.4 - Per-index color/size support

  • Updated ImPlot3D to v0.4
  • ImPlot3DSpec: same numpy array fields as ImPlot
  • New Python demo: Per-Index Colors (colorful lines, scatter, triangles, quads, Gouraud-shaded duck)
  • Refactored Custom Per-Point Style demo to use batched per-index arrays

Markdown Rendered Improvements

Added LaTeX math rendering

LaTeX math is now supported in the Markdown renderer, using the new imgui_microtex library (native rendering via MicroTeX + FreeType). Enable it with AddOnsParams.with_latex = True.

  • Inline $...$ and display $$...$$ math in Markdown
  • Python bindings for imgui_microtex
  • Pyodide: lazy-download LaTeX fonts via jsdelivr
  • Frame-generation cache eviction (default 60 frames)

Markdown: HTML and CommonMark extensions

  • Task lists: - [ ] / - [x]
  • GitHub-style admonitions: > [!NOTE], > [!WARNING], > [!TIP], etc.
  • Permissive autolinks (bare URLs become links; opt-out available)
  • Inline HTML spans: <sub>, <sup>, <kbd>, <mark>, plus an OnHtmlSpan callback for custom spans
  • <details> / <summary> collapsibles
  • <pre> blocks
  • <img> tags with width/height, async download (desktop via libcurl, Pyodide via JS fetch)

Other Markdown improvements

  • Fix word wrapping issues around transitions between bold/italic and normal
  • Make spacing between blocks, headers and paragraphs more coherent
  • Adaptive code snippet colors: new SnippetTheme::Auto picks dark or light based on current ImGui theme
  • TextEdit no longer shows a caret in coded blocks.

Pyodide / Playground

  • New online playground with live code editing and demos
  • Clipboard support (SDL2 + Emscripten)
  • immapp.download_url_bytes / immapp.download_url_bytes_async
  • Pin pyodide-build version to pyodide version
  • Lazy import for pydantic types
  • numpy is now optional (no runtime dependency)

ImGuiColorTextEdit: switched to goossens rewrite (breaking API changes)

Replaced the santaclose-based ImGuiColorTextEdit with the complete rewrite by Johan A. Goossens. This brings a cleaner architecture, proper UTF-8 support, C++17, no regex/boost dependency, and many new features.

New features

  • Find/replace UI with keyboard shortcuts
  • Text markers (colored line highlights with tooltips)
  • Bracket matching with visual indicators
  • Line decorators (custom gutter content per line)
  • Context menu callbacks (separate for line numbers and text area)
  • Change and transaction callbacks
  • Filter selections/lines (transform text via callbacks)
  • Autocomplete framework
  • TextDiff widget (combined and side-by-side diff view)
  • Many more languages (C#, JSON, Markdown, AngelScript)

Breaking API changes (Python)

Old New
TextEditor.PaletteId.dark TextEditor.get_dark_palette()
TextEditor.PaletteId.light TextEditor.get_light_palette()
TextEditor.PaletteId.retro_blue (removed)
TextEditor.PaletteId.mariana (removed)
TextEditor.LanguageDefinitionId.cpp TextEditor.Language.cpp()
set_language_definition(id) set_language(Language.cpp())
set_cursor_position(line, col) set_cursor(line, col)
set_view_at_line(line, mode) scroll_to_line(line, alignment)
get_selected_text(cursor) get_cursor_text(cursor)
get_cursor_position() -> TextPosition get_main_cursor_position() -> CursorPosition
render(title, border, size) -> bool render(title, size, border) -> None
undo(steps) / redo(steps) undo() / redo() (no steps)
SnippetTheme.retro_blue / .mariana (removed)

To detect text changes, use set_change_callback(callback, delay_ms) instead of the old render() return value.

See the breaking changes note at the top of imgui_color_text_edit.pyi for a quick summary.

Breaking API changes (C++)

Same renames as Python (CamelCase). Additionally:

  • Render() parameter order changed: (title, size, border) instead of (title, border, size)
  • Render() returns void instead of bool

hello_imgui

  • Add emscriptenAllowBrowserZoomShortcuts preference: forward browser zoom shortcuts (Ctrl+/Ctrl-) to the browser, true by default
  • Add ImageAndSizeFromEncodedData and LoadImageDataFromEncodedData for loading images from in-memory encoded data
  • IniFolderLocation on Emscripten: return "" for CurrentFolder, "/" for others
  • LoadDefaultFont_WithFontAwesomeIcons: log a message if the icon font file is not found (instead of silently failing)
  • Skip TearDown if it already ran at exit (e.g. if it threw an exception itself)
  • Suppress GCC false positive -Wstringop-overflow in stb_image
  • Document theming API

Test Engine: interaction and screenshot tooling

New helpers for driving an ImGui app from Python (or C++) and capturing screenshots, useful for visual self-validation and automated testing.

  • New immapp.testing module: high-level helpers to interact with widgets and capture screenshots
  • Bind imgui_capture_tool.h for Python; add CaptureSetFilename
  • HelloImGui::OpenglScreenshotRgb: report an explicit error if capture fails

ImmVision

  • Fix colormap rendering for single-channel images
  • Improve draw pixel values: better text contrast against background
  • Fix zoom synchronization between linked views
  • Polish overall look
  • Add license file

Other library updates

  • Updated ImCoolBar, ImGuizmo, ImAnim, nanovg, ImFileDialog, imgui_tex_inspect, md4c

Build & CI

  • MSVC: add /bigobj for implot (fixes Windows ARM64 wheel build)
  • CMake: refuse in-source builds
  • CI: add win64 wheels, bump cibuildwheel/pypi-publish/deploy-pages/upload-pages-artifact
  • Fix ImGui StackLayout fractional-height alignment drift

Python bindings & API fixes

  • Expose TextFilter.input_buf property (#451)
  • imgui_explorer: show im_anim.pyi in Python (#406)
  • Fix get_style_color_vec4 / color_convert_rgb_to_hsv bindings
  • register_demos_assets_folder() helper
  • async runners: fix an issue where immapp.run_async could use 100% CPU (cf #460) Improve handling of sequential async runs in notebooks.

Documentation

  • Developer docs: fork management, justfile workflows, bindings, Pyodide
  • FAQ review, Nuitka compatibility docs
  • Interactive explorable demos

v1.92.601

ImmVision: OpenCV is now optional / use GPU rendering pipeline

ImmVision no longer requires OpenCV: this way the compilation and installation of the library is much faster, and the resulting binaries are smaller.

All image processing (color conversion, statistics, alpha blending, drawing annotations, zoom/pan transform, image saving) has been reimplemented without OpenCV dependencies.

  • New core types: ImageBuffer, Point, Point2d, Size, Matrix33d replace cv::Mat and OpenCV geometric types in all public APIs
  • Zero-copy interop: When OpenCV is available (IMMVISION_HAS_OPENCV), cv::Mat converts seamlessly to/from ImageBuffer via implicit constructors
  • Python: No change for Python users — ImmVision continues to use numpy arrays (the cvnp_nano bridge has been removed)
  • Drawing primitives: Custom bitmap font and Bresenham drawing replace OpenCV's putText, line, ellipse, rectangle
  • Image saving: Uses stb_image_write (PNG/JPG/BMP/TGA/HDR) instead of cv::imwrite
  • Zoom/pan: Custom implementation with nearest, bilinear, and area-based downscaling
  • ImmDebug API change: ImmDebug() now assumes RGB (the common default); use ImmDebugBgr() for OpenCV BGR images. Fixed per-image color order handling in the viewer.
  • Smaller wheels: ~16% size reduction across all platforms (45 MB total savings)
  • Faster CI builds: 5–8 minutes faster per platform (no more OpenCV compilation)
  • New features: colormap support for single-channel integer images, multithreaded pixel drawing/resize, fixed watched pixel delete button visibility

The ImmVision rendering pipeline has been rewritten to use GPU texture sampling and ImGui DrawList:

  • GPU zoom/pan: Image uploaded to GPU texture once (with mipmaps); pan/zoom handled via UV coordinates — no more per-frame CPU warp
  • Mipmap filtering: GL_NEAREST at high zoom (pixel-perfect), GL_LINEAR for moderate zoom, GL_LINEAR_MIPMAP_LINEAR for downsampling (high-quality anti-aliasing)
  • DrawList annotations: Grid lines, pixel values, and watched pixel markers drawn via ImGui DrawList in screen space (TrueType font replaces bitmap font)
  • DrawList backgrounds: School paper and alpha checkerboard rendered via DrawList (no longer composited into texture)
  • Inspector redesign: Horizontal filmstrip with scrolling and adjustable thumbnail size replaces the old vertical listbox
  • Other fixes: "Export colormap image" now available for uint8 images with colormap; save dialog remembers last directory

demo_imgui_bundle (aka "Dear ImGui Bundle Explorer")

  • Display version and compilation time at startup (C++, emscripten and Python versions)
  • Python demo code is also shown in the python version (when installed from Pypi)

hello_imgui

  • Fix potential memory error in font handling (_LoadFontImpl: pass font buffer allocated with IM_ALLOC)
  • Add HelloImGui::LoadImageDataFromAsset() — decode an image from assets into CPU memory (C++ only)
  • Compile imgui_impl_metal.mm and MetalNanoVG with -fobjc-arc (fixes ARC bridge cast warnings)
  • Workaround plutovg file(RELATIVE_PATH) error with relative CMAKE_INSTALL_PREFIX (scikit-build-core)

Build & warnings cleanup

We are approaching zero-warnings.

  • CMake: fetch freetype & plutovg with EXCLUDE_FROM_ALL
  • CMake: fix ImAnim exclusion when IMGUI_BUNDLE_WITH_IMANIM_FULL_DEMOS is off
  • CMake: ibd_add_this_folder_as_demos_library now links demo_utils (fixes GCC linker error)
  • CMake: suppress Apple ld duplicate library warnings
  • CMake: suppress third-party warnings (ImAnim: -Wno-unused-result, -Wno-nontrivial-memaccess; plutosvg: -Wno-deprecated-declarations)
  • CMake: normalize install path (./lib/ → lib) to fix CMP0177 warning
  • Fix ImFileDialog u8path deprecation warning (C++20 compatibility)
  • Fix GCC -Wformat-truncation warning in demo_imgui_bundle_intro.cpp

v1.92.600

Based on ImGui v1.92.6 & hello_imgui v1.92.6.

Dear ImGui Bundle Explorer (formerly "ImGui Bundle Interactive Manual")

The interactive manual has been renamed to Dear ImGui Bundle Explorer and significantly enhanced:

Dear ImGui Explorer

Dear ImGui Explorer (formerly "imgui_manual") has been rewritten from scratch and integrated into the Dear ImGui Bundle repository. It was previously a standalone project; Dear ImGui Bundle is now its parent repository.

It provides interactive manuals for ImGui, ImPlot, ImPlot3D, and ImAnim — with side-by-side C++/Python code, syntax highlighting, and search in API reference files (headers, Python stubs).

  • Follow source: click on any demo widget to jump to its source code
  • Search across API files with Ctrl+Shift+F
  • Lazy-load demo code files (desktop and Emscripten)
  • Deployed at pthom.github.io/imgui_explorer

New library: ImAnim

Added ImAnim, a tweening and animation library for ImGui.

  • Available via immapp.run(..., with_im_anim=True) / ImmApp::AddOnParams::withImAnim
  • Python API adapted for get_float, get_vec2, get_color, etc.

Updates to libraries

  • Update imgui to v1.92.6-docking
  • Update hello_imgui to v1.92.6
  • Update implot to latest version (breaking change: added ImPlotSpec, removed plot item styling)
  • Update implot3d to latest version (breaking change: added ImPlot3DSpec)
  • Update ImGuiColorTextEdit: line numbers always visible in separate gutter, improved selection colors
  • Update imgui_knobs: added SetKnobColors, UnsetKnobColors, default color adapts to light/dark theme
  • Update imgui_md: render tables using ImGui tables (resizable columns), delay before showing link hrefs

Python: Async run and notebook support

Pyodide (web) support

  • Added Docker build system for Pyodide wheels
  • run() is fire-and-forget in Pyodide; use run_async() for awaitable behavior
  • CI workflow for Pyodide builds
  • Pyodide wheels now exclude demo code to reduce size

Python bindings

  • Added em_size() and em_to_vec2() at root of imgui_bundle for DPI-independent sizing
  • Added __getitem__ / __setitem__ (subscript []) for ImVec2 and ImVec4
  • Configurable wheel builds with selective module inclusion
  • Fix: accept read-only numpy arrays (e.g. from pandas) in nanobind bindings

hello_imgui improvements

  • Added AddAssetsSearchPath() / ClearAssetsSearchPaths() / GetAssetsSearchPaths() for multi-folder asset resolution at runtime
  • Added topMost window attribute
  • Added iniDisable and iniClearPreviousSettings params
  • Added FpsIdling::vsyncToMonitor and FpsIdling::fpsMax settings
  • Added theme_changed callback
  • Fix: ManualRender RunnerParams lifetime management

Build & CI

  • Added ARM Linux (aarch64) wheel builds using native ubuntu-24.04-arm runners
  • Reduced Emscripten .data sizes: demos only bundle the assets they actually need
  • Deduplicated demo assets (removed ~1.1M of files duplicated between assets/ and demos_assets/)
  • Emscripten: use GLFW3 backend by default instead of SDL2
  • Fix: shell injection in BrowseToUrl (replaced system() with fork+execlp)

Documentation

  • Complete documentation overhaul using Jupyter Book, available as PDF
  • Added developer documentation (building, bindings, repo structure)

v1.92.5

This version is based on ImGui v1.92.5 & hello_imgui v1.92.5.

Updates to libraries

  • Updates imgui to v1.92.5-docking
  • Update imgui_test_engine to v1.92.5
  • update hello_imgui to v1.92.5
  • update implot to latest version
  • update implot3d to latest version
  • update ImGuizmo to latest version
  • update ImCoolbar to latest version

Python bindings

  • most pip dependencies are now optional: only numpy is required. Pydantic, PyOpenGL, glfw, Pillow, matplotlib, and opencv-python are optional (if you use features that require them)
  • Vec2Protocol and Vec4Protocol are iterable / unpackable
  • import immapp_notebook.run_nb only if IPython is installed
  • option IMGUI_BUNDLE_PYTHON_DISABLE_OPENGL2 (Off by default): can disable Python backend support for OpenGL2
  • Update wgpu example to use wgpu latest API (compatible with v1.92)
  • Implot & ImPlot3d: fix bindings for setup_axis_ticks

Tooling

  • Fix pyodide build (force build sdl2 and libthtml5 with -fPIC)

v1.92.4

This version is based on ImGui v1.92.3, and brings some small fixes.

  • InputTextMultiline: when inside imgui-node-editor, improve handling of single preview
  • imgui-node-editor: solve clipping issue which occur when a popup is open inside a node

v1.92.3

Updates to libraries

ImGui:

  • Updates imgui and imgui_test_engine to v1.92.3

hello_imgui:

  • update to v1.92.3
  • add SetLoadAssetFileDataFunction (and python binding): a way to customize asset loading

imgui_md:

  • fix line wrapping (thanks to @bgribble). cf #366

imgui-knobs, ImGuizmo, imgui_toggle:

  • update to latest version

ImGuiColorTextEdit:

  • update to latest version (from santaclose fork)

Python bindings:

ImGui bindings:

  • ImGui Enums now use 'enum.IntFlag' (This impacts only the typing checks, not the runtime behavior) This means that you may replace code like:
imgui.WindowFlags_.no_collapse.value | imgui.WindowFlags_.no_decoration.value

with:

imgui.WindowFlags_.no_collapse | imgui.WindowFlags_.no_decoration
  • imgui.push_font (accepts optional font)
  • Improve typing for ImVec2 and ImVec4 (use different protocols. Thanks to @joegnis)

Pure Python Backends

Pure Python Backends

  • Fix pygame backend (thanks Dom Ormsby)
  • Fix issue when pasting with glfw backend (thanks to @sunsigil)

Other

  • ImGuizmo:handle deltaMatrix / document Manipulate API

v1.92.0

Starting with v1.92.0, version numbers are now synced between "Dear ImGui", "Hello ImGui" and "Dear ImGui Bundle"

ImGui

v1.92.0: Scaling fonts & many more (big release)

  • Many Font related changes: this release brings many changes on the ImGui side (v1.92.0): do read the release notes for ImGui v1.92.0 TLDR: Fonts may be rendered at any size. Glyphs are loaded and rasterized dynamically. No need to specify ranges, prebake etc. GetTexDataAsRGBA32() is now obsolete.

Python bindings

  • Potentially breaking change for extern pure Python backends: font_atlas_get_tex_data_as_rgba32 was removed (read the advice below)
  • Font-related changes, following ImGui v1.92.0
  • Fix ImPlot stubs (thanks @tlambert03)
  • Fix imgui_ctx and imgui_node_ctx
  • pure python backends: split opengl implems, implement texture update in python pure opengl backends
  • imgui bindings => publish texture related infos

Advice for extern pure Python Backends (wgpu, etc.)

Since v1.92, font_atlas_get_tex_data_as_rgba32 was removed. Backends will need to be adapted by implementing support for dynamic fonts (preferred)

Extract from ImGui doc: ImGui Version 1.92.0 (June 2025), added texture support in Rendering Backends, which is the backbone for supporting dynamic font scaling among other things. In order to move forward and take advantage of all new features, support for ImGuiBackendFlags_RendererHasTextures will likely be REQUIRED for all backends before June 2026.

Read ImGui backend doc: flag ImGuiBackendFlags_RendererHasTextures (1.92+) (read the part "Rendering: Adding support for ImGuiBackendFlags_RendererHasTextures (1.92+)"). For inspiration, look at

    def _update_texture(self, tex: imgui.ImTextureData):

inside ImGui Bundle (bindings/imgui_bundle/python_backends/opengl_base_backend.py)

Pyodide

  • Added support for Pyodide

v1.6.3

ImGui

  • update imgui to v1.91.9b
  • Python: adapt API for ImFont:: CalcWordWrapPositionA (cf #308)

Fixes

  • update imgui_md (fix soft break handling). Cf #306
  • ImGui / Python: adapt API for ImFont:: CalcWordWrapPositionA (cf #308)
  • Fix documentation rendering (cf #316)
  • Fixes for compat with CMake 4

ImPlot

  • update implot
  • Add implot_demo.py (full python transcription of implot_demo.cpp)
  • add demo_implot_stock.py
  • python Bindings: improve setup_axis_ticks

ImPlot3d

  • Update implot3d: added PlotImage & bindings
  • implot3d_demo.py: provide nice demo textures
  • add implot3d_demo.py: full transcription of implot3d_demo.cpp
  • improve python bindings
  • adapt bindings for PlotMesh (cf #320)
  • manual bindings for setup_axis_ticks

Pure Python Backends

  • Review keyboard handling
  • Sdl: handle SDL_GL_MakeCurrent errors
  • Add SDL3 python backend
  • Add an example using wgpu (WebGPU for Python)

ImmVision

  • update immvision (fix for compat with OpenCV 4.11)

ImGuizmo

  • update ImGuizmo to v1.91.3
  • Fix customization of styles (cf #329)

ImGuiColorTextEdit

  • Update ImGuiColorTextEdit (from santaclose fork)

ImGuiMd

  • fix soft break handling. Cf #306

v1.6.2

New library: ImPlot3D

  • The excellent ImPlot3D library is now included!

Fixes

  • Fix #293: IM_ASSERT( g.CurrentDpiScale > 0.0f && g.CurrentDpiScale < 99.0f )
  • Fix initial window positioning / HighDPI on windows (demo window origin was offscreen)

Build

  • Some fixes for conda-forge package

Python

  • make it possible to recover from exceptions in notebooks
  • preliminary work on pyodide support

v1.6.1

ImGuizmo

  • Breaking change on ImGuizmo Python API: Added classes Matrix3/6/16, modifiable by manipulate and view_manipulate See changes in demo_gizmo.py to see how to adapt to the new API Basically:
  • use gizmo.Matrix3 / Matrix6 / Matrix16 instead of np.array
  • gizmo.manipulate and view_manipulate will modify the matrices they receive
  • if using glm, you will to need to convert to Matrix16, see glm_mat4x4_to_float_list in demo_gizmo.py

Python

  • fix bindings for implot.plot_bar_groups
  • sdl pure backend: fix get_clipboard_text
  • patches for conda-forge package (in preparation)

iOs

  • Improved font rendering on iOS (use static freetype, use retina resolution)

v1.6.0

ImGui

  • Updated ImGui to v1.91.5

Hello ImGui: updated to v1.6.0b

  • SVG Font rendering: plutosvg replaces lunasvg (option HELLOIMGUI_USE_FREETYPE_PLUTOSVG on by default)
  • Added AddDockableWindow / RemoveDockableWindow
  • demo_docking: better demonstration / theme customization
  • Add `HelloImGui::ManualRender: a namespace that groups functions, allowing fine-grained control over the rendering process
  • Work on pyodide integration (for ImGui Bundle)
  • Improve font rendering on iOS

Node editor

  • better handle popup placement and child windows: see thedmd/imgui-node-editor#310
  • InputTextMultiline compatible with imgui-node-editor
  • Node theme colors will try to be coherent with the main theme

ImGuiMd

  • Add ImGuiMd::GetFont(const MarkdownFontSpec& fontSpec)

ImmApp

  • Add namespace Immapp::ManualRender: functions allowing fine-grained control over the rendering process

ImmVision

  • Breaking Change - October 2024: Color Order Must Be Set ImmVision now requires you to explicitly set the color order (RGB or BGR) at the start of your program. To configure the color order, you must call one of the following once before displaying images:
    • In C++: ImmVision::UseRgbColorOrder() or ImmVision::UseBgrColorOrder()
    • In Python: immvision.use_rgb_color_order() or immvision.use_bgr_color_order()
    • To enforce a temporary color order, use ImmVision::PushColorOrderBgr/Rgb() and ImmVision::PopColorOrder(). This change ensures that you are explicitly aware of the color order used throughout your program. If the color order is not configured, an error will be thrown when attempting to display images. Note: The IsColorOrderBGR member in ImageParams and the corresponding isBgrOrBgra parameter in ImageDisplay have been removed.
  • Publish GlTexture in the API
  • Refuse zoom if too extreme

Python bindings

Switched binding library from pybind11 to nanobind - Nov 2024:

This change should be almost transparent to users. However, if you encounter any issues, please report them.

Support Python 3.13

  • Binary wheels are provided for Python 3.11, 3.12, and 3.13 (3.10 is still supported, building from source)

Other

  • python glfw_backend: updated clipboard handling to new api
  • enum Key bindings: remove prefix im_gui_ in values
  • Flags enums (InputTextFlagsPrivate_, TreeNodeFlagsPrivate_, etc.): remove unwanted prefixes
  • ImFontGlyph: publish get_codepoint(), is_visible(), is_colored()
  • imgui_fig: let the user change matplotlib renderer
  • add stubs for ImVec2/4 math operators (fix #267)
  • pyglet backend: fix version checking (thks @DragonMoffon)
  • implot: fix binding for setup_axis_links()
  • delay loading PIL and matplotlib to make startup faster
  • Initial efforts to support pyodide

Demos

  • demo docking: improve demo / setup customized theme
  • demos python: do not require opencv (use pillow to load images)
  • suppressed demos / ImGuizmo curve edit (we only maintain the 3D gizmo compatibility)

v1.5.0

ImGui:

  • Updated ImGui to v1.90.9-docking
  • Added support for StackLayout: ImGui::BeginHorizontal & ImGui::BeginVertical (by @thedmd)
  • Warn if users reuse an ID (cf ocornut/imgui#7669)

Hello ImGui

See changes in Hello ImGui v1.5.0-rc1

  • add FontDpiResponsive
  • add OpenGlOptions
  • add null backends
  • Improved text rendering on windows (via improved antialiasing)
  • Can set OpenGL options in hello_imgui.ini in any parent folder
  • add InputTextResizable & WidgetWithResizeHandle
  • Logger: use less vertical space
  • add Push/PopTweakedTheme (different windows can have different themes)
  • add callback PostRenderDockableWindows
  • Polish Themes

Libraries

immvision

  • fixup Custom version of cv::warpAffine for small sizes
  • ImmVision::Image is now resizable / added ImmVision::ImageDisplayResizable
  • fix icon buttons size
  • Add option ResizeKeepAspectRatio: when resizing an image, the widget will keep the aspect ratio of the image

imgui-knobs

  • can drag knob horizontally or vertically

ImPlot

  • Add Python binding for colors (cf #221)

imgui-node-editor

  • Add ForceWindowContentWidthToNodeWidth: ImGui::TextWrapped(), ImGui::Separator(), and ImGui::SliderXXX can now fit inside a Node. See proposed fix to @thedmd here: thedmd/imgui-node-editor#298
  • The theme of the node editor can be derived and adapted automatically from ImGui Theme (see UpdateNodeEditorColorsFromImguiColors)

Python

  • imgui_fig is now resizable
  • Added binding for ColorPicker4
  • Added mathematical operators for ImVec2, ImVec4, ImColor
  • add pickle support for ImVec2, ImVec4, ImColor
  • Add eq operator to ImVec2/4/ImColor bindings
  • add pydantic support for ImVec2, ImVec4, ImColor

Build

v1.3.0

New libraries

Bundle

  • Update imgui to v1.90.1-docking
  • Update implot, imgui_test_engine, imgui-node-editor

Python

  • Release the Python GIL when rendering: improve multithreading performance (see #171)
  • Fix an issue under Ubuntu where cibuildwheel binary wheels did not work (see #170)

Hello ImGui

Fixes

  • Fix usage of ShowIdStackTool without ImGui Test Engine (see #166)
  • ImGuiColorTextEdit: added bindings for GetSelection / Fixed keyboard selection (see #169)

v1.2.1

Hello ImGui

Backends

iOS

Android

Python

Bundle

v1.1.0

3D

  • Added callback runnerParams.callbacks.CustomBackground: display any 3D scene in the background of the app: see doc Custom background

App deployment

  • Added support for macOS application bundles
  • Added option to specify where settings are saved: RunnerParams.iniFolderType can be set to: CurrentFolder, AppUserConfigFolder, DocumentsFolder, HomeFolder, TempFolder, AppExecutableFolder.
  • Support for Application Icon: the file assets/app_settings/icon.png will be used to generate the window icon (C++, Python), and app icon (C++ only) for any platform. See assets structure below:
assets/
├── world.png                         # A custom asset
├── app_settings/                     # Application settings
│         ├── icon.png                # This will be the app icon, it should be square
│         │                           # and at least 512x512. It will  be converted
│         │                           # to the right format, for each platform.
│         ├── apple/
│         │         └── Info.plist    # macOS and iOS app settings
│         │                          # (or Info.ios.plist + Info.macos.plist)
├── fonts/
│         ├── DroidSans.ttf               # Default fonts
│         └── fontawesome-webfont.ttf     #     used by HelloImGui
│         ├── Roboto
│         │    ├── Roboto-Bold.ttf        # Font used by Markdown
│         │    ├── Roboto-BoldItalic.ttf
│         │    ├── Roboto-Regular.ttf
│         │    └── Roboto-RegularItalic.ttf
│         ├── SourceCodePro-Regular.ttf
├── images
│         └── markdown_broken_image.png

Python bindings

CMake

  • hello_imgui_add_app and imgui_bundle.add_app can now accept ASSETS_LOCATION as a parameter e.g. hello_imgui_add_app(my_app file1.cpp file2.cpp ASSETS_LOCATION my_assets)

v1.0.0-beta1

Added support for ImGui Test Engine

ImGui Test Engine is a Tests & Automation Engine for Dear ImGui.

  • Can be used with python, and C++ (all platforms, incl emscripten). See python bindings declarations (stubs).
  • Enabled by default inside ImGui Bundle. Needs to be enabled manually when using Hello ImGui.
  • Lots of work on making ImGui Test Engine's coroutines (thread based) compatible with Python and emscripten
  • ImGui Test Engine is now used to run interactive automations in the interactive manual (click on the "Show me" buttons)
  • Added specific demo and doc

Note: See Dear ImGui Test Engine License. (TL;DR: free for individuals, educational, open-source and small businesses uses. Paid for larger businesses)

New library

  • Added new library: ImCoolBar

Doc

Misc

  • Python bindings stubs: add @overload everywhere when required
  • cmake: add options to run sanitizers (no warning given by any of them at this moment)
  • demo_logger: add logs at startup
  • implot python bindings: add plot_bar_groups & plot_pie_chart
  • update imgui_toggle (after merged PRs from imgui_bundle)
  • update HelloImGui: add callback BeforeImGuiRender
  • update ImmVision: can call gladLoadGl if needed (fix #134)
  • add demo imgui_example_glfw_opengl3.cpp

v0.9.0

  • Added wheels for python3.12 Submodule updates:
  • imgui-node-editor: fix suspend/resume issue
  • HelloImGui::DockingParams::focusDockableWindow() can show a window tab

v0.8.8

  • update imgui to v1.89.6 and implot to v0.17
  • Enable 32 bits ImDrawIdx for ImPlot Submodules changes:
  • ImmVision: fix exit sequence, can save colormap image
  • imgui-node-editor: fixes
  • HelloImGui: basic apps can run without font assets / can set docking options for main dock space

v0.8.7

Updates and new features

  • ImGui: updated imgui to v1.89.6 (May 2023)
  • ImGui: python bindings now can use SDL2 (glfw is of course still supported, and remains the default with Hello ImGui)
  • ImGui: Add python bindings for drag&drop
  • HelloImGui: can now handle several layouts and save settings per layout (see details below)
  • HelloImGui: can now store user defined settings in the ini file
  • HelloImGui: now remembers user choices for the theme, status bar, and fps throttling
  • HelloImGui: handle utf8 filenames for assets loading
  • ImGuiColorTextEdit is now based on @santaclose fork
  • immvision bindings: use shared memory (between python and C++) for images
  • ImPlot bindings: Add support for colormap in implot python bindings
  • ImPlot bindings: Add support for heatmaps

As always, an online interactive manual is available    

More details about layouts handling with Hello ImGui:

Layout demo

Each layout has a different spatial layout and can contain a different list of windows. Each layout also remembers the user modifications to this given layout, as well as the list of opened windows.

See this online emscripten demo of the docking and layout, the C++ demo code, and python demo code

For more explanations on how to handle complex layouts, see this video explanation on YouTube (5 minutes)

v0.8.6

Please use v0.8.7 instead

v0.8.5

Hello ImGui and ImmApp usability improvements:

  • customize menu App
  • Docking Layout: keep user preferences
  • improve windows initial layout

v0.8.3

Added python bindings for implot_internal

Minor improvements:

  • Improve font rendering
  • Improve emscripten idling mode
  • Review main theme (DarculaDarker) to make it easier on the eyes

v0.8.2

  • Autoresize window post startup
  • Corrected notebook rendering

v0.8.1

  • correct launch demo_node_editor_basic

v0.8.0

  • markdown: render code blocks with text editor, and make them easily copyable
  • add lots of demos
  • add doc / ascii_doc
  • add emscripten interactive manual
  • add immapp::snippets
  • add portable_file_dialogs

v0.7.2

  • Improved doc and notebook support

v0.7.1

  • Improved support for High DPI in third parties
  • Improved demos
  • Markdown now support code blocks

v0.7.0 (work in progress)

  • Added support for ImGuizmo
    • all components available in C++ (gizmo, curve, graph, sequencer, etc.)
    • added ImGuizmoPure: C++ wrappers around existing api with clearly marked inputs and outputs
    • for python: ported pure API
    • added set of twin demos showing usage with C++ and with python. A good example showing how to port features between C++ and python.
    • the following items could not be ported to python (making a pure wrapper failed): ImGradient, GraphEditor, Sequencer
  • Added support for imgui_tex_inspect, a texture inspector.
    • Added support for codeless init of imgui_tex_inspect when using ImGuiBundle runner (future ImmApp), thanks to AddOnParams::withTexInspect
  • 6ef5df64: added imgui.set_io_ini_filename() & imgui.set_io_log_filename() Manual binding for ImGuiIO::IniFilename (naked const char* pointer)
  • 778aabf3: Added imgui_bundle.em_size and visible_font_size(): In order to scale your widgets properly on all platforms, use multiples of this size. (on MacOS with retina FontGlobalScale can be equal to 2) (EmSize is an alias for VisibleFontSize)
  • f6ae2072: generate named constructors if there is no user defined constructors
  • 19ca013a: remove ImGui prefix from classes and enums => lots of API changes
  • f9210578: ImPlot bindings: remove prefix ImPlot from classes and enums
  • hardened stub typings with mypy
  • imgui.backends: replace open_gl3 by opengl3
  • immvision module now stable
  • Lots of work on the CI and wheel generation

v0.6.6

Added Immvision (image debugger and analyzer utility)

immvision will be compiled if OpenCV is available. immvision is not available by default on the pip bindings.

To add them, compile from source after having installed conan

Added theming

  • Demo
  • API
  • Default theme is now a variation on Darcula

Improve ImGui & Glfw, low level integration

Full Changelog: https://github.com/pthom/imgui_bundle/compare/v0.6.5...v0.6.6

v0.6.5

Lots of additions

Full Changelog: https://github.com/pthom/imgui_bundle/compare/v0.6.4...v0.6.5