diff --git a/src/Screen.cpp b/src/Screen.cpp index 4954508d..37eac80c 100644 --- a/src/Screen.cpp +++ b/src/Screen.cpp @@ -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 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>::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); diff --git a/src/Screen.h b/src/Screen.h index 91739e4a..31478c01 100644 --- a/src/Screen.h +++ b/src/Screen.h @@ -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 &u); std::vector> _graphicsPlacements; + void scrollPlacements(int n, qint64 below = INT64_MAX, qint64 above = INT64_MAX); bool _hasGraphics; }; diff --git a/src/history/HistoryScroll.h b/src/history/HistoryScroll.h index 0f2901f2..c126dc2a 100644 --- a/src/history/HistoryScroll.h +++ b/src/history/HistoryScroll.h @@ -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 *deltas = nullptr) = 0; // // FIXME: Passing around constant references to HistoryType instances diff --git a/src/history/HistoryScrollFile.cpp b/src/history/HistoryScrollFile.cpp index 51061822..e8ff5508 100644 --- a/src/history/HistoryScrollFile.cpp +++ b/src/history/HistoryScrollFile.cpp @@ -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 *) { auto reflowFile = std::make_unique(); reflowData newLine; diff --git a/src/history/HistoryScrollFile.h b/src/history/HistoryScrollFile.h index bb430656..679e0cd1 100644 --- a/src/history/HistoryScrollFile.h +++ b/src/history/HistoryScrollFile.h @@ -38,7 +38,7 @@ public: // Modify history void removeCells() override; - int reflowLines(const int columns) override; + int reflowLines(const int columns, std::map * = nullptr) override; private: qint64 startOfLine(const int lineno) const; diff --git a/src/history/HistoryScrollNone.cpp b/src/history/HistoryScrollNone.cpp index 143ee702..21c52f02 100644 --- a/src/history/HistoryScrollNone.cpp +++ b/src/history/HistoryScrollNone.cpp @@ -70,7 +70,7 @@ void HistoryScrollNone::removeCells() { } -int HistoryScrollNone::reflowLines(int) +int Konsole::HistoryScrollNone::reflowLines(const int, std::map *) { return 0; } diff --git a/src/history/HistoryScrollNone.h b/src/history/HistoryScrollNone.h index 6720e082..6ecd2a5a 100644 --- a/src/history/HistoryScrollNone.h +++ b/src/history/HistoryScrollNone.h @@ -37,7 +37,7 @@ public: // Modify history (do nothing here) void removeCells() override; - int reflowLines(const int) override; + int reflowLines(const int, std::map * = nullptr) override; }; } diff --git a/src/history/compact/CompactHistoryScroll.cpp b/src/history/compact/CompactHistoryScroll.cpp index 2a571b54..21975fec 100644 --- a/src/history/compact/CompactHistoryScroll.cpp +++ b/src/history/compact/CompactHistoryScroll.cpp @@ -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 *deltas) { std::vector 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); diff --git a/src/history/compact/CompactHistoryScroll.h b/src/history/compact/CompactHistoryScroll.h index c333bd74..00a2323d 100644 --- a/src/history/compact/CompactHistoryScroll.h +++ b/src/history/compact/CompactHistoryScroll.h @@ -37,7 +37,7 @@ public: void setMaxNbLines(const int lineCount); - int reflowLines(const int columns) override; + int reflowLines(const int columns, std::map *deltas = nullptr) override; private: /** diff --git a/src/terminalDisplay/TerminalDisplay.cpp b/src/terminalDisplay/TerminalDisplay.cpp index 1edc5338..7feebc76 100644 --- a/src/terminalDisplay/TerminalDisplay.cpp +++ b/src/terminalDisplay/TerminalDisplay.cpp @@ -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 }