Non-blocking (Popup)menu possible?
Non-blocking (Popup)menu possible?
I currently implement a context menu (wxMenu) with Popupmenu(), but that is a blocking function. It halts execution of the rest of the application. This is a problem for me, because the application is running a real-time simulation which should continue in the background regardless of UI events. Think of it like a video player, where you can right click to toggle options such as subtitles or aspect ratio, while the video keeps playing.
I noticed that when the same menu is shown by clicking via wxMenuBar on Linux/GTK, it doesn't block, so it seems it should be possible to prevent blocking. So why the difference?
On Windows, showing any menu via wxMenuBar does block, like Popupmenu, so it is consistent there (but not desirable). Is there a Windows specific workaround for this?
Does choosing the parent window of the wxMenu (via ::Popupmenu) influence anything?
Are there workarounds? It's fine if the solution is hacky or unsafe. I already implement a manual main loop in this application.
I noticed that when the same menu is shown by clicking via wxMenuBar on Linux/GTK, it doesn't block, so it seems it should be possible to prevent blocking. So why the difference?
On Windows, showing any menu via wxMenuBar does block, like Popupmenu, so it is consistent there (but not desirable). Is there a Windows specific workaround for this?
Does choosing the parent window of the wxMenu (via ::Popupmenu) influence anything?
Are there workarounds? It's fine if the solution is hacky or unsafe. I already implement a manual main loop in this application.
Re: Non-blocking (Popup)menu possible?
Hi,
You best bet on implementing this - run the real-time simulation in a thread, posting the events to the main GUI.
Unfortunately GUI should be run only from the main thread, so you should make you simulation run from the thread.
Everything will work as expected.
Thank you.
You best bet on implementing this - run the real-time simulation in a thread, posting the events to the main GUI.
Unfortunately GUI should be run only from the main thread, so you should make you simulation run from the thread.
Everything will work as expected.
Thank you.
Re: Non-blocking (Popup)menu possible?
I think menus are always blocking under Windows. The only solution i could think of would be to build your own popup menu using wxPopupTransientWindow.
http://docs.wxwidgets.org/trunk/classwx ... indow.html
The "popup" sample shows how to use it.
http://docs.wxwidgets.org/trunk/classwx ... indow.html
The "popup" sample shows how to use it.
Use the source, Luke!
Re: Non-blocking (Popup)menu possible?
Thanks doublemax, didn't know about that one yet, I will experiment with it and post the results here. It is kinda weird though that something as simple as showing a menu blocks things, while other more complex controls don't.
@ONEEYEMAN: I try to avoid threads at all cost, I've found they are rarely needed (even for real-time interactive applications), and usually a symptom of bad design, and often lead to a host of other problems. In the worst case, I'll try wrapping the menu itself in a thread rather than the other way around.
@ONEEYEMAN: I try to avoid threads at all cost, I've found they are rarely needed (even for real-time interactive applications), and usually a symptom of bad design, and often lead to a host of other problems. In the worst case, I'll try wrapping the menu itself in a thread rather than the other way around.
Re: Non-blocking (Popup)menu possible?
Rendul,
Please don't do that.
The GUI has to be run from the main thread only.
Thank you.
Please don't do that.
The GUI has to be run from the main thread only.
Thank you.
Re: Non-blocking (Popup)menu possible?
Hi Remdul,
I'm facing the exact same problem (trying to display a popup menu in a non blocking manner).
Did you find a solution/workaround?
Thank you very much in advance.
I'm facing the exact same problem (trying to display a popup menu in a non blocking manner).
Did you find a solution/workaround?
Thank you very much in advance.
Re: Non-blocking (Popup)menu possible?
When menus are shown (and scrollbars are active, and probably a few other cases), idle events were not sent on MSW (and this might have changed in 3.1.x versions). BTW, which version did you use? Your app is probably relying on the "next idle event". Otherwise, the menu should not be "blocking" anything.
One possible solution is to try with the latest version (i.e. the newly released 3.1.5).
Another one is to switch to timer-based triggering.
There may be others..
One possible solution is to try with the latest version (i.e. the newly released 3.1.5).
Another one is to switch to timer-based triggering.
There may be others..
Re: Non-blocking (Popup)menu possible?
Dear Catalin,
Thank you very much for your extremely quick and precise response.
Even though I failed to mention which system I'm working on, which version of wxWidgets I'm using, and couldn't even formulate my question properly, you've got it all right.
(I'm working on MSW with wxWidgets 3.1.4)
As you explained, even though wxWindow::PopupMenu(...) is a blocking call (it doesn't return until the popup menu is closed), wxWidget's event system is still working behind the scenes, and events are still sent/received, in the main thread, during that period of time.
On MSW however, this excludes idle events, which are simply not sent. As you guessed, I was indeed relying on them to do updates on my underlying wxGLCanvas.
I can confirm that this behaviour is still in effect with 3.1.5, which I just tried.
+++
Following your suggestion, I'm now launching a wxTimer just before calling wxWindow::PopupMenu(...) and use it to trigger my updates while the menu is on.
As it's already been reported here:
viewtopic.php?t=43967
a wxTimer with zero interval on MSW has quite a poor granularity (~15ms tick interval on average, with frequent occurrences of the worst case at more that 20ms), so I experience frame drops while the context menu is on, but I can live with that.
As soon as the context menu is closed, updates can get triggered by idle events again, with a much better granularity, and we're back to silky smooth 60 fps.
+++
Again, thank you very much Catalin. Even though I'd really like to see idle events being sent when menus are shown in future versions of wxWidgets, your suggestion helped me a lot.
Thanks!
Thank you very much for your extremely quick and precise response.
Even though I failed to mention which system I'm working on, which version of wxWidgets I'm using, and couldn't even formulate my question properly, you've got it all right.
(I'm working on MSW with wxWidgets 3.1.4)
As you explained, even though wxWindow::PopupMenu(...) is a blocking call (it doesn't return until the popup menu is closed), wxWidget's event system is still working behind the scenes, and events are still sent/received, in the main thread, during that period of time.
On MSW however, this excludes idle events, which are simply not sent. As you guessed, I was indeed relying on them to do updates on my underlying wxGLCanvas.
I can confirm that this behaviour is still in effect with 3.1.5, which I just tried.
+++
Following your suggestion, I'm now launching a wxTimer just before calling wxWindow::PopupMenu(...) and use it to trigger my updates while the menu is on.
As it's already been reported here:
viewtopic.php?t=43967
a wxTimer with zero interval on MSW has quite a poor granularity (~15ms tick interval on average, with frequent occurrences of the worst case at more that 20ms), so I experience frame drops while the context menu is on, but I can live with that.
As soon as the context menu is closed, updates can get triggered by idle events again, with a much better granularity, and we're back to silky smooth 60 fps.
+++
Again, thank you very much Catalin. Even though I'd really like to see idle events being sent when menus are shown in future versions of wxWidgets, your suggestion helped me a lot.
Thanks!
-
- Earned some good credits
- Posts: 100
- Joined: Sun Jun 27, 2010 6:18 pm
Re: Non-blocking (Popup)menu possible?
Is CallAfter considered to be idle event? I noticed that timer/mouse events are still processed on PopupMenu but CallAfter callback called in the separate thread is not.meltphace wrote: ↑Fri Apr 16, 2021 8:09 am As you explained, even though wxWindow::PopupMenu(...) is a blocking call (it doesn't return until the popup menu is closed), wxWidget's event system is still working behind the scenes, and events are still sent/received, in the main thread, during that period of time.
On MSW however, this excludes idle events, which are simply not sent. As you guessed, I was indeed relying on them to do updates on my underlying wxGLCanvas.
Re: Non-blocking (Popup)menu possible?
AFAIR what you pass to CallAfter will be executed in the main thread at the next idle event. So CallAfter is not itself an idle event, but depends on an idle event.