Support setting window title (as OS command)
This commit is contained in:
@@ -50,3 +50,18 @@ void Esc_Dispatch::act_on_terminal( Terminal::Emulator *emu )
|
||||
{
|
||||
emu->Esc_dispatch( this );
|
||||
}
|
||||
|
||||
void OSC_Put::act_on_terminal( Terminal::Emulator *emu )
|
||||
{
|
||||
emu->dispatch.OSC_put( this );
|
||||
}
|
||||
|
||||
void OSC_Start::act_on_terminal( Terminal::Emulator *emu )
|
||||
{
|
||||
emu->dispatch.OSC_start( this );
|
||||
}
|
||||
|
||||
void OSC_End::act_on_terminal( Terminal::Emulator *emu )
|
||||
{
|
||||
emu->OSC_end( this );
|
||||
}
|
||||
|
||||
+9
-3
@@ -73,13 +73,19 @@ namespace Parser {
|
||||
public: std::string name( void ) { return std::string( "Unhook" ); }
|
||||
};
|
||||
class OSC_Start : public Action {
|
||||
public: std::string name( void ) { return std::string( "OSC_Start" ); }
|
||||
public:
|
||||
std::string name( void ) { return std::string( "OSC_Start" ); }
|
||||
void act_on_terminal( Terminal::Emulator *emu );
|
||||
};
|
||||
class OSC_Put : public Action {
|
||||
public: std::string name( void ) { return std::string( "OSC_Put" ); }
|
||||
public:
|
||||
std::string name( void ) { return std::string( "OSC_Put" ); }
|
||||
void act_on_terminal( Terminal::Emulator *emu );
|
||||
};
|
||||
class OSC_End : public Action {
|
||||
public: std::string name( void ) { return std::string( "OSC_End" ); }
|
||||
public:
|
||||
std::string name( void ) { return std::string( "OSC_End" ); }
|
||||
void act_on_terminal( Terminal::Emulator *emu );
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +120,12 @@ void Emulator::CSI_dispatch( Parser::CSI_Dispatch *act )
|
||||
dispatch.dispatch( CSI, act, &fb );
|
||||
}
|
||||
|
||||
void Emulator::OSC_end( Parser::OSC_End *act )
|
||||
{
|
||||
fb.ds.next_print_will_wrap = false;
|
||||
dispatch.OSC_dispatch( act, &fb );
|
||||
}
|
||||
|
||||
void Emulator::Esc_dispatch( Parser::Esc_Dispatch *act )
|
||||
{
|
||||
fb.ds.next_print_will_wrap = false;
|
||||
@@ -140,6 +146,18 @@ void Emulator::debug_printout( int fd )
|
||||
std::string screen;
|
||||
screen.append( "\033[H" );
|
||||
|
||||
/* set window title */
|
||||
screen.append( "\033]0;" );
|
||||
std::vector<wchar_t> window_title = fb.get_window_title();
|
||||
for ( std::vector<wchar_t>::iterator i = window_title.begin();
|
||||
i != window_title.end();
|
||||
i++ ) {
|
||||
char utf8[ 8 ];
|
||||
snprintf( utf8, 8, "%lc", *i );
|
||||
screen.append( utf8 );
|
||||
}
|
||||
screen.append( "\x7" ); /* xterm's "OSC" string ends in BEL... */
|
||||
|
||||
for ( int y = 0; y < fb.ds.get_height(); y++ ) {
|
||||
for ( int x = 0; x < fb.ds.get_width(); /* let charwidth handle advance */ ) {
|
||||
char curmove[ 32 ];
|
||||
|
||||
+4
-10
@@ -19,6 +19,9 @@ namespace Terminal {
|
||||
friend void Parser::Collect::act_on_terminal( Emulator * );
|
||||
friend void Parser::CSI_Dispatch::act_on_terminal( Emulator * );
|
||||
friend void Parser::Esc_Dispatch::act_on_terminal( Emulator * );
|
||||
friend void Parser::OSC_Start::act_on_terminal( Emulator * );
|
||||
friend void Parser::OSC_Put::act_on_terminal( Emulator * );
|
||||
friend void Parser::OSC_End::act_on_terminal( Emulator * );
|
||||
|
||||
private:
|
||||
Parser::UTF8Parser parser;
|
||||
@@ -28,18 +31,9 @@ namespace Terminal {
|
||||
/* action methods */
|
||||
void print( Parser::Print *act );
|
||||
void execute( Parser::Execute *act );
|
||||
void param( Parser::Param *act );
|
||||
void collect( Parser::Collect *act );
|
||||
void clear( Parser::Clear *act );
|
||||
void CSI_dispatch( Parser::CSI_Dispatch *act );
|
||||
void Esc_dispatch( Parser::Esc_Dispatch *act );
|
||||
|
||||
/* CSI and Escape methods */
|
||||
void CSI_EL( void );
|
||||
void CSI_ED( void );
|
||||
void CSI_cursormove( void );
|
||||
void CSI_DA( void );
|
||||
void Esc_DECALN( void );
|
||||
void OSC_end( Parser::OSC_End *act );
|
||||
|
||||
public:
|
||||
Emulator( size_t s_width, size_t s_height );
|
||||
|
||||
+17
-3
@@ -9,7 +9,7 @@ using namespace Terminal;
|
||||
|
||||
Dispatcher::Dispatcher()
|
||||
: params(), parsed_params(), parsed( false ), dispatch_chars(),
|
||||
terminal_to_host()
|
||||
OSC_string(), terminal_to_host()
|
||||
{}
|
||||
|
||||
void Dispatcher::newparamchar( Parser::Param *act )
|
||||
@@ -146,8 +146,7 @@ Function::Function( Function_Type type, std::string dispatch_chars,
|
||||
void Dispatcher::dispatch( Function_Type type, Parser::Action *act, Framebuffer *fb )
|
||||
{
|
||||
/* add final char to dispatch key */
|
||||
|
||||
if ( type != CONTROL ) {
|
||||
if ( (type == ESCAPE) || (type == CSI) ) {
|
||||
assert( act->char_present );
|
||||
Parser::Collect act2;
|
||||
act2.char_present = true;
|
||||
@@ -177,3 +176,18 @@ void Dispatcher::dispatch( Function_Type type, Parser::Action *act, Framebuffer
|
||||
return i->second.function( fb, this );
|
||||
}
|
||||
}
|
||||
|
||||
void Dispatcher::OSC_put( Parser::OSC_Put *act )
|
||||
{
|
||||
assert( act->char_present );
|
||||
if ( OSC_string.size() < 256 ) { /* should be a long enough window title */
|
||||
OSC_string.push_back( act->ch );
|
||||
act->handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Dispatcher::OSC_start( Parser::OSC_Start *act )
|
||||
{
|
||||
OSC_string.clear();
|
||||
act->handled = true;
|
||||
}
|
||||
|
||||
+10
-1
@@ -13,6 +13,9 @@ namespace Parser {
|
||||
class Esc_Dispatch;
|
||||
class CSI_Dispatch;
|
||||
class Execute;
|
||||
class OSC_Start;
|
||||
class OSC_Put;
|
||||
class OSC_End;
|
||||
}
|
||||
|
||||
namespace Terminal {
|
||||
@@ -49,6 +52,7 @@ namespace Terminal {
|
||||
bool parsed;
|
||||
|
||||
std::string dispatch_chars;
|
||||
std::vector<wchar_t> OSC_string; /* only used to set the window title */
|
||||
|
||||
void parse_params( void );
|
||||
|
||||
@@ -66,7 +70,12 @@ namespace Terminal {
|
||||
std::string str( void );
|
||||
|
||||
void dispatch( Function_Type type, Parser::Action *act, Framebuffer *fb );
|
||||
const std::string get_dispatch_chars( void ) { return dispatch_chars; }
|
||||
std::string get_dispatch_chars( void ) { return dispatch_chars; }
|
||||
std::vector<wchar_t> get_OSC_string( void ) { return OSC_string; }
|
||||
|
||||
void OSC_put( Parser::OSC_Put *act );
|
||||
void OSC_start( Parser::OSC_Start *act );
|
||||
void OSC_dispatch( Parser::OSC_End *act, Framebuffer *fb );
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ DrawState::DrawState( int s_width, int s_height )
|
||||
}
|
||||
|
||||
Framebuffer::Framebuffer( int s_width, int s_height )
|
||||
: rows( s_height, Row( s_width ) ), ds( s_width, s_height )
|
||||
: rows( s_height, Row( s_width ) ), window_title(), ds( s_width, s_height )
|
||||
{}
|
||||
|
||||
void Framebuffer::scroll( int N )
|
||||
@@ -311,6 +311,7 @@ void Framebuffer::reset( void )
|
||||
{
|
||||
int width = ds.get_width(), height = ds.get_height();
|
||||
rows = std::deque<Row>( height, Row( width ) );
|
||||
window_title.clear();
|
||||
ds = DrawState( width, height );
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <string>
|
||||
|
||||
/* Terminal framebuffer */
|
||||
|
||||
@@ -109,6 +110,7 @@ namespace Terminal {
|
||||
class Framebuffer {
|
||||
private:
|
||||
std::deque<Row> rows;
|
||||
std::vector<wchar_t> window_title;
|
||||
|
||||
void scroll( int N );
|
||||
|
||||
@@ -132,6 +134,9 @@ namespace Terminal {
|
||||
|
||||
void reset( void );
|
||||
void soft_reset( void );
|
||||
|
||||
void set_window_title( std::vector<wchar_t> s ) { window_title = s; }
|
||||
std::vector<wchar_t> get_window_title( void ) { return window_title; }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
#include "terminaldispatcher.hpp"
|
||||
#include "terminalframebuffer.hpp"
|
||||
#include "parseraction.hpp"
|
||||
|
||||
using namespace Terminal;
|
||||
|
||||
@@ -457,3 +459,18 @@ void CSI_DECSTR( Framebuffer *fb, Dispatcher *dispatch __attribute((unused)) )
|
||||
}
|
||||
|
||||
static Function func_CSI_DECSTR( CSI, "!p", CSI_DECSTR );
|
||||
|
||||
/* xterm uses an Operating System Command to set the window title */
|
||||
void Dispatcher::OSC_dispatch( Parser::OSC_End *act, Framebuffer *fb )
|
||||
{
|
||||
if ( OSC_string.size() >= 2 ) {
|
||||
if ( (OSC_string[ 0 ] == L'0')
|
||||
&& (OSC_string[ 1 ] == L';') ) {
|
||||
std::vector<wchar_t> newtitle = OSC_string;
|
||||
newtitle.erase( newtitle.begin() );
|
||||
newtitle.erase( newtitle.begin() );
|
||||
fb->set_window_title( newtitle );
|
||||
act->handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user