Stefan Monnier writes: >> I attach a patch with a first idea (based on Stefan's suggestions), >> where we "protect" the parent's markers, inside widget-default-create. >> This is so we can try to catch almost all situations where this bug >> might arise. > > I can't judge whether `widget-default-create` covers all the cases, but > other than that, it's looking good (well, I find this "set and later reset" > to be rather ugly/brittle, but that's probably as good as it gets given > what we have). Thanks for taking a look. >> +(defun widget--protect-parent-markers (widget) >> +  "Protect the :from and :to markers of the WIDGET's parent, if necessary. >> + >> +Usually, the :from marker has type t, while the :to marker has type nil. >> +When creating a child or a button inside a composite widget, they have to be >> +changed to nil and t respectively, so that the WIDGET's parent (if any), >> +properly contains all of its children and buttons." >> +  (let* ((parent (widget-get widget :parent)) >> +         (parent-from-marker (and parent (widget-get parent :from))) >> +         (parent-to-marker (and parent (widget-get parent :to))) >> +         (pos (point))) >> +    (when (and parent-from-marker >> +               (eq pos (marker-position parent-from-marker))) >> +      (set-marker-insertion-type parent-from-marker nil)) >> +    (when (and parent-to-marker >> +               (eq pos (marker-position parent-to-marker))) >> +      (set-marker-insertion-type parent-to-marker t)))) >> + >> +(defun widget--unprotect-parent-markers (widget) >> +  "Unprotect the :from and :to markers of the WIDGET's parent, if necessary. >> + >> +Changes the :from marker type back to t and the :to marker type back to nil." >> +  (let* ((parent (widget-get widget :parent)) >> +         (parent-from-marker (and parent (widget-get parent :from))) >> +         (parent-to-marker (and parent (widget-get parent :to)))) >> +    (when parent-from-marker >> +      (set-marker-insertion-type parent-from-marker t)) >> +    (when parent-to-marker >> +      (set-marker-insertion-type parent-to-marker nil)))) > > I'm not a big fan of the name "protect" here, to be honest. > Maybe `widget--prepare-parent-for-insertion`? Sounds a little bit better, thanks.  I went for something similar. >> It doesn't catch _all_, in theory, since it might happen >> that a grandparent widget doesn't adjust its markers, but maybe that's >> unusual enough that we can get away with it. > > We can probably handle that case easily by just adding to > `widget--protect-parent-markers` a recursive call if either the :from or > the :to marker had to be adjusted.  The only difficulty I see is making > sure we adjust all the makers in the "unprotect" case that we > protected earlier.  Maybe we should make > `widget--protect-parent-markers` return a list of (MARKER > . PREVIOUS-TYPE) so the `widget--unprotect-parent-markers` > would turn into something like (mapcar (apply-partially #'apply > #'set-marker-insertion-type) ...). > IIUC that list would be empty in the vast majority of cases. Thanks for this idea. I attach a patch that implements something like that, along with a new test to check the recursive case.