Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cursor style not handled correctly #1084

Closed
antoniy opened this issue Dec 31, 2019 · 13 comments
Closed

Cursor style not handled correctly #1084

antoniy opened this issue Dec 31, 2019 · 13 comments

Comments

@antoniy
Copy link

antoniy commented Dec 31, 2019

My cursor changes style from pipe to rectangle in ZSH shell when use vim mode but also in vim when switching from Normal and Insert modes. The cursor changes styles when I use ssh but in a mosh session, I see only the pipe-style cursor and it never changes.

Is there a way to fix that behavior?

I'm using the latest git version build on the server and on the client.
Server - archlinux: mosh 1.3.2 [build mosh-1.3.2-86-g0cc492d]
Client - macosx: mosh 1.3.2 [build mosh-1.3.2-86-g0cc492d]

@matheusfillipe
Copy link

I have the exact same issue with arch server and ubuntu client.

@mqzabin
Copy link

mqzabin commented Jul 31, 2020

I have the same issue. My brain use the cursor shape as a primary normal/insert mode detection. It's painfull.

@disrupted
Copy link

same here using mosh-server and client compiled from latest master

@kovasap
Copy link

kovasap commented Dec 22, 2020

Same here!

@damnskippy
Copy link

Long standing known open issue: #352
Probably the most sorely lacking or user impacting missing functionality when using terminal IMHO in an otherwise wonderfully life saving app.

@waltarix
Copy link

Here is a patch for this issue. (based on 378dfa6)
Hope this helps.

diff --git b/src/terminal/terminaldisplay.cc a/src/terminal/terminaldisplay.cc
index e7595c2..9034072 100644
--- b/src/terminal/terminaldisplay.cc
+++ a/src/terminal/terminaldisplay.cc
@@ -154,6 +154,12 @@ std::string Display::new_frame( bool initialized, const Framebuffer &last, const
     frame.append( "\033[?25l" );
   }
 
+  /* is cursor style initialized? */
+  if ( !initialized ) {
+    frame.cursor_style = Terminal::CursorStyle::BLINKING_BLOCK;
+    frame.append( "\033[0 q" );
+  }
+
   int frame_y = 0;
   Framebuffer::row_pointer blank_row;
   Framebuffer::rows_type rows( frame.last_frame.get_rows() );
@@ -286,6 +292,14 @@ std::string Display::new_frame( bool initialized, const Framebuffer &last, const
     }
   }
 
+  /* has cursor style changed? */
+  if ( (!initialized)
+       || (f.ds.cursor_style != frame.cursor_style) ) {
+    char cursor_style_sequence_buf[6];
+    snprintf( cursor_style_sequence_buf, sizeof cursor_style_sequence_buf, "\033[%d q", f.ds.cursor_style );
+    frame.append( cursor_style_sequence_buf );
+  }
+
   /* have renditions changed? */
   frame.update_rendition( f.ds.get_renditions(), !initialized );
 
