Re: wxPython 4/wx.Yield: C++ assert failure

Robin Dunn <[email protected]>
Newsgroups gmane.comp.python.wxpython.devel
Message-ID <[email protected]>
Hi Jamie,

James Teh wrote:
> Hi.
>
> I'm the NVDA developer Joseph was discussing this with. First, my
> thanks to all who have helped with this so far.
>
> Even though I totally understand that wx.Yield can cause re-entrance
> (this is clearly documented), this wasn't previously the case when
> starting the same timer within that timer's callback. That is,
> *another* timer or a wx event might get fired within wx.Yield, but the
> *same* timer never fired. Instead, the inner call to the timer was
> dropped. That is what this test case demonstrates. In wxPython 3, you
> never see the re-entrance message. In wxPython 4, you do.
>
> The question is whether this change is intentional/expected and
> whether the previous behaviour will be restored. It's reasonable to
> argue that we were relying on undefined behaviour (or maybe even a
> bug), and if that is the case and this won't be reverted, we'll find
> another way. However, I wanted to confirm this before putting a huge
> amount of work into "fixing" this.

The wx.PyTimer class is implemented differently in Phoenix than it was
in Classic, but I don't see how that difference could cause this
difference in behavior. I'm not aware of changes in the C++ wxTimer that
might lead to this, but that doesn't mean there aren't any. (There were
no changes in the MSW implementation of wxTimer, but it could be that
one of the changes in how the events are dispatched or something could
have had some impact.)

Either way, the way it is working now is how I've always expected timers
and yielding to work, so I think that this probably is a case of relying
on some undefined behavior.

> The reason we use wx.Yield here is that we need to trigger a Windows
> message pump when sending key presses and checking for pending
> accessibility events, since keyboard events and accessibility events
> depend on the Windows message queue. I guess we could just do our own
> message pump, but I'm concerned this would end up processing wx events
> anyway.

If I understand correctly what you are doing I think you are correct,
unless you manage your message queue on a different thread. It's been a
long time since I worked at that level of the Windows API so I may be
forgetting something however.

There may be some alternatives though. I've not used this before so I
don't know if it will have the effect you are looking for, but I see
that the wx.EventLoopBase class has a WakeUp method that sounds
interesting.  You can call it something like this:

    wx.GetApp().GetMainLoop().WakeUp()


Or you can make your own temporary wx event loop with code like this:

    evtLoop = wx.GetApp().GetTraits().CreateEventLoop()
    with wx.EventLoopActivator(evtLoop):
        # automatically restores the old one upon exit from the context
manager


Once you have the event loop you can selectively yield for categories of
events with the YieldFor method. Messages received that are not in the
given category will be put back on the queue to be processed later. I'm
not sure if this will provide enough control for your needs, but it is
probably worth investigating.

You can also derive a new class from wx.EventLoopBase and use that
instead of the default returned from CreateEventLoop. With a derived
class you can implement your own MainLoop and implement your message
processing there.

HTH,
Robin

-- 
Robin Dunn
Software Craftsman
http://wxPython.org

-- 
You received this message because you are subscribed to the Google Groups "wxPython-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.