Open floooh opened 3 years ago
I have tested on a Mac 13"MBP
This seems like it might have some sort of platform-specific element at play even though your demo is browser based.
I cannot reproduce this on Windows using Edge 95 (latest dev) or Firefox 92.0 (latest stable). I tried both my Steelseries mouse (which has a tilt wheel) and my Surface Book 2's trackpad.
Aha, thanks for checking @PathogenDavid, I'll also try do more testing on my Linux and Windows laptop in native and WASM. I also see the problem in native code on my MBP (that's where I noticed it first).
It'd be weird though if this should turn out to be a problem in my input code since this shouldn't be aware at all about the child view layout differences 🤔
Hmm, how weird, on my Asus Zenbook on Windows in Chrome, horizontal wheel scrolling always has this problem. Not just when vertical scrolling is off. Vertical scrolling works fine.
And on Ubuntu with Firefox there's no problem at all. Scrolling always works in all directions.
I guess it's best if you ignore this problem for now and I'll find some time to investigate with some proper printf-debugging ;) (starting with the scroll-wheel-values that go into Dear ImGui, and following that trail).
It's weird though if this should turn out to be a problem in my input code since this shouldn't be aware at all about the child view layout differences 🤔
I would agree, it's definitely a weird issue. I'd be interested in knowing what the magnitude of MouseWheelH
is on the MacBook, especially if it's super tiny or super big. (It'd still be super weird for that to only matter when the scrollbar is missing.)
With the GLFW backend it's always either -1, 0, or 1 with my mouse. With my trackpad the magnitude seems to always be at least 0.1 and rarely exceeds 5.
(starting with the scroll-wheel-values that go into Dear ImGui, and following that trail).
Edit: lol, you beat me to it. Good luck!
Related to #3795, while working on that issue I identified more problem but didn't post details about it in the thread.
Code is in ImGui::UpdateMouseWheel()
, I suggest to add a IMGUI_DEBUG_LOG("wheel %.3f %.3f\n", wheel_x, wheel_y);
call before // Vertical Mouse Wheel scrolling
as I believe the value of both axises are useful in debugging this, so we see values over time on your system @floooh.
What I imagine happens if both wheel values are non-zero, when wheel_y != 0 we pass the scrolling up to the parent window and then scrolling is locked there. So it only happens when:
Actually between this and other issues with horizontal scrolling at the time I purchased a small touch device exactly for the purpose of testing this, and said device is sitting unopened on my desk right now...
Extracts of the related code
// Reset the locked window if we move the mouse or after the timer elapses
if (g.WheelingWindow != NULL)
{
g.WheelingWindowTimer -= g.IO.DeltaTime;
if (IsMousePosValid() && ImLengthSqr(g.IO.MousePos - g.WheelingWindowRefMousePos) > g.IO.MouseDragThreshold * g.IO.MouseDragThreshold)
g.WheelingWindowTimer = 0.0f;
if (g.WheelingWindowTimer <= 0.0f)
{
g.WheelingWindow = NULL;
g.WheelingWindowTimer = 0.0f;
}
}
Note how the locked wheeling window is selected there:
ImGuiWindow* window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow;
if (!window || window->Collapsed)
return;
Then scroll processed:
const bool swap_axis = g.IO.KeyShift && !g.IO.ConfigMacOSXBehaviors;
const float wheel_y = swap_axis ? 0.0f : g.IO.MouseWheel;
const float wheel_x = swap_axis ? g.IO.MouseWheel : g.IO.MouseWheelH;
IMGUI_DEBUG_LOG("wheel %.3f %.3f\n", wheel_x, wheel_y);
// Vertical Mouse Wheel scrolling
if (wheel_y != 0.0f)
{
StartLockWheelingWindow(window);
while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.y == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))))
window = window->ParentWindow;
if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))
{
float max_step = window->InnerRect.GetHeight() * 0.67f;
float scroll_step = ImFloor(ImMin(5 * window->CalcFontSize(), max_step));
SetScrollY(window, window->Scroll.y - wheel_y * scroll_step);
}
}
// Horizontal Mouse Wheel scrolling, or Vertical Mouse Wheel w/ Shift held
if (wheel_x != 0.0f)
{
StartLockWheelingWindow(window);
while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.x == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))))
window = window->ParentWindow;
if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))
{
float max_step = window->InnerRect.GetWidth() * 0.67f;
float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step));
SetScrollX(window, window->Scroll.x - wheel_x * scroll_step);
}
}
The wheel lock is designed so that when scrolling a parent our scroll doesn't get interrupted by a child window passing under (see #2604) and it is likely also the culprit of this issue here triggered by dual-axis wheeling which is likely to happen on "unfiltered" 2D trackpad drivers (vs actual mouse wheel which are two separate 1D wheels).
One interesting observation is that "Shift + Vertical Mouse Wheel" works in situations where "Horizontal Mouse Wheel" does not.
Also I just confirmed that the macOS touchpad (with two-finger-dragging) provides wheel information in both directions (not mututally exclusive).
...and another observation: if I hack my ImGui wrapper code to only provide one of the two wheel axis (depending which is bigger), it also appears to work. This simple hack still doesn't feel good because of the "wheel inertia" on macOS (so if I had a big change in the vertical direction, the horizontal direction is locked for some time until the vertical wheel change are close to zero).
This might also explain the different behaviour on different browsers and platforms, some of those seem to not provide X- and Y-wheel-movement at the same time (and those appear to work).
I wonder if I can fix the issue on my side with a slightly smarter "axis filter".
Hi @ocornut , I'm the original poster of #3795 ;
You wrote recently in this (#4559) issue :
it only happens when: 1) Using nested child windows where a parent can scroll on a given axis and child cannot <- PROBABLY 2) Using hardware/drivers/platform where scroll inputs are treated in 2D without any single-axis locking of the stream of values, and an initial "swipe right" tend to include a Y component. <- YES
YES for (2). When we use a touchpad (on a MacBook, with the "original" built-in touchpad:
My #3795 contained three fix, and I'm going to update my reques in #3795 to add some informations in it.
I have pushed 80a870a (slight refactor) + c7d3d22 (mitigation/fix) which should mitigate this issue. The more general issue #3795 needs work.
Would appreciate if you can test the mouse_wheeling_target_3795 branch. See: https://github.com/ocornut/imgui/pull/3795#issuecomment-1270527155
...and another observation: if I hack my ImGui wrapper code to only provide one of the two wheel axis (depending which is bigger), it also appears to work. This simple hack still doesn't feel good because of the "wheel inertia" on macOS (so if I had a big change in the vertical direction, the horizontal direction is locked for some time until the vertical wheel change are close to zero). This might also explain the different behaviour on different browsers and platforms, some of those seem to not provide X- and Y-wheel-movement at the same time (and those appear to work). I wonder if I can fix the issue on my side with a slightly smarter "axis filter".
Test would involve disabling all those workarounds on your side and feed raw unfiltered inputs. Thanks!
Excuse the weird ticket title, but that's what seems to happen :)
I just stumbled over this when working with the new table/column API, but it actually seems to be a general problem with child views (at least back to 1.82, I tested with 1.84.2 and that doesn't seem to make a difference).
In a child view which can scroll horizontally and vertically, the horizontal scrolling with MouseWheelH only seems to work properly if the view is big enough to also allow scrolling into the vertical direction. If vertical scrolling is disabled because the view is too small, horizontal scrolling doesn't work (but it doesn't seem to be completely disabled, there's some initial "jitter" on the horizontal direction, as if scrolling is attempted but then immediately reset to the initial position).
For now I only have this existing example to reproduce the problem (you'll need a laptop with touchpad, I have tested on a Mac 13"MBP).
Example video for the working case (enough room to scroll in both directions, horizontal scrolling works):
https://user-images.githubusercontent.com/1699414/134004081-68e60e8f-b2f0-4103-8801-fbe6df9a9f4a.mov
...and if the window is resized so that no vertical scrolling is possible, horizontal mouse-wheel-scrolling doesn't work (you can see some tiny horizontal movement, but it actually should properly scroll):
https://user-images.githubusercontent.com/1699414/134004337-30bbeaf4-40c6-418d-9f24-2af316a88004.mov
Attached small file for drag'n'drop:
drop_me.txt
PS: there could be a tiny chance that this might be caused by my ImGui backend code, but I think it's unlikely.