Hello,
I have two GLFW Windows, each of them has its own ImGuiContext. Each window displays some ImGui widgets. For handling both windows I Just do a context swap both for ImGui and GLFW before displaying the rights ImGui widgets in each window:
ImGui::SetCurrentContext(imGuiContext1)
glfwMakeContextCurrent(glfwWindow1);
// Events polling, new frame, widgets, render, ...
ImGui::SetCurrentContext(imGuiContext2)
glfwMakeContextCurrent(glfwWindow2);
// Events polling, new frame, widgets, render, ...
This works, I have the right widgets displayed in the right window. However, in the ImGui GLFW Implementation (imgui_impl_glfw.h) there is no concept of context switching. Only one GLFWWindow* is stored, in a global variable called g_Window once and for all when calling ImGui_ImplGlfw_InitForOpenGL. If I call ImGui_ImplGlfw_InitForOpenGL for the second window, g_Window is overridden with the second GLFWWindow*. I don’t see any way to change the value of g_Window afterward in order to switch between my two windows.
This is annoying for example when ImGui_ImplGlfw_UpdateMousePosAndButtons() is called, because all the GLFW api calls are based on g_Window:
ImGuiIO& io = ImGui::GetIO();
/* ... */
const bool focused = glfwGetWindowAttrib(g_Window, GLFW_FOCUSED) != 0;
if (focused)
{
if (io.WantSetMousePos)
{
glfwSetCursorPos(g_Window, (double)mouse_pos_backup.x, (double)mouse_pos_backup.y);
}
else
{
double mouse_x, mouse_y;
glfwGetCursorPos(g_Window, &mouse_x, &mouse_y);
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y);
}
}
ImGui::GetIO() will give me the right IO structure from the current ImGuiContext but g_Window will always be my second GLFW window (the last I created). Thus, my first window is never considered focused, and receive mouse coordinates corresponding to the second window. This gives a funny situation when I can only interact with the GUI of the first window from the second window.
There is a quick fix I can think of which is providing a switch context function in imgui_impl_glfw.h/.cpp:
void ImGui_ImplGlfw_SetWindow(GLFWwindow* window)
{
g_Window = window;
}
This seems to work even if some other global variable in this file may have the same problem (callbacks, g_MouseJustPressed, …). The continuity of this solution would be to enclose all these global variables in a struct in the same manner as for ImGuiContext, hence providing a full context switching.
Is there a better solution that I missed? Maybe I can make some GLFW related code in my application to handle my two windows, passing mouse coordinates and events manually to ImGui. If it’s the way to go how should I do that? I would like to avoid modifying the ImGui code like I did to avoid having to merge my modifications in newer version of ImGui each time.
Thank you for your time.