|
@@ -10,6 +10,7 @@
|
|
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
|
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Resizing cursors requires GLFW 3.4+! Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Resizing cursors requires GLFW 3.4+! Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
|
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
|
|
+// [X] Multiple Dear ImGui contexts support.
|
|
// Missing features or Issues:
|
|
// Missing features or Issues:
|
|
// [ ] Touch events are only correctly identified as Touch on Windows. This create issues with some interactions. GLFW doesn't provide a way to identify touch inputs from mouse inputs, we cannot call io.AddMouseSourceEvent() to identify the source. We provide a Windows-specific workaround.
|
|
// [ ] Touch events are only correctly identified as Touch on Windows. This create issues with some interactions. GLFW doesn't provide a way to identify touch inputs from mouse inputs, we cannot call io.AddMouseSourceEvent() to identify the source. We provide a Windows-specific workaround.
|
|
// [ ] Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors.
|
|
// [ ] Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors.
|
|
@@ -31,6 +32,7 @@
|
|
// CHANGELOG
|
|
// CHANGELOG
|
|
// (minor and older changes stripped away, please see git history for details)
|
|
// (minor and older changes stripped away, please see git history for details)
|
|
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
|
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
|
|
|
+// 2025-06-18: Added support for multiple Dear ImGui contexts. (#8676, #8239, #8069)
|
|
// 2025-06-11: Added ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window) and ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor) helper to facilitate making DPI-aware apps.
|
|
// 2025-06-11: Added ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window) and ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor) helper to facilitate making DPI-aware apps.
|
|
// 2025-05-15: [Docking] Add Platform_GetWindowFramebufferScale() handler, to allow varying Retina display density on multiple monitors.
|
|
// 2025-05-15: [Docking] Add Platform_GetWindowFramebufferScale() handler, to allow varying Retina display density on multiple monitors.
|
|
// 2025-04-26: [Docking] Disable multi-viewports under Wayland. (#8587)
|
|
// 2025-04-26: [Docking] Disable multi-viewports under Wayland. (#8587)
|
|
@@ -168,6 +170,16 @@
|
|
#define GLFW_HAS_GETERROR (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetError()
|
|
#define GLFW_HAS_GETERROR (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetError()
|
|
#define GLFW_HAS_GETPLATFORM (GLFW_VERSION_COMBINED >= 3400) // 3.4+ glfwGetPlatform()
|
|
#define GLFW_HAS_GETPLATFORM (GLFW_VERSION_COMBINED >= 3400) // 3.4+ glfwGetPlatform()
|
|
|
|
|
|
|
|
+// Map GLFWWindow* to ImGuiContext*.
|
|
|
|
+// - Would be simpler if we could use glfwSetWindowUserPointer()/glfwGetWindowUserPointer(), but this is a single and shared resource.
|
|
|
|
+// - Would be simpler if we could use e.g. std::map<> as well. But we don't.
|
|
|
|
+// - This is not particularly optimized as we expect size to be small and queries to be rare.
|
|
|
|
+struct ImGui_ImplGlfw_WindowToContext { GLFWwindow* Window; ImGuiContext* Context; };
|
|
|
|
+static ImVector<ImGui_ImplGlfw_WindowToContext> g_ContextMap;
|
|
|
|
+static void ImGui_ImplGlfw_ContextMap_Add(GLFWwindow* window, ImGuiContext* ctx) { g_ContextMap.push_back(ImGui_ImplGlfw_WindowToContext{ window, ctx }); }
|
|
|
|
+static void ImGui_ImplGlfw_ContextMap_Remove(GLFWwindow* window) { for (ImGui_ImplGlfw_WindowToContext& entry : g_ContextMap) if (entry.Window == window) { g_ContextMap.erase_unsorted(&entry); return; } }
|
|
|
|
+static ImGuiContext* ImGui_ImplGlfw_ContextMap_Get(GLFWwindow* window) { for (ImGui_ImplGlfw_WindowToContext& entry : g_ContextMap) if (entry.Window == window) return entry.Context; return nullptr; }
|
|
|
|
+
|
|
// GLFW data
|
|
// GLFW data
|
|
enum GlfwClientApi
|
|
enum GlfwClientApi
|
|
{
|
|
{
|
|
@@ -178,6 +190,7 @@ enum GlfwClientApi
|
|
|
|
|
|
struct ImGui_ImplGlfw_Data
|
|
struct ImGui_ImplGlfw_Data
|
|
{
|
|
{
|
|
|
|
+ ImGuiContext* Context;
|
|
GLFWwindow* Window;
|
|
GLFWwindow* Window;
|
|
GlfwClientApi ClientApi;
|
|
GlfwClientApi ClientApi;
|
|
double Time;
|
|
double Time;
|
|
@@ -217,10 +230,18 @@ struct ImGui_ImplGlfw_Data
|
|
// (passing install_callbacks=false in ImGui_ImplGlfw_InitXXX functions), set the current dear imgui context and then call our callbacks.
|
|
// (passing install_callbacks=false in ImGui_ImplGlfw_InitXXX functions), set the current dear imgui context and then call our callbacks.
|
|
// - Otherwise we may need to store a GLFWWindow* -> ImGuiContext* map and handle this in the backend, adding a little bit of extra complexity to it.
|
|
// - Otherwise we may need to store a GLFWWindow* -> ImGuiContext* map and handle this in the backend, adding a little bit of extra complexity to it.
|
|
// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
|
|
// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
|
|
|
|
+namespace ImGui { extern ImGuiIO& GetIO(ImGuiContext*); }
|
|
static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData()
|
|
static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData()
|
|
{
|
|
{
|
|
|
|
+ // Get data for current context
|
|
return ImGui::GetCurrentContext() ? (ImGui_ImplGlfw_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
|
return ImGui::GetCurrentContext() ? (ImGui_ImplGlfw_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
|
}
|
|
}
|
|
|
|
+static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData(GLFWwindow* window)
|
|
|
|
+{
|
|
|
|
+ // Get data for a given GLFW window, regardless of current context (since GLFW events are sent together)
|
|
|
|
+ ImGuiContext* ctx = ImGui_ImplGlfw_ContextMap_Get(window);
|
|
|
|
+ return (ImGui_ImplGlfw_Data*)ImGui::GetIO(ctx).BackendPlatformUserData;
|
|
|
|
+}
|
|
|
|
|
|
// Forward Declarations
|
|
// Forward Declarations
|
|
static void ImGui_ImplGlfw_UpdateMonitors();
|
|
static void ImGui_ImplGlfw_UpdateMonitors();
|
|
@@ -361,42 +382,40 @@ ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode)
|
|
|
|
|
|
// X11 does not include current pressed/released modifier key in 'mods' flags submitted by GLFW
|
|
// X11 does not include current pressed/released modifier key in 'mods' flags submitted by GLFW
|
|
// See https://github.com/ocornut/imgui/issues/6034 and https://github.com/glfw/glfw/issues/1630
|
|
// See https://github.com/ocornut/imgui/issues/6034 and https://github.com/glfw/glfw/issues/1630
|
|
-static void ImGui_ImplGlfw_UpdateKeyModifiers(GLFWwindow* window)
|
|
|
|
|
|
+static void ImGui_ImplGlfw_UpdateKeyModifiers(ImGuiIO& io, GLFWwindow* window)
|
|
{
|
|
{
|
|
- ImGuiIO& io = ImGui::GetIO();
|
|
|
|
io.AddKeyEvent(ImGuiMod_Ctrl, (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS));
|
|
io.AddKeyEvent(ImGuiMod_Ctrl, (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS));
|
|
io.AddKeyEvent(ImGuiMod_Shift, (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS));
|
|
io.AddKeyEvent(ImGuiMod_Shift, (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS));
|
|
io.AddKeyEvent(ImGuiMod_Alt, (glfwGetKey(window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_ALT) == GLFW_PRESS));
|
|
io.AddKeyEvent(ImGuiMod_Alt, (glfwGetKey(window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_ALT) == GLFW_PRESS));
|
|
io.AddKeyEvent(ImGuiMod_Super, (glfwGetKey(window, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS));
|
|
io.AddKeyEvent(ImGuiMod_Super, (glfwGetKey(window, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS));
|
|
}
|
|
}
|
|
|
|
|
|
-static bool ImGui_ImplGlfw_ShouldChainCallback(GLFWwindow* window)
|
|
|
|
|
|
+static bool ImGui_ImplGlfw_ShouldChainCallback(ImGui_ImplGlfw_Data* bd, GLFWwindow* window)
|
|
{
|
|
{
|
|
- ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
|
|
return bd->CallbacksChainForAllWindows ? true : (window == bd->Window);
|
|
return bd->CallbacksChainForAllWindows ? true : (window == bd->Window);
|
|
}
|
|
}
|
|
|
|
|
|
void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
|
|
void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
|
|
{
|
|
{
|
|
- ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
|
|
- if (bd->PrevUserCallbackMousebutton != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
|
|
|
|
|
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
|
|
|
+
|
|
|
|
+ if (bd->PrevUserCallbackMousebutton != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
|
bd->PrevUserCallbackMousebutton(window, button, action, mods);
|
|
bd->PrevUserCallbackMousebutton(window, button, action, mods);
|
|
|
|
|
|
// Workaround for Linux: ignore mouse up events which are following an focus loss following a viewport creation
|
|
// Workaround for Linux: ignore mouse up events which are following an focus loss following a viewport creation
|
|
if (bd->MouseIgnoreButtonUp && action == GLFW_RELEASE)
|
|
if (bd->MouseIgnoreButtonUp && action == GLFW_RELEASE)
|
|
return;
|
|
return;
|
|
|
|
|
|
- ImGui_ImplGlfw_UpdateKeyModifiers(window);
|
|
|
|
-
|
|
|
|
- ImGuiIO& io = ImGui::GetIO();
|
|
|
|
|
|
+ ImGuiIO& io = ImGui::GetIO(bd->Context);
|
|
|
|
+ ImGui_ImplGlfw_UpdateKeyModifiers(io, window);
|
|
if (button >= 0 && button < ImGuiMouseButton_COUNT)
|
|
if (button >= 0 && button < ImGuiMouseButton_COUNT)
|
|
io.AddMouseButtonEvent(button, action == GLFW_PRESS);
|
|
io.AddMouseButtonEvent(button, action == GLFW_PRESS);
|
|
}
|
|
}
|
|
|
|
|
|
void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset)
|
|
void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset)
|
|
{
|
|
{
|
|
- ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
|
|
- if (bd->PrevUserCallbackScroll != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
|
|
|
|
|
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
|
|
|
+ if (bd->PrevUserCallbackScroll != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
|
bd->PrevUserCallbackScroll(window, xoffset, yoffset);
|
|
bd->PrevUserCallbackScroll(window, xoffset, yoffset);
|
|
|
|
|
|
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
|
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
|
@@ -404,7 +423,7 @@ void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yo
|
|
return;
|
|
return;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- ImGuiIO& io = ImGui::GetIO();
|
|
|
|
|
|
+ ImGuiIO& io = ImGui::GetIO(bd->Context);
|
|
io.AddMouseWheelEvent((float)xoffset, (float)yoffset);
|
|
io.AddMouseWheelEvent((float)xoffset, (float)yoffset);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -444,21 +463,21 @@ static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode)
|
|
|
|
|
|
void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, int action, int mods)
|
|
void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, int action, int mods)
|
|
{
|
|
{
|
|
- ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
|
|
- if (bd->PrevUserCallbackKey != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
|
|
|
|
|
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
|
|
|
+ if (bd->PrevUserCallbackKey != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
|
bd->PrevUserCallbackKey(window, keycode, scancode, action, mods);
|
|
bd->PrevUserCallbackKey(window, keycode, scancode, action, mods);
|
|
|
|
|
|
if (action != GLFW_PRESS && action != GLFW_RELEASE)
|
|
if (action != GLFW_PRESS && action != GLFW_RELEASE)
|
|
return;
|
|
return;
|
|
|
|
|
|
- ImGui_ImplGlfw_UpdateKeyModifiers(window);
|
|
|
|
|
|
+ ImGuiIO& io = ImGui::GetIO(bd->Context);
|
|
|
|
+ ImGui_ImplGlfw_UpdateKeyModifiers(io, window);
|
|
|
|
|
|
if (keycode >= 0 && keycode < IM_ARRAYSIZE(bd->KeyOwnerWindows))
|
|
if (keycode >= 0 && keycode < IM_ARRAYSIZE(bd->KeyOwnerWindows))
|
|
bd->KeyOwnerWindows[keycode] = (action == GLFW_PRESS) ? window : nullptr;
|
|
bd->KeyOwnerWindows[keycode] = (action == GLFW_PRESS) ? window : nullptr;
|
|
|
|
|
|
keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode);
|
|
keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode);
|
|
|
|
|
|
- ImGuiIO& io = ImGui::GetIO();
|
|
|
|
ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey(keycode, scancode);
|
|
ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey(keycode, scancode);
|
|
io.AddKeyEvent(imgui_key, (action == GLFW_PRESS));
|
|
io.AddKeyEvent(imgui_key, (action == GLFW_PRESS));
|
|
io.SetKeyEventNativeData(imgui_key, keycode, scancode); // To support legacy indexing (<1.87 user code)
|
|
io.SetKeyEventNativeData(imgui_key, keycode, scancode); // To support legacy indexing (<1.87 user code)
|
|
@@ -466,25 +485,25 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, i
|
|
|
|
|
|
void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused)
|
|
void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused)
|
|
{
|
|
{
|
|
- ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
|
|
- if (bd->PrevUserCallbackWindowFocus != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
|
|
|
|
|
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
|
|
|
+ if (bd->PrevUserCallbackWindowFocus != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
|
bd->PrevUserCallbackWindowFocus(window, focused);
|
|
bd->PrevUserCallbackWindowFocus(window, focused);
|
|
|
|
|
|
// Workaround for Linux: when losing focus with MouseIgnoreButtonUpWaitForFocusLoss set, we will temporarily ignore subsequent Mouse Up events
|
|
// Workaround for Linux: when losing focus with MouseIgnoreButtonUpWaitForFocusLoss set, we will temporarily ignore subsequent Mouse Up events
|
|
bd->MouseIgnoreButtonUp = (bd->MouseIgnoreButtonUpWaitForFocusLoss && focused == 0);
|
|
bd->MouseIgnoreButtonUp = (bd->MouseIgnoreButtonUpWaitForFocusLoss && focused == 0);
|
|
bd->MouseIgnoreButtonUpWaitForFocusLoss = false;
|
|
bd->MouseIgnoreButtonUpWaitForFocusLoss = false;
|
|
|
|
|
|
- ImGuiIO& io = ImGui::GetIO();
|
|
|
|
|
|
+ ImGuiIO& io = ImGui::GetIO(bd->Context);
|
|
io.AddFocusEvent(focused != 0);
|
|
io.AddFocusEvent(focused != 0);
|
|
}
|
|
}
|
|
|
|
|
|
void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
|
void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
|
{
|
|
{
|
|
- ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
|
|
- if (bd->PrevUserCallbackCursorPos != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
|
|
|
|
|
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
|
|
|
+ if (bd->PrevUserCallbackCursorPos != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
|
bd->PrevUserCallbackCursorPos(window, x, y);
|
|
bd->PrevUserCallbackCursorPos(window, x, y);
|
|
|
|
|
|
- ImGuiIO& io = ImGui::GetIO();
|
|
|
|
|
|
+ ImGuiIO& io = ImGui::GetIO(bd->Context);
|
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
{
|
|
{
|
|
int window_x, window_y;
|
|
int window_x, window_y;
|
|
@@ -500,11 +519,11 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
|
// so we back it up and restore on Leave/Enter (see https://github.com/ocornut/imgui/issues/4984)
|
|
// so we back it up and restore on Leave/Enter (see https://github.com/ocornut/imgui/issues/4984)
|
|
void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
|
|
void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
|
|
{
|
|
{
|
|
- ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
|
|
- if (bd->PrevUserCallbackCursorEnter != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
|
|
|
|
|
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
|
|
|
+ if (bd->PrevUserCallbackCursorEnter != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
|
bd->PrevUserCallbackCursorEnter(window, entered);
|
|
bd->PrevUserCallbackCursorEnter(window, entered);
|
|
|
|
|
|
- ImGuiIO& io = ImGui::GetIO();
|
|
|
|
|
|
+ ImGuiIO& io = ImGui::GetIO(bd->Context);
|
|
if (entered)
|
|
if (entered)
|
|
{
|
|
{
|
|
bd->MouseWindow = window;
|
|
bd->MouseWindow = window;
|
|
@@ -520,11 +539,11 @@ void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
|
|
|
|
|
|
void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c)
|
|
void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c)
|
|
{
|
|
{
|
|
- ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
|
|
- if (bd->PrevUserCallbackChar != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
|
|
|
|
|
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
|
|
|
+ if (bd->PrevUserCallbackChar != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
|
bd->PrevUserCallbackChar(window, c);
|
|
bd->PrevUserCallbackChar(window, c);
|
|
|
|
|
|
- ImGuiIO& io = ImGui::GetIO();
|
|
|
|
|
|
+ ImGuiIO& io = ImGui::GetIO(bd->Context);
|
|
io.AddInputCharacter(c);
|
|
io.AddInputCharacter(c);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -534,17 +553,18 @@ void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int)
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
|
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
|
-static EM_BOOL ImGui_ImplEmscripten_WheelCallback(int, const EmscriptenWheelEvent* ev, void*)
|
|
|
|
|
|
+static EM_BOOL ImGui_ImplEmscripten_WheelCallback(int, const EmscriptenWheelEvent* ev, void* user_data)
|
|
{
|
|
{
|
|
// Mimic Emscripten_HandleWheel() in SDL.
|
|
// Mimic Emscripten_HandleWheel() in SDL.
|
|
// Corresponding equivalent in GLFW JS emulation layer has incorrect quantizing preventing small values. See #6096
|
|
// Corresponding equivalent in GLFW JS emulation layer has incorrect quantizing preventing small values. See #6096
|
|
|
|
+ ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)user_data;
|
|
float multiplier = 0.0f;
|
|
float multiplier = 0.0f;
|
|
if (ev->deltaMode == DOM_DELTA_PIXEL) { multiplier = 1.0f / 100.0f; } // 100 pixels make up a step.
|
|
if (ev->deltaMode == DOM_DELTA_PIXEL) { multiplier = 1.0f / 100.0f; } // 100 pixels make up a step.
|
|
else if (ev->deltaMode == DOM_DELTA_LINE) { multiplier = 1.0f / 3.0f; } // 3 lines make up a step.
|
|
else if (ev->deltaMode == DOM_DELTA_LINE) { multiplier = 1.0f / 3.0f; } // 3 lines make up a step.
|
|
else if (ev->deltaMode == DOM_DELTA_PAGE) { multiplier = 80.0f; } // A page makes up 80 steps.
|
|
else if (ev->deltaMode == DOM_DELTA_PAGE) { multiplier = 80.0f; } // A page makes up 80 steps.
|
|
float wheel_x = ev->deltaX * -multiplier;
|
|
float wheel_x = ev->deltaX * -multiplier;
|
|
float wheel_y = ev->deltaY * -multiplier;
|
|
float wheel_y = ev->deltaY * -multiplier;
|
|
- ImGuiIO& io = ImGui::GetIO();
|
|
|
|
|
|
+ ImGuiIO& io = ImGui::GetIO(bd->Context);
|
|
io.AddMouseWheelEvent(wheel_x, wheel_y);
|
|
io.AddMouseWheelEvent(wheel_x, wheel_y);
|
|
//IMGUI_DEBUG_LOG("[Emsc] mode %d dx: %.2f, dy: %.2f, dz: %.2f --> feed %.2f %.2f\n", (int)ev->deltaMode, ev->deltaX, ev->deltaY, ev->deltaZ, wheel_x, wheel_y);
|
|
//IMGUI_DEBUG_LOG("[Emsc] mode %d dx: %.2f, dy: %.2f, dz: %.2f --> feed %.2f %.2f\n", (int)ev->deltaMode, ev->deltaX, ev->deltaY, ev->deltaZ, wheel_x, wheel_y);
|
|
return EM_TRUE;
|
|
return EM_TRUE;
|
|
@@ -557,7 +577,7 @@ static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wPara
|
|
|
|
|
|
void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
|
|
void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
|
|
{
|
|
{
|
|
- ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
|
|
|
|
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
|
IM_ASSERT(bd->InstalledCallbacks == false && "Callbacks already installed!");
|
|
IM_ASSERT(bd->InstalledCallbacks == false && "Callbacks already installed!");
|
|
IM_ASSERT(bd->Window == window);
|
|
IM_ASSERT(bd->Window == window);
|
|
|
|
|
|
@@ -574,7 +594,7 @@ void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
|
|
|
|
|
|
void ImGui_ImplGlfw_RestoreCallbacks(GLFWwindow* window)
|
|
void ImGui_ImplGlfw_RestoreCallbacks(GLFWwindow* window)
|
|
{
|
|
{
|
|
- ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
|
|
|
|
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
|
IM_ASSERT(bd->InstalledCallbacks == true && "Callbacks not installed!");
|
|
IM_ASSERT(bd->InstalledCallbacks == true && "Callbacks not installed!");
|
|
IM_ASSERT(bd->Window == window);
|
|
IM_ASSERT(bd->Window == window);
|
|
|
|
|
|
@@ -644,8 +664,10 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
|
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
|
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+ bd->Context = ImGui::GetCurrentContext();
|
|
bd->Window = window;
|
|
bd->Window = window;
|
|
bd->Time = 0.0;
|
|
bd->Time = 0.0;
|
|
|
|
+ ImGui_ImplGlfw_ContextMap_Add(window, bd->Context);
|
|
|
|
|
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
#if GLFW_VERSION_COMBINED < 3300
|
|
#if GLFW_VERSION_COMBINED < 3300
|
|
@@ -710,7 +732,9 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
|
|
|
|
|
// Windows: register a WndProc hook so we can intercept some messages.
|
|
// Windows: register a WndProc hook so we can intercept some messages.
|
|
#ifdef _WIN32
|
|
#ifdef _WIN32
|
|
- bd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC);
|
|
|
|
|
|
+ HWND hwnd = (HWND)main_viewport->PlatformHandleRaw;
|
|
|
|
+ ::SetPropA(hwnd, "IMGUI_BACKEND_DATA", bd);
|
|
|
|
+ bd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW(hwnd, GWLP_WNDPROC);
|
|
IM_ASSERT(bd->PrevWndProc != nullptr);
|
|
IM_ASSERT(bd->PrevWndProc != nullptr);
|
|
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
|
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
|
#endif
|
|
#endif
|
|
@@ -721,7 +745,7 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
|
#if EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 >= 34020240817
|
|
#if EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 >= 34020240817
|
|
if (emscripten::glfw3::IsRuntimePlatformApple())
|
|
if (emscripten::glfw3::IsRuntimePlatformApple())
|
|
{
|
|
{
|
|
- ImGui::GetIO().ConfigMacOSXBehaviors = true;
|
|
|
|
|
|
+ io.ConfigMacOSXBehaviors = true;
|
|
|
|
|
|
// Due to how the browser (poorly) handles the Meta Key, this line essentially disables repeats when used.
|
|
// Due to how the browser (poorly) handles the Meta Key, this line essentially disables repeats when used.
|
|
// This means that Meta + V only registers a single key-press, even if the keys are held.
|
|
// This means that Meta + V only registers a single key-press, even if the keys are held.
|
|
@@ -772,6 +796,7 @@ void ImGui_ImplGlfw_Shutdown()
|
|
// Windows: restore our WndProc hook
|
|
// Windows: restore our WndProc hook
|
|
#ifdef _WIN32
|
|
#ifdef _WIN32
|
|
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
|
|
+ ::SetPropA((HWND)main_viewport->PlatformHandleRaw, "IMGUI_BACKEND_DATA", nullptr);
|
|
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->PrevWndProc);
|
|
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->PrevWndProc);
|
|
bd->PrevWndProc = nullptr;
|
|
bd->PrevWndProc = nullptr;
|
|
#endif
|
|
#endif
|
|
@@ -779,6 +804,7 @@ void ImGui_ImplGlfw_Shutdown()
|
|
io.BackendPlatformName = nullptr;
|
|
io.BackendPlatformName = nullptr;
|
|
io.BackendPlatformUserData = nullptr;
|
|
io.BackendPlatformUserData = nullptr;
|
|
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
|
|
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
|
|
|
|
+ ImGui_ImplGlfw_ContextMap_Remove(bd->Window);
|
|
IM_DELETE(bd);
|
|
IM_DELETE(bd);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1083,7 +1109,7 @@ void ImGui_ImplGlfw_InstallEmscriptenCallbacks(GLFWwindow*, const char* canvas_s
|
|
// Register Emscripten Wheel callback to workaround issue in Emscripten GLFW Emulation (#6096)
|
|
// Register Emscripten Wheel callback to workaround issue in Emscripten GLFW Emulation (#6096)
|
|
// We intentionally do not check 'if (install_callbacks)' here, as some users may set it to false and call GLFW callback themselves.
|
|
// We intentionally do not check 'if (install_callbacks)' here, as some users may set it to false and call GLFW callback themselves.
|
|
// FIXME: May break chaining in case user registered their own Emscripten callback?
|
|
// FIXME: May break chaining in case user registered their own Emscripten callback?
|
|
- emscripten_set_wheel_callback(bd->CanvasSelector, nullptr, false, ImGui_ImplEmscripten_WheelCallback);
|
|
|
|
|
|
+ emscripten_set_wheel_callback(bd->CanvasSelector, bd, false, ImGui_ImplEmscripten_WheelCallback);
|
|
}
|
|
}
|
|
#elif defined(EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3)
|
|
#elif defined(EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3)
|
|
// When using --use-port=contrib.glfw3 for the GLFW implementation, you can override the behavior of this call
|
|
// When using --use-port=contrib.glfw3 for the GLFW implementation, you can override the behavior of this call
|
|
@@ -1467,7 +1493,9 @@ static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
|
}
|
|
}
|
|
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
{
|
|
- ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
|
|
|
|
+ ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)::GetPropA(hWnd, "IMGUI_BACKEND_DATA");
|
|
|
|
+ ImGuiIO& io = ImGui::GetIO(bd->Context);
|
|
|
|
+
|
|
WNDPROC prev_wndproc = bd->PrevWndProc;
|
|
WNDPROC prev_wndproc = bd->PrevWndProc;
|
|
ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT");
|
|
ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT");
|
|
if (viewport != NULL)
|
|
if (viewport != NULL)
|
|
@@ -1483,7 +1511,7 @@ static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wPara
|
|
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP:
|
|
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP:
|
|
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP:
|
|
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP:
|
|
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONUP:
|
|
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONUP:
|
|
- ImGui::GetIO().AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
|
|
|
|
|
|
+ io.AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
|
|
break;
|
|
break;
|
|
|
|
|
|
// We have submitted https://github.com/glfw/glfw/pull/1568 to allow GLFW to support "transparent inputs".
|
|
// We have submitted https://github.com/glfw/glfw/pull/1568 to allow GLFW to support "transparent inputs".
|