Const wrote:
If this is normal behavior, then it seems unsafe to me. Shouldn't the
current event handler (`onShowDialog()` below) finish before the event
loop processes another user triggered event?
The situation is not that cut-and-dried. Remember that, to the
operating system, the modal dialog is just another window in your
application. Clicking a button on that window is exactly the same as
clicking a button in your main window. Both of them are just a cascade
of events that get sent to your thread's message queue.
Now, as I said before, I am surprised by the behavior you're seeing.
When I have written modal window handlers, the process has been:
Disable parent window
while( event loop alive )
GetMessage
DispatchMessage
Enable parent window
With that architecture, the situation you're describing cannot happen,
because the parent window is disabled until the event loop exits. There
can't be any new clicks until the parent is re-enabled, and anything
that happens afterward will stay in the queue until we get back to our
main message loop. It APPEARS, from the behavior, that ShowModal is not
doing that. If so, I think you could argue that's a bug in wx. I will
look into the source code and see what I can find..
Ah, it turns out there's already a wxWidgets bug report about this:
wxTrac has been migrated to GitHub Issues - wxWidgets
The obvious fix apparently has undesirable side effects, so it has not
been fixed yet.
So, the only way to reliably do some work after calling `ShowModal()`
is as follows:
onShowDialog(self, event):
dlg = MyDialog(self)
with wx.WindowDisabler():
res = dlg.ShowModal()
doSomeWork()
This works, but can send the main application frame behind another
window; see previous post.
The current ShowModal handler does create a WindowDisabler before
starting the loop. The problem seems to be that it deletes the disabler
during its OnExit handler, which is called in response to an event while
the message loop is still running.
···
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.