Skip to content

Commit

Permalink
Support duplicate clipboard updates
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mgulick committed Jul 23, 2020
1 parent 3c23372 commit e922128
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/terminal/terminaldisplay.cc
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,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();
Expand Down
7 changes: 5 additions & 2 deletions src/terminal/terminalframebuffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ 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 )
: rows(), icon_name(), window_title(), clipboard(), bell_count( 0 ),
title_initialized( false ), clipboard_seqnum( 0 ), ds( s_width, s_height )
{
assert( s_height > 0 );
assert( s_width > 0 );
Expand All @@ -90,7 +91,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 )
title_initialized( other.title_initialized ), clipboard_seqnum( other.clipboard_seqnum ), ds( other.ds )
{
}

Expand All @@ -103,6 +104,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;
Expand Down Expand Up @@ -384,6 +386,7 @@ void Framebuffer::reset( void )
rows = rows_type( height, newrow() );
window_title.clear();
clipboard.clear();
clipboard_seqnum = 0;
/* do not reset bell_count */
}

Expand Down
11 changes: 9 additions & 2 deletions src/terminal/terminalframebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ namespace Terminal {
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 )
{
Expand Down Expand Up @@ -452,7 +453,13 @@ namespace Terminal {
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; }
Expand All @@ -469,7 +476,7 @@ namespace Terminal {

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 );
return ( rows == x.rows ) && ( window_title == x.window_title ) && ( clipboard == x.clipboard ) && ( clipboard_seqnum == x.clipboard_seqnum ) && ( bell_count == x.bell_count ) && ( ds == x.ds );
}
};
}
Expand Down

0 comments on commit e922128

Please sign in to comment.