[LyX features/biginset] Text::dispatch: ignore single par update when there is a full update

2024-06-08 Thread Jean-Marc Lasgouttes
commit cd3453ec453f811e4204eaad8d4df73fde7fa9c9
Author: Jean-Marc Lasgouttes 
Date:   Fri Jun 7 16:49:25 2024 +0200

Text::dispatch: ignore single par update when there is a full update

Reorder the tests so that, when the flag Update::SinglePar has been
specified, it does not take precedence over Update::Force flag.

This fixes the crash with inset-split.

(cherry picked from commit a1856427468cd4e442c77f394715c825d919f902)
---
 src/Text.cpp | 16 +++-
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/src/Text.cpp b/src/Text.cpp
index 4749f36d2c..642eb284c5 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -6374,27 +6374,17 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
}
}
 
-   // FIXME: The cursor flag is reset two lines below
-   // so we need to check here if some of the LFUN did touch that.
-   // for now only Text::erase() and Text::backspace() do that.
-   // The plan is to verify all the LFUNs and then to remove this
-   // singleParUpdate boolean altogether.
-   if (cur.result().screenUpdate() & Update::Force) {
-   singleParUpdate = false;
-   needsUpdate = true;
-   }
-
// FIXME: the following code should go in favor of fine grained
// update flag treatment.
-   if (singleParUpdate || cur.result().screenUpdate() & Update::SinglePar) 
{
+   if (needsUpdate || cur.result().screenUpdate() & Update::Force)
+   cur.screenUpdateFlags(Update::Force | Update::FitCursor);
+   else if (singleParUpdate || cur.result().screenUpdate() & 
Update::SinglePar) {
// Inserting characters does not change par height in general. 
So, try
// to update _only_ this paragraph. BufferView will detect if a 
full
// metrics update is needed anyway.
cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor);
return;
}
-   if (needsUpdate)
-   cur.screenUpdateFlags(Update::Force | Update::FitCursor);
else {
// oldSelection is a backup of cur.selection() at the beginning 
of the function.
if (!oldSelection && !cur.selection())
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Text::dispatch: ignore single par update when there is a full update

2024-06-07 Thread Jean-Marc Lasgouttes
commit a1856427468cd4e442c77f394715c825d919f902
Author: Jean-Marc Lasgouttes 
Date:   Fri Jun 7 16:49:25 2024 +0200

Text::dispatch: ignore single par update when there is a full update

Reorder the tests so that, when the flag Update::SinglePar has been
specified, it does not take precedence over Update::Force flag.

This fixes the crash with inset-split.
---
 src/Text.cpp | 16 +++-
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/src/Text.cpp b/src/Text.cpp
index c6e2e054fb..f9c1037ad3 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -6378,27 +6378,17 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
}
}
 
-   // FIXME: The cursor flag is reset two lines below
-   // so we need to check here if some of the LFUN did touch that.
-   // for now only Text::erase() and Text::backspace() do that.
-   // The plan is to verify all the LFUNs and then to remove this
-   // singleParUpdate boolean altogether.
-   if (cur.result().screenUpdate() & Update::Force) {
-   singleParUpdate = false;
-   needsUpdate = true;
-   }
-
// FIXME: the following code should go in favor of fine grained
// update flag treatment.
-   if (singleParUpdate || cur.result().screenUpdate() & Update::SinglePar) 
{
+   if (needsUpdate || cur.result().screenUpdate() & Update::Force)
+   cur.screenUpdateFlags(Update::Force | Update::FitCursor);
+   else if (singleParUpdate || cur.result().screenUpdate() & 
Update::SinglePar) {
// Inserting characters does not change par height in general. 
So, try
// to update _only_ this paragraph. BufferView will detect if a 
full
// metrics update is needed anyway.
cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor);
return;
}
-   if (needsUpdate)
-   cur.screenUpdateFlags(Update::Force | Update::FitCursor);
else {
// oldSelection is a backup of cur.selection() at the beginning 
of the function.
if (!oldSelection && !cur.selection())
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.x] Fixup 39c7199a: the code did not do what it was supposed to

2024-06-06 Thread Jean-Marc Lasgouttes
commit 312dacb7f32ce5465e1fe3d5d7ac5e0b9b51e045
Author: Jean-Marc Lasgouttes 
Date:   Wed Jun 5 23:05:22 2024 +0200

Fixup 39c7199a: the code did not do what it was supposed to

(cherry picked from commit 92ef555abde86466b7ca3c3401ab8132258fc497)
---
 src/insets/InsetLayout.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/insets/InsetLayout.h b/src/insets/InsetLayout.h
index 7593d844d5..ffa0380f17 100644
--- a/src/insets/InsetLayout.h
+++ b/src/insets/InsetLayout.h
@@ -200,7 +200,7 @@ public:
///
bool docbookrenderasimage() const { return docbookrenderasimage_; }
///
-   std::set required() const & { return required_; }
+   std::set const & required() const { return required_; }
///
bool isMultiPar() const { return multipar_; }
///
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.x] Do not draw appendix lines below en of document

2024-06-06 Thread Jean-Marc Lasgouttes
commit 13a6be1f9c4668dd661bc197df226b20e420e24b
Author: Jean-Marc Lasgouttes 
Date:   Thu Jun 6 14:32:00 2024 +0200

Do not draw appendix lines below en of document

This bug is pretty old, but it was not visible because the grey area
below the document would overwrite it.

It would be better to close the frame at the end of the document, but
this is for later.

(cherry picked from commit 7acfbe0fccc729dcf5d910a4049b25e9943329fc)
(cherry picked from commit c96d3a03400893f440dca7e68ed87bd70bea0b39)
---
 src/RowPainter.cpp | 4 ++--
 status.24x | 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/RowPainter.cpp b/src/RowPainter.cpp
index 77e0ff67e6..19d83c13a3 100644
--- a/src/RowPainter.cpp
+++ b/src/RowPainter.cpp
@@ -313,8 +313,8 @@ void RowPainter::paintAppendix() const
if (par_.params().startOfAppendix())
y += 2 * defaultRowHeight();
 
-   pi_.pain.line(1, y, 1, yo_ + row_.height(), Color_appendix);
-   pi_.pain.line(tm_.width() - 2, y, tm_.width() - 2, yo_ + row_.height(), 
Color_appendix);
+   pi_.pain.line(1, y, 1, yo_ + row_.descent(), Color_appendix);
+   pi_.pain.line(tm_.width() - 2, y, tm_.width() - 2, yo_ + 
row_.descent(), Color_appendix);
 }
 
 
diff --git a/status.24x b/status.24x
index 154a255304..a62ec4aac1 100644
--- a/status.24x
+++ b/status.24x
@@ -43,6 +43,8 @@ What's new
 
 - fix display of equation numbers in right-to-left context.
 
+- fix overflow of appendix red frame in document-bottom grey area.
+
 * INTERNALS
 
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Fixup 7acfbe0fccc7: forgot to change one location

2024-06-06 Thread Jean-Marc Lasgouttes
commit c96d3a03400893f440dca7e68ed87bd70bea0b39
Author: Jean-Marc Lasgouttes 
Date:   Thu Jun 6 17:27:24 2024 +0200

Fixup 7acfbe0fccc7: forgot to change one location
---
 src/RowPainter.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/RowPainter.cpp b/src/RowPainter.cpp
index b8c0a67b5e..19d83c13a3 100644
--- a/src/RowPainter.cpp
+++ b/src/RowPainter.cpp
@@ -313,7 +313,7 @@ void RowPainter::paintAppendix() const
if (par_.params().startOfAppendix())
y += 2 * defaultRowHeight();
 
-   pi_.pain.line(1, y, 1, yo_ + row_.height(), Color_appendix);
+   pi_.pain.line(1, y, 1, yo_ + row_.descent(), Color_appendix);
pi_.pain.line(tm_.width() - 2, y, tm_.width() - 2, yo_ + 
row_.descent(), Color_appendix);
 }
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Do not draw appendix lines below en of document

2024-06-06 Thread Jean-Marc Lasgouttes
commit 7acfbe0fccc729dcf5d910a4049b25e9943329fc
Author: Jean-Marc Lasgouttes 
Date:   Thu Jun 6 14:32:00 2024 +0200

Do not draw appendix lines below en of document

This bug is pretty old, but it was not visible because the grey area
below the document would overwrite it.

It would be better to close the frame at the end of the document, but
this is for later.
---
 src/RowPainter.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/RowPainter.cpp b/src/RowPainter.cpp
index 77e0ff67e6..b8c0a67b5e 100644
--- a/src/RowPainter.cpp
+++ b/src/RowPainter.cpp
@@ -314,7 +314,7 @@ void RowPainter::paintAppendix() const
y += 2 * defaultRowHeight();
 
pi_.pain.line(1, y, 1, yo_ + row_.height(), Color_appendix);
-   pi_.pain.line(tm_.width() - 2, y, tm_.width() - 2, yo_ + row_.height(), 
Color_appendix);
+   pi_.pain.line(tm_.width() - 2, y, tm_.width() - 2, yo_ + 
row_.descent(), Color_appendix);
 }
 
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Fixup de5f63eeb: the code did not do what it was supposed to

2024-06-06 Thread Jean-Marc Lasgouttes
commit 92ef555abde86466b7ca3c3401ab8132258fc497
Author: Jean-Marc Lasgouttes 
Date:   Wed Jun 5 23:05:22 2024 +0200

Fixup de5f63eeb: the code did not do what it was supposed to
---
 src/insets/InsetLayout.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/insets/InsetLayout.h b/src/insets/InsetLayout.h
index 0848adef45..ce45214e7e 100644
--- a/src/insets/InsetLayout.h
+++ b/src/insets/InsetLayout.h
@@ -200,7 +200,7 @@ public:
///
bool docbookrenderasimage() const { return docbookrenderasimage_; }
///
-   std::set required() const & { return required_; }
+   std::set const & required() const { return required_; }
///
bool isMultiPar() const { return multipar_; }
///
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.1-devel] Fix display of math hull inset in RTL context

2024-06-02 Thread Jean-Marc Lasgouttes
commit 342a0f543812e21dade99b7fa46ea674075b8199
Author: Jean-Marc Lasgouttes 
Date:   Thu May 16 14:56:28 2024 +0200

Fix display of math hull inset in RTL context

The inversion of margin was done in the wrong way for RTL support.

(cherry picked from commit b469c142ad579d3338fc81ab3e1c6ee7b4e270ec)
---
 src/TextMetrics.cpp | 13 -
 status.24x  |  1 +
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 6968279c23..a694c997ea 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -2001,8 +2001,14 @@ void TextMetrics::drawParagraph(PainterInfo & pi, 
pit_type const pit, int const
return;
size_t const nrows = pm.rows().size();
// Remember left and right margin for drawing math numbers
-   Changer changeleft = changeVar(pi.leftx, x + leftMargin(pit));
-   Changer changeright = changeVar(pi.rightx, x + width() - 
rightMargin(pit));
+   Changer changeleft, changeright;
+   if (text_->isRTL(pit)) {
+   changeleft = changeVar(pi.leftx, x + rightMargin(pit));
+   changeright = changeVar(pi.rightx, x + width() - 
leftMargin(pit));
+   } else {
+   changeleft = changeVar(pi.leftx, x + leftMargin(pit));
+   changeright = changeVar(pi.rightx, x + width() - 
rightMargin(pit));
+   }
 
// Use fast lane in nodraw stage.
if (pi.pain.isNull()) {
@@ -2049,9 +2055,6 @@ void TextMetrics::drawParagraph(PainterInfo & pi, 
pit_type const pit, int const
}
}
 
-   if (text_->isRTL(pit))
-   swap(pi.leftx, pi.rightx);
-
BookmarksSection::BookmarkPosList bpl =

theSession().bookmarks().bookmarksInPar(bv_->buffer().fileName(), pm.id());
 
diff --git a/status.24x b/status.24x
index f3e8f6b07c..154a255304 100644
--- a/status.24x
+++ b/status.24x
@@ -41,6 +41,7 @@ What's new
 
 * USER INTERFACE
 
+- fix display of equation numbers in right-to-left context.
 
 * INTERNALS
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.1-devel] small changes backported from master

2024-06-02 Thread Jean-Marc Lasgouttes
commit 3941c487e85a5c2a2b7897c9a6da3ac2d00b1da2
Author: Jean-Marc Lasgouttes 
Date:   Fri Apr 19 17:16:00 2024 +0200

small changes backported from master
---
 INSTALL | 6 +++---
 README  | 8 
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/INSTALL b/INSTALL
index 5c9c4d7489..ec959ff6a8 100644
--- a/INSTALL
+++ b/INSTALL
@@ -55,9 +55,9 @@ Requirements
 First of all, you will need a C++11 standard conforming compiler, like g++ (at
 least 4.9, to have proper srd::regex) or clang++.
 
-LyX makes great use of the C++ Standard Template Library (STL).
-This means that gcc users will have to install the relevant libstdc++
-library to be able to compile this version of LyX.
+LyX makes great use of the C++ Standard Library. This means that gcc
+users will have to install the relevant libstdc++ library to be able
+to compile this version of LyX.
 
 For full LyX usability we suggest to use Qt 5.6 and higher, or at the
 very least Qt 5.4. It is also possible to compile against Qt 6. The
diff --git a/README b/README
index b6b7a2ffb3..3d8da5aeea 100644
--- a/README
+++ b/README
@@ -27,8 +27,8 @@ What do I need to run LyX?
 
 Either:
 * a Unix-like system (including Windows with Cygwin)
-* Windows Vista or newer
-* Mac OS 10.4 or newer
+* Windows 7 or newer
+* Mac OS 10.13 or newer
 
 A decent LaTeX2e installation (e.g. TeX Live for Linux, MikTeX for
 Windows).
@@ -42,7 +42,7 @@ How does the LyX version scheme work?
 number "2.x.y" indicates a stable release '2.x', maintenance
 release 'y'.  In other words, LyX 2.3.0 was the first stable
 release in the 2.3-series of LyX. At the time of writing, the
-latest maintenance release in the 2.3-series is LyX 2.3.4.
+latest maintenance release in the 2.3-series is LyX 2.3.7.
 
 Please note that maintenance releases are designed primarily to
 fix bugs, and that the file format will _never_ change due to a
@@ -101,7 +101,7 @@ Okay, I've installed LyX. What now?
 the "Introduction" item under the Help menu.  You should follow
 the instructions there, which tell you to read (or at least skim)
 the Tutorial. After that, you should also read "Help>LaTeX
-configuration" which provides info on your LaTeX configuration
+Configuration" which provides info on your LaTeX configuration
 as LyX sees it.  You might be missing a package or two that you'd
 like to have.
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.1-devel] Fix compilation with msvc 2019

2024-06-02 Thread Jean-Marc Lasgouttes
commit 25f11742036f762aa1a83d377bc416a519bca6ef
Author: Jean-Marc Lasgouttes 
Date:   Sun Apr 7 20:41:13 2024 +0200

Fix compilation with msvc 2019

'uint' is not defined, 'unsigned int' is better.

(cherry picked from commit c7f53afd319fc9028be74f8949cec00063972462)
---
 src/Text.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Text.cpp b/src/Text.cpp
index d5a1069fa1..778c41820e 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -5958,7 +5958,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
// Argument?
if (!arg.empty()) {
if (isStrUnsignedInt(arg)) {
-   num = convert(arg);
+   num = convert(arg);
if (num >= freeFonts.size()) {
cur.message(_("Invalid argument (number 
exceeds stack size)!"));
break;
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.1-devel] Do not include in InsetInfo.h

2024-06-02 Thread Jean-Marc Lasgouttes
commit 89afdb050f2b59aeed09bb199cb698d904e2144d
Author: Jean-Marc Lasgouttes 
Date:   Thu Apr 4 17:35:54 2024 +0200

Do not include  in InsetInfo.h

This is used by getDate/getTime, which actually should not be
InsetInfoParams methods, but functions in anonymous namespace.

(cherry picked from commit 51562ff37732f4949441bd8c2b55692b0719093a)
---
 src/frontends/qt/GuiInfo.cpp |  1 +
 src/insets/InsetInfo.cpp | 42 +-
 src/insets/InsetInfo.h   |  5 -
 3 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/src/frontends/qt/GuiInfo.cpp b/src/frontends/qt/GuiInfo.cpp
index 5ba0b19b46..232697fa5c 100644
--- a/src/frontends/qt/GuiInfo.cpp
+++ b/src/frontends/qt/GuiInfo.cpp
@@ -31,6 +31,7 @@
 #include "support/gettext.h"
 #include "support/lstrings.h"
 
+#include 
 
 using namespace std;
 using namespace lyx::support;
diff --git a/src/insets/InsetInfo.cpp b/src/insets/InsetInfo.cpp
index 3048456e84..df83f96b98 100644
--- a/src/insets/InsetInfo.cpp
+++ b/src/insets/InsetInfo.cpp
@@ -180,10 +180,9 @@ bool translateString(docstring const & in, docstring & 
out, string const & lcode
out = translateIfPossible(in, lcode);
return in != out;
 }
-} // namespace anon
 
 
-docstring InsetInfoParams::getDate(string const & iname, QDate const date) 
const
+docstring getDate(string const & iname, QDate const date, Language const * 
lang)
 {
QLocale loc;
if (lang)
@@ -208,7 +207,7 @@ docstring InsetInfoParams::getDate(string const & iname, 
QDate const date) const
 }
 
 
-docstring InsetInfoParams::getTime(string const & iname, QTime const time) 
const
+docstring getTime(string const & iname, QTime const time, Language const * 
lang)
 {
QLocale loc;
if (lang)
@@ -222,6 +221,7 @@ docstring InsetInfoParams::getTime(string const & iname, 
QTime const time) const
else
return qstring_to_ucs4(loc.toString(time, toqstr(iname)));
 }
+} // namespace anon
 
 
 vector> InsetInfoParams::getArguments(Buffer const * 
buf,
@@ -313,17 +313,17 @@ vector> 
InsetInfoParams::getArguments(Buffer const * buf,
date = (gdate.isValid()) ? gdate : QDate::currentDate();
} else
date = QDate::currentDate();
-   result.push_back(make_pair("long",getDate("long", date)));
-   result.push_back(make_pair("short", getDate("short", date)));
-   result.push_back(make_pair("loclong", getDate("loclong", 
date)));
-   result.push_back(make_pair("locmedium", getDate("locmedium", 
date)));
-   result.push_back(make_pair("locshort", getDate("locshort", 
date)));
-   result.push_back(make_pair("ISO", getDate("ISO", date)));
-   result.push_back(make_pair("", getDate("", date)));
-   result.push_back(make_pair("", getDate("", date)));
-   result.push_back(make_pair("MMM", getDate("MMM", date)));
-   result.push_back(make_pair("", getDate("", date)));
-   result.push_back(make_pair("ddd", getDate("ddd", date)));
+   result.push_back(make_pair("long",getDate("long", date, lang)));
+   result.push_back(make_pair("short", getDate("short", date, 
lang)));
+   result.push_back(make_pair("loclong", getDate("loclong", date, 
lang)));
+   result.push_back(make_pair("locmedium", getDate("locmedium", 
date, lang)));
+   result.push_back(make_pair("locshort", getDate("locshort", 
date, lang)));
+   result.push_back(make_pair("ISO", getDate("ISO", date, lang)));
+   result.push_back(make_pair("", getDate("", date, 
lang)));
+   result.push_back(make_pair("", getDate("", date, 
lang)));
+   result.push_back(make_pair("MMM", getDate("MMM", date, lang)));
+   result.push_back(make_pair("", getDate("", date, 
lang)));
+   result.push_back(make_pair("ddd", getDate("ddd", date, lang)));
result.push_back(make_pair("custom", _("Custom")));
break;
}
@@ -344,9 +344,9 @@ vector> 
InsetInfoParams::getArguments(Buffer const * buf,
time = (gtime.isValid()) ? gtime : QTime::currentTime();
} else
time = QTime::currentTime();
- 

[LyX/2.4.1-devel] Compilation fix with Qt < 5.7

2024-06-02 Thread Jean-Marc Lasgouttes
commit 0cd169d6baecb4e6854c408a7452a843e57070e6
Author: Jean-Marc Lasgouttes 
Date:   Wed Apr 3 12:39:09 2024 +0200

Compilation fix with Qt < 5.7

Qt::ImAnchorRectangle has only been introduced in Qt 5.7. Since it is
used to answer a query from the IM machinery, there is no need for
it with older Qt versions.

(cherry picked from commit 6260689fd552a5e83d2970dcfd4d5ba7e09443e7)
---
 src/frontends/qt/GuiWorkArea.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp
index a4b874097c..341fddc3b8 100644
--- a/src/frontends/qt/GuiWorkArea.cpp
+++ b/src/frontends/qt/GuiWorkArea.cpp
@@ -1422,10 +1422,12 @@ QVariant 
GuiWorkArea::inputMethodQuery(Qt::InputMethodQuery query) const
return QVariant(d->im_cursor_rect_);
break;
}
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
case Qt::ImAnchorRectangle: {
return QVariant(d->im_anchor_rect_);
break;
}
+#endif
default:
return QWidget::inputMethodQuery(query);
}
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.x] Fix display of math hull inset in RTL context

2024-06-01 Thread Jean-Marc Lasgouttes
commit 342a0f543812e21dade99b7fa46ea674075b8199
Author: Jean-Marc Lasgouttes 
Date:   Thu May 16 14:56:28 2024 +0200

Fix display of math hull inset in RTL context

The inversion of margin was done in the wrong way for RTL support.

(cherry picked from commit b469c142ad579d3338fc81ab3e1c6ee7b4e270ec)
---
 src/TextMetrics.cpp | 13 -
 status.24x  |  1 +
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 6968279c23..a694c997ea 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -2001,8 +2001,14 @@ void TextMetrics::drawParagraph(PainterInfo & pi, 
pit_type const pit, int const
return;
size_t const nrows = pm.rows().size();
// Remember left and right margin for drawing math numbers
-   Changer changeleft = changeVar(pi.leftx, x + leftMargin(pit));
-   Changer changeright = changeVar(pi.rightx, x + width() - 
rightMargin(pit));
+   Changer changeleft, changeright;
+   if (text_->isRTL(pit)) {
+   changeleft = changeVar(pi.leftx, x + rightMargin(pit));
+   changeright = changeVar(pi.rightx, x + width() - 
leftMargin(pit));
+   } else {
+   changeleft = changeVar(pi.leftx, x + leftMargin(pit));
+   changeright = changeVar(pi.rightx, x + width() - 
rightMargin(pit));
+   }
 
// Use fast lane in nodraw stage.
if (pi.pain.isNull()) {
@@ -2049,9 +2055,6 @@ void TextMetrics::drawParagraph(PainterInfo & pi, 
pit_type const pit, int const
}
}
 
-   if (text_->isRTL(pit))
-   swap(pi.leftx, pi.rightx);
-
BookmarksSection::BookmarkPosList bpl =

theSession().bookmarks().bookmarksInPar(bv_->buffer().fileName(), pm.id());
 
diff --git a/status.24x b/status.24x
index f3e8f6b07c..154a255304 100644
--- a/status.24x
+++ b/status.24x
@@ -41,6 +41,7 @@ What's new
 
 * USER INTERFACE
 
+- fix display of equation numbers in right-to-left context.
 
 * INTERNALS
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Extend tab context menu features

2024-06-01 Thread Jean-Marc Lasgouttes
commit a114f12868f8b48b9507aa22bf4156af0062ac97
Author: Daniel Ramoeller 
Date:   Sat Feb 27 07:05:54 2021 +0100

Extend tab context menu features

Add

- Close Other Tabs
- Close Tabs to Left/Right
- Move Tab to Start/End
- Show Enclosing Folder

to the tabs context menus.

Fix for bug #11963
---
 src/frontends/qt/GuiWorkArea.cpp | 116 +--
 src/frontends/qt/GuiWorkArea.h   |  15 +
 2 files changed, 127 insertions(+), 4 deletions(-)

diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp
index ec9bedee5f..8b86615b4e 100644
--- a/src/frontends/qt/GuiWorkArea.cpp
+++ b/src/frontends/qt/GuiWorkArea.cpp
@@ -1958,6 +1958,75 @@ void TabWorkArea::closeCurrentBuffer()
 }
 
 
+bool TabWorkArea::closeTabsToRight()
+{
+   if (clicked_tab_ == -1)
+   return false;
+
+   int const initialCurrentIndex = currentIndex();
+
+   while (count() - 1 > clicked_tab_) {
+   GuiWorkArea * wa = workArea(count() - 1);
+   LASSERT(wa, return false);
+   if (!wa->view().closeWorkArea(wa)) {
+   // closing cancelled, if possible, reset initial 
current tab index
+   if (initialCurrentIndex < count())
+   setCurrentIndex(initialCurrentIndex);
+   else
+   setCurrentIndex(clicked_tab_);
+   return false;
+   }
+   }
+   return true;
+}
+
+
+bool TabWorkArea::openEnclosingFolder()
+{
+
+   if (clicked_tab_ == -1)
+   return false;
+
+   Buffer const & buf = workArea(clicked_tab_)->bufferView().buffer();
+   showDirectory(buf.fileName().onlyPath());
+   return true;
+}
+
+
+bool TabWorkArea::closeTabsToLeft()
+{
+   if (clicked_tab_ == -1)
+   return false;
+
+   int const initialCurrentIndex = currentIndex();
+
+   int n = clicked_tab_;
+
+   for (int i = 0; i < n; ++i) {
+   GuiWorkArea * wa = workArea(0);
+   LASSERT(wa, return false);
+   if (!wa->view().closeWorkArea(wa)) {
+   // closing cancelled, if possible, reset initial 
current tab index
+   if (initialCurrentIndex - i >= 0)
+   setCurrentIndex(initialCurrentIndex - i);
+   else
+   setCurrentIndex(clicked_tab_ - i);
+   return false;
+   }
+   }
+   return true;
+}
+
+
+void TabWorkArea::closeOtherTabs()
+{
+   if (clicked_tab_ == -1)
+   return;
+
+   closeTabsToRight() && closeTabsToLeft();
+}
+
+
 void TabWorkArea::hideCurrentTab()
 {
GuiWorkArea * wa;
@@ -1985,6 +2054,22 @@ void TabWorkArea::closeTab(int index)
 }
 
 
