Repository: kivy/kivy

Issue:
Mouse position wrongly processed on high-dpi screens?
Hi,

we experience a strange issue where the mouse pos seems to be wrongly processed (or I misunderstood something). When executing the same code ([see gist](https://gist.github.com/johanneshk/a043333546494e0ae5957ac4c08542b7)), on a Macbook with dpi=192 the mouse pos for the top two squares (click on them) is twice what you get on a 'normal' screen with dpi=96. Which is why we assume that something's wrong with the dpi. The behavior on the 96dpi screen is what we expect.

The top squares are arranged in a GridLayout, the bottom squares in a RelativeLayout. Interestingly the positions for the squares in the RelativeLayout seem to be correct.

Tow screenshots that demonstrate this behavior: [correct](http://i.imgur.com/jGCMR5T.png) [wrong](http://imgur.com/WSULgp1)

Any ideas?



Discussion:
if the dpi is double, all dpi-aware sizes and coordinates will double, this is expected behavior.

If you have a widget with pos `(0, 0)` in Window coordinates and with a size of `('100dp', '100dp')`, you would expect `mouse_pos` to be `(200, 200)` at the upper right corner of the widget when the dpi is 192, no?

The issue is that you're comparing different units - `sp` vs `px`. You specify sizes in `sp`, but internally we convert everything to `px`, because everything we interact with expects `px`. In your case here, you're passing in a size of `50sp`, which is equal to `100px` (`50 * density=2 * fontscale=1`). When you read back the size value, you will always get a value in `px` (we can't make assumptions about what unit you want).

We don't provide a method to convert `px` to other units (only the other way around), but it's a simple process. You can check out the function [`dpi2px`](https://github.com/kivy/kivy/blob/master/kivy/properties.pyx#L223) to see how we do the conversion to `px`.

OK, but please consider again the 'wrong' screenshot (there's something I don't yet understand): If you click on the top left square (as shown) and don't move the mouse after clicking (in the screenshot the mouse has been moved), what you see is, that the mouse pos as recorded in the top-most line is half of what's recorded in the white square that opens. But isn't mouse pos already given in px and shouldn't be influenced by the dpi (or some other means)? Or is the mouse pos converted, once it's passed to the root widget?

And why is it that if I do
`KIVY_DPI=192 python main.py`
on my 96-dpi screen, both mouse positions are exactly the same?

To summarize: What I don't understand is why on a Retina Macbook touch_pos isn't equal to mouse_pos when clicking. Actually  2 \* touch_pos = mouse_pos (see 'wrong' screenshots, and my further explanations in my previous comment). As I understand touch.pos as given by on_touch_down and mouse_pos as given by Window.mouse_pos are given in window coordinates, and thus when a click occurs, both should be the same. Or shouldn't they? x

Plus: As explained in my previous comment, the dpi doesn't seem to influence this behavior.

x touch pos is given in parent coordinates, but in my example parent coordinates should coincide with window coordinates (!?).

Looking at the code, at first glance it looks like they should be the same. I'm not sure why they would end up being different. But I don't have a retina MacBook to test with myself.

Let me know if I somehow can help (I don't own a Retina MacBook, though). I wonder if this is an issue of pygame vs. sdl2, because on my Linux machine I use pygame but on OSX sdl2 is used. 

Any idea where this behavior might originate from? I looked at pygame / sdl window providers, but as far as I understand it, everything's fine there. 

Maybe something is wrong between SDL and kivy or the SDL version that is used contains bugs? 
E.g.: http://stackoverflow.com/questions/18544881/sdl-2-0-retina-mac
Apparently one can emulate a high dpi screen:
http://stackoverflow.com/questions/12124576/how-to-simulate-a-retina-display-hidpi-mode-in-mac-os-x-10-8-mountain-lion-on?rq=1
https://gist.github.com/simX/3191869

I'll see if I can reproduce this on my normal screen.

EDIT: If I follow the instructions in the gist above, I can choose a HiDPI resolution on my Mac Mini and reproduce this behavior.


Resolving patch:
diff --git a/kivy/core/window/window_sdl2.py b/kivy/core/window/window_sdl2.py
--- a/kivy/core/window/window_sdl2.py
+++ b/kivy/core/window/window_sdl2.py
@@ -381,7 +381,7 @@ def _set_cursor_state(self, value):
 
     def _fix_mouse_pos(self, x, y):
         y -= 1
-        self.mouse_pos = x, self.system_size[1] - y
+        self.mouse_pos = x * self._density, (self.system_size[1] - y) * self._density
         return x, y
 
     def _mainloop(self):


Test patch: