So the crash John reported comes in at r31203. Here's the recipe, again:

1. Open LyX. File>New. Document>Outline, to make sure the TOC is open. That isn't necessary, but it helps you to see what is happening.
2. Create a section heading (alt-P, 2) with an x in it.
3. Split the screen.
4. File>New. You should now still see the TOC for the OLD buffer.
5. Click in the top screen. You now see an empty TOC (the one for the empty buffer).
6. Click in the empty buffer. Other TOC!
7. Back to the "x" buffer. Empty TOC. Type something. Boom!

So the issue is that the TOC is out of sync. It gets out of sync when (a) Buffer 1 is open in both top and bottom, but (b) it is actually viewed in only one of them and (c) you click back and forth between top and bottom. You can get it back into sync by clicking on the tabs in the bottom view.

I can explain why this happens, but I am not sure how to fix it. The attached patch solves the problem, but looks ugly.

The change that caused the crash is here:

void GuiView::structureChanged()
{
    //** used to be d.toc_models_.reset(view());
    d.toc_models_.reset(documentBufferView());
    LYXERR0(documentBufferView());
// Navigator needs more than a simple update in this case. It needs to be
    // rebuilt.
    updateDialog("toc", "");
}

The LYXERR0 call is worth adding if you investigate: You can see from it that we're setting the TOC for the wrong BufferView.

We get there from:

void GuiView::setCurrentWorkArea(GuiWorkArea * wa)
{
....
    for (int i = 0; i != d.splitter_->count(); ++i) {
        if (d.tabWorkArea(i)->setCurrentWorkArea(wa)) { // << THIS LINE
            d.current_main_work_area_ = wa;
            return;
        }
    }

It is the setCurrentWorkArea() call that eventually gets us to structureChanged(). The crucial point is that it does so BEFORE the current_main_work_area_ is reset. That means that documentBufferView(), which is
&currentMainWorkArea()->bufferView()
still points to the OLD BufferView. That's why we have the wrong TOC.

Given the LYXERR0 call above, you can see that this is in fact happening even with a split view for a single document. There's no bad effect with the TOC, since they have the same TOC, but there's surely some other bug in the offing.

Richard

Index: src/frontends/qt4/GuiView.cpp
===================================================================
--- src/frontends/qt4/GuiView.cpp       (revision 35965)
+++ src/frontends/qt4/GuiView.cpp       (working copy)
@@ -1216,17 +1216,23 @@
 
        theGuiApp()->setCurrentView(this);
        d.current_work_area_ = wa;
+       
+       // We need to reset this now, because it will need to be
+       // right if the tabWorkArea gets reset in the for loop. We
+       // will change it back if we aren't in that case.
+       GuiWorkArea * const old_cmwa = d.current_main_work_area_;
+       d.current_main_work_area_ = wa;
+
        for (int i = 0; i != d.splitter_->count(); ++i) {
                if (d.tabWorkArea(i)->setCurrentWorkArea(wa)) {
-                       //if (d.current_main_work_area_)
-                       //      
d.current_main_work_area_->setFrameStyle(QFrame::NoFrame);
-                       d.current_main_work_area_ = wa;
-                       //d.current_main_work_area_->setFrameStyle(QFrame::Box 
| QFrame::Plain);
-                       //d.current_main_work_area_->setLineWidth(2);
-                       LYXERR(Debug::DEBUG, "Current wa: " << 
currentWorkArea() << ", Current main wa: " << currentMainWorkArea());
+                       LYXERR(Debug::DEBUG, "Current wa: " << 
currentWorkArea() 
+                               << ", Current main wa: " << 
currentMainWorkArea());
                        return;
                }
        }
+       
+       d.current_main_work_area_ = old_cmwa;
+       
        LYXERR(Debug::DEBUG, "This is not a tabbed wa");
        on_currentWorkAreaChanged(wa);
        BufferView & bv = wa->bufferView();
@@ -1394,6 +1400,7 @@
 void GuiView::structureChanged()
 {
        d.toc_models_.reset(documentBufferView());
+       LYXERR0(documentBufferView());
        // Navigator needs more than a simple update in this case. It needs to 
be
        // rebuilt.
        updateDialog("toc", "");

Reply via email to