[LyX features/biginset] Reduce metrics updates from 4 to 1 when loading file

2024-04-05 Thread Jean-Marc Lasgouttes
commit 1d1f95d2ed0bf02e8a9cd9685ed4ba3365b9b493
Author: Jean-Marc Lasgouttes 
Date:   Wed Nov 22 12:07:51 2023 +0100

Reduce metrics updates from 4 to 1 when loading file

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   |  2 +-
 src/BufferView.cpp   | 11 +++
 src/BufferView.h |  2 ++
 src/frontends/qt/GuiWorkArea.cpp |  8 
 4 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index de7f4d217c..bbe4d80589 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -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");
diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index f0e3704064..34be860691 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -532,7 +532,7 @@ void BufferView::processUpdateFlags(Update::flags flags)
   << flagsAsString(flags) << ")  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 ***"));
diff --git a/src/BufferView.h b/src/BufferView.h
index cc92e215fb..327536a916 100644
--- a/src/BufferView.h
+++ b/src/BufferView.h
@@ -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;
///
diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp
index 7999dceda9..de8241c21f 100644
--- a/src/frontends/qt/GuiWorkArea.cpp
+++ b/src/frontends/qt/GuiWorkArea.cpp
@@ -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;
 
@@ 

[LyX features/biginset] Reduce metrics updates from 4 to 1 when loading file

2023-11-24 Thread Jean-Marc Lasgouttes
The branch, biginset, has been updated.

- Log -

commit c81ec3c7e934f1ba30e3933655cd7a53cf9c23c2
Author: Jean-Marc Lasgouttes 
Date:   Wed Nov 22 12:07:51 2023 +0100

Reduce metrics updates from 4 to 1 when loading file

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.

Fixes bug #12976.

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 2693f4e..f582ef9 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -534,7 +534,7 @@ void BufferView::processUpdateFlags(Update::flags flags)
   << flagsAsString(flags) << ")  buffer: " << _);
 
// Case when no explicit update is requested.
-   if (flags == Update::None)
+   if (flags == Update::None || !ready())
return;
PROFILE_THIS_BLOCK(processUpdateFlags);
 
@@ -614,7 +614,7 @@ void BufferView::processUpdateFlags(Update::flags flags)
 
 void BufferView::updateScrollbarParameters()
 {
-   if (height_ == 0 && width_ == 0)
+   if (!ready())
return;
 
// We prefer fixed size line scrolling.
@@ -2628,6 +2628,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;
@@ -3110,7 +3113,7 @@ void BufferView::updateMetrics()
 void BufferView::updateMetrics(bool force)
 {
PROFILE_THIS_BLOCK(updateMetrics);
-   if (height_ == 0 || width_ == 0)
+   if (!ready())
return;
 
Text & buftext = buffer_.text();
@@ -3571,7 +3574,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 ***"));
diff --git a/src/BufferView.h b/src/BufferView.h
index a31b41d..e2a6873 100644
--- a/src/BufferView.h
+++ b/src/BufferView.h
@@ -345,6 +345,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;
///
diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp
index f81e867..879f207 100644
--- a/src/frontends/qt/GuiWorkArea.cpp
+++ b/src/frontends/qt/GuiWorkArea.cpp
@@ -194,9 +194,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);
@@ -338,7 +335,7 @@ void GuiWorkArea::toggleCaret()
 
 void GuiWorkArea::scheduleRedraw(bool update_metrics)
 {
-   if (!isVisible())
+   if (!isVisible() || view().busy())
// No need to redraw in this case.
return;
 
@@ -1726,6 +1723,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);
@@ -1744,6 +1742,8 @@ GuiWorkArea * TabWorkArea::addWorkArea(Buffer & buffer, 
GuiView & view)
 
updateTabTexts();
 
+   view.setBusy(false);
+
return wa;
 }
 

---

Summary of changes:
 src/BufferView.cpp   |   11 +++
 src/BufferView.h |2 ++
 src/frontends/qt/GuiWorkArea.cpp |8 
 3 files changed, 13 insertions(+), 8 deletions(-)


hooks/post-receive
-- 
Repository for new features
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org