Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,17 @@ jobs:
id: ghostty-cache
with:
path: ghostty-src
key: ghostty-src-${{ steps.ghostty.outputs.full }}
key: ghostty-src-${{ steps.ghostty.outputs.full }}-${{ hashFiles('packages/libghostty/patches/*.patch') }}
- name: download ghostty source
if: steps.ghostty-cache.outputs.cache-hit != 'true'
run: |
curl -fsSL "https://github.com/ghostty-org/ghostty/archive/${{ steps.ghostty.outputs.full }}.tar.gz" -o ghostty.tar.gz
mkdir -p ghostty-src
tar xzf ghostty.tar.gz -C ghostty-src --strip-components=1
git -C ghostty-src init --quiet
git -C ghostty-src apply --unidiff-zero "$GITHUB_WORKSPACE/packages/libghostty/patches/osc52-clipboard-write.patch"
rm -rf ghostty-src/.git
touch ghostty-src/.git
rm ghostty.tar.gz
- name: compile
working-directory: ghostty-src
Expand Down Expand Up @@ -164,13 +168,17 @@ jobs:
id: ghostty-cache
with:
path: ghostty-src
key: ghostty-src-${{ steps.ghostty.outputs.full }}
key: ghostty-src-${{ steps.ghostty.outputs.full }}-${{ hashFiles('packages/libghostty/patches/*.patch') }}
- name: download ghostty source
if: steps.ghostty-cache.outputs.cache-hit != 'true'
run: |
curl -fsSL "https://github.com/ghostty-org/ghostty/archive/${{ steps.ghostty.outputs.full }}.tar.gz" -o ghostty.tar.gz
mkdir -p ghostty-src
tar xzf ghostty.tar.gz -C ghostty-src --strip-components=1
git -C ghostty-src init --quiet
git -C ghostty-src apply --unidiff-zero "$GITHUB_WORKSPACE/packages/libghostty/patches/osc52-clipboard-write.patch"
rm -rf ghostty-src/.git
touch ghostty-src/.git
rm ghostty.tar.gz
- name: compile wasm
working-directory: ghostty-src
Expand Down
15 changes: 12 additions & 3 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,17 @@ jobs:
id: ghostty-cache
with:
path: ghostty
key: ghostty-src-${{ steps.ghostty.outputs.commit }}
key: ghostty-src-${{ steps.ghostty.outputs.commit }}-${{ hashFiles('packages/libghostty/patches/*.patch') }}
- name: download ghostty source
if: steps.ghostty-cache.outputs.cache-hit != 'true'
shell: bash
run: |
curl -fsSL "https://github.com/ghostty-org/ghostty/archive/${{ steps.ghostty.outputs.commit }}.tar.gz" -o ghostty.tar.gz
mkdir -p ghostty
tar xzf ghostty.tar.gz -C ghostty --strip-components=1
git -C ghostty init --quiet
git -C ghostty apply --unidiff-zero "$GITHUB_WORKSPACE/packages/libghostty/patches/osc52-clipboard-write.patch"
rm -rf ghostty/.git
rm ghostty.tar.gz
- run: flutter pub get
- run: dart pub global activate very_good_cli
Expand Down Expand Up @@ -229,13 +232,16 @@ jobs:
id: ghostty-cache
with:
path: ghostty
key: ghostty-src-${{ steps.ghostty.outputs.commit }}
key: ghostty-src-${{ steps.ghostty.outputs.commit }}-${{ hashFiles('packages/libghostty/patches/*.patch') }}
- name: download ghostty source
if: steps.ghostty-cache.outputs.cache-hit != 'true'
run: |
curl -fsSL "https://github.com/ghostty-org/ghostty/archive/${{ steps.ghostty.outputs.commit }}.tar.gz" -o ghostty.tar.gz
mkdir -p ghostty
tar xzf ghostty.tar.gz -C ghostty --strip-components=1
git -C ghostty init --quiet
git -C ghostty apply --unidiff-zero "$GITHUB_WORKSPACE/packages/libghostty/patches/osc52-clipboard-write.patch"
rm -rf ghostty/.git
rm ghostty.tar.gz
- name: isolate from repo git
run: touch ghostty/.git
Expand Down Expand Up @@ -282,14 +288,17 @@ jobs:
id: ghostty-cache
with:
path: ghostty
key: ghostty-src-${{ steps.ghostty.outputs.commit }}
key: ghostty-src-${{ steps.ghostty.outputs.commit }}-${{ hashFiles('packages/libghostty/patches/*.patch') }}
- name: download ghostty source
if: steps.ghostty-cache.outputs.cache-hit != 'true'
shell: bash
run: |
curl -fsSL "https://github.com/ghostty-org/ghostty/archive/${{ steps.ghostty.outputs.commit }}.tar.gz" -o ghostty.tar.gz
mkdir -p ghostty
tar xzf ghostty.tar.gz -C ghostty --strip-components=1
git -C ghostty init --quiet
git -C ghostty apply --unidiff-zero "$GITHUB_WORKSPACE/packages/libghostty/patches/osc52-clipboard-write.patch"
rm -rf ghostty/.git
rm ghostty.tar.gz
- run: flutter pub get
- name: install very_good_cli
Expand Down
19 changes: 19 additions & 0 deletions packages/flterm/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## Unreleased

