diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index 9192d19e3..c0b9a165b 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -16,7 +16,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) -// 2023-02-02: Inputs: Scaling X value on Emscripten (bug?). (#4019, #6096) +// 2023-02-03: Emscripten: Registering custom low-level mouse wheel handler to get more accurate scrolling impulses on Emscripten. (#4019, #6096) // 2023-01-04: Inputs: Fixed mods state on Linux when using Alt-GR text input (e.g. German keyboard layout), could lead to broken text input. Revert a 2022/01/17 change were we resumed using mods provided by GLFW, turns out they were faulty. // 2022-11-22: Perform a dummy glfwGetError() read to cancel missing names with glfwGetKeyName(). (#5908) // 2022-10-18: Perform a dummy glfwGetError() read to cancel missing mouse cursors errors. Using GLFW_VERSION_COMBINED directly. (#5785) @@ -76,6 +76,11 @@ #include // for glfwGetWin32Window #endif +#ifdef __EMSCRIPTEN__ +#include +#include +#endif + // We gather version tests as define in order to easily see which features are version-dependent. #define GLFW_VERSION_COMBINED (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 + GLFW_VERSION_REVISION) #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? @@ -285,7 +290,8 @@ void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yo bd->PrevUserCallbackScroll(window, xoffset, yoffset); #ifdef __EMSCRIPTEN__ - xoffset /= 100.0; + // Ignore GLFW events: will be processed in ImGui_ImplEmscripten_WheelCallback(). + return; #endif ImGuiIO& io = ImGui::GetIO(); @@ -406,6 +412,24 @@ 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. } +#ifdef __EMSCRIPTEN__ +static EM_BOOL ImGui_ImplEmscripten_WheelCallback(int, const EmscriptenWheelEvent* ev, void*) +{ + // Mimic Emscripten_HandleWheel() in SDL. + // Corresponding equivalent in GLFW JS emulation layer has incorrect quantizing preventing small values. See #6096 + float multiplier = 0.0f; + 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_PAGE) { multiplier = 80.0f; } // A page makes up 80 steps. + float wheel_x = ev->deltaX * -multiplier; + float wheel_y = ev->deltaY * -multiplier; + ImGuiIO& io = ImGui::GetIO(); + 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); + return EM_TRUE; +} +#endif + void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window) { ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); @@ -503,6 +527,13 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw if (install_callbacks) ImGui_ImplGlfw_InstallCallbacks(window); + // 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. + // FIXME: May break chaining in case user registered their own Emscripten callback? +#ifdef __EMSCRIPTEN__ + emscripten_set_wheel_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, false, ImGui_ImplEmscripten_WheelCallback); +#endif + bd->ClientApi = client_api; return true; } diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 087db7e8a..b09a248e6 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -35,36 +35,26 @@ HOW TO UPDATE? VERSION 1.89.3 (In Progress) ----------------------------------------------------------------------- -Breaking changes: +All changes: - Inputs, Scrolling: Made horizontal scroll wheel and horizontal scroll direction consistent accross backends/os. (#4019, #6096, #1463) [@PathogenDavid, @ocornut, @rokups] - Clarified that 'wheel_y > 0.0f' scrolls Up, 'wheel_y > 0.0f' scrolls Down. - - Clarified that 'wheel_x > 0.0f' scrolls Left, 'wheel_x > 0.0f' scrolls Right. - - Backends: Win32: flipping WM_MOUSEHWHEEL value to match other backends and - offer consistent horizontal scrolling direction. (#4019) - - Backends: SDL: flipping SDL_MOUSEWHEEL 'wheel.x' value to match other backends and - offer consistent horizontal scrolling direction. (#4019) + Clarified that 'wheel_x > 0.0f' scrolls Left, 'wheel_x > 0.0f' scrolls Right. + - Backends: Fixed horizontal scroll direction for Win32 and SDL backends. (#4019) - Shift+WheelY support on non-OSX machines was already correct. (#2424, #1463) (whereaas on OSX machines Shift+WheelY turns into WheelX at the OS level). - - If you use a custom-backend, you should verify that: - - Wheel up (*) emit wheel_y > 0.0f values and scrolls up. - - Wheel down (*) emit wheel_y < 0.0f values and scrolls down. - - Wheel left (*) or mod+wheel up emit wheel_x > 0.0f values and scroll Left. - - Wheel right (*) or mod+wheel down emits wheel_x < 0.0f values and scroll Right. - - (*) both axises flipped on OSX for mouse and touchpad when 'Natural Scrolling' is on. - - (*) both axises flipped On Windows for touchpad only when 'Settings->Touchpad->Down motion scrolls up' is set. + - If you use a custom-backend, you should verify horizontal wheel direction. + - Axises are flipped by OSX for mouse & touchpad when 'Natural Scrolling' is on. + - Axises are flipped by Windows for touchpad when 'Settings->Touchpad->Down motion scrolls up' is on. - You can use 'Demo->Tools->Debug Log->IO" to visualize values submitted to Dear ImGui. - Known issues remaining with Emscripten: - - The magnitude of wheeling values on Emscripten setups is still not great. (#6096) + - The magnitude of wheeling values on Emscripten was improved but isn't perfect. (#6096) - When running the Emscripten app on a Mac with a mouse, SHIFT+WheelY doesn't turn into WheelX. This is because we don't know that we are running on Mac and apply our own Shift+swapping on top of OSX' own swapping, so wheel axises are swapped twice. Emscripten apps may need to find a way to detect this and set io.ConfigMacOSXBehaviors manually (if you know a way let us know!), or offer the "OSX-style behavior" option to their user. - -All changes: - - Window: Avoid rendering shapes for hidden resize grips. - Tables: Raised max Columns count from 64 to 512. (#6094, #5305, #4876, #3572) The previous limit was due to using 64-bit integers but we moved to bits-array @@ -89,11 +79,17 @@ All changes: can exacerbate that. (#6114, #3644) - Backends: OSX: Fixed scroll/wheel scaling for devices emitting events with hasPreciseScrollingDeltas==false (e.g. non-Apple mices). +- Backends: Win32: flipping WM_MOUSEHWHEEL value to match other backends and + offer consistent horizontal scrolling direction. (#4019) +- Backends: SDL: flipping SDL_MOUSEWHEEL 'wheel.x' value to match other backends and + offer consistent horizontal scrolling direction. (#4019) - Backends: SDL: Removed SDL_MOUSEWHEEL value clamping. (#4019, #6096, #6081) - Backends: SDL: Added support for SDL 2.0.18+ preciseX/preciseY mouse wheel data for smooth scrolling as reported by SDL. (#4019, #6096) - Backends: SDL: Avoid calling SDL_SetCursor() when cursor has not changed, as the function is surprisingly costly on Mac with latest SDL (may be fixed in next SDL version). (#6113) +- Backends: GLFW: Registering custom low-level mouse wheel handler to get more accurate + scrolling impulses on Emscripten. (#4019, #6096) [@ocornut, @wolfpld, @tolopolarity] - Backends: WebGPU: Fix building for latest WebGPU specs (remove implicit layout generation). (#6117, #4116, #3632) [@tonygrue, @bfierz] - Examples: refactord all examples to use a "MainLoopStep()" function. This is in order