Commit 876a1752 authored by Carlos Alves's avatar Carlos Alves Committed by Tomaz Canabrava
Browse files

Reflow when executing an app

The reflow need to guess where the cursor line is when the user change
the konsole window size while executing an app.
parent 6d9c1d27
......@@ -383,6 +383,36 @@ bool Screen::isResize()
return _isResize;
}
// Not to production auxiliar functions to show what is written in screen or history
void toDebug(const Character s[], int count, bool wrapped = false) {
QString out;
for (int i = 0; i < count; i++) {
out += s[i].character;
}
qDebug() << out << (wrapped? " wrapped" : "");
}
void toDebug(const QVector<Character> &s, bool wrapped = false) {
toDebug(s.data(), s.size(), wrapped);
}
/////
int Screen::getCursorLine()
{
if (_currentModes[MODE_AppScreen] == 1) {
return _savedState.cursorLine;
}
return _cuY;
}
void Screen::setCursorLine(int newLine)
{
if (_currentModes[MODE_AppScreen] == 1) {
_savedState.cursorLine = newLine;
} else {
_cuY = newLine;
}
}
void Screen::resizeImage(int new_lines, int new_columns)
{
if ((new_lines == _lines) && (new_columns == _columns)) {
......@@ -393,41 +423,47 @@ void Screen::resizeImage(int new_lines, int new_columns)
_oldTotalLines = getLines() + getHistLines();
_isResize = true;
int cursorLine = getCursorLine();
const int oldCursorLine = (cursorLine == _lines -1)? new_lines - 1 : cursorLine;
// First join everything.
int currentPos = 0;
if (new_columns != _columns) {
while (currentPos < _cuY && currentPos < _screenLines.count() - 1) {
// if the line have the 'LINE_WRAPPED' property, concat with the next line and remove it.
if ((_lineProperties[currentPos] & LINE_WRAPPED) != 0) {
_screenLines[currentPos].append(_screenLines[currentPos + 1]);
_screenLines.remove(currentPos + 1);
_lineProperties.remove(currentPos);
_cuY--;
continue;
}
currentPos++;
while (currentPos < cursorLine && currentPos < _screenLines.count() - 1) {
// if the line have the 'LINE_WRAPPED' property, concat with the next line and remove it.
if ((_lineProperties[currentPos] & LINE_WRAPPED) != 0) {
_screenLines[currentPos].append(_screenLines[currentPos + 1]);
_screenLines.remove(currentPos + 1);
_lineProperties.remove(currentPos);
cursorLine--;
continue;
}
// Then move the data to lines below.
currentPos = 0;
while (currentPos != _screenLines.count() && currentPos != _cuY) {
const bool shouldCopy = _screenLines[currentPos].size() > new_columns;
// Copy from the current line, to the next one.
if (shouldCopy) {
_cuY++;
auto values = _screenLines[currentPos].mid(new_columns);
_screenLines[currentPos].remove(new_columns, values.size());
_lineProperties.insert(currentPos + 1, _lineProperties[currentPos]);
_screenLines.insert(currentPos + 1, values);
_lineProperties[currentPos] |= LINE_WRAPPED;
}
currentPos += 1;
currentPos++;
}
// Then move the data to lines below.
currentPos = 0;
while (currentPos < cursorLine && currentPos < _screenLines.count()) {
// Ignore whitespaces at the end of the line
int lineSize = _screenLines[currentPos].size();
while (lineSize > 0 && QChar(_screenLines[currentPos][lineSize - 1].character).isSpace()) {
lineSize--;
}
const bool shouldCopy = lineSize > new_columns;
// Copy from the current line, to the next one.
if (shouldCopy) {
auto values = _screenLines[currentPos].mid(new_columns);
_screenLines[currentPos].remove(new_columns, values.size());
_lineProperties.insert(currentPos + 1, _lineProperties[currentPos]);
_screenLines.insert(currentPos + 1, values);
_lineProperties[currentPos] |= LINE_WRAPPED;
cursorLine++;
}
currentPos += 1;
}
// Check if it need to move from _screenLine to _history
while (_cuY > new_lines - 1) {
while (cursorLine > new_lines - 1) {
fastAddHistLine();
cursorLine--;
}
_lineProperties.resize(new_lines + 1);
_screenLines.resize(new_lines + 1);
......@@ -437,6 +473,7 @@ void Screen::resizeImage(int new_lines, int new_columns)
// Join next line from _screenLine to _history
while (_history->isWrappedLine(_history->getLines() - 1)) {
fastAddHistLine();
cursorLine--;
}
currentPos = 0;
// Join everything in _history
......@@ -494,7 +531,7 @@ void Screen::resizeImage(int new_lines, int new_columns)
// Check cursor position and send from _history to _screenLines
ImageLine histLine;
histLine.reserve(1024);
while (_cuY < new_lines - 1 && _history->getLines()) {
while (cursorLine < oldCursorLine && _history->getLines()) {
int histPos = _history->getLines() - 1;
int histLineLen = _history->getLineLen(histPos);
int isWrapped = _history->isWrappedLine(histPos)? LINE_WRAPPED : LINE_DEFAULT;
......@@ -503,7 +540,7 @@ void Screen::resizeImage(int new_lines, int new_columns)
_screenLines.insert(0, histLine);
_lineProperties.insert(0, isWrapped);
_history->removeCells(histPos);
_cuY++;
cursorLine++;
}
_lineProperties.resize(new_lines + 1);
......@@ -516,7 +553,8 @@ void Screen::resizeImage(int new_lines, int new_columns)
_lines = new_lines;
_columns = new_columns;
_cuX = qMin(_cuX, _columns - 1);
_cuY = qMin(_cuY, _lines - 1);
cursorLine = qBound(0, cursorLine, _lines - 1);
setCursorLine(cursorLine);
// FIXME: try to keep values, evtl.
setDefaultMargins();
......@@ -1571,7 +1609,7 @@ void Screen::writeLinesToStream(TerminalCharacterDecoder* decoder, int fromLine,
void Screen::fastAddHistLine()
{
bool removeLine = _history->getLines() == _history->getMaxLines();
const bool removeLine = _history->getLines() == _history->getMaxLines();
_history->addCellsVector(_screenLines[0]);
_history->addLine((_lineProperties[0] & LINE_WRAPPED) != 0);
......@@ -1583,7 +1621,6 @@ void Screen::fastAddHistLine()
_screenLines.pop_front();
_lineProperties.remove(0);
_cuY--;
}
void Screen::addHistLine()
......
......@@ -25,7 +25,8 @@
#define MODE_Screen 3
#define MODE_Cursor 4
#define MODE_NewLine 5
#define MODES_SCREEN 6
#define MODE_AppScreen 6
#define MODES_SCREEN 7
namespace Konsole {
class TerminalCharacterDecoder;
......@@ -653,6 +654,11 @@ private:
// should be as minimal as possible
static Character *getCharacterBuffer(const int size);
// Get the cursor line after checking if its app mode or not
int getCursorLine();
// Set the cursor line after checking if its app mode or not
void setCursorLine (int newLine);
int getLineLength(const int line) const;
// screen image ----------------
......
......@@ -1464,8 +1464,8 @@ void Vt102Emulation::resetMode(int m)
setScreen(0);
break;
}
// FIXME: Currently this has a redundant condition as MODES_SCREEN is 6
// and MODE_NewLine is 5
// FIXME: Currently this has a redundant condition as MODES_SCREEN is 7
// MODE_AppScreen is 6 and MODE_NewLine is 5
if (m < MODES_SCREEN || m == MODE_NewLine) {
_screen[0]->resetMode(m);
_screen[1]->resetMode(m);
......
......@@ -20,22 +20,21 @@
class QTimer;
class QKeyEvent;
#define MODE_AppScreen (MODES_SCREEN+0) // Mode #1
#define MODE_AppCuKeys (MODES_SCREEN+1) // Application cursor keys (DECCKM)
#define MODE_AppKeyPad (MODES_SCREEN+2) //
#define MODE_Mouse1000 (MODES_SCREEN+3) // Send mouse X,Y position on press and release
#define MODE_Mouse1001 (MODES_SCREEN+4) // Use Hilight mouse tracking
#define MODE_Mouse1002 (MODES_SCREEN+5) // Use cell motion mouse tracking
#define MODE_Mouse1003 (MODES_SCREEN+6) // Use all motion mouse tracking
#define MODE_Mouse1005 (MODES_SCREEN+7) // Xterm-style extended coordinates
#define MODE_Mouse1006 (MODES_SCREEN+8) // 2nd Xterm-style extended coordinates
#define MODE_Mouse1007 (MODES_SCREEN+9) // XTerm Alternate Scroll mode; also check AlternateScrolling profile property
#define MODE_Mouse1015 (MODES_SCREEN+10) // Urxvt-style extended coordinates
#define MODE_Ansi (MODES_SCREEN+11) // Use US Ascii for character sets G0-G3 (DECANM)
#define MODE_132Columns (MODES_SCREEN+12) // 80 <-> 132 column mode switch (DECCOLM)
#define MODE_Allow132Columns (MODES_SCREEN+13) // Allow DECCOLM mode
#define MODE_BracketedPaste (MODES_SCREEN+14) // Xterm-style bracketed paste mode
#define MODE_total (MODES_SCREEN+15)
#define MODE_AppCuKeys (MODES_SCREEN+0) // Application cursor keys (DECCKM)
#define MODE_AppKeyPad (MODES_SCREEN+1) //
#define MODE_Mouse1000 (MODES_SCREEN+2) // Send mouse X,Y position on press and release
#define MODE_Mouse1001 (MODES_SCREEN+3) // Use Hilight mouse tracking
#define MODE_Mouse1002 (MODES_SCREEN+4) // Use cell motion mouse tracking
#define MODE_Mouse1003 (MODES_SCREEN+5) // Use all motion mouse tracking
#define MODE_Mouse1005 (MODES_SCREEN+6) // Xterm-style extended coordinates
#define MODE_Mouse1006 (MODES_SCREEN+7) // 2nd Xterm-style extended coordinates
#define MODE_Mouse1007 (MODES_SCREEN+8) // XTerm Alternate Scroll mode; also check AlternateScrolling profile property
#define MODE_Mouse1015 (MODES_SCREEN+9) // Urxvt-style extended coordinates
#define MODE_Ansi (MODES_SCREEN+10) // Use US Ascii for character sets G0-G3 (DECANM)
#define MODE_132Columns (MODES_SCREEN+11) // 80 <-> 132 column mode switch (DECCOLM)
#define MODE_Allow132Columns (MODES_SCREEN+12) // Allow DECCOLM mode
#define MODE_BracketedPaste (MODES_SCREEN+13) // Xterm-style bracketed paste mode
#define MODE_total (MODES_SCREEN+14)
namespace Konsole {
extern unsigned short vt100_graphics[32];
......
Markdown is supported
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