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 );
|
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" ); }
|
public: std::string name( void ) { return std::string( "Unhook" ); }
|
||||||
};
|
};
|
||||||
class OSC_Start : public Action {
|
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 {
|
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 {
|
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 );
|
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 )
|
void Emulator::Esc_dispatch( Parser::Esc_Dispatch *act )
|
||||||
{
|
{
|
||||||
fb.ds.next_print_will_wrap = false;
|
fb.ds.next_print_will_wrap = false;
|
||||||
@@ -140,6 +146,18 @@ void Emulator::debug_printout( int fd )
|
|||||||
std::string screen;
|
std::string screen;
|
||||||
screen.append( "\033[H" );
|
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 y = 0; y < fb.ds.get_height(); y++ ) {
|
||||||
for ( int x = 0; x < fb.ds.get_width(); /* let charwidth handle advance */ ) {
|
for ( int x = 0; x < fb.ds.get_width(); /* let charwidth handle advance */ ) {
|
||||||
char curmove[ 32 ];
|
char curmove[ 32 ];
|
||||||
|
|||||||
+4
-10
@@ -19,6 +19,9 @@ namespace Terminal {
|
|||||||
friend void Parser::Collect::act_on_terminal( Emulator * );
|
friend void Parser::Collect::act_on_terminal( Emulator * );
|
||||||
friend void Parser::CSI_Dispatch::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::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:
|
private:
|
||||||
Parser::UTF8Parser parser;
|
Parser::UTF8Parser parser;
|
||||||
@@ -28,18 +31,9 @@ namespace Terminal {
|
|||||||
/* action methods */
|
/* action methods */
|
||||||
void print( Parser::Print *act );
|
void print( Parser::Print *act );
|
||||||
void execute( Parser::Execute *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 CSI_dispatch( Parser::CSI_Dispatch *act );
|
||||||
void Esc_dispatch( Parser::Esc_Dispatch *act );
|
void Esc_dispatch( Parser::Esc_Dispatch *act );
|
||||||
|
void OSC_end( Parser::OSC_End *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 );
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Emulator( size_t s_width, size_t s_height );
|
Emulator( size_t s_width, size_t s_height );
|
||||||
|
|||||||
+17
-3
@@ -9,7 +9,7 @@ using namespace Terminal;
|
|||||||
|
|
||||||
Dispatcher::Dispatcher()
|
Dispatcher::Dispatcher()
|
||||||
: params(), parsed_params(), parsed( false ), dispatch_chars(),
|
: params(), parsed_params(), parsed( false ), dispatch_chars(),
|
||||||
terminal_to_host()
|
OSC_string(), terminal_to_host()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void Dispatcher::newparamchar( Parser::Param *act )
|
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 )
|
void Dispatcher::dispatch( Function_Type type, Parser::Action *act, Framebuffer *fb )
|
||||||
{
|
{
|
||||||
/* add final char to dispatch key */
|
/* add final char to dispatch key */
|
||||||
|
if ( (type == ESCAPE) || (type == CSI) ) {
|
||||||
if ( type != CONTROL ) {
|
|
||||||
assert( act->char_present );
|
assert( act->char_present );
|
||||||
Parser::Collect act2;
|
Parser::Collect act2;
|
||||||
act2.char_present = true;
|
act2.char_present = true;
|
||||||
@@ -177,3 +176,18 @@ void Dispatcher::dispatch( Function_Type type, Parser::Action *act, Framebuffer
|
|||||||
return i->second.function( fb, this );
|
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 Esc_Dispatch;
|
||||||
class CSI_Dispatch;
|
class CSI_Dispatch;
|
||||||
class Execute;
|
class Execute;
|
||||||
|
class OSC_Start;
|
||||||
|
class OSC_Put;
|
||||||
|
class OSC_End;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Terminal {
|
namespace Terminal {
|
||||||
@@ -49,6 +52,7 @@ namespace Terminal {
|
|||||||
bool parsed;
|
bool parsed;
|
||||||
|
|
||||||
std::string dispatch_chars;
|
std::string dispatch_chars;
|
||||||
|
std::vector<wchar_t> OSC_string; /* only used to set the window title */
|
||||||
|
|
||||||
void parse_params( void );
|
void parse_params( void );
|
||||||
|
|
||||||
@@ -66,7 +70,12 @@ namespace Terminal {
|
|||||||
std::string str( void );
|
std::string str( void );
|
||||||
|
|
||||||
void dispatch( Function_Type type, Parser::Action *act, Framebuffer *fb );
|
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 )
|
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 )
|
void Framebuffer::scroll( int N )
|
||||||
@@ -311,6 +311,7 @@ void Framebuffer::reset( void )
|
|||||||
{
|
{
|
||||||
int width = ds.get_width(), height = ds.get_height();
|
int width = ds.get_width(), height = ds.get_height();
|
||||||
rows = std::deque<Row>( height, Row( width ) );
|
rows = std::deque<Row>( height, Row( width ) );
|
||||||
|
window_title.clear();
|
||||||
ds = DrawState( width, height );
|
ds = DrawState( width, height );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
/* Terminal framebuffer */
|
/* Terminal framebuffer */
|
||||||
|
|
||||||
@@ -109,6 +110,7 @@ namespace Terminal {
|
|||||||
class Framebuffer {
|
class Framebuffer {
|
||||||
private:
|
private:
|
||||||
std::deque<Row> rows;
|
std::deque<Row> rows;
|
||||||
|
std::vector<wchar_t> window_title;
|
||||||
|
|
||||||
void scroll( int N );
|
void scroll( int N );
|
||||||
|
|
||||||
@@ -132,6 +134,9 @@ namespace Terminal {
|
|||||||
|
|
||||||
void reset( void );
|
void reset( void );
|
||||||
void soft_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 <unistd.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "terminaldispatcher.hpp"
|
#include "terminaldispatcher.hpp"
|
||||||
#include "terminalframebuffer.hpp"
|
#include "terminalframebuffer.hpp"
|
||||||
|
#include "parseraction.hpp"
|
||||||
|
|
||||||
using namespace Terminal;
|
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 );
|
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