ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
61.15k stars 10.3k forks source link

MouseY has an offset in a SDL decorated window #2151

Open wmeertens opened 6 years ago

wmeertens commented 6 years ago

Version/Branch of Dear ImGui: 1.66 WIP

Back-end file/Renderer/OS: Back-ends: imgui_impl_sdl.cpp + imgui_impl_opengl3.cpp OS: ubuntu 16.04 SDL: 2.0.4

My Issue/Question: The mouse y position is offset by the height of the title bar.

imgui_impl_sdl.cpp Line44: #define SDL_HAS_CAPTURE_MOUSE SDL_VERSION_ATLEAST(2,0,4)

Line219-231: #if SDL_HAS_CAPTURE_MOUSE && !defined(EMSCRIPTEN) In this piece of code the mouse position is calculated based on the WindowPosition and the GlobalMouseState. But it doesn't take into account the size of the WindowTitleBar.

Note Checked it on a machine with SDL2.0.5 and that one doesn't have the issue. But SDL2.0.5 is also the first version which can return the size of the borders SDL_GetWindowBorderSize() (perhaps that has anything to do with it).

As it works with 2.0.5 perhaps line 44 should be changed to:

define SDL_HAS_CAPTURE_MOUSE SDL_VERSION_ATLEAST(2,0,5)

Standalone, minimal, complete and verifiable example: Can be reproduced with the /imgui-master/examples/example_sdl_opengl3/ example

Screenshots/Video

imgui_mouse_y imgui_mouse_y2

ocornut commented 6 years ago

Thank you. I don't mind raising the version to 2.0.5 on this one, those define are particularly useful in the viewport branch which rely on a bug of other 2.0.5 features anyway.

Could you however confirm that on the same machine with SDL 2.0.4, if you install 2.0.5 install the issue is fixed?

I have another issue reported elsewhere that seems to suggest SDL_GetGlobalMouseState() is probably on Mac, which I hadn't had the time to check ..

If you build the “demo” application with source and run on a Mac that has two displays hooked up (it’s most noticeable if one display is arranged as “above” the other), you can see the problem. If you drag the window created from the primary display to the secondary display, you can’t interact with the UI. The problem is actually in the handling of the mouse and started with commit 85f9694bd (“Big example binding refactor…”). Calling SDL_GetGlobalMouseState and then subtracting out the window position is what causes the problem (If I switch the code in imgui_impl_sdl2.cpp to call SDL_GetMouseState rather than SDL_GetGlobalMouseState and remove the subtraction of the window position (wx,wy), I can interact with the demo on either display.

I found that something similar was fixed in SDL on X11 (here: https://bugzilla.libsdl.org/show_bug.cgi?id=2770). My guess is that SDL isn’t being used as much on MacOS and so the same issue hasn’t been addressed. When I get a chance I’ll see if I can find/implement a fix in SDL, but just wanted to let you know about the issue.

wmeertens commented 6 years ago

I tested with both 2.0.5 and 2.0.6 on the ubuntu machine. But the problem persists. On this machine the call to SDL_GetWindowPosition consistently returns the most upper-left corner of the window. So with a decorated title bar the actual view starts at 0,height_of_titlebar.

On the MX Linux machine this call returns the position of the view. (like it's ignoring there's a title bar).

In both cases the the SDL_GetGlobalMouseState return sane values, it's only the SDL_GetWindowPosition which is different and thus give the y-offset.

So it looks like it's just an issue with SDL and my WindowManager.

avneic commented 5 years ago

Hi! I was having the same issue. I solved it as following: The mouse position can be computed by tracking the relative motions via the SDL_MOUSEMOTION event. I store the positions in global variables.

I attached a patch with my changes. mouse_motion_patch.txt