Skip to content

Commit e2dfaf5

Browse files
committed
Revert display layout invalidation
Fix regression made in commit 6511755 - when removing the display layout, we also must remove the other relevant data - particulary the character offset map. But it is all a losing game anyway, just hash as much of the formats as we need to ensure the display layout gets recalculated after theme change, whenever it happens.
1 parent 6227af8 commit e2dfaf5

File tree

3 files changed

+28
-23
lines changed

3 files changed

+28
-23
lines changed

core/katvan_editor.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -466,12 +466,7 @@ void Editor::setTextBlockDirection(Qt::LayoutDirection dir)
466466

467467
void Editor::forceRehighlighting()
468468
{
469-
QTimer::singleShot(0, d_highlighter, [this]() {
470-
EditorLayout* layout = qobject_cast<EditorLayout*>(document()->documentLayout());
471-
layout->invalidateAllDisplayLayouts();
472-
473-
d_highlighter->rehighlight();
474-
});
469+
QTimer::singleShot(0, d_highlighter, &QSyntaxHighlighter::rehighlight);
475470
}
476471

477472
void Editor::checkForModelines()

core/katvan_editorlayout.cpp

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ class LayoutBlockData : public QTextBlockUserData
7676
public:
7777
static constexpr BlockDataKind DATA_KIND = BlockDataKind::LAYOUT;
7878

79-
LayoutBlockData() : textHash(qHash(QStringView())) {}
79+
LayoutBlockData() : contentHash(qHash(QStringView())) {}
8080

8181
std::unique_ptr<QTextLayout> displayLayout;
8282
QList<ushort> displayOffsets;
83-
size_t textHash;
83+
size_t contentHash;
8484
};
8585

8686
static int adjustPosToDisplay(const QList<ushort>& displayOffsets, int pos)
@@ -372,15 +372,37 @@ void EditorLayout::doDocumentLayout(const QTextBlock& startBlock, const QTextBlo
372372
Q_EMIT update();
373373
}
374374

375+
static size_t hashBlockContent(const QTextBlock& block, const QString& blockText)
376+
{
377+
size_t hash = qHash(blockText);
378+
379+
const QList<QTextLayout::FormatRange> formats = block.layout()->formats();
380+
for (const QTextLayout::FormatRange& r : formats) {
381+
// We need to hash the text formats too, to recognize theme changes and
382+
// things stopping being spelling errors due to dictionary changes. The
383+
// problem is that QTextFormat doesn't provide a hash function. Doing
384+
// that generically for all possible properties is rather grueling,
385+
// let's just pick the minimal properties that will act as proxy for the
386+
// events listed above.
387+
hash = qHashMulti(hash,
388+
r.start,
389+
r.length,
390+
r.format.foreground().color().rgb(),
391+
r.format.underlineColor().rgb());
392+
}
393+
394+
return hash;
395+
}
396+
375397
static void buildDisplayLayout(const QTextBlock& block, QString blockText, LayoutBlockData* blockData)
376398
{
377-
size_t newHash = qHash(blockText);
399+
size_t newHash = hashBlockContent(block, blockText);
378400

379401
// Calculating a display layout is expensive, only do it if content actually changed
380-
if (newHash == blockData->textHash) {
402+
if (newHash == blockData->contentHash) {
381403
return;
382404
}
383-
blockData->textHash = newHash;
405+
blockData->contentHash = newHash;
384406

385407
IsolatesBlockData* isolateData = BlockData::get<IsolatesBlockData>(block);
386408
if (isolateData == nullptr || isolateData->isolates().isEmpty()) {
@@ -693,16 +715,6 @@ int EditorLayout::getLineEdgePosition(int pos, QTextLine::Edge edge) const
693715
return block.position() + origLayoutPos;
694716
}
695717

696-
void EditorLayout::invalidateAllDisplayLayouts()
697-
{
698-
for (QTextBlock block = document()->begin(); block.isValid(); block = block.next()) {
699-
LayoutBlockData* layoutData = BlockData::get<LayoutBlockData>(block);
700-
if (layoutData) {
701-
layoutData->displayLayout.reset();
702-
}
703-
}
704-
}
705-
706718
void EditorLayout::recalculateDocumentSize()
707719
{
708720
// TODO: This way (recalculating from scratch after every change) ensures

core/katvan_editorlayout.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ class EditorLayout : public QAbstractTextDocumentLayout
5050
QPointF cursorPositionPoint(int pos) const;
5151
int getLineEdgePosition(int pos, QTextLine::Edge edge) const;
5252

53-
void invalidateAllDisplayLayouts();
54-
5553
signals:
5654
void fullRelayoutDone();
5755

0 commit comments

Comments
 (0)