#1584 Line-wrapping occurs for minimized windows

Bug
closed-wont-fix
scintilla (329)
5
2014-04-04
2014-03-21
No

Scintilla does line-wrapping calculations when idle.
But: if the window that has the Scintilla window as a child is minimized (talking about Windows here), the line-wrapping is completely off:

In bool Editor::WrapLines(enum wrapScope ws) these lines are the problem:

    if (lineToWrap < lineToWrapEnd) {

        PRectangle rcTextArea = GetClientRectangle();
        rcTextArea.left = vs.textStart;
        rcTextArea.right -= vs.rightMarginWidth;
                    ......

When the window is minimized, the rcTextArea rectangle is zero (left, top, right, bottom are all 0).
I think in that situation, the line-wrapping calculations should not happen at all.

Discussion

  • Neil Hodgson

    Neil Hodgson - 2014-03-21

    Any lexing/folding performed for the line wrapping will be stored and remain valid. Also, depending on the line layout cache settings, much of the line layout, apart from the wrap points, should remain valid. Therefore, the work performed here may be beneficial since Scintilla will be able to respond more quickly when restored,

     
  • Stefan Kueng

    Stefan Kueng - 2014-03-21

    But the line-wrapping done with a rect that's null won't be of any use.
    Actually, it's worse: when restoring the window again, the line-wrapping calculations are completely wrong because it calculated that the lines were wrapped at every single char, and therefore it calculated that there are as many display lines as there are chars.

    That then leads to SCI_GETFIRSTVISIBLELINE return the same as SCI_GETLENGTH, at least until the line-wrapping is recalculated.

    The cache should stay valid, that shouldn't change. But Scintilla should not 'refresh' that cache with invalid data - a NULL window clearly messes up that data.

     
    • Neil Hodgson

      Neil Hodgson - 2014-03-21

      Please look at the LineLayout::validity field and the difference between the llPositions state and the llLines state.

       
  • Stefan Kueng

    Stefan Kueng - 2014-03-21

    Ok, the validity field is changed from the ChangeSize() method:
    void Editor::ChangeSize() {
    DropGraphics(false);
    SetScrollBars();
    if (Wrapping()) {
    PRectangle rcTextArea = GetClientRectangle();
    rcTextArea.left = vs.textStart;
    rcTextArea.right -= vs.rightMarginWidth;
    if (wrapWidth != rcTextArea.Width()) {
    NeedWrapping();
    Redraw();
    }
    }
    }

    This is called due to the WM_SIZE message that gets sent when the window minimizes. And here the GetClientRectangle() returns a null rect because the window is minimized.

    With this info, I figured out a workaround which helps solving my problem due to this. But I still think Scintilla should not act upon null rects - if the window has no size then all calculations done on that are 'null' and void too.

     
    • Neil Hodgson

      Neil Hodgson - 2014-03-21

      It may be OK to special case width=0 and not try to progress from llPositions to llLines. Or treat width=0 as infinite or very large width. That allows setting up the cached position information.

      Another option would be for your application to switch off wrap when minimised although that may decache some progress.

       
  • Stefan Kueng

    Stefan Kueng - 2014-03-22

    I'm now working around the issue by catching the WM_SIZE message and prevent it from getting sent to Scintilla if the window is minimized.
    That solves the problem I'm having with this for me.

     
    • Neil Hodgson

      Neil Hodgson - 2014-03-22

      The normal thing to do in Windows is to check the parameters to WM_SIZE and not perform the sub-window sizing or layout when wParam is SIZE_MINIMIZED(1). This is what SciTE does which is why this issue has never been observed in SciTE.

       
  • Neil Hodgson

    Neil Hodgson - 2014-04-04
    • labels: --> scintilla
    • status: open --> closed-wont-fix
    • assigned_to: Neil Hodgson
     

Log in to post a comment.