-
Notifications
You must be signed in to change notification settings - Fork 979
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Is there an existing issue for this?
- I have searched the existing issues
Flutter Quill version
flutter_quill: ^11.0.0-dev.17 & flutter_quill_extensions: ^11.0.0-dev.7
Steps to reproduce
- Add
QuillSimpleToolbar
and passQuillSimpleToolbarConfig
withshowClipboardCut
,showClipboardCopy
, orshowClipboardPaste
set to true - Since it adds the button with Clipboard Service it causes performance issues:
Source code for reference:
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import '../../common/utils/widgets.dart';
import '../../editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart';
import '../../l10n/extensions/localizations_ext.dart';
import '../base_button/base_value_button.dart';
import '../simple_toolbar.dart';
enum ClipboardAction { cut, copy, paste }
class ClipboardMonitor {
bool _canPaste = false;
bool get canPaste => _canPaste;
Timer? _timer;
void monitorClipboard(bool add, void Function() listener) {
if (kIsWeb) return;
if (add) {
_timer = Timer.periodic(
const Duration(seconds: 1), (timer) => _update(listener));
} else {
_timer?.cancel();
}
}
Future<void> _update(void Function() listener) async {
final clipboardService = ClipboardServiceProvider.instance;
if (await clipboardService.hasClipboardContent) {
_canPaste = true;
listener();
}
}
}
class QuillToolbarClipboardButton extends QuillToolbarToggleStyleBaseButton {
QuillToolbarClipboardButton({
required super.controller,
required this.clipboardAction,
super.options = const QuillToolbarToggleStyleButtonOptions(),
/// Shares common options between all buttons, prefer the [options]
/// over the [baseOptions].
super.baseOptions,
super.key,
});
final ClipboardAction clipboardAction;
final ClipboardMonitor _monitor = ClipboardMonitor();
@override
State<StatefulWidget> createState() => QuillToolbarClipboardButtonState();
}
class QuillToolbarClipboardButtonState
extends QuillToolbarToggleStyleBaseButtonState<
QuillToolbarClipboardButton> {
@override
bool get currentStateValue {
switch (widget.clipboardAction) {
case ClipboardAction.cut:
return !controller.readOnly && !controller.selection.isCollapsed;
case ClipboardAction.copy:
return !controller.selection.isCollapsed;
case ClipboardAction.paste:
return !controller.readOnly && (kIsWeb || widget._monitor.canPaste);
}
}
void _listenClipboardStatus() => didChangeEditingValue();
@override
void addExtraListener() {
if (widget.clipboardAction == ClipboardAction.paste) {
widget._monitor.monitorClipboard(true, _listenClipboardStatus);
}
}
@override
void removeExtraListener(covariant QuillToolbarClipboardButton oldWidget) {
if (widget.clipboardAction == ClipboardAction.paste) {
oldWidget._monitor.monitorClipboard(false, _listenClipboardStatus);
}
}
@override
String get defaultTooltip => switch (widget.clipboardAction) {
ClipboardAction.cut => context.loc.cut,
ClipboardAction.copy => context.loc.copy,
ClipboardAction.paste => context.loc.paste,
};
@override
IconData get defaultIconData => switch (widget.clipboardAction) {
ClipboardAction.cut => Icons.cut_outlined,
ClipboardAction.copy => Icons.copy_outlined,
ClipboardAction.paste => Icons.paste_outlined,
};
void _onPressed() {
switch (widget.clipboardAction) {
case ClipboardAction.cut:
controller.clipboardSelection(false);
break;
case ClipboardAction.copy:
controller.clipboardSelection(true);
break;
case ClipboardAction.paste:
controller.clipboardPaste();
break;
}
afterButtonPressed?.call();
}
@override
Widget build(BuildContext context) {
final childBuilder = this.childBuilder;
if (childBuilder != null) {
return childBuilder(
options,
QuillToolbarToggleStyleButtonExtraOptions(
context: context,
controller: controller,
onPressed: _onPressed,
isToggled: currentValue,
),
);
}
return UtilityWidgets.maybeTooltip(
message: tooltip,
child: QuillToolbarIconButton(
icon: Icon(
iconData,
size: iconSize * iconButtonFactor,
),
isSelected: false,
onPressed: currentValue ? _onPressed : null,
afterPressed: afterButtonPressed,
iconTheme: iconTheme,
));
}
}
- Since the
QuillToolbarClipboardButton
was added to the Widget tree, it starts affecting the app performance & memory on the background, even if you are not actively copying or pasting with clipboard at the moment.
W/Looper ( 4641): PerfMonitor longMsg : seq=69 plan=18:41:47.480 late=0ms wall=1570ms h=android.os.Handler c=io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0 procState=-1
W/Looper ( 4641): PerfMonitor longMsg : seq=71 plan=18:41:48.479 late=572ms wall=1418ms h=android.os.Handler c=io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0 procState=-1
W/Looper ( 4641): PerfMonitor longMsg : seq=73 plan=18:41:49.479 late=991ms wall=1410ms h=android.os.Handler c=io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0 procState=-1
W/Looper ( 4641): PerfMonitor longMsg : seq=74 plan=18:41:50.559 late=1323ms wall=1427ms h=android.os.Handler c=io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0 procState=-1
...
...
Expected results
Expected Clipboard to not be as heavy for the application and to not cause performance issues.
Actual results
ClipboardService causes background lag when used.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working