Terminal: Support setting the window title using Xterm escape sequences.

Use this in the /bin/sh prompt to keep the window title in sync with the
shell's working directory. :^)
This commit is contained in:
Andreas Kling 2019-01-25 05:51:39 +01:00
parent 5f14e22a31
commit 5adaeeaa3b
Notes: sideshowbarker 2024-07-19 15:57:08 +09:00
3 changed files with 60 additions and 1 deletions

View file

@ -356,6 +356,24 @@ void Terminal::escape$J(const Vector<unsigned>& params)
} }
} }
void Terminal::execute_xterm_command()
{
bool ok;
unsigned value = parseUInt(String((const char*)m_xterm_param1.data(), m_xterm_param1.size()), ok);
if (ok) {
switch (value) {
case 0:
set_window_title(String((const char*)m_xterm_param2.data(), m_xterm_param2.size()));
break;
default:
notImplemented();
break;
}
}
m_xterm_param1.clear_with_capacity();
m_xterm_param2.clear_with_capacity();
}
void Terminal::execute_escape_sequence(byte final) void Terminal::execute_escape_sequence(byte final)
{ {
auto paramparts = String((const char*)m_parameters.data(), m_parameters.size()).split(';'); auto paramparts = String((const char*)m_parameters.data(), m_parameters.size()).split(';');
@ -437,9 +455,31 @@ void Terminal::on_char(byte ch)
case ExpectBracket: case ExpectBracket:
if (ch == '[') if (ch == '[')
m_escape_state = ExpectParameter; m_escape_state = ExpectParameter;
else if (ch == ']')
m_escape_state = ExpectXtermParameter1;
else else
m_escape_state = Normal; m_escape_state = Normal;
return; return;
case ExpectXtermParameter1:
if (ch != ';') {
m_xterm_param1.append(ch);
return;
}
m_escape_state = ExpectXtermParameter2;
return;
case ExpectXtermParameter2:
if (ch != '\007') {
m_xterm_param2.append(ch);
return;
}
m_escape_state = ExpectXtermFinal;
// fall through
case ExpectXtermFinal:
m_escape_state = Normal;
if (ch == '\007')
execute_xterm_command();
return;
case ExpectParameter: case ExpectParameter:
if (is_valid_parameter_character(ch)) { if (is_valid_parameter_character(ch)) {
m_parameters.append(ch); m_parameters.append(ch);
@ -640,6 +680,15 @@ void Terminal::invalidate_window(const Rect& a_rect)
} }
} }
void Terminal::set_window_title(const String& title)
{
int rc = gui_set_window_title(m_window_id, title.characters(), title.length());
if (rc < 0) {
perror("gui_set_window_title");
exit(1);
}
}
void Terminal::set_in_active_window(bool b) void Terminal::set_in_active_window(bool b)
{ {
if (m_in_active_window == b) if (m_in_active_window == b)

View file

@ -26,6 +26,7 @@ private:
void put_character_at(unsigned row, unsigned column, byte ch); void put_character_at(unsigned row, unsigned column, byte ch);
void invalidate_cursor(); void invalidate_cursor();
void invalidate_window(const Rect& = Rect()); void invalidate_window(const Rect& = Rect());
void set_window_title(const String&);
void escape$A(const Vector<unsigned>&); void escape$A(const Vector<unsigned>&);
void escape$B(const Vector<unsigned>&); void escape$B(const Vector<unsigned>&);
@ -88,6 +89,7 @@ private:
Attribute& attribute_at(word row, word column); Attribute& attribute_at(word row, word column);
void execute_escape_sequence(byte final); void execute_escape_sequence(byte final);
void execute_xterm_command();
enum EscapeState { enum EscapeState {
Normal, Normal,
@ -95,10 +97,16 @@ private:
ExpectParameter, ExpectParameter,
ExpectIntermediate, ExpectIntermediate,
ExpectFinal, ExpectFinal,
ExpectXtermParameter1,
ExpectXtermParameter2,
ExpectXtermFinal,
}; };
EscapeState m_escape_state { Normal }; EscapeState m_escape_state { Normal };
Vector<byte> m_parameters; Vector<byte> m_parameters;
Vector<byte> m_intermediates; Vector<byte> m_intermediates;
Vector<byte> m_xterm_param1;
Vector<byte> m_xterm_param2;
byte* m_horizontal_tabs { nullptr }; byte* m_horizontal_tabs { nullptr };
bool m_belling { false }; bool m_belling { false };

View file

@ -26,8 +26,10 @@ static void prompt()
{ {
if (g->uid == 0) if (g->uid == 0)
printf("# "); printf("# ");
else else {
printf("\033]0;%s@%s:%s\007", g->username.characters(), g->hostname, g->cwd.characters());
printf("\033[31;1m%s\033[0m@\033[37;1m%s\033[0m:\033[32;1m%s\033[0m$> ", g->username.characters(), g->hostname, g->cwd.characters()); printf("\033[31;1m%s\033[0m@\033[37;1m%s\033[0m:\033[32;1m%s\033[0m$> ", g->username.characters(), g->hostname, g->cwd.characters());
}
fflush(stdout); fflush(stdout);
} }