Skip to content

feat(fleather): add iPad Scribble support - #586

Open
zhpoo wants to merge 2 commits into
fleather-editor:masterfrom
zhpoo:master
Open

feat(fleather): add iPad Scribble support#586
zhpoo wants to merge 2 commits into
fleather-editor:masterfrom
zhpoo:master

Conversation

@zhpoo

@zhpoo zhpoo commented Jul 24, 2026

Copy link
Copy Markdown

Changes:

  • expose stylusHandwritingEnabled from FleatherEditor, FleatherField, and RawEditor;
  • implement Flutter's ScribbleClient lifecycle for editable iOS editors;
  • report UTF-16 character, caret, composing, size, and transform geometry to the text input connection;
  • render and remove Scribble placeholders without changing the Parchment document;
  • support selection boxes across Fleather block nodes;
  • accept Scribble handwriting across the full editor surface without moving the current selection on pen-down;
  • connect Fleather history to the iOS system undo manager for Pencil toolbar undo and redo;
  • reject Scribble input whose center is outside the editor bounds;
  • keep Scribble disabled at runtime on non-iOS platforms and in read-only editors.

@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.58491% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.23%. Comparing base (1ee8bdc) to head (10aeb47).

Files with missing lines Patch % Lines
packages/fleather/lib/src/widgets/editor.dart 92.53% 10 Missing ⚠️
packages/fleather/lib/src/widgets/text_line.dart 84.21% 6 Missing ⚠️
packages/fleather/lib/src/widgets/history.dart 97.95% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #586      +/-   ##
==========================================
+ Coverage   88.11%   88.23%   +0.12%     
==========================================
  Files          63       63              
  Lines       10899    11156     +257     
==========================================
+ Hits         9604     9844     +240     
- Misses       1295     1312      +17     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Amir-P
Amir-P requested review from Amir-P and amantoux August 16, 2026 08:02

@Amir-P Amir-P left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this! I took a look at the changes and left some comments. Please take a look. @zhpoo

I don't own an iPad so I'm not gonna be able to test and verify the behavior. Will you be able to do that? @amantoux

}

void _updateUndoState() {
if (defaultTargetPlatform == TargetPlatform.iOS &&

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we should skip the check for iOS platform here. If we are the client, we should update the state anyway.

class _FleatherHistoryState extends State<FleatherHistory> {
class _FleatherHistoryState extends State<FleatherHistory>
with UndoManagerClient {
Timer? _historyStateTimer;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a reason for introducing a timer and periodically updating the undo state as the undo state is retrieved from the controller and it would notify the listeners if the state changes. Am I missing something?

final size = Size(
min(renderEditor.size.width,
renderEditor.maxContentWidth ?? double.infinity) -
renderEditor.padding.horizontal,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should just use the renderEditor.size here and not take padding or content width into account as user should be able to write with stylus anywhere within the editor area. This is also what Flutter's EditableText does:

  void _updateSizeAndTransform() {
    final Size size = renderEditable.size;
    final Matrix4 transform = renderEditable.getTransformTo(null);
    _textInputConnection!.setEditableSizeAndTransform(size, transform);
  }

@override
GlobalKey<EditorState> get editableTextKey => widget.editorKey ?? _editorKey!;

FocusNode get effectiveFocusNode =>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to make the focus node required and non-optional for the RawEditor now that we have lifted the internal focus node creation up. It's gonna be a breaking change but I don't think many would be affected. WDYT? @amantoux

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants