浏览代码

Backends, Viewports: GLFW: Add a workaround for stuck keys after closing a GLFW window (#3837).

Rokas Kupstys 4 年之前
父节点
当前提交
a4adf60576
共有 1 个文件被更改,包括 14 次插入0 次删除
  1. 14 0
      backends/imgui_impl_glfw.cpp

+ 14 - 0
backends/imgui_impl_glfw.cpp

@@ -84,6 +84,7 @@ static GlfwClientApi        g_ClientApi = GlfwClientApi_Unknown;
 static double               g_Time = 0.0;
 static double               g_Time = 0.0;
 static bool                 g_MouseJustPressed[ImGuiMouseButton_COUNT] = {};
 static bool                 g_MouseJustPressed[ImGuiMouseButton_COUNT] = {};
 static GLFWcursor*          g_MouseCursors[ImGuiMouseCursor_COUNT] = {};
 static GLFWcursor*          g_MouseCursors[ImGuiMouseCursor_COUNT] = {};
+static GLFWwindow*          g_KeyOwnerWindows[512] = {};
 static bool                 g_InstalledCallbacks = false;
 static bool                 g_InstalledCallbacks = false;
 static bool                 g_WantUpdateMonitors = true;
 static bool                 g_WantUpdateMonitors = true;
 
 
@@ -135,9 +136,15 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int a
 
 
     ImGuiIO& io = ImGui::GetIO();
     ImGuiIO& io = ImGui::GetIO();
     if (action == GLFW_PRESS)
     if (action == GLFW_PRESS)
+    {
         io.KeysDown[key] = true;
         io.KeysDown[key] = true;
+        g_KeyOwnerWindows[key] = window;
+    }
     if (action == GLFW_RELEASE)
     if (action == GLFW_RELEASE)
+    {
         io.KeysDown[key] = false;
         io.KeysDown[key] = false;
+        g_KeyOwnerWindows[key] = NULL;
+    }
 
 
     // Modifiers are not reliable across systems
     // Modifiers are not reliable across systems
     io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL];
     io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL];
@@ -607,6 +614,13 @@ static void ImGui_ImplGlfw_DestroyWindow(ImGuiViewport* viewport)
             HWND hwnd = (HWND)viewport->PlatformHandleRaw;
             HWND hwnd = (HWND)viewport->PlatformHandleRaw;
             ::RemovePropA(hwnd, "IMGUI_VIEWPORT");
             ::RemovePropA(hwnd, "IMGUI_VIEWPORT");
 #endif
 #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(g_KeyOwnerWindows); i++)
+                if (g_KeyOwnerWindows[i] == data->Window)
+                    ImGui_ImplGlfw_KeyCallback(data->Window, i, 0, GLFW_RELEASE, 0); // Later params are only used for main viewport, on which this function is never called.
+
             glfwDestroyWindow(data->Window);
             glfwDestroyWindow(data->Window);
         }
         }
         data->Window = NULL;
         data->Window = NULL;