wxStyledTextCtrl: SetStatusText() function call destroys the brace highlight feature under Windows

43 views
Skip to first unread message

asmwarrior

unread,
Dec 27, 2015, 4:13:48 PM12/27/15
to wx-u...@googlegroups.com
Hi, I noticed that if I have a SetStatusText() function call inside the wxStyledTextCtrl's EVT_STC_UPDATEUI event handler, the brace highlight failed.
I'm using the Windows XP system, MinGW-Build GCC 5.2 compiler. See the below code snippet:

======================
void AppFrame::OnUpdate(wxStyledTextEvent &WXUNUSED(event))
{
    int min = m_edit->GetCurrentPos ();
    int max = m_edit->BraceMatch (min);
    if (max > (min+1)) {
        m_edit->BraceHighlight (min, max);
        int pos = m_edit->GetCurrentLine();
        static wxString msg;
        msg.Printf(_("Line %d, Column %d"), m_edit->GetCurrentLine() + 1, m_edit->GetColumn(pos) + 1);
        // note that if I comment out the below line, the bug disappeared
        SetStatusText(msg, 0);
    }else{
        m_edit->BraceBadLight (min);
    }
}

======================

SetStatusText(msg, 0) will destroy the previous BraceHighlight()'s behaviour.
To demonstrate this bug, you can just build the stc sample with my attached patch, I'm testing it under the wx trunk, also this bug exists in wx 3.0.2 release. But the official SciTE 3.6.2 for Windows does not show such issue, so I guess it is a bug inside the wx or the wx platform support for scintilla control.

Here is the steps to reproduce:
1, apply my attached path
2, build the stc(styledtextctrl) sample in the code repo
3, run the stc sample, and open a cpp file which have below contents.

======================
void main(    )

{
   
   
}

======================

4, first, mouse click before the "(", you will noticed the brace highlight works OK for the "(    )".
5, then, mouse click before the "{", you will noticed a new brace highlight on the "{", but "}" is not highlighted. Also the previous highlighted

"(    )" is still there.

That's the bug in step 5!
If you comment out the call "
SetStatusText(msg, 0);", everything works fine!

Debugged for a while, I noticed that internally
BraceHighlight() function will call the function:

======================
bool Editor::AbandonPaint() {
    if ((paintState == painting) && !paintingAllText) {
        paintState = paintAbandoned;
    }
    return paintState == paintAbandoned;
}

======================

And once this happens, a refresh() function is called through "
stc->Refresh(false);", see below:

======================
void ScintillaWX::DoPaint(wxDC* dc, wxRect rect) {

    paintState = painting;
    AutoSurface surfaceWindow(dc, this);
    if (surfaceWindow) {
        rcPaint = PRectangleFromwxRect(rect);
        PRectangle rcClient = GetClientRectangle();
        paintingAllText = rcPaint.Contains(rcClient);

        ClipChildren(*dc, rcPaint);
        Paint(surfaceWindow, rcPaint);
        surfaceWindow->Release();
    }

    if (paintState == paintAbandoned) {
        // Painting area was insufficient to cover new styling or brace
        // highlight positions.  So trigger a new paint event that will
        // repaint the whole window.
        stc->Refresh(false);
       
#if defined(__WXOSX__)
        // On Mac we also need to finish the current paint to make sure that
        // everything is on the screen that needs to be there between now and
        // when the next paint event arrives.
        FullPaintDC(dc);
#endif
    }
    paintState = notPainting;
}
======================

What's the strange thing is: when I received the paint event, I see that:


======================
void wxStyledTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(evt)) {
#ifdef __WXGTK__
    wxBufferedPaintDC dc(this);
#else
    wxPaintDC dc(this);
#endif
    m_swx->DoPaint(&dc, GetUpdateRegion().GetBox());
}
======================

GetUpdateRegion().GetBox() only get a line region cover the "{", not the whole client area. So that the "}" is not highlighted, and the previous highlighted braces are not cleared.

Any one can help? Thanks.

In-fact this bug also happens in the Codeblocks internal wxScintilla control, you can see discussions here:
http://forums.codeblocks.org/index.php/topic,20795.msg141916.html#msg141916
And you can also see the badly highlighted braces in the screen shot image:
http://i683.photobucket.com/albums/vv194/ollydbg_cb/2015-12-25%2012%2029%2037_zpsciuajuti.png

BTW: in stc sample, I think the code of Edit::OnBraceMatch is not correct.
======================
void Edit::OnBraceMatch (wxCommandEvent &WXUNUSED(event)) {
    int min = GetCurrentPos ();
    int max = BraceMatch (min);
    if (max > (min+1)) {
        BraceHighlight (min+1, max);
        SetSelection (min+1, max);
    }else{
        BraceBadLight (min);
    }
}
======================
BraceHighlight (min+1, max); should be BraceHighlight (min, max);
In my attached patch, I don't change this, but I use the correct code in my added AppFrame::OnUpdate() function.


Asmwarrior(C::B developer)


0001-wxStyledTextCtrl-bug-when-SetStatusText-is-used-in-u.patch

Eran Ifrah

unread,
Dec 28, 2015, 1:40:26 AM12/28/15
to wx-u...@googlegroups.com
Hi Asmwarrior,

You did not mention the wxWidgets version you are using, but if you are using wx3.0 or later, you could change this line:

SetStatusText(msg, 0);

to:

CallAfter(&AppFrame::SetStatusText, msg, 0);

Usually it fixes such things

In this particular case, it will also improves the editor performance

Eran



--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.
 
To unsubscribe, send email to wx-users+u...@googlegroups.com
or visit http://groups.google.com/group/wx-users



--
Eran Ifrah,
Author of codelite, a cross platform open source C/C++ IDE: http://www.codelite.org

AsmWarrior

unread,
Dec 28, 2015, 2:30:17 AM12/28/15
to wx-users

On Monday, December 28, 2015 at 2:40:26 PM UTC+8, Eran Ifrah wrote:
Hi Asmwarrior,

You did not mention the wxWidgets version you are using, but if you are using wx3.0 or later, you could change this line:

SetStatusText(msg, 0);

to:

CallAfter(&AppFrame::SetStatusText, msg, 0);

Usually it fixes such things

In this particular case, it will also improves the editor performance

Eran

Hi, Eran, Thanks. I did mention that "wx trunk", but that was not clear, sorry. I see this issue in wx 3.0.2 and wx git master head. (I'm currently try to migrate C::B from wx 2.8.12 to wx 3.0.2).

I just test the trick as you suggest, and great, this solves the issue. Thanks. I'm not sure why this kind of trick solves this issue, maybe we should do not do too many things inside the paint event handler.

Asmwarrior
Reply all
Reply to author
Forward
Message has been deleted
0 new messages