ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
59.75k stars 10.17k forks source link

Multiple GLFW contexts : glfw event binding #5439

Open Daandelange opened 2 years ago

Daandelange commented 2 years ago

Version/Branch of Dear ImGui:

Version: 1.89WIP Branch: docking

Back-end/Renderer/Compiler/OS

Back-ends: imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp Compiler: Apple clang 8.0 / g++ 9.3.0 Operating System: Osx 10.12 / Linux Mint 20

My Issue/Question:

Hello, I'm updating the openFrameworks ImGui wrapper.
We've got lots of ways to run our (glfw) ofApps and multi-context + viewports seems to be the best way for supporting all possible configurations, although it's discouraged. But the official glfw backend is not yet fully tested with multiple contexts/viewports, so I'd like to discuss it here.

So I've been reading trough a few PRs and issues. Most notably #3934 where Omar states :

Another solution would be to rework the backend to store an additional GLFWwindow -> ImGuiContext map, and in all the callback set the context based on that (and maybe restore it afterward). This would unfortunately be a little messy :(

After trying the 1st solution from bear24rw, It worked great but did not work in single-window viewports (pop-out-windows), so Omar's proposed solution right below it seemed quite obvious.

I just implemented it and it works great. My code is pushed to Daandelange:features/backend_glfw_multicontext for trying out. Note: example_glfw_opengl3 has been changed to use N windows with one imgui context (and host viewport) per platform window.

I guess there are still some issues around, but it's very useable already.

Standalone, minimal, complete and verifiable example: Please refer to : Daandelange:features/backend_glfw_multicontext/examples/example_glfw_opengl3

ocornut commented 2 years ago

Using glfwSetWindowUserPointer() glfwGetWindowUserPointer() would be neat but of course that's a finite resource. Using std::map is something we can't do/merge. ImGuiStorage would be a good enough replacement.

Monitor callback sets a flag for context to update, would need to set flag on all contexts (so we would need a list of them, which currently doesn't exist, but your map adds it).

If you need this it may be possible to do it externally by hooking callbacks yourself. A little more code but you'd have a fully external implementation without modifying imgui_impl_glfw.

I would generally question the need to support multiple-contexts on your end but it may be a hard requirement for you.

Daandelange commented 2 years ago

Hello Omar, and thanks for your valuable directions and feedback. :)
I'll digg the ImGuiStorage way and set the monitor update flag.

Of course, not modifying the backend would be awesome, I tried it like solution 1 (above) but then I couldn't bind the single-window viewport events. I guess I should then replace platform_io.Platform_CreateWindow ?

And not using multiple imgui contexts would be better too, but with multiple platform host windows, this seemed difficult to achieve (prior to v1.80), do you think it's possible to have a single context within multiple viewports ? (and how if so?)