From c347d6944bc74205b7ac4334c681ca4a3e481670 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 5 Nov 2024 11:26:38 +0100 Subject: [PATCH] Backends: GLFW: Linux workaround for spurious mouse up events emitted while dragging and creating new viewport. (#3158, #7733, #7922) Initially suggested by rokups. Rewrote for recent backends with a few tweaks to accomodate for variable WM unfocus timing. --- backends/imgui_impl_glfw.cpp | 17 +++++++++++++++++ docs/CHANGELOG.txt | 3 +++ 2 files changed, 20 insertions(+) diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index 5ea6d36cc..26ef27c48 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -29,6 +29,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) // 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2024-11-05: [Docking] Added Linux workaround for spurious mouse up events emitted while dragging and creating new viewport. (#3158, #7733, #7922) // 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO: // - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn // - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn @@ -172,6 +173,8 @@ struct ImGui_ImplGlfw_Data double Time; GLFWwindow* MouseWindow; GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT]; + bool MouseIgnoreButtonUpWaitForFocusLoss; + bool MouseIgnoreButtonUp; ImVec2 LastValidMousePos; GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST]; bool InstalledCallbacks; @@ -367,6 +370,10 @@ void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int acti if (bd->PrevUserCallbackMousebutton != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window)) bd->PrevUserCallbackMousebutton(window, button, action, mods); + // Workaround for Linux: ignore mouse up events which are following an focus loss following a viewport creation + if (bd->MouseIgnoreButtonUp && action == GLFW_RELEASE) + return; + ImGui_ImplGlfw_UpdateKeyModifiers(window); ImGuiIO& io = ImGui::GetIO(); @@ -451,6 +458,10 @@ void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused) if (bd->PrevUserCallbackWindowFocus != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window)) bd->PrevUserCallbackWindowFocus(window, focused); + // Workaround for Linux: when losing focus with MouseIgnoreButtonUpWaitForFocusLoss set, we will temporarily ignore subsequent Mouse Up events + bd->MouseIgnoreButtonUp = (bd->MouseIgnoreButtonUpWaitForFocusLoss && focused == 0); + bd->MouseIgnoreButtonUpWaitForFocusLoss = false; + ImGuiIO& io = ImGui::GetIO(); io.AddFocusEvent(focused != 0); } @@ -965,6 +976,7 @@ void ImGui_ImplGlfw_NewFrame() io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f); bd->Time = current_time; + bd->MouseIgnoreButtonUp = false; ImGui_ImplGlfw_UpdateMouseData(); ImGui_ImplGlfw_UpdateMouseCursor(); @@ -1104,6 +1116,11 @@ static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport) ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)(); viewport->PlatformUserData = vd; + // Workaround for Linux: ignore mouse up events corresponding to losing focus of the previously focused window (#7733, #3158, #7922) +#ifdef __linux__ + bd->MouseIgnoreButtonUpWaitForFocusLoss = true; +#endif + // 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); diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 101ba26fc..4d25e569a 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -55,6 +55,9 @@ Other changes: Docking+Viewports Branch: +- Backends: GLFW: added Linux workaround for spurious mouse up events emitted while dragging + and creating new viewports. Generally they would be interrupting a dragging operations. + (#3158, #7733, #7922) [@rokups, @ocornut] - Docking: fixed using ImGuiDockNodeFlags_KeepAliveOnly with DockSpaceOverViewport(): the normally invisible space did erroneously claim mouse hover and could be potentially focused. (#8125) [@kcbanner]