Commit 37b9f9e3 authored by Matan Ziv-Av's avatar Matan Ziv-Av Committed by Tomaz Canabrava
Browse files

Manage graphics placements vertical position on text reflow.

When a line is reflowed then the vertical position of all
graphics placements above or below it (as appropriate) are
adjusted, so they remain in the same place relative to the
text lines.
parent e3fd9f7b
Pipeline #188791 passed with stage
in 3 minutes and 38 seconds
......@@ -476,7 +476,6 @@ void Screen::resizeImage(int new_lines, int new_columns)
if ((new_lines == _lines) && (new_columns == _columns)) {
return;
}
// Adjust scroll position, and fix glitches
_oldTotalLines = getLines() + getHistLines();
_isResize = true;
......@@ -490,14 +489,20 @@ void Screen::resizeImage(int new_lines, int new_columns)
while (!_screenLines.empty() && _history->isWrappedLine(_history->getLines() - 1)) {
fastAddHistLine();
--cursorLine;
scrollPlacements(1);
}
auto removedLines = _history->reflowLines(new_columns);
std::map<int, int> deltas = {};
auto removedLines = _history->reflowLines(new_columns, &deltas);
// If _history size > max history size it will drop a line from _history.
// We need to verify if we need to remove a URL.
if (removedLines && _escapeSequenceUrlExtractor) {
_escapeSequenceUrlExtractor->historyLinesRemoved(removedLines);
}
for (const auto &[pos, delta] : deltas) {
scrollPlacements(delta, INT64_MIN, pos);
}
}
if (_enableReflowLines && new_columns != _columns) {
......@@ -531,6 +536,7 @@ void Screen::resizeImage(int new_lines, int new_columns)
_screenLines.erase(_screenLines.begin() + currentPos + 1);
_lineProperties.erase(_lineProperties.begin() + currentPos);
--cursorLine;
scrollPlacements(1, currentPos);
continue;
}
......@@ -548,6 +554,7 @@ void Screen::resizeImage(int new_lines, int new_columns)
_screenLines.insert(_screenLines.begin() + currentPos + 1, std::move(values));
_lineProperties[currentPos] |= LINE_WRAPPED;
++cursorLine;
scrollPlacements(-1, currentPos);
}
currentPos += 1;
}
......@@ -557,6 +564,7 @@ void Screen::resizeImage(int new_lines, int new_columns)
while (cursorLine > new_lines - 1) {
fastAddHistLine();
--cursorLine;
scrollPlacements(1);
}
if (_enableReflowLines) {
......@@ -572,6 +580,7 @@ void Screen::resizeImage(int new_lines, int new_columns)
_lineProperties.insert(_lineProperties.begin(), lineProperty);
_history->removeCells();
++cursorLine;
scrollPlacements(-1);
}
}
......@@ -1121,7 +1130,7 @@ void Screen::scrollUp(int from, int n)
moveImage(loc(0, from), loc(0, from + n), loc(_columns, _bottomMargin));
clearImage(loc(0, _bottomMargin - n + 1), loc(_columns - 1, _bottomMargin), ' ');
if (_hasGraphics) {
scrollUpVisiblePlacements(n);
scrollPlacements(n);
}
}
......@@ -2043,14 +2052,14 @@ TerminalGraphicsPlacement_t *Screen::getGraphicsPlacement(unsigned int i)
return _graphicsPlacements[i].get();
}
void Screen::scrollUpVisiblePlacements(int n)
void Screen::scrollPlacements(int n, qint64 below, qint64 above)
{
std::vector<std::unique_ptr<TerminalGraphicsPlacement_t>>::iterator i;
int histMaxLines = _history->getMaxLines();
i = _graphicsPlacements.begin();
while (i != _graphicsPlacements.end()) {
TerminalGraphicsPlacement_t *placement = i->get();
if (placement->scrolling) {
if ((placement->scrolling && below == INT64_MAX) || (placement->row > below && placement->row < above)) {
placement->row -= n;
if (placement->row + placement->rows < -histMaxLines) {
i = _graphicsPlacements.erase(i);
......
......@@ -633,7 +633,6 @@ public:
int X = 0,
int Y = 0);
TerminalGraphicsPlacement_t *getGraphicsPlacement(unsigned int i);
void scrollUpVisiblePlacements(int n);
void delPlacements(int = 'a', qint64 = 0, qint64 = -1, int = 0, int = 0, int = 0);
bool hasGraphics() const
......@@ -816,6 +815,7 @@ private:
/* Graphics */
void addPlacement(std::unique_ptr<TerminalGraphicsPlacement_t> &u);
std::vector<std::unique_ptr<TerminalGraphicsPlacement_t>> _graphicsPlacements;
void scrollPlacements(int n, qint64 below = INT64_MAX, qint64 above = INT64_MAX);
bool _hasGraphics;
};
......
......@@ -55,7 +55,7 @@ public:
// modify history
virtual void removeCells() = 0;
virtual int reflowLines(const int columns) = 0;
virtual int reflowLines(const int columns, std::map<int, int> *deltas = nullptr) = 0;
//
// FIXME: Passing around constant references to HistoryType instances
......
......@@ -104,7 +104,7 @@ void HistoryScrollFile::removeCells()
_lineflags.removeLast(res * sizeof(unsigned char));
}
int HistoryScrollFile::reflowLines(const int columns)
int Konsole::HistoryScrollFile::reflowLines(const int columns, std::map<int, int> *)
{
auto reflowFile = std::make_unique<HistoryFile>();
reflowData newLine;
......
......@@ -38,7 +38,7 @@ public:
// Modify history
void removeCells() override;
int reflowLines(const int columns) override;
int reflowLines(const int columns, std::map<int, int> * = nullptr) override;
private:
qint64 startOfLine(const int lineno) const;
......
......@@ -70,7 +70,7 @@ void HistoryScrollNone::removeCells()
{
}
int HistoryScrollNone::reflowLines(int)
int Konsole::HistoryScrollNone::reflowLines(const int, std::map<int, int> *)
{
return 0;
}
......@@ -37,7 +37,7 @@ public:
// Modify history (do nothing here)
void removeCells() override;
int reflowLines(const int) override;
int reflowLines(const int, std::map<int, int> * = nullptr) override;
};
}
......
......@@ -141,7 +141,7 @@ LineProperty CompactHistoryScroll::getLineProperty(const int lineNumber) const
return _lineDatas.at(lineNumber).flag;
}
int CompactHistoryScroll::reflowLines(const int columns)
int CompactHistoryScroll::reflowLines(const int columns, std::map<int, int> *deltas)
{
std::vector<LineData> newLineData;
......@@ -153,6 +153,8 @@ int CompactHistoryScroll::reflowLines(const int columns)
};
int currentPos = 0;
int newPos = 0;
int delta = 0;
while (currentPos < getLines()) {
int startLine = startOfLine(currentPos);
int endLine = startOfLine(currentPos + 1);
......@@ -168,9 +170,15 @@ int CompactHistoryScroll::reflowLines(const int columns)
while (reflowLineLen(startLine, endLine) > columns && !(lineProperty & (LINE_DOUBLEHEIGHT_BOTTOM | LINE_DOUBLEHEIGHT_TOP))) {
startLine += columns;
setNewLine(newLineData, startLine + _indexBias, lineProperty | LINE_WRAPPED);
newPos++;
}
setNewLine(newLineData, endLine + _indexBias, lineProperty & ~LINE_WRAPPED);
currentPos++;
newPos++;
if (deltas && delta != newPos - currentPos) {
(*deltas)[currentPos - getLines()] = newPos - currentPos - delta;
delta = newPos - currentPos;
}
}
_lineDatas = std::move(newLineData);
......
......@@ -37,7 +37,7 @@ public:
void setMaxNbLines(const int lineCount);
int reflowLines(const int columns) override;
int reflowLines(const int columns, std::map<int, int> *deltas = nullptr) override;
private:
/**
......
......@@ -1002,21 +1002,6 @@ void TerminalDisplay::updateImageSize()
if (_resizing) {
showResizeNotification();
if (oldLines != _lines) {
// An image's vertical position is relative to top line of the
// terminal, but text is relative to the bottom line, so the
// position needs adjusting when the terminal is resized.
int histLines = 0;
int change = oldLines - _lines;
if (_screenWindow && _screenWindow->screen()) {
histLines = _screenWindow->screen()->getHistLines();
}
if (histLines) {
_screenWindow->screen()->scrollUpVisiblePlacements(qMax(-histLines, change));
} else if (oldLines > _lines && cursorPosition().y() >= oldLines - change) {
_screenWindow->screen()->scrollUpVisiblePlacements(cursorPosition().y() - _lines + 1);
}
}
Q_EMIT changedContentSizeSignal(_contentRect.height(), _contentRect.width()); // expose resizeEvent
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment