proton icon indicating copy to clipboard operation
proton copied to clipboard

Bullet list toggle bug – numbered and unordered lists overlap

Open margolisdavid opened this issue 2 months ago • 2 comments

Environment:

  • Proton version: 0.8.35 (commit 30c0f87)
  • Platform: iOS
  • SwiftUI integration using EditorView + ListCommand
  • Custom EditorListFormattingProvider for bullets/numbers

Steps to Reproduce

  1. Start a bullet list. Hit return to create next item on list.
  2. The next bullet is auto continued on the next line.
  3. Tap to switch to an alternative bullet, ie numbered bullets.
  4. The bullet from step 2 vanishes. There is now no bullet at all.
  5. User taps the bullet button again to try and get their bullet.
  6. Now the original bullet returns with the numbered bullet at the same time. ie they are literally on top of each other!

Expected Behaviour

  • Toggling from a numbered list to a bullet list should replace the marker cleanly (one style active at a time).

Actual Behaviour

  • Switching list type can leave both attributes active in the same paragraph, producing overlapping markers.

Additional Notes

  • I’ve verified the issue persists even after explicitly removing all known list-related attributes (com.rajdeep.proton.list, NSListItem, ProtonListKind, etc.) before applying the new list type.
  • Delaying cleanup with DispatchQueue.main.asyncAfter doesn’t solve it.
  • Appears related to internal async normalisation pass in ListTextProcessor that re-applies previous attributes.

Would love any guidance on whether this is known or in-progress — happy to help test potential fixes.

Thanks for all the brilliant work on Proton

Dave

margolisdavid avatar Oct 26 '25 10:10 margolisdavid

hi @margolisdavid, thanks for the appreciation. This is a known issue. I'll try to get a fix in in next few days. The cause of the issue is within layout manager that may end up drawing the list marker over the previous ones in some cases, like the one you ran into. If you would like to look into this, drawListMarkers would be the starting point and looking at the ranges that it's trying to draw in.

rajdeep avatar Oct 27 '25 06:10 rajdeep

@margolisdavid, I spent some time looking at it and this is what I am seeing in 0.8.35, and also the latest main:

Image

I mentioned this earlier as a known issue because same has also been reported earlier but I wasn't able to get to it until now. In the example above, the only change is that I am toggling the ListFormattingProvider and invoking editor.invalidateDisplay(for: range).

If you would like to try the same in Proton Example app, you can use this patch: list-toggle.patch. For invalidating the range of text, I have just used the entire range of editor, but if you choose to use this, it would be best to get the range of list to invalidate the display. You can use editor.attributeRangeFor(.listItem, at: editor.selectedRange.location - 1) to query that, with a check for location != 0:

rajdeep avatar Oct 30 '25 23:10 rajdeep