mirror of https://github.com/liamg/aminal.git
Vttest 2 (#187)
* added Tab Stops support * added support for Screen Mode (DECSCNM) -- reverse colors * bug fix: cursor rendition in Origin Mode
This commit is contained in:
parent
97fe7362ce
commit
23797d50f3
|
@ -361,7 +361,7 @@ func (buffer *Buffer) RestoreCursor() {
|
|||
}
|
||||
|
||||
func (buffer *Buffer) CursorAttr() *CellAttributes {
|
||||
return &buffer.terminalState.cursorAttr
|
||||
return &buffer.terminalState.CursorAttr
|
||||
}
|
||||
|
||||
func (buffer *Buffer) GetCell(viewCol uint16, viewRow uint16) *Cell {
|
||||
|
@ -391,7 +391,12 @@ func (buffer *Buffer) CursorColumn() uint16 {
|
|||
return buffer.terminalState.cursorX
|
||||
}
|
||||
|
||||
// Line returns cursor line
|
||||
// CursorLineAbsolute returns absolute cursor line coordinate (ignoring Origin Mode)
|
||||
func (buffer *Buffer) CursorLineAbsolute() uint16 {
|
||||
return buffer.terminalState.cursorY
|
||||
}
|
||||
|
||||
// CursorLine returns cursor line (in Origin Mode it is relative to the top margin)
|
||||
func (buffer *Buffer) CursorLine() uint16 {
|
||||
if buffer.terminalState.OriginMode {
|
||||
result := buffer.terminalState.cursorY - uint16(buffer.terminalState.topMargin)
|
||||
|
@ -502,7 +507,7 @@ func (buffer *Buffer) InsertBlankCharacters(count int) {
|
|||
index := int(buffer.RawLine())
|
||||
for i := 0; i < count; i++ {
|
||||
cells := buffer.lines[index].cells
|
||||
buffer.lines[index].cells = append(cells[:buffer.terminalState.cursorX], append([]Cell{buffer.terminalState.defaultCell}, cells[buffer.terminalState.cursorX:]...)...)
|
||||
buffer.lines[index].cells = append(cells[:buffer.terminalState.cursorX], append([]Cell{buffer.terminalState.DefaultCell(true)}, cells[buffer.terminalState.cursorX:]...)...)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -619,9 +624,9 @@ func (buffer *Buffer) Write(runes ...rune) {
|
|||
}
|
||||
|
||||
for int(buffer.CursorColumn()) >= len(line.cells) {
|
||||
line.cells = append(line.cells, buffer.terminalState.defaultCell)
|
||||
line.cells = append(line.cells, buffer.terminalState.DefaultCell(int(buffer.CursorColumn()) == len(line.cells)))
|
||||
}
|
||||
line.cells[buffer.terminalState.cursorX].attr = buffer.terminalState.cursorAttr
|
||||
line.cells[buffer.terminalState.cursorX].attr = buffer.terminalState.CursorAttr
|
||||
line.cells[buffer.terminalState.cursorX].setRune(r)
|
||||
buffer.incrementCursorPosition()
|
||||
continue
|
||||
|
@ -635,11 +640,11 @@ func (buffer *Buffer) Write(runes ...rune) {
|
|||
|
||||
newLine := buffer.getCurrentLine()
|
||||
if len(newLine.cells) == 0 {
|
||||
newLine.cells = append(newLine.cells, buffer.terminalState.defaultCell)
|
||||
newLine.cells = append(newLine.cells, buffer.terminalState.DefaultCell(true))
|
||||
}
|
||||
cell := &newLine.cells[0]
|
||||
cell.setRune(r)
|
||||
cell.attr = buffer.terminalState.cursorAttr
|
||||
cell.attr = buffer.terminalState.CursorAttr
|
||||
|
||||
} else {
|
||||
// no more room on line and wrapping is disabled
|
||||
|
@ -650,12 +655,12 @@ func (buffer *Buffer) Write(runes ...rune) {
|
|||
} else {
|
||||
|
||||
for int(buffer.CursorColumn()) >= len(line.cells) {
|
||||
line.cells = append(line.cells, buffer.terminalState.defaultCell)
|
||||
line.cells = append(line.cells, buffer.terminalState.DefaultCell(int(buffer.CursorColumn()) == len(line.cells)))
|
||||
}
|
||||
|
||||
cell := &line.cells[buffer.CursorColumn()]
|
||||
cell.setRune(r)
|
||||
cell.attr = buffer.terminalState.cursorAttr
|
||||
cell.attr = buffer.terminalState.CursorAttr
|
||||
}
|
||||
|
||||
buffer.incrementCursorPosition()
|
||||
|
@ -848,7 +853,7 @@ func (buffer *Buffer) EraseLineToCursor() {
|
|||
line := buffer.getCurrentLine()
|
||||
for i := 0; i <= int(buffer.terminalState.cursorX); i++ {
|
||||
if i < len(line.cells) {
|
||||
line.cells[i].erase(buffer.terminalState.defaultCell.attr.BgColour)
|
||||
line.cells[i].erase(buffer.terminalState.CursorAttr.BgColour)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -909,7 +914,7 @@ func (buffer *Buffer) EraseCharacters(n int) {
|
|||
}
|
||||
|
||||
for i := int(buffer.terminalState.cursorX); i < max; i++ {
|
||||
line.cells[i].erase(buffer.terminalState.defaultCell.attr.BgColour)
|
||||
line.cells[i].erase(buffer.terminalState.CursorAttr.BgColour)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -939,7 +944,7 @@ func (buffer *Buffer) EraseDisplayToCursor() {
|
|||
if i >= len(line.cells) {
|
||||
break
|
||||
}
|
||||
line.cells[i].erase(buffer.terminalState.defaultCell.attr.BgColour)
|
||||
line.cells[i].erase(buffer.terminalState.CursorAttr.BgColour)
|
||||
}
|
||||
for i := uint16(0); i < buffer.terminalState.cursorY; i++ {
|
||||
rawLine := buffer.convertViewLineToRawLine(i)
|
||||
|
@ -1086,3 +1091,11 @@ func (buffer *Buffer) Compare(path string) bool {
|
|||
}
|
||||
return bytes.Equal(f, bufferContent)
|
||||
}
|
||||
|
||||
func (buffer *Buffer) ReverseVideo() {
|
||||
defer buffer.emitDisplayChange()
|
||||
|
||||
for _, line := range buffer.lines {
|
||||
line.ReverseVideo()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -393,7 +393,7 @@ func TestGetCellWithBadCursor(t *testing.T) {
|
|||
|
||||
func TestCursorAttr(t *testing.T) {
|
||||
b := NewBuffer(NewTerminalState(80, 2, CellAttributes{}, 1000))
|
||||
assert.Equal(t, &b.terminalState.cursorAttr, b.CursorAttr())
|
||||
assert.Equal(t, &b.terminalState.CursorAttr, b.CursorAttr())
|
||||
}
|
||||
|
||||
func TestCursorPositionQuerying(t *testing.T) {
|
||||
|
|
|
@ -17,7 +17,7 @@ type CellAttributes struct {
|
|||
Dim bool
|
||||
Underline bool
|
||||
Blink bool
|
||||
Reverse bool
|
||||
Inverse bool
|
||||
Hidden bool
|
||||
}
|
||||
|
||||
|
@ -40,20 +40,20 @@ func (cell *Cell) Rune() rune {
|
|||
}
|
||||
|
||||
func (cell *Cell) Fg() [3]float32 {
|
||||
if cell.Attr().Reverse {
|
||||
if cell.Attr().Inverse {
|
||||
return cell.attr.BgColour
|
||||
}
|
||||
return cell.attr.FgColour
|
||||
}
|
||||
|
||||
func (cell *Cell) Bg() [3]float32 {
|
||||
if cell.Attr().Reverse {
|
||||
if cell.Attr().Inverse {
|
||||
return cell.attr.FgColour
|
||||
}
|
||||
return cell.attr.BgColour
|
||||
}
|
||||
|
||||
func (cell *Cell) erase(bgColour [3]float32) {
|
||||
func (cell *Cell) erase(bgColour [3]float32) {
|
||||
cell.setRune(0)
|
||||
cell.attr.BgColour = bgColour
|
||||
}
|
||||
|
@ -69,3 +69,9 @@ func NewBackgroundCell(colour [3]float32) Cell {
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (cellAttr *CellAttributes) ReverseVideo() {
|
||||
oldFgColour := cellAttr.FgColour
|
||||
cellAttr.FgColour = cellAttr.BgColour
|
||||
cellAttr.BgColour = oldFgColour
|
||||
}
|
||||
|
|
|
@ -20,6 +20,12 @@ func (line *Line) Cells() []Cell {
|
|||
return line.cells
|
||||
}
|
||||
|
||||
func (line *Line) ReverseVideo() {
|
||||
for i, _ := range line.cells {
|
||||
line.cells[i].attr.ReverseVideo()
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanse removes null bytes from the end of the row
|
||||
func (line *Line) Cleanse() {
|
||||
cut := 0
|
||||
|
|
|
@ -4,8 +4,7 @@ type TerminalState struct {
|
|||
scrollLinesFromBottom uint
|
||||
cursorX uint16
|
||||
cursorY uint16
|
||||
cursorAttr CellAttributes
|
||||
defaultCell Cell
|
||||
CursorAttr CellAttributes
|
||||
viewHeight uint16
|
||||
viewWidth uint16
|
||||
topMargin uint // see DECSTBM docs - this is for scrollable regions
|
||||
|
@ -13,6 +12,7 @@ type TerminalState struct {
|
|||
ReplaceMode bool // overwrite character at cursor or insert new
|
||||
OriginMode bool // see DECOM docs - whether cursor is positioned within the margins or not
|
||||
LineFeedMode bool
|
||||
ScreenMode bool // DECSCNM (black on white background)
|
||||
AutoWrap bool
|
||||
maxLines uint64
|
||||
tabStops map[uint16]struct{}
|
||||
|
@ -23,9 +23,8 @@ func NewTerminalState(viewCols uint16, viewLines uint16, attr CellAttributes, ma
|
|||
b := &TerminalState{
|
||||
cursorX: 0,
|
||||
cursorY: 0,
|
||||
cursorAttr: attr,
|
||||
CursorAttr: attr,
|
||||
AutoWrap: true,
|
||||
defaultCell: Cell{attr: attr},
|
||||
maxLines: maxLines,
|
||||
viewWidth: viewCols,
|
||||
viewHeight: viewLines,
|
||||
|
@ -36,6 +35,19 @@ func NewTerminalState(viewCols uint16, viewLines uint16, attr CellAttributes, ma
|
|||
return b
|
||||
}
|
||||
|
||||
func (terminalState *TerminalState) DefaultCell(applyEffects bool) Cell {
|
||||
attr := terminalState.CursorAttr
|
||||
if !applyEffects {
|
||||
attr.Blink = false
|
||||
attr.Bold = false
|
||||
attr.Dim = false
|
||||
attr.Inverse = false
|
||||
attr.Underline = false
|
||||
attr.Dim = false
|
||||
}
|
||||
return Cell{attr: attr}
|
||||
}
|
||||
|
||||
func (terminalState *TerminalState) SetVerticalMargins(top uint, bottom uint) {
|
||||
terminalState.topMargin = top
|
||||
terminalState.bottomMargin = bottom
|
||||
|
|
51
gui/gui.go
51
gui/gui.go
|
@ -48,6 +48,7 @@ type GUI struct {
|
|||
resizeLock *sync.Mutex
|
||||
handCursor *glfw.Cursor
|
||||
arrowCursor *glfw.Cursor
|
||||
defaultCell *buffer.Cell
|
||||
|
||||
prevLeftClickX uint16
|
||||
prevLeftClickY uint16
|
||||
|
@ -185,6 +186,22 @@ func (gui *GUI) resizeToTerminal(newCols uint, newRows uint) {
|
|||
gui.window.SetSize(roundedWidth, roundedHeight) // will trigger resize()
|
||||
}
|
||||
|
||||
func (gui *GUI) generateDefaultCell(reverse bool) {
|
||||
color := gui.config.ColourScheme.Background
|
||||
if reverse {
|
||||
color = gui.config.ColourScheme.Foreground
|
||||
}
|
||||
cell := buffer.NewBackgroundCell(color)
|
||||
gui.renderer.backgroundColour = color
|
||||
gui.defaultCell = &cell
|
||||
gl.ClearColor(
|
||||
color[0],
|
||||
color[1],
|
||||
color[2],
|
||||
1.0,
|
||||
)
|
||||
}
|
||||
|
||||
// can only be called on OS thread
|
||||
func (gui *GUI) resize(w *glfw.Window, width int, height int) {
|
||||
|
||||
|
@ -232,7 +249,7 @@ func (gui *GUI) resize(w *glfw.Window, width int, height int) {
|
|||
|
||||
gui.logger.Debugf("Resize complete!")
|
||||
|
||||
gui.redraw(buffer.NewBackgroundCell(gui.config.ColourScheme.Background))
|
||||
gui.redraw()
|
||||
gui.window.SwapBuffers()
|
||||
}
|
||||
|
||||
|
@ -279,6 +296,7 @@ func (gui *GUI) Render() error {
|
|||
|
||||
titleChan := make(chan bool, 1)
|
||||
resizeChan := make(chan bool, 1)
|
||||
reverseChan := make(chan bool, 1)
|
||||
|
||||
gui.renderer = NewOpenGLRenderer(gui.config, gui.fontMap, 0, 0, gui.width, gui.height, gui.colourAttr, program)
|
||||
|
||||
|
@ -297,6 +315,8 @@ func (gui *GUI) Render() error {
|
|||
}
|
||||
})
|
||||
|
||||
gui.generateDefaultCell(false)
|
||||
|
||||
{
|
||||
w, h := gui.window.GetFramebufferSize()
|
||||
gui.resize(gui.window, w, h)
|
||||
|
@ -320,21 +340,13 @@ func (gui *GUI) Render() error {
|
|||
gl.Disable(gl.DEPTH_TEST)
|
||||
gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
||||
|
||||
gl.ClearColor(
|
||||
gui.config.ColourScheme.Background[0],
|
||||
gui.config.ColourScheme.Background[1],
|
||||
gui.config.ColourScheme.Background[2],
|
||||
1.0,
|
||||
)
|
||||
|
||||
gui.terminal.AttachTitleChangeHandler(titleChan)
|
||||
gui.terminal.AttachResizeHandler(resizeChan)
|
||||
gui.terminal.AttachReverseHandler(reverseChan)
|
||||
|
||||
ticker := time.NewTicker(time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
defaultCell := buffer.NewBackgroundCell(gui.config.ColourScheme.Background)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
<-ticker.C
|
||||
|
@ -359,20 +371,25 @@ func (gui *GUI) Render() error {
|
|||
|
||||
for !gui.window.ShouldClose() {
|
||||
|
||||
forceRedraw := false
|
||||
|
||||
select {
|
||||
case <-titleChan:
|
||||
gui.window.SetTitle(gui.terminal.GetTitle())
|
||||
case <-resizeChan:
|
||||
cols, rows := gui.terminal.GetSize()
|
||||
gui.resizeToTerminal(uint(cols), uint(rows))
|
||||
case reverse := <-reverseChan:
|
||||
gui.generateDefaultCell(reverse)
|
||||
forceRedraw = true
|
||||
default:
|
||||
// this is more efficient than glfw.PollEvents()
|
||||
glfw.WaitEventsTimeout(0.02) // up to 50fps on no input, otherwise higher
|
||||
}
|
||||
|
||||
if gui.terminal.CheckDirty() {
|
||||
if gui.terminal.CheckDirty() || forceRedraw {
|
||||
|
||||
gui.redraw(defaultCell)
|
||||
gui.redraw()
|
||||
|
||||
if gui.showDebugInfo {
|
||||
gui.textbox(2, 2, fmt.Sprintf(`Cursor: %d,%d
|
||||
|
@ -422,7 +439,7 @@ Buffer Size: %d lines
|
|||
|
||||
}
|
||||
|
||||
func (gui *GUI) redraw(defaultCell buffer.Cell) {
|
||||
func (gui *GUI) redraw() {
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)
|
||||
lines := gui.terminal.GetVisibleLines()
|
||||
lineCount := int(gui.terminal.ActiveBuffer().ViewHeight())
|
||||
|
@ -446,18 +463,18 @@ func (gui *GUI) redraw(defaultCell buffer.Cell) {
|
|||
colour = nil
|
||||
}
|
||||
|
||||
cell := defaultCell
|
||||
cell := gui.defaultCell
|
||||
if colour != nil || cursor || x < len(cells) {
|
||||
|
||||
if x < len(cells) {
|
||||
cell = cells[x]
|
||||
cell = &cells[x]
|
||||
if cell.Image() != nil {
|
||||
gui.renderer.DrawCellImage(cell, uint(x), uint(y))
|
||||
gui.renderer.DrawCellImage(*cell, uint(x), uint(y))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
gui.renderer.DrawCellBg(cell, uint(x), uint(y), cursor, colour, false)
|
||||
gui.renderer.DrawCellBg(*cell, uint(x), uint(y), cursor, colour, false)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,20 +11,21 @@ import (
|
|||
)
|
||||
|
||||
type OpenGLRenderer struct {
|
||||
areaWidth int
|
||||
areaHeight int
|
||||
areaX int
|
||||
areaY int
|
||||
cellWidth float32
|
||||
cellHeight float32
|
||||
termCols uint
|
||||
termRows uint
|
||||
cellPositions map[[2]uint][2]float32
|
||||
config *config.Config
|
||||
colourAttr uint32
|
||||
program uint32
|
||||
textureMap map[*image.RGBA]uint32
|
||||
fontMap *FontMap
|
||||
areaWidth int
|
||||
areaHeight int
|
||||
areaX int
|
||||
areaY int
|
||||
cellWidth float32
|
||||
cellHeight float32
|
||||
termCols uint
|
||||
termRows uint
|
||||
cellPositions map[[2]uint][2]float32
|
||||
config *config.Config
|
||||
colourAttr uint32
|
||||
program uint32
|
||||
textureMap map[*image.RGBA]uint32
|
||||
fontMap *FontMap
|
||||
backgroundColour [3]float32
|
||||
}
|
||||
|
||||
type rectangle struct {
|
||||
|
@ -185,7 +186,7 @@ func (r *OpenGLRenderer) GetRectangleSize(col uint, row uint) (float32, float32)
|
|||
|
||||
func (r *OpenGLRenderer) getRectangle(col uint, row uint) *rectangle {
|
||||
x := float32(float32(col) * r.cellWidth)
|
||||
y := float32(float32(row) * r.cellHeight) + r.cellHeight
|
||||
y := float32(float32(row)*r.cellHeight) + r.cellHeight
|
||||
|
||||
return r.newRectangle(x, y, r.colourAttr)
|
||||
}
|
||||
|
@ -207,13 +208,17 @@ func (r *OpenGLRenderer) DrawCellBg(cell buffer.Cell, col uint, row uint, cursor
|
|||
} else {
|
||||
|
||||
if cursor {
|
||||
bg = r.config.ColourScheme.Cursor
|
||||
if r.config.ColourScheme.Cursor != r.backgroundColour {
|
||||
bg = r.config.ColourScheme.Cursor
|
||||
} else {
|
||||
bg = cell.Fg()
|
||||
}
|
||||
} else {
|
||||
bg = cell.Bg()
|
||||
}
|
||||
}
|
||||
|
||||
if bg != r.config.ColourScheme.Background || force {
|
||||
if bg != r.backgroundColour || force {
|
||||
rect := r.getRectangle(col, row)
|
||||
rect.setColour(bg)
|
||||
rect.Draw()
|
||||
|
|
|
@ -47,18 +47,13 @@ func csiSetMode(modeStr string, enabled bool, terminal *Terminal) error {
|
|||
terminal.SetSize(80, uint(lines))
|
||||
}
|
||||
terminal.Clear()
|
||||
/*
|
||||
case "?4":
|
||||
// DECSCLM
|
||||
// @todo smooth scrolling / jump scrolling
|
||||
case "?5":
|
||||
// DECSCNM
|
||||
if enabled {
|
||||
// @todo SCreeN Mode, black on white background
|
||||
} else {
|
||||
// @todo Normal screen (white on black background)
|
||||
}
|
||||
*/
|
||||
/*
|
||||
case "?4":
|
||||
// DECSCLM
|
||||
// @todo smooth scrolling / jump scrolling
|
||||
*/
|
||||
case "?5": // DECSCNM
|
||||
terminal.SetScreenMode(enabled)
|
||||
case "?6":
|
||||
// DECOM
|
||||
terminal.SetOriginMode(enabled)
|
||||
|
|
|
@ -35,7 +35,7 @@ func sgrSequenceHandler(params []string, terminal *Terminal) error {
|
|||
case "5", "05":
|
||||
terminal.ActiveBuffer().CursorAttr().Blink = true
|
||||
case "7", "07":
|
||||
terminal.ActiveBuffer().CursorAttr().Reverse = true
|
||||
terminal.ActiveBuffer().CursorAttr().Inverse = true
|
||||
case "8", "08":
|
||||
terminal.ActiveBuffer().CursorAttr().Hidden = true
|
||||
case "21":
|
||||
|
@ -49,7 +49,7 @@ func sgrSequenceHandler(params []string, terminal *Terminal) error {
|
|||
case "25":
|
||||
terminal.ActiveBuffer().CursorAttr().Blink = false
|
||||
case "27":
|
||||
terminal.ActiveBuffer().CursorAttr().Reverse = false
|
||||
terminal.ActiveBuffer().CursorAttr().Inverse = false
|
||||
case "28":
|
||||
terminal.ActiveBuffer().CursorAttr().Hidden = false
|
||||
case "29":
|
||||
|
|
|
@ -41,6 +41,7 @@ type Terminal struct {
|
|||
config *config.Config
|
||||
titleHandlers []chan bool
|
||||
resizeHandlers []chan bool
|
||||
reverseHandlers []chan bool
|
||||
modes Modes
|
||||
mouseMode MouseMode
|
||||
bracketedPasteMode bool
|
||||
|
@ -196,6 +197,10 @@ func (terminal *Terminal) AttachResizeHandler(handler chan bool) {
|
|||
terminal.resizeHandlers = append(terminal.resizeHandlers, handler)
|
||||
}
|
||||
|
||||
func (terminal *Terminal) AttachReverseHandler(handler chan bool) {
|
||||
terminal.reverseHandlers = append(terminal.reverseHandlers, handler)
|
||||
}
|
||||
|
||||
func (terminal *Terminal) Modes() Modes {
|
||||
return terminal.modes
|
||||
}
|
||||
|
@ -216,6 +221,14 @@ func (terminal *Terminal) emitResize() {
|
|||
}
|
||||
}
|
||||
|
||||
func (terminal *Terminal) emitReverse(reverse bool) {
|
||||
for _, h := range terminal.reverseHandlers {
|
||||
go func(c chan bool) {
|
||||
c <- reverse
|
||||
}(h)
|
||||
}
|
||||
}
|
||||
|
||||
func (terminal *Terminal) GetLogicalCursorX() uint16 {
|
||||
if terminal.ActiveBuffer().CursorColumn() >= terminal.ActiveBuffer().Width() {
|
||||
return 0
|
||||
|
@ -226,10 +239,10 @@ func (terminal *Terminal) GetLogicalCursorX() uint16 {
|
|||
|
||||
func (terminal *Terminal) GetLogicalCursorY() uint16 {
|
||||
if terminal.ActiveBuffer().CursorColumn() >= terminal.ActiveBuffer().Width() {
|
||||
return terminal.ActiveBuffer().CursorLine() + 1
|
||||
return terminal.ActiveBuffer().CursorLineAbsolute() + 1
|
||||
}
|
||||
|
||||
return terminal.ActiveBuffer().CursorLine()
|
||||
return terminal.ActiveBuffer().CursorLineAbsolute()
|
||||
}
|
||||
|
||||
func (terminal *Terminal) GetTitle() string {
|
||||
|
@ -349,3 +362,15 @@ func (terminal *Terminal) SetLineFeedMode() {
|
|||
func (terminal *Terminal) ResetVerticalMargins() {
|
||||
terminal.terminalState.ResetVerticalMargins()
|
||||
}
|
||||
|
||||
func (terminal *Terminal) SetScreenMode(enabled bool) {
|
||||
if terminal.terminalState.ScreenMode == enabled {
|
||||
return
|
||||
}
|
||||
terminal.terminalState.ScreenMode = enabled
|
||||
terminal.terminalState.CursorAttr.ReverseVideo()
|
||||
for _, buffer := range terminal.buffers {
|
||||
buffer.ReverseVideo()
|
||||
}
|
||||
terminal.emitReverse(enabled)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue