|
@@ -21,6 +21,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.
|
|
|
+// 2022-02-07: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing callbacks after iniitializing 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+).
|
|
@@ -110,6 +111,7 @@ struct ImGui_ImplGlfw_Data
|
|
|
double Time;
|
|
|
GLFWwindow* MouseWindow;
|
|
|
GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
|
|
+ ImVec2 LastValidMousePos;
|
|
|
GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST];
|
|
|
bool InstalledCallbacks;
|
|
|
bool WantUpdateMonitors;
|
|
@@ -374,8 +376,11 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
|
|
y += window_y;
|
|
|
}
|
|
|
io.AddMousePosEvent((float)x, (float)y);
|
|
|
+ bd->LastValidMousePos = ImVec2((float)x, (float)y);
|
|
|
}
|
|
|
|
|
|
+// Workaround: X11 seems to send spurious Leave/Enter events which would make us lose our position,
|
|
|
+// 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)
|
|
|
{
|
|
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
@@ -384,9 +389,13 @@ void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
|
|
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
if (entered)
|
|
|
+ {
|
|
|
bd->MouseWindow = window;
|
|
|
- if (!entered && bd->MouseWindow == window)
|
|
|
+ io.AddMousePosEvent(bd->LastValidMousePos.x, bd->LastValidMousePos.y);
|
|
|
+ }
|
|
|
+ else if (!entered && bd->MouseWindow == window)
|
|
|
{
|
|
|
+ bd->LastValidMousePos = io.MousePos;
|
|
|
bd->MouseWindow = NULL;
|
|
|
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
|
|
}
|
|
@@ -408,6 +417,48 @@ void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int)
|
|
|
bd->WantUpdateMonitors = true;
|
|
|
}
|
|
|
|
|
|
+void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
|
|
|
+{
|
|
|
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
|
+ IM_ASSERT(bd->InstalledCallbacks == false && "Callbacks already installed!");
|
|
|
+ IM_ASSERT(bd->Window == window);
|
|
|
+
|
|
|
+ bd->PrevUserCallbackWindowFocus = glfwSetWindowFocusCallback(window, ImGui_ImplGlfw_WindowFocusCallback);
|
|
|
+ bd->PrevUserCallbackCursorEnter = glfwSetCursorEnterCallback(window, ImGui_ImplGlfw_CursorEnterCallback);
|
|
|
+ bd->PrevUserCallbackCursorPos = glfwSetCursorPosCallback(window, ImGui_ImplGlfw_CursorPosCallback);
|
|
|
+ bd->PrevUserCallbackMousebutton = glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback);
|
|
|
+ bd->PrevUserCallbackScroll = glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback);
|
|
|
+ bd->PrevUserCallbackKey = glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback);
|
|
|
+ bd->PrevUserCallbackChar = glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback);
|
|
|
+ bd->PrevUserCallbackMonitor = glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback);
|
|
|
+ bd->InstalledCallbacks = true;
|
|
|
+}
|
|
|
+
|
|
|
+void ImGui_ImplGlfw_RestoreCallbacks(GLFWwindow* window)
|
|
|
+{
|
|
|
+ ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
|
+ IM_ASSERT(bd->InstalledCallbacks == true && "Callbacks not installed!");
|
|
|
+ IM_ASSERT(bd->Window == window);
|
|
|
+
|
|
|
+ glfwSetWindowFocusCallback(window, bd->PrevUserCallbackWindowFocus);
|
|
|
+ glfwSetCursorEnterCallback(window, bd->PrevUserCallbackCursorEnter);
|
|
|
+ glfwSetCursorPosCallback(window, bd->PrevUserCallbackCursorPos);
|
|
|
+ glfwSetMouseButtonCallback(window, bd->PrevUserCallbackMousebutton);
|
|
|
+ glfwSetScrollCallback(window, bd->PrevUserCallbackScroll);
|
|
|
+ glfwSetKeyCallback(window, bd->PrevUserCallbackKey);
|
|
|
+ glfwSetCharCallback(window, bd->PrevUserCallbackChar);
|
|
|
+ glfwSetMonitorCallback(bd->PrevUserCallbackMonitor);
|
|
|
+ bd->InstalledCallbacks = false;
|
|
|
+ bd->PrevUserCallbackWindowFocus = NULL;
|
|
|
+ bd->PrevUserCallbackCursorEnter = NULL;
|
|
|
+ bd->PrevUserCallbackCursorPos = NULL;
|
|
|
+ bd->PrevUserCallbackMousebutton = NULL;
|
|
|
+ bd->PrevUserCallbackScroll = NULL;
|
|
|
+ bd->PrevUserCallbackKey = NULL;
|
|
|
+ bd->PrevUserCallbackChar = NULL;
|
|
|
+ bd->PrevUserCallbackMonitor = NULL;
|
|
|
+}
|
|
|
+
|
|
|
static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api)
|
|
|
{
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
@@ -456,25 +507,8 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
|
|
glfwSetErrorCallback(prev_error_callback);
|
|
|
|
|
|
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
|
|
|
- bd->PrevUserCallbackWindowFocus = NULL;
|
|
|
- bd->PrevUserCallbackCursorEnter = NULL;
|
|
|
- bd->PrevUserCallbackMousebutton = NULL;
|
|
|
- bd->PrevUserCallbackScroll = NULL;
|
|
|
- bd->PrevUserCallbackKey = NULL;
|
|
|
- bd->PrevUserCallbackChar = NULL;
|
|
|
- bd->PrevUserCallbackMonitor = NULL;
|
|
|
if (install_callbacks)
|
|
|
- {
|
|
|
- bd->InstalledCallbacks = true;
|
|
|
- bd->PrevUserCallbackWindowFocus = glfwSetWindowFocusCallback(window, ImGui_ImplGlfw_WindowFocusCallback);
|
|
|
- bd->PrevUserCallbackCursorEnter = glfwSetCursorEnterCallback(window, ImGui_ImplGlfw_CursorEnterCallback);
|
|
|
- bd->PrevUserCallbackCursorPos = glfwSetCursorPosCallback(window, ImGui_ImplGlfw_CursorPosCallback);
|
|
|
- bd->PrevUserCallbackMousebutton = glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback);
|
|
|
- bd->PrevUserCallbackScroll = glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback);
|
|
|
- bd->PrevUserCallbackKey = glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback);
|
|
|
- bd->PrevUserCallbackChar = glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback);
|
|
|
- bd->PrevUserCallbackMonitor = glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback);
|
|
|
- }
|
|
|
+ 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();
|
|
@@ -517,16 +551,7 @@ void ImGui_ImplGlfw_Shutdown()
|
|
|
ImGui_ImplGlfw_ShutdownPlatformInterface();
|
|
|
|
|
|
if (bd->InstalledCallbacks)
|
|
|
- {
|
|
|
- glfwSetWindowFocusCallback(bd->Window, bd->PrevUserCallbackWindowFocus);
|
|
|
- glfwSetCursorEnterCallback(bd->Window, bd->PrevUserCallbackCursorEnter);
|
|
|
- glfwSetCursorPosCallback(bd->Window, bd->PrevUserCallbackCursorPos);
|
|
|
- glfwSetMouseButtonCallback(bd->Window, bd->PrevUserCallbackMousebutton);
|
|
|
- glfwSetScrollCallback(bd->Window, bd->PrevUserCallbackScroll);
|
|
|
- glfwSetKeyCallback(bd->Window, bd->PrevUserCallbackKey);
|
|
|
- glfwSetCharCallback(bd->Window, bd->PrevUserCallbackChar);
|
|
|
- glfwSetMonitorCallback(bd->PrevUserCallbackMonitor);
|
|
|
- }
|
|
|
+ ImGui_ImplGlfw_RestoreCallbacks(bd->Window);
|
|
|
|
|
|
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
|
|
glfwDestroyCursor(bd->MouseCursors[cursor_n]);
|
|
@@ -575,6 +600,7 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
|
|
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);
|
|
|
}
|
|
|
}
|