This commit is contained in:
Adam D. Ruppe 2020-04-02 15:03:57 -04:00
parent 1c119753b3
commit 738148b861
2 changed files with 73 additions and 12 deletions

View File

@ -1109,7 +1109,15 @@ struct Terminal {
nw.show(); nw.show();
}); });
tew = window.tew; tew = window.tew;
window.loop(); //try
window.loop();
/*
catch(Throwable t) {
import std.stdio;
stdout.writeln(t);
stdout.flush();
}
*/
}); });
guiThread.start(); guiThread.start();
guiThread.priority = Thread.PRIORITY_MAX; // gui thread needs responsiveness guiThread.priority = Thread.PRIORITY_MAX; // gui thread needs responsiveness
@ -1813,10 +1821,13 @@ struct Terminal {
} }
+/ +/
void writePrintableString(in char[] s, ForceOption force = ForceOption.automatic) { void writePrintableString(const(char)[] s, ForceOption force = ForceOption.automatic) {
// an escape character is going to mess things up. Actually any non-printable character could, but meh // an escape character is going to mess things up. Actually any non-printable character could, but meh
// assert(s.indexOf("\033") == -1); // assert(s.indexOf("\033") == -1);
if(s.length == 0)
return;
// tracking cursor position // tracking cursor position
// FIXME: by grapheme? // FIXME: by grapheme?
foreach(dchar ch; s) { foreach(dchar ch; s) {
@ -1852,7 +1863,26 @@ struct Terminal {
+/ +/
} }
writeStringRaw(s); version(TerminalDirectToEmulator) {
// this breaks up extremely long output a little as an aid to the
// gui thread; by breaking it up, it helps to avoid monopolizing the
// event loop. Easier to do here than in the thread itself because
// this one doesn't have escape sequences to break up so it avoids work.
while(s.length) {
auto len = s.length;
if(len > 1024 * 32) {
len = 1024 * 32;
// get to the start of a utf-8 sequence. kidna sorta.
while(len && (s[len] & 0x1000_0000))
len--;
}
auto next = s[0 .. len];
s = s[len .. $];
writeStringRaw(next);
}
} else {
writeStringRaw(s);
}
} }
/* private */ bool _wrapAround = true; /* private */ bool _wrapAround = true;
@ -1864,6 +1894,8 @@ struct Terminal {
// you really, really shouldn't use this unless you know what you are doing // you really, really shouldn't use this unless you know what you are doing
/*private*/ void writeStringRaw(in char[] s) { /*private*/ void writeStringRaw(in char[] s) {
writeBuffer ~= s; // buffer it to do everything at once in flush() calls writeBuffer ~= s; // buffer it to do everything at once in flush() calls
if(writeBuffer.length > 1024 * 32)
flush();
} }
/// Clears the screen. /// Clears the screen.
@ -6214,13 +6246,18 @@ version(TerminalDirectToEmulator) {
} }
protected override void demandAttention() { protected override void demandAttention() {
//window.requestAttention(); if(widget && widget.parentWindow)
widget.parentWindow.win.requestAttention();
} }
protected override void copyToClipboard(string text) { protected override void copyToClipboard(string text) {
setClipboardText(widget.parentWindow.win, text); setClipboardText(widget.parentWindow.win, text);
} }
override int maxScrollbackLength() const {
return int.max; // no scrollback limit for custom programs
}
protected override void pasteFromClipboard(void delegate(in char[]) dg) { protected override void pasteFromClipboard(void delegate(in char[]) dg) {
static if(UsingSimpledisplayX11) static if(UsingSimpledisplayX11)
getPrimarySelection(widget.parentWindow.win, dg); getPrimarySelection(widget.parentWindow.win, dg);

View File

@ -362,6 +362,9 @@ class TerminalEmulator {
start = idx; start = idx;
end = selectionEnd; end = selectionEnd;
} }
if(start < 0 || end >= ((alternateScreenActive ? alternateScreen.length : normalScreen.length)))
return false;
foreach(ref cell; (alternateScreenActive ? alternateScreen : normalScreen)[start .. end]) { foreach(ref cell; (alternateScreenActive ? alternateScreen : normalScreen)[start .. end]) {
cell.invalidated = true; cell.invalidated = true;
cell.selected = false; cell.selected = false;
@ -1477,10 +1480,12 @@ class TerminalEmulator {
bool overflowed; bool overflowed;
foreach(cell; line) { foreach(cell; line) {
cell.invalidated = true; cell.invalidated = true;
if(overflowed) if(overflowed) {
screen[cursorY * screenWidth + cursorX] = overflowCell; screen[cursorY * screenWidth + cursorX] = overflowCell;
else break;
} else {
screen[cursorY * screenWidth + cursorX] = cell; screen[cursorY * screenWidth + cursorX] = cell;
}
if(cursorX == screenWidth-1) { if(cursorX == screenWidth-1) {
if(scrollbackReflow) { if(scrollbackReflow) {
@ -1665,8 +1670,12 @@ class TerminalEmulator {
void clear() { void clear() {
start = 0; start = 0;
length_ = 0; length_ = 0;
backing = null;
} }
// FIXME: if scrollback hits limits the scroll bar needs
// to understand the circular buffer
void opOpAssign(string op : "~")(TerminalCell[] line) { void opOpAssign(string op : "~")(TerminalCell[] line) {
if(length_ < maxScrollback) { if(length_ < maxScrollback) {
backing.assumeSafeAppend(); backing.assumeSafeAppend();
@ -1900,26 +1909,41 @@ class TerminalEmulator {
} }
} }
private int recalculationThreshold = 0;
public void addScrollbackLine(TerminalCell[] line) { public void addScrollbackLine(TerminalCell[] line) {
scrollbackBuffer ~= line; scrollbackBuffer ~= line;
if(!scrollbackReflow && line.length > scrollbackWidth_) if(scrollbackBuffer.length_ == ScrollbackBuffer.maxScrollback) {
scrollbackWidth_ = cast(int) line.length; recalculationThreshold++;
scrollbackLength = cast(int) (scrollbackLength + 1 + (scrollbackBuffer[cast(int) scrollbackBuffer.length - 1].length) / screenWidth); if(recalculationThreshold > 100) {
notifyScrollbackAdded(); recalculateScrollbackLength();
notifyScrollbackAdded();
recalculationThreshold = 0;
}
} else {
if(!scrollbackReflow && line.length > scrollbackWidth_)
scrollbackWidth_ = cast(int) line.length;
scrollbackLength = cast(int) (scrollbackLength + 1 + (scrollbackBuffer[cast(int) scrollbackBuffer.length - 1].length) / screenWidth);
notifyScrollbackAdded();
}
if(!alternateScreenActive) if(!alternateScreenActive)
notifyScrollbarPosition(0, int.max); notifyScrollbarPosition(0, int.max);
} }
protected int maxScrollbackLength() pure const @nogc nothrow {
return 1024;
}
bool insertMode = false; bool insertMode = false;
void newLine(bool commitScrollback) { void newLine(bool commitScrollback) {
if(!alternateScreenActive && commitScrollback) { if(!alternateScreenActive && commitScrollback) {
// I am limiting this because obscenely long lines are kinda useless anyway and // I am limiting this because obscenely long lines are kinda useless anyway and
// i don't want it to eat excessive memory when i spam some thing accidentally // i don't want it to eat excessive memory when i spam some thing accidentally
if(currentScrollbackLine.length < 1024) if(currentScrollbackLine.length < maxScrollbackLength())
addScrollbackLine(currentScrollbackLine.sliceTrailingWhitespace); addScrollbackLine(currentScrollbackLine.sliceTrailingWhitespace);
else else
addScrollbackLine(currentScrollbackLine[0 .. 1024].sliceTrailingWhitespace); addScrollbackLine(currentScrollbackLine[0 .. maxScrollbackLength()].sliceTrailingWhitespace);
currentScrollbackLine = null; currentScrollbackLine = null;
currentScrollbackLine.reserve(64); currentScrollbackLine.reserve(64);