Redrawing seems to affect the frequency of mouse events

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
flutterkind
In need of some credit
In need of some credit
Posts: 3
Joined: Mon Jun 29, 2020 5:41 pm

Redrawing seems to affect the frequency of mouse events

Post by flutterkind » Mon Jun 29, 2020 6:13 pm

I am trying to create small application using wxWidgets. This is the first time I'm using wxWidgets. One of the features requires me to redraw a canvas while the user drags the mouse. While it is preferable to render and respond to user input as quickly as possible, it is not necessary for the response to be instant and I cannot guarantee the rendering process to adhere to any particular time limit. It is, however, rather important to receive mouse input events – particularly mouse move events – as often as possible, as the application wants to know the path that the mouse took retroactively.

I have noticed that if I call Refresh(), thus (eventually?) triggering a redraw, I receive significantly fewer mouse events per second. It would seem plausible that wxWidgets simply records no mouse events while my wxEVT_PAINT callback or the redraw is running. Or it could be that the redraw reduces the framerate and only one mouse movement can be recognized per frame. Ultimately, however I have no idea how the event system in wxWidgets works.

Do you know what's causing the reduction in mouse event rate?

Is it possible to prevent the redraw from affecting the frequency of mouse events? I don't mind if I receive more than one mouse event in between two redraws.

User avatar
doublemax
Moderator
Moderator
Posts: 15065
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Redrawing seems to affect the frequency of mouse events

Post by doublemax » Mon Jun 29, 2020 6:45 pm

What/how much are you actually drawing in your paint event handler?

This might be one of the few cases where it might be necessary to draw directly into the wxClientDC of the window instead of forcing a complete redraw. The "mdi" sample has some code that shows how to do that.

Be aware that you still need to keep a record of what has been drawn, because if your application receives a paint event, you need to able to redraw everything. (Everything drawing onto the wxClientDC will be lost).

Another option would be to just store the coordinates of the mouse event in a list, and in a secondary thread you process that list and draw everything into a wxBitmap. And only occasionally you redraw the window by just blitting the bitmap, which should be reasonably fast.
Use the source, Luke!

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 4360
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Redrawing seems to affect the frequency of mouse events

Post by ONEEYEMAN » Mon Jun 29, 2020 6:53 pm

Hi,
However, keep in mind that drawing on anything other than wxPaintDC is not guaranteed to work cross-platform.
In particular drawing on wxClientDC in Wayland is not supported (and mdi sample does not perform there as seen in the recent post here on the forum).

Thank you.

flutterkind
In need of some credit
In need of some credit
Posts: 3
Joined: Mon Jun 29, 2020 5:41 pm

Re: Redrawing seems to affect the frequency of mouse events

Post by flutterkind » Mon Jun 29, 2020 8:05 pm

I am not actually drawing myself, I am using the wxSVG library and drawing using the wxSVGCtrl class.

Judging from your answers it sounds like drawing faster is the only way to receive more mouse events. Is that correct?

Is there a resource where I can read up on how exactly the event system works?

User avatar
doublemax
Moderator
Moderator
Posts: 15065
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Redrawing seems to affect the frequency of mouse events

Post by doublemax » Mon Jun 29, 2020 8:45 pm

flutterkind wrote:
Mon Jun 29, 2020 8:05 pm
Is there a resource where I can read up on how exactly the event system works?
There is an overview, but it doesn't go as low-level as you probably expect: https://docs.wxwidgets.org/trunk/overview_events.html

The important bits for your case are:
- the wx event system always wraps the native events of the underlying OS

- there are no threads involved. while any event handler is executed, no other events can be processed(!) (they can be received however by the OS)

- if your event handler finished, any other pending events that may be in the event queue of the OS can be processed

- whether events get lost during the time your event handler runs, is up to the OS. e.g. i'm sure that mouse clicks and key pressed that occur during that time, are received. I'm not sure about mouse move events though. It is possible that the OS summarizes them and you only get the final position. You'd have to write a small test case to check that.
Use the source, Luke!

flutterkind
In need of some credit
In need of some credit
Posts: 3
Joined: Mon Jun 29, 2020 5:41 pm

Re: Redrawing seems to affect the frequency of mouse events

Post by flutterkind » Tue Jun 30, 2020 8:53 pm

Not being able to see new mouse move events while drawing seems rather undesirable. Do you reckon this is something specific to wxWidgets or will other UI libraries run into the same problem? I mean, I can see how it's not directly wxWidgets' fault if the OS simply only reports one mouse event after a long redraw, but I would have expected some mitigation to be in place or possible, as maintaining an input behavior that is independent from render times seems important.

User avatar
doublemax
Moderator
Moderator
Posts: 15065
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Redrawing seems to affect the frequency of mouse events

Post by doublemax » Tue Jun 30, 2020 9:17 pm

I don't think it's a wxWidgets problem and i don't know any workaround. Your paint event handler (any event handler in fact) just must finish as quickly as possible.

You say you were drawing an SVG in the paint event handler. Assuming the SVG doesn't change you should pre-render it in a bitmap and only draw the bitmap in the paint event handler.
Use the source, Luke!

Post Reply