StyledTextCtrl hangs while processing EVT_STC_STYLENEEDED

(CentOS, python2.5, wxPython 2.8.9.1 -- and no, upgrading is not
possible at this time)

I'm using the StyledTextCtrl, and it repeatedly hangs while I am
processing EVT_STC_STYLENEEDED events.This only happens when I type
fast or use an autorepeat key. Events continue to be processed it
seems, but the display visually freezes.

The curious thing is, if I move all the code to another method and
call it with wx.CallAfter, the freeze goes away.

For example, consider the following code:

class MyApp:
    def __init__(self):
        ...
        self._text = wx.stc.StyledTextCtrl(...)
        self._text.SetLexer(wx.stc.STC_LEX_CONTAINER)
        self._text.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyleNeeded)

    def OnStyleNeeded(self, event):
        self.OnStyleNeededWorker()

    def OnStyleNeededWorker(self):
        start = self._text.GetEndStyled()
        start_line = self._text.LineFromPosition(start)
        for line in range(start_line, self._text.GetLineCount()):
            self._style_line(line)

With the above code, my GUI will hang if I type real fast. I can
reproduce this at will on my linux and mac boxes. It usually only
takes a couple dozen characters of input before this happens. I can
unfreeze it by doing something like resizing the window real small to
force the vertical scrollbar to appear.

However, if I change OnStyleNeeded to the following, it doesn't hang:

    def OnStyleNeeded(self, event):
        wx.CallAfter(self.OnStyleNeededWorker)

Is this a known issue with the styledtextctrl? I'm certain that my
_style_line method doesn't add or remove any characters so I'm
assuming it doesn't cause another EVT_STC_STYLENEEDED event to be
called recursively. And I'm pretty sure I'm accurately styling every
single byte (since by experimentation I discovered if I don't, the
EVT_STC_STYLENEEDED eventts never stop). I'm also certain my code
doesn't call Freeze(), and explicitly calling Thaw() when done working
has no effect.

Hi,

···

On Fri, Sep 17, 2010 at 4:24 PM, Bryan Oakley <bryan.oakley@gmail.com> wrote:

Is this a known issue with the styledtextctrl? I'm certain that my
_style_line method doesn't add or remove any characters so I'm
assuming it doesn't cause another EVT_STC_STYLENEEDED event to be
called recursively. And I'm pretty sure I'm accurately styling every
single byte (since by experimentation I discovered if I don't, the
EVT_STC_STYLENEEDED eventts never stop). I'm also certain my code
doesn't call Freeze(), and explicitly calling Thaw() when done working
has no effect.

Have you checked to see how efficient your _style_line method is? My
guess is that it is the key events are coming in faster than you are
processing them.

Cody

It's roughly as efficient as it can be, given the underlying
architecture of how the styledtextctrl works (read: if I edit the
first byte, the widget expects me to re-style the entire document
which potentially can be slow).

If it was just that I couldn't process the events fast enough I would
expect a slowdown as I type, but this is more than that. It's as if
the StyledTextCtrl called Freeze() without a subsequent Thaw(). Once
it freezes, that's it. I can't stop typing and wait for it to catch
up. If I continue to type and then click a button that fetches the
content of the widget, all my typing is in the output; it simply stops
drawing to the screen.

<shrug> calling my code via CallAfter seems to work around the
problem, but I wish I understood it better. I can't help but think
there might be some unwritten rule somewhere that says "always call
??? after processing a EVT_STC_STYLENEEDED event" or "be sure to use a
mask of ???", or something like that.

···

On Fri, Sep 17, 2010 at 9:09 PM, Cody Precord <codyprecord@gmail.com> wrote:

Hi,

On Fri, Sep 17, 2010 at 4:24 PM, Bryan Oakley <bryan.oakley@gmail.com> wrote:

Is this a known issue with the styledtextctrl? I'm certain that my
_style_line method doesn't add or remove any characters so I'm
assuming it doesn't cause another EVT_STC_STYLENEEDED event to be
called recursively. And I'm pretty sure I'm accurately styling every
single byte (since by experimentation I discovered if I don't, the
EVT_STC_STYLENEEDED eventts never stop). I'm also certain my code
doesn't call Freeze(), and explicitly calling Thaw() when done working
has no effect.

Have you checked to see how efficient your _style_line method is? My
guess is that it is the key events are coming in faster than you are
processing them.

Please make a small runnable sample that demonstrates the problem. MakingSampleApps - wxPyWiki

···

On 9/20/10 8:27 AM, Bryan Oakley wrote:

If it was just that I couldn't process the events fast enough I would
expect a slowdown as I type, but this is more than that. It's as if
the StyledTextCtrl called Freeze() without a subsequent Thaw(). Once
it freezes, that's it. I can't stop typing and wait for it to catch
up. If I continue to type and then click a button that fetches the
content of the widget, all my typing is in the output; it simply stops
drawing to the screen.

--
Robin Dunn
Software Craftsman