Use Erase-in-Line more carefully
Instead of erasing a whole line before writing a line, simply write the line. At the end of the line, issue a CSI 0K to erase from the cursor to the end of the line. The erasing serves two purposes: * It can clear characters beyond the right end of the terminal, which have been obscured by a terminal resize. * It sets the background color for the trailing whitespace. Doing the erasing like so has two benefits: * It's more correct. Previously, the trailing whitespace was colored arbitrarily. Now, it is correctly colored to the last color on the line. * It should eliminate a lot of flicker.
This commit is contained in:
parent
d4a5d0f5a0
commit
efb10c4fcf
@ -309,12 +309,9 @@ void Terminal::sendLine(int line, CHAR_INFO *lineData, int width)
|
||||
hideTerminalCursor();
|
||||
moveTerminalToLine(line);
|
||||
|
||||
// Erase in Line -- erase entire line.
|
||||
if (!m_consoleMode)
|
||||
m_output->write(CSI"2K");
|
||||
|
||||
m_termLine.clear();
|
||||
int trimmedLineLength = 0;
|
||||
bool alreadyErasedLine = false;
|
||||
|
||||
int cellCount = 1;
|
||||
for (int i = 0; i < width; i += cellCount) {
|
||||
@ -331,6 +328,19 @@ void Terminal::sendLine(int line, CHAR_INFO *lineData, int width)
|
||||
if (ch == ' ') {
|
||||
m_termLine.push_back(' ');
|
||||
} else {
|
||||
if (i + cellCount == width) {
|
||||
// We'd like to erase the line after outputting all non-blank
|
||||
// characters, but this doesn't work if the last cell in the
|
||||
// line is non-blank. At the point, the cursor is positioned
|
||||
// just past the end of the line, but in many terminals,
|
||||
// issuing a CSI 0K at that point also erases the last cell in
|
||||
// the line. Work around this behavior by issuing the erase
|
||||
// one character early in that case.
|
||||
if (!m_consoleMode) {
|
||||
m_termLine.append(CSI"0K"); // Erase from cursor to EOL
|
||||
}
|
||||
alreadyErasedLine = true;
|
||||
}
|
||||
ch = fixConsolePopupBoxArt(ch);
|
||||
char enc[4];
|
||||
int enclen = encodeUtf8(enc, ch);
|
||||
@ -344,6 +354,10 @@ void Terminal::sendLine(int line, CHAR_INFO *lineData, int width)
|
||||
}
|
||||
|
||||
m_output->write(m_termLine.data(), trimmedLineLength);
|
||||
|
||||
if (!alreadyErasedLine && !m_consoleMode) {
|
||||
m_output->write(CSI"0K"); // Erase from cursor to EOL
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::finishOutput(const std::pair<int, int> &newCursorPos)
|
||||
|
Loading…
Reference in New Issue
Block a user