To implement your own custom windowing backend, you need to derive from and override the UImGui::GenericWindow class. This class looks like this:

namespace UImGui
{
    class UIMGUI_PUBLIC_API GenericWindow
    {
    public:
        GenericWindow() noexcept = default;
        virtual ~GenericWindow() noexcept = default;

        virtual void createWindow() noexcept = 0;
        virtual void destroyWindow() noexcept = 0;

        // -------------------------------------------------------------------------------------------------------------
        // ---------------------------------------- Renderer and UI integration ----------------------------------------
        // -------------------------------------------------------------------------------------------------------------

#ifndef __EMSCRIPTEN__
        virtual void ImGuiInitFor_Vulkan() noexcept = 0;
#endif
        virtual void ImGuiInitFor_OpenGL() noexcept = 0;
        virtual void ImGuiInitFor_Other() noexcept = 0;

        virtual void ImGuiInstallCallbacks() noexcept = 0;
        virtual void ImGuiNewFrame() noexcept = 0;
        virtual void ImGuiShutdown() noexcept = 0;

        virtual bool shouldRender() noexcept = 0;
        virtual void pollEvents(double& now, double& deltaTime, double& lastTime) noexcept = 0;
        virtual void waitEventsTimeout(double timeout) noexcept = 0;
        virtual void waitEvents() noexcept = 0;

        virtual RendererUtils::OpenGL::Context* OpenGL_createContext() noexcept = 0;
        virtual RendererUtils::OpenGL::Context* OpenGL_getCurrentContext() noexcept = 0;
        virtual void OpenGL_setCurrentContext(RendererUtils::OpenGL::Context* ctx) noexcept = 0;
        virtual void OpenGL_destroyContext(RendererUtils::OpenGL::Context* ctx) noexcept = 0;

        virtual void OpenGL_swapBuffers() noexcept = 0;
        virtual void OpenGL_setSwapInterval(int interval) noexcept = 0;
        virtual void OpenGL_setHints(int majorVersion, int minorVersion, RendererClientAPI clientApi, RendererUtils::OpenGL::Profile profile, bool bForwardCompatible, uint32_t samples) noexcept = 0;
        virtual RendererUtils::OpenGL::GetProcAddressFun OpenGL_getProcAddressFunction() noexcept = 0;

        virtual void setupManualRenderingHints() noexcept = 0;

#ifndef __EMSCRIPTEN__
        virtual VkResult Vulkan_createWindowSurface(VkInstance instance, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface) noexcept = 0;
        virtual void Vulkan_fillInstanceAndLayerExtensions(TVector<const char*>& instanceExtensions, TVector<const char*>& instanceLayers) noexcept = 0;
#endif

        // -------------------------------------------------------------------------------------------------------------
        // --------------------------------------------- Input integration ---------------------------------------------
        // -------------------------------------------------------------------------------------------------------------

        virtual CKeyState getKey(CKeys key) noexcept = 0;

        FVector2 getMousePositionChange() noexcept;
        [[nodiscard]] FVector2 getCurrentMousePosition() const noexcept;
        [[nodiscard]] FVector2 getLastMousePosition() const noexcept;

        FVector2 getScroll() noexcept;

        virtual void setCursorVisibility(CursorVisibilityState visibility) noexcept = 0;

        virtual void setRawMouseMotion(bool bEnable) noexcept = 0;
        virtual bool getRawMouseMotion() noexcept = 0;

        // -------------------------------------------------------------------------------------------------------------
        // ---------------------------------------------- Window interface ---------------------------------------------
        // -------------------------------------------------------------------------------------------------------------

        virtual void setTitle(String name) noexcept = 0;
        virtual String getTitle() noexcept = 0;
        virtual void setTitleSetting(String name) noexcept = 0;
        virtual String getTitleSetting() noexcept = 0;

        virtual void setIcon(String name) noexcept = 0;
        virtual String getIconLocation() noexcept = 0;
        virtual String getIconLocationSetting() noexcept = 0;
        virtual void setIconLocationSetting(String location) noexcept = 0;

        virtual float getAspectRatio() noexcept = 0;

        virtual FVector2 getCurrentWindowPosition() noexcept = 0;
        virtual FVector2 getLastWindowPosition() noexcept = 0;
        virtual FVector2 getWindowPositionChange() noexcept = 0;

        virtual void setCurrentWindowPosition(FVector2 pos) noexcept = 0;
        virtual void pushWindowPositionChangeCallback(const TFunction<void(FVector2)>& f) noexcept = 0;

        virtual FVector2 getWindowSize() noexcept = 0;
        virtual FVector2& getWindowSizeSetting() noexcept = 0;

        virtual bool getWindowFullscreen() noexcept = 0;
        virtual bool& getWindowFullscreenSetting() noexcept = 0;
        virtual void setWindowFullscreen(bool bFullscreen) noexcept = 0;

        virtual void saveSettings(bool bSaveKeybinds) noexcept;
        void openConfig() noexcept;
        virtual void refreshSettings() noexcept = 0;

        virtual void close() noexcept = 0;
        virtual void pushWindowCloseCallback(const TFunction<void(void)>& f) noexcept = 0;

        virtual void Platform_setWindowAlwaysOnTop() noexcept = 0;
        virtual void Platform_setWindowAlwaysOnBottom() noexcept = 0;

        virtual void Platform_setWindowShowingOnPager(bool bShowInPager) noexcept = 0;
        virtual bool Platform_getWindowShowingOnPager() noexcept = 0;

        virtual void Platform_setWindowShowingOnTaskbar(bool bShowOnTaskbar) noexcept = 0;
        virtual bool Platform_getWindowShowingOnTaskbar() noexcept = 0;

        virtual void Platform_setWindowType(String type) noexcept = 0;
        virtual size_t Platform_getWindowID() noexcept = 0;

        virtual void* Platform_getNativeWindowHandle() noexcept = 0;
        virtual WindowPlatform Platform_getCurrentWindowPlatform() noexcept = 0;
        virtual void* Platform_getNativeDisplay() noexcept = 0;

        virtual void setWindowSizeInScreenCoords(FVector2 sz) noexcept = 0;
        virtual FVector2 getWindowSizeInScreenCoords() noexcept = 0;
        virtual void pushWindowResizedInScreenCoordsCallback(const TFunction<void(int, int)>& f) noexcept = 0;

        virtual void setWindowResizeable(bool bResizeable) noexcept = 0;
        virtual bool& getWindowResizeableSetting() noexcept = 0;
        virtual bool getWindowCurrentlyResizeable() noexcept = 0;
        virtual void pushWindowResizeCallback(const TFunction<void(int, int)>& f) noexcept = 0;

        virtual void requestWindowAttention() noexcept = 0;

        virtual void hideWindow() noexcept = 0;
        virtual void showWindow() noexcept = 0;
        virtual bool& getWindowHiddenSetting() noexcept = 0;
        virtual bool getWindowCurrentlyHidden() noexcept = 0;

        virtual bool getWindowSurfaceTransparent() noexcept = 0;
        virtual void setWindowSurfaceTransparent(bool bTransparent) noexcept = 0;
        virtual bool& getWindowSurfaceTransparentSetting() noexcept = 0;

        virtual void focusWindow() noexcept = 0;
        virtual bool& getWindowFocusedSetting() noexcept = 0;
        virtual bool getWindowCurrentlyFocused() noexcept = 0;
        virtual void pushWindowFocusCallback(const TFunction<void(bool)>& f) noexcept = 0;

        virtual void iconifyWindow() noexcept = 0;
        virtual void restoreWindowState() noexcept = 0;
        virtual void pushWindowIconifyCallback(const TFunction<void(bool)>& f) noexcept = 0;
        virtual bool getWindowIconified() noexcept = 0;

        virtual FVector2 getWindowContentScale() noexcept = 0;
        virtual void pushWindowContentScaleCallback(const TFunction<void(FVector2)>& f) noexcept = 0;

        virtual void setSizeLimits(FVector2 min, FVector2 max) noexcept = 0;
        virtual void setSizeLimitByAspectRatio(FVector2 ratio) noexcept = 0;
        virtual FVector4& getSizeLimits() noexcept = 0;
        virtual FVector2& getAspectRatioSizeLimits() noexcept = 0;

        virtual FVector4 getWindowDecorationFrameDistances() noexcept = 0;
        virtual bool getCurrentWindowDecoratedState() noexcept = 0;
        virtual bool& getWindowDecoratedSetting() noexcept = 0;
        virtual void setWindowDecorated(bool bDecorated) noexcept = 0;

        virtual void pushWindowRefreshCallback(const TFunction<void(void)>& f) noexcept = 0;

        virtual void maximiseWindow() noexcept = 0;
        virtual bool& getWindowMaximisedSetting() noexcept = 0;
        virtual void pushWindowMaximiseCallback(const TFunction<void(bool)>& f) noexcept = 0;
        virtual bool getWindowCurrentlyMaximised() noexcept = 0;

        virtual Monitor getWindowMonitor() noexcept = 0;
        virtual Monitor getPrimaryMonitor() noexcept = 0;
        virtual const TVector<Monitor>& getMonitors() noexcept = 0;

        // Event safety - begin, style, post-begin
        virtual void pushWindowOSDragDropCallback(const TFunction<void(const FString&)>& f) noexcept = 0;

        virtual void* getInternal() noexcept = 0;
        virtual GenericWindow* get() noexcept = 0;
    protected:
        friend void ::UImGui_Window_pushWindowOSDragDropCallback(UImGui_Window_pushWindowOSDragDropCallbackFun f);
        friend class Input;
        friend class Layouts;
        friend class Monitor;

        bool bResized = false;

        bool bFirstMouseMove = true;
        FVector2 mousePos = { 0.0f, 0.0f };
        FVector2 mouseLastPos = { 0.0f, 0.0f };
        FVector2 mouseOffset = { 0.0f, 0.0f };

        FVector2 scroll{};

        FVector2 windowLastPos = { 0.0f, 0.0f };
        FVector2 windowCurrentPos = { 0.0f, 0.0f };

        bool bShowOnPager = true;
        bool bShowOnTaskbar = true;

        TVector<TFunction<void(int, int)>> windowResizeCallbackList;
        TVector<TFunction<void(int, int)>> windowResizeInScreenCoordCallbackList;
        TVector<TFunction<void()>> windowCloseCallbackList;
        TVector<TFunction<void(bool)>> windowFocusCallbackList;
        TVector<TFunction<void(bool)>> windowIconifiedCallbackList;
        TVector<TFunction<void(FVector2)>> windowPositionChangeCallbackList;
        TVector<TFunction<void(FVector2)>> windowContentScaleChangeCallbackList;
        TVector<TFunction<void(void)>> windowRefreshCallbackList;
        TVector<TFunction<void(bool)>> windowMaximisedCallbackList;
        TVector<TFunction<void(String)>> dragDropPathCallbackList;

        FVector2 windowSizeS = { 800.0f, 600.0f };
        FVector2 windowSizeInScreenCoords{};

        WindowData windowData;
        TVector<InputAction> inputActionList{};

        GenericMonitor* monitor = nullptr;
    };
}

The window's data

The GenericWindow class stores some publicly-accessible variables that are needed to store the minimal amount of state that is required for the framework's systems to work as expected. The data is as follows:

Configuration

The only variable for configuring the window's settings is the windowData variable which is of type UImGui::WindowData. This structure holds all window settings from the Config/Core/Window.yaml file and looks like this:

struct UIMGUI_PUBLIC_API WindowData
{
    FString name = "UntitledImGuiFramework Application";
    FString iconLocation = "example-icon.png";
    FString layoutLocation = "DefaultLayout";

    bool bLoadLayout = true;
    bool bSaveLayout = true;

    bool fullscreen = false;
    bool bResizeable = true;

    bool bSurfaceTransparent = false;

    bool bHidden = false;
    bool bFocused = true;

    FVector2 aspectRatioSizeLimit = { -1, -1 };
    FVector4 sizeLimits = { -1, -1, -1, -1 };

    bool bDecorated = true;
    bool bMaximised = false;
};

The fields are as follows:

  1. name - The application window's default name
  2. iconLocation - The default icon location for the window
  3. layoutLocation - The name of the default dear imgui UI layout file to be loaded
  4. bLoadLayout and bSaveLayout - Whether to load or to save the dear imgui UI layout to the default layout location
  5. fullscreen - whether the window is started in fullscreen mode
  6. bResizeable - whether the window can be resized by default
  7. bSurfaceTransparent - whether the window surface is transparent by default
  8. bHidden - whether the window launches as hidden by default
  9. bFocused - whether the window gains focus immediately by default
  10. sizeLimits and aspectRatioSizeLimit - the window size limits and aspect ratio size limits respectively. Set to -1 to disable limits
  11. bDecorated - whether the window launches as decorated by default
  12. bMaximised - whether the window launches maximised by default

Input

  1. mousePos, mouseLastPos and mouseOffset - The current, last and the delta between the current and the last mouse positions as FVector2. The delta is reset each time it's accessed through Input::getMousePositionChange()
  2. scroll - The current scroll direction as an FVector2
  3. inputActionList - A TVector<InputAction> that stores all current input actions

Monitor

The monitor variable is of type GenericMonitor* when the window instance is constructed, this pointer should be set to point to an instance of your custom monitor backend for the window system you're implementing.

More information on this topic can be found in the following wiki entry.

Window attributes

  1. windowCurrentPos and windowLastPos - The current and last positions of the window on screen as FVector2. The size should be in screen coordinates
  2. windowSizeS - The size of the window as an FVector2
  3. windowSizeInScreenCoords - The size of the window but in screen coordinates as an FVector2.

Platform

  1. bShowOnPager - whether to show the window in the pager(virtual desktop overview)
  2. bShowOnTaskbar - whether to show the window on the taskbar

Callbacks

The following arrays of TFunction hold callbacks for different window events:

  1. windowResizeCallbackList - Call when the window is resized. Function type: void(int x, int y)
  2. windowResizeInScreenCoordCallbackList - Call when the window is resized, but in screen coordinates. Function type: void(int x, int y)
  3. windowCloseCallbackList - Call when the window is closed. Function type: void(void)
  4. windowFocusCallbackList - Call when the window is focused or unfocused. Function type: void(bool bFocused)
  5. windowIconifiedCallbackList - Call when the window is iconified/minimised or restored. Function type: void(bool bIconified)
  6. windowPositionChangeCallbackList - Call when the position of the window changes. Function type: void(FVector2 position)
  7. windowContentScaleChangeCallbackList - Call when the content scale of the window changes. Function type: void(FVector2 scale)
  8. windowRefreshCallbackList - Call when the window's state gets forcibly refreshed. Function type: void(void)
  9. windowMaximisedCallbackList - Call when the window was maximised or restored. Function type: void(bool bMaximised)
  10. dragDropPathCallbackList - Call when a drag and drop from an outside application is completed over the window of your application. When the windowing library or API allows for multiple strings per drag-and-drop action, all the events need to be called again for every string in the list.

Methods

Window creation and destruction

During the construction of your class, make sure to do the following:

  1. Initialise any of your data.
  2. If storing keys as an array of ascii characters, zero the array to KeyStateReleased
  3. Set the monitor pointer to point to your own custom GenericMonitor instance.

The createWindow() and destroyWindow() pure virtual methods are used to create and to destroy the window.

Inside createWindow(), applications are required to do the following in order:

  1. Call openConfig() to load the default window configuration
  2. Initialise with their windowing library if necessary(not creating the window yet)
  3. Call RendererUtils::getRenderer()->setupWindowIntegration()
  4. Create the window with the required settings from `windowData, set its icon, size limits, etc.
  5. Get the framebuffer size and initialise windowSizeS with the correct size
  6. Call RendererUtils::getRenderer()->setupPostWindowCreation()
  7. Finish setting up your window.

Inside destroyWindow(), simply free your window's resources.

Rendering and UI integration

The following functions are mainly used by the RendererUtils and WindowUtils classes. Renderers then use them to integrate with the window you created.

Initialising dear imgui:

  1. ImGuiInstallCallbacks() - Installs additional dear imgui window callbacks. This function is not needed or used by some graphics APIs, since it's mainly used for applications that run under Emscripten.
  2. ImGuiInitFor_Vulkan() - Initialises dear imgui to render with Vulkan. This is not available when targeting Emscripten. Make sure to guard both the declaration and the implementation inside a #ifndef __EMSCRIPTEN__ preprocessor guard to prevent compiler errors.
  3. ImGuiInitFor_OpenGL() - Initialises dear imgui to render with OpenGL.
  4. ImGuiInitFor_Other() - Initialises dear imgui to render with any other graphics API

Note

If you're using a custom renderer and your dear imgui backend has does not use ImGui_ImplWindow_InitForOther() but instead has a specialisation for that specific rendering API, make sure to implement your own ImGuiIntFor_ function for your windowing system that extends the current interface. You can then use it, instead of ImGuiInitFor_Other() inside your custom renderer.

Other dear imgui functions:

  1. ImGuiNewFrame() - Calls ImGui_ImplWindow_NewFrame() in the render loop
  2. ImGuiShutdown() - Calls ImGui_ImplWindow_Shutdown() when the application is shutting down and exiting

Window event hooks:

  1. bool shouldRender() - This function is called every frame to check if the application is still rendering. Else, the application quits gracefully, as if the user clicked on its close button.
  2. pollEvents(double& now, double& deltaTime, double& lastTime) - Polls and executes window events in the render loop. It then calculates and emplaces the delta time between the last frames. It also needs to calculate and emplace the current time and last time as part of its calculations.
  3. waitEventsTimeout(double timeout) - waits for events with a timeout
  4. waitEvents() - waits for an event to be emmited indefinitely

OpenGL utility functions:

  1. RendererUtils::OpenGL::Context* OpenGL_createContext() - Creates an OpenGL context and returns it
  2. RendererUtils::OpenGL::Context* OpenGL_getCurrentContext() - Returns the current OpenGL context
  3. OpenGL_setCurrentContext(RendererUtils::OpenGL::Context* ctx) - Sets an existing context as the current context
  4. OpenGL_destroyContext(RendererUtils::OpenGL::Context* ctx) - Destroys an frees an existing OpenGL context
  5. OpenGL_swapBuffers() - swaps the OpenGL buffers. OpenGL renderers call this every frame
  6. OpenGL_setSwapInterval(int interval) - When set to 0 the window should render without frame limiting. When set to 1 the window should render with V-Sync. Higher values are not considered as standard but you may offer half or quarter V-blank sync increments
  7. RendererUtils::OpenGL::GetProcAddressFun OpenGL_getProcAddressFunction() - This function returns the proc address function that the OpenGL loader uses to load extensions dynamically. This function is of type void(*(*)(const char*))()
  8. OpenGL_setHints(int majorVersion, int minorVersion, RendererClientAPI clientApi, RendererUtils::OpenGL::Profile profile, bool bForwardCompatible, uint32_t samples) - Sets up the renderer hints for OpenGL. The windowing API needs to be able to provide all of the requests. Refer to the RendererUtils documentation for more information

Vulkan utility functions(These functions need to be under a #ifndef __EMSCRIPTEN__ guard):

  1. VkResult Vulkan_createWindowSurface(VkInstance instance, const VkAllocatorCallbacks* allocator, VkSurfaceKHR* surface) - Creates a Vulkan surface for the window. Takes a Vulkan instance, an optional allocator and a pointer to a Vulkan surface. The function results a VkResult which needs to be checked for errors.
  2. Vulkan_fillInstanceAndLayerExtensions(TVector<const char*>& instanceExtensions, TVector<const char*>& instanceLayers) - When creating the Vulkan instance, this function fills the provided arrays with the needed extensions and layers for the instance to work with the underlying windowing and surface API

Manual rendering:

  1. setupManualRenderingHints() - Custom renderers use this to set up for rendering with any unmanaged APIs(basically always non-OpenGL)

Input integration

The following functions are used as part of the Input interface:

  1. CKeyState getKey(CKeys) - Returns the state of a key. This function is used to convert between your native window system's keys and the framework's keys
  2. setCursorVisibility(CursorVisibilityState visibility) - Sets the cursor visibility based on the CursorVisibilityState enum argument
  3. setRawMouseMotion(bool) - Whether to enable or disable raw mouse motion
  4. bool getRawMouseMotion() - Returns whether the window is currently using raw mouse motion

Window interface

The rest of the functions are the same as the functions in the window interface. The only exception are functions prefixed with Platform_ which correspond to the ones under the UImGui::Window::Platform class.

Notable functions:

  1. saveSettings(bool bSaveKeybindings) - This function is not a pure virtual function. This is because it has a default implementation as part of the GenericWindow class. This means that you can extend this function by calling GenericWindow::saveSettings() in your own saveSettings() function.
  2. void* getInternal() - This function must return a pointer to your current window handle as a void*
  3. GenericWindow* get() - This should return this in most cases

Adding a GenericMonitor to your window

For a fully compliant implementation, the monitor member variable needs to be filled with an instance of a child of the GenericMonitor class. More information can be found here.

Using your window backend

To use your backend set the customWindow variable in the InitInfo struct to point to a non-null instance of GenericMonitor.

C API

The C API for generic windows looks like this:

 /**
 * @brief Creates a GenericWindow instance. Memory management over the InitInfo struct falls on the user
 * @param initInfo - A struct containing function pointers for each GenericWindow event. push*Callback functions
 * get a void* which points to the corresponding C++ std::function instance. Casts need to be done across FFI
 * boundaries which is not ideal. Memory management over the InitInfo struct falls on the user
 * @note Event Safety - Any time
 */
 UIMGUI_PUBLIC_API void UImGui_CGenericWindow_create(struct UImGui_CGenericWindowInitInfo* initInfo);

 /**
 * @brief Frees the GenericWindow instance part of the InitInfo struct. Memory management over the InitInfo struct
 * falls on the user.
 * @param instance - The InitInfo struct used to create the GenericWindow struct. The instance is stored as part of
 * this struct, but only it will be freed. Ownership over the InitInfo struct instance is placed upon the user.
 * @note Event Safety - Any time
 */
UIMGUI_PUBLIC_API void UImGui_CGenericWindow_destroy(const struct UImGui_CGenericWindowInitInfo* instance);

Your handle to each intance is a struct of type UImGui_CGenericWindowInitInfo. This struct needs to be initialised with GenericWindow events in the form of C function pointer. The struct looks like this:

// Note: all push*Callback functions take a void* instead of a function pointer. This is because arguments are
// passed from C++ as std::function<...>* and therefore they need to be cast back into their underlying C++ type.
// Therefore, all implementations of this function have to be implemented from C++, which is not ideal, since it
// overcomplicates interfacing from non C/C++ languages.
typedef struct UIMGUI_PUBLIC_API UImGui_CGenericWindowInitInfo
{
    void(*createWindow)(struct UImGui_CGenericWindowInitInfo*);
    void(*destroyWindow)(struct UImGui_CGenericWindowInitInfo*);

#ifdef __EMSCRIPTEN__
    void(*ImGuiInitFor_Vulkan)(struct UImGui_CGenericWindowInitInfo*);
#endif
    void(*ImGuiInitFor_OpenGL)(struct UImGui_CGenericWindowInitInfo*);
    void(*ImGuiInitFor_Other)(struct UImGui_CGenericWindowInitInfo*);
    void(*ImGuiInstallCallbacks)(struct UImGui_CGenericWindowInitInfo*);

    void(*ImGuiNewFrame)(struct UImGui_CGenericWindowInitInfo*);
    void(*ImGuiShutdown)(struct UImGui_CGenericWindowInitInfo*);

    bool(*shouldRender)(struct UImGui_CGenericWindowInitInfo*);
    void(*pollEvents)(struct UImGui_CGenericWindowInitInfo*, double*, double*, double*);
    void(*waitEventsTimeout)(struct UImGui_CGenericWindowInitInfo*, double);
    void(*waitEvents)(struct UImGui_CGenericWindowInitInfo*);

    UImGui_OpenGLContext*(*OpenGL_createContext)(struct UImGui_CGenericWindowInitInfo*);
    UImGui_OpenGLContext*(*OpenGL_getCurrentContext)(struct UImGui_CGenericWindowInitInfo*);
    void(*OpenGL_setCurrentContext)(struct UImGui_CGenericWindowInitInfo*, UImGui_OpenGLContext*);
    void(*OpenGL_destroyContext)(struct UImGui_CGenericWindowInitInfo*, UImGui_OpenGLContext*);

    void(*OpenGL_swapBuffers)(struct UImGui_CGenericWindowInitInfo*);
    void(*OpenGL_setSwapInterval)(struct UImGui_CGenericWindowInitInfo*, int);

    void(*OpenGL_setHints)(struct UImGui_CGenericWindowInitInfo*, int, int, UImGui_RendererClientAPI, UImGui_OpenGLProfile, bool, uint32_t);
    UImGui_OpenGL_GetProcAddressFun(*OpenGL_getProcAddressFunction)(struct UImGui_CGenericWindowInitInfo*);

    void(*setupManualRenderingHints)(struct UImGui_CGenericWindowInitInfo*);

#ifndef __EMSCRIPTEN__
    VkResult(*Vulkan_createWindowSurface)(struct UImGui_CGenericWindowInitInfo*, VkInstance, const VkAllocationCallbacks*, VkSurfaceKHR*);
    void(*Vulkan_fillInstanceAndLayerExtensions)(struct UImGui_CGenericWindowInitInfo*, const char**, size_t, const char**, size_t);
#endif

    CKeyState(*getKey)(struct UImGui_CGenericWindowInitInfo*, CKeys);

    UImGui_FVector2(*getMousePositionChange)(struct UImGui_CGenericWindowInitInfo*);
    UImGui_FVector2(*getCurrentMousePosition)(struct UImGui_CGenericWindowInitInfo*);
    UImGui_FVector2(*getLastMousePosition)(struct UImGui_CGenericWindowInitInfo*);

    UImGui_FVector2(*getScroll)(struct UImGui_CGenericWindowInitInfo*);

    void(*setCursorVisibility)(struct UImGui_CGenericWindowInitInfo*, UImGui_CursorVisibilityState);

    void(*setRawMouseMotion)(struct UImGui_CGenericWindowInitInfo*, bool);
    bool(*getRawMouseMotion)(struct UImGui_CGenericWindowInitInfo*);

    void(*setTitle)(struct UImGui_CGenericWindowInitInfo*, UImGui_String);
    UImGui_String(*getTitle)(struct UImGui_CGenericWindowInitInfo*);
    void(*setTitleSetting)(struct UImGui_CGenericWindowInitInfo*, UImGui_String);
    UImGui_String(*getTitleSetting)(struct UImGui_CGenericWindowInitInfo*);

    void(*setIcon)(struct UImGui_CGenericWindowInitInfo*, UImGui_String);
    UImGui_String(*getIconLocation)(struct UImGui_CGenericWindowInitInfo*);
    void(*setIconLocationSetting)(struct UImGui_CGenericWindowInitInfo*, UImGui_String);
    UImGui_String(*getIconLocationSetting)(struct UImGui_CGenericWindowInitInfo*);

    float(*getAspectRatio)(struct UImGui_CGenericWindowInitInfo*);

    UImGui_FVector2(*getCurrentWindowPosition)(struct UImGui_CGenericWindowInitInfo*);
    UImGui_FVector2(*getLastWindowPosition)(struct UImGui_CGenericWindowInitInfo*);
    UImGui_FVector2(*getWindowPositionChange)(struct UImGui_CGenericWindowInitInfo*);
    void(*setCurrentWindowPosition)(struct UImGui_CGenericWindowInitInfo*, UImGui_FVector2);
    void(*pushWindowPositionChangeCallback)(struct UImGui_CGenericWindowInitInfo*, const void*);

    UImGui_FVector2(*getWindowSize)(struct UImGui_CGenericWindowInitInfo*);
    UImGui_FVector2*(*getWindowSizeSetting)(struct UImGui_CGenericWindowInitInfo*);

    bool(*getWindowFullscreen)(struct UImGui_CGenericWindowInitInfo*);
    bool*(*getWindowFullscreenSetting)(struct UImGui_CGenericWindowInitInfo*);
    void(*setWindowFullscreen)(struct UImGui_CGenericWindowInitInfo*, bool);

    void(*saveSettings)(struct UImGui_CGenericWindowInitInfo*, bool);
    void(*openConfig)(struct UImGui_CGenericWindowInitInfo*);
    void(*refreshSettings)(struct UImGui_CGenericWindowInitInfo*);

    void(*close)(struct UImGui_CGenericWindowInitInfo*);
    void(*pushWindowCloseCallback)(struct UImGui_CGenericWindowInitInfo*, const void*);

    void(*Platform_setWindowAlwaysOnTop)(struct UImGui_CGenericWindowInitInfo*);
    void(*Platform_setWindowAlwaysOnBotton)(struct UImGui_CGenericWindowInitInfo*);

    void(*Platform_setWindowShowingOnPager)(struct UImGui_CGenericWindowInitInfo*, bool);
    bool(*Platform_getWindowShowingOnPager)(struct UImGui_CGenericWindowInitInfo*);

    void(*Platform_setWindowShowingOnTaskbar)(struct UImGui_CGenericWindowInitInfo*, bool);
    bool(*Platform_getWindowShowingOnTaskbar)(struct UImGui_CGenericWindowInitInfo*);

    void(*Platform_setWindowType)(struct UImGui_CGenericWindowInitInfo*, UImGui_String);
    size_t(*Platform_getWindowID)(struct UImGui_CGenericWindowInitInfo*);

    void*(*Platform_getNativeWindowHandle)(struct UImGui_CGenericWindowInitInfo*);
    UImGui_WindowPlatform(*Platform_getCurrentWindowPlatform)(struct UImGui_CGenericWindowInitInfo*);
    void*(*Platform_getNativeDisplay)(struct UImGui_CGenericWindowInitInfo*);

    void(*setWindowSizeInScreenCoords)(struct UImGui_CGenericWindowInitInfo*, UImGui_FVector2);
    UImGui_FVector2(*getWindowSizeInScreenCoords)(struct UImGui_CGenericWindowInitInfo*);
    void(*pushWindowResizedInScreenCoordsCallback)(struct UImGui_CGenericWindowInitInfo*, const void*);

    void(*setWindowResizeable)(struct UImGui_CGenericWindowInitInfo*, bool);
    bool*(*getWindowResizeableSetting)(struct UImGui_CGenericWindowInitInfo*);
    bool(*getWindowCurrentlyResizeable)(struct UImGui_CGenericWindowInitInfo*);
    void(*pushWindowResizeCallback)(struct UImGui_CGenericWindowInitInfo*, const void*);

    void(*requestWindowAttention)(struct UImGui_CGenericWindowInitInfo*);

    void(*hideWindow)(struct UImGui_CGenericWindowInitInfo*);
    void(*showWindow)(struct UImGui_CGenericWindowInitInfo*);
    bool*(*getWindowHiddenSetting)(struct UImGui_CGenericWindowInitInfo*);
    bool(*getWindowCurrentlyHidden)(struct UImGui_CGenericWindowInitInfo*);

    bool(*getWindowSurfaceTransparent)(struct UImGui_CGenericWindowInitInfo*);
    void(*setWindowSurfaceTransparent)(struct UImGui_CGenericWindowInitInfo*, bool);
    bool*(*getWindowSurfaceTransparentSetting)(struct UImGui_CGenericWindowInitInfo*);

    void(*focusWindow)(struct UImGui_CGenericWindowInitInfo*);
    bool*(*getWindowFocusSetting)(struct UImGui_CGenericWindowInitInfo*);
    bool(*getWindowCurrentlyFocused)(struct UImGui_CGenericWindowInitInfo*);
    void(*pushWindowFocusCallback)(struct UImGui_CGenericWindowInitInfo*, const void*);

    void(*iconifyWindow)(struct UImGui_CGenericWindowInitInfo*);
    void(*restoreWindowState)(struct UImGui_CGenericWindowInitInfo*);
    void(*pushWindowIconifyCallback)(struct UImGui_CGenericWindowInitInfo*, const void*);
    bool(*getWindowIconified)(struct UImGui_CGenericWindowInitInfo*);

    UImGui_FVector2(*getWindowContentScale)(struct UImGui_CGenericWindowInitInfo*);
    void(*pushWindowContentScaleCallback)(struct UImGui_CGenericWindowInitInfo*, const void*);

    void(*setSizeLimits)(struct UImGui_CGenericWindowInitInfo*, UImGui_FVector2, UImGui_FVector2);
    void(*setSizeLimitByAspectRatio)(struct UImGui_CGenericWindowInitInfo*, UImGui_FVector2);
    UImGui_FVector4*(*getSizeLimits)(struct UImGui_CGenericWindowInitInfo*);
    UImGui_FVector2*(*getAspectRatioSizeLimits)(struct UImGui_CGenericWindowInitInfo*);

    UImGui_FVector4(*getWindowDecorationFrameDistances)(struct UImGui_CGenericWindowInitInfo*);
    bool(*getCurrentWindowDecoratedState)(struct UImGui_CGenericWindowInitInfo*);
    bool*(*getWindowDecoratedSetting)(struct UImGui_CGenericWindowInitInfo*);
    void(*setWindowDecorated)(struct UImGui_CGenericWindowInitInfo*, bool);

    void(*pushWindowRefreshCallback)(struct UImGui_CGenericWindowInitInfo*, const void*);

    void(*maximiseWindow)(struct UImGui_CGenericWindowInitInfo*);
    bool*(*getWindowMaximizedSetting)(struct UImGui_CGenericWindowInitInfo*);
    void(*pushWindowMaximiseCallback)(struct UImGui_CGenericWindowInitInfo*, const void*);
    bool(*getWindowCurrentlyMaximised)(struct UImGui_CGenericWindowInitInfo*);

    UImGui_MonitorData(*getWindowMonitor)(struct UImGui_CGenericWindowInitInfo*);
    UImGui_MonitorData(*getPrimaryMonitor)(struct UImGui_CGenericWindowInitInfo*);
    UImGui_MonitorData*(*getMonitors)(struct UImGui_CGenericWindowInitInfo*, size_t*);

    void(*pushWindowOSDragDropCallback)(struct UImGui_CGenericWindowInitInfo*, const void*);

    void*(*getInternal)(struct UImGui_CGenericWindowInitInfo*);
    UImGui_CGenericWindow*(*get)(struct UImGui_CGenericWindowInitInfo*);

    void* context;
    size_t contextSize;

    UImGui_CGenericMonitor* monitor;
    UImGui_CGenericWindow* instance;
} UImGui_CGenericWindowInitInfo;

The struct contains all of the functions from the GenericWindow class, with some changes and additions. Mainly:

  1. It adds additional context and contextSize data types for custom window data.
  2. The monitor variable is now of type UImGui_CGenericMonitor*
  3. There is an internal instance variable of type UImGui_CGenericWindow* which is used for internal state management
  4. All functions have a UImGui_CGenericWindowInitInfo* as their first function argument. This is so that members can still call other members without issues
  5. All functions named push*Callback take a void* instead of a function pointer. This pointer needs to be passed to C++, where it has to be cast as TFunction<...>*. This means that fully compliant implementations still need to implement part of their code in C++ for this type of state management.

Caution

Implementing all the push*Callback functions is required for the compliant function of the framework with most of its interfaces. Some of these functions are also required by renderers, for example pushWindowResizeCallback()

Custom windows can be added from the C API by setting the customWindow field as part of the CInitInfo sturct to a non-null value.