Tk Source Code

Ticket Change Details
Login
Overview

Artifact ID: 2e790be3820b45b17080e6a1bfddca5e4f643134d43700205276531018404b75
Ticket: bdd1f64523f509f2632cdaaed4447de8c5abb7cb
Assertion failed when switching -elide in the revised text widget
User & Date: fvogel 2025-02-01 15:26:15
Changes

  1. assignee changed to: "fvogel"
  2. icomment:
    Many thanks for your input. There are small errors in your post (notably segment order inversion in the linked list, the 3rd and 2nd segments are in the wrong order - the picture above that list is however correct), but it was definitely very useful to help me in the debug process.
    
    I have understood what's happening. When toggling the -elide state of seg4 (the "text_hidden" segment), in the first iteration of the [https://core.tcl-lang.org/tk/artifact/c5bb7602?ln=8736|while (1) loop], the lastBranchPtr is obtained by [https://core.tcl-lang.org/tk/artifact/c5bb7602?ln=8872|calling TkBTreeFindStartOfElidedRange()]. This function supposes (and checks through asserts) that the segment from which it is requested to start its search for the branch segment is elided. With the given reproducible script, at the time this gets called, that segment is not seen as elided since the elide state of the tag pertaining to this segment already has its state toggled to the desired new state (here: 0). And the assert (correctly) triggers.
    
    I can think of at least two possible fixes:
    
      a.  Temporarily restore the elide state of the tag before calling TkBTreeFindStartOfElidedRange(), and do the reverse manoeuver after this call. This is [https://core.tcl-lang.org/tk/artifact/c5bb7602?ln=8681,8721|done already in the code] for finding the elide state of the segment predecessing the start of the considered range, that is to set the value of 'actualElided'.
    
      b.  Instead of starting the search for the branch segment from the first segment of the range where the elide state must be toggled, start the search from the segment that precedes it. This must work because this predecessing segment is always elided (actualElided=1) at this place of the code.
    
    Fix a. is easy to understand, is straightforward to implement, and is safe. I have implemented it in [4bce1cc132].
    
    Fix b. is more elegant (instead of passing <code>*firstSegPtr</code>, just pass <code>(*firstSegPtr)->prevPtr</code> to TkBTreeFindStartOfElidedRange()) but it is more difficult to do correctly since there might be cases where <code>(*firstSegPtr)->prevPtr</code> could be NULL, which would need to be handled by looking at the previous line (and what if there is no previous line, and so on). I have to think about this.
    
    At this point, could you perhaps try fix a. and confirm whether it works in your large aplication? We could perhaps decide to be satisfied enough by this fix.
    
  3. login: "fvogel"
  4. mimetype: "text/x-fossil-wiki"
  5. resolution changed to: "Fixed"