Backends: GLFW: Registering custom low-level mouse wheel handler to get more accurate scrolling impulses on Emscripten. (#4019, #6096)

Namely, GLFW JS emulation seems to quantize values to a min of -1/+1 which breaks modern OSX/Windows emulating smoothness with stepping wheels (slow steps are sending sub-1.0 values)
+ Massage changelog.
This commit is contained in:
ocornut 2023-02-03 15:00:41 +01:00
parent 6584de4a78
commit d0b1aaa076
2 changed files with 46 additions and 19 deletions

View File

@ -16,7 +16,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)
// 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. // 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-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) // 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 <GLFW/glfw3native.h> // for glfwGetWin32Window #include <GLFW/glfw3native.h> // for glfwGetWin32Window
#endif #endif
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#include <emscripten/html5.h>
#endif
// We gather version tests as define in order to easily see which features are version-dependent. // 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) #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? #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); bd->PrevUserCallbackScroll(window, xoffset, yoffset);
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
xoffset /= 100.0; // Ignore GLFW events: will be processed in ImGui_ImplEmscripten_WheelCallback().
return;
#endif #endif
ImGuiIO& io = ImGui::GetIO(); 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. // 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) void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
{ {
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); 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) if (install_callbacks)
ImGui_ImplGlfw_InstallCallbacks(window); 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; bd->ClientApi = client_api;
return true; return true;
} }

View File

@ -35,36 +35,26 @@ HOW TO UPDATE?
VERSION 1.89.3 (In Progress) VERSION 1.89.3 (In Progress)
----------------------------------------------------------------------- -----------------------------------------------------------------------
Breaking changes: All changes:
- Inputs, Scrolling: Made horizontal scroll wheel and horizontal scroll direction consistent - Inputs, Scrolling: Made horizontal scroll wheel and horizontal scroll direction consistent
accross backends/os. (#4019, #6096, #1463) [@PathogenDavid, @ocornut, @rokups] 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_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. 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 - Backends: Fixed horizontal scroll direction for Win32 and SDL backends. (#4019)
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)
- Shift+WheelY support on non-OSX machines was already correct. (#2424, #1463) - 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). (whereaas on OSX machines Shift+WheelY turns into WheelX at the OS level).
- If you use a custom-backend, you should verify that: - If you use a custom-backend, you should verify horizontal wheel direction.
- Wheel up (*) emit wheel_y > 0.0f values and scrolls up. - Axises are flipped by OSX for mouse & touchpad when 'Natural Scrolling' is on.
- Wheel down (*) emit wheel_y < 0.0f values and scrolls down. - Axises are flipped by Windows for touchpad when 'Settings->Touchpad->Down motion scrolls up' is on.
- 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.
- You can use 'Demo->Tools->Debug Log->IO" to visualize values submitted to Dear ImGui. - You can use 'Demo->Tools->Debug Log->IO" to visualize values submitted to Dear ImGui.
- Known issues remaining with Emscripten: - 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. - 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 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 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 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. let us know!), or offer the "OSX-style behavior" option to their user.
All changes:
- Window: Avoid rendering shapes for hidden resize grips. - Window: Avoid rendering shapes for hidden resize grips.
- Tables: Raised max Columns count from 64 to 512. (#6094, #5305, #4876, #3572) - 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 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) can exacerbate that. (#6114, #3644)
- Backends: OSX: Fixed scroll/wheel scaling for devices emitting events with - Backends: OSX: Fixed scroll/wheel scaling for devices emitting events with
hasPreciseScrollingDeltas==false (e.g. non-Apple mices). 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: Removed SDL_MOUSEWHEEL value clamping. (#4019, #6096, #6081)
- Backends: SDL: Added support for SDL 2.0.18+ preciseX/preciseY mouse wheel data - Backends: SDL: Added support for SDL 2.0.18+ preciseX/preciseY mouse wheel data
for smooth scrolling as reported by SDL. (#4019, #6096) for smooth scrolling as reported by SDL. (#4019, #6096)
- Backends: SDL: Avoid calling SDL_SetCursor() when cursor has not changed, as the function - 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) 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). - Backends: WebGPU: Fix building for latest WebGPU specs (remove implicit layout generation).
(#6117, #4116, #3632) [@tonygrue, @bfierz] (#6117, #4116, #3632) [@tonygrue, @bfierz]
- Examples: refactord all examples to use a "MainLoopStep()" function. This is in order - Examples: refactord all examples to use a "MainLoopStep()" function. This is in order