Skip to content

UndoManager does not release UndoManagerClient causing memory leaks #148291

@CoderBuck

Description

@CoderBuck

When exit EditPage, UndoManager still holds the UndoHistory of the TextField of the page, eventually causing the Element of the page to be leaked.

related code: flutter/lib/src/widgets/undo_history.dart:200

  void _handleFocus() {
    if (!widget.focusNode.hasFocus) {
      return;
    }
    UndoManager.client = this; // no release when lose focus
    _updateState();
  }

Steps to reproduce

  1. flutter run --serve-observatory
  2. enter EditPage and exit EditPage
  3. open Observatory check EditPageElement is leak

Expected results

EditPageElement not leak

Actual results

EditPageElement leaked

Code sample

Code sample
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('Home'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.push(context, MaterialPageRoute(builder: (context) => const EditPage()));
        },
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

class EditPage extends StatelessWidget {
  const EditPage({super.key});

  @override
  StatelessElement createElement() => EditPageElement(this);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('EditPage')),
      body: const Center(
        child: TextField(
          autofocus: true,
        ),
      ),
    );
  }
}

class EditPageElement extends StatelessElement {
  EditPageElement(super.widget);
}

Screenshots or Video

Screenshots / Video demonstration

image

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.22.0, on macOS 12.7.4 21H1123 darwin-x64, locale zh-Hans-CN)

Metadata

Metadata

Labels

P3Issues that are less important to the Flutter projectfound in release: 3.22Found to occur in 3.22frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionteam-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions