On 12/30/2016 11:05 AM, Jean-Marc Lasgouttes wrote: > Le 29/12/2016 à 07:21, Guillaume Munch a écrit : >> Le 27/12/2016 à 23:11, Scott Kostyshak a écrit : >>> On Tue, May 31, 2016 at 01:15:38AM +0200, Guillaume Munch wrote: >>>> commit 1cc14a31ca8320d881b674f93c34a09cf1666cca >>>> Author: Guillaume Munch <g...@lyx.org> >>>> Date: Mon May 30 21:42:08 2016 +0100 >>>> >>>> TocWidget: fix an erroneous collapse and optimise updates based >>>> on profiling >>>> >>>> TocModels::reset() in GuiView::structureChanged() collapses the >>>> TocWidget, and >>>> therefore requires an update right after, which was missing. >>>> >>>> In fact, profiling TocWidget::updateView() shows that delaying >>>> the update is >>>> good only for fast keypresses (essentially movement). It costs 5% >>>> of a >>>> char-forward operation in a document with approx. 100 table of >>>> contents >>>> items. The update optimisation has been rewritten to take this >>>> data into >>>> account. >>> >>> A git bisect suggests this causes a SIGSEGV. To reproduce: >>> >>> 1. open the attached file >>> 2. open the outline pane >>> 3. put the cursor just to the left of "Hello" (but inside the caption >>> inset) >>> 4. "Save As" to a new filename. >>> >>> Can you reproduce? >>> >>> Backtrace is attached. >>> >> >> Hi, >> >> The root of the issue is in Buffer::reload() called during "Save As". >> After loadLyXFile() there, all the insets have been deleted, and >> therefore the Inset pointer >> GuiView::documentBufferView()->cursor().inset() is dangling. Immediately >> after loadLyXFile(), reload() calls updateBuffer() from your backtrace >> which then crashes. > > In general this is when we add a cursor.fixIfBroken() somewhere.
Yes, that would simplify things. >> The attached patch fixes this crash, but I find very unsatisfactory to >> have to update the cursors by hand like this. > > What's with all the indirections? Updating directly one cursor seems > more straightforward. The issue seems to be getting a cursor in the first place, since this has to be done from Buffer. One option would be to pass a Cursor (or optional pointer to a Cursor) to Buffer::reload(). Then that can be fixed after the reload is successful. How's that sound? Otherwise, we do have to go via the gui_ pointer in Buffer, which is what leads to all the redirection. Richard