Incorrect mouse position on OSX

I’ve noticed that the mouse pointer seems to be a few pixels off vertically on OS X. Specifically, the tip of the pointer seems to be 2 or 3 pixels below where it appears on screen. This means that when you mouse down, you’re not mousing down where you appear to be.

You can see what I mean by running the Juce Demo and moving the mouse up and down over the main menu. It works especially well if you use the native title bar. You can get to a point where the menu highlights in purple because the mouse is over it, but when you click, you’re actually clicking on the title bar, and if you drag after clicking, you’ll be dragging the window around, but the menu item will still be highlighted.

Anyone else notice this sort of behavior?

No… can’t see that here…

Maybe a silly question, but you know that in OSX the mouse-cursor’s hotspot is the topmost black pixel, not the topmost white pixel of its outline?

1 Like

Sure, but that doesn’t change what I described above.

Here’s a screenshot. It looks like the mouse is over the menu (as evidenced by the purple highlight around “Look-and-Feel”), but you’re just gonna have to trust me that when I click and drag the mouse at that position, it moves the window, and the menu doesn’t open.

It’s also worth mentioning that it doesn’t happen every time – you have to play with it a bit to get it to happen.

Well - the arrow’s hotspot is definitely over the menu, so the highlighting is correct.

And since it’s the OS, and not my code that decides whether to start dragging the window’s titlebar, then if that’s incorrect, then it’s not something that I could fix! Perhaps the OS just allows a small margin of error when grabbing the title bar?

So in summary: not a bug, and certainly not an incorrect mouse position!

I wonder, is it possibly related to this?

Maybe it’s just that the mouseEnter/Exit callbacks aren’t happening exactly right, due to the difficulties you describe in that thread. Although it looks to be specific to plugins, so I’m not sure it applies.

Did you not read my post?

The cursor is INSIDE the menu. The position is correct. There is no bug.

Let me clarify. I should have said that I’ve also gotten it to happen when the topmost black mouse pixel is definitely OUTSIDE the target area, even if just by one pixel. I can see it. And it happens with Components that are entirely inside a Juce window. For example, as I leave a button’s area, the topmost black mouse pixel is clearly not inside the button, but the button remains highlighted. However, when I mouse down, I’m not clicking on the button.

It’s hard to grab a clear screen capture of this, because the Grab utility seems to render the pointer poorly, but I can assure you that it’s happening.

I don’t know if it’s a Juce issue or not – I’m just trying to see if anyone else has noticed this. Maybe it’s just my mouse. But I’ve also noticed that mouse drags occasionally report an incorrect length, off by one pixel. I’m guessing it’s the same issue. It sometimes makes it difficult to precisely set a slider value, for example.

The mouse position is actually a floating point value, so there could easily be rounding errors of up to 1 pixel - unless if was definitely and consistently wrong by more than that, then there’s really nothing to investigate!

Ahh, that’s interesting! When you say it’s a floating point value, do you mean natively in OS X? Because Juce MouseEvents have all integer members, right? So is there a conversion happening somewhere? I bet that’s what it is.

Yes, the OS supplies it with floating point accuracy, and some mice will provide sub-pixel positions. But honestly, don’t worry about it!

To be perfectly honest with you, I’m concerned about it because it makes mouse drags inaccurate in my app.

However, I think I’ve fixed it in the following function in by changing roundToInt:

static Point<int> getMousePos (NSEvent* e, NSView* view) { NSPoint p = [view convertPoint: [e locationInWindow] fromView: nil]; return Point<int> (roundToInt (p.x), roundToInt ([view frame].size.height - p.y)); }
to (int):

This resolves my issue, but I don’t know if it will create any new issues.

Ok, to be honest that change probably makes good sense because of rounding errors in just-below-zero values, but… your app requires the user to click on things so accurately that a 1-pixel error causes problems!? Isn’t the real problem here your crazy expectations of people’s hand-to-eye coordination!?

For example, I often use a graphics tablet, and it’s impossible to click on things without the mouse wobbling by a few pixels - how would I be able to use your app?

It’s not so much that the accuracy is necessary, but that a user actually gets what they think they’re getting. If the mouse is dragged to change a value, the value shouldn’t change after the mouse is released. This becomes even more of an issue when using beginDragAutoRepeat, since it might not look like the mouse pointer is moving.

You’re right though – I didn’t expect people would be using my app with a graphics tablet, but I should keep that in mind.

Off topic, but I use a tablet too! Maybe its just me, but the amount of mouse clicking I do in a day is insane. (I tried the ‘mighty’/‘mouse’ mouse too but still cramped). Having a touch sensitive pen certainly helps.

On topic, i’m not up to date on the tip so can’t comment, but I have seen on occasion my app tracking menu changes offset by 400 pixels! (Probably the offset distance from the main window’s left edge[in which case it(drawing submenu’s) would happen x pixels to the left of the window]) Swapping out of the app and back into it fixes things, and its so rare as to not even be worth mentioning.

I know many changes have been done regarding mouse cursor and floatness since then, but I still have that 1 pixel issue here.
cf the two attached screenshots. sometime it's fine, sometimes not...

Really nothing can be done to improve the component mouse over accuracy?


1 Like

The mouse over is already accurate, what you're seeing is an artifact of subpixel positioning :) If your UI is relying upon single pixel precision, you're asking too much of your users!