SDL_RenderSetLogicalSize: Mouse coordinates after resize

Hi folks

I am new here and I have just started writing a framework/template for small graphical desktop applications, using SDL2 for video, events and audio. So far everything went very smoothly and I really appreciate the work you guys/gals put into this. But today I have encountered the following problem:

When using SDL_RenderSetLogicalSize the mouse coordinates (x/y) reported by mousemotion, mousebuttondown and mousebuttonup events are completely wrong after resizing my main window.
I could not find any documentation on this function in the API reference, so all I know, about what it is supposed to do, is from the comments in the header that defines the function (iirc SDL_render.h). There it says: “If the output display is a window, mouse events in the window will be filtered and scaled so they seem to arrive within the logical resolution.”

I understand this as: If I render an image and click on a feature on that image, then resize the window, display the same (now scaled) image again and click on the same feature I should get the same mousecoordinates in a mousebuttondown event in both cases. But this is not the case (far from it…I get seemingly random numbers like 2254 and -189). If my understanding is correct, and please correct me if it is not, then that would be exactly the behaviour I am looking for.

Also I made a simple test without rendering an image and with keeping the aspect ratio constant between resizes:

  • I opened a window with a resolution of 1280x720 (aspect ratio 16:9), and the logical size was set to that. Reported mouse coordinates went from (0,0) to (1279,719); so perfect, exactly what I would expect.
  • Then I resized the window to 1600x900 (also aspect ratio 16:9) using SDL_SetWindowSize. Reported mouse coordinates now went from (0,0) to (1023, 575), which is still 16:9, but neither the initial/logical resolution, nor the new one.

So when using the same aspect ratio in resizes the values do not seem like complete bogus, but they still do not make sense to me (why would the reported coordinates be in a smaller 16:9 resolution than the initial/logical resolution?). Btw. it makes no difference whether the window is resized using SDL_SetWindowSize or using the window manager.

This has gotten a bit long, sorry for that. I would basically just like to know whether this behaviour is a bug or I do not understand how it is supposed to work. If you need more information/tests please feel free to ask.

Extra information that may (or may not) be useful:

My programming platform is Debian/GNU Linux with a 3.10.9 kernel, NVidia driver 325.15, Xorg 1.12.4 and Fluxbox 1.3.5 as the window manager (nothing else runs on top of the xserver by default (e.g. no panels, starters, docks, etc.)). I use SDL2 version 2.0.0 and SDL2_image version 2.0.0 at the moment.

I did some additional testing.
When I set the viewport to the new resolution myself, using SDL_RenderSetViewport, in my size_changed event callback then the mouse coordinates of the top-left corner of the window are (0,0) again (as is the case when not using SDL_RenderSetLogicalSize and resizing). But the x/y-coordinates reported by my mouse event callbacks still end up with wrong values for the bottom right corner of the window.
It seems that if I scale the window to a larger size than the logical resolution, then the mouse coordinates only go to much smaller values than this, and vice versa.

Does anyone know where I can find the source code for this mouse coordinate scaling that is done when using SDL_RenderSetLogicalSize?

I believe it is in the SDL_RendererEventWatch callback in SDL_render.c
(line 102 in my copy).

Jonny DOn Tue, Sep 10, 2013 at 6:28 AM, lgm <xxx.xxx at x-mail.net> wrote:

**
I did some additional testing.
When I set the viewport to the new resolution myself, using
SDL_RenderSetViewport, in my size_changed event callback then the mouse
coordinates of the top-left corner of the window are (0,0) again (as is the
case when not using SDL_RenderSetLogicalSize and resizing). But the
x/y-coordinates reported by my mouse event callbacks still end up with
wrong values for the bottom right corner of the window.
It seems that if I scale the window to a larger size than the logical
resolution, then the mouse coordinates only go to much smaller values than
this, and vice versa.

Does anyone know where I can find the source code for this mouse
coordinate scaling that is done when using SDL_RenderSetLogicalSize?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Thank you Jonny D, that was exactly what I was looking for.

I went through the SDL_RendererEventWatch function several times with pen and paper on hand, checking the calculations, and everything seemed perfectly fine. I would expect small rounding errors, but nothing huge like described above. Then, looking at the coordinates gathered in tests I did before, I found the problem:

The strange/wrong coordinates can be perfectly explained when going through the whole function twice (for one resize)!

Is this just happening on my system, or is it a general bug? Is it possible that resize events as well as size_changed events both trigger this same function in just one effective resize (e.g. just one call to SDL_SetWindowSize or one resize using the window manager controls)?

I reported a bug that sounds suspiciously familiar to this in SDL1.2 ages
ago. I forget some of the details, but basically it was clamping mouse
coordinates to the old window size and not the new one.

Now I know that the functionality in SDL2 is mostly completely different
from SDL1.2, but perhaps this is the same issue, and the section of code
is reused from the old codebase??

I need to look through the old bug reports to see the exact issue. IIRC,
it was filed under my name “Stephen Anthony”.On September 10, 2013 7:51:01 PM lgm wrote:

Thank you Jonny D, that was exactly what I was looking for.

I went through the SDL_RendererEventWatch function several times with
pen and paper on hand, checking the calculations, and everything
seemed perfectly fine. I would expect small rounding errors, but
nothing huge like described above. Then, looking at the coordinates
gathered in tests I did before, I found the problem:

The strange/wrong coordinates can be perfectly explained when going
through the whole function twice (for one resize)!

Is this just happening on my system, or is it a general bug? Is it
possible that resize events as well as size_changed events both
trigger this same function in just one effective resize (e.g. just one
call to SDL_SetWindowSize or one resize using the window manager
controls)?

I did some more testing. I set an event filter for size_changed events and can now say that there are definitely two size_changed events arriving at the event queue for one window resize. Their data1 and data2 fields hold identical values (the new window size), therefore the renderer side of the scaling does not show wrong behaviour (it just does unnecessary work), but the mouse coordinates are first scaled to their correct values and then those correct values are scaled a second time to the wrong values (the ones I then receive in my mouse events).

I solved the problem! There is nothing wrong with SDL. It was my own fault. I waited for events and then started polling as soon as one arrived (to be as light as possible on CPU usage). To not have all events double, I popped the first and pushed it back, and from then on processed them normally. This worked perfectly for all normal events, but it turns out that events which have a filter attached to them (like size_changed, mousemotion, mousebuttondown and mousebuttonup) trigger that filter function twice (because it is triggered before events go into the event queue). That is why the filter function for size_changed and the scaling of the mouse coordinates was done twice.
Sorry for the wild goose chase. [Embarassed]

1 Like