@@ -4138,15 +4138,17 @@ impl Screen<'_> {
41384138 // `cursor.style()`):
41394139 // 1. Decide render style with strict priority:
41404140 // preedit > visible > focused > blink > shape.
4141- // 2. Always clear both cursor slots first — last
4142- // frame's sprite (if any) needs to disappear
4143- // whether we emit a new one or not.
4144- // 3. Some(style): emit a sprite into slot 0 (block)
4145- // or slot rows+1 (others). For Block we ALSO
4146- // write the bg-tint uniforms below so the bg
4147- // fragment paints the block + the text shader
4148- // inverts the underlying glyph.
4149- // 4. None: leave both slots empty + zero uniforms.
4141+ // 2. Some(style): build the sprite for the block
4142+ // slot (drawn under text; the bg-tint uniforms
4143+ // below make the bg fragment paint the block +
4144+ // the text shader invert the underlying glyph)
4145+ // or the tail slot (bar/underline, drawn over
4146+ // text). None: both stay empty + zero uniforms.
4147+ // 3. One `grid.set_cursor(block, tail)` call
4148+ // replaces both slots. It diffs against last
4149+ // frame and only dirties cursor buffers on
4150+ // change — do NOT clear the slots beforehand,
4151+ // that would dirty them every frame.
41504152 let render_style = crate :: grid_emit:: cursor_render_style (
41514153 crate :: grid_emit:: CursorRenderInputs {
41524154 visible : p. cursor_visible ,
@@ -4157,7 +4159,10 @@ impl Screen<'_> {
41574159 shape : p. cursor_shape ,
41584160 } ,
41594161 ) ;
4160- grid. clear_cursor ( ) ;
4162+ let mut block_cursor: Option < rio_backend:: sugarloaf:: grid:: CellText > =
4163+ None ;
4164+ let mut tail_cursor: Option < rio_backend:: sugarloaf:: grid:: CellText > =
4165+ None ;
41614166 if let Some ( style) = render_style {
41624167 let cell_w = p. cell_w . round ( ) . clamp ( 1.0 , u32:: MAX as f32 ) as u32 ;
41634168 let cell_h = p. cell_h . round ( ) . clamp ( 1.0 , u32:: MAX as f32 ) as u32 ;
@@ -4167,16 +4172,23 @@ impl Screen<'_> {
41674172 ( p. cursor_color [ 2 ] . clamp ( 0.0 , 1.0 ) * 255.0 ) as u8 ,
41684173 255 ,
41694174 ] ;
4170- crate :: grid_emit:: emit_cursor_sprite (
4175+ if let Some ( ( is_block , cell ) ) = crate :: grid_emit:: cursor_sprite_cell (
41714176 grid,
41724177 style,
41734178 p. cursor_col ,
41744179 p. cursor_row ,
41754180 cursor_color,
41764181 cell_w,
41774182 cell_h,
4178- ) ;
4183+ ) {
4184+ if is_block {
4185+ block_cursor = Some ( cell) ;
4186+ } else {
4187+ tail_cursor = Some ( cell) ;
4188+ }
4189+ }
41794190 }
4191+ grid. set_cursor ( block_cursor. as_slice ( ) , tail_cursor. as_slice ( ) ) ;
41804192
41814193 // Panel's grid origin in drawable-pixel space =
41824194 // window scaled_margin + the panel's layout rect
@@ -4299,6 +4311,11 @@ impl Screen<'_> {
42994311 . set_dirty ( ) ;
43004312 }
43014313
4314+ if let Some ( wake_in) = self . renderer . scrollbar . next_wake_in ( ) {
4315+ self . context_manager
4316+ . schedule_render_on_route ( wake_in. as_millis ( ) as u64 ) ;
4317+ }
4318+
43024319 // In case the configuration of blinking cursor is enabled
43034320 // TODO: enable blinking for selection after adding debounce (https://github.com/raphamorim/rio/issues/437)
43044321 if self . renderer . is_window_focused
0 commit comments