From e8337eff281f1cbecf6292dac64598ede7277928 Mon Sep 17 00:00:00 2001 From: Mike Gulick Date: Wed, 22 Jul 2020 21:10:05 -0400 Subject: [PATCH] Support duplicate clipboard updates Instead of using the contents of the clipboard to determine if the user has copied any text, use a sequence number that is updated whenever text is copied. Consider the following scenario (as described in #1090): 1. User copies text 'abc' on remote machine via mosh. 2. User copies text 'xyz' on local machine. 3. User copies text 'abc' on remote machine again. The local clipboard will still has 'xyz' because the most recent copy text 'abc' matches the last text copied via mosh, so it does not detect that the user copied new text and does not update the local clipboard. This patch updates detection of newly copied text via a sequence number. This number is an 8-bit unsigned integer that is updated every time new text is copied. This will roll over after 256 clipboard updates, but that is fine as we only care about it being different than the last value. Fixes #1090. Fixes #637. --- src/terminal/terminaldisplay.cc | 2 +- src/terminal/terminalframebuffer.cc | 6 ++++-- src/terminal/terminalframebuffer.h | 11 +++++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/terminal/terminaldisplay.cc b/src/terminal/terminaldisplay.cc index 9600119e4..73dc9a4df 100644 --- a/src/terminal/terminaldisplay.cc +++ b/src/terminal/terminaldisplay.cc @@ -103,7 +103,7 @@ std::string Display::new_frame( bool initialized, const Framebuffer& last, const } /* has clipboard changed? */ - if ( f.get_clipboard() != frame.last_frame.get_clipboard() ) { + 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++ ) { diff --git a/src/terminal/terminalframebuffer.cc b/src/terminal/terminalframebuffer.cc index 5d3a1bc07..9efa030fa 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 9039d4e7f..0e4749bc3 100644 --- a/src/terminal/terminalframebuffer.h +++ b/src/terminal/terminalframebuffer.h @@ -385,6 +385,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 ) { @@ -461,7 +462,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; } @@ -479,7 +486,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 ); } }; }