I can't find a clear explanation of "immediate mode" GUI creation (which this library enables) but it appears to be the sort of paradigm that pre-dated object-oriented and event-driven interaction handling that became the norm in the mid 90s (especially after the popularising of dev tools from Borland and Microsoft eg. Visual Basic etc), so I guess it is a formalisation of the procedural (?) methods from the era preceding that.

https://wiki.c2.com/?ImmediateModeGui

Immediate Mode GUIs are just GUIs that are instanced and drawn immediately during a single frame. There's no need to persist any object or structure because the whole screen will be cleaned and redrawn in the next frame. Immediate mode is popular in video games because in most games the screen is re-rendered on each frame.

This is in opposition from retained-mode, where things are re-rendered only when necessary, like in Win32/Cocoa or the HTML DOM. With those, you need to keep an object in memory.

The nature of the job is what allows for very simple procedure calls that looks almost declarative. Here's an example (it's Unity3D btw):

    GUI.Label (new Rect (25, 25, 100, 30), "Label");
    if (GUI.Button (new Rect (25, 25, 100, 30), "Button")) {
      // This code is executed when the Button is clicked
    }

> There's no need to persist any object or structure because

This isn't quite correct, at least for the library internals. Dear ImGui does persist UI state between frames, the "immediate mode" term only describes how the API looks like to the user, not how the library behind the API is implemented. The user code doesn't need to keep "widget handles" around, and there is no "event handler code" that is called asynchronously. From the user's point of view, control flow is entirely sequential, the UI is described and input events are processed in the same linear control flow context. But this is just what the library user sees, what happens under the hood is very different (e.g. the internal UI state is not rebuilt every frame from scratch, instead the API calls cause changes to the internal UI representation, those API calls just happen to also contain all the information needed to create the required internal UI state if it doesn't exist yet).

There's also nothing preventing the library from only redrawing what has changed, it just turned out that redrawing everything is usually so fast that only drawing what has changed would just add complexity to the implementation for very little gain (even complex ImGui UIs are usually a few dozen drawcalls at most and don't take up any significant chunk of the per-frame budget).

This description may be simplified and in details also slightly incorrect, but it's important to point out that "immediate mode" only applies to the API, not to the implementation, because this argument is often brought up by critics (who often don't quite understand what the "immediate" in "immediate mode UIs" is actually about) as a reason why immediate mode UIs can never be as efficient as traditional "retained mode" UIs (in reality they usually are more efficient than traditional UIs, and situations where traditional UIs are ahead can be optimized in immediate mode UIs just as well).

Correct. In order to tell if a button is clicked, you need to know whether it was clicked last frame, which means keeping around state. One difficulty with immediate-style GUIs is that it's difficult to tell whether two widgets are "the same". Dear ImGUI mostly uses a widget's label as its core identifier, which can cause issues if the button label changes.

There's actually a lot more in common between React and ImGUI than you might think, in terms of "state reconciliation". The difference is that React is diffing to apply itself to a retained model, while ImGUI retains the state behind your back.

This isn't true.

All state you need to keep track of is purely the input state: e.g. whether a button is pressed, keys are pressed, etc. And very importantly, you also need to store the edges of the input signal. That is, you need to store whether left mouse has changed from not pressed to pressed this frame, and whether it has changed from pressed to not pressed.

Then, the Button(...) call computes the hitbox of the button, checks whether the left mouse button has changed from 'not pressed' to 'pressed' this frame, and if yes, whether the mouse coordinates are inside the hitbox. If yes, it returns True, else it returns False.

No widget state needs to be kept.

There's a bit more subtlety than that. If I press down on a button, then move my mouse off of it, it will be deselected. This is normal and not too hard to implement your model. But, if I keep my mouse button held down, and drag back on, it will become re-highlighted, and it will go through. Note that only the button I originally clicked on will have this behavior. I just tested this right now in the ImGUI demo, so clearly per-widget state is tracked (or at least which "widget" is the one that has the mouse's active state): https://github.com/ocornut/imgui/#demo

If you think this is obscure, try implementing a slider widget any other way. You need a way to keep track of which slider you were dragging, even when the mouse cursor leaves to another.