+void TabWorkArea::moveToStartCurrentTab()
+{
+   if (clicked_tab_ == -1)
+   return;
+   tabBar()->moveTab(clicked_tab_, 0);
+}
+
+
+void TabWorkArea::moveToEndCurrentTab()
+{
+   if (clicked_tab_ == -1)
+   return;
+   tabBar()->moveTab(clicked_tab_, count() - 1);
+}
+
+
 ///
 class DisplayPath {
 public:
@@ -2232,19 +2317,42 @@ void TabWorkArea::showContextMenu(const QPoint & pos)
 
// show tab popup
QMenu popup;
-   popup.addAction(QIcon(getPixmap("images/", "hidetab", "svgz,png")),
-   qt_(" Tab"), this, SLOT(hideCurrentTab()));
+   popup.addAction(qt_(" Tab"), this, SLOT(hideCurrentTab()));
 
// we want to show the 'close' option only if this is not a child 
buffer.
Buffer const & buf = wa->bufferView().buffer();
if (!buf.parent())
-   popup.addAction(QIcon(getPixmap("images/", "closetab", 
"svgz,png")),
-   qt_(" Tab"), this, SLOT(closeCurrentBuffer()));
+   popup.addAction(qt_(" Tab"), this, 
SLOT(closeCurrentBuffer()));
+
+   popup.addSeparator();
+
+   QAction * closeOther = popup.addAction(qt_("Close  Tabs"), this, 
SLOT(closeOtherTabs()));
+   closeOther->setEnabled(clicked_tab_ != 0 || 
hasTabsToRight(clicked_tab_));
+   QAction * closeRight = popup.addAction(qt_("Close Tabs to the "), 
this, SLOT(closeTabsToRight()));
+   closeRight->setEnabled(hasTabsToRight(clicked_tab_));
+   QAction * closeLeft = popup.addAction(qt_("Close Tabs to the "), 
this, SLOT(closeTabsToLeft()));
+   closeLeft->setEnabled(clicked_tab_ != 0);
+
+   popup.addSeparator();
+
+   QAction * moveStart = popup.addAction(qt_("Move Tab to "), this, 
SLOT(moveToStartCurrentTab()));
+   moveStart->setEnabled(closeLeft->isEnabled());
+   QAction * moveEnd = popup.addAction(qt_("Move Tab to "), this, 
SLOT(moveToEndCurrentTab()));
+   moveEnd->setEnabled(closeRight->isEnabled());
+
+   popup.addSeparator();
+
+   popup.addAction(qt_("Open Enclosing "), this, 
SLOT(openEnclosingFolder()));

[LyX/2.4.1-devel] Set buffer when creating a MathData from parts of another one

2024-06-01 Thread Jean-Marc Lasgouttes
commit 2699a58cd7c98e54cb5cfbaf3f6cdf2621651a64
Author: Jean-Marc Lasgouttes 
Date:   Thu Apr 25 17:13:15 2024 +0200

Set buffer when creating a MathData from parts of another one

This is triggered by selecting part of an equation under Xcb platform
(x11). Indeed, the current selection has to be sent to the X11 server
and BufferView::requestSelection() is called. Eventually
cap::grabSelection() is the function that creates this partial
MathData object.

Fixes ticket #12947.

(cherry picked from commit ed2f3cb9cfa1e871d48a92d41791a77bd218ab67)
---
 src/mathed/MathData.cpp | 4 +++-
 status.24x  | 2 ++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/mathed/MathData.cpp b/src/mathed/MathData.cpp
index 4c33934828..38f44a696e 100644
--- a/src/mathed/MathData.cpp
+++ b/src/mathed/MathData.cpp
@@ -49,7 +49,9 @@ namespace lyx {
 
 MathData::MathData(Buffer * buf, const_iterator from, const_iterator to)
: base_type(from, to), buffer_(buf)
-{}
+{
+   setContentsBuffer();
+}
 
 
 void MathData::setContentsBuffer()
diff --git a/status.24x b/status.24x
index 0328af480b..e7f677295e 100644
--- a/status.24x
+++ b/status.24x
@@ -90,6 +90,8 @@ What's new
 
 - Fix initialization of an internal value.
 
+- Fix "Unassigned buffer_" error with math references (bug 12947).
+
 
 * DOCUMENTATION AND LOCALIZATION
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.1-devel] Try to make sure that math insets have a properly set buffer_ member

2024-06-01 Thread Jean-Marc Lasgouttes
commit 76188dcdf11e06e8772e900de04ccbfb079bafac
Author: Jean-Marc Lasgouttes 
Date:   Fri Oct 14 22:42:21 2022 +0200

Try to make sure that math insets have a properly set buffer_ member

Set the buffer of contents that is added to a MathData object through
MathData::insert() (both versions)
MathData::push_back()
asArray()

Also in math macros, initialize look_ with the relevant buffer.

This reduces the number of insets hat do not have a proper buffer.

See #13050 for discussion of this issue.

(cherry picked from commit f3c5ff9cb72c5231f1e1e81452e67d6f12dadecb)
---
 src/mathed/InsetMathMacroTemplate.cpp |  8 +---
 src/mathed/MathData.cpp   | 24 ++--
 src/mathed/MathData.h |  7 +--
 src/mathed/MathSupport.cpp|  3 +++
 4 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/src/mathed/InsetMathMacroTemplate.cpp 
b/src/mathed/InsetMathMacroTemplate.cpp
index 2a721833b0..cf830fbf3b 100644
--- a/src/mathed/InsetMathMacroTemplate.cpp
+++ b/src/mathed/InsetMathMacroTemplate.cpp
@@ -394,7 +394,7 @@ void InsetNameWrapper::draw(PainterInfo & pi, int x, int y) 
const
 
 
 InsetMathMacroTemplate::InsetMathMacroTemplate(Buffer * buf)
-   : InsetMathNest(buf, 3), numargs_(0), argsInLook_(0), optionals_(0),
+   : InsetMathNest(buf, 3), look_(buf), numargs_(0), argsInLook_(0), 
optionals_(0),
  type_(MacroTypeNewcommand), redefinition_(false), lookOutdated_(true),
  premetrics_(false), labelBoxAscent_(0), labelBoxDescent_(0)
 {
@@ -405,8 +405,8 @@ InsetMathMacroTemplate::InsetMathMacroTemplate(Buffer * buf)
 InsetMathMacroTemplate::InsetMathMacroTemplate(Buffer * buf, docstring const & 
name, int numargs,
int optionals, MacroType type, vector const & optionalValues,
MathData const & def, MathData const & display)
-   : InsetMathNest(buf, optionals + 3), numargs_(numargs), 
argsInLook_(numargs),
- optionals_(optionals), optionalValues_(optionalValues),
+   : InsetMathNest(buf, optionals + 3), look_(buf), numargs_(numargs),
+ argsInLook_(numargs), optionals_(optionals), 
optionalValues_(optionalValues),
  type_(type), redefinition_(false), lookOutdated_(true),
  premetrics_(false), labelBoxAscent_(0), labelBoxDescent_(0)
 {
@@ -536,6 +536,8 @@ void InsetMathMacroTemplate::createLook(int args) const
look_.push_back(MathAtom(
new InsetDisplayLabelBox(buffer_, MathAtom(
new InsetMathWrapper((displayIdx(, _("LyX"), 
*this)));
+
+   look_.setContentsBuffer();
 }
 
 
diff --git a/src/mathed/MathData.cpp b/src/mathed/MathData.cpp
index 24b4d86fb9..4c33934828 100644
--- a/src/mathed/MathData.cpp
+++ b/src/mathed/MathData.cpp
@@ -52,11 +52,18 @@ MathData::MathData(Buffer * buf, const_iterator from, 
const_iterator to)
 {}
 
 
+void MathData::setContentsBuffer()
+{
+   if (buffer_)
+   for (MathAtom & at : *this)
+   at.nucleus()->setBuffer(*buffer_);
+}
+
+
 void MathData::setBuffer(Buffer & b)
 {
buffer_ = 
-   for (MathAtom & at : *this)
-   at.nucleus()->setBuffer(b);
+   setContentsBuffer();
 }
 
 
@@ -78,6 +85,8 @@ void MathData::insert(size_type pos, MathAtom const & t)
 {
LBUFERR(pos <= size());
base_type::insert(begin() + pos, t);
+   if (buffer_)
+   operator[](pos)->setBuffer(*buffer_);
 }
 
 
@@ -85,6 +94,17 @@ void MathData::insert(size_type pos, MathData const & ar)
 {
LBUFERR(pos <= size());
base_type::insert(begin() + pos, ar.begin(), ar.end());
+   if (buffer_)
+   for (size_type i = 0 ; i < ar.size() ; ++i)
+   operator[](pos + i)->setBuffer(*buffer_);
+}
+
+
+void MathData::push_back(MathAtom const & t)
+{
+   base_type::push_back(t);
+   if (buffer_)
+   back()->setBuffer(*buffer_);
 }
 
 
diff --git a/src/mathed/MathData.h b/src/mathed/MathData.h
index 865742df4c..c2d731efcb 100644
--- a/src/mathed/MathData.h
+++ b/src/mathed/MathData.h
@@ -59,7 +59,6 @@ public:
using base_type::clear;
using base_type::begin;
using base_type::end;
-   using base_type::push_back;
using base_type::pop_back;
using base_type::back;
using base_type::front;
@@ -85,6 +84,8 @@ public:
void insert(size_type pos, MathAtom const & at);
/// inserts multiple atoms at position pos
void insert(size_type pos, MathData const & ar);
+   /// inserts single atom at end
+   void push_back(MathAtom const & at);
 
/// erase range from pos1 to pos2
void erase(iterator pos1, iterator pos2);
@@ -187,8 +188,10 @@ public:
void updateMacros(Cursor * cur, MacroContext const & mc, UpdateType, 
int nesting);

[LyX features/biginset] Fix up a4d9315b: handle metrics of not visible paragraphs

2024-05-17 Thread Jean-Marc Lasgouttes
commit 5c5410c39cd7f3dfe4e187eedb7a4222e07c4b83
Author: Jean-Marc Lasgouttes 
Date:   Fri May 17 15:42:08 2024 +0200

Fix up a4d9315b: handle metrics of not visible paragraphs

The code is not ready for situations where some paragraphs that are
not visible have metrics available. This has been made visible by
a4d9315b, which removes a couple of full metrics updates: the screen
was not correctly scrolled after a scrollToCursor() call.

In PararagraphMetrics, some methods are added to be able to handle the
fact that paragraphs have or do not have a position.

In TextMetrics, a new method returns the first visible paragraph.

Finally, in BufferView::updateMetrics, the paragraphs' positions are
reset (in the case where everything is not cleared) and some care is
taken to skip the ones that are not relevant.

The assumption outside of this method is that all the paragraphs that
are in the TextMetrics are visible (we are talking about top-level
TextMetrics here). This could be changed (in order to avoid
recomputing paragraph metrics), but the cost is high in terms of
complexity and it is not clear that the gain in terms of performance
would be important.

(cherry picked from commit 145af7c2ac1eb2c5ec5102a7a11cb740be7b3c43)
---
 src/BufferView.cpp   | 11 +++
 src/ParagraphMetrics.cpp | 24 ++--
 src/ParagraphMetrics.h   |  6 +-
 src/TextMetrics.cpp  | 17 -
 src/TextMetrics.h|  2 ++
 5 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index de82559485..2193d29e4e 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3156,6 +3156,7 @@ void BufferView::updateMetrics(bool force)
d->text_metrics_.clear();
}
 
+   // This should not be moved earlier
TextMetrics & tm = textMetrics();
 
// make sure inline completion pointer is ok
@@ -3171,14 +3172,16 @@ void BufferView::updateMetrics(bool force)
 
// Check that the end of the document is not too high
int const min_visible = lyxrc.scroll_below_document ? minVisiblePart() 
: height_;
-   if (tm.last().first == lastpit && tm.last().second->bottom() < 
min_visible) {
+   if (tm.last().first == lastpit && tm.last().second->hasPosition()
+&& tm.last().second->bottom() < min_visible) {
d->anchor_ypos_ += min_visible - tm.last().second->bottom();
LYXERR(Debug::SCROLLING, "Too high, adjusting anchor ypos to " 
<< d->anchor_ypos_);
tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
}
 
// Check that the start of the document is not too low
-   if (tm.first().first == 0 && tm.first().second->top() > 0) {
+   if (tm.first().first == 0 && tm.first().second->hasPosition()
+&& tm.first().second->top() > 0) {
d->anchor_ypos_ -= tm.first().second->top();
LYXERR(Debug::SCROLLING, "Too low, adjusting anchor ypos to " 
<< d->anchor_ypos_);
tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
@@ -3191,11 +3194,11 @@ void BufferView::updateMetrics(bool force)
 * extra paragraphs are removed
 */
// Remove paragraphs that are outside of screen
-   while(tm.first().second->bottom() <= 0) {
+   while(!tm.first().second->hasPosition() || tm.first().second->bottom() 
<= 0) {
//LYXERR0("Forget pit: " << tm.first().first);
tm.forget(tm.first().first);
}
-   while(tm.last().second->top() > height_) {
+   while(!tm.last().second->hasPosition() || tm.last().second->top() > 
height_) {
//LYXERR0("Forget pit: " << tm.first().first);
tm.forget(tm.last().first);
}
diff --git a/src/ParagraphMetrics.cpp b/src/ParagraphMetrics.cpp
index 31b31a2d01..e1284b0e80 100644
--- a/src/ParagraphMetrics.cpp
+++ b/src/ParagraphMetrics.cpp
@@ -40,9 +40,10 @@ using namespace lyx::support;
 
 namespace lyx {
 
+const int pm_npos = -1;
 
 ParagraphMetrics::ParagraphMetrics(Paragraph const & par) :
-   position_(-1), id_(par.id()), par_()
+   position_(pm_npos), id_(par.id()), par_()
 {}
 
 
@@ -61,7 +62,14 @@ void ParagraphMetrics::reset(Paragraph const & par)
 {
par_ = 
dim_ = Dimension();
-   //position_ = -1;
+   //position_ = pm_npos;
+}
+
+
+int ParagraphMetrics::position() const
+{
+   LASSERT(hasPosition(), return pm_npos);
+   return position_;
 }
 
 
@@ -71,6 +79,18 @@ void ParagraphMetrics::setPosition(int position)
 }
 
 
+void ParagraphMetrics::resetPosition()
+{
+   position_ = pm_npos;
+}
+
+

[LyX/master] Fix up a4d9315b: handle metrics of not visible paragraphs

2024-05-17 Thread Jean-Marc Lasgouttes
commit 145af7c2ac1eb2c5ec5102a7a11cb740be7b3c43
Author: Jean-Marc Lasgouttes 
Date:   Fri May 17 15:42:08 2024 +0200

Fix up a4d9315b: handle metrics of not visible paragraphs

The code is not ready for situations where some paragraphs that are
not visible have metrics available. This has been made visible by
a4d9315b, which removes a couple of full metrics updates: the screen
was not correctly scrolled after a scrollToCursor() call.

In PararagraphMetrics, some methods are added to be able to handle the
fact that paragraphs have or do not have a position.

In TextMetrics, a new method returns the first visible paragraph.

Finally, in BufferView::updateMetrics, the paragraphs' positions are
reset (in the case where everything is not cleared) and some care is
taken to skip the ones that are not relevant.

The assumption outside of this method is that all the paragraphs that
are in the TextMetrics are visible (we are talking about top-level
TextMetrics here). This could be changed (in order to avoid
recomputing paragraph metrics), but the cost is high in terms of
complexity and it is not clear that the gain in terms of performance
would be important.
---
 src/BufferView.cpp   | 11 +++
 src/ParagraphMetrics.cpp | 24 ++--
 src/ParagraphMetrics.h   |  6 +-
 src/TextMetrics.cpp  | 17 -
 src/TextMetrics.h|  2 ++
 5 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 800801c264..755e2f7b4e 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3211,6 +3211,7 @@ void BufferView::updateMetrics(bool force)
d->text_metrics_.clear();
}
 
+   // This should not be moved earlier
TextMetrics & tm = textMetrics();
 
// make sure inline completion pointer is ok
@@ -3226,14 +3227,16 @@ void BufferView::updateMetrics(bool force)
 
// Check that the end of the document is not too high
int const min_visible = lyxrc.scroll_below_document ? minVisiblePart() 
: height_;
-   if (tm.last().first == lastpit && tm.last().second->bottom() < 
min_visible) {
+   if (tm.last().first == lastpit && tm.last().second->hasPosition()
+&& tm.last().second->bottom() < min_visible) {
d->anchor_ypos_ += min_visible - tm.last().second->bottom();
LYXERR(Debug::SCROLLING, "Too high, adjusting anchor ypos to " 
<< d->anchor_ypos_);
tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
}
 
// Check that the start of the document is not too low
-   if (tm.first().first == 0 && tm.first().second->top() > 0) {
+   if (tm.first().first == 0 && tm.first().second->hasPosition()
+&& tm.first().second->top() > 0) {
d->anchor_ypos_ -= tm.first().second->top();
LYXERR(Debug::SCROLLING, "Too low, adjusting anchor ypos to " 
<< d->anchor_ypos_);
tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
@@ -3246,11 +3249,11 @@ void BufferView::updateMetrics(bool force)
 * extra paragraphs are removed
 */
// Remove paragraphs that are outside of screen
-   while(tm.first().second->bottom() <= 0) {
+   while(!tm.first().second->hasPosition() || tm.first().second->bottom() 
<= 0) {
//LYXERR0("Forget pit: " << tm.first().first);
tm.forget(tm.first().first);
}
-   while(tm.last().second->top() > height_) {
+   while(!tm.last().second->hasPosition() || tm.last().second->top() > 
height_) {
//LYXERR0("Forget pit: " << tm.first().first);
tm.forget(tm.last().first);
}
diff --git a/src/ParagraphMetrics.cpp b/src/ParagraphMetrics.cpp
index 31b31a2d01..e1284b0e80 100644
--- a/src/ParagraphMetrics.cpp
+++ b/src/ParagraphMetrics.cpp
@@ -40,9 +40,10 @@ using namespace lyx::support;
 
 namespace lyx {
 
+const int pm_npos = -1;
 
 ParagraphMetrics::ParagraphMetrics(Paragraph const & par) :
-   position_(-1), id_(par.id()), par_()
+   position_(pm_npos), id_(par.id()), par_()
 {}
 
 
@@ -61,7 +62,14 @@ void ParagraphMetrics::reset(Paragraph const & par)
 {
par_ = 
dim_ = Dimension();
-   //position_ = -1;
+   //position_ = pm_npos;
+}
+
+
+int ParagraphMetrics::position() const
+{
+   LASSERT(hasPosition(), return pm_npos);
+   return position_;
 }
 
 
@@ -71,6 +79,18 @@ void ParagraphMetrics::setPosition(int position)
 }
 
 
+void ParagraphMetrics::resetPosition()
+{
+   position_ = pm_npos;
+}
+
+
+bool ParagraphMetrics::hasPosition() const
+{
+   return position_ != pm_np

[LyX/master] Fix display of math hull inset in RTL context

2024-05-16 Thread Jean-Marc Lasgouttes
commit b469c142ad579d3338fc81ab3e1c6ee7b4e270ec
Author: Jean-Marc Lasgouttes 
Date:   Thu May 16 14:56:28 2024 +0200

Fix display of math hull inset in RTL context

The inversion of margin was done in the wrong way for RTL support.
---
 src/TextMetrics.cpp | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index ce8cfe552d..fe8aa4d73a 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -2050,8 +2050,14 @@ void TextMetrics::drawParagraph(PainterInfo & pi, 
pit_type const pit, int const
size_t const nrows = pm.rows().size();
int const wh = bv_->workHeight();
// Remember left and right margin for drawing math numbers
-   Changer changeleft = changeVar(pi.leftx, x + leftMargin(pit));
-   Changer changeright = changeVar(pi.rightx, x + width() - 
rightMargin(pit));
+   Changer changeleft, changeright;
+   if (text_->isRTL(pit)) {
+   changeleft = changeVar(pi.leftx, x + rightMargin(pit));
+   changeright = changeVar(pi.rightx, x + width() - 
leftMargin(pit));
+   } else {
+   changeleft = changeVar(pi.leftx, x + leftMargin(pit));
+   changeright = changeVar(pi.rightx, x + width() - 
rightMargin(pit));
+   }
 
// Use fast lane in nodraw stage.
if (pi.pain.isNull()) {
@@ -2100,9 +2106,6 @@ void TextMetrics::drawParagraph(PainterInfo & pi, 
pit_type const pit, int const
}
}
 
-   if (text_->isRTL(pit))
-   swap(pi.leftx, pi.rightx);
-
BookmarksSection::BookmarkPosList bpl =

theSession().bookmarks().bookmarksInPar(bv_->buffer().fileName(), pm.id());
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] one less place where metrics have to be recomputed

2024-05-09 Thread Jean-Marc Lasgouttes
commit 6b3ced7c075108b8667636d48fff46706d22045d
Author: Jean-Marc Lasgouttes 
Date:   Thu May 9 11:50:18 2024 +0200

one less place where metrics have to be recomputed
---
 src/BufferView.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index deba1db919..800801c264 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -1017,7 +1017,7 @@ void BufferView::showCursor(DocIterator const & dit, 
ScrollType how,
bool update)
 {
if (scrollToCursor(dit, how) && update)
-   processUpdateFlags(Update::Force);
+   processUpdateFlags(Update::ForceDraw);
 }
 
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] typo

2024-05-09 Thread Jean-Marc Lasgouttes
commit d4f3e87b14aae869a82fb72e788810a743d5c6e0
Author: Jean-Marc Lasgouttes 
Date:   Thu May 9 11:45:55 2024 +0200

typo
---
 src/BufferView.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 317a276cdd..deba1db919 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3241,7 +3241,7 @@ void BufferView::updateMetrics(bool force)
 
/* FIXME: do we want that? It avoids potential issues with old
 * paragraphs that should have been recomputed but have not, at
-* the price of potential extra metrics computaiton. I do not
+* the price of potential extra metrics computation. I do not
 * think that the performance gain is high, so that for now the
 * extra paragraphs are removed
 */
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Fixup 527984ed: fix initial screen size when using backing store

2024-05-07 Thread Jean-Marc Lasgouttes
commit ec9d0a94209037b080d0d7a5fb2d776b61addda7
Author: Jean-Marc Lasgouttes 
Date:   Tue May 7 12:01:34 2024 +0200

Fixup 527984ed: fix initial screen size when using backing store

When using a back store, it is obviously important to resize it
whenever the buffer view is resized. The new code path added in
527984ed skipped this part, so that the window was wrong when creating
a new window.
---
 src/frontends/qt/GuiWorkArea.cpp | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp
index 5935baaf77..ec9bedee5f 100644
--- a/src/frontends/qt/GuiWorkArea.cpp
+++ b/src/frontends/qt/GuiWorkArea.cpp
@@ -464,6 +464,9 @@ void GuiWorkArea::resizeBufferView()
busy(true);
 
bool const caret_in_view = d->buffer_view_->caretInView();
+   // Change backing store size if needed
+   d->resetScreen();
+   // Do the actual work: recompute metrics
d->buffer_view_->resize(viewport()->width(), viewport()->height());
if (caret_in_view)
d->buffer_view_->showCursor();
@@ -1391,10 +1394,8 @@ void GuiWorkArea::paintEvent(QPaintEvent * ev)
// LYXERR(Debug::PAINTING, "paintEvent begin: x: " << rc.x()
//  << " y: " << rc.y() << " w: " << rc.width() << " h: " << 
rc.height());
 
-   if (d->need_resize_ || pixelRatio() != d->last_pixel_ratio_) {
-   d->resetScreen();
+   if (d->need_resize_ || pixelRatio() != d->last_pixel_ratio_)
resizeBufferView();
-   }
 
d->last_pixel_ratio_ = pixelRatio();
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Fix up 5577e877: remove logic error

2024-05-03 Thread Jean-Marc Lasgouttes
commit 9f33db8f537e4488e229305d9a7a8707135d8e42
Author: Jean-Marc Lasgouttes 
Date:   Fri May 3 14:28:30 2024 +0200

Fix up 5577e877: remove logic error

Commit 5577e877 introduces forceUpdateBuffer() to delay actual
updatBuffer() calls to a central place.

In Cursor::upDownInText, the updateNeeded flag (which triggers
Update::Force update flag) is set to true when Cursor::checkDepm
returns true. This is fine, except that checkDepm also leads to a
forceBufferUpdate() call.

The logic in the method was such that, when updateNeeded is already
true when entering, forceBufferUpdate() will be called even though
checkDepm did not request it.

Fixes a slight delay with selecting in MergedManual (the manual of
manuals).
---
 src/Cursor.cpp | 24 +++-
 src/Cursor.h   |  5 ++---
 src/Text.cpp   | 11 ++-
 3 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/src/Cursor.cpp b/src/Cursor.cpp
index 45ae34c4b2..c1427f731a 100644
--- a/src/Cursor.cpp
+++ b/src/Cursor.cpp
@@ -2143,7 +2143,7 @@ bool Cursor::mathBackward(bool word)
 }
 
 
-bool Cursor::upDownInText(bool up, bool & updateNeeded)
+bool Cursor::upDownInText(bool up)
 {
LASSERT(text(), return false);
 
@@ -2153,6 +2153,9 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
getPos(xo, yo);
xo = beforeDispatchPosX_;
 
+   // Is a full repaint necessary?
+   bool updateNeeded = false;
+
// update the targetX - this is here before the "return false"
// to set a new target which can be used by InsetTexts above
// if we cannot move up/down inside this inset anymore
@@ -2221,12 +2224,13 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
dummy.pos() = dummy.pos() == 0 ? dummy.lastpos() : 0;
dummy.pit() = dummy.pit() == 0 ? dummy.lastpit() : 0;
 
-   updateNeeded |= bv().checkDepm(dummy, *this);
-   updateTextTargetOffset();
-   if (updateNeeded)
+   if (bv().checkDepm(dummy, *this)) {
+   updateNeeded = true;
forceBufferUpdate();
+   }
+   updateTextTargetOffset();
}
-   return false;
+   return updateNeeded;
}
 
// with and without selection are handled differently
@@ -2252,6 +2256,7 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
++dummy.pos();
if (bv().checkDepm(dummy, old)) {
updateNeeded = true;
+   forceBufferUpdate();
// Make sure that cur gets back whatever happened to 
dummy (Lgb)
operator=(dummy);
}
@@ -2292,13 +2297,14 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
// When selection==false, this is done by TextMetrics::editXY
setCurrentFont();
 
-   updateNeeded |= bv().checkDepm(*this, old);
+   if (bv().checkDepm(*this, old)) {
+   updateNeeded = true;
+   forceBufferUpdate();
+   }
}
 
-   if (updateNeeded)
-   forceBufferUpdate();
updateTextTargetOffset();
-   return true;
+   return updateNeeded;
 }
 
 
diff --git a/src/Cursor.h b/src/Cursor.h
index e362073ef4..094a540f24 100644
--- a/src/Cursor.h
+++ b/src/Cursor.h
@@ -506,9 +506,8 @@ public:
/// return true if fullscreen update is needed
bool down();
/// move up/down in a text inset, called for LFUN_UP/DOWN,
-   /// return true if successful, updateNeeded set to true if fullscreen
-   /// update is needed, otherwise it's not touched
-   bool upDownInText(bool up, bool & updateNeeded);
+   /// return true if fullscreen update is needed
+   bool upDownInText(bool up);
/// move up/down in math or any non text inset, call for LFUN_UP/DOWN
/// return true if successful
bool upDownInMath(bool up);
diff --git a/src/Text.cpp b/src/Text.cpp
index 55e150d6ac..44ca43f3ae 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -4333,7 +4333,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
if (!atFirstOrLastRow) {
needsUpdate |= cur.selHandle(select);
-   cur.upDownInText(up, needsUpdate);
+   needsUpdate |= cur.upDownInText(up);
needsUpdate |= cur.beforeDispatchCursor().inMathed();
} else {
pos_type newpos = up ? 0 : cur.lastpos();
@@ -4341,10 +4341,11 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
needsUpdate |= cur.selHandle(select);

[LyX/master] Fixup 2660df9b99b80: missing stuff after moving Lexer to support/

2024-05-01 Thread Jean-Marc Lasgouttes
commit f58957747a21f34b0d663d420ae9cd2aa60ffd36
Author: Jean-Marc Lasgouttes 
Date:   Wed May 1 16:54:10 2024 +0200

Fixup 2660df9b99b80: missing stuff after moving Lexer to support/
---
 src/Makefile.am|  2 +-
 src/tests/check_layout.cpp |  2 +-
 src/tex2lyx/Makefile.am| 10 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index 47a8e1ead5..44ddf66491 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -709,6 +709,7 @@ check_layout_SOURCES = \
tests/boost.cpp
 check_layout_LYX_OBJS = \
insets/InsetLayout.o \
+   support/Lexer.o \
CiteEnginesList.o \
Color.o \
Counters.o \
@@ -717,7 +718,6 @@ check_layout_LYX_OBJS = \
FontInfo.o \
Layout.o \
LayoutFile.o \
-   Lexer.o \
ModuleList.o \
Spacing.o \
TextClass.o
diff --git a/src/tests/check_layout.cpp b/src/tests/check_layout.cpp
index f92daa2250..5e9faf3a6b 100644
--- a/src/tests/check_layout.cpp
+++ b/src/tests/check_layout.cpp
@@ -3,9 +3,9 @@
 #include "../support/debug.h"
 #include "../support/FileName.h"
 #include "../support/filetools.h"
+#include "../support/Lexer.h"
 #include "../LayoutFile.h"
 #include "../LaTeXFeatures.h"
-#include "../Lexer.h"
 #include "../support/Messages.h"
 #include "../support/os.h"
 #include "../support/Package.h"
diff --git a/src/tex2lyx/Makefile.am b/src/tex2lyx/Makefile.am
index 7ad91a0828..57b6b7e01d 100644
--- a/src/tex2lyx/Makefile.am
+++ b/src/tex2lyx/Makefile.am
@@ -86,6 +86,11 @@ updatetests: tex2lyx
$(PYTHON) "$(srcdir)/test/runtests.py" ./tex2lyx 
"$(top_srcdir)/lib/scripts" "$(srcdir)/test"
 
 LYX_OBJS = \
+   ../graphics/GraphicsParams.o \
+   ../insets/ExternalTemplate.o \
+   ../insets/ExternalTransforms.o \
+   ../insets/InsetLayout.o \
+   ../support/Lexer.o \
../Author.o \
../CiteEnginesList.o \
../Color.o \
@@ -94,15 +99,10 @@ LYX_OBJS = \
../FloatList.o \
../Floating.o \
../FontInfo.o \
-   ../graphics/GraphicsParams.o \
-   ../insets/ExternalTemplate.o \
-   ../insets/ExternalTransforms.o \
-   ../insets/InsetLayout.o \
../LaTeXPackages.o \
../Layout.o \
../LayoutFile.o \
../LayoutModuleList.o \
-   ../Lexer.o \
../ModuleList.o \
../Spacing.o \
../TextClass.o \
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Avoid full metrics computation with Update:FitCursor

2024-04-30 Thread Jean-Marc Lasgouttes
commit be4e5dd43bf1563db832599b9e23c8800889db52
Author: Jean-Marc Lasgouttes 
Date:   Tue Apr 30 15:02:16 2024 +0200

Avoid full metrics computation with Update:FitCursor

The handling of Update::FitCursor traditionnally recomputes all
metrics once or twice. Now that updateMetrics(false) ensures that all
paragraphs that require it have a metrics, we might as well use that.

Take this occasion to move handling of Update::SinglePar earlier,
before the check for Update::ForceDraw.

(cherry picked from commit a4d9315bc49445e4419b3b59fd238a13c5f7be31)
---
 src/BufferView.cpp | 32 ++--
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index dd2259747d..de82559485 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -549,36 +549,40 @@ void BufferView::processUpdateFlags(Update::flags flags)
updateMetrics(true);
// metrics is done, full drawing is necessary now
flags = (flags & ~Update::Force) | Update::ForceDraw;
-   } else if (flags & Update::ForceDraw)
+   }
+   /* If a single paragraph update has been requested and we are not
+* already repainting all, check whether this update changes the
+* paragraph metrics. If it does, then compute all metrics (in
+* case the paragraph is in an inset)
+*
+* We handle this before FitCursor because the later will require
+* correct metrics at cursor position.
+*/
+   else if ((flags & Update::SinglePar) && !(flags & Update::ForceDraw)) {
+   if (!singleParUpdate())
+   updateMetrics(true);
+   }
+   else if (flags & Update::ForceDraw)
// This will compute only the needed metrics and update 
positions.
updateMetrics(false);
 
-   // Detect whether we can only repaint a single paragraph (if we
-   // are not already redrawing all).
-   // We handle this before FitCursor because the later will require
-   // correct metrics at cursor position.
-   if (!(flags & Update::ForceDraw)
-   && (flags & Update::SinglePar)
-   && !singleParUpdate())
-   updateMetrics(true);
-
// Then make sure that the screen contains the cursor if needed
if (flags & Update::FitCursor) {
if (needsFitCursor()) {
// First try to make the selection start visible
// (which is just the cursor when there is no selection)
scrollToCursor(d->cursor_.selectionBegin(), 
SCROLL_VISIBLE);
-   // Metrics have to be recomputed (maybe again)
-   updateMetrics(true);
+   // Metrics have to be updated
+   updateMetrics(false);
// Is the cursor visible? (only useful if cursor is at 
end of selection)
if (needsFitCursor()) {
// then try to make cursor visible instead
scrollToCursor(d->cursor_, SCROLL_VISIBLE);
// Metrics have to be recomputed (maybe again)
-   updateMetrics(true);
+   updateMetrics(false);
}
}
-   flags = flags & ~Update::FitCursor;
+   flags = (flags & ~Update::FitCursor) | Update::ForceDraw;
}
 
// Add flags to the the update flags. These will be reset to None
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Avoid full metrics computation with Update:FitCursor

2024-04-30 Thread Jean-Marc Lasgouttes
commit a4d9315bc49445e4419b3b59fd238a13c5f7be31
Author: Jean-Marc Lasgouttes 
Date:   Tue Apr 30 15:02:16 2024 +0200

Avoid full metrics computation with Update:FitCursor

The handling of Update::FitCursor traditionnally recomputes all
metrics once or twice. Now that updateMetrics(false) ensures that all
paragraphs that require it have a metrics, we might as well use that.

Take this occasion to move handling of Update::SinglePar earlier,
before the check for Update::ForceDraw.
---
 src/BufferView.cpp | 32 ++--
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 3c35d75ec8..317a276cdd 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -556,36 +556,40 @@ void BufferView::processUpdateFlags(Update::flags flags)
updateMetrics(true);
// metrics is done, full drawing is necessary now
flags = (flags & ~Update::Force) | Update::ForceDraw;
-   } else if (flags & Update::ForceDraw)
+   }
+   /* If a single paragraph update has been requested and we are not
+* already repainting all, check whether this update changes the
+* paragraph metrics. If it does, then compute all metrics (in
+* case the paragraph is in an inset)
+*
+* We handle this before FitCursor because the later will require
+* correct metrics at cursor position.
+*/
+   else if ((flags & Update::SinglePar) && !(flags & Update::ForceDraw)) {
+   if (!singleParUpdate())
+   updateMetrics(true);
+   }
+   else if (flags & Update::ForceDraw)
// This will compute only the needed metrics and update 
positions.
updateMetrics(false);
 
-   // Detect whether we can only repaint a single paragraph (if we
-   // are not already redrawing all).
-   // We handle this before FitCursor because the later will require
-   // correct metrics at cursor position.
-   if (!(flags & Update::ForceDraw)
-   && (flags & Update::SinglePar)
-   && !singleParUpdate())
-   updateMetrics(true);
-
// Then make sure that the screen contains the cursor if needed
if (flags & Update::FitCursor) {
if (needsFitCursor()) {
// First try to make the selection start visible
// (which is just the cursor when there is no selection)
scrollToCursor(d->cursor_.selectionBegin(), 
SCROLL_VISIBLE);
-   // Metrics have to be recomputed (maybe again)
-   updateMetrics(true);
+   // Metrics have to be updated
+   updateMetrics(false);
// Is the cursor visible? (only useful if cursor is at 
end of selection)
if (needsFitCursor()) {
// then try to make cursor visible instead
scrollToCursor(d->cursor_, SCROLL_VISIBLE);
// Metrics have to be recomputed (maybe again)
-   updateMetrics(true);
+   updateMetrics(false);
}
}
-   flags = flags & ~Update::FitCursor;
+   flags = (flags & ~Update::FitCursor) | Update::ForceDraw;
}
 
// Add flags to the the update flags. These will be reset to None
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


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

2024-04-30 Thread Jean-Marc Lasgouttes
commit eb7b3c08f712fd0bc410aac56e80ba541d9de44c
Author: Jean-Marc Lasgouttes 
Date:   Mon Apr 29 14:22:57 2024 +0200

Fix up 'Reduce metrics updates from 4 to 1 when loading file'

The missing metrics computation meant that, when loading a file, the
workarea would not be scrolled correctly to show the cursor.

The resizeBufferView does not create an additional metrics
computation, it just triggers it earlier.

The default value 1 in anchor_pos_ constructor ensures that the
first row is shown entirely.

(cherry picked from commit 527984ed2e0269861f5e1efc021fa0302d80819b)
---
 src/BufferView.cpp |  2 +-
 src/frontends/qt/GuiView.cpp   |  1 +
 src/frontends/qt/GuiWorkArea.cpp   | 26 +-
 src/frontends/qt/GuiWorkArea.h |  2 ++
 src/frontends/qt/GuiWorkArea_Private.h |  3 ---
 5 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index e1527b6548..dd2259747d 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -214,7 +214,7 @@ struct BufferView::Private
Private(BufferView & bv) :
update_strategy_(FullScreenUpdate),
update_flags_(Update::Force),
-   cursor_(bv), anchor_pit_(0), anchor_ypos_(0),
+   cursor_(bv), anchor_pit_(0), anchor_ypos_(1),
wh_(0), inlineCompletionUniqueChars_(0),
last_inset_(nullptr), mouse_position_cache_(),
gui_(nullptr), bookmark_edit_position_(-1),
diff --git a/src/frontends/qt/GuiView.cpp b/src/frontends/qt/GuiView.cpp
index facdb81b67..06818e58fe 100644
--- a/src/frontends/qt/GuiView.cpp
+++ b/src/frontends/qt/GuiView.cpp
@@ -2099,6 +2099,7 @@ void GuiView::setBuffer(Buffer * newBuffer, bool 
switch_to)
newBuffer->masterBuffer()->updateBuffer();
setBusy(false);
wa = addWorkArea(*newBuffer);
+   wa->resizeBufferView();
// scroll to the position when the BufferView was last closed
if (lyxrc.use_lastfilepos) {
LastFilePosSection::FilePos filepos =
diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp
index de8241c21f..0f847303c5 100644
--- a/src/frontends/qt/GuiWorkArea.cpp
+++ b/src/frontends/qt/GuiWorkArea.cpp
@@ -446,33 +446,33 @@ void GuiWorkArea::Private::dispatch(FuncRequest const & 
cmd)
 }
 
 
-void GuiWorkArea::Private::resizeBufferView()
+void GuiWorkArea::resizeBufferView()
 {
// WARNING: Please don't put any code that will trigger a repaint here!
// We are already inside a paint event.
-   p->stopBlinkingCaret();
+   stopBlinkingCaret();
// Warn our container (GuiView).
-   p->busy(true);
+   busy(true);
 
-   bool const caret_in_view = buffer_view_->caretInView();
-   buffer_view_->resize(p->viewport()->width(), p->viewport()->height());
+   bool const caret_in_view = d->buffer_view_->caretInView();
+   d->buffer_view_->resize(viewport()->width(), viewport()->height());
if (caret_in_view)
-   buffer_view_->showCursor();
-   resetCaret();
+   d->buffer_view_->showCursor();
+   d->resetCaret();
 
// Update scrollbars which might have changed due different
// BufferView dimension. This is especially important when the
// BufferView goes from zero-size to the real-size for the first time,
// as the scrollbar parameters are then set for the first time.
-   updateScrollbar();
+   d->updateScrollbar();
 
-   need_resize_ = false;
-   p->busy(false);
+   d->need_resize_ = false;
+   busy(false);
// Eventually, restart the caret after the resize event.
// We might be resizing even if the focus is on another widget so we 
only
// restart the caret if we have the focus.
-   if (p->hasFocus())
-   QTimer::singleShot(50, p, SLOT(startBlinkingCaret()));
+   if (hasFocus())
+   QTimer::singleShot(50, this, SLOT(startBlinkingCaret()));
 }
 
 
@@ -1317,7 +1317,7 @@ void GuiWorkArea::paintEvent(QPaintEvent * ev)
 
if (d->need_resize_ || pixelRatio() != d->last_pixel_ratio_) {
d->resetScreen();
-   d->resizeBufferView();
+   resizeBufferView();
}
 
d->last_pixel_ratio_ = pixelRatio();
diff --git a/src/frontends/qt/GuiWorkArea.h b/src/frontends/qt/GuiWorkArea.h
index 6f24ff313c..7731914249 100644
--- a/src/frontends/qt/GuiWorkArea.h
+++ b/src/frontends/qt/GuiWorkArea.h
@@ -63,6 +63,8 @@ public:
///
BufferView const & bufferView() const;
///
+   void resizeBufferView();
+   ///
void scheduleRedraw(bool update_metrics) override;
 
/// return true if

[LyX/master] Fix up 'Reduce metrics updates from 4 to 1 when loading file'

2024-04-30 Thread Jean-Marc Lasgouttes
commit 527984ed2e0269861f5e1efc021fa0302d80819b
Author: Jean-Marc Lasgouttes 
Date:   Mon Apr 29 14:22:57 2024 +0200

Fix up 'Reduce metrics updates from 4 to 1 when loading file'

The missing metrics computation meant that, when loading a file, the
workarea would not be scrolled correctly to show the cursor.

The resizeBufferView does not create an additional metrics
computation, it just triggers it earlier.
---
 src/BufferView.cpp |  2 +-
 src/frontends/qt/GuiView.cpp   |  1 +
 src/frontends/qt/GuiWorkArea.cpp   | 26 +-
 src/frontends/qt/GuiWorkArea.h |  2 ++
 src/frontends/qt/GuiWorkArea_Private.h |  3 ---
 5 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 292b0f6a01..3c35d75ec8 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -214,7 +214,7 @@ struct BufferView::Private
Private(BufferView & bv) :
update_strategy_(FullScreenUpdate),
update_flags_(Update::Force),
-   cursor_(bv), anchor_pit_(0), anchor_ypos_(0),
+   cursor_(bv), anchor_pit_(0), anchor_ypos_(1),
wh_(0), inlineCompletionUniqueChars_(0),
last_inset_(nullptr), mouse_position_cache_(),
gui_(nullptr), bookmark_edit_position_(-1),
diff --git a/src/frontends/qt/GuiView.cpp b/src/frontends/qt/GuiView.cpp
index 94a0a84be2..b4c412be6d 100644
--- a/src/frontends/qt/GuiView.cpp
+++ b/src/frontends/qt/GuiView.cpp
@@ -2119,6 +2119,7 @@ void GuiView::setBuffer(Buffer * newBuffer, bool 
switch_to)
newBuffer->masterBuffer()->updateBuffer();
setBusy(false);
wa = addWorkArea(*newBuffer);
+   wa->resizeBufferView();
// scroll to the position when the BufferView was last closed
if (lyxrc.use_lastfilepos) {
LastFilePosSection::FilePos filepos =
diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp
index d860d29b60..5935baaf77 100644
--- a/src/frontends/qt/GuiWorkArea.cpp
+++ b/src/frontends/qt/GuiWorkArea.cpp
@@ -455,33 +455,33 @@ void GuiWorkArea::Private::dispatch(FuncRequest const & 
cmd)
 }
 
 
-void GuiWorkArea::Private::resizeBufferView()
+void GuiWorkArea::resizeBufferView()
 {
// WARNING: Please don't put any code that will trigger a repaint here!
// We are already inside a paint event.
-   p->stopBlinkingCaret();
+   stopBlinkingCaret();
// Warn our container (GuiView).
-   p->busy(true);
+   busy(true);
 
-   bool const caret_in_view = buffer_view_->caretInView();
-   buffer_view_->resize(p->viewport()->width(), p->viewport()->height());
+   bool const caret_in_view = d->buffer_view_->caretInView();
+   d->buffer_view_->resize(viewport()->width(), viewport()->height());
if (caret_in_view)
-   buffer_view_->showCursor();
-   resetCaret();
+   d->buffer_view_->showCursor();
+   d->resetCaret();
 
// Update scrollbars which might have changed due different
// BufferView dimension. This is especially important when the
// BufferView goes from zero-size to the real-size for the first time,
// as the scrollbar parameters are then set for the first time.
-   updateScrollbar();
+   d->updateScrollbar();
 
-   need_resize_ = false;
-   p->busy(false);
+   d->need_resize_ = false;
+   busy(false);
// Eventually, restart the caret after the resize event.
// We might be resizing even if the focus is on another widget so we 
only
// restart the caret if we have the focus.
-   if (p->hasFocus())
-   QTimer::singleShot(50, p, SLOT(startBlinkingCaret()));
+   if (hasFocus())
+   QTimer::singleShot(50, this, SLOT(startBlinkingCaret()));
 }
 
 
@@ -1393,7 +1393,7 @@ void GuiWorkArea::paintEvent(QPaintEvent * ev)
 
if (d->need_resize_ || pixelRatio() != d->last_pixel_ratio_) {
d->resetScreen();
-   d->resizeBufferView();
+   resizeBufferView();
}
 
d->last_pixel_ratio_ = pixelRatio();
diff --git a/src/frontends/qt/GuiWorkArea.h b/src/frontends/qt/GuiWorkArea.h
index 86bbfda939..8cb0771c0f 100644
--- a/src/frontends/qt/GuiWorkArea.h
+++ b/src/frontends/qt/GuiWorkArea.h
@@ -63,6 +63,8 @@ public:
///
BufferView const & bufferView() const override;
///
+   void resizeBufferView();
+   ///
void scheduleRedraw(bool update_metrics) override;
 
/// return true if the key is part of a shortcut
diff --git a/src/frontends/qt/GuiWorkArea_Private.h 
b/src/frontends/qt/GuiWorkArea_Private.h
index 42dcef836c..672cba2056 100644
--- a/src/frontends/qt/G

[LyX/master] Remove unused #include

2024-04-28 Thread Jean-Marc Lasgouttes
commit df19a709008e706c40c3b81e6a42f61bbef745ef
Author: Jean-Marc Lasgouttes 
Date:   Sun Apr 28 12:33:33 2024 +0200

Remove unused #include
---
 src/support/filetools.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/support/filetools.cpp b/src/support/filetools.cpp
index a2eba83eef..3bdeb8e1e1 100644
--- a/src/support/filetools.cpp
+++ b/src/support/filetools.cpp
@@ -23,7 +23,6 @@
 
 #include "support/filetools.h"
 
-#include "LyX.h"
 #include "LyXRC.h"
 
 #include "support/convert.h"
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Move Lexer to support/ directory (and lyx::support namespace)

2024-04-28 Thread Jean-Marc Lasgouttes
commit 2660df9b99b8059856b931c22f53ee8f714a1d8e
Author: Jean-Marc Lasgouttes 
Date:   Sun Apr 28 00:24:46 2024 +0200

Move Lexer to support/ directory (and lyx::support namespace)

This requires quite a bit of trivial code shuffling.

 src/Buffer.cpp|  2 +-
 src/Buffer.h  |  8 
 src/BufferParams.cpp  |  2 +-
 src/BufferParams.h| 28 +++-
 src/BufferView.cpp|  2 +-
 src/CiteEnginesList.cpp   |  2 +-
 src/CmdDef.cpp|  2 +-
 src/ConverterCache.cpp|  2 +-
 src/Counters.cpp  |  2 +-
 src/Counters.h|  7 ---
 src/Encoding.cpp  |  3 +--
 src/Font.cpp  |  2 +-
 src/FontInfo.cpp  |  2 +-
 src/FontInfo.h|  4 ++--
 src/KeyMap.cpp|  2 +-
 src/LaTeXFonts.cpp|  2 +-
 src/LaTeXFonts.h  |  6 +++---
 src/LaTeXPackages.cpp |  3 +--
 src/Language.cpp  |  2 +-
 src/Language.h| 10 ++
 src/Layout.cpp|  2 +-
 src/Layout.h  | 23 ---
 src/LayoutFile.cpp|  2 +-
 src/LyXRC.cpp |  2 +-
 src/LyXRC.h   |  7 ---
 src/Makefile.am   |  2 --
 src/ModuleList.cpp|  2 +-
 src/PDFOptions.cpp|  2 +-
 src/PDFOptions.h  |  5 +++--
 src/ParagraphParameters.cpp   |  2 +-
 src/ParagraphParameters.h |  5 +++--
 src/Text.cpp  |  2 +-
 src/Text.h|  9 +
 src/TextClass.cpp |  2 +-
 src/TextClass.h   | 30 --
 src/Trans.cpp |  2 +-
 src/Trans.h   |  5 +++--
 src/factory.cpp   |  2 +-
 src/factory.h |  4 ++--
 src/frontends/qt/GuiApplication.cpp   |  2 +-
 src/frontends/qt/GuiLog.cpp   |  2 +-
 src/frontends/qt/GuiParagraph.cpp |  3 +--
 src/frontends/qt/GuiView.cpp  |  6 +++---
 src/frontends/qt/Menus.cpp|  4 ++--
 src/frontends/qt/Menus.h  |  5 +++--
 src/frontends/qt/Toolbars.cpp |  2 +-
 src/frontends/qt/Toolbars.h   |  9 +
 src/insets/ExternalTemplate.cpp   |  2 +-
 src/insets/ExternalTemplate.h |  9 +
 src/insets/Inset.h|  8 +---
 src/insets/InsetArgument.cpp  |  3 ++-
 src/insets/InsetArgument.h|  2 +-
 src/insets/InsetBibitem.cpp   |  2 +-
 src/insets/InsetBibitem.h |  2 +-
 src/insets/InsetBox.cpp   |  2 +-
 src/insets/InsetBox.h |  4 ++--
 src/insets/InsetBranch.cpp|  4 +++-
 src/insets/InsetBranch.h  |  4 ++--
 src/insets/InsetCollapsible.cpp   |  4 +++-
 src/insets/InsetCollapsible.h |  2 +-
 src/insets/InsetCommand.cpp   |  2 +-
 src/insets/InsetCommand.h |  2 +-
 src/insets/InsetCommandParams.cpp |  5 ++---
 src/insets/InsetCommandParams.h   |  7 ---
 src/insets/InsetERT.cpp   |  2 +-
 src/insets/InsetExternal.cpp  |  3 +--
 src/insets/InsetExternal.h|  4 ++--
 src/insets/InsetFlex.cpp  |  2 +-
 src/insets/InsetFloat.cpp |  2 +-
 src/insets/InsetFloat.h   |  4 ++--
 src/insets/InsetFloatList.cpp |  2 +-
 src/insets/InsetFloatList.h   |  2 +-
 src/insets/InsetGraphics.cpp  |  2 +-
 src/insets/InsetGraphics.h|  2 +-
 src/insets/InsetGraphicsParams.cpp|  2 +-
 src/insets/InsetGraphicsParams.h  |  4 ++--
 src/insets/InsetIPA.cpp   |  3 ++-
 src/insets/InsetIPAMacro.cpp  |  4 +++-
 src/insets/InsetIPAMacro.h|  6 +++---
 src/insets/InsetIndex.cpp |  2 +-
 src/insets/InsetIndex.h   |  4 ++--
 src/insets/InsetIndexMacro.cpp|  2 +-
 src/insets/InsetIndexMacro.h  |  4 ++--
 src/insets/InsetInfo.cpp  |  2 +-
 src/insets/InsetInfo.h|  2 +-
 src/insets/InsetLayout.cpp|  2 +-
 src/insets/InsetLayout.h  |  6 +++---
 src/insets/InsetListings.cpp  |  2 +-
 src/insets/InsetListings.h|  2 +-
 src/insets/InsetListingsParams.cpp|  5 ++---
 src/insets/InsetListingsParams.h  |  2 +-
 src/insets/InsetNewline.cpp   |  4 +++-
 src/insets/InsetNewline.h |  4 ++--
 src/insets/InsetNewpage.cpp   |  7 ---
 src/insets/InsetNewpage.h |  4 ++--
 src/insets/InsetNote.cpp  |  4 +++-
 src/insets/InsetNote.h

[LyX/2.4.1-devel] Set buffer_ correctly when inseting a math macro over a selection

2024-04-25 Thread Jean-Marc Lasgouttes
commit 13a34d6cd1bbf2a93d5b51624de7085d594cf8fa
Author: Jean-Marc Lasgouttes 
Date:   Thu Apr 25 14:28:10 2024 +0200

Set buffer_ correctly when inseting a math macro over a selection

The code that handles this special macro insertion (in
Cursor::mathMacroClose())) is very weird: it inserts the contents of
the macro _after_ the macro and later, since the macro is 'greedy', it
will eat this contents and put it in its first macro cell.

Does it make sense to you? It does not ake sense to me either. Anyway,
this is the point where one should make sure that the buffer is set.

Fixes ticket #12682.

(cherry picked from commit b45a957929a78cefc729a0fa984214eb83357d42)
---
 po/cs.gmo | Bin 627180 -> 627292 bytes
 po/de.gmo | Bin 653622 -> 653742 bytes
 po/sk.gmo | Bin 636629 -> 636898 bytes
 src/mathed/InsetMathMacro.cpp |   2 ++
 status.24x|   2 ++
 5 files changed, 4 insertions(+)

diff --git a/po/cs.gmo b/po/cs.gmo
index 77e6cdb0b6..a2e7997798 100644
Binary files a/po/cs.gmo and b/po/cs.gmo differ
diff --git a/po/de.gmo b/po/de.gmo
index 9fc86c4547..6677f06738 100644
Binary files a/po/de.gmo and b/po/de.gmo differ
diff --git a/po/sk.gmo b/po/sk.gmo
index 848fb84684..be2c5419d8 100644
Binary files a/po/sk.gmo and b/po/sk.gmo differ
diff --git a/src/mathed/InsetMathMacro.cpp b/src/mathed/InsetMathMacro.cpp
index a90bf87f5e..9caf4853dc 100644
--- a/src/mathed/InsetMathMacro.cpp
+++ b/src/mathed/InsetMathMacro.cpp
@@ -1078,6 +1078,8 @@ void InsetMathMacro::attachArguments(vector 
const & args, size_t arity
 {
LASSERT(d->displayMode_ == DISPLAY_NORMAL, return);
cells_ = args;
+   for (auto & cell : cells_)
+   cell.setBuffer(*buffer_);
d->attachedArgsNum_ = args.size();
cells_.resize(arity);
d->expanded_ = MathData();
diff --git a/status.24x b/status.24x
index 78494339b1..421226bba1 100644
--- a/status.24x
+++ b/status.24x
@@ -75,6 +75,8 @@ What's new
 
 * INTERNALS
 
+- Fix case where insets do not have proper information about current buffer
+  (bug 12682).
 
 
 * DOCUMENTATION AND LOCALIZATION
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Set buffer when creating a MathData from parts of another one

2024-04-25 Thread Jean-Marc Lasgouttes
commit ed2f3cb9cfa1e871d48a92d41791a77bd218ab67
Author: Jean-Marc Lasgouttes 
Date:   Thu Apr 25 17:13:15 2024 +0200

Set buffer when creating a MathData from parts of another one

This is triggered by selecting part of an equation under Xcb platform
(x11). Indeed, the current selection has to be sent to the X11 server
and BufferView::requestSelection() is called. Eventually
cap::grabSelection() is the function that creates this partial
MathData object.

Fixes ticket #12947.
---
 src/mathed/MathData.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/mathed/MathData.cpp b/src/mathed/MathData.cpp
index 5f62d86846..73c1d9db90 100644
--- a/src/mathed/MathData.cpp
+++ b/src/mathed/MathData.cpp
@@ -49,7 +49,9 @@ namespace lyx {
 
 MathData::MathData(Buffer * buf, const_iterator from, const_iterator to)
: base_type(from, to), buffer_(buf)
-{}
+{
+   setContentsBuffer();
+}
 
 
 void MathData::setContentsBuffer()
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Set buffer_ correctly when inseting a math macro over a selection

2024-04-25 Thread Jean-Marc Lasgouttes
commit b45a957929a78cefc729a0fa984214eb83357d42
Author: Jean-Marc Lasgouttes 
Date:   Thu Apr 25 14:28:10 2024 +0200

Set buffer_ correctly when inseting a math macro over a selection

The code that handles this special macro insertion (in
Cursor::mathMacroClose())) is very weird: it inserts the contents of
the macro _after_ the macro and later, since the macro is 'greedy', it
will eat this contents and put it in its first macro cell.

Does it make sense to you? It does not ake sense to me either. Anyway,
this is the point where one should make sure that the buffer is set.

Fixes ticket #12682.
---
 src/mathed/InsetMathMacro.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/mathed/InsetMathMacro.cpp b/src/mathed/InsetMathMacro.cpp
index 9d67c78077..03794c6632 100644
--- a/src/mathed/InsetMathMacro.cpp
+++ b/src/mathed/InsetMathMacro.cpp
@@ -1080,6 +1080,8 @@ void InsetMathMacro::attachArguments(vector 
const & args, size_t arity
 {
LASSERT(d->displayMode_ == DISPLAY_NORMAL, return);
cells_ = args;
+   for (auto & cell : cells_)
+   cell.setBuffer(*buffer_);
d->attachedArgsNum_ = args.size();
cells_.resize(arity, MathData(buffer_));
d->expanded_ = MathData(buffer_);
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] typo

2024-04-25 Thread Jean-Marc Lasgouttes
commit af3521881c209fa0019414096334057f3b6e8c75
Author: Jean-Marc Lasgouttes 
Date:   Thu Apr 25 14:27:22 2024 +0200

typo
---
 src/mathed/MathRow.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/mathed/MathRow.cpp b/src/mathed/MathRow.cpp
index b8d8f63d8e..4f605fa19c 100644
--- a/src/mathed/MathRow.cpp
+++ b/src/mathed/MathRow.cpp
@@ -340,7 +340,7 @@ void MathRow::draw(PainterInfo & pi, int x, int const y) 
const
if (pi.pain.develMode() && !e.inset->isBufferValid()) {
pi.pain.fillRectangle(x + e.before, y - 
g.dim.ascent(),
  g.dim.width(), 
g.dim.height(), Color_error);
-   LYXERR0("Unset Buffer memeber in " << 
insetName(e.inset->lyxCode()));
+   LYXERR0("Unset Buffer member in " << 
insetName(e.inset->lyxCode()));
}
e.inset->draw(pi, x + e.before, y);
g.pos = {x, y};
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Autotools: optimize with -Og when debugging

2024-04-25 Thread Jean-Marc Lasgouttes
commit 623cc13b60bc7345ad8a45bb1a6ab95e16dba6b0
Author: Jean-Marc Lasgouttes 
Date:   Thu Apr 25 12:30:48 2024 +0200

Autotools: optimize with -Og when debugging

When debug (-g) is enabled (default when compiling a development
version), the existing -O optimization level is not correct, since
many variables are optimized out when debugging.

Use -Og instead, and condition not on compiling a development version,
but on --enable-debug. This is the same by default, but it more
precise in our case.
---
 INSTALL  | 5 +++--
 config/lyxinclude.m4 | 4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/INSTALL b/INSTALL
index ec959ff6a8..9496fc16c7 100644
--- a/INSTALL
+++ b/INSTALL
@@ -107,7 +107,7 @@ flags:
 the settings in terms of various options that are described later
 
   release   prerelease  development profiling gprof
-optimization-O2 -O2 -O -O2 -O2
+optimization-O2 -O2 -Og-O2 -O2
 assertions   X   X
 stdlib-assertionsX
 stdlib-debug
@@ -213,10 +213,11 @@ values):
 
   o --enable-optimization=VALUE enables you to set optimization to a
 higher level than the default, for example --enable-optimization=-O3.
+Default is -Og when debugging is enabled, -O2 otherwise.
 
   o --disable-optimization - you can use this to disable compiler
 optimization of LyX. The compile may be much quicker with some
-compilers, but LyX will run more slowly.
+compilers, but LyX will be slower.
 
   o --enable-debug will add debug information to your binary. This
 requires a lot more disk space, but is a must if you want to try
diff --git a/config/lyxinclude.m4 b/config/lyxinclude.m4
index 90113fdf37..03e40581c9 100644
--- a/config/lyxinclude.m4
+++ b/config/lyxinclude.m4
@@ -326,8 +326,8 @@ AC_ARG_ENABLE(optimization,
 enable_optimization=yes;)
 case $enable_optimization in
 yes)
-if test $lyx_devel_version = yes ; then
-lyx_optim=-O
+if test $enable_debug = yes ; then
+lyx_optim=-Og
 else
 lyx_optim=-O2
 fi;;
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Force a Buffer * argument to math insets constructor

2024-04-25 Thread Jean-Marc Lasgouttes
commit c013799887eb5c330f3cff4d51542028683fe1bb
Author: Jean-Marc Lasgouttes 
Date:   Wed Apr 24 15:07:15 2024 +0200

Force a Buffer * argument to math insets constructor

Make sure that math insets have a proper buffer. To this end, make the
Buffer* parameter of InsetMath mandatory and fix the compilation
errors that ensue.
---
 src/Cursor.cpp|  6 ++---
 src/mathed/InsetMath.h|  2 +-
 src/mathed/InsetMathBig.cpp   |  4 ++--
 src/mathed/InsetMathBig.h |  2 +-
 src/mathed/InsetMathBrace.cpp |  4 ++--
 src/mathed/InsetMathBrace.h   |  2 +-
 src/mathed/InsetMathChar.cpp  |  4 ++--
 src/mathed/InsetMathChar.h|  2 +-
 src/mathed/InsetMathDots.cpp  |  4 ++--
 src/mathed/InsetMathDots.h|  2 +-
 src/mathed/InsetMathExInt.cpp |  4 ++--
 src/mathed/InsetMathGrid.cpp  |  6 ++---
 src/mathed/InsetMathHull.cpp  |  2 +-
 src/mathed/InsetMathKern.cpp  | 11 -
 src/mathed/InsetMathKern.h|  6 ++---
 src/mathed/InsetMathMacro.cpp |  6 +++--
 src/mathed/InsetMathMacroArgument.cpp |  4 ++--
 src/mathed/InsetMathMacroArgument.h   |  5 +++--
 src/mathed/InsetMathMacroTemplate.cpp | 41 +-
 src/mathed/InsetMathNest.cpp  | 36 ++
 src/mathed/InsetMathNumber.cpp|  4 ++--
 src/mathed/InsetMathNumber.h  |  2 +-
 src/mathed/InsetMathSpace.cpp | 12 +-
 src/mathed/InsetMathSpace.h   |  6 ++---
 src/mathed/InsetMathSpecialChar.cpp   |  4 ++--
 src/mathed/InsetMathSpecialChar.h |  2 +-
 src/mathed/InsetMathString.cpp|  4 ++--
 src/mathed/InsetMathString.h  |  2 +-
 src/mathed/InsetMathSymbol.cpp| 12 +-
 src/mathed/InsetMathSymbol.h  |  6 ++---
 src/mathed/InsetMathUnknown.cpp   |  4 ++--
 src/mathed/InsetMathUnknown.h |  2 +-
 src/mathed/MathData.cpp   |  4 ++--
 src/mathed/MathExtern.cpp |  4 ++--
 src/mathed/MathFactory.cpp| 16 ++---
 src/mathed/MathParser.cpp | 42 +--
 36 files changed, 141 insertions(+), 138 deletions(-)

diff --git a/src/Cursor.cpp b/src/Cursor.cpp
index 0e1c3ded55..45ae34c4b2 100644
--- a/src/Cursor.cpp
+++ b/src/Cursor.cpp
@@ -1492,7 +1492,7 @@ void Cursor::insert(char_type c)
LASSERT(!empty(), return);
if (inMathed()) {
cap::selClearOrDel(*this);
-   insert(new InsetMathChar(c));
+   insert(new InsetMathChar(buffer(), c));
} else {
text()->insertChar(*this, c);
}
@@ -1576,7 +1576,7 @@ void Cursor::niceInsert(MathAtom const & t)
docstring const name = t->asMacro()->name();
MacroData const * data = buffer()->getMacro(name);
if (data && data->numargs() - data->optionals() > 0) {
-   plainInsert(MathAtom(new InsetMathBrace(ar)));
+   plainInsert(MathAtom(new InsetMathBrace(buffer(), ar)));
posBackward();
}
}
@@ -1836,7 +1836,7 @@ bool Cursor::macroModeClose(bool cancel)
// finally put the macro argument behind, if needed
if (macroArg) {
if (selection.size() > 1 || selection[0]->asScriptInset())
-   plainInsert(MathAtom(new InsetMathBrace(selection)));
+   plainInsert(MathAtom(new InsetMathBrace(buffer(), 
selection)));
else
insert(selection);
}
diff --git a/src/mathed/InsetMath.h b/src/mathed/InsetMath.h
index 7ea8a7cfc1..34484028bb 100644
--- a/src/mathed/InsetMath.h
+++ b/src/mathed/InsetMath.h
@@ -120,7 +120,7 @@ class ReplaceData;
 class InsetMath : public Inset {
 public:
///
-   explicit InsetMath(Buffer * buf = 0) : Inset(buf) {}
+   explicit InsetMath(Buffer * buf) : Inset(buf) {}
/// identification as math inset
InsetMath * asInsetMath() override { return this; }
/// identification as math inset
diff --git a/src/mathed/InsetMathBig.cpp b/src/mathed/InsetMathBig.cpp
index 4972911b75..93661e1f56 100644
--- a/src/mathed/InsetMathBig.cpp
+++ b/src/mathed/InsetMathBig.cpp
@@ -28,8 +28,8 @@
 namespace lyx {
 
 
-InsetMathBig::InsetMathBig(docstring const & name, docstring const & delim)
-   : name_(name), delim_(delim)
+InsetMathBig::InsetMathBig(Buffer * buf, docstring const & name, docstring 
const & delim)
+   : InsetMath(buf), name_(name), delim_(delim)
 {}
 
 
diff --git a/src/mathed/InsetMathBig.h b/src/mathed/InsetMathBig.h
index 09f04a6f78..5f6793 100644
--- a/src/mathed/InsetMathBig.h
+++ b/src/mathed/InsetMathBig.h
@@ -21,7 +21,7 @@ namespace lyx {
 class InsetMathBig : public InsetMath {
 public:
///
-   Inset

[LyX/master] Force a Buffer * argument to MathData constructor

2024-04-25 Thread Jean-Marc Lasgouttes
commit 57d713065545ac53a62a641d12a8b8c2c62c22fc
Author: Jean-Marc Lasgouttes 
Date:   Wed Apr 24 12:04:23 2024 +0200

Force a Buffer * argument to MathData constructor

In order to ensure that MathData objects have a valid buffer, the
default MathData() constructor is deleted. This means that a buffer
shall be specified for each MathData object created.

This is fairly mechanical, actually. In particular, in most
InsetMathXxx cases, in MathData and in MathParser, the available
buffer_ member is used.

More specific cases:
- lyxfind.cpp takes the buffer from the Cursor

- calls to vector::resize take an additional
  MathData(buffer_) parameter. There are cases where resize actually
  remove cells, and in this case clear() or even erase() have been
  used.

- in InsetMathMacroTemplate, the optional parameters of the
  constructors cannot be allowed anymore (a default value cannot
  depend on another parameter). Therefore there a now two constructors
  instead.

- in MathAutoCorrect.cpp, the MathData objects are not bound to a
  buffer, so that std::nullptr is used instead.

- in MathExtern, use a buffer when one is specified, std::nulptr
  instead.
---
 src/lyxfind.cpp   |  6 ++--
 src/mathed/InsetMath.cpp  |  2 +-
 src/mathed/InsetMathGrid.cpp  |  2 +-
 src/mathed/InsetMathHull.cpp  |  8 +++---
 src/mathed/InsetMathMacro.cpp | 22 +++---
 src/mathed/InsetMathMacroTemplate.cpp | 12 ++--
 src/mathed/InsetMathMacroTemplate.h   |  8 --
 src/mathed/InsetMathNest.cpp  | 10 +++
 src/mathed/InsetMathRef.cpp   |  6 ++--
 src/mathed/InsetMathScript.cpp|  4 +--
 src/mathed/InsetMathSpace.cpp |  2 +-
 src/mathed/MathAutoCorrect.cpp|  4 +--
 src/mathed/MathData.cpp   |  8 +++---
 src/mathed/MathData.h |  2 +-
 src/mathed/MathExtern.cpp | 20 ++---
 src/mathed/MathParser.cpp | 54 +--
 16 files changed, 90 insertions(+), 80 deletions(-)

diff --git a/src/lyxfind.cpp b/src/lyxfind.cpp
index 6e3b324bfa..ea2f669e13 100644
--- a/src/lyxfind.cpp
+++ b/src/lyxfind.cpp
@@ -4131,7 +4131,7 @@ docstring stringifyFromCursor(DocIterator const & cur, 
int len)
(( len == -1 || cs.pos() + len > int(md.size()))
 ? md.end()
 : md.begin() + cs.pos() + len );
-   MathData md2;
+   MathData md2(cur.buffer());
for (MathData::const_iterator it = md.begin() + cs.pos(); it != 
it_end; ++it)
md2.push_back(*it);
docstring res = from_utf8(latexNamesToUtf8(asString(md2), 
false));
@@ -4197,7 +4197,7 @@ docstring latexifyFromCursor(DocIterator const & cur, int 
len)
((len == -1 || cs.pos() + len > int(md.size()))
 ? md.end()
 : md.begin() + cs.pos() + len);
-   MathData md2;
+   MathData md2(cur.buffer());
for (MathData::const_iterator it = md.begin() + cs.pos();
 it != it_end; ++it)
md2.push_back(*it);
@@ -4861,7 +4861,7 @@ bool findAdv(BufferView * bv, FindAndReplaceOptions & opt)
MathData md = cs.cell();
int len = -1;
MathData::const_iterator it_end 
= md.end();
-   MathData md2;
+   MathData md2(cur.buffer());
// Start the check with one 
character before actual cursor position
for (MathData::const_iterator 
it = md.begin() + cs.pos() - 1;
it != it_end; ++it)
diff --git a/src/mathed/InsetMath.cpp b/src/mathed/InsetMath.cpp
index e072b487a0..5aea5716ce 100644
--- a/src/mathed/InsetMath.cpp
+++ b/src/mathed/InsetMath.cpp
@@ -88,7 +88,7 @@ MathData & InsetMath::cell(idx_type)
 
 MathData const & InsetMath::cell(idx_type) const
 {
-   static MathData dummyCell;
+   static MathData dummyCell(const_cast(()));
LYXERR0("I don't have any cell");
return dummyCell;
 }
diff --git a/src/mathed/InsetMathGrid.cpp b/src/mathed/InsetMathGrid.cpp
index 3adec0ca2b..05242aca00 100644
--- a/src/mathed/InsetMathGrid.cpp
+++ b/src/mathed/InsetMathGrid.cpp
@@ -835,7 +835,7 @@ void InsetMathGrid::addCol(col_type newcol)
 {
const col_type nc = ncols();
const row_type nr = nrows();
-   cells_type new_cells((nc + 1) * nr);
+   cells_type new_c

[LyX/master] Try to make sure that math insets have a properly set buffer_ member

2024-04-22 Thread Jean-Marc Lasgouttes
commit f3c5ff9cb72c5231f1e1e81452e67d6f12dadecb
Author: Jean-Marc Lasgouttes 
Date:   Fri Oct 14 22:42:21 2022 +0200

Try to make sure that math insets have a properly set buffer_ member

Set the buffer of contents that is added to a MathData object through
MathData::insert() (both versions)
MathData::push_back()
asArray()

Also in math macros, initialize look_ with the relevant buffer.

This reduces the number of insets hat do not have a proper buffer.

See #13050 for discussion of this issue.
---
 src/mathed/InsetMathMacroTemplate.cpp |  8 +---
 src/mathed/MathData.cpp   | 24 ++--
 src/mathed/MathData.h |  7 +--
 src/mathed/MathSupport.cpp|  3 +++
 4 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/src/mathed/InsetMathMacroTemplate.cpp 
b/src/mathed/InsetMathMacroTemplate.cpp
index 9fe10491e2..c28c0d100f 100644
--- a/src/mathed/InsetMathMacroTemplate.cpp
+++ b/src/mathed/InsetMathMacroTemplate.cpp
@@ -394,7 +394,7 @@ void InsetNameWrapper::draw(PainterInfo & pi, int x, int y) 
const
 
 
 InsetMathMacroTemplate::InsetMathMacroTemplate(Buffer * buf)
-   : InsetMathNest(buf, 3), numargs_(0), argsInLook_(0), optionals_(0),
+   : InsetMathNest(buf, 3), look_(buf), numargs_(0), argsInLook_(0), 
optionals_(0),
  type_(MacroTypeNewcommand), redefinition_(false), lookOutdated_(true),
  premetrics_(false), labelBoxAscent_(0), labelBoxDescent_(0)
 {
@@ -405,8 +405,8 @@ InsetMathMacroTemplate::InsetMathMacroTemplate(Buffer * buf)
 InsetMathMacroTemplate::InsetMathMacroTemplate(Buffer * buf, docstring const & 
name, int numargs,
int optionals, MacroType type, vector const & optionalValues,
MathData const & def, MathData const & display)
-   : InsetMathNest(buf, optionals + 3), numargs_(numargs), 
argsInLook_(numargs),
- optionals_(optionals), optionalValues_(optionalValues),
+   : InsetMathNest(buf, optionals + 3), look_(buf), numargs_(numargs),
+ argsInLook_(numargs), optionals_(optionals), 
optionalValues_(optionalValues),
  type_(type), redefinition_(false), lookOutdated_(true),
  premetrics_(false), labelBoxAscent_(0), labelBoxDescent_(0)
 {
@@ -536,6 +536,8 @@ void InsetMathMacroTemplate::createLook(int args) const
look_.push_back(MathAtom(
new InsetDisplayLabelBox(buffer_, MathAtom(
new InsetMathWrapper((displayIdx(, _("LyX"), 
*this)));
+
+   look_.setContentsBuffer();
 }
 
 
diff --git a/src/mathed/MathData.cpp b/src/mathed/MathData.cpp
index 24b4d86fb9..4c33934828 100644
--- a/src/mathed/MathData.cpp
+++ b/src/mathed/MathData.cpp
@@ -52,11 +52,18 @@ MathData::MathData(Buffer * buf, const_iterator from, 
const_iterator to)
 {}
 
 
+void MathData::setContentsBuffer()
+{
+   if (buffer_)
+   for (MathAtom & at : *this)
+   at.nucleus()->setBuffer(*buffer_);
+}
+
+
 void MathData::setBuffer(Buffer & b)
 {
buffer_ = 
-   for (MathAtom & at : *this)
-   at.nucleus()->setBuffer(b);
+   setContentsBuffer();
 }
 
 
@@ -78,6 +85,8 @@ void MathData::insert(size_type pos, MathAtom const & t)
 {
LBUFERR(pos <= size());
base_type::insert(begin() + pos, t);
+   if (buffer_)
+   operator[](pos)->setBuffer(*buffer_);
 }
 
 
@@ -85,6 +94,17 @@ void MathData::insert(size_type pos, MathData const & ar)
 {
LBUFERR(pos <= size());
base_type::insert(begin() + pos, ar.begin(), ar.end());
+   if (buffer_)
+   for (size_type i = 0 ; i < ar.size() ; ++i)
+   operator[](pos + i)->setBuffer(*buffer_);
+}
+
+
+void MathData::push_back(MathAtom const & t)
+{
+   base_type::push_back(t);
+   if (buffer_)
+   back()->setBuffer(*buffer_);
 }
 
 
diff --git a/src/mathed/MathData.h b/src/mathed/MathData.h
index 865742df4c..c2d731efcb 100644
--- a/src/mathed/MathData.h
+++ b/src/mathed/MathData.h
@@ -59,7 +59,6 @@ public:
using base_type::clear;
using base_type::begin;
using base_type::end;
-   using base_type::push_back;
using base_type::pop_back;
using base_type::back;
using base_type::front;
@@ -85,6 +84,8 @@ public:
void insert(size_type pos, MathAtom const & at);
/// inserts multiple atoms at position pos
void insert(size_type pos, MathData const & ar);
+   /// inserts single atom at end
+   void push_back(MathAtom const & at);
 
/// erase range from pos1 to pos2
void erase(iterator pos1, iterator pos2);
@@ -187,8 +188,10 @@ public:
void updateMacros(Cursor * cur, MacroContext const & mc, UpdateType, 
int nesting);
///
void updateBuffer(ParIterator const &, UpdateType, bool const deleted = 
fals

[LyX/2.4.1-devel] Sanitize cursors after a buffer has been reloaded

2024-04-22 Thread Jean-Marc Lasgouttes
commit 21096f696a0de7a95b0a12b1d9530c3b4aa399e7
Author: Jean-Marc Lasgouttes 
Date:   Tue Apr 16 11:45:09 2024 +0200

Sanitize cursors after a buffer has been reloaded

When a buffer is reloaded, its content may remain the same, but the
memory allocation is new, so that the inset pointers in cursors are
now wrong. This requires to sanitize the cursors held by the buffer
views.

Before the biginset branch, some full metrics computation call that is
now removed probably did that as a side effect. Now we have to be more
precise.

To this effect, introduce WorkAreaManager::sanitizeCursors() and use
it in Buffer::reload().

(cherry picked from commit c1fd622c51752d790576600f5911813ff8dac3fa)
---
 src/Buffer.cpp|  3 +++
 src/frontends/WorkArea.h  |  7 +++
 src/frontends/WorkAreaManager.cpp | 12 
 src/frontends/WorkAreaManager.h   |  2 ++
 src/frontends/qt/GuiWorkArea.h|  4 ++--
 5 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index de7f4d217c..38d236964a 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -5562,6 +5562,9 @@ Buffer::ReadStatus Buffer::reload()
Buffer const * oldparent = d->parent();
d->setParent(nullptr);
ReadStatus const status = loadLyXFile();
+   // The inset members in cursors held by buffer views are now wrong.
+   workAreaManager().sanitizeCursors();
+   setBusy(false);
if (status == ReadSuccess) {
updateBuffer();
changed(true);
diff --git a/src/frontends/WorkArea.h b/src/frontends/WorkArea.h
index d6912fc7fa..c0e673554a 100644
--- a/src/frontends/WorkArea.h
+++ b/src/frontends/WorkArea.h
@@ -18,6 +18,8 @@
 
 namespace lyx {
 
+class BufferView;
+
 namespace frontend {
 
 /**
@@ -40,6 +42,11 @@ public:
 
/// Update window titles of all users.
virtual void updateWindowTitle() = 0;
+
+   ///
+   virtual BufferView & bufferView() = 0;
+   ///
+   virtual BufferView const & bufferView() const = 0;
 };
 
 } // namespace frontend
diff --git a/src/frontends/WorkAreaManager.cpp 
b/src/frontends/WorkAreaManager.cpp
index 8d32c6b6d8..324d5571af 100644
--- a/src/frontends/WorkAreaManager.cpp
+++ b/src/frontends/WorkAreaManager.cpp
@@ -13,6 +13,9 @@
 
 #include "WorkAreaManager.h"
 
+#include "BufferView.h"
+#include "Cursor.h"
+
 #include "Application.h"
 #include "WorkArea.h"
 
@@ -69,6 +72,15 @@ void WorkAreaManager::scheduleRedraw()
 }
 
 
+void WorkAreaManager::sanitizeCursors()
+{
+   for (WorkArea * wa : work_areas_) {
+   wa->bufferView().cursor().sanitize();
+   wa->bufferView().resetInlineCompletionPos();
+   }
+}
+
+
 } // namespace frontend
 } // namespace lyx
 
diff --git a/src/frontends/WorkAreaManager.h b/src/frontends/WorkAreaManager.h
index 94c528b3a6..73548592fa 100644
--- a/src/frontends/WorkAreaManager.h
+++ b/src/frontends/WorkAreaManager.h
@@ -49,6 +49,8 @@ public:
/// If there is no work area, create a new one in the current view 
using the
/// buffer buf. Returns false if not possible.
bool unhide(Buffer * buf) const;
+   /// Fix cursors in all buffer views held by work areas.
+   void sanitizeCursors();
 
 private:
typedef std::list::iterator iterator;
diff --git a/src/frontends/qt/GuiWorkArea.h b/src/frontends/qt/GuiWorkArea.h
index 148b79b73a..86bbfda939 100644
--- a/src/frontends/qt/GuiWorkArea.h
+++ b/src/frontends/qt/GuiWorkArea.h
@@ -59,9 +59,9 @@ public:
/// is GuiView in fullscreen mode?
bool isFullScreen() const;
///
-   BufferView & bufferView();
+   BufferView & bufferView() override;
///
-   BufferView const & bufferView() const;
+   BufferView const & bufferView() const override;
///
void scheduleRedraw(bool update_metrics) override;
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.x] small changes backported from master

2024-04-22 Thread Jean-Marc Lasgouttes
commit 3941c487e85a5c2a2b7897c9a6da3ac2d00b1da2
Author: Jean-Marc Lasgouttes 
Date:   Fri Apr 19 17:16:00 2024 +0200

small changes backported from master
---
 INSTALL | 6 +++---
 README  | 8 
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/INSTALL b/INSTALL
index 5c9c4d7489..ec959ff6a8 100644
--- a/INSTALL
+++ b/INSTALL
@@ -55,9 +55,9 @@ Requirements
 First of all, you will need a C++11 standard conforming compiler, like g++ (at
 least 4.9, to have proper srd::regex) or clang++.
 
-LyX makes great use of the C++ Standard Template Library (STL).
-This means that gcc users will have to install the relevant libstdc++
-library to be able to compile this version of LyX.
+LyX makes great use of the C++ Standard Library. This means that gcc
+users will have to install the relevant libstdc++ library to be able
+to compile this version of LyX.
 
 For full LyX usability we suggest to use Qt 5.6 and higher, or at the
 very least Qt 5.4. It is also possible to compile against Qt 6. The
diff --git a/README b/README
index b6b7a2ffb3..3d8da5aeea 100644
--- a/README
+++ b/README
@@ -27,8 +27,8 @@ What do I need to run LyX?
 
 Either:
 * a Unix-like system (including Windows with Cygwin)
-* Windows Vista or newer
-* Mac OS 10.4 or newer
+* Windows 7 or newer
+* Mac OS 10.13 or newer
 
 A decent LaTeX2e installation (e.g. TeX Live for Linux, MikTeX for
 Windows).
@@ -42,7 +42,7 @@ How does the LyX version scheme work?
 number "2.x.y" indicates a stable release '2.x', maintenance
 release 'y'.  In other words, LyX 2.3.0 was the first stable
 release in the 2.3-series of LyX. At the time of writing, the
-latest maintenance release in the 2.3-series is LyX 2.3.4.
+latest maintenance release in the 2.3-series is LyX 2.3.7.
 
 Please note that maintenance releases are designed primarily to
 fix bugs, and that the file format will _never_ change due to a
@@ -101,7 +101,7 @@ Okay, I've installed LyX. What now?
 the "Introduction" item under the Help menu.  You should follow
 the instructions there, which tell you to read (or at least skim)
 the Tutorial. After that, you should also read "Help>LaTeX
-configuration" which provides info on your LaTeX configuration
+Configuration" which provides info on your LaTeX configuration
 as LyX sees it.  You might be missing a package or two that you'd
 like to have.
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.1-devel] Document biginset branch

2024-04-21 Thread Jean-Marc Lasgouttes
commit 9b4b05e64ea0e692035052e5c5797545a6915b5a
Author: Jean-Marc Lasgouttes 
Date:   Sun Apr 21 22:26:41 2024 +0200

Document biginset branch
---
 status.24x | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/status.24x b/status.24x
index 350e94d4da..78494339b1 100644
--- a/status.24x
+++ b/status.24x
@@ -35,6 +35,9 @@ What's new
 - Allow relative statistics values in statusbar, improve update times for
   some UI and buffer operations.
 
+- The performance of LyX with large insets on slower computers has
+  been improved a lot (bug 12297).
+
 
 * DOCUMENTATION AND LOCALIZATION
 
@@ -63,7 +66,11 @@ What's new
 - Fix wrong position of conversion windows of the input method (bugs 11723,
   13054).
 
-- Speed up mouse movement when there is no selection (part of bug 13050).
+- Speed up mouse movement when there is no selection (part of bug
+  13050).
+
+- Fix incorrect scrolling when using outline to jump to a paragraph
+  (bug 10425).
 
 
 * INTERNALS
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Small change

2024-04-19 Thread Jean-Marc Lasgouttes
commit e631f908a71336e4ff237fec91ced73eed3dba24
Author: Jeân-Marc Lâsgöuttes 
Date:   Fri Apr 19 17:51:29 2024 +0200

Small change
---
 README | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README b/README
index 5621c68b9d..39d5aba7e4 100644
--- a/README
+++ b/README
@@ -42,7 +42,7 @@ How does the LyX version scheme work?
 number "2.x.y" indicates a stable release '2.x', maintenance
 release 'y'.  In other words, LyX 2.3.0 was the first stable
 release in the 2.3-series of LyX. At the time of writing, the
-latest maintenance release in the 2.3-series is LyX 2.3.4.
+latest maintenance release in the 2.3-series is LyX 2.3.7.
 
 Please note that maintenance releases are designed primarily to
 fix bugs, and that the file format will _never_ change due to a
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] small change

2024-04-19 Thread Jean-Marc Lasgouttes
commit abc8d49acd507089025b93976ae0fde10cb99c7f
Author: Jean-Marc Lasgouttes 
Date:   Fri Apr 19 17:24:10 2024 +0200

small change
---
 README | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README b/README
index b6b7a2ffb3..5621c68b9d 100644
--- a/README
+++ b/README
@@ -27,8 +27,8 @@ What do I need to run LyX?
 
 Either:
 * a Unix-like system (including Windows with Cygwin)
-* Windows Vista or newer
-* Mac OS 10.4 or newer
+* Windows 7 or newer
+* Mac OS 10.13 or newer
 
 A decent LaTeX2e installation (e.g. TeX Live for Linux, MikTeX for
 Windows).
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.1-devel] Always repaint the gray area below main inset

2024-04-18 Thread Jean-Marc Lasgouttes
commit c9f5f34fd703117981cc198ba910328b93e43e99
Author: Jean-Marc Lasgouttes 
Date:   Tue Apr 16 23:55:24 2024 +0200

Always repaint the gray area below main inset

Now that SingleParUpdate does not always lead to a full screen update
when the height of the paragraph changes (see new behavior of
updateMatrics(bool)), it is necessary to make sure that the grey area
below the main page is always repainted.

(cherry picked from commit 1a11abe4394272f521cd63993e426c136e0e9b6c)
---
 src/BufferView.cpp | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index e7f6bd04ed..1b2752e638 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3701,7 +3701,11 @@ void BufferView::draw(frontend::Painter & pain, bool 
paint_caret)
// Draw everything.
tm.draw(pi, 0, y);
 
-   // and possibly grey out below
+   break;
+   }
+
+   // Possibly grey out below
+   if (d->update_strategy_ != NoScreenUpdate) {
pair lastpm = tm.last();
int const y2 = lastpm.second->bottom();
 
@@ -3710,8 +3714,8 @@ void BufferView::draw(frontend::Painter & pain, bool 
paint_caret)
? Color_background : Color_bottomarea;
pain.fillRectangle(0, y2, width_, height_ - y2, color);
}
-   break;
}
+
LYXERR(Debug::PAINTING, (pain.isNull() ? "\t\t --- END NODRAW ---"
: "\t\t *** END DRAWING ***"));
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.1-devel] Do not compute metrics at each preview when loading file

2024-04-18 Thread Jean-Marc Lasgouttes
commit 15eef6a2c7cdca128a3476f2109371f35b372eba
Author: Jean-Marc Lasgouttes 
Date:   Thu Dec 21 16:33:06 2023 +0100

Do not compute metrics at each preview when loading file

With the branch-test.lyx file from #12297, loading takes forever when
previews are activated. This is because each preview element causes a
full screen metrics recomputation.

This commit just skips these calls and only does one when all previews
have been obtained. As a result, computing the previews takes 1 second
instead of 25 seconds on branch-test.lyx.

Part of bug #12297.

(cherry picked from commit 244969330108a89f4be93d3b2eb9024bdb756204)
---
 src/graphics/PreviewLoader.cpp | 12 
 1 file changed, 12 insertions(+)

diff --git a/src/graphics/PreviewLoader.cpp b/src/graphics/PreviewLoader.cpp
index 4c37f7a8d0..004ced6d89 100644
--- a/src/graphics/PreviewLoader.cpp
+++ b/src/graphics/PreviewLoader.cpp
@@ -787,6 +787,16 @@ void PreviewLoader::Impl::finishedGenerating(pid_t pid, 
int retval)
// Remove the item from the list of still-executing processes.
in_progress_.erase(git);
 
+#if 0
+   /* FIXME : there is no need for all these calls, which recompute
+* all metrics for each and every preview. The single call at the
+* end of this method is sufficient.
+
+* It seems that this whole imageReady mechanism is actually not
+* needed. If it is the case, the whole updateFrontend/updateInset
+* bloat can go too.
+*/
+
// Tell the outside world
list::const_reverse_iterator
nit  = newimages.rbegin();
@@ -795,6 +805,8 @@ void PreviewLoader::Impl::finishedGenerating(pid_t pid, int 
retval)
for (; nit != nend; ++nit) {
imageReady(*nit->get());
}
+#endif
+
finished_generating_ = true;
buffer_.scheduleRedrawWorkAreas();
 }
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.1-devel] Improve the code that limits scrolling at top/bottom

2024-04-18 Thread Jean-Marc Lasgouttes
commit e5aaa64b63ab0a0090df90b034925decd1c84061
Author: Jean-Marc Lasgouttes 
Date:   Fri Nov 17 18:30:37 2023 +0100

Improve the code that limits scrolling at top/bottom

The most visible part of this commit is the move of part of
BufferView::updateMetrics to a new TextMetrics::updateMetrics. This
new method makes sure that metrics are known for all visible paragraphs
(starting from anchor), and that the positions of the paragraphs have
been recorded.

This method is called up to 3 times in BufferView::updateMetrics:
* unconditionally, to update all visible metrics,
* then, if the bottom of the document is visible and too high, after
  updating the anchor ypos,
* and similarly if the top of the document is visible and too low.

This fixes for example the case where one jumps to Section 5.3 at the
end of Tutorial and 'scroll_below_document' is false.

Some now redundant code is removed from BufferView::scrollToCursor.

The anchor-setting code in BufferView::draw is not clearly useful, but
left here just in case. It generates a debug warning, though.

Part of bug #12297.

(cherry picked from commit f15d2ebf3819913114ab93d1ff7e140cb26b03d5)
---
 src/BufferView.cpp  | 99 ++---
 src/TextMetrics.cpp | 50 +++
 src/TextMetrics.h   |  4 +++
 3 files changed, 88 insertions(+), 65 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index a37ebcd814..e7f6bd04ed 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -769,6 +769,7 @@ void BufferView::scrollDocView(int const pixels, bool 
update)
TextMetrics const & tm = textMetrics(_.text());
if (tm.first().second->top() - pixels <= height_
 &&  tm.last().second->bottom() - pixels >= 0) {
+   LYXERR(Debug::SCROLLING, "small skip");
d->anchor_ypos_ -= pixels;
processUpdateFlags(Update::ForceDraw);
return;
@@ -791,6 +792,7 @@ void BufferView::scrollDocView(int const pixels, bool 
update)
return;
}
 
+   LYXERR(Debug::SCROLLING, "search paragraph");
// find paragraph at target position
int par_pos = d->scrollbarParameters_.min;
pit_type i = 0;
@@ -1104,8 +1106,6 @@ bool BufferView::scrollToCursor(DocIterator const & dit, 
ScrollType how)
d->anchor_ypos_ = - offset + row_dim.ascent();
if (how == SCROLL_CENTER)
d->anchor_ypos_ += height_/2 - row_dim.height() / 2;
-   else if (!lyxrc.scroll_below_document && d->anchor_pit_ == max_pit)
-   d->anchor_ypos_ = height_ - offset - row_dim.descent();
else if (offset > height_)
d->anchor_ypos_ = height_ - offset - defaultRowHeight();
else
@@ -3184,7 +3184,7 @@ void BufferView::updateMetrics(bool force)
return;
 
Text & buftext = buffer_.text();
-   pit_type const npit = int(buftext.paragraphs().size());
+   pit_type const lastpit = int(buftext.paragraphs().size()) - 1;
 
if (force) {
// Clear out the position cache in case of full screen redraw,
@@ -3203,62 +3203,35 @@ void BufferView::updateMetrics(bool force)
if (d->inlineCompletionPos_.fixIfBroken())
d->inlineCompletionPos_ = DocIterator();
 
-   if (d->anchor_pit_ >= npit)
+   if (d->anchor_pit_ > lastpit)
// The anchor pit must have been deleted...
-   d->anchor_pit_ = npit - 1;
+   d->anchor_pit_ = lastpit;
 
-   if (!tm.contains(d->anchor_pit_))
-   // Rebreak anchor paragraph.
-   tm.redoParagraph(d->anchor_pit_);
-   ParagraphMetrics & anchor_pm = tm.parMetrics(d->anchor_pit_);
+   // Update metrics around the anchor
+   tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
 
-   // make sure than first paragraph of document is not too low
-   if (d->anchor_pit_ == 0) {
-   int scrollRange = d->scrollbarParameters_.max - 
d->scrollbarParameters_.min;
+   // Check that the end of the document is not too high
+   int const min_visible = lyxrc.scroll_below_document ? minVisiblePart() 
: height_;
+   if (tm.last().first == lastpit && tm.last().second->bottom() < 
min_visible) {
+   d->anchor_ypos_ += min_visible - tm.last().second->bottom();
+   LYXERR(Debug::SCROLLING, "Too high, adjusting anchor ypos to " 
<< d->anchor_ypos_);
+   tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
+   }
 
-   // Complete buffer visible? Then it's easy.
-   if (scrollRange == 0)
-   d->anchor_ypos_ = anch

[LyX/2.4.1-devel] Introduce new helpers ParagraphMetrics::top/bottom

2024-04-18 Thread Jean-Marc Lasgouttes
commit b1a0983570b01348685fbcb3070fc071f1b40c15
Author: Jean-Marc Lasgouttes 
Date:   Tue Jul 25 16:31:13 2023 +0200

Introduce new helpers ParagraphMetrics::top/bottom

This avoids code with position/ascent/descent that is difficult to follow.

No change in function intended.

(cherry picked from commit 0b6105b9245350e428c73deee88af2cd7c0d4732)
---
 src/BufferView.cpp   | 18 --
 src/ParagraphMetrics.h   |  6 +-
 src/TextMetrics.cpp  | 20 ++--
 src/frontends/qt/GuiWorkArea.cpp |  2 +-
 4 files changed, 20 insertions(+), 26 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 27ad1ad8f2..c433487884 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -648,8 +648,8 @@ void BufferView::updateScrollbarParameters()
<< d->par_height_[pit]);
}
 
-   int top_pos = first.second->position() - first.second->ascent();
-   int bottom_pos = last.second->position() + last.second->descent();
+   int top_pos = first.second->top();
+   int bottom_pos = last.second->bottom();
bool first_visible = first.first == 0 && top_pos >= 0;
bool last_visible = last.first + 1 == int(parsize) && bottom_pos <= 
height_;
if (first_visible && last_visible) {
@@ -2781,7 +2781,7 @@ int BufferView::scrollDown(int pixels)
int const ymax = height_ + pixels;
while (true) {
pair last = tm.last();
-   int bottom_pos = last.second->position() + 
last.second->descent();
+   int bottom_pos = last.second->bottom();
if (lyxrc.scroll_below_document)
bottom_pos += height_ - minVisiblePart();
if (last.first + 1 == int(text->paragraphs().size())) {
@@ -2806,7 +2806,7 @@ int BufferView::scrollUp(int pixels)
int ymin = - pixels;
while (true) {
pair first = tm.first();
-   int top_pos = first.second->position() - first.second->ascent();
+   int top_pos = first.second->top();
if (first.first == 0) {
if (top_pos >= 0)
return 0;
@@ -3157,10 +3157,8 @@ bool BufferView::singleParUpdate()
 
tm.updatePosCache(pit);
 
-   LYXERR(Debug::PAINTING, "\ny1: " << pm.position() - pm.ascent()
-   << " y2: " << pm.position() + pm.descent()
-   << " pit: " << pit
-   << " singlepar: 1");
+   LYXERR(Debug::PAINTING, "\ny1: " << pm.top() << " y2: " << pm.bottom()
+   << " pit: " << pit << " singlepar: 1");
return true;
 }
 
@@ -3708,7 +3706,7 @@ void BufferView::draw(frontend::Painter & pain, bool 
paint_caret)
 
// and possibly grey out below
pair lastpm = tm.last();
-   int const y2 = lastpm.second->position() + 
lastpm.second->descent();
+   int const y2 = lastpm.second->bottom();
 
if (y2 < height_) {
Color color = buffer().isInternal()
@@ -3729,7 +3727,7 @@ void BufferView::draw(frontend::Painter & pain, bool 
paint_caret)
pair lastpm = tm.last();
for (pit_type pit = firstpm.first; pit <= lastpm.first; ++pit) {
ParagraphMetrics const & pm = tm.parMetrics(pit);
-   if (pm.position() + pm.descent() > 0) {
+   if (pm.bottom() > 0) {
if (d->anchor_pit_ != pit
|| d->anchor_ypos_ != pm.position())
LYXERR(Debug::PAINTING, "Found new anchor pit = 
" << d->anchor_pit_
diff --git a/src/ParagraphMetrics.h b/src/ParagraphMetrics.h
index 0d186f158b..805d056541 100644
--- a/src/ParagraphMetrics.h
+++ b/src/ParagraphMetrics.h
@@ -69,9 +69,13 @@ public:
///
bool hfillExpansion(Row const & row, pos_type pos) const;
 
-   ///
+   /// The vertical position of the baseline of the first line of the 
paragraph
int position() const { return position_; }
void setPosition(int position);
+   /// The vertical position of the top of the paragraph
+   int top() const { return position_ - dim_.ascent(); }
+   /// The vertical position of the bottom of the paragraph
+   int bottom() const { return position_ + dim_.descent(); }
///
int id() const { return id_; }
 
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 06e00f4220..837ad5766f 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -191,8 +191,7 @@ void TextMetrics::newParMetricsDown()
 
// do it and update its position.
  

[LyX/2.4.1-devel] Implement quick scroll

2024-04-18 Thread Jean-Marc Lasgouttes
commit 2434a3a28848669f7d8463bef70c668e0d6e615a
Author: Jean-Marc Lasgouttes 
Date:   Mon Jul 24 23:23:40 2023 +0200

Implement quick scroll

Replace flag parameter for updateMetrics() by a `force' boolean. When
it is false, the method keeps the metrics of paragraphs that are still
visible in WorkArea instead of computing everything afresh. All it has
to do is update their positions.

Add code to updateMetrics() to update the value of the anchor pit/ypos
(similar to the one in draw()).

Update processUpdateFlags() to use this when update flag is ForceDraw.

Modify scrollDocView() to just change the anchor paragraph position
when the scrolling operation would re-use some of the existing
paragraphs.

The time needed to update the metrics when scrolling with mouse in the
branch-test.lyx document is now divided by 20!

Part of bug #12297.

(cherry picked from commit 08010c6a5e425b3f2d0d625536e3a571c90a0482)
---
 src/BufferView.cpp  | 102 ++--
 src/BufferView.h|  14 ++--
 src/TextMetrics.cpp |   6 
 src/TextMetrics.h   |   2 ++
 4 files changed, 86 insertions(+), 38 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index c433487884..a37ebcd814 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -552,10 +552,13 @@ void BufferView::processUpdateFlags(Update::flags flags)
 
// First check whether the metrics and inset positions should be updated
if (flags & Update::Force) {
-   // This will update the CoordCache items and replace Force
-   // with ForceDraw in flags.
-   updateMetrics(flags);
-   }
+   // This will compute all metrics and positions.
+   updateMetrics(true);
+   // metrics is done, full drawing is necessary now
+   flags = (flags & ~Update::Force) | Update::ForceDraw;
+   } else if (flags & Update::ForceDraw)
+   // This will compute only the needed metrics and update 
positions.
+   updateMetrics(false);
 
// Detect whether we can only repaint a single paragraph (if we
// are not already redrawing all).
@@ -564,7 +567,7 @@ void BufferView::processUpdateFlags(Update::flags flags)
if (!(flags & Update::ForceDraw)
&& (flags & Update::SinglePar)
&& !singleParUpdate())
-   updateMetrics(flags);
+   updateMetrics(true);
 
// Then make sure that the screen contains the cursor if needed
if (flags & Update::FitCursor) {
@@ -573,13 +576,13 @@ void BufferView::processUpdateFlags(Update::flags flags)
// (which is just the cursor when there is no selection)
scrollToCursor(d->cursor_.selectionBegin(), 
SCROLL_VISIBLE);
// Metrics have to be recomputed (maybe again)
-   updateMetrics();
+   updateMetrics(true);
// Is the cursor visible? (only useful if cursor is at 
end of selection)
if (needsFitCursor()) {
// then try to make cursor visible instead
scrollToCursor(d->cursor_, SCROLL_VISIBLE);
// Metrics have to be recomputed (maybe again)
-   updateMetrics(flags);
+   updateMetrics(true);
}
}
flags = flags & ~Update::FitCursor;
@@ -761,10 +764,13 @@ void BufferView::scrollDocView(int const pixels, bool 
update)
if (pixels == 0)
return;
 
-   // If the offset is less than 2 screen height, prefer to scroll instead.
-   if (abs(pixels) <= 2 * height_) {
+   // If part of the existing paragraphs will remain visible, prefer to
+   // scroll
+   TextMetrics const & tm = textMetrics(_.text());
+   if (tm.first().second->top() - pixels <= height_
+&&  tm.last().second->bottom() - pixels >= 0) {
d->anchor_ypos_ -= pixels;
-   processUpdateFlags(Update::Force);
+   processUpdateFlags(Update::ForceDraw);
return;
}
 
@@ -3165,12 +3171,14 @@ bool BufferView::singleParUpdate()
 
 void BufferView::updateMetrics()
 {
-   updateMetrics(d->update_flags_);
+   updateMetrics(true);
+   // metrics is done, full drawing is necessary now
+   d->update_flags_ = (d->update_flags_ & ~Update::Force) | 
Update::ForceDraw;
d->update_strategy_ = FullScreenUpdate;
 }
 
 
-void BufferView::updateMetrics(Update::flags & update_flags)
+void BufferView::updateMetrics(bool force)
 {
if (height_ == 0 || width_ == 0)

[LyX/2.4.1-devel] Remove some redundant calls to updatePosCache

2024-04-18 Thread Jean-Marc Lasgouttes
commit e51f9d9f885bdf76ba6a20671d0f730d6be87483
Author: Jean-Marc Lasgouttes 
Date:   Mon Jul 24 15:35:16 2023 +0200

Remove some redundant calls to updatePosCache

The setting of insets positions was done twice in updateMetrics.
When one of the paragraph is a huge branch, this can be very expensive.

This leads to a 17% improvement on updateMetrics time on a scrolling test.

Part of bug #12297

(cherry picked from commit d19ade9a611d3ecf6840c5eb43291cb268ad6f4f)
---
 src/BufferView.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 4065a464b6..27ad1ad8f2 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3216,7 +3216,6 @@ void BufferView::updateMetrics(Update::flags & 
update_flags)
}
}
anchor_pm.setPosition(d->anchor_ypos_);
-   tm.updatePosCache(d->anchor_pit_);
 
LYXERR(Debug::PAINTING, "metrics: "
<< " anchor pit = " << d->anchor_pit_
@@ -3232,7 +3231,6 @@ void BufferView::updateMetrics(Update::flags & 
update_flags)
y1 -= pm.descent();
// Save the paragraph position in the cache.
pm.setPosition(y1);
-   tm.updatePosCache(pit1);
y1 -= pm.ascent();
}
 
@@ -3246,7 +3244,6 @@ void BufferView::updateMetrics(Update::flags & 
update_flags)
y2 += pm.ascent();
// Save the paragraph position in the cache.
pm.setPosition(y2);
-   tm.updatePosCache(pit2);
y2 += pm.descent();
}
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.1-devel] In the no-draw phase, do not cache the positions of not visible insets

2024-04-18 Thread Jean-Marc Lasgouttes
commit 5e1c414a21cd5d3345e7d3ff9181d7fa08c86830
Author: Jean-Marc Lasgouttes 
Date:   Mon Jul 24 17:53:16 2023 +0200

In the no-draw phase, do not cache the positions of not visible insets

This can make a big difference for a very large branch that contains
lots of equations.

This is complementary to the previous patch, since instead of reducing
the number of calls to updatePosCache, we make it faster.

In the same test of scrolling with mouse wheel through the
branch-test.lyx document, one finds a 23% improvement for
BufferView::updateMetrics().

Part of bug #12297.

(cherry picked from commit 7f85024f80601b15634fb5e771bba51435ad429f)
---
 src/TextMetrics.cpp | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 6968279c23..06e00f4220 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -2000,6 +2000,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, 
pit_type const pit, int const
if (pm.rows().empty())
return;
size_t const nrows = pm.rows().size();
+   int const wh = bv_->workHeight();
// Remember left and right margin for drawing math numbers
Changer changeleft = changeVar(pi.leftx, x + leftMargin(pit));
Changer changeright = changeVar(pi.rightx, x + width() - 
rightMargin(pit));
@@ -2014,15 +2015,17 @@ void TextMetrics::drawParagraph(PainterInfo & pi, 
pit_type const pit, int const
if (i)
y += row.ascent();
 
-   RowPainter rp(pi, *text_, row, row_x, y);
-
-   rp.paintOnlyInsets();
+   // It is not needed to draw on screen if we are not 
inside
+   bool const inside = (y + row.descent() >= 0 && y - 
row.ascent() < wh);
+   if (inside) {
+   RowPainter rp(pi, *text_, row, row_x, y);
+   rp.paintOnlyInsets();
+   }
y += row.descent();
}
return;
}
 
-   int const ww = bv_->workHeight();
Cursor const & cur = bv_->cursor();
DocIterator sel_beg = cur.selectionBegin();
DocIterator sel_end = cur.selectionEnd();
@@ -2065,7 +2068,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, 
pit_type const pit, int const
 
// It is not needed to draw on screen if we are not inside.
bool const inside = (y + row.descent() >= 0
-   && y - row.ascent() < ww);
+   && y - row.ascent() < wh);
if (!inside) {
// Inset positions have already been set in nodraw 
stage.
y += row.descent();
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.1-devel] Enable Update::SinglePar in nested insets too

2024-04-18 Thread Jean-Marc Lasgouttes
commit 13c7fd78c6c4876330598e89146ef4c7e44998bd
Author: Jean-Marc Lasgouttes 
Date:   Mon Jul 17 14:43:29 2023 +0200

Enable Update::SinglePar in nested insets too

The idea of single par update is to try to re-break only the paragraph
containing the cursor (if this paragraph contains insets etc.,
re-breaking will recursively descend).

The existing single paragraph update mechanism was tailored to work
only at top level. Indeed changing a paragraph nested into an inset may
lead to larger changes.

This commit tries a rather naive approach that seems to work well: we
need a full redraw if either

1/ the height has changed
or
2/ the width has changed and it was equal to the text metrics width;
   the goal is to catch the case of a one-row inset that grows with
   its contents, but optimize the case of typing in a short paragraph
   part of a larger inset.

NOTE: if only the height has changed, then it should be
  possible to update all metrics at minimal cost. However,
  since this is risky, we do not try that right now.

Part of bug #12297.

(cherry picked from commit 9a96726bcd06d565c3027011fea954656aa46668)
---
 src/BufferView.cpp | 42 +++---
 1 file changed, 27 insertions(+), 15 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index e20b0a7978..4065a464b6 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3118,24 +3118,36 @@ Cursor const & BufferView::cursor() const
 
 bool BufferView::singleParUpdate()
 {
-   Text & buftext = buffer_.text();
-   pit_type const bottom_pit = d->cursor_.bottom().pit();
-   TextMetrics & tm = textMetrics();
-   Dimension const old_dim = tm.parMetrics(bottom_pit).dim();
+   CursorSlice const & its = d->cursor_.innerTextSlice();
+   pit_type const pit = its.pit();
+   TextMetrics & tm = textMetrics(its.text());
+   Dimension const old_dim = tm.parMetrics(pit).dim();
 
// make sure inline completion pointer is ok
if (d->inlineCompletionPos_.fixIfBroken())
d->inlineCompletionPos_ = DocIterator();
 
-   // In Single Paragraph mode, rebreak only
-   // the (main text, not inset!) paragraph containing the cursor.
-   // (if this paragraph contains insets etc., rebreaking will
-   // recursively descend)
-   tm.redoParagraph(bottom_pit);
-   ParagraphMetrics & pm = tm.parMetrics(bottom_pit);
-   if (pm.height() != old_dim.height()) {
-   // Paragraph height has changed so we cannot proceed to
-   // the singlePar optimisation.
+   /* Try to rebreak only the paragraph containing the cursor (if
+* this paragraph contains insets etc., rebreaking will
+* recursively descend). We need a full redraw if either
+* 1/ the height has changed
+* or
+* 2/ the width has changed and it was equal to the textmetrics
+*width; the goal is to catch the case of a one-row inset that
+*grows with its contents, but optimize the case of typing at
+*the end of a mmultiple-row paragraph.
+*
+* NOTE: if only the height has changed, then it should be
+*   possible to update all metrics at minimal cost. However,
+*   since this is risky, we do not try that right now.
+*/
+   tm.redoParagraph(pit);
+   ParagraphMetrics & pm = tm.parMetrics(pit);
+   if (pm.height() != old_dim.height()
+   || (pm.width() != old_dim.width() && old_dim.width() == 
tm.width())) {
+   // Paragraph height or width has changed so we cannot proceed
+   // to the singlePar optimisation.
+   LYXERR(Debug::PAINTING, "SinglePar optimization failed.");
return false;
}
// Since position() points to the baseline of the first row, we
@@ -3143,11 +3155,11 @@ bool BufferView::singleParUpdate()
// the height does not change but the ascent does.
pm.setPosition(pm.position() - old_dim.ascent() + pm.ascent());
 
-   tm.updatePosCache(bottom_pit);
+   tm.updatePosCache(pit);
 
LYXERR(Debug::PAINTING, "\ny1: " << pm.position() - pm.ascent()
<< " y2: " << pm.position() + pm.descent()
-   << " pit: " << bottom_pit
+   << " pit: " << pit
<< " singlepar: 1");
return true;
 }
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Always repaint the gray area below main inset

2024-04-17 Thread Jean-Marc Lasgouttes
commit 3953698d9af73e647280308a75b7716d7054955c
Author: Jean-Marc Lasgouttes 
Date:   Tue Apr 16 23:55:24 2024 +0200

Always repaint the gray area below main inset

Now that SingleParUpdate does not always lead to a full screen update
when the height of the paragraph changes (see new behavior of
updateMatrics(bool)), it is necessary to make sure that the grey area
below the main page is always repainted.

(cherry picked from commit 1a11abe4394272f521cd63993e426c136e0e9b6c)
---
 src/BufferView.cpp | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 1056459ea2..e1527b6548 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3656,7 +3656,11 @@ void BufferView::draw(frontend::Painter & pain, bool 
paint_caret)
// Draw everything.
tm.draw(pi, 0, y);
 
-   // and possibly grey out below
+   break;
+   }
+
+   // Possibly grey out below
+   if (d->update_strategy_ != NoScreenUpdate) {
pair lastpm = tm.last();
int const y2 = lastpm.second->bottom();
 
@@ -3665,8 +3669,8 @@ void BufferView::draw(frontend::Painter & pain, bool 
paint_caret)
? Color_background : Color_bottomarea;
pain.fillRectangle(0, y2, width_, height_ - y2, color);
}
-   break;
}
+
LYXERR(Debug::PAINTING, (pain.isNull() ? "\t\t --- END NODRAW ---"
: "\t\t *** END DRAWING ***"));
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Always repaint the gray area below main inset

2024-04-17 Thread Jean-Marc Lasgouttes
commit 1a11abe4394272f521cd63993e426c136e0e9b6c
Author: Jean-Marc Lasgouttes 
Date:   Tue Apr 16 23:55:24 2024 +0200

Always repaint the gray area below main inset

Now that SingleParUpdate does not always lead to a full screen update
when the height of the paragraph changes (see new behavior of
updateMatrics(bool)), it is necessary to make sure that the grey area
below the main page is always repainted.
---
 src/BufferView.cpp | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 7abaea0d40..006211c15a 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3711,7 +3711,11 @@ void BufferView::draw(frontend::Painter & pain, bool 
paint_caret)
// Draw everything.
tm.draw(pi, 0, y);
 
-   // and possibly grey out below
+   break;
+   }
+
+   // Possibly grey out below
+   if (d->update_strategy_ != NoScreenUpdate) {
pair lastpm = tm.last();
int const y2 = lastpm.second->bottom();
 
@@ -3720,8 +3724,8 @@ void BufferView::draw(frontend::Painter & pain, bool 
paint_caret)
? Color_background : Color_bottomarea;
pain.fillRectangle(0, y2, width_, height_ - y2, color);
}
-   break;
}
+
LYXERR(Debug::PAINTING, (pain.isNull() ? "\t\t --- END NODRAW ---"
: "\t\t *** END DRAWING ***"));
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Sanitize cursors after a buffer has been reloaded

2024-04-16 Thread Jean-Marc Lasgouttes
commit c1fd622c51752d790576600f5911813ff8dac3fa
Author: Jean-Marc Lasgouttes 
Date:   Tue Apr 16 11:45:09 2024 +0200

Sanitize cursors after a buffer has been reloaded

When a buffer is reloaded, its content may remain the same, but the
memory allocation is new, so that the inset pointers in cursors are
now wrong. This requires to sanitize the cursors held by the buffer
views.

Before the biginset branch, some full metrics computation call that is
now removed probably did that as a side effect. Now we have to be more
precise.

To this effect, introduce WorkAreaManager::sanitizeCursors() and use
it in Buffer::reload().
---
 src/Buffer.cpp|  2 ++
 src/frontends/WorkArea.h  |  7 +++
 src/frontends/WorkAreaManager.cpp | 12 
 src/frontends/WorkAreaManager.h   |  2 ++
 src/frontends/qt/GuiWorkArea.h|  4 ++--
 5 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index bbe4d80589..c9d6818df6 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -5562,6 +5562,8 @@ Buffer::ReadStatus Buffer::reload()
Buffer const * oldparent = d->parent();
d->setParent(nullptr);
ReadStatus const status = loadLyXFile();
+   // The inset members in cursors held by buffer views are now wrong.
+   workAreaManager().sanitizeCursors();
setBusy(false);
if (status == ReadSuccess) {
updateBuffer();
diff --git a/src/frontends/WorkArea.h b/src/frontends/WorkArea.h
index d6912fc7fa..c0e673554a 100644
--- a/src/frontends/WorkArea.h
+++ b/src/frontends/WorkArea.h
@@ -18,6 +18,8 @@
 
 namespace lyx {
 
+class BufferView;
+
 namespace frontend {
 
 /**
@@ -40,6 +42,11 @@ public:
 
/// Update window titles of all users.
virtual void updateWindowTitle() = 0;
+
+   ///
+   virtual BufferView & bufferView() = 0;
+   ///
+   virtual BufferView const & bufferView() const = 0;
 };
 
 } // namespace frontend
diff --git a/src/frontends/WorkAreaManager.cpp 
b/src/frontends/WorkAreaManager.cpp
index 8d32c6b6d8..324d5571af 100644
--- a/src/frontends/WorkAreaManager.cpp
+++ b/src/frontends/WorkAreaManager.cpp
@@ -13,6 +13,9 @@
 
 #include "WorkAreaManager.h"
 
+#include "BufferView.h"
+#include "Cursor.h"
+
 #include "Application.h"
 #include "WorkArea.h"
 
@@ -69,6 +72,15 @@ void WorkAreaManager::scheduleRedraw()
 }
 
 
+void WorkAreaManager::sanitizeCursors()
+{
+   for (WorkArea * wa : work_areas_) {
+   wa->bufferView().cursor().sanitize();
+   wa->bufferView().resetInlineCompletionPos();
+   }
+}
+
+
 } // namespace frontend
 } // namespace lyx
 
diff --git a/src/frontends/WorkAreaManager.h b/src/frontends/WorkAreaManager.h
index 94c528b3a6..73548592fa 100644
--- a/src/frontends/WorkAreaManager.h
+++ b/src/frontends/WorkAreaManager.h
@@ -49,6 +49,8 @@ public:
/// If there is no work area, create a new one in the current view 
using the
/// buffer buf. Returns false if not possible.
bool unhide(Buffer * buf) const;
+   /// Fix cursors in all buffer views held by work areas.
+   void sanitizeCursors();
 
 private:
typedef std::list::iterator iterator;
diff --git a/src/frontends/qt/GuiWorkArea.h b/src/frontends/qt/GuiWorkArea.h
index 148b79b73a..86bbfda939 100644
--- a/src/frontends/qt/GuiWorkArea.h
+++ b/src/frontends/qt/GuiWorkArea.h
@@ -59,9 +59,9 @@ public:
/// is GuiView in fullscreen mode?
bool isFullScreen() const;
///
-   BufferView & bufferView();
+   BufferView & bufferView() override;
///
-   BufferView const & bufferView() const;
+   BufferView const & bufferView() const override;
///
void scheduleRedraw(bool update_metrics) override;
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Fixup 'Avoid metrics computation on resize when width did not change'

2024-04-10 Thread Jean-Marc Lasgouttes
commit 9fa3a90f2672b2d454f0cd24f36265151520f5c3
Author: Jean-Marc Lasgouttes 
Date:   Wed Apr 10 12:31:12 2024 +0200

Fixup 'Avoid metrics computation on resize when width did not change'

When the width of the window did not change, computing full metrics is
not necessary in BufferView::resize(), but it is better to redraw the
screen (especially with Wayland).

Typical use cases are when using M-x to open the minibuffer or going
in and out of an equation (which shows/hides the math toolbars).

(cherry picked from commit 83e7c74f6b4ce06936f11a5239a6c88f019a43ff)
---
 src/BufferView.cpp | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index c03f928c4d..1056459ea2 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -2492,8 +2492,11 @@ void BufferView::resize(int width, int height)
// Clear the paragraph height cache.
d->par_height_.clear();
// Redo the metrics.
-   updateMetrics();
+   updateMetrics(true);
}
+   // metrics is OK, full drawing is necessary now
+   d->update_flags_ = (d->update_flags_ & ~Update::Force) | 
Update::ForceDraw;
+   d->update_strategy_ = FullScreenUpdate;
 }
 
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Fixup 'Avoid metrics computation on resize when width did not change'

2024-04-10 Thread Jean-Marc Lasgouttes
commit 83e7c74f6b4ce06936f11a5239a6c88f019a43ff
Author: Jean-Marc Lasgouttes 
Date:   Wed Apr 10 12:31:12 2024 +0200

Fixup 'Avoid metrics computation on resize when width did not change'

When the width of the window did not change, computing full metrics is
not necessary in BufferView::resize(), but it is better to redraw the
screen (especially with Wayland).

Typical use cases are when using M-x to open the minibuffer or going
in and out of an equation (which shows/hides the math toolbars).
---
 src/BufferView.cpp | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index b5bf6d6ea1..acf80d7871 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -2529,8 +2529,11 @@ void BufferView::resize(int width, int height)
// Clear the paragraph height cache.
d->par_height_.clear();
// Redo the metrics.
-   updateMetrics();
+   updateMetrics(true);
}
+   // metrics is OK, full drawing is necessary now
+   d->update_flags_ = (d->update_flags_ & ~Update::Force) | 
Update::ForceDraw;
+   d->update_strategy_ = FullScreenUpdate;
 }
 
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Comment out too verbose debug output

2024-04-10 Thread Jean-Marc Lasgouttes
commit c3fb9fe95f02319ed8dd4bfc1f2fe306819a3d90
Author: Jean-Marc Lasgouttes 
Date:   Wed Apr 10 14:06:30 2024 +0200

Comment out too verbose debug output
---
 src/TextMetrics.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 93d4334598..ce8cfe552d 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -1547,8 +1547,8 @@ pit_type TextMetrics::getPitNearY(int y)
}
 
for (; it != et; ++it) {
-   LYXERR(Debug::PAINTING, "examining: pit: " << it->first
-   << " y: " << it->second.position());
+   // LYXERR(Debug::PAINTING, "examining: pit: " << it->first
+   //  << " y: " << it->second.position());
 
if (it->first >= pit && it->second.top() <= y) {
pit = it->first;
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.x] Do not include in InsetInfo.h

2024-04-08 Thread Jean-Marc Lasgouttes
commit 89afdb050f2b59aeed09bb199cb698d904e2144d
Author: Jean-Marc Lasgouttes 
Date:   Thu Apr 4 17:35:54 2024 +0200

Do not include  in InsetInfo.h

This is used by getDate/getTime, which actually should not be
InsetInfoParams methods, but functions in anonymous namespace.

(cherry picked from commit 51562ff37732f4949441bd8c2b55692b0719093a)
---
 src/frontends/qt/GuiInfo.cpp |  1 +
 src/insets/InsetInfo.cpp | 42 +-
 src/insets/InsetInfo.h   |  5 -
 3 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/src/frontends/qt/GuiInfo.cpp b/src/frontends/qt/GuiInfo.cpp
index 5ba0b19b46..232697fa5c 100644
--- a/src/frontends/qt/GuiInfo.cpp
+++ b/src/frontends/qt/GuiInfo.cpp
@@ -31,6 +31,7 @@
 #include "support/gettext.h"
 #include "support/lstrings.h"
 
+#include 
 
 using namespace std;
 using namespace lyx::support;
diff --git a/src/insets/InsetInfo.cpp b/src/insets/InsetInfo.cpp
index 3048456e84..df83f96b98 100644
--- a/src/insets/InsetInfo.cpp
+++ b/src/insets/InsetInfo.cpp
@@ -180,10 +180,9 @@ bool translateString(docstring const & in, docstring & 
out, string const & lcode
out = translateIfPossible(in, lcode);
return in != out;
 }
-} // namespace anon
 
 
-docstring InsetInfoParams::getDate(string const & iname, QDate const date) 
const
+docstring getDate(string const & iname, QDate const date, Language const * 
lang)
 {
QLocale loc;
if (lang)
@@ -208,7 +207,7 @@ docstring InsetInfoParams::getDate(string const & iname, 
QDate const date) const
 }
 
 
-docstring InsetInfoParams::getTime(string const & iname, QTime const time) 
const
+docstring getTime(string const & iname, QTime const time, Language const * 
lang)
 {
QLocale loc;
if (lang)
@@ -222,6 +221,7 @@ docstring InsetInfoParams::getTime(string const & iname, 
QTime const time) const
else
return qstring_to_ucs4(loc.toString(time, toqstr(iname)));
 }
+} // namespace anon
 
 
 vector> InsetInfoParams::getArguments(Buffer const * 
buf,
@@ -313,17 +313,17 @@ vector> 
InsetInfoParams::getArguments(Buffer const * buf,
date = (gdate.isValid()) ? gdate : QDate::currentDate();
} else
date = QDate::currentDate();
-   result.push_back(make_pair("long",getDate("long", date)));
-   result.push_back(make_pair("short", getDate("short", date)));
-   result.push_back(make_pair("loclong", getDate("loclong", 
date)));
-   result.push_back(make_pair("locmedium", getDate("locmedium", 
date)));
-   result.push_back(make_pair("locshort", getDate("locshort", 
date)));
-   result.push_back(make_pair("ISO", getDate("ISO", date)));
-   result.push_back(make_pair("", getDate("", date)));
-   result.push_back(make_pair("", getDate("", date)));
-   result.push_back(make_pair("MMM", getDate("MMM", date)));
-   result.push_back(make_pair("", getDate("", date)));
-   result.push_back(make_pair("ddd", getDate("ddd", date)));
+   result.push_back(make_pair("long",getDate("long", date, lang)));
+   result.push_back(make_pair("short", getDate("short", date, 
lang)));
+   result.push_back(make_pair("loclong", getDate("loclong", date, 
lang)));
+   result.push_back(make_pair("locmedium", getDate("locmedium", 
date, lang)));
+   result.push_back(make_pair("locshort", getDate("locshort", 
date, lang)));
+   result.push_back(make_pair("ISO", getDate("ISO", date, lang)));
+   result.push_back(make_pair("", getDate("", date, 
lang)));
+   result.push_back(make_pair("", getDate("", date, 
lang)));
+   result.push_back(make_pair("MMM", getDate("MMM", date, lang)));
+   result.push_back(make_pair("", getDate("", date, 
lang)));
+   result.push_back(make_pair("ddd", getDate("ddd", date, lang)));
result.push_back(make_pair("custom", _("Custom")));
break;
}
@@ -344,9 +344,9 @@ vector> 
InsetInfoParams::getArguments(Buffer const * buf,
time = (gtime.isValid()) ? gtime : QTime::currentTime();
} else
time = QTime::currentTime();
- 

[LyX/2.4.x] Fix compilation with msvc 2019

2024-04-08 Thread Jean-Marc Lasgouttes
commit 25f11742036f762aa1a83d377bc416a519bca6ef
Author: Jean-Marc Lasgouttes 
Date:   Sun Apr 7 20:41:13 2024 +0200

Fix compilation with msvc 2019

'uint' is not defined, 'unsigned int' is better.

(cherry picked from commit c7f53afd319fc9028be74f8949cec00063972462)
---
 src/Text.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Text.cpp b/src/Text.cpp
index d5a1069fa1..778c41820e 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -5958,7 +5958,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
// Argument?
if (!arg.empty()) {
if (isStrUnsignedInt(arg)) {
-   num = convert(arg);
+   num = convert(arg);
if (num >= freeFonts.size()) {
cur.message(_("Invalid argument (number 
exceeds stack size)!"));
break;
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Fix compilation with msvc 2019

2024-04-07 Thread Jean-Marc Lasgouttes
commit c7f53afd319fc9028be74f8949cec00063972462
Author: Jean-Marc Lasgouttes 
Date:   Sun Apr 7 20:41:13 2024 +0200

Fix compilation with msvc 2019

'uint' is not defined, 'unsigned int' is better.
---
 src/Text.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Text.cpp b/src/Text.cpp
index 4749f36d2c..1f9696de0d 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -5958,7 +5958,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
// Argument?
if (!arg.empty()) {
if (isStrUnsignedInt(arg)) {
-   num = convert(arg);
+   num = convert(arg);
if (num >= freeFonts.size()) {
cur.message(_("Invalid argument (number 
exceeds stack size)!"));
break;
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Fix compilation with msvc 2019

2024-04-07 Thread Jean-Marc Lasgouttes
commit 01355ab9b630c358c41aa72508b1604460766f60
Author: Jean-Marc Lasgouttes 
Date:   Sun Apr 7 20:41:13 2024 +0200

Fix compilation with msvc 2019

'uint' is not defined, 'unsigned int' is better.
---
 src/Text.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Text.cpp b/src/Text.cpp
index 4749f36d2c..1f9696de0d 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -5958,7 +5958,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
// Argument?
if (!arg.empty()) {
if (isStrUnsignedInt(arg)) {
-   num = convert(arg);
+   num = convert(arg);
if (num >= freeFonts.size()) {
cur.message(_("Invalid argument (number 
exceeds stack size)!"));
break;
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Fix crash when deleting inset with backspace

2024-04-07 Thread Jean-Marc Lasgouttes
commit b9e7754c932b014e019534f8e7aaf46797537e64
Author: Jean-Marc Lasgouttes 
Date:   Sun Apr 7 19:23:12 2024 +0200

Fix crash when deleting inset with backspace

See description here:
https://marc.info/?l=lyx-devel=171243435229412=2

cutSelectionHelper did not request a metrics update when the selection
was inner to a paragraph. The new code is better, but it was not
necessary before the biginset branch because of a full metrics
computation that hid this missing case.

(cherry picked from commit 89901123c579c6c7dbd1aecd092d62c3a0a3db24)
---
 src/CutAndPaste.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/CutAndPaste.cpp b/src/CutAndPaste.cpp
index 7fd76f98bc..09978d7c50 100644
--- a/src/CutAndPaste.cpp
+++ b/src/CutAndPaste.cpp
@@ -984,6 +984,8 @@ void cutSelectionHelper(Cursor & cur, CutStack & cuts, bool 
realcut, bool putcli
 
if (begpit != endpit)
cur.screenUpdateFlags(Update::Force | 
Update::FitCursor);
+   else
+   cur.screenUpdateFlags(Update::SinglePar | 
Update::FitCursor);
 
tie(endpit, endpos) =
eraseSelectionHelper(bp, text->paragraphs(), begpit, 
endpit,
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Fix crash when deleting inset with backspace

2024-04-07 Thread Jean-Marc Lasgouttes
commit 89901123c579c6c7dbd1aecd092d62c3a0a3db24
Author: Jean-Marc Lasgouttes 
Date:   Sun Apr 7 19:23:12 2024 +0200

Fix crash when deleting inset with backspace

See description here:
https://marc.info/?l=lyx-devel=171243435229412=2

cutSelectionHelper did not request a metrics update when the selection
was inner to a paragraph. The new code is better, but it was not
necessary before the biginset branch because of a full metrics
computation that hid this missing case.
---
 src/CutAndPaste.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/CutAndPaste.cpp b/src/CutAndPaste.cpp
index 276285dfbc..abed1567d7 100644
--- a/src/CutAndPaste.cpp
+++ b/src/CutAndPaste.cpp
@@ -989,6 +989,8 @@ void cutSelectionHelper(Cursor & cur, CutStack & cuts, bool 
realcut, bool putcli
 
if (begpit != endpit)
cur.screenUpdateFlags(Update::Force | 
Update::FitCursor);
+   else
+   cur.screenUpdateFlags(Update::SinglePar | 
Update::FitCursor);
 
tie(endpit, endpos) =
eraseSelectionHelper(bp, text->paragraphs(), begpit, 
endpit,
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Indicate that, by default, mouse LFUN do not require a metrics update

2024-04-05 Thread Jean-Marc Lasgouttes
commit 9fd397ac1cb8c97d9b3058a669a045db0cceee1c
Author: Jean-Marc Lasgouttes 
Date:   Mon Nov 27 17:50:40 2023 +0100

Indicate that, by default, mouse LFUN do not require a metrics update

This is done easily in LyXAction.cpp. Remember that, by default, each
function is supposed to request a full metrics computation.

Part of bug #12297.
---
 src/LyXAction.cpp | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index ece248e61c..0b3d0a25ad 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -3121,7 +3121,7 @@ void LyXAction::init()
  * \li Origin: Andre, 9 Aug 2002
  * \endvar
  */
-   { LFUN_MOUSE_DOUBLE, "", ReadOnly, Hidden },
+   { LFUN_MOUSE_DOUBLE, "", ReadOnly | NoUpdate, Hidden },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_MOUSE_MOTION
@@ -3131,7 +3131,7 @@ void LyXAction::init()
  * \li Origin: Andre, 9 Aug 2002
  * \endvar
  */
-   { LFUN_MOUSE_MOTION, "", ReadOnly | SingleParUpdate, Hidden },
+   { LFUN_MOUSE_MOTION, "", ReadOnly | NoUpdate, Hidden },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_MOUSE_PRESS
@@ -3141,7 +3141,7 @@ void LyXAction::init()
  * \li Origin: Andre, 9 Aug 2002
  * \endvar
  */
-   { LFUN_MOUSE_PRESS, "", ReadOnly, Hidden },
+   { LFUN_MOUSE_PRESS, "", ReadOnly | NoUpdate, Hidden },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_MOUSE_RELEASE
@@ -3151,7 +3151,7 @@ void LyXAction::init()
  * \li Origin: Andre, 9 Aug 2002
  * \endvar
  */
-   { LFUN_MOUSE_RELEASE, "", ReadOnly, Hidden },
+   { LFUN_MOUSE_RELEASE, "", ReadOnly | NoUpdate, Hidden },
 
 
 /*!
@@ -3162,7 +3162,7 @@ void LyXAction::init()
  * \li Origin: Andre, 9 Aug 2002
  * \endvar
  */
-   { LFUN_MOUSE_TRIPLE, "", ReadOnly, Hidden },
+   { LFUN_MOUSE_TRIPLE, "", ReadOnly | NoUpdate, Hidden },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_NEWLINE_INSERT
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Avoid metrics computation on resize when width did not change

2024-04-05 Thread Jean-Marc Lasgouttes
commit f7218cec188cad2dbf68de47ad4345fcddf1bdb8
Author: Jean-Marc Lasgouttes 
Date:   Mon Nov 27 11:46:52 2023 +0100

Avoid metrics computation on resize when width did not change

Entering a math inset triggers a work area reize because the math
toobars appear automatically. However, by default these toolbars are
at the bottom of the screen and their presence does not change the
typesetting of paragraphs. Therefore it is useful to avoid a call to
updateMetrics() in the case where the width of the work area did not
change.

Part of bug #12297.
---
 src/BufferView.cpp | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 34be860691..c03f928c4d 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -2484,14 +2484,16 @@ void BufferView::clearSelection()
 
 void BufferView::resize(int width, int height)
 {
-   // Update from work area
-   width_ = width;
height_ = height;
+   // Update metrics only if width has changed
+   if (width != width_) {
+   width_ = width;
 
-   // Clear the paragraph height cache.
-   d->par_height_.clear();
-   // Redo the metrics.
-   updateMetrics();
+   // Clear the paragraph height cache.
+   d->par_height_.clear();
+   // Redo the metrics.
+   updateMetrics();
+   }
 }
 
 
@@ -3131,6 +3133,8 @@ void BufferView::updateMetrics(bool force)
if (!ready())
return;
 
+   //LYXERR0("updateMetrics " << _v_(force));
+
Text & buftext = buffer_.text();
pit_type const lastpit = int(buftext.paragraphs().size()) - 1;
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Avoid full metrics computation when entering/leaving inset

2024-04-05 Thread Jean-Marc Lasgouttes
commit 73678dcde977802d5ff3ae07f0226484041fff48
Author: Jean-Marc Lasgouttes 
Date:   Mon Nov 27 15:57:09 2023 +0100

Avoid full metrics computation when entering/leaving inset

Annotate function LFUN_FINISHED_xxx to indicate that they do not
require a full metrics computation.

Remove an "optimization" that meant that when the cursor changed
inset, a full metrics computation was requested.

Part of bug #12297
---
 src/LyXAction.cpp |  8 
 src/Text.cpp  | 33 +
 2 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index b6bb52152c..ece248e61c 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -1655,7 +1655,7 @@ void LyXAction::init()
  * \li Notion: See also #LFUN_FINISHED_FORWARD.
  * \endvar
  */
-   { LFUN_FINISHED_BACKWARD, "", ReadOnly, Hidden },
+   { LFUN_FINISHED_BACKWARD, "", ReadOnly | NoUpdate, Hidden },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_FINISHED_FORWARD
@@ -1668,7 +1668,7 @@ void LyXAction::init()
back into the surrounding text.
  * \endvar
  */
-   { LFUN_FINISHED_FORWARD, "", ReadOnly, Hidden },
+   { LFUN_FINISHED_FORWARD, "", ReadOnly | NoUpdate, Hidden },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_FINISHED_LEFT
@@ -1676,7 +1676,7 @@ void LyXAction::init()
  * \li Notion: See also #LFUN_FINISHED_FORWARD.
  * \endvar
  */
-   { LFUN_FINISHED_LEFT, "", ReadOnly, Hidden },
+   { LFUN_FINISHED_LEFT, "", ReadOnly | NoUpdate, Hidden },
 
 
 /*!
@@ -1685,7 +1685,7 @@ void LyXAction::init()
  * \li Notion: See also #LFUN_FINISHED_FORWARD
  * \endvar
  */
-   { LFUN_FINISHED_RIGHT, "", ReadOnly, Hidden },
+   { LFUN_FINISHED_RIGHT, "", ReadOnly | NoUpdate, Hidden },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_FLEX_INSERT
diff --git a/src/Text.cpp b/src/Text.cpp
index 2684309dec..4749f36d2c 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -6393,23 +6393,24 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor);
return;
}
-   if (!needsUpdate
-   && () == ()
-   && oldTopSlice.idx() == cur.idx()
-   && !oldSelection // oldSelection is a backup of cur.selection() at 
the beginning of the function.
-   && !cur.selection())
-   // FIXME: it would be better if we could just do this
-   //
-   //if (cur.result().update() != Update::FitCursor)
-   //  cur.noScreenUpdate();
-   //
-   // But some LFUNs do not set Update::FitCursor when needed, so 
we
-   // do it for all. This is not very harmfull as FitCursor will 
provoke
-   // a full redraw only if needed but still, a proper review of 
all LFUN
-   // should be done and this needsUpdate boolean can then be 
removed.
-   cur.screenUpdateFlags(Update::FitCursor);
-   else
+   if (needsUpdate)
cur.screenUpdateFlags(Update::Force | Update::FitCursor);
+   else {
+   // oldSelection is a backup of cur.selection() at the beginning 
of the function.
+   if (!oldSelection && !cur.selection())
+   // FIXME: it would be better if we could just do this
+   //
+   //if (cur.result().update() != Update::FitCursor)
+   //  cur.noScreenUpdate();
+   //
+   // But some LFUNs do not set Update::FitCursor when 
needed, so we
+   // do it for all. This is not very harmfull as 
FitCursor will provoke
+   // a full redraw only if needed but still, a proper 
review of all LFUN
+   // should be done and this needsUpdate boolean can then 
be removed.
+   cur.screenUpdateFlags(Update::FitCursor);
+   else
+   cur.screenUpdateFlags(Update::ForceDraw | 
Update::FitCursor);
+   }
 }
 
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Avoid some full metrics computations related to math previews

2024-04-05 Thread Jean-Marc Lasgouttes
commit 5e8578837fea0321998eac04222102986261666d
Author: Jean-Marc Lasgouttes 
Date:   Mon Nov 27 15:13:56 2023 +0100

Avoid some full metrics computations related to math previews

When entering/leaving a math hull inset, a Update::Force flag was set,
in case the metrics of the inset would change because of a switch
between normal and preview representation.

When entering the inset, this code is now used only when the inset was
in preview mode.

In both cases, Update::Force is replaced with Update::SinglePar.

This requites in Text::dispatch to honor Update::SinglePar when it has
been set by some lfun, even when singleparupdate is false.

Part of bug #12297.
---
 src/Text.cpp |  2 +-
 src/mathed/InsetMathHull.cpp | 13 -
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/src/Text.cpp b/src/Text.cpp
index d5a1069fa1..2684309dec 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -6386,7 +6386,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
// FIXME: the following code should go in favor of fine grained
// update flag treatment.
-   if (singleParUpdate) {
+   if (singleParUpdate || cur.result().screenUpdate() & Update::SinglePar) 
{
// Inserting characters does not change par height in general. 
So, try
// to update _only_ this paragraph. BufferView will detect if a 
full
// metrics update is needed anyway.
diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp
index 94d293870d..34c319ea5c 100644
--- a/src/mathed/InsetMathHull.cpp
+++ b/src/mathed/InsetMathHull.cpp
@@ -902,7 +902,7 @@ bool InsetMathHull::notifyCursorLeaves(Cursor const & old, 
Cursor & cur)
 {
if (RenderPreview::previewMath()) {
reloadPreview(old);
-   cur.screenUpdateFlags(Update::Force);
+   cur.screenUpdateFlags(Update::SinglePar);
}
return false;
 }
@@ -2273,14 +2273,17 @@ void InsetMathHull::handleFont2(Cursor & cur, docstring 
const & arg)
 
 void InsetMathHull::edit(Cursor & cur, bool front, EntryDirection entry_from)
 {
+   bool const has_preview = previewState(());
cur.push(*this);
bool enter_front = (entry_from == Inset::ENTRY_DIRECTION_LEFT ||
(entry_from == Inset::ENTRY_DIRECTION_IGNORE && front));
enter_front ? idxFirst(cur) : idxLast(cur);
-   // The inset formula dimension is not necessarily the same as the
-   // one of the instant preview image, so we have to indicate to the
-   // BufferView that a metrics update is needed.
-   cur.screenUpdateFlags(Update::Force);
+   if (has_preview) {
+   // The inset formula dimension is in general different from the
+   // one of the instant preview image, so we have to indicate to 
the
+   // BufferView that a metrics update is needed.
+   cur.screenUpdateFlags(Update::SinglePar);
+   }
 }
 
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Update PAINTING_ANALYSIS

2024-04-05 Thread Jean-Marc Lasgouttes
commit a23522073c8bb2cd06ddc7cc564e9c78f868a86d
Author: Jean-Marc Lasgouttes 
Date:   Mon Nov 20 17:24:09 2023 +0100

Update PAINTING_ANALYSIS
---
 development/PAINTING_ANALYSIS | 62 +--
 1 file changed, 42 insertions(+), 20 deletions(-)

diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS
index a506371965..438d7ca9c3 100644
--- a/development/PAINTING_ANALYSIS
+++ b/development/PAINTING_ANALYSIS
@@ -3,7 +3,7 @@ Understanding the painting process
 
 This file tries to describe the state of the metrics/painting
 mechanism, and identify the improvements that could be made. The first
-section can be read alone, although the context for them is really
+sections can be read alone, although the context for them is really
 given in the following ones.
 
 Please keep this file up to date as the code evolves!!!
@@ -20,9 +20,10 @@ following section. Some actions are proposed.
 
 ** SinglePar update
 
-This flag only has an effect in the current BufferView and at
-top-level, but I think it is useful in other views too. Doing this
-will require some work on the update pipeline, though.
+This flag only has an effect in the current BufferView, but I think it
+is useful in other views too. Doing this will require some work on the
+update pipeline, though.
+
 
 ** Buffer::change issues
 
@@ -53,17 +54,16 @@ The global idea would be to extend FitCursor to cover also 
horizontal
 cursor.
 
 
-* Clean-up of drawing code
+* TODO Clean-up of drawing code
 
 ** Set Row::changed() in a finer way
 
 *** singleParUpdate
 
 When the height of the current paragraph changes, there is no need for
-a full screen update. Only the rows after the current one need to have
-their position recomputed.
+a full screen update (at top level, at least). Only the rows after the
+current one need to have their position recomputed.
 
-This is also true when scrolling (how to do that?)
 
 *** redoParagraph
 
@@ -71,13 +71,16 @@ It should be possible to check whether the new row is the 
same as the
 old one and keep its changed() status in this case. This would reduce
 a lot the amount of stuff to redraw.
 
+
 ** Put labels and friends in the Row as elements
 
 It should not be necessary to access the Paragraph object to draw.
 Adding the static elements to Row is a lot of work, but worth it IMO.
 
+
 ** When a paragraph ends with a newline, compute correctly the height of the 
extra row.
 
+
 ** Merging bv::updateMetrics and tm::metrics
 
 While the full metrics computation tries hard to limit the number of
@@ -89,6 +92,12 @@ insets. We should re-use the bv::updateMetrics logic:
 
 The difficulty for a tall table cell for example, is that it may be
 necessary to break the whole contents to know the width of the cell.
+Also, the anchor is relative to the outer paragraph, which means that
+for a very long inset it is necessary to rebreak until the contents
+that needs to be shown (to compute the heights).
+
+All in all, this is difficult to get right. This is less important now
+that SinglePar updates work in nested insets.
 
 
 * Description of current drawing mechanism
@@ -99,10 +108,12 @@ There are three parts to drawing the work area:
 
  + the metrics phase computes the size of insets and breaks the
paragraphs into rows. It stores the dimension of insets (both
-   normal and math) in bv::coordCache.
+   normal and math) in bv::coordCache and the vertical position of the
+   top-level paragraphs.
 
  + the nodraw drawing phase paints the screen (see below) with a null
-   painter. The only useful effect is to store the inset positions.
+   painter. The only useful effect is to store the positions of
+   visible insets.
 
  + an update() signal is sent. This in turn will trigger a paint
event, and the actual screen painting will happen then.
@@ -115,18 +126,18 @@ whether this is correct.
 
 Depending on the Update::flags passed to the method, it sets an update
 strategy in (NoScreenUpdate, SingleParUpdate, FullScreenUpdate,
-DecorationUpdate). It triggers a recomputation of the metrics when either:
+DecorationUpdate). It triggers a call to updateMetrics when either:
 
  + Update::Force has been specified
  + Update::FitCursor has been specified and there is a need to scroll
the display.
  + Update::SinglePar has been specified and the current paragraph has
-   not changed height.
+   changed height.
 
 If a computation of metrics has taken place, Force is removed from the
 flags and ForceDraw is added instead.
 
-It is OK to call processUpateFlags several times before an update. In
+It is OK to call processUpdateFlags several times before an update. In
 this case, the effects are cumulative. processUpdateFlags executes the
 metrics-related actions, but defers the actual drawing to the next
 paint event.
@@ -137,21 +148,32 @@ update flag is Update::None.
 
 ** Metrics computation (and nodraw drawing phase)
 
-This is triggered by bv::updateMetrics, which calls tm

[LyX/master] 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::

[LyX/master] Implement quick scroll

2024-04-05 Thread Jean-Marc Lasgouttes
commit 08010c6a5e425b3f2d0d625536e3a571c90a0482
Author: Jean-Marc Lasgouttes 
Date:   Mon Jul 24 23:23:40 2023 +0200

Implement quick scroll

Replace flag parameter for updateMetrics() by a `force' boolean. When
it is false, the method keeps the metrics of paragraphs that are still
visible in WorkArea instead of computing everything afresh. All it has
to do is update their positions.

Add code to updateMetrics() to update the value of the anchor pit/ypos
(similar to the one in draw()).

Update processUpdateFlags() to use this when update flag is ForceDraw.

Modify scrollDocView() to just change the anchor paragraph position
when the scrolling operation would re-use some of the existing
paragraphs.

The time needed to update the metrics when scrolling with mouse in the
branch-test.lyx document is now divided by 20!

Part of bug #12297.
---
 src/BufferView.cpp  | 102 ++--
 src/BufferView.h|  14 ++--
 src/TextMetrics.cpp |   6 
 src/TextMetrics.h   |   2 ++
 4 files changed, 86 insertions(+), 38 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index dd312739b5..ca3939aabf 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -545,10 +545,13 @@ void BufferView::processUpdateFlags(Update::flags flags)
 
// First check whether the metrics and inset positions should be updated
if (flags & Update::Force) {
-   // This will update the CoordCache items and replace Force
-   // with ForceDraw in flags.
-   updateMetrics(flags);
-   }
+   // This will compute all metrics and positions.
+   updateMetrics(true);
+   // metrics is done, full drawing is necessary now
+   flags = (flags & ~Update::Force) | Update::ForceDraw;
+   } else if (flags & Update::ForceDraw)
+   // This will compute only the needed metrics and update 
positions.
+   updateMetrics(false);
 
// Detect whether we can only repaint a single paragraph (if we
// are not already redrawing all).
@@ -557,7 +560,7 @@ void BufferView::processUpdateFlags(Update::flags flags)
if (!(flags & Update::ForceDraw)
&& (flags & Update::SinglePar)
&& !singleParUpdate())
-   updateMetrics(flags);
+   updateMetrics(true);
 
// Then make sure that the screen contains the cursor if needed
if (flags & Update::FitCursor) {
@@ -566,13 +569,13 @@ void BufferView::processUpdateFlags(Update::flags flags)
// (which is just the cursor when there is no selection)
scrollToCursor(d->cursor_.selectionBegin(), 
SCROLL_VISIBLE);
// Metrics have to be recomputed (maybe again)
-   updateMetrics();
+   updateMetrics(true);
// Is the cursor visible? (only useful if cursor is at 
end of selection)
if (needsFitCursor()) {
// then try to make cursor visible instead
scrollToCursor(d->cursor_, SCROLL_VISIBLE);
// Metrics have to be recomputed (maybe again)
-   updateMetrics(flags);
+   updateMetrics(true);
}
}
flags = flags & ~Update::FitCursor;
@@ -754,10 +757,13 @@ void BufferView::scrollDocView(int const pixels, bool 
update)
if (pixels == 0)
return;
 
-   // If the offset is less than 2 screen height, prefer to scroll instead.
-   if (abs(pixels) <= 2 * height_) {
+   // If part of the existing paragraphs will remain visible, prefer to
+   // scroll
+   TextMetrics const & tm = textMetrics(_.text());
+   if (tm.first().second->top() - pixels <= height_
+&&  tm.last().second->bottom() - pixels >= 0) {
d->anchor_ypos_ -= pixels;
-   processUpdateFlags(Update::Force);
+   processUpdateFlags(Update::ForceDraw);
return;
}
 
@@ -3110,12 +3116,14 @@ bool BufferView::singleParUpdate()
 
 void BufferView::updateMetrics()
 {
-   updateMetrics(d->update_flags_);
+   updateMetrics(true);
+   // metrics is done, full drawing is necessary now
+   d->update_flags_ = (d->update_flags_ & ~Update::Force) | 
Update::ForceDraw;
d->update_strategy_ = FullScreenUpdate;
 }
 
 
-void BufferView::updateMetrics(Update::flags & update_flags)
+void BufferView::updateMetrics(bool force)
 {
if (height_ == 0 || width_ == 0)
return;
@@ -3123,14 +3131,16 @@ void BufferView::updateMetrics(Updat

[LyX/master] Do not compute metrics at each preview when loading file

2024-04-05 Thread Jean-Marc Lasgouttes
commit 244969330108a89f4be93d3b2eb9024bdb756204
Author: Jean-Marc Lasgouttes 
Date:   Thu Dec 21 16:33:06 2023 +0100

Do not compute metrics at each preview when loading file

With the branch-test.lyx file from #12297, loading takes forever when
previews are activated. This is because each preview element causes a
full screen metrics recomputation.

This commit just skips these calls and only does one when all previews
have been obtained. As a result, computing the previews takes 1 second
instead of 25 seconds on branch-test.lyx.

Part of bug #12297.
---
 src/graphics/PreviewLoader.cpp | 12 
 1 file changed, 12 insertions(+)

diff --git a/src/graphics/PreviewLoader.cpp b/src/graphics/PreviewLoader.cpp
index 4c37f7a8d0..004ced6d89 100644
--- a/src/graphics/PreviewLoader.cpp
+++ b/src/graphics/PreviewLoader.cpp
@@ -787,6 +787,16 @@ void PreviewLoader::Impl::finishedGenerating(pid_t pid, 
int retval)
// Remove the item from the list of still-executing processes.
in_progress_.erase(git);
 
+#if 0
+   /* FIXME : there is no need for all these calls, which recompute
+* all metrics for each and every preview. The single call at the
+* end of this method is sufficient.
+
+* It seems that this whole imageReady mechanism is actually not
+* needed. If it is the case, the whole updateFrontend/updateInset
+* bloat can go too.
+*/
+
// Tell the outside world
list::const_reverse_iterator
nit  = newimages.rbegin();
@@ -795,6 +805,8 @@ void PreviewLoader::Impl::finishedGenerating(pid_t pid, int 
retval)
for (; nit != nend; ++nit) {
imageReady(*nit->get());
}
+#endif
+
finished_generating_ = true;
buffer_.scheduleRedrawWorkAreas();
 }
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Remove some redundant calls to updatePosCache

2024-04-05 Thread Jean-Marc Lasgouttes
commit d19ade9a611d3ecf6840c5eb43291cb268ad6f4f
Author: Jean-Marc Lasgouttes 
Date:   Mon Jul 24 15:35:16 2023 +0200

Remove some redundant calls to updatePosCache

The setting of insets positions was done twice in updateMetrics.
When one of the paragraph is a huge branch, this can be very expensive.

This leads to a 17% improvement on updateMetrics time on a scrolling test.

Part of bug #12297
---
 src/BufferView.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index fd61401dff..3612143019 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3161,7 +3161,6 @@ void BufferView::updateMetrics(Update::flags & 
update_flags)
}
}
anchor_pm.setPosition(d->anchor_ypos_);
-   tm.updatePosCache(d->anchor_pit_);
 
LYXERR(Debug::PAINTING, "metrics: "
<< " anchor pit = " << d->anchor_pit_
@@ -3177,7 +3176,6 @@ void BufferView::updateMetrics(Update::flags & 
update_flags)
y1 -= pm.descent();
// Save the paragraph position in the cache.
pm.setPosition(y1);
-   tm.updatePosCache(pit1);
y1 -= pm.ascent();
}
 
@@ -3191,7 +3189,6 @@ void BufferView::updateMetrics(Update::flags & 
update_flags)
y2 += pm.ascent();
// Save the paragraph position in the cache.
pm.setPosition(y2);
-   tm.updatePosCache(pit2);
y2 += pm.descent();
}
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Improve the code that limits scrolling at top/bottom

2024-04-05 Thread Jean-Marc Lasgouttes
commit f15d2ebf3819913114ab93d1ff7e140cb26b03d5
Author: Jean-Marc Lasgouttes 
Date:   Fri Nov 17 18:30:37 2023 +0100

Improve the code that limits scrolling at top/bottom

The most visible part of this commit is the move of part of
BufferView::updateMetrics to a new TextMetrics::updateMetrics. This
new method makes sure that metrics are known for all visible paragraphs
(starting from anchor), and that the positions of the paragraphs have
been recorded.

This method is called up to 3 times in BufferView::updateMetrics:
* unconditionally, to update all visible metrics,
* then, if the bottom of the document is visible and too high, after
  updating the anchor ypos,
* and similarly if the top of the document is visible and too low.

This fixes for example the case where one jumps to Section 5.3 at the
end of Tutorial and 'scroll_below_document' is false.

Some now redundant code is removed from BufferView::scrollToCursor.

The anchor-setting code in BufferView::draw is not clearly useful, but
left here just in case. It generates a debug warning, though.

Part of bug #12297.
---
 src/BufferView.cpp  | 99 ++---
 src/TextMetrics.cpp | 50 +++
 src/TextMetrics.h   |  4 +++
 3 files changed, 88 insertions(+), 65 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index ca3939aabf..f0e3704064 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -762,6 +762,7 @@ void BufferView::scrollDocView(int const pixels, bool 
update)
TextMetrics const & tm = textMetrics(_.text());
if (tm.first().second->top() - pixels <= height_
 &&  tm.last().second->bottom() - pixels >= 0) {
+   LYXERR(Debug::SCROLLING, "small skip");
d->anchor_ypos_ -= pixels;
processUpdateFlags(Update::ForceDraw);
return;
@@ -784,6 +785,7 @@ void BufferView::scrollDocView(int const pixels, bool 
update)
return;
}
 
+   LYXERR(Debug::SCROLLING, "search paragraph");
// find paragraph at target position
int par_pos = d->scrollbarParameters_.min;
pit_type i = 0;
@@ -1097,8 +1099,6 @@ bool BufferView::scrollToCursor(DocIterator const & dit, 
ScrollType how)
d->anchor_ypos_ = - offset + row_dim.ascent();
if (how == SCROLL_CENTER)
d->anchor_ypos_ += height_/2 - row_dim.height() / 2;
-   else if (!lyxrc.scroll_below_document && d->anchor_pit_ == max_pit)
-   d->anchor_ypos_ = height_ - offset - row_dim.descent();
else if (offset > height_)
d->anchor_ypos_ = height_ - offset - defaultRowHeight();
else
@@ -3129,7 +3129,7 @@ void BufferView::updateMetrics(bool force)
return;
 
Text & buftext = buffer_.text();
-   pit_type const npit = int(buftext.paragraphs().size());
+   pit_type const lastpit = int(buftext.paragraphs().size()) - 1;
 
if (force) {
// Clear out the position cache in case of full screen redraw,
@@ -3148,62 +3148,35 @@ void BufferView::updateMetrics(bool force)
if (d->inlineCompletionPos_.fixIfBroken())
d->inlineCompletionPos_ = DocIterator();
 
-   if (d->anchor_pit_ >= npit)
+   if (d->anchor_pit_ > lastpit)
// The anchor pit must have been deleted...
-   d->anchor_pit_ = npit - 1;
+   d->anchor_pit_ = lastpit;
 
-   if (!tm.contains(d->anchor_pit_))
-   // Rebreak anchor paragraph.
-   tm.redoParagraph(d->anchor_pit_);
-   ParagraphMetrics & anchor_pm = tm.parMetrics(d->anchor_pit_);
+   // Update metrics around the anchor
+   tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
 
-   // make sure than first paragraph of document is not too low
-   if (d->anchor_pit_ == 0) {
-   int scrollRange = d->scrollbarParameters_.max - 
d->scrollbarParameters_.min;
+   // Check that the end of the document is not too high
+   int const min_visible = lyxrc.scroll_below_document ? minVisiblePart() 
: height_;
+   if (tm.last().first == lastpit && tm.last().second->bottom() < 
min_visible) {
+   d->anchor_ypos_ += min_visible - tm.last().second->bottom();
+   LYXERR(Debug::SCROLLING, "Too high, adjusting anchor ypos to " 
<< d->anchor_ypos_);
+   tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
+   }
 
-   // Complete buffer visible? Then it's easy.
-   if (scrollRange == 0)
-   d->anchor_ypos_ = anchor_pm.ascent();
-   else {
-   // avoid empty 

[LyX/master] In the no-draw phase, do not cache the positions of not visible insets

2024-04-05 Thread Jean-Marc Lasgouttes
commit 7f85024f80601b15634fb5e771bba51435ad429f
Author: Jean-Marc Lasgouttes 
Date:   Mon Jul 24 17:53:16 2023 +0200

In the no-draw phase, do not cache the positions of not visible insets

This can make a big difference for a very large branch that contains
lots of equations.

This is complementary to the previous patch, since instead of reducing
the number of calls to updatePosCache, we make it faster.

In the same test of scrolling with mouse wheel through the
branch-test.lyx document, one finds a 23% improvement for
BufferView::updateMetrics().

Part of bug #12297.
---
 src/TextMetrics.cpp | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 6968279c23..06e00f4220 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -2000,6 +2000,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, 
pit_type const pit, int const
if (pm.rows().empty())
return;
size_t const nrows = pm.rows().size();
+   int const wh = bv_->workHeight();
// Remember left and right margin for drawing math numbers
Changer changeleft = changeVar(pi.leftx, x + leftMargin(pit));
Changer changeright = changeVar(pi.rightx, x + width() - 
rightMargin(pit));
@@ -2014,15 +2015,17 @@ void TextMetrics::drawParagraph(PainterInfo & pi, 
pit_type const pit, int const
if (i)
y += row.ascent();
 
-   RowPainter rp(pi, *text_, row, row_x, y);
-
-   rp.paintOnlyInsets();
+   // It is not needed to draw on screen if we are not 
inside
+   bool const inside = (y + row.descent() >= 0 && y - 
row.ascent() < wh);
+   if (inside) {
+   RowPainter rp(pi, *text_, row, row_x, y);
+   rp.paintOnlyInsets();
+   }
y += row.descent();
}
return;
}
 
-   int const ww = bv_->workHeight();
Cursor const & cur = bv_->cursor();
DocIterator sel_beg = cur.selectionBegin();
DocIterator sel_end = cur.selectionEnd();
@@ -2065,7 +2068,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, 
pit_type const pit, int const
 
// It is not needed to draw on screen if we are not inside.
bool const inside = (y + row.descent() >= 0
-   && y - row.ascent() < ww);
+   && y - row.ascent() < wh);
if (!inside) {
// Inset positions have already been set in nodraw 
stage.
y += row.descent();
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Introduce new helpers ParagraphMetrics::top/bottom

2024-04-05 Thread Jean-Marc Lasgouttes
commit 0b6105b9245350e428c73deee88af2cd7c0d4732
Author: Jean-Marc Lasgouttes 
Date:   Tue Jul 25 16:31:13 2023 +0200

Introduce new helpers ParagraphMetrics::top/bottom

This avoids code with position/ascent/descent that is difficult to follow.

No change in function intended.
---
 src/BufferView.cpp   | 18 --
 src/ParagraphMetrics.h   |  6 +-
 src/TextMetrics.cpp  | 20 ++--
 src/frontends/qt/GuiWorkArea.cpp |  2 +-
 4 files changed, 20 insertions(+), 26 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 3612143019..dd312739b5 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -641,8 +641,8 @@ void BufferView::updateScrollbarParameters()
<< d->par_height_[pit]);
}
 
-   int top_pos = first.second->position() - first.second->ascent();
-   int bottom_pos = last.second->position() + last.second->descent();
+   int top_pos = first.second->top();
+   int bottom_pos = last.second->bottom();
bool first_visible = first.first == 0 && top_pos >= 0;
bool last_visible = last.first + 1 == int(parsize) && bottom_pos <= 
height_;
if (first_visible && last_visible) {
@@ -2726,7 +2726,7 @@ int BufferView::scrollDown(int pixels)
int const ymax = height_ + pixels;
while (true) {
pair last = tm.last();
-   int bottom_pos = last.second->position() + 
last.second->descent();
+   int bottom_pos = last.second->bottom();
if (lyxrc.scroll_below_document)
bottom_pos += height_ - minVisiblePart();
if (last.first + 1 == int(text->paragraphs().size())) {
@@ -2751,7 +2751,7 @@ int BufferView::scrollUp(int pixels)
int ymin = - pixels;
while (true) {
pair first = tm.first();
-   int top_pos = first.second->position() - first.second->ascent();
+   int top_pos = first.second->top();
if (first.first == 0) {
if (top_pos >= 0)
return 0;
@@ -3102,10 +3102,8 @@ bool BufferView::singleParUpdate()
 
tm.updatePosCache(pit);
 
-   LYXERR(Debug::PAINTING, "\ny1: " << pm.position() - pm.ascent()
-   << " y2: " << pm.position() + pm.descent()
-   << " pit: " << pit
-   << " singlepar: 1");
+   LYXERR(Debug::PAINTING, "\ny1: " << pm.top() << " y2: " << pm.bottom()
+   << " pit: " << pit << " singlepar: 1");
return true;
 }
 
@@ -3653,7 +3651,7 @@ void BufferView::draw(frontend::Painter & pain, bool 
paint_caret)
 
// and possibly grey out below
pair lastpm = tm.last();
-   int const y2 = lastpm.second->position() + 
lastpm.second->descent();
+   int const y2 = lastpm.second->bottom();
 
if (y2 < height_) {
Color color = buffer().isInternal()
@@ -3674,7 +3672,7 @@ void BufferView::draw(frontend::Painter & pain, bool 
paint_caret)
pair lastpm = tm.last();
for (pit_type pit = firstpm.first; pit <= lastpm.first; ++pit) {
ParagraphMetrics const & pm = tm.parMetrics(pit);
-   if (pm.position() + pm.descent() > 0) {
+   if (pm.bottom() > 0) {
if (d->anchor_pit_ != pit
|| d->anchor_ypos_ != pm.position())
LYXERR(Debug::PAINTING, "Found new anchor pit = 
" << d->anchor_pit_
diff --git a/src/ParagraphMetrics.h b/src/ParagraphMetrics.h
index 0d186f158b..805d056541 100644
--- a/src/ParagraphMetrics.h
+++ b/src/ParagraphMetrics.h
@@ -69,9 +69,13 @@ public:
///
bool hfillExpansion(Row const & row, pos_type pos) const;
 
-   ///
+   /// The vertical position of the baseline of the first line of the 
paragraph
int position() const { return position_; }
void setPosition(int position);
+   /// The vertical position of the top of the paragraph
+   int top() const { return position_ - dim_.ascent(); }
+   /// The vertical position of the bottom of the paragraph
+   int bottom() const { return position_ + dim_.descent(); }
///
int id() const { return id_; }
 
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 06e00f4220..837ad5766f 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -191,8 +191,7 @@ void TextMetrics::newParMetricsDown()
 
// do it and update its position.
redoParagraph(pit);
-   par_metrics_[pit].setPosition(last.second.position()
-

[LyX/master] Enable Update::SinglePar in nested insets too

2024-04-05 Thread Jean-Marc Lasgouttes
commit 9a96726bcd06d565c3027011fea954656aa46668
Author: Jean-Marc Lasgouttes 
Date:   Mon Jul 17 14:43:29 2023 +0200

Enable Update::SinglePar in nested insets too

The idea of single par update is to try to re-break only the paragraph
containing the cursor (if this paragraph contains insets etc.,
re-breaking will recursively descend).

The existing single paragraph update mechanism was tailored to work
only at top level. Indeed changing a paragraph nested into an inset may
lead to larger changes.

This commit tries a rather naive approach that seems to work well: we
need a full redraw if either

1/ the height has changed
or
2/ the width has changed and it was equal to the text metrics width;
   the goal is to catch the case of a one-row inset that grows with
   its contents, but optimize the case of typing in a short paragraph
   part of a larger inset.

NOTE: if only the height has changed, then it should be
  possible to update all metrics at minimal cost. However,
  since this is risky, we do not try that right now.

Part of bug #12297.
---
 src/BufferView.cpp | 42 +++---
 1 file changed, 27 insertions(+), 15 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 39fffed68e..fd61401dff 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3063,24 +3063,36 @@ Cursor const & BufferView::cursor() const
 
 bool BufferView::singleParUpdate()
 {
-   Text & buftext = buffer_.text();
-   pit_type const bottom_pit = d->cursor_.bottom().pit();
-   TextMetrics & tm = textMetrics();
-   Dimension const old_dim = tm.parMetrics(bottom_pit).dim();
+   CursorSlice const & its = d->cursor_.innerTextSlice();
+   pit_type const pit = its.pit();
+   TextMetrics & tm = textMetrics(its.text());
+   Dimension const old_dim = tm.parMetrics(pit).dim();
 
// make sure inline completion pointer is ok
if (d->inlineCompletionPos_.fixIfBroken())
d->inlineCompletionPos_ = DocIterator();
 
-   // In Single Paragraph mode, rebreak only
-   // the (main text, not inset!) paragraph containing the cursor.
-   // (if this paragraph contains insets etc., rebreaking will
-   // recursively descend)
-   tm.redoParagraph(bottom_pit);
-   ParagraphMetrics & pm = tm.parMetrics(bottom_pit);
-   if (pm.height() != old_dim.height()) {
-   // Paragraph height has changed so we cannot proceed to
-   // the singlePar optimisation.
+   /* Try to rebreak only the paragraph containing the cursor (if
+* this paragraph contains insets etc., rebreaking will
+* recursively descend). We need a full redraw if either
+* 1/ the height has changed
+* or
+* 2/ the width has changed and it was equal to the textmetrics
+*width; the goal is to catch the case of a one-row inset that
+*grows with its contents, but optimize the case of typing at
+*the end of a mmultiple-row paragraph.
+*
+* NOTE: if only the height has changed, then it should be
+*   possible to update all metrics at minimal cost. However,
+*   since this is risky, we do not try that right now.
+*/
+   tm.redoParagraph(pit);
+   ParagraphMetrics & pm = tm.parMetrics(pit);
+   if (pm.height() != old_dim.height()
+   || (pm.width() != old_dim.width() && old_dim.width() == 
tm.width())) {
+   // Paragraph height or width has changed so we cannot proceed
+   // to the singlePar optimisation.
+   LYXERR(Debug::PAINTING, "SinglePar optimization failed.");
return false;
}
// Since position() points to the baseline of the first row, we
@@ -3088,11 +3100,11 @@ bool BufferView::singleParUpdate()
// the height does not change but the ascent does.
pm.setPosition(pm.position() - old_dim.ascent() + pm.ascent());
 
-   tm.updatePosCache(bottom_pit);
+   tm.updatePosCache(pit);
 
LYXERR(Debug::PAINTING, "\ny1: " << pm.position() - pm.ascent()
<< " y2: " << pm.position() + pm.descent()
-   << " pit: " << bottom_pit
+   << " pit: " << pit
<< " singlepar: 1");
return true;
 }
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Avoid full metrics computation when entering/leaving inset

2024-04-05 Thread Jean-Marc Lasgouttes
commit 73678dcde977802d5ff3ae07f0226484041fff48
Author: Jean-Marc Lasgouttes 
Date:   Mon Nov 27 15:57:09 2023 +0100

Avoid full metrics computation when entering/leaving inset

Annotate function LFUN_FINISHED_xxx to indicate that they do not
require a full metrics computation.

Remove an "optimization" that meant that when the cursor changed
inset, a full metrics computation was requested.

Part of bug #12297
---
 src/LyXAction.cpp |  8 
 src/Text.cpp  | 33 +
 2 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index b6bb52152c..ece248e61c 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -1655,7 +1655,7 @@ void LyXAction::init()
  * \li Notion: See also #LFUN_FINISHED_FORWARD.
  * \endvar
  */
-   { LFUN_FINISHED_BACKWARD, "", ReadOnly, Hidden },
+   { LFUN_FINISHED_BACKWARD, "", ReadOnly | NoUpdate, Hidden },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_FINISHED_FORWARD
@@ -1668,7 +1668,7 @@ void LyXAction::init()
back into the surrounding text.
  * \endvar
  */
-   { LFUN_FINISHED_FORWARD, "", ReadOnly, Hidden },
+   { LFUN_FINISHED_FORWARD, "", ReadOnly | NoUpdate, Hidden },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_FINISHED_LEFT
@@ -1676,7 +1676,7 @@ void LyXAction::init()
  * \li Notion: See also #LFUN_FINISHED_FORWARD.
  * \endvar
  */
-   { LFUN_FINISHED_LEFT, "", ReadOnly, Hidden },
+   { LFUN_FINISHED_LEFT, "", ReadOnly | NoUpdate, Hidden },
 
 
 /*!
@@ -1685,7 +1685,7 @@ void LyXAction::init()
  * \li Notion: See also #LFUN_FINISHED_FORWARD
  * \endvar
  */
-   { LFUN_FINISHED_RIGHT, "", ReadOnly, Hidden },
+   { LFUN_FINISHED_RIGHT, "", ReadOnly | NoUpdate, Hidden },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_FLEX_INSERT
diff --git a/src/Text.cpp b/src/Text.cpp
index 2684309dec..4749f36d2c 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -6393,23 +6393,24 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor);
return;
}
-   if (!needsUpdate
-   && () == ()
-   && oldTopSlice.idx() == cur.idx()
-   && !oldSelection // oldSelection is a backup of cur.selection() at 
the beginning of the function.
-   && !cur.selection())
-   // FIXME: it would be better if we could just do this
-   //
-   //if (cur.result().update() != Update::FitCursor)
-   //  cur.noScreenUpdate();
-   //
-   // But some LFUNs do not set Update::FitCursor when needed, so 
we
-   // do it for all. This is not very harmfull as FitCursor will 
provoke
-   // a full redraw only if needed but still, a proper review of 
all LFUN
-   // should be done and this needsUpdate boolean can then be 
removed.
-   cur.screenUpdateFlags(Update::FitCursor);
-   else
+   if (needsUpdate)
cur.screenUpdateFlags(Update::Force | Update::FitCursor);
+   else {
+   // oldSelection is a backup of cur.selection() at the beginning 
of the function.
+   if (!oldSelection && !cur.selection())
+   // FIXME: it would be better if we could just do this
+   //
+   //if (cur.result().update() != Update::FitCursor)
+   //  cur.noScreenUpdate();
+   //
+   // But some LFUNs do not set Update::FitCursor when 
needed, so we
+   // do it for all. This is not very harmfull as 
FitCursor will provoke
+   // a full redraw only if needed but still, a proper 
review of all LFUN
+   // should be done and this needsUpdate boolean can then 
be removed.
+   cur.screenUpdateFlags(Update::FitCursor);
+   else
+   cur.screenUpdateFlags(Update::ForceDraw | 
Update::FitCursor);
+   }
 }
 
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[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::

[LyX features/biginset] Update PAINTING_ANALYSIS

2024-04-05 Thread Jean-Marc Lasgouttes
commit a23522073c8bb2cd06ddc7cc564e9c78f868a86d
Author: Jean-Marc Lasgouttes 
Date:   Mon Nov 20 17:24:09 2023 +0100

Update PAINTING_ANALYSIS
---
 development/PAINTING_ANALYSIS | 62 +--
 1 file changed, 42 insertions(+), 20 deletions(-)

diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS
index a506371965..438d7ca9c3 100644
--- a/development/PAINTING_ANALYSIS
+++ b/development/PAINTING_ANALYSIS
@@ -3,7 +3,7 @@ Understanding the painting process
 
 This file tries to describe the state of the metrics/painting
 mechanism, and identify the improvements that could be made. The first
-section can be read alone, although the context for them is really
+sections can be read alone, although the context for them is really
 given in the following ones.
 
 Please keep this file up to date as the code evolves!!!
@@ -20,9 +20,10 @@ following section. Some actions are proposed.
 
 ** SinglePar update
 
-This flag only has an effect in the current BufferView and at
-top-level, but I think it is useful in other views too. Doing this
-will require some work on the update pipeline, though.
+This flag only has an effect in the current BufferView, but I think it
+is useful in other views too. Doing this will require some work on the
+update pipeline, though.
+
 
 ** Buffer::change issues
 
@@ -53,17 +54,16 @@ The global idea would be to extend FitCursor to cover also 
horizontal
 cursor.
 
 
-* Clean-up of drawing code
+* TODO Clean-up of drawing code
 
 ** Set Row::changed() in a finer way
 
 *** singleParUpdate
 
 When the height of the current paragraph changes, there is no need for
-a full screen update. Only the rows after the current one need to have
-their position recomputed.
+a full screen update (at top level, at least). Only the rows after the
+current one need to have their position recomputed.
 
-This is also true when scrolling (how to do that?)
 
 *** redoParagraph
 
@@ -71,13 +71,16 @@ It should be possible to check whether the new row is the 
same as the
 old one and keep its changed() status in this case. This would reduce
 a lot the amount of stuff to redraw.
 
+
 ** Put labels and friends in the Row as elements
 
 It should not be necessary to access the Paragraph object to draw.
 Adding the static elements to Row is a lot of work, but worth it IMO.
 
+
 ** When a paragraph ends with a newline, compute correctly the height of the 
extra row.
 
+
 ** Merging bv::updateMetrics and tm::metrics
 
 While the full metrics computation tries hard to limit the number of
@@ -89,6 +92,12 @@ insets. We should re-use the bv::updateMetrics logic:
 
 The difficulty for a tall table cell for example, is that it may be
 necessary to break the whole contents to know the width of the cell.
+Also, the anchor is relative to the outer paragraph, which means that
+for a very long inset it is necessary to rebreak until the contents
+that needs to be shown (to compute the heights).
+
+All in all, this is difficult to get right. This is less important now
+that SinglePar updates work in nested insets.
 
 
 * Description of current drawing mechanism
@@ -99,10 +108,12 @@ There are three parts to drawing the work area:
 
  + the metrics phase computes the size of insets and breaks the
paragraphs into rows. It stores the dimension of insets (both
-   normal and math) in bv::coordCache.
+   normal and math) in bv::coordCache and the vertical position of the
+   top-level paragraphs.
 
  + the nodraw drawing phase paints the screen (see below) with a null
-   painter. The only useful effect is to store the inset positions.
+   painter. The only useful effect is to store the positions of
+   visible insets.
 
  + an update() signal is sent. This in turn will trigger a paint
event, and the actual screen painting will happen then.
@@ -115,18 +126,18 @@ whether this is correct.
 
 Depending on the Update::flags passed to the method, it sets an update
 strategy in (NoScreenUpdate, SingleParUpdate, FullScreenUpdate,
-DecorationUpdate). It triggers a recomputation of the metrics when either:
+DecorationUpdate). It triggers a call to updateMetrics when either:
 
  + Update::Force has been specified
  + Update::FitCursor has been specified and there is a need to scroll
the display.
  + Update::SinglePar has been specified and the current paragraph has
-   not changed height.
+   changed height.
 
 If a computation of metrics has taken place, Force is removed from the
 flags and ForceDraw is added instead.
 
-It is OK to call processUpateFlags several times before an update. In
+It is OK to call processUpdateFlags several times before an update. In
 this case, the effects are cumulative. processUpdateFlags executes the
 metrics-related actions, but defers the actual drawing to the next
 paint event.
@@ -137,21 +148,32 @@ update flag is Update::None.
 
 ** Metrics computation (and nodraw drawing phase)
 
-This is triggered by bv::updateMetrics, which calls tm

[LyX features/biginset] Indicate that, by default, mouse LFUN do not require a metrics update

2024-04-05 Thread Jean-Marc Lasgouttes
commit 9fd397ac1cb8c97d9b3058a669a045db0cceee1c
Author: Jean-Marc Lasgouttes 
Date:   Mon Nov 27 17:50:40 2023 +0100

Indicate that, by default, mouse LFUN do not require a metrics update

This is done easily in LyXAction.cpp. Remember that, by default, each
function is supposed to request a full metrics computation.

Part of bug #12297.
---
 src/LyXAction.cpp | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index ece248e61c..0b3d0a25ad 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -3121,7 +3121,7 @@ void LyXAction::init()
  * \li Origin: Andre, 9 Aug 2002
  * \endvar
  */
-   { LFUN_MOUSE_DOUBLE, "", ReadOnly, Hidden },
+   { LFUN_MOUSE_DOUBLE, "", ReadOnly | NoUpdate, Hidden },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_MOUSE_MOTION
@@ -3131,7 +3131,7 @@ void LyXAction::init()
  * \li Origin: Andre, 9 Aug 2002
  * \endvar
  */
-   { LFUN_MOUSE_MOTION, "", ReadOnly | SingleParUpdate, Hidden },
+   { LFUN_MOUSE_MOTION, "", ReadOnly | NoUpdate, Hidden },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_MOUSE_PRESS
@@ -3141,7 +3141,7 @@ void LyXAction::init()
  * \li Origin: Andre, 9 Aug 2002
  * \endvar
  */
-   { LFUN_MOUSE_PRESS, "", ReadOnly, Hidden },
+   { LFUN_MOUSE_PRESS, "", ReadOnly | NoUpdate, Hidden },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_MOUSE_RELEASE
@@ -3151,7 +3151,7 @@ void LyXAction::init()
  * \li Origin: Andre, 9 Aug 2002
  * \endvar
  */
-   { LFUN_MOUSE_RELEASE, "", ReadOnly, Hidden },
+   { LFUN_MOUSE_RELEASE, "", ReadOnly | NoUpdate, Hidden },
 
 
 /*!
@@ -3162,7 +3162,7 @@ void LyXAction::init()
  * \li Origin: Andre, 9 Aug 2002
  * \endvar
  */
-   { LFUN_MOUSE_TRIPLE, "", ReadOnly, Hidden },
+   { LFUN_MOUSE_TRIPLE, "", ReadOnly | NoUpdate, Hidden },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_NEWLINE_INSERT
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Introduce new helpers ParagraphMetrics::top/bottom

2024-04-05 Thread Jean-Marc Lasgouttes
commit 0b6105b9245350e428c73deee88af2cd7c0d4732
Author: Jean-Marc Lasgouttes 
Date:   Tue Jul 25 16:31:13 2023 +0200

Introduce new helpers ParagraphMetrics::top/bottom

This avoids code with position/ascent/descent that is difficult to follow.

No change in function intended.
---
 src/BufferView.cpp   | 18 --
 src/ParagraphMetrics.h   |  6 +-
 src/TextMetrics.cpp  | 20 ++--
 src/frontends/qt/GuiWorkArea.cpp |  2 +-
 4 files changed, 20 insertions(+), 26 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 3612143019..dd312739b5 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -641,8 +641,8 @@ void BufferView::updateScrollbarParameters()
<< d->par_height_[pit]);
}
 
-   int top_pos = first.second->position() - first.second->ascent();
-   int bottom_pos = last.second->position() + last.second->descent();
+   int top_pos = first.second->top();
+   int bottom_pos = last.second->bottom();
bool first_visible = first.first == 0 && top_pos >= 0;
bool last_visible = last.first + 1 == int(parsize) && bottom_pos <= 
height_;
if (first_visible && last_visible) {
@@ -2726,7 +2726,7 @@ int BufferView::scrollDown(int pixels)
int const ymax = height_ + pixels;
while (true) {
pair last = tm.last();
-   int bottom_pos = last.second->position() + 
last.second->descent();
+   int bottom_pos = last.second->bottom();
if (lyxrc.scroll_below_document)
bottom_pos += height_ - minVisiblePart();
if (last.first + 1 == int(text->paragraphs().size())) {
@@ -2751,7 +2751,7 @@ int BufferView::scrollUp(int pixels)
int ymin = - pixels;
while (true) {
pair first = tm.first();
-   int top_pos = first.second->position() - first.second->ascent();
+   int top_pos = first.second->top();
if (first.first == 0) {
if (top_pos >= 0)
return 0;
@@ -3102,10 +3102,8 @@ bool BufferView::singleParUpdate()
 
tm.updatePosCache(pit);
 
-   LYXERR(Debug::PAINTING, "\ny1: " << pm.position() - pm.ascent()
-   << " y2: " << pm.position() + pm.descent()
-   << " pit: " << pit
-   << " singlepar: 1");
+   LYXERR(Debug::PAINTING, "\ny1: " << pm.top() << " y2: " << pm.bottom()
+   << " pit: " << pit << " singlepar: 1");
return true;
 }
 
@@ -3653,7 +3651,7 @@ void BufferView::draw(frontend::Painter & pain, bool 
paint_caret)
 
// and possibly grey out below
pair lastpm = tm.last();
-   int const y2 = lastpm.second->position() + 
lastpm.second->descent();
+   int const y2 = lastpm.second->bottom();
 
if (y2 < height_) {
Color color = buffer().isInternal()
@@ -3674,7 +3672,7 @@ void BufferView::draw(frontend::Painter & pain, bool 
paint_caret)
pair lastpm = tm.last();
for (pit_type pit = firstpm.first; pit <= lastpm.first; ++pit) {
ParagraphMetrics const & pm = tm.parMetrics(pit);
-   if (pm.position() + pm.descent() > 0) {
+   if (pm.bottom() > 0) {
if (d->anchor_pit_ != pit
|| d->anchor_ypos_ != pm.position())
LYXERR(Debug::PAINTING, "Found new anchor pit = 
" << d->anchor_pit_
diff --git a/src/ParagraphMetrics.h b/src/ParagraphMetrics.h
index 0d186f158b..805d056541 100644
--- a/src/ParagraphMetrics.h
+++ b/src/ParagraphMetrics.h
@@ -69,9 +69,13 @@ public:
///
bool hfillExpansion(Row const & row, pos_type pos) const;
 
-   ///
+   /// The vertical position of the baseline of the first line of the 
paragraph
int position() const { return position_; }
void setPosition(int position);
+   /// The vertical position of the top of the paragraph
+   int top() const { return position_ - dim_.ascent(); }
+   /// The vertical position of the bottom of the paragraph
+   int bottom() const { return position_ + dim_.descent(); }
///
int id() const { return id_; }
 
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 06e00f4220..837ad5766f 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -191,8 +191,7 @@ void TextMetrics::newParMetricsDown()
 
// do it and update its position.
redoParagraph(pit);
-   par_metrics_[pit].setPosition(last.second.position()
-

[LyX features/biginset] Improve the code that limits scrolling at top/bottom

2024-04-05 Thread Jean-Marc Lasgouttes
commit f15d2ebf3819913114ab93d1ff7e140cb26b03d5
Author: Jean-Marc Lasgouttes 
Date:   Fri Nov 17 18:30:37 2023 +0100

Improve the code that limits scrolling at top/bottom

The most visible part of this commit is the move of part of
BufferView::updateMetrics to a new TextMetrics::updateMetrics. This
new method makes sure that metrics are known for all visible paragraphs
(starting from anchor), and that the positions of the paragraphs have
been recorded.

This method is called up to 3 times in BufferView::updateMetrics:
* unconditionally, to update all visible metrics,
* then, if the bottom of the document is visible and too high, after
  updating the anchor ypos,
* and similarly if the top of the document is visible and too low.

This fixes for example the case where one jumps to Section 5.3 at the
end of Tutorial and 'scroll_below_document' is false.

Some now redundant code is removed from BufferView::scrollToCursor.

The anchor-setting code in BufferView::draw is not clearly useful, but
left here just in case. It generates a debug warning, though.

Part of bug #12297.
---
 src/BufferView.cpp  | 99 ++---
 src/TextMetrics.cpp | 50 +++
 src/TextMetrics.h   |  4 +++
 3 files changed, 88 insertions(+), 65 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index ca3939aabf..f0e3704064 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -762,6 +762,7 @@ void BufferView::scrollDocView(int const pixels, bool 
update)
TextMetrics const & tm = textMetrics(_.text());
if (tm.first().second->top() - pixels <= height_
 &&  tm.last().second->bottom() - pixels >= 0) {
+   LYXERR(Debug::SCROLLING, "small skip");
d->anchor_ypos_ -= pixels;
processUpdateFlags(Update::ForceDraw);
return;
@@ -784,6 +785,7 @@ void BufferView::scrollDocView(int const pixels, bool 
update)
return;
}
 
+   LYXERR(Debug::SCROLLING, "search paragraph");
// find paragraph at target position
int par_pos = d->scrollbarParameters_.min;
pit_type i = 0;
@@ -1097,8 +1099,6 @@ bool BufferView::scrollToCursor(DocIterator const & dit, 
ScrollType how)
d->anchor_ypos_ = - offset + row_dim.ascent();
if (how == SCROLL_CENTER)
d->anchor_ypos_ += height_/2 - row_dim.height() / 2;
-   else if (!lyxrc.scroll_below_document && d->anchor_pit_ == max_pit)
-   d->anchor_ypos_ = height_ - offset - row_dim.descent();
else if (offset > height_)
d->anchor_ypos_ = height_ - offset - defaultRowHeight();
else
@@ -3129,7 +3129,7 @@ void BufferView::updateMetrics(bool force)
return;
 
Text & buftext = buffer_.text();
-   pit_type const npit = int(buftext.paragraphs().size());
+   pit_type const lastpit = int(buftext.paragraphs().size()) - 1;
 
if (force) {
// Clear out the position cache in case of full screen redraw,
@@ -3148,62 +3148,35 @@ void BufferView::updateMetrics(bool force)
if (d->inlineCompletionPos_.fixIfBroken())
d->inlineCompletionPos_ = DocIterator();
 
-   if (d->anchor_pit_ >= npit)
+   if (d->anchor_pit_ > lastpit)
// The anchor pit must have been deleted...
-   d->anchor_pit_ = npit - 1;
+   d->anchor_pit_ = lastpit;
 
-   if (!tm.contains(d->anchor_pit_))
-   // Rebreak anchor paragraph.
-   tm.redoParagraph(d->anchor_pit_);
-   ParagraphMetrics & anchor_pm = tm.parMetrics(d->anchor_pit_);
+   // Update metrics around the anchor
+   tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
 
-   // make sure than first paragraph of document is not too low
-   if (d->anchor_pit_ == 0) {
-   int scrollRange = d->scrollbarParameters_.max - 
d->scrollbarParameters_.min;
+   // Check that the end of the document is not too high
+   int const min_visible = lyxrc.scroll_below_document ? minVisiblePart() 
: height_;
+   if (tm.last().first == lastpit && tm.last().second->bottom() < 
min_visible) {
+   d->anchor_ypos_ += min_visible - tm.last().second->bottom();
+   LYXERR(Debug::SCROLLING, "Too high, adjusting anchor ypos to " 
<< d->anchor_ypos_);
+   tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
+   }
 
-   // Complete buffer visible? Then it's easy.
-   if (scrollRange == 0)
-   d->anchor_ypos_ = anchor_pm.ascent();
-   else {
-   // avoid empty 

[LyX features/biginset] Avoid some full metrics computations related to math previews

2024-04-05 Thread Jean-Marc Lasgouttes
commit 5e8578837fea0321998eac04222102986261666d
Author: Jean-Marc Lasgouttes 
Date:   Mon Nov 27 15:13:56 2023 +0100

Avoid some full metrics computations related to math previews

When entering/leaving a math hull inset, a Update::Force flag was set,
in case the metrics of the inset would change because of a switch
between normal and preview representation.

When entering the inset, this code is now used only when the inset was
in preview mode.

In both cases, Update::Force is replaced with Update::SinglePar.

This requites in Text::dispatch to honor Update::SinglePar when it has
been set by some lfun, even when singleparupdate is false.

Part of bug #12297.
---
 src/Text.cpp |  2 +-
 src/mathed/InsetMathHull.cpp | 13 -
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/src/Text.cpp b/src/Text.cpp
index d5a1069fa1..2684309dec 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -6386,7 +6386,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 
// FIXME: the following code should go in favor of fine grained
// update flag treatment.
-   if (singleParUpdate) {
+   if (singleParUpdate || cur.result().screenUpdate() & Update::SinglePar) 
{
// Inserting characters does not change par height in general. 
So, try
// to update _only_ this paragraph. BufferView will detect if a 
full
// metrics update is needed anyway.
diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp
index 94d293870d..34c319ea5c 100644
--- a/src/mathed/InsetMathHull.cpp
+++ b/src/mathed/InsetMathHull.cpp
@@ -902,7 +902,7 @@ bool InsetMathHull::notifyCursorLeaves(Cursor const & old, 
Cursor & cur)
 {
if (RenderPreview::previewMath()) {
reloadPreview(old);
-   cur.screenUpdateFlags(Update::Force);
+   cur.screenUpdateFlags(Update::SinglePar);
}
return false;
 }
@@ -2273,14 +2273,17 @@ void InsetMathHull::handleFont2(Cursor & cur, docstring 
const & arg)
 
 void InsetMathHull::edit(Cursor & cur, bool front, EntryDirection entry_from)
 {
+   bool const has_preview = previewState(());
cur.push(*this);
bool enter_front = (entry_from == Inset::ENTRY_DIRECTION_LEFT ||
(entry_from == Inset::ENTRY_DIRECTION_IGNORE && front));
enter_front ? idxFirst(cur) : idxLast(cur);
-   // The inset formula dimension is not necessarily the same as the
-   // one of the instant preview image, so we have to indicate to the
-   // BufferView that a metrics update is needed.
-   cur.screenUpdateFlags(Update::Force);
+   if (has_preview) {
+   // The inset formula dimension is in general different from the
+   // one of the instant preview image, so we have to indicate to 
the
+   // BufferView that a metrics update is needed.
+   cur.screenUpdateFlags(Update::SinglePar);
+   }
 }
 
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Avoid metrics computation on resize when width did not change

2024-04-05 Thread Jean-Marc Lasgouttes
commit f7218cec188cad2dbf68de47ad4345fcddf1bdb8
Author: Jean-Marc Lasgouttes 
Date:   Mon Nov 27 11:46:52 2023 +0100

Avoid metrics computation on resize when width did not change

Entering a math inset triggers a work area reize because the math
toobars appear automatically. However, by default these toolbars are
at the bottom of the screen and their presence does not change the
typesetting of paragraphs. Therefore it is useful to avoid a call to
updateMetrics() in the case where the width of the work area did not
change.

Part of bug #12297.
---
 src/BufferView.cpp | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 34be860691..c03f928c4d 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -2484,14 +2484,16 @@ void BufferView::clearSelection()
 
 void BufferView::resize(int width, int height)
 {
-   // Update from work area
-   width_ = width;
height_ = height;
+   // Update metrics only if width has changed
+   if (width != width_) {
+   width_ = width;
 
-   // Clear the paragraph height cache.
-   d->par_height_.clear();
-   // Redo the metrics.
-   updateMetrics();
+   // Clear the paragraph height cache.
+   d->par_height_.clear();
+   // Redo the metrics.
+   updateMetrics();
+   }
 }
 
 
@@ -3131,6 +3133,8 @@ void BufferView::updateMetrics(bool force)
if (!ready())
return;
 
+   //LYXERR0("updateMetrics " << _v_(force));
+
Text & buftext = buffer_.text();
pit_type const lastpit = int(buftext.paragraphs().size()) - 1;
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Do not compute metrics at each preview when loading file

2024-04-05 Thread Jean-Marc Lasgouttes
commit 244969330108a89f4be93d3b2eb9024bdb756204
Author: Jean-Marc Lasgouttes 
Date:   Thu Dec 21 16:33:06 2023 +0100

Do not compute metrics at each preview when loading file

With the branch-test.lyx file from #12297, loading takes forever when
previews are activated. This is because each preview element causes a
full screen metrics recomputation.

This commit just skips these calls and only does one when all previews
have been obtained. As a result, computing the previews takes 1 second
instead of 25 seconds on branch-test.lyx.

Part of bug #12297.
---
 src/graphics/PreviewLoader.cpp | 12 
 1 file changed, 12 insertions(+)

diff --git a/src/graphics/PreviewLoader.cpp b/src/graphics/PreviewLoader.cpp
index 4c37f7a8d0..004ced6d89 100644
--- a/src/graphics/PreviewLoader.cpp
+++ b/src/graphics/PreviewLoader.cpp
@@ -787,6 +787,16 @@ void PreviewLoader::Impl::finishedGenerating(pid_t pid, 
int retval)
// Remove the item from the list of still-executing processes.
in_progress_.erase(git);
 
+#if 0
+   /* FIXME : there is no need for all these calls, which recompute
+* all metrics for each and every preview. The single call at the
+* end of this method is sufficient.
+
+* It seems that this whole imageReady mechanism is actually not
+* needed. If it is the case, the whole updateFrontend/updateInset
+* bloat can go too.
+*/
+
// Tell the outside world
list::const_reverse_iterator
nit  = newimages.rbegin();
@@ -795,6 +805,8 @@ void PreviewLoader::Impl::finishedGenerating(pid_t pid, int 
retval)
for (; nit != nend; ++nit) {
imageReady(*nit->get());
}
+#endif
+
finished_generating_ = true;
buffer_.scheduleRedrawWorkAreas();
 }
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Implement quick scroll

2024-04-05 Thread Jean-Marc Lasgouttes
commit 08010c6a5e425b3f2d0d625536e3a571c90a0482
Author: Jean-Marc Lasgouttes 
Date:   Mon Jul 24 23:23:40 2023 +0200

Implement quick scroll

Replace flag parameter for updateMetrics() by a `force' boolean. When
it is false, the method keeps the metrics of paragraphs that are still
visible in WorkArea instead of computing everything afresh. All it has
to do is update their positions.

Add code to updateMetrics() to update the value of the anchor pit/ypos
(similar to the one in draw()).

Update processUpdateFlags() to use this when update flag is ForceDraw.

Modify scrollDocView() to just change the anchor paragraph position
when the scrolling operation would re-use some of the existing
paragraphs.

The time needed to update the metrics when scrolling with mouse in the
branch-test.lyx document is now divided by 20!

Part of bug #12297.
---
 src/BufferView.cpp  | 102 ++--
 src/BufferView.h|  14 ++--
 src/TextMetrics.cpp |   6 
 src/TextMetrics.h   |   2 ++
 4 files changed, 86 insertions(+), 38 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index dd312739b5..ca3939aabf 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -545,10 +545,13 @@ void BufferView::processUpdateFlags(Update::flags flags)
 
// First check whether the metrics and inset positions should be updated
if (flags & Update::Force) {
-   // This will update the CoordCache items and replace Force
-   // with ForceDraw in flags.
-   updateMetrics(flags);
-   }
+   // This will compute all metrics and positions.
+   updateMetrics(true);
+   // metrics is done, full drawing is necessary now
+   flags = (flags & ~Update::Force) | Update::ForceDraw;
+   } else if (flags & Update::ForceDraw)
+   // This will compute only the needed metrics and update 
positions.
+   updateMetrics(false);
 
// Detect whether we can only repaint a single paragraph (if we
// are not already redrawing all).
@@ -557,7 +560,7 @@ void BufferView::processUpdateFlags(Update::flags flags)
if (!(flags & Update::ForceDraw)
&& (flags & Update::SinglePar)
&& !singleParUpdate())
-   updateMetrics(flags);
+   updateMetrics(true);
 
// Then make sure that the screen contains the cursor if needed
if (flags & Update::FitCursor) {
@@ -566,13 +569,13 @@ void BufferView::processUpdateFlags(Update::flags flags)
// (which is just the cursor when there is no selection)
scrollToCursor(d->cursor_.selectionBegin(), 
SCROLL_VISIBLE);
// Metrics have to be recomputed (maybe again)
-   updateMetrics();
+   updateMetrics(true);
// Is the cursor visible? (only useful if cursor is at 
end of selection)
if (needsFitCursor()) {
// then try to make cursor visible instead
scrollToCursor(d->cursor_, SCROLL_VISIBLE);
// Metrics have to be recomputed (maybe again)
-   updateMetrics(flags);
+   updateMetrics(true);
}
}
flags = flags & ~Update::FitCursor;
@@ -754,10 +757,13 @@ void BufferView::scrollDocView(int const pixels, bool 
update)
if (pixels == 0)
return;
 
-   // If the offset is less than 2 screen height, prefer to scroll instead.
-   if (abs(pixels) <= 2 * height_) {
+   // If part of the existing paragraphs will remain visible, prefer to
+   // scroll
+   TextMetrics const & tm = textMetrics(_.text());
+   if (tm.first().second->top() - pixels <= height_
+&&  tm.last().second->bottom() - pixels >= 0) {
d->anchor_ypos_ -= pixels;
-   processUpdateFlags(Update::Force);
+   processUpdateFlags(Update::ForceDraw);
return;
}
 
@@ -3110,12 +3116,14 @@ bool BufferView::singleParUpdate()
 
 void BufferView::updateMetrics()
 {
-   updateMetrics(d->update_flags_);
+   updateMetrics(true);
+   // metrics is done, full drawing is necessary now
+   d->update_flags_ = (d->update_flags_ & ~Update::Force) | 
Update::ForceDraw;
d->update_strategy_ = FullScreenUpdate;
 }
 
 
-void BufferView::updateMetrics(Update::flags & update_flags)
+void BufferView::updateMetrics(bool force)
 {
if (height_ == 0 || width_ == 0)
return;
@@ -3123,14 +3131,16 @@ void BufferView::updateMetrics(Updat

[LyX features/biginset] In the no-draw phase, do not cache the positions of not visible insets

2024-04-05 Thread Jean-Marc Lasgouttes
commit 7f85024f80601b15634fb5e771bba51435ad429f
Author: Jean-Marc Lasgouttes 
Date:   Mon Jul 24 17:53:16 2023 +0200

In the no-draw phase, do not cache the positions of not visible insets

This can make a big difference for a very large branch that contains
lots of equations.

This is complementary to the previous patch, since instead of reducing
the number of calls to updatePosCache, we make it faster.

In the same test of scrolling with mouse wheel through the
branch-test.lyx document, one finds a 23% improvement for
BufferView::updateMetrics().

Part of bug #12297.
---
 src/TextMetrics.cpp | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 6968279c23..06e00f4220 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -2000,6 +2000,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, 
pit_type const pit, int const
if (pm.rows().empty())
return;
size_t const nrows = pm.rows().size();
+   int const wh = bv_->workHeight();
// Remember left and right margin for drawing math numbers
Changer changeleft = changeVar(pi.leftx, x + leftMargin(pit));
Changer changeright = changeVar(pi.rightx, x + width() - 
rightMargin(pit));
@@ -2014,15 +2015,17 @@ void TextMetrics::drawParagraph(PainterInfo & pi, 
pit_type const pit, int const
if (i)
y += row.ascent();
 
-   RowPainter rp(pi, *text_, row, row_x, y);
-
-   rp.paintOnlyInsets();
+   // It is not needed to draw on screen if we are not 
inside
+   bool const inside = (y + row.descent() >= 0 && y - 
row.ascent() < wh);
+   if (inside) {
+   RowPainter rp(pi, *text_, row, row_x, y);
+   rp.paintOnlyInsets();
+   }
y += row.descent();
}
return;
}
 
-   int const ww = bv_->workHeight();
Cursor const & cur = bv_->cursor();
DocIterator sel_beg = cur.selectionBegin();
DocIterator sel_end = cur.selectionEnd();
@@ -2065,7 +2068,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, 
pit_type const pit, int const
 
// It is not needed to draw on screen if we are not inside.
bool const inside = (y + row.descent() >= 0
-   && y - row.ascent() < ww);
+   && y - row.ascent() < wh);
if (!inside) {
// Inset positions have already been set in nodraw 
stage.
y += row.descent();
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Implement undo coalescing

2024-04-05 Thread Jean-Marc Lasgouttes
commit f5bbadbad92d55d480ea8b20c1e29f9ffe4ca224
Author: Jean-Marc Lasgouttes 
Date:   Thu Jul 14 01:02:28 2022 +0200

Implement undo coalescing

if the undo element we want to add only changes stuff that was already
modified by the previous one on undo stack (in the same group), then
skip it. There is nothing to gain in adding it to the stack.

The typical use case is when doing a search and replace in a large
document that does many replacements in each paragraph. In this case,
the same paragraph would be stored repeatedly.

Fixes bug #12564.
---
 src/Undo.cpp | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/Undo.cpp b/src/Undo.cpp
index 4e970df5a0..ddc7025e1c 100644
--- a/src/Undo.cpp
+++ b/src/Undo.cpp
@@ -312,12 +312,29 @@ void Undo::Private::doRecordUndo(UndoKind kind,
 
if (first_pit > last_pit)
swap(first_pit, last_pit);
+   pit_type const from = first_pit;
+   pit_type const end = cell.lastpit() - last_pit;
+
+   /* Undo coalescing: if the undo element we want to add only
+* changes stuff that was already modified by the previous one on
+* undo stack (in the same group), then skip it. There is nothing
+* to gain in adding it to the stack. The code below works for
+* both texted and mathed.
+   */
+   if (!stack.empty()
+   && stack.top().group_id == group_id_
+   && !stack.top().bparams
+   && samePar(stack.top().cell, cell)
+   //&& stack.top().kind == kind // needed?
+   && stack.top().from <= from
+   && stack.top().end >= end) {
+   LYXERR(Debug::UNDO, "Undo coalescing: skip entry");
+   return;
+   }
 
// Undo::ATOMIC are always recorded (no overlapping there).
// As nobody wants all removed character appear one by one when undoing,
// we want combine 'similar' non-ATOMIC undo recordings to one.
-   pit_type from = first_pit;
-   pit_type end = cell.lastpit() - last_pit;
if (!undo_finished_
&& kind != ATOMIC_UNDO
&& !stack.empty()
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Enable Update::SinglePar in nested insets too

2024-04-05 Thread Jean-Marc Lasgouttes
commit 9a96726bcd06d565c3027011fea954656aa46668
Author: Jean-Marc Lasgouttes 
Date:   Mon Jul 17 14:43:29 2023 +0200

Enable Update::SinglePar in nested insets too

The idea of single par update is to try to re-break only the paragraph
containing the cursor (if this paragraph contains insets etc.,
re-breaking will recursively descend).

The existing single paragraph update mechanism was tailored to work
only at top level. Indeed changing a paragraph nested into an inset may
lead to larger changes.

This commit tries a rather naive approach that seems to work well: we
need a full redraw if either

1/ the height has changed
or
2/ the width has changed and it was equal to the text metrics width;
   the goal is to catch the case of a one-row inset that grows with
   its contents, but optimize the case of typing in a short paragraph
   part of a larger inset.

NOTE: if only the height has changed, then it should be
  possible to update all metrics at minimal cost. However,
  since this is risky, we do not try that right now.

Part of bug #12297.
---
 src/BufferView.cpp | 42 +++---
 1 file changed, 27 insertions(+), 15 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 39fffed68e..fd61401dff 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3063,24 +3063,36 @@ Cursor const & BufferView::cursor() const
 
 bool BufferView::singleParUpdate()
 {
-   Text & buftext = buffer_.text();
-   pit_type const bottom_pit = d->cursor_.bottom().pit();
-   TextMetrics & tm = textMetrics();
-   Dimension const old_dim = tm.parMetrics(bottom_pit).dim();
+   CursorSlice const & its = d->cursor_.innerTextSlice();
+   pit_type const pit = its.pit();
+   TextMetrics & tm = textMetrics(its.text());
+   Dimension const old_dim = tm.parMetrics(pit).dim();
 
// make sure inline completion pointer is ok
if (d->inlineCompletionPos_.fixIfBroken())
d->inlineCompletionPos_ = DocIterator();
 
-   // In Single Paragraph mode, rebreak only
-   // the (main text, not inset!) paragraph containing the cursor.
-   // (if this paragraph contains insets etc., rebreaking will
-   // recursively descend)
-   tm.redoParagraph(bottom_pit);
-   ParagraphMetrics & pm = tm.parMetrics(bottom_pit);
-   if (pm.height() != old_dim.height()) {
-   // Paragraph height has changed so we cannot proceed to
-   // the singlePar optimisation.
+   /* Try to rebreak only the paragraph containing the cursor (if
+* this paragraph contains insets etc., rebreaking will
+* recursively descend). We need a full redraw if either
+* 1/ the height has changed
+* or
+* 2/ the width has changed and it was equal to the textmetrics
+*width; the goal is to catch the case of a one-row inset that
+*grows with its contents, but optimize the case of typing at
+*the end of a mmultiple-row paragraph.
+*
+* NOTE: if only the height has changed, then it should be
+*   possible to update all metrics at minimal cost. However,
+*   since this is risky, we do not try that right now.
+*/
+   tm.redoParagraph(pit);
+   ParagraphMetrics & pm = tm.parMetrics(pit);
+   if (pm.height() != old_dim.height()
+   || (pm.width() != old_dim.width() && old_dim.width() == 
tm.width())) {
+   // Paragraph height or width has changed so we cannot proceed
+   // to the singlePar optimisation.
+   LYXERR(Debug::PAINTING, "SinglePar optimization failed.");
return false;
}
// Since position() points to the baseline of the first row, we
@@ -3088,11 +3100,11 @@ bool BufferView::singleParUpdate()
// the height does not change but the ascent does.
pm.setPosition(pm.position() - old_dim.ascent() + pm.ascent());
 
-   tm.updatePosCache(bottom_pit);
+   tm.updatePosCache(pit);
 
LYXERR(Debug::PAINTING, "\ny1: " << pm.position() - pm.ascent()
<< " y2: " << pm.position() + pm.descent()
-   << " pit: " << bottom_pit
+   << " pit: " << pit
<< " singlepar: 1");
return true;
 }
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Remove some redundant calls to updatePosCache

2024-04-05 Thread Jean-Marc Lasgouttes
commit d19ade9a611d3ecf6840c5eb43291cb268ad6f4f
Author: Jean-Marc Lasgouttes 
Date:   Mon Jul 24 15:35:16 2023 +0200

Remove some redundant calls to updatePosCache

The setting of insets positions was done twice in updateMetrics.
When one of the paragraph is a huge branch, this can be very expensive.

This leads to a 17% improvement on updateMetrics time on a scrolling test.

Part of bug #12297
---
 src/BufferView.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index fd61401dff..3612143019 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3161,7 +3161,6 @@ void BufferView::updateMetrics(Update::flags & 
update_flags)
}
}
anchor_pm.setPosition(d->anchor_ypos_);
-   tm.updatePosCache(d->anchor_pit_);
 
LYXERR(Debug::PAINTING, "metrics: "
<< " anchor pit = " << d->anchor_pit_
@@ -3177,7 +3176,6 @@ void BufferView::updateMetrics(Update::flags & 
update_flags)
y1 -= pm.descent();
// Save the paragraph position in the cache.
pm.setPosition(y1);
-   tm.updatePosCache(pit1);
y1 -= pm.ascent();
}
 
@@ -3191,7 +3189,6 @@ void BufferView::updateMetrics(Update::flags & 
update_flags)
y2 += pm.ascent();
// Save the paragraph position in the cache.
pm.setPosition(y2);
-   tm.updatePosCache(pit2);
y2 += pm.descent();
}
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Do not include in InsetInfo.h

2024-04-05 Thread Jean-Marc Lasgouttes
commit 51562ff37732f4949441bd8c2b55692b0719093a
Author: Jean-Marc Lasgouttes 
Date:   Thu Apr 4 17:35:54 2024 +0200

Do not include  in InsetInfo.h

This is used by getDate/getTime, which actually should not be
InsetInfoParams methods, but functions in anonymous namespace.
---
 src/frontends/qt/GuiInfo.cpp |  1 +
 src/insets/InsetInfo.cpp | 42 +-
 src/insets/InsetInfo.h   |  5 -
 3 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/src/frontends/qt/GuiInfo.cpp b/src/frontends/qt/GuiInfo.cpp
index 5ba0b19b46..232697fa5c 100644
--- a/src/frontends/qt/GuiInfo.cpp
+++ b/src/frontends/qt/GuiInfo.cpp
@@ -31,6 +31,7 @@
 #include "support/gettext.h"
 #include "support/lstrings.h"
 
+#include 
 
 using namespace std;
 using namespace lyx::support;
diff --git a/src/insets/InsetInfo.cpp b/src/insets/InsetInfo.cpp
index 3048456e84..df83f96b98 100644
--- a/src/insets/InsetInfo.cpp
+++ b/src/insets/InsetInfo.cpp
@@ -180,10 +180,9 @@ bool translateString(docstring const & in, docstring & 
out, string const & lcode
out = translateIfPossible(in, lcode);
return in != out;
 }
-} // namespace anon
 
 
-docstring InsetInfoParams::getDate(string const & iname, QDate const date) 
const
+docstring getDate(string const & iname, QDate const date, Language const * 
lang)
 {
QLocale loc;
if (lang)
@@ -208,7 +207,7 @@ docstring InsetInfoParams::getDate(string const & iname, 
QDate const date) const
 }
 
 
-docstring InsetInfoParams::getTime(string const & iname, QTime const time) 
const
+docstring getTime(string const & iname, QTime const time, Language const * 
lang)
 {
QLocale loc;
if (lang)
@@ -222,6 +221,7 @@ docstring InsetInfoParams::getTime(string const & iname, 
QTime const time) const
else
return qstring_to_ucs4(loc.toString(time, toqstr(iname)));
 }
+} // namespace anon
 
 
 vector> InsetInfoParams::getArguments(Buffer const * 
buf,
@@ -313,17 +313,17 @@ vector> 
InsetInfoParams::getArguments(Buffer const * buf,
date = (gdate.isValid()) ? gdate : QDate::currentDate();
} else
date = QDate::currentDate();
-   result.push_back(make_pair("long",getDate("long", date)));
-   result.push_back(make_pair("short", getDate("short", date)));
-   result.push_back(make_pair("loclong", getDate("loclong", 
date)));
-   result.push_back(make_pair("locmedium", getDate("locmedium", 
date)));
-   result.push_back(make_pair("locshort", getDate("locshort", 
date)));
-   result.push_back(make_pair("ISO", getDate("ISO", date)));
-   result.push_back(make_pair("", getDate("", date)));
-   result.push_back(make_pair("", getDate("", date)));
-   result.push_back(make_pair("MMM", getDate("MMM", date)));
-   result.push_back(make_pair("", getDate("", date)));
-   result.push_back(make_pair("ddd", getDate("ddd", date)));
+   result.push_back(make_pair("long",getDate("long", date, lang)));
+   result.push_back(make_pair("short", getDate("short", date, 
lang)));
+   result.push_back(make_pair("loclong", getDate("loclong", date, 
lang)));
+   result.push_back(make_pair("locmedium", getDate("locmedium", 
date, lang)));
+   result.push_back(make_pair("locshort", getDate("locshort", 
date, lang)));
+   result.push_back(make_pair("ISO", getDate("ISO", date, lang)));
+   result.push_back(make_pair("", getDate("", date, 
lang)));
+   result.push_back(make_pair("", getDate("", date, 
lang)));
+   result.push_back(make_pair("MMM", getDate("MMM", date, lang)));
+   result.push_back(make_pair("", getDate("", date, 
lang)));
+   result.push_back(make_pair("ddd", getDate("ddd", date, lang)));
result.push_back(make_pair("custom", _("Custom")));
break;
}
@@ -344,9 +344,9 @@ vector> 
InsetInfoParams::getArguments(Buffer const * buf,
time = (gtime.isValid()) ? gtime : QTime::currentTime();
} else
time = QTime::currentTime();
-   result.push_back(make_pair("long",getTime("long", time))

[LyX features/biginset] fix typo in fr/Intro.lyx

2024-04-05 Thread Jean-Marc Lasgouttes
commit b28655e91ec64b7fb063d8bfea548f82d5d4cc5b
Author: Jean-Marc Lasgouttes 
Date:   Thu Apr 4 17:16:06 2024 +0200

fix typo in fr/Intro.lyx
---
 lib/doc/fr/Intro.lyx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/doc/fr/Intro.lyx b/lib/doc/fr/Intro.lyx
index 86bb5fabde..013f4fa0dd 100644
--- a/lib/doc/fr/Intro.lyx
+++ b/lib/doc/fr/Intro.lyx
@@ -288,7 +288,7 @@ Qu'est-ce que \SpecialChar LyX
  des articles dans des publications scientifiques,
  des scripts pour des pièces de théâtre ou des films,
  des propositions de contrats,
- des )présentations\SpecialChar ldots
+ des présentations\SpecialChar ldots
 
 \end_layout
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Compilation fix with Qt < 5.7

2024-04-05 Thread Jean-Marc Lasgouttes
commit 6260689fd552a5e83d2970dcfd4d5ba7e09443e7
Author: Jean-Marc Lasgouttes 
Date:   Wed Apr 3 12:39:09 2024 +0200

Compilation fix with Qt < 5.7

Qt::ImAnchorRectangle has only been introduced in Qt 5.7. Since it is
used to answer a query from the IM machinery, there is no need for
it with older Qt versions.
---
 src/frontends/qt/GuiWorkArea.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp
index a4b874097c..341fddc3b8 100644
--- a/src/frontends/qt/GuiWorkArea.cpp
+++ b/src/frontends/qt/GuiWorkArea.cpp
@@ -1422,10 +1422,12 @@ QVariant 
GuiWorkArea::inputMethodQuery(Qt::InputMethodQuery query) const
return QVariant(d->im_cursor_rect_);
break;
}
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
case Qt::ImAnchorRectangle: {
return QVariant(d->im_anchor_rect_);
break;
}
+#endif
default:
return QWidget::inputMethodQuery(query);
}
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Typo in doc

2024-04-05 Thread Jean-Marc Lasgouttes
commit 43b1234a98c645bee29e3c9bcca9e4c1bcc46d22
Author: Jean-Marc Lasgouttes 
Date:   Mon Mar 25 22:32:17 2024 +0100

Typo in doc

Thanks to Peter J. Puchyr for noticing it.
---
 lib/doc/LaTeXConfig.lyx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/doc/LaTeXConfig.lyx b/lib/doc/LaTeXConfig.lyx
index 52d3ab0a14..0cc3257704 100644
--- a/lib/doc/LaTeXConfig.lyx
+++ b/lib/doc/LaTeXConfig.lyx
@@ -7834,7 +7834,7 @@ Notes:
 \family sans
 enumitem
 \family default
- provides many possibilities to tweak the appaerance of lists (enumerate,
+ provides many possibilities to tweak the appearance of lists (enumerate,
  itemize,
  description).
  It is used by the Linguistics module to fine tune the appearance of numbered 
subexamples.
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] Fix display of a math hull inset in a tight inset

2024-04-05 Thread Jean-Marc Lasgouttes
commit 4dfebbe9da27ff500b8245858322f1baeb00100b
Author: Jean-Marc Lasgouttes 
Date:   Fri Jul 14 02:13:18 2023 +0200

Fix display of a math hull inset in a tight inset

This is a kind of hack. This allows InsetMathHull to state that it
needs some elbow room beyond its width, in order to fit the numbering
and/or the left margin (with left alignment), which are outside of the
inset itself.

To this end, InsetMathHull::metrics() sets a value in
MetricsInfo::extrawidth and this value is added later to the width of
the row that contains the inset (when this row is tight or shorter
than the max allowed width).

Fixes bug #12320.
---
 src/MetricsInfo.cpp  |  3 ++-
 src/MetricsInfo.h|  2 ++
 src/TextMetrics.cpp  | 21 +
 src/mathed/InsetMathHull.cpp |  9 +++--
 4 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/src/MetricsInfo.cpp b/src/MetricsInfo.cpp
index d663c9a77d..844c1c13f3 100644
--- a/src/MetricsInfo.cpp
+++ b/src/MetricsInfo.cpp
@@ -152,7 +152,8 @@ int MetricsBase::inPixels(Length const & len) const
 
 MetricsInfo::MetricsInfo(BufferView * bv, FontInfo font, int textwidth,
  MacroContext const & mc, bool vm, bool tight)
-   : base(bv, font, textwidth), macrocontext(mc), vmode(vm), 
tight_insets(tight)
+   : base(bv, font, textwidth), macrocontext(mc), vmode(vm), 
tight_insets(tight),
+ extrawidth(0)
 {}
 
 
diff --git a/src/MetricsInfo.h b/src/MetricsInfo.h
index 176eabfea8..6f1d404822 100644
--- a/src/MetricsInfo.h
+++ b/src/MetricsInfo.h
@@ -109,6 +109,8 @@ public:
bool vmode;
/// if true, do not expand insets to max width artificially
bool tight_insets;
+   /// Extra width required by an inset, in addition to its dimension
+   int extrawidth;
 };
 
 
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 4692918e8e..6968279c23 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -485,6 +485,7 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool 
const align_rows)
par.setBeginOfBody();
Font const bufferfont = buffer.params().getFont();
CoordCache::Insets & insetCache = bv_->coordCache().insets();
+   map  extrawidths;
for (auto const & e : par.insetList()) {
// FIXME Doesn't this HAVE to be non-empty?
// position already initialized?
@@ -521,6 +522,20 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool 
const align_rows)
MetricsInfo mi(bv_, font.fontInfo(), w, mc, e.pos == 0, tight_);
mi.base.outer_font = displayFont(pit, e.pos).fontInfo();
e.inset->metrics(mi, dim);
+   /* FIXME: This is a hack. This allows InsetMathHull to state
+* that it needs some elbow room beyond its width, in order to
+* fit the numbering and/or the left margin (with left
+* alignment), which are outside of the inset itself.
+*
+* To this end, InsetMathHull::metrics() sets a value in
+* MetricsInfo::extrawidth and this value is added later to
+* the width of the row that contains the inset (when this row
+* is tight or shorter than the max allowed width).
+*
+* See ticket #12320 for details.
+   */
+   extrawidths[e.inset] = mi.extrawidth;
+
if (!insetCache.has(e.inset) || insetCache.dim(e.inset) != dim) 
{
insetCache.add(e.inset, dim);
changed = true;
@@ -532,6 +547,12 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool 
const align_rows)
// Split the row in several rows fitting in available width
pm.rows() = breakParagraph(bigrow);
 
+   // Add the needed extra width to the rows that contain the insets that 
request it
+   for (Row & row : pm.rows())
+   for (Row::Element & e : row)
+   if (e.type == Row::INSET && (row.width() < max_width_ 
|| tight_))
+   row.dim().wid += extrawidths[e.inset];
+
/* If there is more than one row, expand the text to the full
 * allowable width. This setting here is needed for the
 * setRowAlignment() below. We do nothing when tight insets are
diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp
index 30ec93a14f..94d293870d 100644
--- a/src/mathed/InsetMathHull.cpp
+++ b/src/mathed/InsetMathHull.cpp
@@ -523,6 +523,9 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & 
dim) const
if (mi.vmode)
top_display_margin += theFontMetrics(mi.base.font).maxHeight() 
+ 2;
 
+   int const ind = indent(*mi.base.bv);
+   mi.extrawidth = ind;
+
if (previewState(mi.base

[LyX features/biginset] Revert "Fix display of a math hull inset in a tight inset"

2024-04-05 Thread Jean-Marc Lasgouttes
commit 6d62d8009f3c41874cf84aa6577aae3293ebb5e6
Author: Jean-Marc Lasgouttes 
Date:   Fri Mar 22 15:08:26 2024 +0100

Revert "Fix display of a math hull inset in a tight inset"

This commit will be replaed by a better solution.

Part of ticket #12320.

This reverts commit 4bbd4a45e7494363903801540102150886fa2c6b.
---
 src/MetricsInfo.cpp  |  3 +--
 src/MetricsInfo.h|  2 --
 src/Row.cpp  |  5 ++---
 src/RowPainter.cpp   |  9 ++---
 src/TextMetrics.cpp  | 18 +-
 src/mathed/InsetMathHull.cpp |  9 ++---
 6 files changed, 8 insertions(+), 38 deletions(-)

diff --git a/src/MetricsInfo.cpp b/src/MetricsInfo.cpp
index 844c1c13f3..d663c9a77d 100644
--- a/src/MetricsInfo.cpp
+++ b/src/MetricsInfo.cpp
@@ -152,8 +152,7 @@ int MetricsBase::inPixels(Length const & len) const
 
 MetricsInfo::MetricsInfo(BufferView * bv, FontInfo font, int textwidth,
  MacroContext const & mc, bool vm, bool tight)
-   : base(bv, font, textwidth), macrocontext(mc), vmode(vm), 
tight_insets(tight),
- extrawidth(0)
+   : base(bv, font, textwidth), macrocontext(mc), vmode(vm), 
tight_insets(tight)
 {}
 
 
diff --git a/src/MetricsInfo.h b/src/MetricsInfo.h
index 6f1d404822..176eabfea8 100644
--- a/src/MetricsInfo.h
+++ b/src/MetricsInfo.h
@@ -109,8 +109,6 @@ public:
bool vmode;
/// if true, do not expand insets to max width artificially
bool tight_insets;
-   /// Extra width required by an inset, in addition to its dimension
-   int extrawidth;
 };
 
 
diff --git a/src/Row.cpp b/src/Row.cpp
index 86b4e5014c..b85ef3d18b 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -510,15 +510,14 @@ void Row::addMarginSpace(pos_type const pos, int const 
width,
 
 void Row::push_back(Row::Element const & e)
 {
-   dim_.wid += e.dim.wid + ((e.type == INSET) ? e.extra : 0);
+   dim_.wid += e.dim.wid;
elements_.push_back(e);
 }
 
 
 void Row::pop_back()
 {
-   Element const & e = elements_.back();
-   dim_.wid -= e.dim.wid + ((e.type == INSET) ? e.extra : 0);
+   dim_.wid -= elements_.back().dim.wid;
elements_.pop_back();
 }
 
diff --git a/src/RowPainter.cpp b/src/RowPainter.cpp
index d893fd01eb..77e0ff67e6 100644
--- a/src/RowPainter.cpp
+++ b/src/RowPainter.cpp
@@ -100,7 +100,6 @@ void RowPainter::paintInset(Row::Element const & e) const
bool const pi_full_repaint = pi_.full_repaint;
bool const pi_do_spellcheck = pi_.do_spellcheck;
Change const pi_change = pi_.change;
-   int const pi_textwidth = pi_.base.textwidth;
 
pi_.base.font = e.inset->inheritFont() ? e.font.fontInfo() :
pi_.base.bv->buffer().params().getFont().fontInfo();
@@ -108,7 +107,6 @@ void RowPainter::paintInset(Row::Element const & e) const
pi_.ltr_pos = !e.font.isVisibleRightToLeft();
pi_.change = pi_.change.changed() ? pi_.change : e.change;
pi_.do_spellcheck &= e.inset->allowSpellCheck();
-   pi_.base.textwidth += e.extra;
 
int const x1 = int(x_);
pi_.base.bv->coordCache().insets().add(e.inset, x1, yo_);
@@ -125,7 +123,6 @@ void RowPainter::paintInset(Row::Element const & e) const
pi_.change = pi_change;
pi_.do_spellcheck = pi_do_spellcheck;
pi_.selected = pi_selected;
-   pi_.base.textwidth = pi_textwidth;
 
 #ifdef DEBUG_METRICS
Dimension const & dim = pi_.base.bv->coordCache().insets().dim(e.inset);
@@ -559,8 +556,7 @@ void RowPainter::paintOnlyInsets()
paintChange(e);
}
 
-   // extra is the extrawidth band-aid described in redoParagraphs
-   x_ +=  e.full_width() + ((e.type == Row::INSET) ? e.extra : 0);
+   x_ += e.full_width();
}
 }
 
@@ -595,8 +591,7 @@ void RowPainter::paintText()
if (e.type != Row::INSET || ! 
e.inset->canPaintChange(*pi_.base.bv))
paintChange(e);
 
-   // extra is the extrawidth band-aid described in redoParagraphs
-   x_ +=  e.full_width() + ((e.type == Row::INSET) ? e.extra : 0);
+   x_ += e.full_width();
}
 }
 
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 32768970bb..4692918e8e 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -485,7 +485,6 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool 
const align_rows)
par.setBeginOfBody();
Font const bufferfont = buffer.params().getFont();
CoordCache::Insets & insetCache = bv_->coordCache().insets();
-   map  extrawidths;
for (auto const & e : par.insetList()) {
// FIXME Doesn't this HAVE to be non-empty?
// position already initialized?
@@ -522,17 +521,6 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool 
const align_r

[LyX features/biginset] fix documentation of --enable-cxx-mode

2024-04-05 Thread Jean-Marc Lasgouttes
commit 44c0b4e4cc1827d38dcc5284513a62cc62a54362
Author: Jean-Marc Lasgouttes 
Date:   Thu Mar 21 22:50:38 2024 +0100

fix documentation of --enable-cxx-mode
---
 INSTALL | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/INSTALL b/INSTALL
index 7a44ad8896..5c9c4d7489 100644
--- a/INSTALL
+++ b/INSTALL
@@ -208,8 +208,8 @@ precisely (see the description of --enable-build-type for 
the default
 values):
 
   o --enable-cxx-mode=VALUE can be used to select a C++ standard, for
-example --enable-cxx-mode=11. The default is to try C++14, and then
-C++11.
+example --enable-cxx-mode=11. The default is to try C++17, C++14, and
+C++11, in this order.
 
   o --enable-optimization=VALUE enables you to set optimization to a
 higher level than the default, for example --enable-optimization=-O3.
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX features/biginset] typo

2024-04-05 Thread Jean-Marc Lasgouttes
commit b659d7e3bdb26ed9c862cdb6dcfeb6dcb8cfb89b
Author: Jean-Marc Lasgouttes 
Date:   Thu Mar 21 22:40:19 2024 +0100

typo
---
 INSTALL | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/INSTALL b/INSTALL
index 8f2836c742..7a44ad8896 100644
--- a/INSTALL
+++ b/INSTALL
@@ -60,7 +60,7 @@ This means that gcc users will have to install the relevant 
libstdc++
 library to be able to compile this version of LyX.
 
 For full LyX usability we suggest to use Qt 5.6 and higher, or at the
-very least Qt 5.4. It is also possible to compile against Qt 6.The
+very least Qt 5.4. It is also possible to compile against Qt 6. The
 only special point to make is that you must ensure that both LyX and
 the Qt libraries are compiled with the same C++ compiler.
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Implement undo coalescing

2024-04-05 Thread Jean-Marc Lasgouttes
commit f5bbadbad92d55d480ea8b20c1e29f9ffe4ca224
Author: Jean-Marc Lasgouttes 
Date:   Thu Jul 14 01:02:28 2022 +0200

Implement undo coalescing

if the undo element we want to add only changes stuff that was already
modified by the previous one on undo stack (in the same group), then
skip it. There is nothing to gain in adding it to the stack.

The typical use case is when doing a search and replace in a large
document that does many replacements in each paragraph. In this case,
the same paragraph would be stored repeatedly.

Fixes bug #12564.
---
 src/Undo.cpp | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/Undo.cpp b/src/Undo.cpp
index 4e970df5a0..ddc7025e1c 100644
--- a/src/Undo.cpp
+++ b/src/Undo.cpp
@@ -312,12 +312,29 @@ void Undo::Private::doRecordUndo(UndoKind kind,
 
if (first_pit > last_pit)
swap(first_pit, last_pit);
+   pit_type const from = first_pit;
+   pit_type const end = cell.lastpit() - last_pit;
+
+   /* Undo coalescing: if the undo element we want to add only
+* changes stuff that was already modified by the previous one on
+* undo stack (in the same group), then skip it. There is nothing
+* to gain in adding it to the stack. The code below works for
+* both texted and mathed.
+   */
+   if (!stack.empty()
+   && stack.top().group_id == group_id_
+   && !stack.top().bparams
+   && samePar(stack.top().cell, cell)
+   //&& stack.top().kind == kind // needed?
+   && stack.top().from <= from
+   && stack.top().end >= end) {
+   LYXERR(Debug::UNDO, "Undo coalescing: skip entry");
+   return;
+   }
 
// Undo::ATOMIC are always recorded (no overlapping there).
// As nobody wants all removed character appear one by one when undoing,
// we want combine 'similar' non-ATOMIC undo recordings to one.
-   pit_type from = first_pit;
-   pit_type end = cell.lastpit() - last_pit;
if (!undo_finished_
&& kind != ATOMIC_UNDO
&& !stack.empty()
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/2.4.x] Compilation fix with Qt < 5.7

2024-04-04 Thread Jean-Marc Lasgouttes
commit 0cd169d6baecb4e6854c408a7452a843e57070e6
Author: Jean-Marc Lasgouttes 
Date:   Wed Apr 3 12:39:09 2024 +0200

Compilation fix with Qt < 5.7

Qt::ImAnchorRectangle has only been introduced in Qt 5.7. Since it is
used to answer a query from the IM machinery, there is no need for
it with older Qt versions.

(cherry picked from commit 6260689fd552a5e83d2970dcfd4d5ba7e09443e7)
---
 src/frontends/qt/GuiWorkArea.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp
index a4b874097c..341fddc3b8 100644
--- a/src/frontends/qt/GuiWorkArea.cpp
+++ b/src/frontends/qt/GuiWorkArea.cpp
@@ -1422,10 +1422,12 @@ QVariant 
GuiWorkArea::inputMethodQuery(Qt::InputMethodQuery query) const
return QVariant(d->im_cursor_rect_);
break;
}
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
case Qt::ImAnchorRectangle: {
return QVariant(d->im_anchor_rect_);
break;
}
+#endif
default:
return QWidget::inputMethodQuery(query);
}
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


  1   2   3   4   5   6   7   8   9   10   >