Skip to content

Add paintSelectionBehindText configuration option #2604

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

Hamza-Bayar-2
Copy link

@Hamza-Bayar-2 Hamza-Bayar-2 commented Jun 23, 2025

Fix: Web platform text selection scroll jumping + Feature: Configurable selection paint order

1. Web Platform Scroll Jumping Issue Description

On web platform, when performing text selection by dragging (especially with long documents), the scroll behavior becomes erratic and jumpy. The viewport constantly jumps back to the selection start position, making it nearly impossible to select text upwards or across long distances.

2. Selection Readability Issue

Text selection highlighting was always painted in front of text, requiring transparent selection colors which could make selected text hard to read with certain color combinations.

Root Causes

  • Scroll Issue
    The problem was in the caretTextPosition getter in RenderEditor class. During drag selection, it always returned selection.extent (the current drag position), causing the scroll mechanism to constantly try to bring the moving selection end into view, resulting in conflicting scroll behaviors.

  • Selection Paint Order
    The selection highlighting was hardcoded to paint in front of text, limiting flexibility for different UI preferences and readability requirements.

Solutions Implemented

1. Intelligent Scroll Behavior for Web Platform

Enhanced QuillController with drag state management:

  • Added _isDragging flag to track drag state
  • Added _previousSelection to track selection changes
  • Added startDragSelection() and endDragSelection() methods
  • Added getCaretPositionForScrolling() method that returns appropriate caret position based on which selection boundary changed

Updated RenderEditor to use controller's smart caret positioning:

  • Modified caretTextPosition getter to use controller's getCaretPositionForScrolling() during web drag operations
  • This ensures scroll follows the correct selection boundary (base vs extent) based on drag direction

Updated selection handling to properly track drag lifecycle:

  • Integrated drag start/end calls in selection delegates
  • Updated _updateSelection to maintain previous selection state during drag

2. Configurable Selection Paint Order

Added paintSelectionBehindText boolean field to control rendering order:

  • true (default): Selection is painted behind the text, allowing opaque selection colors
  • false: Selection is painted in front of the text (previous behavior), requiring transparent selection colors

Implementation details:

  • Added field to QuillEditorConfig with default value true
  • Propagated through QuillRawEditorConfig, EditableTextLine, and RenderEditableTextLine
  • Modified paint order in RenderEditableTextLine.paint() method based on the boolean value

Usage

Scroll Fix (Automatic)

// Web scroll fix is automatically applied - no configuration needed
QuillEditor.basic(
  controller: _controller,
)

Selection Paint Order Configuration

// Use new behavior (opaque selection behind text) - Default
QuillEditor.basic(
  controller: _controller,
  config: const QuillEditorConfig(
    paintSelectionBehindText: true, // Default value
  ),
)

// Use old behavior (transparent selection in front of text)
QuillEditor.basic(
  controller: _controller,
  config: const QuillEditorConfig(
    paintSelectionBehindText: false,
  ),
)

Benefits

Scroll Fix

  • Text selection works smoothly in all directions on web
  • No scroll jumping during drag operations
  • Maintains backward compatibility with mobile platforms
  • Normal cursor behavior unchanged when not dragging

Selection Paint Order

  • Improves text readability with opaque selection colors
  • Maintains backward compatibility with default true value
  • Provides flexibility for different UI preferences
  • Better accessibility with high-contrast selection colors

Testing

Scroll Fix

  • Web platform upward and downward drag selection
  • Long document text selection
  • Mobile/Desktop platform compatibility (no regression)
  • Normal cursor behavior when not selecting

Selection Paint Order

  • Default behavior with opaque selection colors
  • Legacy behavior with transparent selection colors
  • Cross-platform compatibility
  • Performance impact assessment

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.

1 participant