diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-01-25 05:51:39 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-01-25 05:52:16 +0100 |
commit | 5adaeeaa3bed7f3022cc11d03eeb1b3426d7c200 (patch) | |
tree | fda28db007acd51b64112406838d44fd097b9a6f | |
parent | 5f14e22a31855465f251ad7eac014d7b46aab1b1 (diff) | |
download | serenity-5adaeeaa3bed7f3022cc11d03eeb1b3426d7c200.zip |
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. :^)
-rw-r--r-- | Terminal/Terminal.cpp | 49 | ||||
-rw-r--r-- | Terminal/Terminal.h | 8 | ||||
-rw-r--r-- | Userland/sh.cpp | 4 |
3 files changed, 60 insertions, 1 deletions
diff --git a/Terminal/Terminal.cpp b/Terminal/Terminal.cpp index 467f63608d..a4a00df443 100644 --- a/Terminal/Terminal.cpp +++ b/Terminal/Terminal.cpp @@ -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) { auto paramparts = String((const char*)m_parameters.data(), m_parameters.size()).split(';'); @@ -437,9 +455,31 @@ void Terminal::on_char(byte ch) case ExpectBracket: if (ch == '[') m_escape_state = ExpectParameter; + else if (ch == ']') + m_escape_state = ExpectXtermParameter1; else m_escape_state = Normal; 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: if (is_valid_parameter_character(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) { if (m_in_active_window == b) diff --git a/Terminal/Terminal.h b/Terminal/Terminal.h index 151a610ae3..3c8f6a2a1f 100644 --- a/Terminal/Terminal.h +++ b/Terminal/Terminal.h @@ -26,6 +26,7 @@ private: void put_character_at(unsigned row, unsigned column, byte ch); void invalidate_cursor(); void invalidate_window(const Rect& = Rect()); + void set_window_title(const String&); void escape$A(const Vector<unsigned>&); void escape$B(const Vector<unsigned>&); @@ -88,6 +89,7 @@ private: Attribute& attribute_at(word row, word column); void execute_escape_sequence(byte final); + void execute_xterm_command(); enum EscapeState { Normal, @@ -95,10 +97,16 @@ private: ExpectParameter, ExpectIntermediate, ExpectFinal, + + ExpectXtermParameter1, + ExpectXtermParameter2, + ExpectXtermFinal, }; EscapeState m_escape_state { Normal }; Vector<byte> m_parameters; Vector<byte> m_intermediates; + Vector<byte> m_xterm_param1; + Vector<byte> m_xterm_param2; byte* m_horizontal_tabs { nullptr }; bool m_belling { false }; diff --git a/Userland/sh.cpp b/Userland/sh.cpp index d94113ab21..38976a2751 100644 --- a/Userland/sh.cpp +++ b/Userland/sh.cpp @@ -26,8 +26,10 @@ static void prompt() { if (g->uid == 0) 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()); + } fflush(stdout); } |