kterm 1.5.4
kterm: ^1.5.4 copied to clipboard
kterm is a fast and fully-featured terminal emulator for Flutter applications, with support for mobile and desktop platforms.
1.5.4 - 2026-08-05 #
Bug Fixes #
- Keytab parser no longer crashes on truncated input: A keytab ending mid-record previously null-checked with
!and threwTypeError; it now throwsParseErrorconsistently. —lib/src/core/input/keytab/keytab_parse.dart Observable.notifyListenersiterates a snapshot: Adding/removing listeners from inside a notification callback no longer throwsConcurrentModificationError(mirrorsChangeNotifiersemantics). —lib/src/base/observable.dartCellAnchordetached access throwsStateError: The guards wereasserts that vanish in release builds, leaving a raw null-check crash. —lib/src/core/buffer/line.dartIndexAwareCircularBuffer.swapbounds-checked: Out-of-range index now throwsRangeErrorlikeoperator []. —lib/src/utils/circular_buffer.dart- ZModem session race hardened:
_session!dereferences could crash when a timeout or user callback reset the session while an async chain was mid-flight; all paths now null-check or verify session identity. —lib/zmodem.dart TerminalController.searchno longer swallows real errors: The catch now wraps onlyRegExpcompilation; an invalid pattern still returns no results, but bugs in offset conversion surface instead of being silently ignored. —lib/src/ui/controller.dart
API #
- Export
GraphicsManagerfromcore.dart:Terminal.graphicsManager's type was previously unnameable outside the package (dark API). —lib/core.dart
Docs #
- Full dartdoc for
EscapeHandler: All 130+ interface methods now documented; staleTerminal.resizedoc corrected (reflow has shipped). —lib/src/core/escape/handler.dart,lib/src/terminal.dart - dartdoc for
GraphicsManagerfields,TerminalControllerandBuffer: Completes the public API documentation pass;Bufferclass doc now clarifies screen-relative vs absolute coordinates. —lib/src/core/graphics_manager.dart,lib/src/ui/controller.dart,lib/src/core/buffer/buffer.dart
Refactor #
- Merge
renderBelowImages/renderAboveImages: ~60 duplicated lines collapsed into one_renderImageswithoverlay+filterQualityparameters (behavior unchanged; below-text keepsFilterQuality.none, above-text keepsmedium). —lib/src/ui/painter.dart - Extract
_requestKeyboardFocusinTerminalViewto remove the duplicatedhardwareKeyboardOnlybranch in tap handling. —lib/src/terminal_view.dart
Testing #
- New direct tests for
Keytab.defaultKeytab(the ~700-line default table previously had zero coverage) and 5 truncated-input parse cases. —test/src/core/input/keytab/ - New image-rendering tests for the merged painter path (overlay filtering, out-of-range placements, no-manager case). —
test/src/ui/painter_test.dart - Merged the duplicate
cell_flagstest files, keeping both files' unique assertions. —test/src/core/buffer/cell_flags_test.dart
Publishing #
.pubignorekeepsexample/(lib + pubspec) so pub.dev scores the example, while excludingbuild/and platform directories to keep the package slim. —.pubignore
1.5.3 - 2026-07-10 #
Performance #
- Plain-text fast path in
Terminal.write(): BypassEscapeParserfor data chunks without escape sequences (\x1b). Plain text throughput improved from ~5 MB/s to ~18 MB/s (3.5x), significantly reducing CPU usage during high-throughput output (e.g.cat,tail -f, log streaming). —lib/src/terminal.dart - Add
writeString()toEscapeHandler: New interface method with default fallback to per-characterwriteChar(), enabling batch text writing for future optimizations. —lib/src/core/escape/handler.dart
1.5.2 - 2026-07-10 #
Bug Fixes #
- Fix reflow crash from CircularBuffer null pointer:
IndexAwareCircularBuffer.insert()silently returned no-op whenindex == 0 && _length >= _array.length, leaving null slots that causedNull check operator used on a null valueinreflow()—lib/src/utils/circular_buffer.dart - Fix eraseDisplayAbove RangeError from negative cursorX:
eraseLineToCursor()anderaseLineFromCursor()used raw_cursorXwithout clamping, causingUint32Listnegative-index crash whencursorXwas negative —lib/src/core/buffer/buffer.dart - Fix restoreCursor without bounds check:
Buffer.restoreCursor()assigned saved cursor values directly without clamping, allowing out-of-range cursor after terminal resize —lib/src/core/buffer/buffer.dart - Defensive padding after reflow: Ensure
Buffer.resize()always produces at leastnewHeightlines after reflow —lib/src/core/buffer/buffer.dart
Testing #
- Expand stress test coverage: Add multi-seed random fuzz (8 seeds), data integrity checks (all lines recoverable), cursor-bounds assertion after resize, and buffer cycling correctness —
test/stress/
1.5.1 - 2026-07-04 #
Bug Fixes #
- Fix input lag on key press / delete:
RenderTerminal._onTerminalChangedeferredmarkNeedsPaint()to a post-frame callback, adding a 1-frame delay (~16ms at 60Hz) on every visual update. NowmarkNeedsPaint()/markNeedsLayout()is called immediately, while the post-frame callback is only used to reset the coalescing guard —lib/src/ui/render.dart
1.5.0 - 2026-06-24 #
Bug Fixes #
- Fix htop-style apps showing spurious underlines on letters:
_flushRunparagraph cache key was missing theunderlineflag, causing cache collisions between underlined and non-underlined runs with identical text/color/weight/italic —lib/src/ui/painter.dart - Remove dead code:
paintCellUnderlinehad an unreachableCellAttr.underlineStyleSingleswitch case (single underline is handled by FlutterTextStylevia_flushRun) —lib/src/ui/painter.dart
1.4.2 - 2026-06-24 #
Performance #
- Coalesce notifications:
Terminal.write()defersnotifyListeners()via microtask, coalescing rapid data chunks (e.g.tail -f) into a single notification pass —lib/src/terminal.dart - Coalesce layout/paint:
RenderTerminal._onTerminalChangeusesaddPostFrameCallbackto merge multiple content changes within one frame into a single layout/paint pass —lib/src/ui/render.dart - Batch drawParagraph calls:
TerminalPainter.paintLinenow does two-pass rendering (background per-cell, foreground batched by style-run) so consecutive same-style characters produce onedrawParagraphinstead of one-per-cell —lib/src/ui/painter.dart - Skip unnecessary layout:
_onTerminalChangecallsmarkNeedsPaint()instead ofmarkNeedsLayout()when not scrolled to bottom;_onControllerUpdateusesmarkNeedsPaint()since selection/search changes are visual-only —lib/src/ui/render.dart
1.4.1 - 2026-06-23 #
Bug Fixes #
- Fix paste shortcut (Cmd+V/Ctrl+V) broken on Linux/Windows —
PasteTextIntenthandler now reads clipboard directly instead of depending on macOS-only IME path - Fix macOS IME paste duplicate: skip IME text when shortcut already handled paste
1.4.0 - 2026-06-22 #
Bug Fixes #
- Fix Kitty Graphics Protocol chunked transmission:
m=1(non-final) chunks now properly parse and accumulate payload data instead of leaving raw base64 in the parser queue - Fix X10 mouse protocol row coordinate encoding: remove extra
+1that caused CellOffset y to be reported as 2-based instead of 1-based - Fix tertiary (middle) mouse button gesture:
onTertiaryTapUpwas usingTerminalMouseButton.rightinstead of.middle, inconsistent withonTertiaryTapDown - Fix
KeyboardVisibiltyclass name typo: renamed toKeyboardVisibility(missing 'i')
Code Quality #
- Upgrade
kitty_protocoldependency from^1.2.3to^1.3.1 - Fix unused local variable warnings in
keyboard_visibility_test.dart
Tests #
- Add APC parser tests:
m=1with payload verifies dataChunk without commandEnd (2 tests)
1.3.0 - 2026-06-22 #
Bug Fixes #
- Fix Ctrl+letter combinations (Ctrl+U/A/E/C, etc.) being silently dropped in Kitty Keyboard Protocol mode — sends raw ASCII control characters for shell backward compatibility
- Fix Kitty Keyboard Protocol push/pop flag stack:
CSI > + n uandCSI > - usequences now correctly parse intermediate bytes (+/-) instead of stripping them - Fix
_KittyKeyboardEncoderWrapper.flagsreturning default values (wrapper now delegatesflagsto the inner encoder via super constructor) - Fix
_updateKittyKeyboardEncoderlazy init skipping the first push/pop call - Fix KeyUp events sending empty strings to
onOutputwhen Kitty encoder cannot encode the key - Fix modifier+letter keys (Alt+A, Meta+U, etc.) being dropped when Kitty encoder returns empty — fall back to standard keytab input
- Fix copy/paste/select-all shortcuts not working in Kitty mode (checked before Kitty dispatch now)
- Fix unknown CSI intermediate bytes in
>+sequences accidentally triggeringsetKittyMode
Code Quality #
- Refactor
_handleKeyEvent(180+ lines) into clean dispatcher: extract_handleKittyKeyEventand_tryKeyInputhelper, eliminating 3 duplicate keyInput patterns - Add
.pubignoreto exclude test, example, media, docs from published package
Documentation #
- Update AGENTS.md with comprehensive Kitty Keyboard Protocol architecture, test commands, and known limitations
- Fix README: correct Flutter version requirement to
>=3.19.0, fix screenshot URLs pointing to oldxterm.dartrepo, remove misleading "What's new in 3.0.0" section from fork - Fix README: merge duplicated "Key Features" and "Features" sections
Tests #
- Add CSI parser tests: push/pop with
+/-intermediate bytes (5 tests) - Add Terminal integration tests: push/pop flag stack, Ctrl+letter control codes via keyInput (9 tests, all 26 Ctrl+A–Z verified)
1.2.0 - 2025-07-11 #
Bug Fixes #
- Fix
_evictIfNeededmemory eviction loop: while condition now checks future memory state (current + required > target) instead of current memory, preventing leaked memory under 50% threshold - Fix
OverlayPortal.targetsRootOverlaydeprecation: replace withOverlayPortal(Flutter 3.33+) - Fix
handleTextSizeQuerydead code: remove unreachablecommand == 133branch
Code Quality #
- Migrate lint config from
package:lints/recommended.yamltopackage:flutter_lints/flutter.yaml(+30 Flutter-specific rules) - Fix 12 info-level lint issues:
unnecessary_library_name,unintended_html_in_doc_comment,avoid_print,sort_child_properties_last,prefer_const_constructors_in_immutables,sized_box_for_whitespace,avoid_unnecessary_containers - Add DCS (Kitty Remote Control), text size query, and shell integration test coverage (+19 tests)
- Add
_evictIfNeededLRU eviction edge-case tests: count limit, memory threshold, 50% target stop, LRU ordering (+4 tests) - Add
pointer_input_test.dartcompleting 100% test coverage for all 73lib/src/source files (+14 tests) - Fix
analysis_options.yaml: remove staledeprecated_member_use: ignore - Sync
AGENTS.mdCI command list with.github/workflows/dart-ci.yml
Bug Fixes #
- Fix SGR 38/48/58 malformed color recovery: incomplete color spec no longer causes subsequent params to be misparsed
- Add CSI params size limit (256) to prevent OOM from malformed sequences
- Remove dead code
case 10061000in DECSET handler
1.1.10 - 2026-05-18 #
Bug Fixes #
- Fix
Future.delayedzombie callback in graphics manager test: replace withtester.pump - Fix
gesture_detector.dartdouble-tap timer disposal on widget dispose
Code Quality #
- Fix test isolation: eliminate async callback leaks across test files
- Add
run_test.shunified test runner with smoke/full/golden/fuzz modes - Add
Makefilewith convenient targets:make test,make smoke,make golden,make fuzz - Add gesture detector timer cleanup verification (already had
dispose, confirmed correct)
1.1.9 - 2026-05-15 #
Bug Fixes #
- Fix example imports: replace removed
xterm.dartwithkterm.dartacross 6 files - Fix
withOpacitydeprecation: migrate towithValues(alpha:)(Flutter 3.27+)
Code Quality #
- Add
publish_to: 'none'to suppress invalid_dependency warning (zmodem_lbp git dep) - Add ZModem protocol decoding tests: ZMPHDR frame type parsing, file info header (29 new assertions across 7 tests)
- Clean up
AGENTS.mdwith accurate test commands