@@ -483,6 +497,7 @@ bool Display::put_row( bool initialized, FrameState &frame, const Framebuffer &f
 FrameState::FrameState( const Framebuffer &s_last )
       : str(), cursor_x(0), cursor_y(0), current_rendition( 0 ),
 	cursor_visible( s_last.ds.cursor_visible ),
+	cursor_style( s_last.ds.cursor_style ),
 	last_frame( s_last )
 {
   /* Preallocate for better performance.  Make a guess-- doesn't matter for correctness */
diff --git b/src/terminal/terminaldisplay.h a/src/terminal/terminaldisplay.h
index 81009b0..0d6335d 100644
--- b/src/terminal/terminaldisplay.h
+++ a/src/terminal/terminaldisplay.h
@@ -44,6 +44,7 @@ namespace Terminal {
     int cursor_x, cursor_y;
     Renditions current_rendition;
     bool cursor_visible;
+    int cursor_style;
 
     const Framebuffer &last_frame;
 
diff --git b/src/terminal/terminalframebuffer.cc a/src/terminal/terminalframebuffer.cc
index 2751f3b..7b7d076 100644
--- b/src/terminal/terminalframebuffer.cc
+++ a/src/terminal/terminalframebuffer.cc
@@ -69,6 +69,7 @@ DrawState::DrawState( int s_width, int s_height )
     combining_char_col( 0 ), combining_char_row( 0 ), default_tabs( true ), tabs( s_width ),
     scrolling_region_top_row( 0 ), scrolling_region_bottom_row( height - 1 ),
     renditions( 0 ), save(),
+    cursor_style( Terminal::CursorStyle::BLINKING_BLOCK ),
     next_print_will_wrap( false ), origin_mode( false ), auto_wrap_mode( true ),
     insert_mode( false ), cursor_visible( true ), reverse_video( false ),
     bracketed_paste( false ), mouse_reporting_mode( MOUSE_REPORTING_NONE ), mouse_focus_event( false ),
@@ -392,6 +393,7 @@ void Framebuffer::soft_reset( void )
   ds.insert_mode = false;
   ds.origin_mode = false;
   ds.cursor_visible = true; /* per xterm and gnome-terminal */
+  ds.cursor_style = Terminal::CursorStyle::BLINKING_BLOCK;
   ds.application_mode_cursor_keys = false;
   ds.set_scrolling_region( 0, ds.get_height() - 1 );
   ds.add_rendition( 0 );
diff --git b/src/terminal/terminalframebuffer.h a/src/terminal/terminalframebuffer.h
index de93869..4c2345b 100644
--- b/src/terminal/terminalframebuffer.h
+++ a/src/terminal/terminalframebuffer.h
@@ -51,6 +51,16 @@ namespace Terminal {
   using shared::make_shared;
   typedef uint32_t color_type;
 
+  enum CursorStyle {
+    BLINKING_BLOCK = 0,
+    BLINKING_BLOCK_DEFAULT = 1,
+    STEADY_BLOCK = 2,
+    BLINKING_UNDERLINE = 3,
+    STEADY_UNDERLINE = 4,
+    BLINKING_BAR = 5,
+    STEADY_BAR = 6,
+  };
+
   class Renditions {
   public:
     typedef enum { bold, faint, italic, underlined, blink, inverse, invisible, SIZE } attribute_type;
@@ -275,6 +285,8 @@ namespace Terminal {
     SavedCursor save;
 
   public:
+    int cursor_style;
+
     bool next_print_will_wrap;
     bool origin_mode;
     bool auto_wrap_mode;
@@ -351,6 +363,7 @@ namespace Terminal {
       return ( width == x.width ) && ( height == x.height ) && ( cursor_col == x.cursor_col )
 	&& ( cursor_row == x.cursor_row ) && ( cursor_visible == x.cursor_visible ) &&
 	( reverse_video == x.reverse_video ) && ( renditions == x.renditions ) &&
+	( cursor_style == x.cursor_style ) &&
   ( bracketed_paste == x.bracketed_paste ) && ( mouse_reporting_mode == x.mouse_reporting_mode ) &&
   ( mouse_focus_event == x.mouse_focus_event ) && ( mouse_alternate_scroll == x.mouse_alternate_scroll) &&
   ( mouse_encoding_mode == x.mouse_encoding_mode );
diff --git b/src/terminal/terminalfunctions.cc a/src/terminal/terminalfunctions.cc
index ca141dd..7cf6e58 100644
--- b/src/terminal/terminalfunctions.cc
+++ a/src/terminal/terminalfunctions.cc
@@ -50,6 +50,26 @@ static void clearline( Framebuffer *fb, int row, int start, int end )
   }
 }
 
+/* cursor style */
+static void CSI_DECSCUSR( Framebuffer *fb, Dispatcher *dispatch ) {
+  int style = dispatch->getparam( 0, 0 );
+  switch ( style ) {
+  case 0:
+  case 1:
+  case 2:
+  case 3:
+  case 4:
+  case 5:
+  case 6:
+    fb->ds.cursor_style = style;
+    break;
+  default:
+    break;
+  }
+}
+
+static Function func_CSI_DECSCUSR( CSI, " q", CSI_DECSCUSR );
+
 /* erase in line */
 static void CSI_EL( Framebuffer *fb, Dispatcher *dispatch )
 {

@disrupted
Copy link

@waltarix really cool! have you already created a PR for it?

@waltarix
Copy link

No, I haven't, because it's just a quick fix.
However, anyone is free to use this patch, so if someone wants to make a PR, that would be great.

@matheusfillipe
Copy link

@waltarix I tested your patch and it fixes the issue on my case. I took the freedom to submit a PR with your changes now.

@waltarix
Copy link

That's nice. Thanks for your help.

@jasonjurotich
Copy link

Any news on whether they are going to add this. We still can't see the cursor change using mosh...

@Ingvix
Copy link

Ingvix commented Jul 7, 2022

@waltarix's patch doesn't seem to work for me on st. I only see a blinking block. Any thoughts?

@achernya
Copy link
Collaborator

Marking this as a duplicate of #352 which covers more cursor style issues.

@achernya achernya closed this as not planned Won't fix, can't repro, duplicate, stale Jan 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants