@@ -48,6 +48,7 @@ struct VTermScreen
48
48
49
49
const VTermScreenCallbacks * callbacks ;
50
50
void * cbdata ;
51
+ bool callbacks_has_pushline4 ;
51
52
52
53
VTermDamageSize damage_merge ;
53
54
/* start_row == -1 => no damage */
@@ -205,27 +206,40 @@ static int putglyph(VTermGlyphInfo *info, VTermPos pos, void *user)
205
206
return 1 ;
206
207
}
207
208
208
- static void sb_pushline_from_row (VTermScreen * screen , int row )
209
+ static void sb_pushline_from_row (VTermScreen * screen , int row , bool continuation )
209
210
{
210
211
VTermPos pos = { .row = row };
211
212
for (pos .col = 0 ; pos .col < screen -> cols ; pos .col ++ )
212
213
vterm_screen_get_cell (screen , pos , screen -> sb_buffer + pos .col );
213
214
214
- (screen -> callbacks -> sb_pushline )(screen -> cols , screen -> sb_buffer , screen -> cbdata );
215
+ if (screen -> callbacks_has_pushline4 && screen -> callbacks -> sb_pushline4 )
216
+ (screen -> callbacks -> sb_pushline4 )(screen -> cols , screen -> sb_buffer , continuation , screen -> cbdata );
217
+ else
218
+ (screen -> callbacks -> sb_pushline )(screen -> cols , screen -> sb_buffer , screen -> cbdata );
215
219
}
216
220
217
- static int moverect_internal (VTermRect dest , VTermRect src , void * user )
221
+ static int premove (VTermRect rect , void * user )
218
222
{
219
223
VTermScreen * screen = user ;
220
224
221
- if (screen -> callbacks && screen -> callbacks -> sb_pushline &&
222
- dest .start_row == 0 && dest .start_col == 0 && // starts top-left corner
223
- dest .end_col == screen -> cols && // full width
225
+ if (((screen -> callbacks && screen -> callbacks -> sb_pushline ) ||
226
+ (screen -> callbacks_has_pushline4 && screen -> callbacks && screen -> callbacks -> sb_pushline4 )) &&
227
+ rect .start_row == 0 && rect .start_col == 0 && // starts top-left corner
228
+ rect .end_col == screen -> cols && // full width
224
229
screen -> buffer == screen -> buffers [BUFIDX_PRIMARY ]) { // not altscreen
225
- for (int row = 0 ; row < src .start_row ; row ++ )
226
- sb_pushline_from_row (screen , row );
230
+ for (int row = 0 ; row < rect .end_row ; row ++ ) {
231
+ const VTermLineInfo * lineinfo = vterm_state_get_lineinfo (screen -> state , row );
232
+ sb_pushline_from_row (screen , row , lineinfo -> continuation );
233
+ }
227
234
}
228
235
236
+ return 1 ;
237
+ }
238
+
239
+ static int moverect_internal (VTermRect dest , VTermRect src , void * user )
240
+ {
241
+ VTermScreen * screen = user ;
242
+
229
243
int cols = src .end_col - src .start_col ;
230
244
int downward = src .start_row - dest .start_row ;
231
245
@@ -667,9 +681,12 @@ static void resize_buffer(VTermScreen *screen, int bufidx, int new_rows, int new
667
681
668
682
if (old_row >= 0 && bufidx == BUFIDX_PRIMARY ) {
669
683
/* Push spare lines to scrollback buffer */
670
- if (screen -> callbacks && screen -> callbacks -> sb_pushline )
671
- for (int row = 0 ; row <= old_row ; row ++ )
672
- sb_pushline_from_row (screen , row );
684
+ if ((screen -> callbacks && screen -> callbacks -> sb_pushline ) ||
685
+ (screen -> callbacks_has_pushline4 && screen -> callbacks && screen -> callbacks -> sb_pushline4 ))
686
+ for (int row = 0 ; row <= old_row ; row ++ ) {
687
+ const VTermLineInfo * lineinfo = old_lineinfo + row ;
688
+ sb_pushline_from_row (screen , row , lineinfo -> continuation );
689
+ }
673
690
if (active )
674
691
statefields -> pos .row -= (old_row + 1 );
675
692
}
@@ -840,6 +857,7 @@ static int sb_clear(void *user) {
840
857
static VTermStateCallbacks state_cbs = {
841
858
.putglyph = & putglyph ,
842
859
.movecursor = & movecursor ,
860
+ .premove = & premove ,
843
861
.scrollrect = & scrollrect ,
844
862
.erase = & erase ,
845
863
.setpenattr = & setpenattr ,
@@ -876,6 +894,7 @@ static VTermScreen *screen_new(VTerm *vt)
876
894
877
895
screen -> callbacks = NULL ;
878
896
screen -> cbdata = NULL ;
897
+ screen -> callbacks_has_pushline4 = false;
879
898
880
899
screen -> buffers [BUFIDX_PRIMARY ] = alloc_buffer (screen , rows , cols );
881
900
@@ -884,6 +903,7 @@ static VTermScreen *screen_new(VTerm *vt)
884
903
screen -> sb_buffer = vterm_allocator_malloc (screen -> vt , sizeof (VTermScreenCell ) * cols );
885
904
886
905
vterm_state_set_callbacks (screen -> state , & state_cbs , screen );
906
+ vterm_state_callbacks_has_premove (screen -> state );
887
907
888
908
return screen ;
889
909
}
@@ -1061,6 +1081,11 @@ void *vterm_screen_get_cbdata(VTermScreen *screen)
1061
1081
return screen -> cbdata ;
1062
1082
}
1063
1083
1084
+ void vterm_screen_callbacks_has_pushline4 (VTermScreen * screen )
1085
+ {
1086
+ screen -> callbacks_has_pushline4 = true;
1087
+ }
1088
+
1064
1089
void vterm_screen_set_unrecognised_fallbacks (VTermScreen * screen , const VTermStateFallbacks * fallbacks , void * user )
1065
1090
{
1066
1091
vterm_state_set_unrecognised_fallbacks (screen -> state , fallbacks , user );
0 commit comments