Skip to content

fix(w-input): native text selection (web mouse-drag + platform-adaptive handles)#116

Merged
anilcancakir merged 6 commits into
masterfrom
fix/winput-native-text-selection
Jun 23, 2026
Merged

fix(w-input): native text selection (web mouse-drag + platform-adaptive handles)#116
anilcancakir merged 6 commits into
masterfrom
fix/winput-native-text-selection

Conversation

@anilcancakir

@anilcancakir anilcancakir commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

WInput lost text selection when it was rewritten Material-free onto a bare EditableText (#106): a bare EditableText does not install the selection pointer gestures (those live in TextSelectionGestureDetectorBuilder, which TextField/CupertinoTextField use to wrap it). On web, mouse drag-select did nothing and only keyboard select-all (Ctrl/Cmd+A) worked.

This wires the framework's canonical Material-free selectable-input recipe:

  • _WInputState implements TextSelectionGestureDetectorBuilderDelegate (single GlobalKey<EditableTextState>).
  • The whole decorated box is wrapped by TextSelectionGestureDetectorBuilder.buildGestureDetector, and EditableText.rendererIgnoresPointer is true so the gesture layer is the sole pointer handler.
  • The hand-built whole-box GestureDetector is removed; onTap is forwarded via onUserTap.

Selection handles: cupertino-only (no material.dart import)

WInput wires cupertinoTextSelectionHandleControls on every platform, unchanged from the 1.1.0 shipped behavior. This keeps the widget cupertino-only with no package:flutter/material.dart import, preserving the deliberate import-free state established in #106 (WInput is the only widget file that imports cupertino.dart and not material.dart). cupertinoTextSelectionHandleControls mixes in TextSelectionHandleControls, so the toolbar stays on the Material-free contextMenuBuilder path and no Overlay-less long-press throws. The Material-free guarantee (no Material ancestor required at runtime) holds; WFormInput / WSelect / WDynamic inherit the fix unchanged.

(An earlier revision of this branch made handles platform-adaptive via the Material *HandleControls constants, which re-introduced the material.dart import. That was reverted to honor #106's cupertino-only intent; platform-adaptive handles can be revisited later via a widgets-only custom TextSelectionControls if desired.)

Behavior change

  • onTap now dispatches through the native gesture builder instead of a hand-built GestureDetector. It continues to fire when the user taps the field; the change is the gesture mechanism (which also brings drag-select and double-tap word selection), not a new onTap contract.

Test plan

  • test/widgets/w_input/selection_test.dart: mouse drag-select (non-collapsed selection), double-tap word, whole-box tap focus + onTap, disabled inert, read-only selectable, no-Overlay no-crash, and a Cupertino-handle assertion across every TargetPlatform under a bare Material-free Overlay harness.
  • dart analyze: clean (no material.dart import). dart format: no diff. flutter test: 1443 pass (1 pre-existing skip). Coverage: 91.2% (gate 90%). flutter build web --release: succeeds.

Post-change sync

  • doc/widgets/w-input.md, example/lib/pages/forms/input_basic.dart, skills/wind-ui (SKILL.md 2.5.0 -> 2.6.0 + forms.md), CHANGELOG.md ([Unreleased] Fixed + Changed) — all state cupertino-only handles.

Closes the WInput selection regression from #106.

…ctorBuilder

The Material-free rewrite (#106) dropped the selection gesture layer by
rendering a bare EditableText, so mouse drag-select did nothing on web
(only keyboard select-all worked). Adopt the framework's canonical
Material-free recipe: _WInputState implements
TextSelectionGestureDetectorBuilderDelegate, the whole decorated box is
wrapped by buildGestureDetector, and EditableText.rendererIgnoresPointer
is true so the gesture layer is the sole pointer handler. The hand-built
whole-box GestureDetector is removed; onTap is forwarded via onUserTap.
Selection handles are platform-adaptive via the lowercase *HandleControls
constants (Cupertino on iOS, Cupertino-desktop on macOS, Material on
Android/Fuchsia, desktop on Linux/Windows); each mixes in
TextSelectionHandleControls so the toolbar stays on the Material-free
contextMenuBuilder path and no Overlay-less long-press throws.
Update the w-input reference, the wind-ui SKILL.md WInput row (version
2.5.0 -> 2.6.0), and the forms reference to describe native text
selection (mouse-drag, double-tap word, whole-box tap) and the
platform-adaptive handles, replacing the stale Cupertino-on-all-platforms
note. Add a web-reality note: Flutter renders selection to a canvas (no
native browser input); right-click shows the browser menu by default, and
an app opting into WInput's own toolbar calls
BrowserContextMenu.disableContextMenu() at startup.
Add a Text Selection section with a prefilled read-only WInput and a
caption explaining drag-to-select, double-tap word, and platform-adaptive
handles, so the demo gallery showcases the native selection behavior.
Copilot AI review requested due to automatic review settings June 23, 2026 18:35
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@anilcancakir, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 24 minutes and 4 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses rolling per-developer review limits. Reviews become available again as older review attempts age out of the rolling limit window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6bfc17e8-3c5e-4fb9-a692-a5e5c652daa0

📥 Commits

Reviewing files that changed from the base of the PR and between af524fd and f12fe02.

📒 Files selected for processing (7)
  • CHANGELOG.md
  • doc/widgets/w-input.md
  • example/lib/pages/forms/input_basic.dart
  • lib/src/widgets/w_input.dart
  • skills/wind-ui/SKILL.md
  • skills/wind-ui/references/forms.md
  • test/widgets/w_input/selection_test.dart
📝 Walkthrough

Walkthrough

WInput is migrated from a manual GestureDetector tap wrapper to Flutter's TextSelectionGestureDetectorBuilderDelegate framework, restoring native drag-select, double-tap, and long-press selection. A platform-adaptive helper picks Cupertino, Material, or desktop selection handle controls at runtime, selection UI is gated on Overlay presence, and a new test suite and docs accompany the change.

Changes

WInput Native Text Selection

Layer / File(s) Summary
Delegate interface and gesture builder wiring
lib/src/widgets/w_input.dart
_WInputState implements TextSelectionGestureDetectorBuilderDelegate; _editableTextKey is typed to GlobalKey<EditableTextState>; _WInputSelectionGestureDetectorBuilder class is added overriding onUserTap to forward widget.onTap; the box-level wrapper switches from GestureDetector(onTap:...) to _selectionGestureDetectorBuilder.buildGestureDetector(...).
Platform-adaptive selection controls and EditableText config
lib/src/widgets/w_input.dart
EditableText gains rendererIgnoresPointer: true; selectionControls is resolved via _platformSelectionControls() switching on defaultTargetPlatform (Cupertino/Material/desktop); selectionEnabled is gated by Overlay presence and widget.enabled.
Selection test suite
test/widgets/w_input/selection_test.dart
New test file with bare (no Overlay) and overlay-enabled harnesses; covers mouse-drag selection, double-tap word selection, tap-to-focus with onTap, disabled-field inertness, read-only drag selection, typing and long-press without Overlay, and per-platform selectionControls runtime-type assertions.
Example page, documentation, and changelog
example/lib/pages/forms/input_basic.dart, doc/widgets/w-input.md, skills/wind-ui/SKILL.md, skills/wind-ui/references/forms.md, CHANGELOG.md
Adds a Text Selection demo section to the forms example page; expands WInput accessibility docs with platform handle/Overlay and web context-menu notes; updates SKILL.md to version 2.6.0; adds CHANGELOG entries for the gesture path change and native selection restoration.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • fluttersdk/wind#106: Introduced the Material-free EditableText-based rendering in WInput that this PR builds on, replacing the gesture wiring and adding selection handle controls.

Poem

🐇 A tap and a drag, the selection comes alive,
No more GestureDetector — now gestures really thrive!
Cupertino on iOS, Material where droid reigns,
Desktop gets its handles, each platform fully gains.
The Overlay guards the toolbar, hidden when bare,
Long-press without crashing? The rabbit handled it with care! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: native text selection support for WInput, specifically mentioning web mouse-drag and platform-adaptive selection handles.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/winput-native-text-selection

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Restores native text selection behavior in WInput after the Material-free EditableText rewrite by adopting Flutter’s canonical TextSelectionGestureDetectorBuilder-based gesture layer and platform-adaptive selection handle controls, with corresponding tests and documentation updates.

Changes:

  • Reintroduces pointer-driven selection gestures (mouse drag-select, double-tap word, whole-box tap-to-focus) via TextSelectionGestureDetectorBuilder and rendererIgnoresPointer: true.
  • Switches selection handles to platform-adaptive *TextSelectionHandleControls constants while keeping the input Material-free (no Material ancestor required).
  • Adds targeted widget tests plus doc/example/skill/changelog updates describing the restored selection behavior and web/Overlay constraints.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
lib/src/widgets/w_input.dart Installs the selection gesture detector builder, enables platform-adaptive handle controls, removes hand-rolled whole-box GestureDetector.
test/widgets/w_input/selection_test.dart Adds coverage for drag selection, double-tap word selection, whole-box tap focus/onTap, disabled/read-only/no-Overlay behavior, and per-platform controls wiring.
doc/widgets/w-input.md Documents native selection behavior, Overlay requirement, and web-specific context menu behavior.
example/lib/pages/forms/input_basic.dart Adds a read-only “Text Selection” demo section with realistic prefilled content.
skills/wind-ui/SKILL.md Bumps skill version and updates WInput capability summary to include native selection + Overlay notes.
skills/wind-ui/references/forms.md Adds a concise note about WInput/WFormInput native selection + Overlay requirement.
CHANGELOG.md Records the gesture-path change and the restored selection behavior under [Unreleased].

@codecov

codecov Bot commented Jun 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

…rt import)

Restore w_input.dart to its deliberate cupertino-only state from #106
(the only widget file that imports cupertino.dart and not material.dart).
The platform-adaptive handle switch added the package:flutter/material.dart
import back for materialTextSelectionHandleControls / desktopTextSelectionHandleControls,
which #106 explicitly dropped. WInput now wires cupertinoTextSelectionHandleControls
on every platform (unchanged from the 1.1.0 shipped behavior), keeping the
widget cupertino-only while the gesture-builder fix (the actual web mouse
drag-select bug) is untouched. Tests assert Cupertino handles on every
TargetPlatform under a bare Material-free Overlay harness.
Update the w-input doc, the selectable example caption, the wind-ui skill
+ forms reference, and the CHANGELOG to state selection handles are
Cupertino-style on all platforms (cupertino-only, no material.dart import),
replacing the platform-adaptive wording.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Comment thread doc/widgets/w-input.md Outdated
Comment thread skills/wind-ui/references/forms.md Outdated
Comment thread skills/wind-ui/SKILL.md Outdated
Comment thread lib/src/widgets/w_input.dart Outdated
Copilot flagged that the docs/comment claimed only the selection toolbar
and handles are suppressed without an Overlay. In fact interactive
selection is fully gated on an Overlay (enableInteractiveSelection and the
gesture builder delegate's selectionEnabled both check Overlay.maybeOf), so
without one drag-select, double-tap word, and long-press are all off too;
only typing and focus work. Reword the class dartdoc, the selectionControls
comment, the w-input doc note, and the wind-ui skill + forms reference to
state this accurately.
@anilcancakir anilcancakir merged commit 9a73387 into master Jun 23, 2026
9 checks passed
@anilcancakir anilcancakir deleted the fix/winput-native-text-selection branch June 23, 2026 19:17
@anilcancakir anilcancakir mentioned this pull request Jun 23, 2026
anilcancakir added a commit that referenced this pull request Jun 23, 2026
Patch release 1.1.1: WInput native text selection (#116), WText DefaultTextStyle color cascade (#112), WInput onTap gesture-builder dispatch (#116). pubspec + CHANGELOG + version strings synced to 1.1.1.
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