For the Russian version, see WINDOWS-GUIDE-RU.md.
Practical guide for ImGuiX windowing with focus on:
include/imguix/core/window/WindowInterface.hppinclude/imguix/core/window/WindowInstance.hppinclude/imguix/core/window/WindowManager.ippinclude/imguix/windows/ImGuiFramedWindow.hppinclude/imguix/windows/ImGuiFramedWindow.ipp
- Quick Start Path (10 minutes)
- Which Base Class to Use
- Runtime Lifecycle and Frame Pipeline
- WindowInterface and WindowInstance API Map
- ImGuiFramedWindow Model
- WindowFlags Matrix
- ImGuiFramedWindowConfig Matrix
- Backend Capability Matrix
- Transparency Behavior Matrix
- Practical Recipes
- What to Override by Scenario
- Smoke Demo Map
- Common Gotchas
- Debug Checklist
- Choose base class:
- Use
ImGuiFramedWindowfor most operator UIs. - Use
WindowInstanceonly when you need fully custom window chrome/layout.
- Choose layout mode via flags:
- Classic layout: do not set
WindowFlags::HasCornerIconArea. - Corner layout: set
WindowFlags::HasCornerIconArea.
- Set minimal config:
title_bar_heightside_panel_width- frame strokes (
frame_stroke_thickness,frame_outer_stroke_thickness,frame_inner_stroke_thickness)
- Add only required virtual hooks:
drawTitleBarText()drawSidePanel()drawMenuBar()(only withHasMenuBar)drawCornerIcon()(only in corner mode)
- Validate with one smoke target:
cmake --build external/ImGuiX/build-mingw --target corner_icon_area_demo_v3 --parallel 36| Use case | Recommended base class | Why |
|---|---|---|
| Full custom rendering loop and custom native/chrome behavior | WindowInstance |
Lowest-level window abstraction with full lifecycle control. |
| Ready framed host window (title, side, corner icon area, control buttons) | Windows::ImGuiFramedWindow |
Builds on WindowInstance and gives reusable framed geometry/styling. |
Rule of thumb:
- Start with
ImGuiFramedWindow. - Drop to
WindowInstanceonly when framed layout rules are a limitation.
Two levels are involved:
WindowManagerorchestrates all windows.- Each
WindowInstanceprocesses its own frame.
Source: include/imguix/core/window/WindowManager.ipp.
-
prepareFrame():flushPending()initializePending()->window->fontsStartInit(),window->onInit(),window->buildFonts()removeClosed()initializeControllers()
-
processFrame()order:handleEvents()tickAll()drawContentAll()drawUiAll()presentAll()loadIniAll()saveIniAll()
Base hooks in WindowInstance:
handleEvents()tick()drawContent()drawUi()present()
ImGuiFramedWindow overrides drawUi() in backend-specific files and dispatches to:
drawClassicLayout(...)whenWindowFlags::HasCornerIconAreais not setdrawCornerLayout(...)whenWindowFlags::HasCornerIconAreais set
- Identity:
id(),name() - Size:
width(),height(),setSize(int, int) - Visibility/focus:
setVisible(bool),setActive(bool),isActive() - Open/close:
isOpen(),close() - Window state:
minimize(),maximize(),restore(),isMaximized(),toggleMaximizeRestore()
- Theme:
setTheme(std::string),themeManager() - Options:
options()(control/view) - Event bus:
eventBus() - Resources:
registry() - Notifications:
notifications()
- Font lookup:
getFont(FontRole) - Font manager access:
fontsView(),fontsControl() - Language:
langStore(),requestLanguageChange(...),applyPendingLanguageChange() - Manual atlas init API (init-only):
fontsBeginManual()fontsSetLocale(...)fontsSetRangesPreset(...)fontsSetRangesExplicit(...)fontsClearRanges()fontsAddBody(...)fontsAddHeadline(...)fontsAddMerge(...)fontsBuildNow()
iniPath()initIni()loadIni()saveIniNow()
Main customization hooks:
drawTitleBarText()drawSidePanel()drawCornerIcon()drawMenuBar()
Layout modes:
- Classic mode:
- Active when
WindowFlags::HasCornerIconAreais not set. - Title row always exists.
- Side panel exists only if
side_panel_width > 0.
- Corner mode:
- Active when
WindowFlags::HasCornerIconAreais set. - Top-left icon area is reserved.
- Side width:
side_panel_width > 0: explicit widthside_panel_width <= 0: auto width from corner parameters
Source: include/imguix/windows/window_flags.hpp.
| Flag | Effect | Notes |
|---|---|---|
HasMenuBar |
Enables menu bar region and drawMenuBar() calls |
In corner mode, placement depends on corner_menu_bar_placement. |
EnableTransparency |
Requests transparent backend/native clear path | Backend-dependent behavior. |
DisableBackground |
Makes root ImGui host background transparent | Frame/border can remain visible. |
ShowControlButtons |
Shows minimize/maximize/close buttons | Geometry depends on style and stroke config. |
MacStyledControlButtons |
Circular mac-like buttons | Mutually exclusive with other style flags. |
ImGuiStyledControlButtons |
Widgets::SystemButton style |
Release fallback style if style flags conflict. |
ClassicStyledControlButtons |
Text-button style | Mutually exclusive with other style flags. |
HasCornerIconArea |
Enables corner layout and icon slot | Switches from classic to corner layout. |
CornerModeRounding |
Enables rounded title/side geometry in corner mode | Radius from corner_icon_mode_rounding_radius. |
CornerModeBorder |
Enables corner-mode border strokes for title/side | Uses frame_stroke_thickness. |
DefaultControlButtons |
`ShowControlButtons | ImGuiStyledControlButtons` |
Control-button style conflict policy (resolveControlButtonsStyle()):
- Debug builds: assert if more than one style flag is set.
- Release builds: fallback to ImGui style.
Source: include/imguix/windows/ImGuiFramedWindow.hpp.
| Field | Meaning | Default / auto semantics |
|---|---|---|
min_width, min_height |
Minimum client size | 640x480 |
frame_corner_radius |
Native rounded region radius and root host rounding source | 8 |
resize_border |
Manual resize hit-test thickness (Win32 borderless path) | 8 |
title_bar_height |
Title row height | 32 |
side_panel_width |
Classic: <=0 disables side panel; Corner: <=0 means auto width |
0 |
frame_stroke_thickness |
Title/side separator stroke thickness | 1.0f |
frame_outer_stroke_thickness |
Outer host frame stroke thickness | 2.0f |
frame_inner_stroke_thickness |
Inner host frame stroke thickness | 1.0f |
Notes:
- In the SFML framed backend,
frame_outer_stroke_thickness+frame_inner_stroke_thicknessreduce the available layout space ofmain_regionand menu slices rendered in the main column on the outer edges they touch. - This frame-aware inset does not change title-bar, side-panel, or corner-icon chrome geometry.
| Field | Meaning | Auto rule |
|---|---|---|
title_content_left_inset |
Baseline left inset for title content | <0: style-based auto inset |
side_panel_content_left_inset |
Baseline left inset for side-panel content | <0: style-based auto inset |
main_region_padding |
Inner padding of framed-window main content area | Each component <0: fallback to runtime style.WindowPadding |
side_panel_content_alignment |
Side-panel content alignment policy | LegacyLeftInset: left-only legacy placement; SymmetricInset: keep panel width, center the inner content region with equal horizontal inset |
Notes:
main_region_paddingaffects only themain_regionchild where controllers/widgets are rendered.main_region_paddingdoes not affect title bar, menu bar, side panel, or corner icon area.- Frame-aware host-stroke insets are still applied first;
main_region_paddingis then used as the inner child padding inside that already reduced rect. SymmetricInsetdoes not resize the side panel itself; it only narrows and centers the content region inside it.SymmetricInsetis best for equal-width controls or widgets sized fromGetContentRegionAvail().x.SymmetricInsetdoes not automatically center arbitrary intrinsic-width text or links item-by-item.
| Field | Meaning | Notes |
|---|---|---|
corner_icon_mode_rounding_radius |
Radius for corner-mode title/side rounding | Effective only with CornerModeRounding. |
corner_rounding_style |
Corner rounding policy (Legacy, NoTopLeftOnTitleAndSide) |
Effective only with CornerModeRounding. |
corner_icon_mode_area_width |
Reserved width for corner icon area | <0: fallback formula. |
corner_icon_mode_icon_size |
Corner icon content size | <0: auto-fit with frame-aware compensation. |
corner_icon_mode_gap |
Gap between icon area and title/side | <0: runtime style.WindowPadding.x. |
corner_menu_bar_placement |
MainRegion, InTitleBar, BelowTitleBar |
Effective only with HasMenuBar. |
close_button_text,minimize_button_text,maximize_button_text: labels/IDs for classic text buttons.clear_color: backend clear color when transparency is disabled.
| Capability | SFML | GLFW | SDL2 |
|---|---|---|---|
Native rounded region (SetWindowRgn) in framed backend |
Yes (Win32 path) | No | No |
EnableTransparency clear-path handling in framed backend |
Yes | Yes | Yes |
ImGuiFramedWindow::setWindowIcon(...) meaningful success |
Yes | No (returns false) |
No (returns false) |
| Manual Win32 hit-test resize in framed backend | Yes (SFML Win32 path) | No | No |
| Control | Scope | Typical result |
|---|---|---|
WindowFlags::EnableTransparency |
Backend/native clear path | Transparent clear path (backend-dependent). |
WindowFlags::DisableBackground |
Root ImGui host background | Host background transparent; frame can stay visible. |
setDisableBackground(bool) |
Runtime toggle for background behavior | Same visual effect as disable-background mode, toggled at runtime. |
Practical sequence:
- Start with
DisableBackgroundto validate framed visuals. - Add
EnableTransparencyonly when native/translucent surface behavior is required.
#include <imguix/windows/ImGuiFramedWindow.hpp>
class DemoWindow final : public ImGuiX::Windows::ImGuiFramedWindow {
public:
DemoWindow(int id, ImGuiX::ApplicationContext& app)
: ImGuiFramedWindow(id, app, "demo_window", "Demo Window", buildFlags(), buildConfig()) {}
void onInit() override {
setWindowIcon("data/resources/icons/icon.png");
create(1280, 720);
}
protected:
void drawTitleBarText() override {
ImGui::TextUnformatted("Demo Window");
}
void drawSidePanel() override {
ImGui::TextUnformatted("A1");
ImGui::TextUnformatted("A2");
}
void drawMenuBar() override {
if (ImGui::BeginMenuBar()) {
if (ImGui::BeginMenu("File")) {
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
}
private:
static ImGuiX::Windows::WindowFlags buildFlags() {
using namespace ImGuiX::Windows;
return WindowFlags::HasMenuBar | WindowFlags::DefaultControlButtons;
}
static ImGuiX::Windows::ImGuiFramedWindowConfig buildConfig() {
ImGuiX::Windows::ImGuiFramedWindowConfig cfg{};
cfg.title_bar_height = 40;
cfg.side_panel_width = 48;
return cfg;
}
};static ImGuiX::Windows::WindowFlags buildClassicFlags() {
using namespace ImGuiX::Windows;
return WindowFlags::HasMenuBar | WindowFlags::DefaultControlButtons;
}
static ImGuiX::Windows::ImGuiFramedWindowConfig buildClassicConfig() {
ImGuiX::Windows::ImGuiFramedWindowConfig cfg{};
cfg.title_bar_height = 40;
cfg.side_panel_width = 48;
cfg.main_region_padding = ImVec2(16.0f, 12.0f);
cfg.frame_stroke_thickness = 1.0f;
return cfg;
}static ImGuiX::Windows::WindowFlags buildCornerV3Flags() {
using namespace ImGuiX::Windows;
return WindowFlags::DefaultControlButtons |
WindowFlags::HasCornerIconArea |
WindowFlags::CornerModeRounding |
WindowFlags::CornerModeBorder;
}
static ImGuiX::Windows::ImGuiFramedWindowConfig buildCornerV3Config() {
ImGuiX::Windows::ImGuiFramedWindowConfig cfg{};
cfg.title_bar_height = 40;
cfg.side_panel_width = 0; // corner auto-width
cfg.corner_menu_bar_placement = ImGuiX::Windows::CornerMenuBarPlacement::MainRegion;
return cfg;
}| Scenario | Required overrides | Optional overrides |
|---|---|---|
| Classic app (title + menu + side) | drawTitleBarText(), drawMenuBar(), drawSidePanel() |
drawCornerIcon() (not used) |
| Corner app (icon + side, no menu) | drawTitleBarText(), drawSidePanel() |
drawCornerIcon() |
| Menu in title bar (corner mode) | drawTitleBarText(), drawMenuBar() |
drawSidePanel(), drawCornerIcon() |
Source: examples/smoke/.
| Demo | What it demonstrates |
|---|---|
corner_icon_area_off_demo |
Classic layout, menu + side panel |
corner_icon_area_off_no_side_demo |
Classic layout, menu, no side panel |
corner_icon_area_off_no_menu_demo |
Classic layout with title only |
corner_icon_area_off_no_menu_odd_title_demo |
Classic layout with odd title-height alignment checks |
corner_icon_area_demo |
Corner layout + menu in title bar |
corner_icon_area_demo_v2 |
Corner layout + menu below title bar |
corner_icon_area_demo_v3 |
Corner layout baseline (no menu bar) |
corner_icon_area_demo_v4 |
Corner layout + nested child in main_region to inspect framed-window padding against mgc-style content flow |
corner_icon_area_demo_v3_no_top_left |
Corner layout + NoTopLeftOnTitleAndSide |
corner_icon_area_demo_v3_mac |
Corner layout + Mac-style control buttons |
Build one smoke target from repository root:
cmake --build external/ImGuiX/build-mingw --target corner_icon_area_demo_v3 --parallel 36For full smoke profile, see agents/imguix-smoke-build.md.
- Rounded region clipping on SFML/Win32
- With
SetWindowRgn, pixels outside region do not exist.
setWindowIconbehavior differs by backend
- In current
ImGuiFramedWindow, meaningful success is SFML-only.
side_panel_widthsemantics differ by layout mode
- Classic:
<= 0disables side panel. - Corner:
<= 0enables auto width.
side_panel_content_alignment = SymmetricInsetcenters the content region, not each widget
- Equal-width controls behave as expected.
- Narrow text/link items still use normal ImGui flow unless you center them explicitly.
corner_menu_bar_placementhas no effect withoutHasMenuBar
- Placement logic runs only when menu flag is active.
- Control-button style flag conflicts
- Multiple style flags trigger debug assert and release fallback.
- Verify layout mode first (
HasCornerIconAreaon/off). - Verify style flag exclusivity for control buttons.
- Verify
side_panel_widthsemantics for the active layout mode. - On SFML/Win32, validate corner borders during resize with rounded region enabled.
- Validate background/transparency combination (
EnableTransparency,DisableBackground, runtime toggle).