### Added

- **OSC 52 clipboard writes**: `TerminalController.onClipboardWrite` forwards
write-only clipboard requests from libghostty to terminal embedders.

## 0.0.4

### Breaking
Expand All @@ -13,6 +20,9 @@

- **Terminal links**: `TerminalView.linkSettings` detects OSC 8 links,
text URLs, file paths, and custom regex links.
- **Accessibility semantics**: `TerminalView` exposes visible, non-concealed
terminal text and terminal-focus actions to assistive technologies, with
customizable labels and hints.
- **Controller APIs**: `selectRange`, `hasSelection`, `pwd`, and
`onPwdChanged` expose selection and working-directory state.
- **Glyph Protocol**: `TerminalConfig.glyphProtocol` toggles Glyph Protocol
Expand All @@ -23,6 +33,15 @@
- **Rendering pipeline**: selection, cursor viewport state, and cell metadata
use refreshed libghostty render snapshots.

### Fixed

- **Tracked pointer input**: mouse buttons, hover, wheel coordinates, and
touch/stylus scroll positions are preserved in terminal mouse reports.
- **Rendering invalidation**: size reports no longer consume renderer dirty
state, and Kitty image replacements stay drawable while uploads complete.
- **Accessibility rendering**: terminal semantics use the renderer snapshot,
coalesce repeated updates, and follow the visible scrollback viewport.

## 0.0.3

### Breaking
Expand Down
3 changes: 3 additions & 0 deletions packages/flterm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ libghostty-vt engine.
hyperlinks; fonts. Immutable and `lerp`-able.
- Links for OSC 8 metadata, text URLs, file paths, and custom regex
rules with activation callbacks.
- Screen-reader semantics expose the visible viewport as text and provide an
action for focusing terminal input without announcing every output update as
a live region.

## Getting started

Expand Down
1 change: 0 additions & 1 deletion packages/flterm/lib/src/foundation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@ export 'foundation/input_types.dart';
export 'foundation/platform_map.dart';
export 'foundation/terminal_config.dart';
export 'foundation/terminal_gesture_settings.dart';
export 'foundation/terminal_render_observer.dart';
export 'foundation/terminal_theme.dart';
2 changes: 1 addition & 1 deletion packages/flterm/lib/src/foundation/callbacks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ typedef OnResize = void Function(int cols, int rows);
/// ```
typedef TerminalMouseEvent = ({
MouseAction action,
MouseButton button,
MouseButton? button,
double pixelX,
double pixelY,
});
36 changes: 10 additions & 26 deletions packages/flterm/lib/src/foundation/terminal_config.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:flutter/foundation.dart' show immutable;
import 'package:flutter/foundation.dart' show immutable, mapEquals;
import 'package:libghostty/libghostty.dart';

