This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch reproducible-widget-previews
in repository efl.
View the commit online.
commit bd26a126cdcddc4f52379555f66c78bae1e6d2d5
Author: Cedric BAIL <[email protected]>
AuthorDate: Tue Mar 17 22:47:49 2026 -0600
ecore_cocoa: accumulate trackpad scroll deltas instead of emitting per-event
macOS trackpads report scroll events via hasPreciseScrollingDeltas
with fine-grained pixel deltas (often < 5 points per event). The
old code converted every such event into z = ±1, meaning a single
finger swipe that generated 30-50 events would scroll 30-50 lines
— far too fast for any practical use.
Accumulate the precise pixel deltas and only emit an
Ecore_Event_Mouse_Wheel once the built-up amount crosses a
threshold (40 points, roughly one line of text). The accumulator
is reset when a new scroll gesture begins (NSEventPhaseBegan)
and when both the gesture and momentum phases end.
Discrete scroll events (physical mouse wheel) are unchanged and
still emit z = ±1 per click.
This also fixes a pre-existing memory leak where the Ecore event
struct was allocated before the zero-delta early-exit check.
Made-with: Cursor
---
src/lib/ecore_cocoa/ecore_cocoa.m | 114 ++++++++++++++++++++++++++++----------
1 file changed, 86 insertions(+), 28 deletions(-)
diff --git a/src/lib/ecore_cocoa/ecore_cocoa.m b/src/lib/ecore_cocoa/ecore_cocoa.m
index 35daac6179..ae52f24727 100644
--- a/src/lib/ecore_cocoa/ecore_cocoa.m
+++ b/src/lib/ecore_cocoa/ecore_cocoa.m
@@ -341,46 +341,104 @@ _ecore_cocoa_feed_events(void *anEvent)
}
case NSEventTypeScrollWheel:
{
+ /* Trackpads report fine-grained pixel deltas via
+ * hasPreciseScrollingDeltas. Each tiny delta used to produce
+ * z = ±1, making scrolling absurdly fast. Accumulate the
+ * pixel values and only emit a wheel event once the built-up
+ * amount crosses a per-line threshold. */
+ static float _scroll_acc_x = 0.0f;
+ static float _scroll_acc_y = 0.0f;
+ static const float PRECISE_SCROLL_THRESHOLD = 40.0f;
+
DBG("Scroll Wheel");
EcoreCocoaWindow *window = (EcoreCocoaWindow *)[event window];
- Ecore_Event_Mouse_Wheel *ev;
- float dx, dy = 0;
-
- ev = calloc(1, sizeof(Ecore_Event_Mouse_Wheel));
- if (!ev) return pass;
if ([event hasPreciseScrollingDeltas])
{
- dx = -[event scrollingDeltaX];
- dy = -[event scrollingDeltaY];
+ NSEventPhase phase = [event phase];
+ NSEventPhase momentum = [event momentumPhase];
+ int steps;
+
+ if (phase == NSEventPhaseBegan)
+ {
+ _scroll_acc_x = 0.0f;
+ _scroll_acc_y = 0.0f;
+ }
+
+ _scroll_acc_x += [event scrollingDeltaX];
+ _scroll_acc_y += [event scrollingDeltaY];
+
+ /* vertical */
+ steps = (int)(_scroll_acc_y / PRECISE_SCROLL_THRESHOLD);
+ if (steps != 0)
+ {
+ Ecore_Event_Mouse_Wheel *ev;
+ ev = calloc(1, sizeof(Ecore_Event_Mouse_Wheel));
+ if (ev)
+ {
+ _scroll_acc_y -= steps * PRECISE_SCROLL_THRESHOLD;
+ ev->window = (Ecore_Window)window.ecore_window_data;
+ ev->event_window = ev->window;
+ ev->modifiers = ecore_cocoa_event_modifiers([event modifierFlags]);
+ ev->timestamp = time;
+ ev->direction = 0;
+ ev->z = -steps;
+ ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL);
+ }
+ }
+
+ /* horizontal */
+ steps = (int)(_scroll_acc_x / PRECISE_SCROLL_THRESHOLD);
+ if (steps != 0)
+ {
+ Ecore_Event_Mouse_Wheel *ev;
+ ev = calloc(1, sizeof(Ecore_Event_Mouse_Wheel));
+ if (ev)
+ {
+ _scroll_acc_x -= steps * PRECISE_SCROLL_THRESHOLD;
+ ev->window = (Ecore_Window)window.ecore_window_data;
+ ev->event_window = ev->window;
+ ev->modifiers = ecore_cocoa_event_modifiers([event modifierFlags]);
+ ev->timestamp = time;
+ ev->direction = 1;
+ ev->z = -steps;
+ ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL);
+ }
+ }
+
+ if (phase == NSEventPhaseEnded ||
+ phase == NSEventPhaseCancelled ||
+ momentum == NSEventPhaseEnded ||
+ momentum == NSEventPhaseCancelled)
+ {
+ _scroll_acc_x = 0.0f;
+ _scroll_acc_y = 0.0f;
+ }
}
else
{
- dx = -[event deltaX];
- dy = -[event deltaY];
- }
+ /* Discrete scrolling (mouse wheel): one event per click. */
+ Ecore_Event_Mouse_Wheel *ev;
+ float dx = -[event deltaX];
+ float dy = -[event deltaY];
- if (dx == 0 && dy == 0)
- {
- break;
- }
+ if (dx == 0 && dy == 0) break;
- ev->window = (Ecore_Window)window.ecore_window_data;
- ev->event_window = ev->window;
- ev->modifiers = ecore_cocoa_event_modifiers([event modifierFlags]);
- ev->timestamp = time;
- if (dy != 0)
- {
- ev->z = (dy > 0) ? 1 : -1;
- }
- else
- {
- ev->z = (dx > 0) ? 1 : -1;
- }
- ev->direction = (dy != 0) ? 0 : 1;
+ ev = calloc(1, sizeof(Ecore_Event_Mouse_Wheel));
+ if (!ev) break;
- ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL);
+ ev->window = (Ecore_Window)window.ecore_window_data;
+ ev->event_window = ev->window;
+ ev->modifiers = ecore_cocoa_event_modifiers([event modifierFlags]);
+ ev->timestamp = time;
+ if (dy != 0)
+ ev->z = (dy > 0) ? 1 : -1;
+ else
+ ev->z = (dx > 0) ? 1 : -1;
+ ev->direction = (dy != 0) ? 0 : 1;
+ ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL);
+ }
break;
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.