Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mouse scrolling not working #228

Open
Qlii256 opened this issue Apr 25, 2021 · 8 comments
Open

Mouse scrolling not working #228

Qlii256 opened this issue Apr 25, 2021 · 8 comments

Comments

@Qlii256
Copy link

Qlii256 commented Apr 25, 2021

For some reason whenever I have a window in focus that has a scrollbar (vertical), using the mouses' scroll wheel does not scroll the window. I can however click and drag the scrollbar to move it. Is there something extra I have to do to enable this? This is on MacOS, haven't tested it on Windows though. Using the latest stable build of pyimgui.

@KinoxKlark
Copy link
Member

What is the window management API that you use (glfw, pyglet, sdl2, etc )? Did you correctly map the scrolling event to imgui io .mouse_wheel and io.mouse_wheel_horizontal?

I am only able to check it on Windows 10 but have you a code example that reproduces your problem?

@Qlii256
Copy link
Author

Qlii256 commented Apr 25, 2021

I'm using Pyglet, and I did not know I had to link the mouse wheel events? The docs don't have anything on this.

@KinoxKlark
Copy link
Member

Normally, if you use the proposed integration in imgui.integrations.pyglet you shouldn't have to set it yourself. Unfortunately, I am not that familiar with pyglet and can only test it on Windows where everything looks fine for vertical scrolling (pyglet 1.5.14). I did however check the integration code to check for anything fishy and what I found is that the scrolling callback was defined as:

def on_mouse_scroll(self, x, y, mods, scroll):
        self.io.mouse_wheel = scroll

In pyglet documentation (latest release) I can see that they suggest to use:

def on_mouse_scroll(x, y, scroll_x, scroll_y):
    pass

I don't know if your problem might somehow link to this. As I understand it the vertical scroll scroll_y is passed as the fourth parameter. Pyimgui gets the scroll value as its fourth parameter as well and uses it for vertical scrolling which seems alright. But I don't know why we use parameters mods instead of scroll_x (probably an ancient artifact of old code). In any case, nothing is done for horizontal scrolling which is definitely a bug. A more correct implementation would look like this:

def on_mouse_scroll(self, x, y, scroll_x, scroll_y):
        self.io.mouse_wheel_horizontal = scroll_x
        self.io.mouse_wheel = scroll_y

I'll create a push request for this but I would prefer that we found the origin of your problem before in order to not forget anything important.

Can you confirm that the implementation code that you have looks like what I have shown here please? Could you test that callbacks are correctly called with reasonable values? Is it possible for you to test it on another machine to check that the same problem reproduces? (Note: the implementation code is in imgui/integrations/pyglet.py. You should be able to copy/past it to create your custom integration for testing and import create_renderer() from it as in example code.)

@Qlii256
Copy link
Author

Qlii256 commented Apr 25, 2021

The integration file has this in it:

def on_mouse_scroll(self, x, y, mods, scroll):
    self.io.mouse_wheel = scroll

Which seems wrong to me? I can however verify that when I print scroll by editing the integration file, I do get values when scrolling. But the actual ImGui windows are not being scrolled. I've also noticed that there's a print in _on_mods_change which is quite annoying and spamming my console whenever I press any of the modifier keys (should I create a separate bug report for this? I guess I could fix this myself and do a pull request if that's ok).

I'd also like to go through the whole integration of pyglet and "clean it up" if that's ok. Because I've never really looked into that file and I can see a lot of very old code, such as the mods and scroll as you mentioned.

@KinoxKlark
Copy link
Member

Mmh, I think it would be a problem with imgui if the correct data is passed through io.mouse_wheel. IO properties assignations are directly mapped to C pointer ImGuiIO properties assignation. For now, I have no clue what could cause your issue, I'll have to take a deeper look but I can't promise to do it quickly. Unfortunately, I do not have a lot of spare time these coming days. I suppose that you have the same problem with other integration codes like glwf?

Concerning the print statement in _on_mods_change I think that it already has been removed since I can't see it in the master branch (but can definitely see it in the latest release). So I don't think that there is a need for another bug report for this one.

You are more than welcome to propose a cleanup version of pyglet integration code. I don't think that it has been updated for a long time and I don't know that anybody has planned to do it. Thanks for your help!

@KinoxKlark
Copy link
Member

KinoxKlark commented Apr 25, 2021

Sorry for the double post but it quickly crossed my mind that IO should be cleared after a call to end_frame(). Dear imgui use inputs during the new_frame() call. Thus if IO are set between new_frame() and end_frame() they should be ignored. This clearly seems to be incompatible with the callbacks implementation with Pyglet (and possibly other integration code). However I do not see any use of end_frame() which seems wrong to me. I will have to take a closer look at that.

EDIT: Dear Imgui automatically call EndFrame() at the end of the Render() call, so nothing fishy here.

@Qlii256
Copy link
Author

Qlii256 commented Apr 25, 2021

You might be on to something! I'll try to dig into the code a little deeper and try and understand how it all works. The way it's set up now in the integration file is like you say, it's doing it whenever a pyglet event is triggered. So I guess the integration should cache it and send it over once end_frame() is called. Is there a way to know if we're in between end_frame() and new_frame()?

Also worth noting that mouse presses and keyboard clicks seem to work fine, which would also be sent just whenever and could also lie in-between new_frame() and end_frame() if I'm not mistaking?

EDIT: One more thing, so I just have a imgui.begin() and imgui.end() and in between some imgui.text(). Enough to get a scrollbar. Is there anything else I need to do to make sure that scrollbar will work while scrolling? I've made sure the window is "active/focused", and it still doesn't work.

@KinoxKlark
Copy link
Member

My bad, the end_frame() is automatically called at the end of render(). Thus it is not a problem with the integration code (I added an edit to my previous message).

Yes, I think it could be cached and sent to imgui once per frame. It is not yet part of the master branch but in #192 the integration code has a process_inputs() method that should be called before the new_frame() call (It is used to update delta time). So my suggestion would be to cache inputs in the PygletMixin object when a callback is triggered and send it once per frame to imgui in process_inputs().

Also worth noting that mouse presses and keyboard clicks seem to work fine, which would also be sent just whenever and could also lie in-between new_frame() and end_frame() if I'm not mistaking?

Indeed the same problem should occur with mouse presses and keyboard clicks. I think we should be careful and verify "somehow" that this is the origin of the problem and that it should be changed.

One more thing, so I just have a imgui.begin() and imgui.end() and in between some imgui.text(). Enough to get a scrollbar. Is there anything else I need to do to make sure that scrollbar will work while scrolling? I've made sure the window is "active/focused", and it still doesn't work.

I think you got it and that should work just like that. It should also work without window focus (but may depend on your os).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants