aboutsummaryrefslogtreecommitdiff
path: root/3rdparty/imgui/source/backends
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/imgui/source/backends')
-rw-r--r--3rdparty/imgui/source/backends/imgui_impl_glfw.cpp576
-rw-r--r--3rdparty/imgui/source/backends/imgui_impl_glfw.h7
-rw-r--r--3rdparty/imgui/source/backends/imgui_impl_opengl2.cpp42
-rw-r--r--3rdparty/imgui/source/backends/imgui_impl_opengl2.h1
-rw-r--r--3rdparty/imgui/source/backends/imgui_impl_opengl3.cpp42
-rw-r--r--3rdparty/imgui/source/backends/imgui_impl_opengl3.h3
6 files changed, 634 insertions, 37 deletions
diff --git a/3rdparty/imgui/source/backends/imgui_impl_glfw.cpp b/3rdparty/imgui/source/backends/imgui_impl_glfw.cpp
index 68f1188..02706c7 100644
--- a/3rdparty/imgui/source/backends/imgui_impl_glfw.cpp
+++ b/3rdparty/imgui/source/backends/imgui_impl_glfw.cpp
@@ -1,13 +1,17 @@
// dear imgui: Platform Backend for GLFW
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..)
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
-// (Requires: GLFW 3.1+)
+// (Requires: GLFW 3.1+. Prefer GLFW 3.3+ for full feature support.)
// Implemented features:
// [X] Platform: Clipboard support.
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
+// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
+
+// Issues:
+// [ ] Platform: Multi-viewport support: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
@@ -16,7 +20,9 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
-// 2022-02-07: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing callbacks after iniitializing backend.
+// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
+// 2022-03-23: Inputs: Fixed a regression in 1.87 which resulted in keyboard modifiers events being reported incorrectly on Linux/X11.
+// 2022-02-07: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing callbacks after initializing backend.
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
@@ -69,11 +75,25 @@
#define GLFW_EXPOSE_NATIVE_WIN32
#include <GLFW/glfw3native.h> // for glfwGetWin32Window
#endif
+#define GLFW_HAS_WINDOW_TOPMOST (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ GLFW_FLOATING
+#define GLFW_HAS_WINDOW_HOVERED (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ GLFW_HOVERED
+#define GLFW_HAS_WINDOW_ALPHA (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwSetWindowOpacity
+#define GLFW_HAS_PER_MONITOR_DPI (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetMonitorContentScale
+#define GLFW_HAS_VULKAN (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwCreateWindowSurface
+#define GLFW_HAS_FOCUS_WINDOW (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwFocusWindow
+#define GLFW_HAS_FOCUS_ON_SHOW (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ GLFW_FOCUS_ON_SHOW
+#define GLFW_HAS_MONITOR_WORK_AREA (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetMonitorWorkarea
+#define GLFW_HAS_OSX_WINDOW_POS_FIX (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 + GLFW_VERSION_REVISION * 10 >= 3310) // 3.3.1+ Fixed: Resizing window repositions it on MacOS #1553
#ifdef GLFW_RESIZE_NESW_CURSOR // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2019-11-29 (cursors defines) // FIXME: Remove when GLFW 3.4 is released?
#define GLFW_HAS_NEW_CURSORS (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3400) // 3.4+ GLFW_RESIZE_ALL_CURSOR, GLFW_RESIZE_NESW_CURSOR, GLFW_RESIZE_NWSE_CURSOR, GLFW_NOT_ALLOWED_CURSOR
#else
#define GLFW_HAS_NEW_CURSORS (0)
#endif
+#ifdef GLFW_MOUSE_PASSTHROUGH // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2020-07-17 (passthrough)
+#define GLFW_HAS_MOUSE_PASSTHROUGH (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3400) // 3.4+ GLFW_MOUSE_PASSTHROUGH
+#else
+#define GLFW_HAS_MOUSE_PASSTHROUGH (0)
+#endif
#define GLFW_HAS_GAMEPAD_API (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetGamepadState() new api
#define GLFW_HAS_GET_KEY_NAME (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwGetKeyName()
@@ -93,7 +113,9 @@ struct ImGui_ImplGlfw_Data
GLFWwindow* MouseWindow;
GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT];
ImVec2 LastValidMousePos;
+ GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST];
bool InstalledCallbacks;
+ bool WantUpdateMonitors;
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
GLFWwindowfocusfun PrevUserCallbackWindowFocus;
@@ -105,7 +127,7 @@ struct ImGui_ImplGlfw_Data
GLFWcharfun PrevUserCallbackChar;
GLFWmonitorfun PrevUserCallbackMonitor;
- ImGui_ImplGlfw_Data() { memset(this, 0, sizeof(*this)); }
+ ImGui_ImplGlfw_Data() { memset((void*)this, 0, sizeof(*this)); }
};
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
@@ -120,6 +142,11 @@ static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData()
return ImGui::GetCurrentContext() ? (ImGui_ImplGlfw_Data*)ImGui::GetIO().BackendPlatformUserData : NULL;
}
+// Forward Declarations
+static void ImGui_ImplGlfw_UpdateMonitors();
+static void ImGui_ImplGlfw_InitPlatformInterface();
+static void ImGui_ImplGlfw_ShutdownPlatformInterface();
+
// Functions
static const char* ImGui_ImplGlfw_GetClipboardText(void* user_data)
{
@@ -131,6 +158,7 @@ static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text)
glfwSetClipboardString((GLFWwindow*)user_data, text);
}
+// CUSTOM ADDITIONS
ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int key)
{
switch (key)
@@ -244,6 +272,19 @@ ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int key)
}
}
+static int ImGui_ImplGlfw_KeyToModifier(int key)
+{
+ if (key == GLFW_KEY_LEFT_CONTROL || key == GLFW_KEY_RIGHT_CONTROL)
+ return GLFW_MOD_CONTROL;
+ if (key == GLFW_KEY_LEFT_SHIFT || key == GLFW_KEY_RIGHT_SHIFT)
+ return GLFW_MOD_SHIFT;
+ if (key == GLFW_KEY_LEFT_ALT || key == GLFW_KEY_RIGHT_ALT)
+ return GLFW_MOD_ALT;
+ if (key == GLFW_KEY_LEFT_SUPER || key == GLFW_KEY_RIGHT_SUPER)
+ return GLFW_MOD_SUPER;
+ return 0;
+}
+
static void ImGui_ImplGlfw_UpdateKeyModifiers(int mods)
{
ImGuiIO& io = ImGui::GetIO();
@@ -312,8 +353,14 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, i
if (action != GLFW_PRESS && action != GLFW_RELEASE)
return;
+ // Workaround: X11 does not include current pressed/released modifier key in 'mods' flags. https://github.com/glfw/glfw/issues/1630
+ if (int keycode_to_mod = ImGui_ImplGlfw_KeyToModifier(keycode))
+ mods = (action == GLFW_PRESS) ? (mods | keycode_to_mod) : (mods & ~keycode_to_mod);
ImGui_ImplGlfw_UpdateKeyModifiers(mods);
+ if (keycode >= 0 && keycode < IM_ARRAYSIZE(bd->KeyOwnerWindows))
+ bd->KeyOwnerWindows[keycode] = (action == GLFW_PRESS) ? window : NULL;
+
keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode);
ImGuiIO& io = ImGui::GetIO();
@@ -339,6 +386,13 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
bd->PrevUserCallbackCursorPos(window, x, y);
ImGuiIO& io = ImGui::GetIO();
+ if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
+ {
+ int window_x, window_y;
+ glfwGetWindowPos(window, &window_x, &window_y);
+ x += window_x;
+ y += window_y;
+ }
io.AddMousePosEvent((float)x, (float)y);
bd->LastValidMousePos = ImVec2((float)x, (float)y);
}
@@ -377,7 +431,8 @@ void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c)
void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int)
{
- // Unused in 'master' branch but 'docking' branch will use this, so we declare it ahead of it so if you have to install callbacks you can install this one too.
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
+ bd->WantUpdateMonitors = true;
}
void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
@@ -433,19 +488,19 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
io.BackendPlatformName = "imgui_impl_glfw";
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
+ io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
+#if GLFW_HAS_MOUSE_PASSTHROUGH || (GLFW_HAS_WINDOW_HOVERED && defined(_WIN32))
+ io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
+#endif
bd->Window = window;
bd->Time = 0.0;
+ bd->WantUpdateMonitors = true;
io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText;
io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText;
io.ClipboardUserData = bd->Window;
- // Set platform dependent data in viewport
-#if defined(_WIN32)
- ImGui::GetMainViewport()->PlatformHandleRaw = (void*)glfwGetWin32Window(bd->Window);
-#endif
-
// Create mouse cursors
// (By design, on X11 cursors are user configurable and some cursors may be missing. When a cursor doesn't exist,
// GLFW will emit an error which will often be printed by the app, so we temporarily disable error reporting.
@@ -473,6 +528,19 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
if (install_callbacks)
ImGui_ImplGlfw_InstallCallbacks(window);
+ // Update monitors the first time (note: monitor callback are broken in GLFW 3.2 and earlier, see github.com/glfw/glfw/issues/784)
+ ImGui_ImplGlfw_UpdateMonitors();
+ glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback);
+
+ // Our mouse update function expect PlatformHandle to be filled for the main viewport
+ ImGuiViewport* main_viewport = ImGui::GetMainViewport();
+ main_viewport->PlatformHandle = (void*)bd->Window;
+#ifdef _WIN32
+ main_viewport->PlatformHandleRaw = glfwGetWin32Window(bd->Window);
+#endif
+ if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
+ ImGui_ImplGlfw_InitPlatformInterface();
+
bd->ClientApi = client_api;
return true;
}
@@ -498,6 +566,8 @@ void ImGui_ImplGlfw_Shutdown()
IM_ASSERT(bd != NULL && "No platform backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO();
+ ImGui_ImplGlfw_ShutdownPlatformInterface();
+
if (bd->InstalledCallbacks)
ImGui_ImplGlfw_RestoreCallbacks(bd->Window);
@@ -513,27 +583,70 @@ static void ImGui_ImplGlfw_UpdateMouseData()
{
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
ImGuiIO& io = ImGui::GetIO();
+ ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
+
+ ImGuiID mouse_viewport_id = 0;
+ const ImVec2 mouse_pos_prev = io.MousePos;
+ for (int n = 0; n < platform_io.Viewports.Size; n++)
+ {
+ ImGuiViewport* viewport = platform_io.Viewports[n];
+ GLFWwindow* window = (GLFWwindow*)viewport->PlatformHandle;
#ifdef __EMSCRIPTEN__
- const bool is_app_focused = true;
+ const bool is_window_focused = true;
#else
- const bool is_app_focused = glfwGetWindowAttrib(bd->Window, GLFW_FOCUSED) != 0;
+ const bool is_window_focused = glfwGetWindowAttrib(window, GLFW_FOCUSED) != 0;
#endif
- if (is_app_focused)
- {
- // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
- if (io.WantSetMousePos)
- glfwSetCursorPos(bd->Window, (double)io.MousePos.x, (double)io.MousePos.y);
-
- // (Optional) Fallback to provide mouse position when focused (ImGui_ImplGlfw_CursorPosCallback already provides this when hovered or captured)
- if (is_app_focused && bd->MouseWindow == NULL)
+ if (is_window_focused)
{
- double mouse_x, mouse_y;
- glfwGetCursorPos(bd->Window, &mouse_x, &mouse_y);
- io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
- bd->LastValidMousePos = ImVec2((float)mouse_x, (float)mouse_y);
+ // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
+ // When multi-viewports are enabled, all Dear ImGui positions are same as OS positions.
+ if (io.WantSetMousePos)
+ glfwSetCursorPos(window, (double)(mouse_pos_prev.x - viewport->Pos.x), (double)(mouse_pos_prev.y - viewport->Pos.y));
+
+ // (Optional) Fallback to provide mouse position when focused (ImGui_ImplGlfw_CursorPosCallback already provides this when hovered or captured)
+ if (bd->MouseWindow == NULL)
+ {
+ double mouse_x, mouse_y;
+ glfwGetCursorPos(window, &mouse_x, &mouse_y);
+ if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
+ {
+ // Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
+ // Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
+ int window_x, window_y;
+ glfwGetWindowPos(window, &window_x, &window_y);
+ mouse_x += window_x;
+ mouse_y += window_y;
+ }
+ bd->LastValidMousePos = ImVec2((float)mouse_x, (float)mouse_y);
+ io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
+ }
}
+
+ // (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
+ // If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
+ // - [X] GLFW >= 3.3 backend ON WINDOWS ONLY does correctly ignore viewports with the _NoInputs flag.
+ // - [!] GLFW <= 3.2 backend CANNOT correctly ignore viewports with the _NoInputs flag, and CANNOT reported Hovered Viewport because of mouse capture.
+ // Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
+ // for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
+ // by the backend, and use its flawed heuristic to guess the viewport behind.
+ // - [X] GLFW backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
+ // FIXME: This is currently only correct on Win32. See what we do below with the WM_NCHITTEST, missing an equivalent for other systems.
+ // See https://github.com/glfw/glfw/issues/1236 if you want to help in making this a GLFW feature.
+#if GLFW_HAS_MOUSE_PASSTHROUGH || (GLFW_HAS_WINDOW_HOVERED && defined(_WIN32))
+ const bool window_no_input = (viewport->Flags & ImGuiViewportFlags_NoInputs) != 0;
+#if GLFW_HAS_MOUSE_PASSTHROUGH
+ glfwSetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH, window_no_input);
+#endif
+ if (glfwGetWindowAttrib(window, GLFW_HOVERED) && !window_no_input)
+ mouse_viewport_id = viewport->ID;
+#else
+ // We cannot use bd->MouseWindow maintained from CursorEnter/Leave callbacks, because it is locked to the window capturing mouse.
+#endif
}
+
+ if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)
+ io.AddMouseViewportEvent(mouse_viewport_id);
}
static void ImGui_ImplGlfw_UpdateMouseCursor()
@@ -544,17 +657,22 @@ static void ImGui_ImplGlfw_UpdateMouseCursor()
return;
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
- if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
+ ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
+ for (int n = 0; n < platform_io.Viewports.Size; n++)
{
- // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
- glfwSetInputMode(bd->Window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
- }
- else
- {
- // Show OS mouse cursor
- // FIXME-PLATFORM: Unfocused windows seems to fail changing the mouse cursor with GLFW 3.2, but 3.3 works here.
- glfwSetCursor(bd->Window, bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow]);
- glfwSetInputMode(bd->Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
+ GLFWwindow* window = (GLFWwindow*)platform_io.Viewports[n]->PlatformHandle;
+ if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
+ {
+ // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
+ glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
+ }
+ else
+ {
+ // Show OS mouse cursor
+ // FIXME-PLATFORM: Unfocused windows seems to fail changing the mouse cursor with GLFW 3.2, but 3.3 works here.
+ glfwSetCursor(window, bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow]);
+ glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
+ }
}
}
@@ -611,6 +729,41 @@ static void ImGui_ImplGlfw_UpdateGamepads()
#undef MAP_ANALOG
}
+static void ImGui_ImplGlfw_UpdateMonitors()
+{
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
+ ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
+ int monitors_count = 0;
+ GLFWmonitor** glfw_monitors = glfwGetMonitors(&monitors_count);
+ platform_io.Monitors.resize(0);
+ for (int n = 0; n < monitors_count; n++)
+ {
+ ImGuiPlatformMonitor monitor;
+ int x, y;
+ glfwGetMonitorPos(glfw_monitors[n], &x, &y);
+ const GLFWvidmode* vid_mode = glfwGetVideoMode(glfw_monitors[n]);
+ monitor.MainPos = monitor.WorkPos = ImVec2((float)x, (float)y);
+ monitor.MainSize = monitor.WorkSize = ImVec2((float)vid_mode->width, (float)vid_mode->height);
+#if GLFW_HAS_MONITOR_WORK_AREA
+ int w, h;
+ glfwGetMonitorWorkarea(glfw_monitors[n], &x, &y, &w, &h);
+ if (w > 0 && h > 0) // Workaround a small GLFW issue reporting zero on monitor changes: https://github.com/glfw/glfw/pull/1761
+ {
+ monitor.WorkPos = ImVec2((float)x, (float)y);
+ monitor.WorkSize = ImVec2((float)w, (float)h);
+ }
+#endif
+#if GLFW_HAS_PER_MONITOR_DPI
+ // Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime.
+ float x_scale, y_scale;
+ glfwGetMonitorContentScale(glfw_monitors[n], &x_scale, &y_scale);
+ monitor.DpiScale = x_scale;
+#endif
+ platform_io.Monitors.push_back(monitor);
+ }
+ bd->WantUpdateMonitors = false;
+}
+
void ImGui_ImplGlfw_NewFrame()
{
ImGuiIO& io = ImGui::GetIO();
@@ -625,6 +778,8 @@ void ImGui_ImplGlfw_NewFrame()
io.DisplaySize = ImVec2((float)w, (float)h);
if (w > 0 && h > 0)
io.DisplayFramebufferScale = ImVec2((float)display_w / (float)w, (float)display_h / (float)h);
+ if (bd->WantUpdateMonitors)
+ ImGui_ImplGlfw_UpdateMonitors();
// Setup time step
double current_time = glfwGetTime();
@@ -638,6 +793,361 @@ void ImGui_ImplGlfw_NewFrame()
ImGui_ImplGlfw_UpdateGamepads();
}
+//--------------------------------------------------------------------------------------------------------
+// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
+// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
+// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
+//--------------------------------------------------------------------------------------------------------
+
+// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data.
+struct ImGui_ImplGlfw_ViewportData
+{
+ GLFWwindow* Window;
+ bool WindowOwned;
+ int IgnoreWindowPosEventFrame;
+ int IgnoreWindowSizeEventFrame;
+
+ ImGui_ImplGlfw_ViewportData() { Window = NULL; WindowOwned = false; IgnoreWindowSizeEventFrame = IgnoreWindowPosEventFrame = -1; }
+ ~ImGui_ImplGlfw_ViewportData() { IM_ASSERT(Window == NULL); }
+};
+
+static void ImGui_ImplGlfw_WindowCloseCallback(GLFWwindow* window)
+{
+ if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
+ viewport->PlatformRequestClose = true;
+}
+
+// GLFW may dispatch window pos/size events after calling glfwSetWindowPos()/glfwSetWindowSize().
+// However: depending on the platform the callback may be invoked at different time:
+// - on Windows it appears to be called within the glfwSetWindowPos()/glfwSetWindowSize() call
+// - on Linux it is queued and invoked during glfwPollEvents()
+// Because the event doesn't always fire on glfwSetWindowXXX() we use a frame counter tag to only
+// ignore recent glfwSetWindowXXX() calls.
+static void ImGui_ImplGlfw_WindowPosCallback(GLFWwindow* window, int, int)
+{
+ if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
+ {
+ if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData)
+ {
+ bool ignore_event = (ImGui::GetFrameCount() <= vd->IgnoreWindowPosEventFrame + 1);
+ //data->IgnoreWindowPosEventFrame = -1;
+ if (ignore_event)
+ return;
+ }
+ viewport->PlatformRequestMove = true;
+ }
+}
+
+static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int)
+{
+ if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
+ {
+ if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData)
+ {
+ bool ignore_event = (ImGui::GetFrameCount() <= vd->IgnoreWindowSizeEventFrame + 1);
+ //data->IgnoreWindowSizeEventFrame = -1;
+ if (ignore_event)
+ return;
+ }
+ viewport->PlatformRequestResize = true;
+ }
+}
+
+static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
+{
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
+ ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)();
+ viewport->PlatformUserData = vd;
+
+ // GLFW 3.2 unfortunately always set focus on glfwCreateWindow() if GLFW_VISIBLE is set, regardless of GLFW_FOCUSED
+ // With GLFW 3.3, the hint GLFW_FOCUS_ON_SHOW fixes this problem
+ glfwWindowHint(GLFW_VISIBLE, false);
+ glfwWindowHint(GLFW_FOCUSED, false);
+#if GLFW_HAS_FOCUS_ON_SHOW
+ glfwWindowHint(GLFW_FOCUS_ON_SHOW, false);
+ #endif
+ glfwWindowHint(GLFW_DECORATED, (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? false : true);
+#if GLFW_HAS_WINDOW_TOPMOST
+ glfwWindowHint(GLFW_FLOATING, (viewport->Flags & ImGuiViewportFlags_TopMost) ? true : false);
+#endif
+ GLFWwindow* share_window = (bd->ClientApi == GlfwClientApi_OpenGL) ? bd->Window : NULL;
+ vd->Window = glfwCreateWindow((int)viewport->Size.x, (int)viewport->Size.y, "No Title Yet", NULL, share_window);
+ vd->WindowOwned = true;
+ viewport->PlatformHandle = (void*)vd->Window;
+#ifdef _WIN32
+ viewport->PlatformHandleRaw = glfwGetWin32Window(vd->Window);
+#endif
+ glfwSetWindowPos(vd->Window, (int)viewport->Pos.x, (int)viewport->Pos.y);
+
+ // Install GLFW callbacks for secondary viewports
+ glfwSetWindowFocusCallback(vd->Window, ImGui_ImplGlfw_WindowFocusCallback);
+ glfwSetCursorEnterCallback(vd->Window, ImGui_ImplGlfw_CursorEnterCallback);
+ glfwSetCursorPosCallback(vd->Window, ImGui_ImplGlfw_CursorPosCallback);
+ glfwSetMouseButtonCallback(vd->Window, ImGui_ImplGlfw_MouseButtonCallback);
+ glfwSetScrollCallback(vd->Window, ImGui_ImplGlfw_ScrollCallback);
+ glfwSetKeyCallback(vd->Window, ImGui_ImplGlfw_KeyCallback);
+ glfwSetCharCallback(vd->Window, ImGui_ImplGlfw_CharCallback);
+ glfwSetWindowCloseCallback(vd->Window, ImGui_ImplGlfw_WindowCloseCallback);
+ glfwSetWindowPosCallback(vd->Window, ImGui_ImplGlfw_WindowPosCallback);
+ glfwSetWindowSizeCallback(vd->Window, ImGui_ImplGlfw_WindowSizeCallback);
+ if (bd->ClientApi == GlfwClientApi_OpenGL)
+ {
+ glfwMakeContextCurrent(vd->Window);
+ glfwSwapInterval(0);
+ }
+}
+
+static void ImGui_ImplGlfw_DestroyWindow(ImGuiViewport* viewport)
+{
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
+ if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData)
+ {
+ if (vd->WindowOwned)
+ {
+#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED && defined(_WIN32)
+ HWND hwnd = (HWND)viewport->PlatformHandleRaw;
+ ::RemovePropA(hwnd, "IMGUI_VIEWPORT");
+#endif
+
+ // Release any keys that were pressed in the window being destroyed and are still held down,
+ // because we will not receive any release events after window is destroyed.
+ for (int i = 0; i < IM_ARRAYSIZE(bd->KeyOwnerWindows); i++)
+ if (bd->KeyOwnerWindows[i] == vd->Window)
+ ImGui_ImplGlfw_KeyCallback(vd->Window, i, 0, GLFW_RELEASE, 0); // Later params are only used for main viewport, on which this function is never called.
+
+ glfwDestroyWindow(vd->Window);
+ }
+ vd->Window = NULL;
+ IM_DELETE(vd);
+ }
+ viewport->PlatformUserData = viewport->PlatformHandle = NULL;
+}
+
+// We have submitted https://github.com/glfw/glfw/pull/1568 to allow GLFW to support "transparent inputs".
+// In the meanwhile we implement custom per-platform workarounds here (FIXME-VIEWPORT: Implement same work-around for Linux/OSX!)
+#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED && defined(_WIN32)
+static WNDPROC g_GlfwWndProc = NULL;
+static LRESULT CALLBACK WndProcNoInputs(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (msg == WM_NCHITTEST)
+ {
+ // Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() properly (which is OPTIONAL).
+ // The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging.
+ // If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in
+ // your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system.
+ ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT");
+ if (viewport->Flags & ImGuiViewportFlags_NoInputs)
+ return HTTRANSPARENT;
+ }
+ return ::CallWindowProc(g_GlfwWndProc, hWnd, msg, wParam, lParam);
+}
+#endif
+
+static void ImGui_ImplGlfw_ShowWindow(ImGuiViewport* viewport)
+{
+ ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
+
+#if defined(_WIN32)
+ // GLFW hack: Hide icon from task bar
+ HWND hwnd = (HWND)viewport->PlatformHandleRaw;
+ if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon)
+ {
+ LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
+ ex_style &= ~WS_EX_APPWINDOW;
+ ex_style |= WS_EX_TOOLWINDOW;
+ ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
+ }
+
+ // GLFW hack: install hook for WM_NCHITTEST message handler
+#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED && defined(_WIN32)
+ ::SetPropA(hwnd, "IMGUI_VIEWPORT", viewport);
+ if (g_GlfwWndProc == NULL)
+ g_GlfwWndProc = (WNDPROC)::GetWindowLongPtr(hwnd, GWLP_WNDPROC);
+ ::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)WndProcNoInputs);
+#endif
+
+#if !GLFW_HAS_FOCUS_ON_SHOW
+ // GLFW hack: GLFW 3.2 has a bug where glfwShowWindow() also activates/focus the window.
+ // The fix was pushed to GLFW repository on 2018/01/09 and should be included in GLFW 3.3 via a GLFW_FOCUS_ON_SHOW window attribute.
+ // See https://github.com/glfw/glfw/issues/1189
+ // FIXME-VIEWPORT: Implement same work-around for Linux/OSX in the meanwhile.
+ if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
+ {
+ ::ShowWindow(hwnd, SW_SHOWNA);
+ return;
+ }
+#endif
+#endif
+
+ glfwShowWindow(vd->Window);
+}
+
+static ImVec2 ImGui_ImplGlfw_GetWindowPos(ImGuiViewport* viewport)
+{
+ ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
+ int x = 0, y = 0;
+ glfwGetWindowPos(vd->Window, &x, &y);
+ return ImVec2((float)x, (float)y);
+}
+
+static void ImGui_ImplGlfw_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
+{
+ ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
+ vd->IgnoreWindowPosEventFrame = ImGui::GetFrameCount();
+ glfwSetWindowPos(vd->Window, (int)pos.x, (int)pos.y);
+}
+
+static ImVec2 ImGui_ImplGlfw_GetWindowSize(ImGuiViewport* viewport)
+{
+ ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
+ int w = 0, h = 0;
+ glfwGetWindowSize(vd->Window, &w, &h);
+ return ImVec2((float)w, (float)h);
+}
+
+static void ImGui_ImplGlfw_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
+{
+ ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
+#if __APPLE__ && !GLFW_HAS_OSX_WINDOW_POS_FIX
+ // Native OS windows are positioned from the bottom-left corner on macOS, whereas on other platforms they are
+ // positioned from the upper-left corner. GLFW makes an effort to convert macOS style coordinates, however it
+ // doesn't handle it when changing size. We are manually moving the window in order for changes of size to be based
+ // on the upper-left corner.
+ int x, y, width, height;
+ glfwGetWindowPos(vd->Window, &x, &y);
+ glfwGetWindowSize(vd->Window, &width, &height);
+ glfwSetWindowPos(vd->Window, x, y - height + size.y);
+#endif
+ vd->IgnoreWindowSizeEventFrame = ImGui::GetFrameCount();
+ glfwSetWindowSize(vd->Window, (int)size.x, (int)size.y);
+}
+
+static void ImGui_ImplGlfw_SetWindowTitle(ImGuiViewport* viewport, const char* title)
+{
+ ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
+ glfwSetWindowTitle(vd->Window, title);
+}
+
+static void ImGui_ImplGlfw_SetWindowFocus(ImGuiViewport* viewport)
+{
+#if GLFW_HAS_FOCUS_WINDOW
+ ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
+ glfwFocusWindow(vd->Window);
+#else
+ // FIXME: What are the effect of not having this function? At the moment imgui doesn't actually call SetWindowFocus - we set that up ahead, will answer that question later.
+ (void)viewport;
+#endif
+}
+
+static bool ImGui_ImplGlfw_GetWindowFocus(ImGuiViewport* viewport)
+{
+ ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
+ return glfwGetWindowAttrib(vd->Window, GLFW_FOCUSED) != 0;
+}
+
+static bool ImGui_ImplGlfw_GetWindowMinimized(ImGuiViewport* viewport)
+{
+ ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
+ return glfwGetWindowAttrib(vd->Window, GLFW_ICONIFIED) != 0;
+}
+
+#if GLFW_HAS_WINDOW_ALPHA
+static void ImGui_ImplGlfw_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
+{
+ ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
+ glfwSetWindowOpacity(vd->Window, alpha);
+}
+#endif
+
+static void ImGui_ImplGlfw_RenderWindow(ImGuiViewport* viewport, void*)
+{
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
+ ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
+ if (bd->ClientApi == GlfwClientApi_OpenGL)
+ glfwMakeContextCurrent(vd->Window);
+}
+
+static void ImGui_ImplGlfw_SwapBuffers(ImGuiViewport* viewport, void*)
+{
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
+ ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
+ if (bd->ClientApi == GlfwClientApi_OpenGL)
+ {
+ glfwMakeContextCurrent(vd->Window);
+ glfwSwapBuffers(vd->Window);
+ }
+}
+
+//--------------------------------------------------------------------------------------------------------
+// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface)
+//--------------------------------------------------------------------------------------------------------
+
+// Avoid including <vulkan.h> so we can build without it
+#if GLFW_HAS_VULKAN
+#ifndef VULKAN_H_
+#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
+#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
+#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
+#else
+#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
+#endif
+VK_DEFINE_HANDLE(VkInstance)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
+struct VkAllocationCallbacks;
+enum VkResult { VK_RESULT_MAX_ENUM = 0x7FFFFFFF };
+#endif // VULKAN_H_
+extern "C" { extern GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); }
+static int ImGui_ImplGlfw_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface)
+{
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
+ ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
+ IM_UNUSED(bd);
+ IM_ASSERT(bd->ClientApi == GlfwClientApi_Vulkan);
+ VkResult err = glfwCreateWindowSurface((VkInstance)vk_instance, vd->Window, (const VkAllocationCallbacks*)vk_allocator, (VkSurfaceKHR*)out_vk_surface);
+ return (int)err;
+}
+#endif // GLFW_HAS_VULKAN
+
+static void ImGui_ImplGlfw_InitPlatformInterface()
+{
+ // Register platform interface (will be coupled with a renderer interface)
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
+ ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
+ platform_io.Platform_CreateWindow = ImGui_ImplGlfw_CreateWindow;
+ platform_io.Platform_DestroyWindow = ImGui_ImplGlfw_DestroyWindow;
+ platform_io.Platform_ShowWindow = ImGui_ImplGlfw_ShowWindow;
+ platform_io.Platform_SetWindowPos = ImGui_ImplGlfw_SetWindowPos;
+ platform_io.Platform_GetWindowPos = ImGui_ImplGlfw_GetWindowPos;
+ platform_io.Platform_SetWindowSize = ImGui_ImplGlfw_SetWindowSize;
+ platform_io.Platform_GetWindowSize = ImGui_ImplGlfw_GetWindowSize;
+ platform_io.Platform_SetWindowFocus = ImGui_ImplGlfw_SetWindowFocus;
+ platform_io.Platform_GetWindowFocus = ImGui_ImplGlfw_GetWindowFocus;
+ platform_io.Platform_GetWindowMinimized = ImGui_ImplGlfw_GetWindowMinimized;
+ platform_io.Platform_SetWindowTitle = ImGui_ImplGlfw_SetWindowTitle;
+ platform_io.Platform_RenderWindow = ImGui_ImplGlfw_RenderWindow;
+ platform_io.Platform_SwapBuffers = ImGui_ImplGlfw_SwapBuffers;
+#if GLFW_HAS_WINDOW_ALPHA
+ platform_io.Platform_SetWindowAlpha = ImGui_ImplGlfw_SetWindowAlpha;
+#endif
+#if GLFW_HAS_VULKAN
+ platform_io.Platform_CreateVkSurface = ImGui_ImplGlfw_CreateVkSurface;
+#endif
+
+ // Register main window handle (which is owned by the main application, not by us)
+ // This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports.
+ ImGuiViewport* main_viewport = ImGui::GetMainViewport();
+ ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)();
+ vd->Window = bd->Window;
+ vd->WindowOwned = false;
+ main_viewport->PlatformUserData = vd;
+ main_viewport->PlatformHandle = (void*)bd->Window;
+}
+
+static void ImGui_ImplGlfw_ShutdownPlatformInterface()
+{
+ ImGui::DestroyPlatformWindows();
+}
+
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
diff --git a/3rdparty/imgui/source/backends/imgui_impl_glfw.h b/3rdparty/imgui/source/backends/imgui_impl_glfw.h
index 86811ef..13b3896 100644
--- a/3rdparty/imgui/source/backends/imgui_impl_glfw.h
+++ b/3rdparty/imgui/source/backends/imgui_impl_glfw.h
@@ -1,12 +1,17 @@
// dear imgui: Platform Backend for GLFW
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..)
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
+// (Requires: GLFW 3.1+. Prefer GLFW 3.3+ for full feature support.)
// Implemented features:
// [X] Platform: Clipboard support.
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
-// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
+// [x] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
+// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
+
+// Issues:
+// [ ] Platform: Multi-viewport support: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
diff --git a/3rdparty/imgui/source/backends/imgui_impl_opengl2.cpp b/3rdparty/imgui/source/backends/imgui_impl_opengl2.cpp
index 17a6fae..6f906d2 100644
--- a/3rdparty/imgui/source/backends/imgui_impl_opengl2.cpp
+++ b/3rdparty/imgui/source/backends/imgui_impl_opengl2.cpp
@@ -3,6 +3,7 @@
// Implemented features:
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
+// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
@@ -19,6 +20,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
+// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2021-12-08: OpenGL: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
@@ -61,7 +63,7 @@ struct ImGui_ImplOpenGL2_Data
{
GLuint FontTexture;
- ImGui_ImplOpenGL2_Data() { memset(this, 0, sizeof(*this)); }
+ ImGui_ImplOpenGL2_Data() { memset((void*)this, 0, sizeof(*this)); }
};
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
@@ -71,6 +73,10 @@ static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData()
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL2_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
}
+// Forward Declarations
+static void ImGui_ImplOpenGL2_InitPlatformInterface();
+static void ImGui_ImplOpenGL2_ShutdownPlatformInterface();
+
// Functions
bool ImGui_ImplOpenGL2_Init()
{
@@ -81,6 +87,10 @@ bool ImGui_ImplOpenGL2_Init()
ImGui_ImplOpenGL2_Data* bd = IM_NEW(ImGui_ImplOpenGL2_Data)();
io.BackendRendererUserData = (void*)bd;
io.BackendRendererName = "imgui_impl_opengl2";
+ io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
+
+ if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
+ ImGui_ImplOpenGL2_InitPlatformInterface();
return true;
}
@@ -91,6 +101,7 @@ void ImGui_ImplOpenGL2_Shutdown()
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO();
+ ImGui_ImplOpenGL2_ShutdownPlatformInterface();
ImGui_ImplOpenGL2_DestroyDeviceObjects();
io.BackendRendererName = NULL;
io.BackendRendererUserData = NULL;
@@ -244,6 +255,7 @@ bool ImGui_ImplOpenGL2_CreateFontsTexture()
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
// Upload texture to graphics system
+ // (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
GLint last_texture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
glGenTextures(1, &bd->FontTexture);
@@ -283,3 +295,31 @@ void ImGui_ImplOpenGL2_DestroyDeviceObjects()
{
ImGui_ImplOpenGL2_DestroyFontsTexture();
}
+
+//--------------------------------------------------------------------------------------------------------
+// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
+// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
+// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
+//--------------------------------------------------------------------------------------------------------
+
+static void ImGui_ImplOpenGL2_RenderWindow(ImGuiViewport* viewport, void*)
+{
+ if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
+ {
+ ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
+ glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ ImGui_ImplOpenGL2_RenderDrawData(viewport->DrawData);
+}
+
+static void ImGui_ImplOpenGL2_InitPlatformInterface()
+{
+ ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
+ platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL2_RenderWindow;
+}
+
+static void ImGui_ImplOpenGL2_ShutdownPlatformInterface()
+{
+ ImGui::DestroyPlatformWindows();
+}
diff --git a/3rdparty/imgui/source/backends/imgui_impl_opengl2.h b/3rdparty/imgui/source/backends/imgui_impl_opengl2.h
index d00d27f..780204a 100644
--- a/3rdparty/imgui/source/backends/imgui_impl_opengl2.h
+++ b/3rdparty/imgui/source/backends/imgui_impl_opengl2.h
@@ -3,6 +3,7 @@
// Implemented features:
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
+// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
diff --git a/3rdparty/imgui/source/backends/imgui_impl_opengl3.cpp b/3rdparty/imgui/source/backends/imgui_impl_opengl3.cpp
index 93f057d..1c8425b 100644
--- a/3rdparty/imgui/source/backends/imgui_impl_opengl3.cpp
+++ b/3rdparty/imgui/source/backends/imgui_impl_opengl3.cpp
@@ -9,6 +9,7 @@
// Implemented features:
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
+// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
// [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
@@ -18,6 +19,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
+// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2021-12-15: OpenGL: Using buffer orphaning + glBufferSubData(), seems to fix leaks with multi-viewports with some Intel HD drivers.
// 2021-08-23: OpenGL: Fixed ES 3.0 shader ("#version 300 es") use normal precision floats to avoid wobbly rendering at HD resolutions.
// 2021-08-19: OpenGL: Embed and use our own minimal GL loader (imgui_impl_opengl3_loader.h), removing requirement and support for third-party loader.
@@ -197,7 +199,7 @@ struct ImGui_ImplOpenGL3_Data
GLsizeiptr IndexBufferSize;
bool HasClipOrigin;
- ImGui_ImplOpenGL3_Data() { memset(this, 0, sizeof(*this)); }
+ ImGui_ImplOpenGL3_Data() { memset((void*)this, 0, sizeof(*this)); }
};
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
@@ -207,6 +209,10 @@ static ImGui_ImplOpenGL3_Data* ImGui_ImplOpenGL3_GetBackendData()
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL3_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
}
+// Forward Declarations
+static void ImGui_ImplOpenGL3_InitPlatformInterface();
+static void ImGui_ImplOpenGL3_ShutdownPlatformInterface();
+
// Functions
bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
{
@@ -248,6 +254,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
if (bd->GlVersion >= 320)
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
#endif
+ io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
// Store GLSL version string so we can refer to it later in case we recreate shaders.
// Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure.
@@ -285,6 +292,9 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
}
#endif
+ if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
+ ImGui_ImplOpenGL3_InitPlatformInterface();
+
return true;
}
@@ -294,6 +304,7 @@ void ImGui_ImplOpenGL3_Shutdown()
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO();
+ ImGui_ImplOpenGL3_ShutdownPlatformInterface();
ImGui_ImplOpenGL3_DestroyDeviceObjects();
io.BackendRendererName = NULL;
io.BackendRendererUserData = NULL;
@@ -543,6 +554,7 @@ bool ImGui_ImplOpenGL3_CreateFontsTexture()
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
// Upload texture to graphics system
+ // (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
GLint last_texture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
glGenTextures(1, &bd->FontTexture);
@@ -810,6 +822,34 @@ void ImGui_ImplOpenGL3_DestroyDeviceObjects()
ImGui_ImplOpenGL3_DestroyFontsTexture();
}
+//--------------------------------------------------------------------------------------------------------
+// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
+// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
+// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
+//--------------------------------------------------------------------------------------------------------
+
+static void ImGui_ImplOpenGL3_RenderWindow(ImGuiViewport* viewport, void*)
+{
+ if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
+ {
+ ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
+ glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ ImGui_ImplOpenGL3_RenderDrawData(viewport->DrawData);
+}
+
+static void ImGui_ImplOpenGL3_InitPlatformInterface()
+{
+ ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
+ platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL3_RenderWindow;
+}
+
+static void ImGui_ImplOpenGL3_ShutdownPlatformInterface()
+{
+ ImGui::DestroyPlatformWindows();
+}
+
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
diff --git a/3rdparty/imgui/source/backends/imgui_impl_opengl3.h b/3rdparty/imgui/source/backends/imgui_impl_opengl3.h
index 98c9aca..e7f652f 100644
--- a/3rdparty/imgui/source/backends/imgui_impl_opengl3.h
+++ b/3rdparty/imgui/source/backends/imgui_impl_opengl3.h
@@ -5,6 +5,7 @@
// Implemented features:
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
+// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
// [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
@@ -46,7 +47,7 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
#endif
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__))
#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
-#elif defined(__EMSCRIPTEN__)
+#elif defined(__EMSCRIPTEN__) || defined(__amigaos4__)
#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100"
#else
// Otherwise imgui_impl_opengl3_loader.h will be used.