Mac Magic mouse

Is there a way to stop temporarily the mouse wheel scrolling when you give it a push. Normally, that’s a good feature, for example when quick scrolling through many pages in a text, but one of my cases it’s really annoying.

Depending on the control, return True from the MouseWheel event.

Yes I got Return True on Mouse Wheel. It works on an ordinary mouse having the typical “tractor wheel” for scrolling, but there you can’t set in motion like on a track pad or phone. In almost every aspect I prefer the Magic Mouse, but in this particular case it’s really annoying.

I believe the keyword you are looking for is “inertia” (this is when the scroll gesture starts an object scrolling, and it keeps scrolling as if it has momentum). There are some other behaviors such as the “rubber band” or “bounceback” effects which happen when you hit the end of the scroll limit. Which ones are you trying to disable?

Me, I’d like to disable the rubber-banding and the bounceback. Very irritating when one’s app contains an HTMLViewer.

Specifically, I use the scroll wheel for zooming in and out over a fairly complex model. This means that the model has to be updated, which of course take a little time, say 0.15 to 0.30 seconds for a full redraw and 0.1 to 0.15 seconds in “simplified mode” used when working dynamically. With a standard mouse wheel, it’s not really a problem, but with Apple’s Magic Mouse, it often tends to live a life of it’s own, going into a frantic for several seconds where it goes into an uncontrolled spin. I have tried all sorts of timers to block it, without much success.

Have you tried logic like this?


Event MouseWheel
   if Timer1.Mode = Timer.RunModes.Single then
    Timer1.Mode = Timer.RunModes.Single
  end if

In other words, while the user is still scrolling, you never update the display, always waiting until the scroll events have stopped, before allowing the timer to trigger the refresh.

Finding a way to turn off inertia might be a better solution? Not sure.

What 3D display technology are you using?

Here’s an example (which uses WebGL) : three.js examples and on my mac, it renders perfectly at 60fps, even when using the zoom in / zoom out behaviors on my Magic Mouse.

TLDR: If you can get your refresh code running in under 16msec, then you shouldn’t have any issues with scroll mouse events.

I will experiment a bit with that

First of all, the scroll wheel is only used for zooming, no actual scrolling. The problem is not when running OpenGL, which I also do. It used the scroll wheel for zooming there, and it’s not a problem.

The problem lies in the modeling unit, which does not use OpenGL, as its main purpose is to model fairly complex parametric NURBS based shapes, and where the task usually consist of hundreds or even thousands of micro adjustments. The example consist of around 325 objects controlled by about 13000 control points.

Thanks, that helps explain the situation. If I were you, I would do this:

  • run my app using apple Instruments / Time Profiler and look for any slow methods. If you are lucky, you might get your 300msec render time down to 30msec or lower.
  • if this isn’t possible, figure out a way to abort a render-in-progress. Using this scheme, you start rendering on any mouseEvent, but if a second event arrives while you are rendering, you immediatly abort and start rendering again. This pretty much requires that your rendering be happening in a separate thread.
  • you may need to add some heuristics, such as keeping track of the prior render time so the rendner code knows when it’s smarter to abort vs. just finishing.

Edit to add

  • you mention already having “simplified mode” which takes 100msec. Could you do some more optimizations so that gets down to 20msec or faster? That might also solve all your problems.

  • I wonder if the issue is that you are rendering in the main thread, and since events are blocked in the main thread until the current event completes, these scroll events are “stacking up”. The solution would be to render in a thread, so events come in realtime to the main thread, and then have some logic deciding when to ignore or honor the events, something like this:

Canvas1.MouseWheel(X as integer, Y as integer, DeltaX as integer, DeltaY as Integer) as boolean
  if RenderingThread.IsStillWorking()
       ' store the new scroll coordinates, but don't actually render yet
       scrollX = scrollX + deltaX
       scrollY = scrollY + deltaY
      Timer1.Reset ' launch a timer which will actually do the render, but if the timer was already counting down, reset it
      Self.Invalidate() ' trigger a render now
  end if
end Function

Are you using compiler #pragmas judiciously?
In xojo, tight loops doing small changes can be very inefficient, since each loop will check for Thread yielding, nil objects, etc.

Try adding

   #pragma BackgroundTasks False 
   #pragma BoundsChecking False 
   #pragma NilObjectChecking False 
   #pragma StackOverflowChecking false

I’ve seen these lead to an easy ~10x speedup in tight loops where not much calculation is being done

1 Like

I have worked very hard optimizing the code, and generally speaking, it actually feels quite snappy. I have accepted that it will never be the fastest program, as I have favored shape control and maneuverability over speed. It uses a dynamic method for calculating the shape of the model at any given time in the fly, which costs in speed. In reality though, it does what it’s supposed to do way quicker than any similar program on the market doing what the program does as it constantly delivers feedback to the user.

Of course, I always try to improve the speed. One lead I have is that the Windows version on a fairly humble I3 clone seems to be faster than on an M1 Macbook. The test model redrawing times are 0.16 vs 0.20 on average in favor of the Windows machine. For some reason the Mac is slightly quicker in Simplified mode (used when rotating the model) 0.07 vs 0.055 seconds. It suggests that math grinding may be a bit slower on the Mac, whereas the drawing parts works better (as lines, it’s about 100 000 objects to draw).

Anyway, my problem is fairly restricted to this zoom thing, and explicitly using this particular mouse. An ordinary mouse is not really a problem. I will investigate your leads. Thanks for your help.

1 Like