apply method
Implementation
void apply(GridUpdate u) {
final oldCursorRow = _cursorRow;
final oldCursorCol = _cursorCol;
final oldCursorVisible = _cursorVisible;
final oldCursorShape = _cursorShape;
final oldCursorBlinking = _cursorBlinking;
final oldCursorColor = _cursorColor;
final oldDefaultFg = _defaultFg;
final oldDefaultBg = _defaultBg;
_defaultFg = u.defaultFg;
_defaultBg = u.defaultBg;
_cursorColor = u.cursorColor;
// Partial damage only names changed lines; rows/columns on GridUpdate are not
// viewport size (see FrbEngineBinding._toGridUpdate). Resize on full only.
if (u.full) {
_ensureSize(u.rows, u.columns);
_markAllRowsDirty();
}
final delta = u.scrollLineDelta;
if (delta != 0 && _rows > 0) {
_rotateRows(delta);
_scrollLineDeltaForPaint = delta;
// Only the rows revealed by the scroll need a fresh paint when the
// painter can blit the retained frame; if retain is unavailable the
// painter falls back to paintAll.
final d = delta.abs() > _rows ? _rows : delta.abs();
if (delta > 0) {
for (var i = 0; i < d; i++) {
_dirtyRows.add(i);
}
} else {
for (var i = _rows - d; i < _rows; i++) {
_dirtyRows.add(i);
}
}
}
for (final l in u.lines) {
if (l.line < 0) continue;
if (l.line >= _rows) {
_applyOverscanLine(l);
continue;
}
if (!u.full) {
_dirtyRows.add(l.line);
}
// Partial damage can arrive with engine cols > mirror cols when resize races
// the async drain (LayoutBuilder grew before post-frame resize ran).
final copy = l.codepoints.length < _columns ? l.codepoints.length : _columns;
if (copy == 0) continue;
_codepoints[l.line].setRange(0, copy, l.codepoints);
_fg[l.line].setRange(0, copy, l.fg);
_bg[l.line].setRange(0, copy, l.bg);
_flags[l.line].setRange(0, copy, l.flags);
_hyperlinkId[l.line].setRange(0, copy, l.hyperlinkId);
if (copy < _columns) {
_codepoints[l.line].fillRange(copy, _columns, 32);
_fg[l.line].fillRange(copy, _columns, _defaultFg);
_bg[l.line].fillRange(copy, _columns, _defaultBg);
_flags[l.line].fillRange(copy, _columns, 0);
_hyperlinkId[l.line].fillRange(copy, _columns, 0);
}
}
// Overscan from explicit field (full updates) or sentinel line index (scroll).
final o = u.overscan;
if (o != null) {
_applyOverscanLine(o);
}
_scrollFraction = u.scrollFraction;
_cursorRow = u.cursorRow;
_cursorCol = u.cursorCol;
_cursorVisible = u.cursorVisible;
_cursorShape = u.cursorShape;
_cursorBlinking = u.cursorBlinking;
_modeFlags = u.modeFlags;
_displayOffset = u.displayOffset;
if (u.full || u.historySize > 0) {
_historySize = u.historySize;
}
// Metadata-only (or mixed) damage: default colors repaint the whole grid;
// cursor field changes need the old and new cursor rows at minimum.
if (!u.full && delta == 0) {
if (u.defaultFg != oldDefaultFg || u.defaultBg != oldDefaultBg) {
_markAllRowsDirty();
} else {
final cursorChanged = u.cursorRow != oldCursorRow ||
u.cursorCol != oldCursorCol ||
u.cursorVisible != oldCursorVisible ||
u.cursorShape != oldCursorShape ||
u.cursorBlinking != oldCursorBlinking ||
u.cursorColor != oldCursorColor;
if (cursorChanged) {
_markRowDirtyIfInRange(oldCursorRow);
_markRowDirtyIfInRange(u.cursorRow);
}
}
}
_generation++;
TerminalScrollLatency.markGridOrTextureUpdated(_generation);
_notifyRepaint();
}