diff --git a/src/terminal/terminaldisplay.cc b/src/terminal/terminaldisplay.cc index c4495285..73dc9a4d 100644 --- a/src/terminal/terminaldisplay.cc +++ b/src/terminal/terminaldisplay.cc @@ -103,8 +103,8 @@ std::string Display::new_frame( bool initialized, const Framebuffer& last, const } /* has clipboard changed? */ - if ( f.get_clipboard() != frame.last_frame.get_clipboard() ) { - frame.append( "\033]52;c;" ); + if ( f.get_clipboard_seqnum() != frame.last_frame.get_clipboard_seqnum() ) { + frame.append( "\033]52;" ); const title_type& clipboard( f.get_clipboard() ); for ( title_type::const_iterator i = clipboard.begin(); i != clipboard.end(); i++ ) { frame.append( *i ); diff --git a/src/terminal/terminalframebuffer.cc b/src/terminal/terminalframebuffer.cc index 1d5ffe37..4a022ba6 100644 --- a/src/terminal/terminalframebuffer.cc +++ b/src/terminal/terminalframebuffer.cc @@ -73,7 +73,7 @@ DrawState::DrawState( int s_width, int s_height ) Framebuffer::Framebuffer( int s_width, int s_height ) : rows(), icon_name(), window_title(), clipboard(), bell_count( 0 ), title_initialized( false ), - ds( s_width, s_height ) + clipboard_seqnum( 0 ), ds( s_width, s_height ) { assert( s_height > 0 ); assert( s_width > 0 ); @@ -85,7 +85,7 @@ Framebuffer::Framebuffer( int s_width, int s_height ) Framebuffer::Framebuffer( const Framebuffer& other ) : rows( other.rows ), icon_name( other.icon_name ), window_title( other.window_title ), clipboard( other.clipboard ), bell_count( other.bell_count ), title_initialized( other.title_initialized ), - ds( other.ds ) + clipboard_seqnum( other.clipboard_seqnum ), ds( other.ds ) {} Framebuffer& Framebuffer::operator=( const Framebuffer& other ) @@ -97,6 +97,7 @@ Framebuffer& Framebuffer::operator=( const Framebuffer& other ) clipboard = other.clipboard; bell_count = other.bell_count; title_initialized = other.title_initialized; + clipboard_seqnum = other.clipboard_seqnum; ds = other.ds; } return *this; @@ -379,6 +380,7 @@ void Framebuffer::reset( void ) rows = rows_type( height, newrow() ); window_title.clear(); clipboard.clear(); + clipboard_seqnum = 0; /* do not reset bell_count */ } diff --git a/src/terminal/terminalframebuffer.h b/src/terminal/terminalframebuffer.h index 8de59890..0347dee1 100644 --- a/src/terminal/terminalframebuffer.h +++ b/src/terminal/terminalframebuffer.h @@ -386,6 +386,7 @@ class Framebuffer title_type clipboard; unsigned int bell_count; bool title_initialized; /* true if the window title has been set via an OSC */ + uint8_t clipboard_seqnum; row_pointer newrow( void ) { @@ -462,7 +463,13 @@ class Framebuffer bool is_title_initialized( void ) const { return title_initialized; } void set_icon_name( const title_type& s ) { icon_name = s; } void set_window_title( const title_type& s ) { window_title = s; } - void set_clipboard( const title_type& s ) { clipboard = s; } + void set_clipboard( const title_type& s ) + { + clipboard = s; + // Rolling over 255 -> 0 is okay + clipboard_seqnum++; + } + uint8_t get_clipboard_seqnum( void ) const { return clipboard_seqnum; } const title_type& get_icon_name( void ) const { return icon_name; } const title_type& get_window_title( void ) const { return window_title; } const title_type& get_clipboard( void ) const { return clipboard; } @@ -480,7 +487,7 @@ class Framebuffer bool operator==( const Framebuffer& x ) const { return ( rows == x.rows ) && ( window_title == x.window_title ) && ( clipboard == x.clipboard ) - && ( bell_count == x.bell_count ) && ( ds == x.ds ); + && ( clipboard_seqnum == x.clipboard_seqnum ) && ( bell_count == x.bell_count ) && ( ds == x.ds ); } }; } diff --git a/src/terminal/terminalfunctions.cc b/src/terminal/terminalfunctions.cc index 40c41afc..2bd59d21 100644 --- a/src/terminal/terminalfunctions.cc +++ b/src/terminal/terminalfunctions.cc @@ -591,10 +591,13 @@ static Function func_CSI_DECSTR( CSI, "!p", CSI_DECSTR ); /* xterm uses an Operating System Command to set the window title */ void Dispatcher::OSC_dispatch( const Parser::OSC_End* act __attribute( ( unused ) ), Framebuffer* fb ) { - /* handle osc copy clipboard sequence 52;c; */ - if ( OSC_string.size() >= 5 && OSC_string[0] == L'5' && OSC_string[1] == L'2' && OSC_string[2] == L';' - && OSC_string[3] == L'c' && OSC_string[4] == L';' ) { - Terminal::Framebuffer::title_type clipboard( OSC_string.begin() + 5, OSC_string.end() ); + /* Handle OSC copy clipboard sequence 52;c; and variants */ + if ( OSC_string.size() >= 5 && OSC_string[0] == L'5' && OSC_string[1] == L'2' && OSC_string[2] == L';' ) { + /* Capture the options and clipboard contents + e.g. '52;c;bW9zaCBpcyBncmVhdAo=' + ^^^^^^^^^^^^^^^^^^^^^^^ + capture this part */ + Terminal::Framebuffer::title_type clipboard( OSC_string.begin() + 3, OSC_string.end() ); fb->set_clipboard( clipboard ); /* handle osc terminal title sequence */ } else if ( OSC_string.size() >= 1 ) {