diff --git a/sky/sdk/lib/editing/input.dart b/sky/sdk/lib/editing/input.dart index 91eb5e316b72d..0f0e3e5217488 100644 --- a/sky/sdk/lib/editing/input.dart +++ b/sky/sdk/lib/editing/input.dart @@ -19,7 +19,7 @@ const EdgeDims _kTextfieldPadding = const EdgeDims.symmetric(vertical: 8.0); class Input extends StatefulComponent { Input({ - Key key, + GlobalKey key, this.placeholder, this.onChanged }): super(key: key); diff --git a/sky/sdk/lib/widgets/basic.dart b/sky/sdk/lib/widgets/basic.dart index 5e7ba5dee04b7..f7df35c8f5aa8 100644 --- a/sky/sdk/lib/widgets/basic.dart +++ b/sky/sdk/lib/widgets/basic.dart @@ -22,7 +22,7 @@ import 'package:sky/widgets/widget.dart'; export 'package:sky/rendering/box.dart' show BackgroundImage, BoxConstraints, BoxDecoration, Border, BorderSide, EdgeDims; export 'package:sky/rendering/flex.dart' show FlexDirection, FlexJustifyContent, FlexAlignItems; export 'package:sky/rendering/object.dart' show Point, Offset, Size, Rect, Color, Paint, Path; -export 'package:sky/widgets/widget.dart' show Key, Widget, Component, StatefulComponent, App, runApp, Listener, ParentDataNode; +export 'package:sky/widgets/widget.dart' show Key, GlobalKey, Widget, Component, StatefulComponent, App, runApp, Listener, ParentDataNode; // PAINTING NODES diff --git a/sky/sdk/lib/widgets/focus.dart b/sky/sdk/lib/widgets/focus.dart index 5abb6fd1b4377..c50d434d622fc 100644 --- a/sky/sdk/lib/widgets/focus.dart +++ b/sky/sdk/lib/widgets/focus.dart @@ -14,11 +14,11 @@ class Focus extends Inherited { Focus({ GlobalKey key, - GlobalKey initialFocus, + this.initialFocus, Widget child }) : super(key: key, child: child); - GlobalKey initialFocus; + final GlobalKey initialFocus; GlobalKey _currentlyFocusedKey; GlobalKey get currentlyFocusedKey { diff --git a/sky/sdk/lib/widgets/widget.dart b/sky/sdk/lib/widgets/widget.dart index 83b04d002a4ac..a7de0ca712bd5 100644 --- a/sky/sdk/lib/widgets/widget.dart +++ b/sky/sdk/lib/widgets/widget.dart @@ -140,13 +140,46 @@ abstract class Widget { _notifyingMountStatus = false; sky.tracing.end("Widget._notifyMountStatusChanged"); } + assert(_debugDuplicateGlobalKeys.isEmpty); } + static final Map _globalKeys = new Map(); + static final Map _debugDuplicateGlobalKeys = new Map(); + /// Override this function to learn when this [Widget] enters the widget tree. - void didMount() { } + void didMount() { + if (key is GlobalKey) { + assert(() { + if (_globalKeys.containsKey(key)) { + int oldCount = _debugDuplicateGlobalKeys.putIfAbsent(key, () => 1); + assert(oldCount >= 1); + _debugDuplicateGlobalKeys[key] = oldCount + 1; + } + return true; + }); + _globalKeys[key] = this; + } + } /// Override this function to learn when this [Widget] leaves the widget tree. - void didUnmount() { } + void didUnmount() { + if (key is GlobalKey) { + assert(() { + if (_globalKeys.containsKey(key) && _debugDuplicateGlobalKeys.containsKey(key)) { + int oldCount = _debugDuplicateGlobalKeys[key]; + assert(oldCount >= 2); + if (oldCount == 2) { + _debugDuplicateGlobalKeys.remove(key); + } else { + _debugDuplicateGlobalKeys[key] = oldCount - 1; + } + } + return true; + }); + if (_globalKeys[key] == this) + _globalKeys.remove(key); + } + } RenderObject _root;