]> git.lyx.org Git - lyx.git/commitdiff
Reduce metrics updates from 4 to 1 when loading file
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Wed, 22 Nov 2023 11:07:51 +0000 (12:07 +0100)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Fri, 5 Apr 2024 11:06:26 +0000 (13:06 +0200)
The number of metrics updates when loading file and showing it in a
new work area is unreasonable.

The first avoided call to updateMetrics() was an explicit resize in
BufferView::init(). Instead, an assertion is suppressed by exiting
early BufferView::processUpdateFlags() when BufferView::ready()
returns false. This is a new method introduced to factor in some
existing tests.

Two other metrics computations are avoided by setting the enclosing
View object busy() while creating the new tab. To make this work
properly, GuiWorkArea::scheduleRedraw has to return early in this
case.

When saving an unnamed document or invoking "Save as...", call
setBusy(false) earlier so that repainting occurs correctly.

Fixes bug #12976.

src/Buffer.cpp
src/BufferView.cpp
src/BufferView.h
src/frontends/qt/GuiWorkArea.cpp

index de7f4d217c98b947f09a0796de4f3607ca23f525..bbe4d80589651fa2bf86bcc6a7029c153e7dd408 100644 (file)
@@ -5562,6 +5562,7 @@ Buffer::ReadStatus Buffer::reload()
        Buffer const * oldparent = d->parent();
        d->setParent(nullptr);
        ReadStatus const status = loadLyXFile();
+       setBusy(false);
        if (status == ReadSuccess) {
                updateBuffer();
                changed(true);
@@ -5578,7 +5579,6 @@ Buffer::ReadStatus Buffer::reload()
        } else {
                message(bformat(_("Could not reload document %1$s."), disp_fn));
        }
-       setBusy(false);
        removePreviews();
        updatePreviews();
        errors("Parse");
index f0e3704064acf008e91a36977aa2d44e1cf3db3c..34be8606914e92c0b4111b9caac0520b092dd425 100644 (file)
@@ -532,7 +532,7 @@ void BufferView::processUpdateFlags(Update::flags flags)
                   << flagsAsString(flags) << ")  buffer: " << &buffer_);
 
        // Case when no explicit update is requested.
-       if (flags == Update::None)
+       if (flags == Update::None || !ready())
                return;
 
        /* FIXME We would like to avoid doing this here, since it is very
@@ -611,7 +611,7 @@ void BufferView::processUpdateFlags(Update::flags flags)
 
 void BufferView::updateScrollbarParameters()
 {
-       if (height_ == 0 && width_ == 0)
+       if (!ready())
                return;
 
        // We prefer fixed size line scrolling.
@@ -2625,6 +2625,9 @@ void BufferView::mouseEventDispatch(FuncRequest const & cmd0)
 {
        //lyxerr << "[ cmd0 " << cmd0 << "]" << endl;
 
+       if (!ready())
+               return;
+
        // This is only called for mouse related events including
        // LFUN_FILE_OPEN generated by drag-and-drop.
        FuncRequest cmd = cmd0;
@@ -3125,7 +3128,7 @@ void BufferView::updateMetrics()
 
 void BufferView::updateMetrics(bool force)
 {
-       if (height_ == 0 || width_ == 0)
+       if (!ready())
                return;
 
        Text & buftext = buffer_.text();
@@ -3586,7 +3589,7 @@ bool BufferView::busy() const
 
 void BufferView::draw(frontend::Painter & pain, bool paint_caret)
 {
-       if (height_ == 0 || width_ == 0)
+       if (!ready())
                return;
        LYXERR(Debug::PAINTING, (pain.isNull() ? "\t\t--- START NODRAW ---"
                                 : "\t\t*** START DRAWING ***"));
index cc92e215fb3cecf7d4b87db92dab1d657c9bac08..327536a916cd7bdee06dd22f0479ce74cfbc3710 100644 (file)
@@ -348,6 +348,8 @@ public:
        /// the shape of the caret
        frontend::CaretGeometry const & caretGeometry() const;
 
+       /// Returns true when metrics have been computed at least once
+       bool ready() const { return width_ > 0 && height_ > 0; }
        /// Returns true when the BufferView is not ready for drawing
        bool busy() const;
        ///
index 7999dceda9fb6fb765d3b77a312c78f6ad847dee..de8241c21faa8c859fd5723426c758d9adb9d756 100644 (file)
@@ -199,9 +199,6 @@ void GuiWorkArea::init()
                });
 
        d->resetScreen();
-       // A mouse event will happen before the first paint event,
-       // so make sure that the buffer view has an up to date metrics.
-       d->buffer_view_->resize(viewport()->width(), viewport()->height());
 
        setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        setAcceptDrops(true);
@@ -345,7 +342,7 @@ void GuiWorkArea::toggleCaret()
 
 void GuiWorkArea::scheduleRedraw(bool update_metrics)
 {
-       if (!isVisible())
+       if (!isVisible() || view().busy())
                // No need to redraw in this case.
                return;
 
@@ -1793,6 +1790,7 @@ bool TabWorkArea::setCurrentWorkArea(GuiWorkArea * work_area)
 
 GuiWorkArea * TabWorkArea::addWorkArea(Buffer & buffer, GuiView & view)
 {
+       view.setBusy(true);
        GuiWorkArea * wa = new GuiWorkArea(buffer, view);
        GuiWorkAreaContainer * wac = new GuiWorkAreaContainer(wa);
        wa->setUpdatesEnabled(false);
@@ -1811,6 +1809,8 @@ GuiWorkArea * TabWorkArea::addWorkArea(Buffer & buffer, GuiView & view)
 
        updateTabTexts();
 
+       view.setBusy(false);
+
        return wa;
 }