/// When to auto-scroll the viewport to the bottom.
Expand Down Expand Up @@ -43,11 +43,12 @@ enum ScrollToBottom {
/// ```
@immutable
class TerminalConfig {
/// Default terminal modes.
/// Overrides applied on top of libghostty's terminal defaults.
///
/// Includes grapheme cluster mode for proper multi-codepoint character
/// handling. Applied on terminal init and restored when the alternate
/// screen exits back to the primary screen.
/// Flterm only overrides behavior needed by its renderer: cursor blinking
/// and grapheme clustering. Other modes retain libghostty's defaults.
/// Applied on terminal init and restored when the alternate screen exits
/// back to the primary screen.
///
/// Spread and override to change individual defaults:
///
Expand All @@ -60,13 +61,7 @@ class TerminalConfig {
/// );
/// ```
static const defaultModes = <TerminalMode, bool>{
.srm(): true,
.autoWrap(): true,
.cursorBlinking(): true,
.cursorVisible(): true,
.alternateScroll(): true,
.numlockKeypad(): true,
.altEscPrefix(): true,
.graphemeCluster(): true,
};

Expand Down Expand Up @@ -115,9 +110,10 @@ class TerminalConfig {
/// - `false`: never blink, ignore DEC mode 12 (DECSCUSR still respected).
final bool? cursorBlink;

/// Terminal modes applied on init and primary screen restore.
/// Terminal mode overrides applied on init and primary screen restore.
///
/// Programs can change modes at runtime via escape sequences. Use
/// Modes absent from this map retain libghostty's defaults. Programs can
/// change modes at runtime via escape sequences. Use
/// [TerminalController.modeGet] and [TerminalController.modeSet] to
/// query or override the live state.
final Map<TerminalMode, bool> modes;
Expand Down Expand Up @@ -195,7 +191,7 @@ class TerminalConfig {
glyphProtocol == other.glyphProtocol &&
cursorStyle == other.cursorStyle &&
cursorBlink == other.cursorBlink &&
_modesEqual(modes, other.modes) &&
mapEquals(modes, other.modes) &&
scrollToBottom == other.scrollToBottom &&
selectionClearOnTyping == other.selectionClearOnTyping &&
enquiryResponse == other.enquiryResponse &&
Expand Down Expand Up @@ -242,16 +238,4 @@ class TerminalConfig {
'cols: $cols, rows: $rows, '
'scrollbackLimit: $scrollbackLimit, '
'modes: ${modes.length} entries)';

static bool _modesEqual(
Map<TerminalMode, bool> a,
Map<TerminalMode, bool> b,
) {
if (identical(a, b)) return true;
if (a.length != b.length) return false;
for (final entry in a.entries) {
if (b[entry.key] != entry.value) return false;
}
return true;
}
}
18 changes: 0 additions & 18 deletions packages/flterm/lib/src/foundation/terminal_render_observer.dart

This file was deleted.

12 changes: 2 additions & 10 deletions packages/flterm/lib/src/rendering/atlas/atlas_config.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:ui' show FontWeight;

import 'package:flutter/foundation.dart' show listEquals;
import 'package:meta/meta.dart';

import '../../foundation.dart';
Expand Down Expand Up @@ -53,7 +54,7 @@ class AtlasConfig {
other.fontSize == fontSize &&
other.fontWeight == fontWeight &&
other.fontFamily == fontFamily &&
_listEquals(other.fontFamilyFallback, fontFamilyFallback) &&
listEquals(other.fontFamilyFallback, fontFamilyFallback) &&
other.metrics == metrics &&
other.devicePixelRatio == devicePixelRatio;

Expand All @@ -74,13 +75,4 @@ class AtlasConfig {
devicePixelRatio: devicePixelRatio ?? this.devicePixelRatio,
);
}

static bool _listEquals(List<String> a, List<String> b) {
if (identical(a, b)) return true;
if (a.length != b.length) return false;
for (var i = 0; i < a.length; i++) {
if (a[i] != b[i]) return false;
}
return true;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

import 'font_data_resolver_io.dart'
Expand Down Expand Up @@ -44,10 +43,6 @@ class FontDataResolver {

FontDataResolver._();

/// Clears the resolution cache.
@visibleForTesting
static void clearCache() => _cache.clear();

/// Resolves font file bytes for [fontFamily].
///
/// Returns cached results on subsequent calls. Returns `null` if the
Expand Down
Loading