test / unit + widget + golden + a11y (push) Failing after 27s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
test / dart doc (lib API) (push) Failing after 27s
The Phase-1 wedge of epic T-132 (D-75): the Claude pane no longer renders the PTY's TUI. It runs claude in tmux as before (so the transcript is written) but displays the conversation as native cards read from the transcript via TranscriptReader — user / assistant markdown / thinking / tool-use / tool-result. The whole list sits under a new no-Material ClideSelectionArea (SelectableRegion-based, since Flutter's SelectionArea is Material and D-7 bans it), so text selects and copies across cards — recovering the terminal's one real advantage. ClaudePane drops its Terminal model and the resize-driven spawn trigger (spawn now fires once on didChangeDependencies with a fixed tmux size, since the TUI isn't shown); pane.output is no longer consumed. The terminal builtin is untouched and still available as a general tool. Input/composer is the next ticket (T-138). Co-Authored-By: Claude <noreply@anthropic.com>
44 lines
1.4 KiB
Dart
44 lines
1.4 KiB
Dart
import 'package:flutter/widgets.dart';
|
|
|
|
/// No-Material text selection wrapper (D-7 — clide ships no Material).
|
|
///
|
|
/// Flutter's convenient `SelectionArea` lives in `package:flutter/material.dart`,
|
|
/// so clide can't use it. This wraps the widget-layer [SelectableRegion]
|
|
/// with the desktop-appropriate setup: a managed [FocusNode], no on-screen
|
|
/// selection handles (`emptyTextSelectionControls` — desktop selects by
|
|
/// mouse drag), and [DefaultTextEditingShortcuts] so Ctrl/Cmd+A and
|
|
/// Ctrl/Cmd+C work even outside a `WidgetsApp`.
|
|
///
|
|
/// Any descendant `Text` / `Text.rich` (e.g. [ClideMarkdown],
|
|
/// [ClideCodeBlock] after T-135) becomes selectable, and selection +
|
|
/// copy span across them.
|
|
class ClideSelectionArea extends StatefulWidget {
|
|
const ClideSelectionArea({super.key, required this.child});
|
|
|
|
final Widget child;
|
|
|
|
@override
|
|
State<ClideSelectionArea> createState() => _ClideSelectionAreaState();
|
|
}
|
|
|
|
class _ClideSelectionAreaState extends State<ClideSelectionArea> {
|
|
final FocusNode _focusNode = FocusNode(debugLabel: 'ClideSelectionArea');
|
|
|
|
@override
|
|
void dispose() {
|
|
_focusNode.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return DefaultTextEditingShortcuts(
|
|
child: SelectableRegion(
|
|
focusNode: _focusNode,
|
|
selectionControls: emptyTextSelectionControls,
|
|
child: widget.child,
|
|
),
|
|
);
|
|
}
|
|
}
|