mirror of https://github.com/gdamore/tcell.git
fixes #710 Add support for setting the window title
This commit is contained in:
parent
887cf2766e
commit
c9ba0cf327
|
@ -123,6 +123,7 @@ func main() {
|
|||
fmt.Fprintf(os.Stderr, "%v\n", e)
|
||||
os.Exit(1)
|
||||
}
|
||||
s.SetTitle("Tcell Mouse Demonstration")
|
||||
defStyle = tcell.StyleDefault.
|
||||
Background(tcell.ColorReset).
|
||||
Foreground(tcell.ColorReset)
|
||||
|
|
|
@ -109,6 +109,9 @@ func main() {
|
|||
Background(tcell.ColorWhite))
|
||||
s.Clear()
|
||||
|
||||
// we can even try to use unicode window titles!
|
||||
s.SetTitle("Unicode Demonstration -- 🤯")
|
||||
|
||||
quit := make(chan struct{})
|
||||
|
||||
style = bold
|
||||
|
|
|
@ -42,6 +42,7 @@ type cScreen struct {
|
|||
truecolor bool
|
||||
running bool
|
||||
disableAlt bool // disable the alternate screen
|
||||
title string
|
||||
|
||||
w int
|
||||
h int
|
||||
|
@ -176,6 +177,9 @@ const (
|
|||
vtExitUrl = "\x1b]8;;\x1b\\"
|
||||
vtCursorColorRGB = "\x1b]12;#%02x%02x%02x\007"
|
||||
vtCursorColorReset = "\x1b]112\007"
|
||||
vtSaveTitle = "\x1b[22;2t"
|
||||
vtRestoreTitle = "\x1b[23;2t"
|
||||
vtSetTitle = "\x1b]2;%s\x1b\\"
|
||||
)
|
||||
|
||||
var vtCursorStyles = map[CursorStyle]string{
|
||||
|
@ -350,6 +354,7 @@ func (s *cScreen) disengage() {
|
|||
s.emitVtString(vtCursorColorReset)
|
||||
s.emitVtString(vtEnableAm)
|
||||
if !s.disableAlt {
|
||||
s.emitVtString(vtRestoreTitle)
|
||||
s.emitVtString(vtExitCA)
|
||||
}
|
||||
} else if !s.disableAlt {
|
||||
|
@ -387,9 +392,13 @@ func (s *cScreen) engage() error {
|
|||
if s.vten {
|
||||
s.setOutMode(modeVtOutput | modeNoAutoNL | modeCookedOut | modeUnderline)
|
||||
if !s.disableAlt {
|
||||
s.emitVtString(vtSaveTitle)
|
||||
s.emitVtString(vtEnterCA)
|
||||
}
|
||||
s.emitVtString(vtDisableAm)
|
||||
if s.title != "" {
|
||||
s.emitVtString(fmt.Sprintf(vtSetTitle, s.title))
|
||||
}
|
||||
} else {
|
||||
s.setOutMode(0)
|
||||
}
|
||||
|
@ -1275,6 +1284,15 @@ func (s *cScreen) SetStyle(style Style) {
|
|||
s.Unlock()
|
||||
}
|
||||
|
||||
func (s *cScreen) SetTitle(title string) {
|
||||
s.Lock()
|
||||
s.title = title
|
||||
if s.vten {
|
||||
s.emitVtString(fmt.Sprintf(vtSetTitle, title))
|
||||
}
|
||||
s.Unlock()
|
||||
}
|
||||
|
||||
// No fallback rune support, since we have Unicode. Yay!
|
||||
|
||||
func (s *cScreen) RegisterRuneFallback(_ rune, _ string) {
|
||||
|
|
|
@ -266,6 +266,12 @@ type Screen interface {
|
|||
// Tty returns the underlying Tty. If the screen is not a terminal, the
|
||||
// returned bool will be false
|
||||
Tty() (Tty, bool)
|
||||
|
||||
// SetTitle sets a window title on the screen.
|
||||
// Terminals may be configured to ignore this, or unable to.
|
||||
// Tcell may attempt to save and restore the window title on entry and exit, but
|
||||
// the results may vary. Use of unicode characters may not be supported.
|
||||
SetTitle(string)
|
||||
}
|
||||
|
||||
// NewScreen returns a default Screen suitable for the user's terminal
|
||||
|
@ -335,6 +341,7 @@ type screenImpl interface {
|
|||
Resume() error
|
||||
Beep() error
|
||||
SetSize(int, int)
|
||||
SetTitle(string)
|
||||
Tty() (Tty, bool)
|
||||
|
||||
// Following methods are not part of the Screen api, but are used for interaction with
|
||||
|
|
10
sim_test.go
10
sim_test.go
|
@ -150,3 +150,13 @@ func TestBeep(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTitle(t *testing.T) {
|
||||
s := mkTestScreen(t, "")
|
||||
defer s.Fini()
|
||||
s.SetTitle("My Title")
|
||||
s.Show()
|
||||
if s.GetTitle() != "My Title" {
|
||||
t.Errorf("Title mismatched")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,9 @@ type SimulationScreen interface {
|
|||
|
||||
// GetCursor returns the cursor details.
|
||||
GetCursor() (x int, y int, visible bool)
|
||||
|
||||
// GetTitle gets the set title
|
||||
GetTitle() string
|
||||
}
|
||||
|
||||
// SimCell represents a simulated screen cell. The purpose of this
|
||||
|
@ -98,6 +101,7 @@ type simscreen struct {
|
|||
fillchar rune
|
||||
fillstyle Style
|
||||
fallback map[rune]string
|
||||
title string
|
||||
|
||||
Screen
|
||||
sync.Mutex
|
||||
|
@ -495,3 +499,11 @@ func (s *simscreen) EventQ() chan Event {
|
|||
func (s *simscreen) StopQ() <-chan struct{} {
|
||||
return s.quit
|
||||
}
|
||||
|
||||
func (s *simscreen) SetTitle(title string) {
|
||||
s.title = title
|
||||
}
|
||||
|
||||
func (s *simscreen) GetTitle() string {
|
||||
return s.title
|
||||
}
|
||||
|
|
|
@ -233,6 +233,7 @@ type Terminfo struct {
|
|||
EnterUrl string
|
||||
ExitUrl string
|
||||
SetWindowSize string
|
||||
SetWindowTitle string // no terminfo extension
|
||||
EnableFocusReporting string
|
||||
DisableFocusReporting string
|
||||
DisableAutoMargin string // smam
|
||||
|
|
40
tscreen.go
40
tscreen.go
|
@ -171,6 +171,10 @@ type tScreen struct {
|
|||
mouseFlags MouseFlags
|
||||
pasteEnabled bool
|
||||
focusEnabled bool
|
||||
setTitle string
|
||||
saveTitle string
|
||||
restoreTitle string
|
||||
title string
|
||||
|
||||
sync.Mutex
|
||||
}
|
||||
|
@ -414,27 +418,37 @@ func (t *tScreen) prepareExtendedOSC() {
|
|||
if t.ti.EnterUrl != "" {
|
||||
t.enterUrl = t.ti.EnterUrl
|
||||
t.exitUrl = t.ti.ExitUrl
|
||||
} else if t.ti.Mouse != "" {
|
||||
} else if t.ti.Mouse != "" || t.ti.XTermLike {
|
||||
t.enterUrl = "\x1b]8;%p2%s;%p1%s\x1b\\"
|
||||
t.exitUrl = "\x1b]8;;\x1b\\"
|
||||
}
|
||||
|
||||
if t.ti.SetWindowSize != "" {
|
||||
t.setWinSize = t.ti.SetWindowSize
|
||||
} else if t.ti.Mouse != "" {
|
||||
} else if t.ti.Mouse != "" || t.ti.XTermLike {
|
||||
t.setWinSize = "\x1b[8;%p1%p2%d;%dt"
|
||||
}
|
||||
|
||||
if t.ti.EnableFocusReporting != "" {
|
||||
t.enableFocus = t.ti.EnableFocusReporting
|
||||
} else if t.ti.Mouse != "" {
|
||||
} else if t.ti.Mouse != "" || t.ti.XTermLike {
|
||||
t.enableFocus = "\x1b[?1004h"
|
||||
}
|
||||
if t.ti.DisableFocusReporting != "" {
|
||||
t.disableFocus = t.ti.DisableFocusReporting
|
||||
} else if t.ti.Mouse != "" {
|
||||
} else if t.ti.Mouse != "" || t.ti.XTermLike {
|
||||
t.disableFocus = "\x1b[?1004l"
|
||||
}
|
||||
|
||||
if t.ti.SetWindowTitle != "" {
|
||||
t.setTitle = t.ti.SetWindowTitle
|
||||
} else if t.ti.XTermLike {
|
||||
t.saveTitle = "\x1b[22;2t"
|
||||
t.restoreTitle = "\x1b[23;2t"
|
||||
// this also tries to request that UTF-8 is allowed in the title
|
||||
t.setTitle = "\x1b[>2t\x1b]2;%p1%s\x1b\\"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tScreen) prepareCursorStyles() {
|
||||
|
@ -1938,12 +1952,18 @@ func (t *tScreen) engage() error {
|
|||
// (In theory there could be terminals that don't support X,Y cursor
|
||||
// positions without a setup command, but we don't support them.)
|
||||
t.TPuts(ti.EnterCA)
|
||||
if t.saveTitle != "" {
|
||||
t.TPuts(t.saveTitle)
|
||||
}
|
||||
}
|
||||
t.TPuts(ti.EnterKeypad)
|
||||
t.TPuts(ti.HideCursor)
|
||||
t.TPuts(ti.EnableAcs)
|
||||
t.TPuts(ti.DisableAutoMargin)
|
||||
t.TPuts(ti.Clear)
|
||||
if t.title != "" && t.setTitle != "" {
|
||||
t.TPuts(t.ti.TParm(t.setTitle, t.title))
|
||||
}
|
||||
|
||||
t.wg.Add(2)
|
||||
go t.inputLoop(stopQ)
|
||||
|
@ -1987,6 +2007,9 @@ func (t *tScreen) disengage() {
|
|||
t.TPuts(ti.ExitKeypad)
|
||||
t.TPuts(ti.EnableAutoMargin)
|
||||
if os.Getenv("TCELL_ALTSCREEN") != "disable" {
|
||||
if t.restoreTitle != "" {
|
||||
t.TPuts(t.restoreTitle)
|
||||
}
|
||||
t.TPuts(ti.Clear) // only needed if ExitCA is empty
|
||||
t.TPuts(ti.ExitCA)
|
||||
}
|
||||
|
@ -2021,3 +2044,12 @@ func (t *tScreen) EventQ() chan Event {
|
|||
func (t *tScreen) GetCells() *CellBuffer {
|
||||
return &t.cells
|
||||
}
|
||||
|
||||
func (t *tScreen) SetTitle(title string) {
|
||||
t.Lock()
|
||||
t.title = title
|
||||
if t.setTitle != "" && t.running {
|
||||
t.TPuts(t.ti.TParm(t.setTitle, title))
|
||||
}
|
||||
t.Unlock()
|
||||
}
|
||||
|
|
|
@ -222,6 +222,10 @@ function beep() {
|
|||
beepAudio.play();
|
||||
}
|
||||
|
||||
function setTitle(title) {
|
||||
document.title = title;
|
||||
}
|
||||
|
||||
function intToHex(n) {
|
||||
return "#" + n.toString(16).padStart(6, "0");
|
||||
}
|
||||
|
|
|
@ -523,6 +523,10 @@ func (t *wScreen) StopQ() <-chan struct{} {
|
|||
return t.quit
|
||||
}
|
||||
|
||||
func (t *wScreen) SetTitle(title string) {
|
||||
js.Global().Call("setTitle", title)
|
||||
}
|
||||
|
||||
// WebKeyNames maps string names reported from HTML
|
||||
// (KeyboardEvent.key) to tcell accepted keys.
|
||||
var WebKeyNames = map[string]Key{
|
||||
|
|
Loading…
Reference in New Issue