From 5ab71593f82f6a96e7262583fe78ee5013935704 Mon Sep 17 00:00:00 2001 From: "Vadim A. Misbakh-Soloviov" Date: Mon, 17 Jun 2024 09:34:25 +0700 Subject: [PATCH] notifications+files OCS (mobile-shell/mosh#1144) --- src/terminal/terminaldisplay.cc | 22 ++++++++++++++++++++++ src/terminal/terminalframebuffer.cc | 6 ++++++ src/terminal/terminalframebuffer.h | 7 +++++++ src/terminal/terminalfunctions.cc | 17 +++++++++++++++++ 4 files changed, 52 insertions(+) diff --git a/src/terminal/terminaldisplay.cc b/src/terminal/terminaldisplay.cc index fd2856bc..aeab26cc 100644 --- a/src/terminal/terminaldisplay.cc +++ b/src/terminal/terminaldisplay.cc @@ -111,6 +111,28 @@ std::string Display::new_frame( bool initialized, const Framebuffer& last, const } frame.append( '\007' ); } + /* has notification changed? */ + if (f.get_notification() != frame.last_frame.get_notification()) { + frame.append( "\033]" ); + const title_type ¬ification( f.get_notification() ); + for ( title_type::const_iterator i = notification.begin(); + i != notification.end(); + i++ ) { + frame.append( *i ); + } + frame.append( '\007' ); + } + /* has sendfile changed? */ + if (f.get_sendfile() != frame.last_frame.get_sendfile()) { + frame.append( "\033]1337;" ); + const title_type &sendfile( f.get_sendfile() ); + for ( title_type::const_iterator i = sendfile.begin(); + i != sendfile.end(); + i++ ) { + frame.append( *i ); + } + frame.append( '\007' ); + } /* has reverse video state changed? */ if ( ( !initialized ) || ( f.ds.reverse_video != frame.last_frame.ds.reverse_video ) ) { diff --git a/src/terminal/terminalframebuffer.cc b/src/terminal/terminalframebuffer.cc index 4d36c4a9..d0778db0 100644 --- a/src/terminal/terminalframebuffer.cc +++ b/src/terminal/terminalframebuffer.cc @@ -74,6 +74,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 ), + notification(), sendfile(), clipboard_seqnum( 0 ), ds( s_width, s_height ) { @@ -87,6 +88,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 ), + notification( other.notification ), sendfile( other.sendfile ), clipboard_seqnum( other.clipboard_seqnum ), ds( other.ds ) {} @@ -100,6 +102,8 @@ Framebuffer& Framebuffer::operator=( const Framebuffer& other ) clipboard = other.clipboard; bell_count = other.bell_count; title_initialized = other.title_initialized; + notification = other.notification; + sendfile = other.sendfile; clipboard_seqnum = other.clipboard_seqnum; ds = other.ds; } @@ -382,6 +386,8 @@ void Framebuffer::reset( void ) ds = DrawState( width, height ); rows = rows_type( height, newrow() ); window_title.clear(); + notification.clear(); + sendfile.clear(); clipboard.clear(); clipboard_seqnum = 0; /* do not reset bell_count */ diff --git a/src/terminal/terminalframebuffer.h b/src/terminal/terminalframebuffer.h index ba8bfc05..4837bb6f 100644 --- a/src/terminal/terminalframebuffer.h +++ b/src/terminal/terminalframebuffer.h @@ -406,6 +406,8 @@ class Framebuffer title_type clipboard; unsigned int bell_count; bool title_initialized; /* true if the window title has been set via an OSC */ + title_type notification; + title_type sendfile; uint8_t clipboard_seqnum; row_pointer newrow( void ) @@ -484,10 +486,14 @@ class Framebuffer 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; clipboard_seqnum++; } // Rolling over 255 -> 0 is okay + void set_notification( const title_type &s ) { notification = s; } + void set_sendfile( const title_type &s ) { sendfile = s; } 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; } + const title_type & get_notification( void ) const { return notification; } + const title_type & get_sendfile( void ) const { return sendfile; } void prefix_window_title( const title_type& s ); @@ -502,6 +508,7 @@ class Framebuffer bool operator==( const Framebuffer& x ) const { return ( rows == x.rows ) && ( window_title == x.window_title ) && ( clipboard == x.clipboard ) + && ( notification == x.notification ) && ( sendfile == x.sendfile ) && ( 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 870d8c94..1fddd942 100644 --- a/src/terminal/terminalfunctions.cc +++ b/src/terminal/terminalfunctions.cc @@ -663,6 +663,23 @@ void Dispatcher::OSC_dispatch( const Parser::OSC_End* act __attribute( ( unused capture this part */ Terminal::Framebuffer::title_type clipboard( OSC_string.begin() + 3, OSC_string.end() ); fb->set_clipboard( clipboard ); + } else if ( OSC_string.size() >= 2 && OSC_string[0] == L'9' && + OSC_string[1] == L';') { + Terminal::Framebuffer::title_type notification( + OSC_string.begin(), OSC_string.end() ); + fb->set_notification( notification ); + } else if ( OSC_string.size() >= 4 && OSC_string[0] == L'7' && + OSC_string[1] == L'7' && OSC_string[2] == L'7' && + OSC_string[3] == L';') { + Terminal::Framebuffer::title_type notification( + OSC_string.begin(), OSC_string.end() ); + fb->set_notification( notification ); + } else if ( OSC_string.size() >= 5 && OSC_string[0] == L'1' && + OSC_string[1] == L'3' && OSC_string[2] == L'3' && + OSC_string[3] == L'7' && OSC_string[4] == L';') { + Terminal::Framebuffer::title_type sendfile( + OSC_string.begin() + 5, OSC_string.end() ); + fb->set_sendfile( sendfile ); /* handle osc terminal title sequence */ } else if ( OSC_string.size() >= 1 ) { long cmd_num = -1;