• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4// Synced 2019-05-30T14:20:57.841444.
5
6part of ui;
7
8/// Signature of callbacks that have no arguments and return no data.
9typedef VoidCallback = void Function();
10
11/// Signature for frame-related callbacks from the scheduler.
12///
13/// The `timeStamp` is the number of milliseconds since the beginning of the
14/// scheduler's epoch. Use timeStamp to determine how far to advance animation
15/// timelines so that all the animations in the system are synchronized to a
16/// common time base.
17typedef FrameCallback = void Function(Duration duration);
18
19/// Signature for [Window.onReportTimings].
20typedef TimingsCallback = void Function(List<FrameTiming> timings);
21
22/// Signature for [Window.onPointerDataPacket].
23typedef PointerDataPacketCallback = void Function(PointerDataPacket packet);
24
25/// Signature for [Window.onSemanticsAction].
26typedef SemanticsActionCallback = void Function(
27    int id, SemanticsAction action, ByteData args);
28
29/// Signature for responses to platform messages.
30///
31/// Used as a parameter to [Window.sendPlatformMessage] and
32/// [Window.onPlatformMessage].
33typedef PlatformMessageResponseCallback = void Function(ByteData data);
34
35/// Signature for [Window.onPlatformMessage].
36typedef PlatformMessageCallback = void Function(
37    String name, ByteData data, PlatformMessageResponseCallback callback);
38
39/// States that an application can be in.
40///
41/// The values below describe notifications from the operating system.
42/// Applications should not expect to always receive all possible
43/// notifications. For example, if the users pulls out the battery from the
44/// device, no notification will be sent before the application is suddenly
45/// terminated, along with the rest of the operating system.
46///
47/// See also:
48///
49///  * [WidgetsBindingObserver], for a mechanism to observe the lifecycle state
50///    from the widgets layer.
51enum AppLifecycleState {
52  /// The application is visible and responding to user input.
53  resumed,
54
55  /// The application is in an inactive state and is not receiving user input.
56  ///
57  /// On iOS, this state corresponds to an app or the Flutter host view running
58  /// in the foreground inactive state. Apps transition to this state when in
59  /// a phone call, responding to a TouchID request, when entering the app
60  /// switcher or the control center, or when the UIViewController hosting the
61  /// Flutter app is transitioning.
62  ///
63  /// On Android, this corresponds to an app or the Flutter host view running
64  /// in the foreground inactive state.  Apps transition to this state when
65  /// another activity is focused, such as a split-screen app, a phone call,
66  /// a picture-in-picture app, a system dialog, or another window.
67  ///
68  /// Apps in this state should assume that they may be [paused] at any time.
69  inactive,
70
71  /// The application is not currently visible to the user, not responding to
72  /// user input, and running in the background.
73  ///
74  /// When the application is in this state, the engine will not call the
75  /// [Window.onBeginFrame] and [Window.onDrawFrame] callbacks.
76  ///
77  /// Android apps in this state should assume that they may enter the
78  /// [suspending] state at any time.
79  paused,
80
81  /// The application will be suspended momentarily.
82  ///
83  /// When the application is in this state, the engine will not call the
84  /// [Window.onBeginFrame] and [Window.onDrawFrame] callbacks.
85  ///
86  /// On iOS, this state is currently unused.
87  suspending,
88}
89
90/// A representation of distances for each of the four edges of a rectangle,
91/// used to encode the view insets and padding that applications should place
92/// around their user interface, as exposed by [Window.viewInsets] and
93/// [Window.padding]. View insets and padding are preferably read via
94/// [MediaQuery.of].
95///
96/// For a generic class that represents distances around a rectangle, see the
97/// [EdgeInsets] class.
98///
99/// See also:
100///
101///  * [WidgetsBindingObserver], for a widgets layer mechanism to receive
102///    notifications when the padding changes.
103///  * [MediaQuery.of], for the preferred mechanism for accessing these values.
104///  * [Scaffold], which automatically applies the padding in material design
105///    applications.
106class WindowPadding {
107  const WindowPadding._({this.left, this.top, this.right, this.bottom});
108
109  /// The distance from the left edge to the first unpadded pixel, in physical
110  /// pixels.
111  final double left;
112
113  /// The distance from the top edge to the first unpadded pixel, in physical
114  /// pixels.
115  final double top;
116
117  /// The distance from the right edge to the first unpadded pixel, in physical
118  /// pixels.
119  final double right;
120
121  /// The distance from the bottom edge to the first unpadded pixel, in physical
122  /// pixels.
123  final double bottom;
124
125  /// A window padding that has zeros for each edge.
126  static const WindowPadding zero =
127      WindowPadding._(left: 0.0, top: 0.0, right: 0.0, bottom: 0.0);
128
129  @override
130  String toString() {
131    return 'WindowPadding(left: $left, top: $top, right: $right, bottom: $bottom)';
132  }
133}
134
135/// An identifier used to select a user's language and formatting preferences.
136///
137/// This represents a [Unicode Language
138/// Identifier](https://www.unicode.org/reports/tr35/#Unicode_language_identifier)
139/// (i.e. without Locale extensions), except variants are not supported.
140///
141/// Locales are canonicalized according to the "preferred value" entries in the
142/// [IANA Language Subtag
143/// Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry).
144/// For example, `const Locale('he')` and `const Locale('iw')` are equal and
145/// both have the [languageCode] `he`, because `iw` is a deprecated language
146/// subtag that was replaced by the subtag `he`.
147///
148/// See also:
149///
150///  * [Window.locale], which specifies the system's currently selected
151///    [Locale].
152class Locale {
153  /// Creates a new Locale object. The first argument is the
154  /// primary language subtag, the second is the region (also
155  /// referred to as 'country') subtag.
156  ///
157  /// For example:
158  ///
159  /// ```dart
160  /// const Locale swissFrench = const Locale('fr', 'CH');
161  /// const Locale canadianFrench = const Locale('fr', 'CA');
162  /// ```
163  ///
164  /// The primary language subtag must not be null. The region subtag is
165  /// optional. When there is no region/country subtag, the parameter should
166  /// be omitted or passed `null` instead of an empty-string.
167  ///
168  /// The subtag values are _case sensitive_ and must be one of the valid
169  /// subtags according to CLDR supplemental data:
170  /// [language](http://unicode.org/cldr/latest/common/validity/language.xml),
171  /// [region](http://unicode.org/cldr/latest/common/validity/region.xml). The
172  /// primary language subtag must be at least two and at most eight lowercase
173  /// letters, but not four letters. The region region subtag must be two
174  /// uppercase letters or three digits. See the [Unicode Language
175  /// Identifier](https://www.unicode.org/reports/tr35/#Unicode_language_identifier)
176  /// specification.
177  ///
178  /// Validity is not checked by default, but some methods may throw away
179  /// invalid data.
180  ///
181  /// See also:
182  ///
183  ///  * [new Locale.fromSubtags], which also allows a [scriptCode] to be
184  ///    specified.
185  const Locale(
186    this._languageCode, [
187    this._countryCode,
188  ])  : assert(_languageCode != null),
189        assert(_languageCode != ''),
190        scriptCode = null;
191
192  /// Creates a new Locale object.
193  ///
194  /// The keyword arguments specify the subtags of the Locale.
195  ///
196  /// The subtag values are _case sensitive_ and must be valid subtags according
197  /// to CLDR supplemental data:
198  /// [language](http://unicode.org/cldr/latest/common/validity/language.xml),
199  /// [script](http://unicode.org/cldr/latest/common/validity/script.xml) and
200  /// [region](http://unicode.org/cldr/latest/common/validity/region.xml) for
201  /// each of languageCode, scriptCode and countryCode respectively.
202  ///
203  /// The [countryCode] subtag is optional. When there is no country subtag,
204  /// the parameter should be omitted or passed `null` instead of an empty-string.
205  ///
206  /// Validity is not checked by default, but some methods may throw away
207  /// invalid data.
208  const Locale.fromSubtags({
209    String languageCode = 'und',
210    this.scriptCode,
211    String countryCode,
212  })  : assert(languageCode != null),
213        assert(languageCode != ''),
214        _languageCode = languageCode,
215        assert(scriptCode != ''),
216        assert(countryCode != ''),
217        _countryCode = countryCode;
218
219  /// The primary language subtag for the locale.
220  ///
221  /// This must not be null. It may be 'und', representing 'undefined'.
222  ///
223  /// This is expected to be string registered in the [IANA Language Subtag
224  /// Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry)
225  /// with the type "language". The string specified must match the case of the
226  /// string in the registry.
227  ///
228  /// Language subtags that are deprecated in the registry and have a preferred
229  /// code are changed to their preferred code. For example, `const
230  /// Locale('he')` and `const Locale('iw')` are equal, and both have the
231  /// [languageCode] `he`, because `iw` is a deprecated language subtag that was
232  /// replaced by the subtag `he`.
233  ///
234  /// This must be a valid Unicode Language subtag as listed in [Unicode CLDR
235  /// supplemental
236  /// data](http://unicode.org/cldr/latest/common/validity/language.xml).
237  ///
238  /// See also:
239  ///
240  ///  * [new Locale.fromSubtags], which describes the conventions for creating
241  ///    [Locale] objects.
242  String get languageCode => _replaceDeprecatedLanguageSubtag(_languageCode);
243  final String _languageCode;
244
245  static String _replaceDeprecatedLanguageSubtag(String languageCode) {
246    // This switch statement is generated by //flutter/tools/gen_locale.dart
247    // Mappings generated for language subtag registry as of 2018-08-08.
248    switch (languageCode) {
249      case 'in':
250        return 'id'; // Indonesian; deprecated 1989-01-01
251      case 'iw':
252        return 'he'; // Hebrew; deprecated 1989-01-01
253      case 'ji':
254        return 'yi'; // Yiddish; deprecated 1989-01-01
255      case 'jw':
256        return 'jv'; // Javanese; deprecated 2001-08-13
257      case 'mo':
258        return 'ro'; // Moldavian, Moldovan; deprecated 2008-11-22
259      case 'aam':
260        return 'aas'; // Aramanik; deprecated 2015-02-12
261      case 'adp':
262        return 'dz'; // Adap; deprecated 2015-02-12
263      case 'aue':
264        return 'ktz'; // =/Kx'au//'ein; deprecated 2015-02-12
265      case 'ayx':
266        return 'nun'; // Ayi (China); deprecated 2011-08-16
267      case 'bgm':
268        return 'bcg'; // Baga Mboteni; deprecated 2016-05-30
269      case 'bjd':
270        return 'drl'; // Bandjigali; deprecated 2012-08-12
271      case 'ccq':
272        return 'rki'; // Chaungtha; deprecated 2012-08-12
273      case 'cjr':
274        return 'mom'; // Chorotega; deprecated 2010-03-11
275      case 'cka':
276        return 'cmr'; // Khumi Awa Chin; deprecated 2012-08-12
277      case 'cmk':
278        return 'xch'; // Chimakum; deprecated 2010-03-11
279      case 'coy':
280        return 'pij'; // Coyaima; deprecated 2016-05-30
281      case 'cqu':
282        return 'quh'; // Chilean Quechua; deprecated 2016-05-30
283      case 'drh':
284        return 'khk'; // Darkhat; deprecated 2010-03-11
285      case 'drw':
286        return 'prs'; // Darwazi; deprecated 2010-03-11
287      case 'gav':
288        return 'dev'; // Gabutamon; deprecated 2010-03-11
289      case 'gfx':
290        return 'vaj'; // Mangetti Dune !Xung; deprecated 2015-02-12
291      case 'ggn':
292        return 'gvr'; // Eastern Gurung; deprecated 2016-05-30
293      case 'gti':
294        return 'nyc'; // Gbati-ri; deprecated 2015-02-12
295      case 'guv':
296        return 'duz'; // Gey; deprecated 2016-05-30
297      case 'hrr':
298        return 'jal'; // Horuru; deprecated 2012-08-12
299      case 'ibi':
300        return 'opa'; // Ibilo; deprecated 2012-08-12
301      case 'ilw':
302        return 'gal'; // Talur; deprecated 2013-09-10
303      case 'jeg':
304        return 'oyb'; // Jeng; deprecated 2017-02-23
305      case 'kgc':
306        return 'tdf'; // Kasseng; deprecated 2016-05-30
307      case 'kgh':
308        return 'kml'; // Upper Tanudan Kalinga; deprecated 2012-08-12
309      case 'koj':
310        return 'kwv'; // Sara Dunjo; deprecated 2015-02-12
311      case 'krm':
312        return 'bmf'; // Krim; deprecated 2017-02-23
313      case 'ktr':
314        return 'dtp'; // Kota Marudu Tinagas; deprecated 2016-05-30
315      case 'kvs':
316        return 'gdj'; // Kunggara; deprecated 2016-05-30
317      case 'kwq':
318        return 'yam'; // Kwak; deprecated 2015-02-12
319      case 'kxe':
320        return 'tvd'; // Kakihum; deprecated 2015-02-12
321      case 'kzj':
322        return 'dtp'; // Coastal Kadazan; deprecated 2016-05-30
323      case 'kzt':
324        return 'dtp'; // Tambunan Dusun; deprecated 2016-05-30
325      case 'lii':
326        return 'raq'; // Lingkhim; deprecated 2015-02-12
327      case 'lmm':
328        return 'rmx'; // Lamam; deprecated 2014-02-28
329      case 'meg':
330        return 'cir'; // Mea; deprecated 2013-09-10
331      case 'mst':
332        return 'mry'; // Cataelano Mandaya; deprecated 2010-03-11
333      case 'mwj':
334        return 'vaj'; // Maligo; deprecated 2015-02-12
335      case 'myt':
336        return 'mry'; // Sangab Mandaya; deprecated 2010-03-11
337      case 'nad':
338        return 'xny'; // Nijadali; deprecated 2016-05-30
339      case 'ncp':
340        return 'kdz'; // Ndaktup; deprecated 2018-03-08
341      case 'nnx':
342        return 'ngv'; // Ngong; deprecated 2015-02-12
343      case 'nts':
344        return 'pij'; // Natagaimas; deprecated 2016-05-30
345      case 'oun':
346        return 'vaj'; // !O!ung; deprecated 2015-02-12
347      case 'pcr':
348        return 'adx'; // Panang; deprecated 2013-09-10
349      case 'pmc':
350        return 'huw'; // Palumata; deprecated 2016-05-30
351      case 'pmu':
352        return 'phr'; // Mirpur Panjabi; deprecated 2015-02-12
353      case 'ppa':
354        return 'bfy'; // Pao; deprecated 2016-05-30
355      case 'ppr':
356        return 'lcq'; // Piru; deprecated 2013-09-10
357      case 'pry':
358        return 'prt'; // Pray 3; deprecated 2016-05-30
359      case 'puz':
360        return 'pub'; // Purum Naga; deprecated 2014-02-28
361      case 'sca':
362        return 'hle'; // Sansu; deprecated 2012-08-12
363      case 'skk':
364        return 'oyb'; // Sok; deprecated 2017-02-23
365      case 'tdu':
366        return 'dtp'; // Tempasuk Dusun; deprecated 2016-05-30
367      case 'thc':
368        return 'tpo'; // Tai Hang Tong; deprecated 2016-05-30
369      case 'thx':
370        return 'oyb'; // The; deprecated 2015-02-12
371      case 'tie':
372        return 'ras'; // Tingal; deprecated 2011-08-16
373      case 'tkk':
374        return 'twm'; // Takpa; deprecated 2011-08-16
375      case 'tlw':
376        return 'weo'; // South Wemale; deprecated 2012-08-12
377      case 'tmp':
378        return 'tyj'; // Tai Mène; deprecated 2016-05-30
379      case 'tne':
380        return 'kak'; // Tinoc Kallahan; deprecated 2016-05-30
381      case 'tnf':
382        return 'prs'; // Tangshewi; deprecated 2010-03-11
383      case 'tsf':
384        return 'taj'; // Southwestern Tamang; deprecated 2015-02-12
385      case 'uok':
386        return 'ema'; // Uokha; deprecated 2015-02-12
387      case 'xba':
388        return 'cax'; // Kamba (Brazil); deprecated 2016-05-30
389      case 'xia':
390        return 'acn'; // Xiandao; deprecated 2013-09-10
391      case 'xkh':
392        return 'waw'; // Karahawyana; deprecated 2016-05-30
393      case 'xsj':
394        return 'suj'; // Subi; deprecated 2015-02-12
395      case 'ybd':
396        return 'rki'; // Yangbye; deprecated 2012-08-12
397      case 'yma':
398        return 'lrr'; // Yamphe; deprecated 2012-08-12
399      case 'ymt':
400        return 'mtm'; // Mator-Taygi-Karagas; deprecated 2015-02-12
401      case 'yos':
402        return 'zom'; // Yos; deprecated 2013-09-10
403      case 'yuu':
404        return 'yug'; // Yugh; deprecated 2014-02-28
405      default:
406        return languageCode;
407    }
408  }
409
410  /// The script subtag for the locale.
411  ///
412  /// This may be null, indicating that there is no specified script subtag.
413  ///
414  /// This must be a valid Unicode Language Identifier script subtag as listed
415  /// in [Unicode CLDR supplemental
416  /// data](http://unicode.org/cldr/latest/common/validity/script.xml).
417  ///
418  /// See also:
419  ///
420  ///  * [new Locale.fromSubtags], which describes the conventions for creating
421  ///    [Locale] objects.
422  final String scriptCode;
423
424  /// The region subtag for the locale.
425  ///
426  /// This may be null, indicating that there is no specified region subtag.
427  ///
428  /// This is expected to be string registered in the [IANA Language Subtag
429  /// Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry)
430  /// with the type "region". The string specified must match the case of the
431  /// string in the registry.
432  ///
433  /// Region subtags that are deprecated in the registry and have a preferred
434  /// code are changed to their preferred code. For example, `const Locale('de',
435  /// 'DE')` and `const Locale('de', 'DD')` are equal, and both have the
436  /// [countryCode] `DE`, because `DD` is a deprecated language subtag that was
437  /// replaced by the subtag `DE`.
438  ///
439  /// See also:
440  ///
441  ///  * [new Locale.fromSubtags], which describes the conventions for creating
442  ///    [Locale] objects.
443  String get countryCode => _replaceDeprecatedRegionSubtag(_countryCode);
444  final String _countryCode;
445
446  static String _replaceDeprecatedRegionSubtag(String regionCode) {
447    // This switch statement is generated by //flutter/tools/gen_locale.dart
448    // Mappings generated for language subtag registry as of 2018-08-08.
449    switch (regionCode) {
450      case 'BU':
451        return 'MM'; // Burma; deprecated 1989-12-05
452      case 'DD':
453        return 'DE'; // German Democratic Republic; deprecated 1990-10-30
454      case 'FX':
455        return 'FR'; // Metropolitan France; deprecated 1997-07-14
456      case 'TP':
457        return 'TL'; // East Timor; deprecated 2002-05-20
458      case 'YD':
459        return 'YE'; // Democratic Yemen; deprecated 1990-08-14
460      case 'ZR':
461        return 'CD'; // Zaire; deprecated 1997-07-14
462      default:
463        return regionCode;
464    }
465  }
466
467  @override
468  bool operator ==(dynamic other) {
469    if (identical(this, other)) {
470      return true;
471    }
472    if (other is! Locale) {
473      return false;
474    }
475    final Locale typedOther = other;
476    return languageCode == typedOther.languageCode &&
477        scriptCode == typedOther.scriptCode &&
478        countryCode == typedOther.countryCode;
479  }
480
481  @override
482  int get hashCode => hashValues(languageCode, scriptCode, countryCode);
483
484  @override
485  String toString() {
486    final StringBuffer out = StringBuffer(languageCode);
487    if (scriptCode != null) out.write('_$scriptCode');
488    if (_countryCode != null) out.write('_$countryCode');
489    return out.toString();
490  }
491
492  // TODO(yjbanov): implement to match flutter native.
493  String toLanguageTag() => '_';
494}
495
496/// The most basic interface to the host operating system's user interface.
497///
498/// There is a single Window instance in the system, which you can
499/// obtain from the [window] property.
500abstract class Window {
501  /// The number of device pixels for each logical pixel. This number might not
502  /// be a power of two. Indeed, it might not even be an integer. For example,
503  /// the Nexus 6 has a device pixel ratio of 3.5.
504  ///
505  /// Device pixels are also referred to as physical pixels. Logical pixels are
506  /// also referred to as device-independent or resolution-independent pixels.
507  ///
508  /// By definition, there are roughly 38 logical pixels per centimeter, or
509  /// about 96 logical pixels per inch, of the physical display. The value
510  /// returned by [devicePixelRatio] is ultimately obtained either from the
511  /// hardware itself, the device drivers, or a hard-coded value stored in the
512  /// operating system or firmware, and may be inaccurate, sometimes by a
513  /// significant margin.
514  ///
515  /// The Flutter framework operates in logical pixels, so it is rarely
516  /// necessary to directly deal with this property.
517  ///
518  /// When this changes, [onMetricsChanged] is called.
519  ///
520  /// See also:
521  ///
522  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
523  ///    observe when this value changes.
524  double get devicePixelRatio;
525
526  /// The dimensions of the rectangle into which the application will be drawn,
527  /// in physical pixels.
528  ///
529  /// When this changes, [onMetricsChanged] is called.
530  ///
531  /// At startup, the size of the application window may not be known before
532  /// Dart code runs. If this value is observed early in the application
533  /// lifecycle, it may report [Size.zero].
534  ///
535  /// This value does not take into account any on-screen keyboards or other
536  /// system UI. The [padding] and [viewInsets] properties provide a view into
537  /// how much of each side of the application may be obscured by system UI.
538  ///
539  /// See also:
540  ///
541  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
542  ///    observe when this value changes.
543  Size get physicalSize;
544
545  /// The physical depth is the maximum elevation that the Window allows.
546  ///
547  /// Physical layers drawn at or above this elevation will have their elevation
548  /// clamped to this value. This can happen if the physical layer itself has
549  /// an elevation larger than available depth, or if some ancestor of the layer
550  /// causes it to have a cumulative elevation that is larger than the available
551  /// depth.
552  ///
553  /// The default value is [double.maxFinite], which is used for platforms that
554  /// do not specify a maximum elevation. This property is currently on expected
555  /// to be set to a non-default value on Fuchsia.
556  double get physicalDepth;
557
558  /// The number of physical pixels on each side of the display rectangle into
559  /// which the application can render, but over which the operating system
560  /// will likely place system UI, such as the keyboard, that fully obscures
561  /// any content.
562  ///
563  /// When this changes, [onMetricsChanged] is called.
564  ///
565  /// See also:
566  ///
567  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
568  ///    observe when this value changes.
569  ///  * [MediaQuery.of], a simpler mechanism for the same.
570  ///  * [Scaffold], which automatically applies the view insets in material
571  ///    design applications.
572  WindowPadding get viewInsets => WindowPadding.zero;
573
574  WindowPadding get viewPadding => WindowPadding.zero;
575
576  WindowPadding get systemGestureInsets => WindowPadding.zero;
577
578  /// The number of physical pixels on each side of the display rectangle into
579  /// which the application can render, but which may be partially obscured by
580  /// system UI (such as the system notification area), or or physical
581  /// intrusions in the display (e.g. overscan regions on television screens or
582  /// phone sensor housings).
583  ///
584  /// When this changes, [onMetricsChanged] is called.
585  ///
586  /// See also:
587  ///
588  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
589  ///    observe when this value changes.
590  ///  * [MediaQuery.of], a simpler mechanism for the same.
591  ///  * [Scaffold], which automatically applies the padding in material design
592  ///    applications.
593  WindowPadding get padding => WindowPadding.zero;
594
595  /// The system-reported text scale.
596  ///
597  /// This establishes the text scaling factor to use when rendering text,
598  /// according to the user's platform preferences.
599  ///
600  /// The [onTextScaleFactorChanged] callback is called whenever this value
601  /// changes.
602  ///
603  /// See also:
604  ///
605  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
606  ///    observe when this value changes.
607  double get textScaleFactor => _textScaleFactor;
608  double _textScaleFactor = 1.0;
609
610  /// The setting indicating whether time should always be shown in the 24-hour
611  /// format.
612  ///
613  /// This option is used by [showTimePicker].
614  bool get alwaysUse24HourFormat => _alwaysUse24HourFormat;
615  bool _alwaysUse24HourFormat = false;
616
617  /// A callback that is invoked whenever [textScaleFactor] changes value.
618  ///
619  /// The framework invokes this callback in the same zone in which the
620  /// callback was set.
621  ///
622  /// See also:
623  ///
624  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
625  ///    observe when this callback is invoked.
626  VoidCallback get onTextScaleFactorChanged => _onTextScaleFactorChanged;
627  VoidCallback _onTextScaleFactorChanged;
628  set onTextScaleFactorChanged(VoidCallback callback) {
629    _onTextScaleFactorChanged = callback;
630  }
631
632  /// The setting indicating the current brightness mode of the host platform.
633  /// If the platform has no preference, [platformBrightness] defaults to [Brightness.light].
634  Brightness get platformBrightness => _platformBrightness;
635  Brightness _platformBrightness = Brightness.light;
636
637  /// A callback that is invoked whenever [platformBrightness] changes value.
638  ///
639  /// The framework invokes this callback in the same zone in which the
640  /// callback was set.
641  ///
642  /// See also:
643  ///
644  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
645  ///    observe when this callback is invoked.
646  VoidCallback get onPlatformBrightnessChanged => _onPlatformBrightnessChanged;
647  VoidCallback _onPlatformBrightnessChanged;
648  set onPlatformBrightnessChanged(VoidCallback callback) {
649    _onPlatformBrightnessChanged = callback;
650  }
651
652  /// A callback that is invoked whenever the [devicePixelRatio],
653  /// [physicalSize], [padding], or [viewInsets] values change, for example
654  /// when the device is rotated or when the application is resized (e.g. when
655  /// showing applications side-by-side on Android).
656  ///
657  /// The engine invokes this callback in the same zone in which the callback
658  /// was set.
659  ///
660  /// The framework registers with this callback and updates the layout
661  /// appropriately.
662  ///
663  /// See also:
664  ///
665  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
666  ///    register for notifications when this is called.
667  ///  * [MediaQuery.of], a simpler mechanism for the same.
668  VoidCallback get onMetricsChanged => _onMetricsChanged;
669  VoidCallback _onMetricsChanged;
670  set onMetricsChanged(VoidCallback callback) {
671    _onMetricsChanged = callback;
672  }
673
674  static const _enUS = const Locale('en', 'US');
675
676  /// The system-reported default locale of the device.
677  ///
678  /// This establishes the language and formatting conventions that application
679  /// should, if possible, use to render their user interface.
680  ///
681  /// This is the first locale selected by the user and is the user's
682  /// primary locale (the locale the device UI is displayed in)
683  ///
684  /// This is equivalent to `locales.first` and will provide an empty non-null locale
685  /// if the [locales] list has not been set or is empty.
686  Locale get locale {
687    if (_locales != null && _locales.isNotEmpty) {
688      return _locales.first;
689    }
690    return null;
691  }
692
693  /// The full system-reported supported locales of the device.
694  ///
695  /// This establishes the language and formatting conventions that application
696  /// should, if possible, use to render their user interface.
697  ///
698  /// The list is ordered in order of priority, with lower-indexed locales being
699  /// preferred over higher-indexed ones. The first element is the primary [locale].
700  ///
701  /// The [onLocaleChanged] callback is called whenever this value changes.
702  ///
703  /// See also:
704  ///
705  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
706  ///    observe when this value changes.
707  List<Locale> get locales => _locales;
708  // TODO(flutter_web): Get the real locale from the browser.
709  List<Locale> _locales = const [_enUS];
710
711  /// A callback that is invoked whenever [locale] changes value.
712  ///
713  /// The framework invokes this callback in the same zone in which the
714  /// callback was set.
715  ///
716  /// See also:
717  ///
718  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
719  ///    observe when this callback is invoked.
720  VoidCallback get onLocaleChanged => _onLocaleChanged;
721  VoidCallback _onLocaleChanged;
722  set onLocaleChanged(VoidCallback callback) {
723    _onLocaleChanged = callback;
724  }
725
726  /// Requests that, at the next appropriate opportunity, the [onBeginFrame]
727  /// and [onDrawFrame] callbacks be invoked.
728  ///
729  /// See also:
730  ///
731  ///  * [SchedulerBinding], the Flutter framework class which manages the
732  ///    scheduling of frames.
733  void scheduleFrame() {
734    if (webOnlyScheduleFrameCallback == null) {
735      throw new Exception(
736          'webOnlyScheduleFrameCallback must be initialized first.');
737    }
738    webOnlyScheduleFrameCallback();
739  }
740
741  /// A callback that is invoked to notify the application that it is an
742  /// appropriate time to provide a scene using the [SceneBuilder] API and the
743  /// [render] method. When possible, this is driven by the hardware VSync
744  /// signal. This is only called if [scheduleFrame] has been called since the
745  /// last time this callback was invoked.
746  ///
747  /// The [onDrawFrame] callback is invoked immediately after [onBeginFrame],
748  /// after draining any microtasks (e.g. completions of any [Future]s) queued
749  /// by the [onBeginFrame] handler.
750  ///
751  /// The framework invokes this callback in the same zone in which the
752  /// callback was set.
753  ///
754  /// See also:
755  ///
756  ///  * [SchedulerBinding], the Flutter framework class which manages the
757  ///    scheduling of frames.
758  ///  * [RendererBinding], the Flutter framework class which manages layout and
759  ///    painting.
760  FrameCallback get onBeginFrame => _onBeginFrame;
761  FrameCallback _onBeginFrame;
762  set onBeginFrame(FrameCallback callback) {
763    _onBeginFrame = callback;
764  }
765
766  /// A callback that is invoked to report the [FrameTiming] of recently
767  /// rasterized frames.
768  ///
769  /// This can be used to see if the application has missed frames (through
770  /// [FrameTiming.buildDuration] and [FrameTiming.rasterDuration]), or high
771  /// latencies (through [FrameTiming.totalSpan]).
772  ///
773  /// Unlike [Timeline], the timing information here is available in the release
774  /// mode (additional to the profile and the debug mode). Hence this can be
775  /// used to monitor the application's performance in the wild.
776  ///
777  /// The callback may not be immediately triggered after each frame. Instead,
778  /// it tries to batch frames together and send all their timings at once to
779  /// decrease the overhead (as this is available in the release mode). The
780  /// timing of any frame will be sent within about 1 second even if there are
781  /// no later frames to batch.
782  TimingsCallback get onReportTimings => _onReportTimings;
783  TimingsCallback _onReportTimings;
784  Zone _onReportTimingsZone;
785  set onReportTimings(TimingsCallback callback) {
786    _onReportTimings = callback;
787    _onReportTimingsZone = Zone.current;
788  }
789
790  /// A callback that is invoked for each frame after [onBeginFrame] has
791  /// completed and after the microtask queue has been drained. This can be
792  /// used to implement a second phase of frame rendering that happens
793  /// after any deferred work queued by the [onBeginFrame] phase.
794  ///
795  /// The framework invokes this callback in the same zone in which the
796  /// callback was set.
797  ///
798  /// See also:
799  ///
800  ///  * [SchedulerBinding], the Flutter framework class which manages the
801  ///    scheduling of frames.
802  ///  * [RendererBinding], the Flutter framework class which manages layout and
803  ///    painting.
804  VoidCallback get onDrawFrame => _onDrawFrame;
805  VoidCallback _onDrawFrame;
806  set onDrawFrame(VoidCallback callback) {
807    _onDrawFrame = callback;
808  }
809
810  /// A callback that is invoked when pointer data is available.
811  ///
812  /// The framework invokes this callback in the same zone in which the
813  /// callback was set.
814  ///
815  /// See also:
816  ///
817  ///  * [GestureBinding], the Flutter framework class which manages pointer
818  ///    events.
819  PointerDataPacketCallback get onPointerDataPacket => _onPointerDataPacket;
820  PointerDataPacketCallback _onPointerDataPacket;
821  set onPointerDataPacket(PointerDataPacketCallback callback) {
822    _onPointerDataPacket = callback;
823  }
824
825  /// The route or path that the embedder requested when the application was
826  /// launched.
827  ///
828  /// This will be the string "`/`" if no particular route was requested.
829  ///
830  /// ## Android
831  ///
832  /// On Android, calling
833  /// [`FlutterView.setInitialRoute`](/javadoc/io/flutter/view/FlutterView.html#setInitialRoute-java.lang.String-)
834  /// will set this value. The value must be set sufficiently early, i.e. before
835  /// the [runApp] call is executed in Dart, for this to have any effect on the
836  /// framework. The `createFlutterView` method in your `FlutterActivity`
837  /// subclass is a suitable time to set the value. The application's
838  /// `AndroidManifest.xml` file must also be updated to have a suitable
839  /// [`<intent-filter>`](https://developer.android.com/guide/topics/manifest/intent-filter-element.html).
840  ///
841  /// ## iOS
842  ///
843  /// On iOS, calling
844  /// [`FlutterViewController.setInitialRoute`](/objcdoc/Classes/FlutterViewController.html#/c:objc%28cs%29FlutterViewController%28im%29setInitialRoute:)
845  /// will set this value. The value must be set sufficiently early, i.e. before
846  /// the [runApp] call is executed in Dart, for this to have any effect on the
847  /// framework. The `application:didFinishLaunchingWithOptions:` method is a
848  /// suitable time to set this value.
849  ///
850  /// See also:
851  ///
852  ///  * [Navigator], a widget that handles routing.
853  ///  * [SystemChannels.navigation], which handles subsequent navigation
854  ///    requests from the embedder.
855  String get defaultRouteName;
856
857  /// Whether the user has requested that [updateSemantics] be called when
858  /// the semantic contents of window changes.
859  ///
860  /// The [onSemanticsEnabledChanged] callback is called whenever this value
861  /// changes.
862  ///
863  /// This defaults to `true` on the Web because we may never receive a signal
864  /// that an assistive technology is turned on.
865  bool get semanticsEnabled =>
866      engine.EngineSemanticsOwner.instance.semanticsEnabled;
867
868  /// A callback that is invoked when the value of [semanticsEnabled] changes.
869  ///
870  /// The framework invokes this callback in the same zone in which the
871  /// callback was set.
872  VoidCallback get onSemanticsEnabledChanged => _onSemanticsEnabledChanged;
873  VoidCallback _onSemanticsEnabledChanged;
874  set onSemanticsEnabledChanged(VoidCallback callback) {
875    _onSemanticsEnabledChanged = callback;
876  }
877
878  /// A callback that is invoked whenever the user requests an action to be
879  /// performed.
880  ///
881  /// This callback is used when the user expresses the action they wish to
882  /// perform based on the semantics supplied by [updateSemantics].
883  ///
884  /// The framework invokes this callback in the same zone in which the
885  /// callback was set.
886  SemanticsActionCallback get onSemanticsAction => _onSemanticsAction;
887  SemanticsActionCallback _onSemanticsAction;
888  set onSemanticsAction(SemanticsActionCallback callback) {
889    _onSemanticsAction = callback;
890  }
891
892  /// A callback that is invoked when the value of [accessibilityFlags] changes.
893  ///
894  /// The framework invokes this callback in the same zone in which the
895  /// callback was set.
896  VoidCallback get onAccessibilityFeaturesChanged =>
897      _onAccessibilityFeaturesChanged;
898  VoidCallback _onAccessibilityFeaturesChanged;
899  set onAccessibilityFeaturesChanged(VoidCallback callback) {
900    _onAccessibilityFeaturesChanged = callback;
901  }
902
903  /// Called whenever this window receives a message from a platform-specific
904  /// plugin.
905  ///
906  /// The `name` parameter determines which plugin sent the message. The `data`
907  /// parameter is the payload and is typically UTF-8 encoded JSON but can be
908  /// arbitrary data.
909  ///
910  /// Message handlers must call the function given in the `callback` parameter.
911  /// If the handler does not need to respond, the handler should pass null to
912  /// the callback.
913  ///
914  /// The framework invokes this callback in the same zone in which the
915  /// callback was set.
916  PlatformMessageCallback get onPlatformMessage => _onPlatformMessage;
917  PlatformMessageCallback _onPlatformMessage;
918  set onPlatformMessage(PlatformMessageCallback callback) {
919    _onPlatformMessage = callback;
920  }
921
922  /// Change the retained semantics data about this window.
923  ///
924  /// If [semanticsEnabled] is true, the user has requested that this funciton
925  /// be called whenever the semantic content of this window changes.
926  ///
927  /// In either case, this function disposes the given update, which means the
928  /// semantics update cannot be used further.
929  void updateSemantics(SemanticsUpdate update) {
930    engine.EngineSemanticsOwner.instance.updateSemantics(update);
931  }
932
933  /// Sends a message to a platform-specific plugin.
934  ///
935  /// The `name` parameter determines which plugin receives the message. The
936  /// `data` parameter contains the message payload and is typically UTF-8
937  /// encoded JSON but can be arbitrary data. If the plugin replies to the
938  /// message, `callback` will be called with the response.
939  ///
940  /// The framework invokes [callback] in the same zone in which this method
941  /// was called.
942  void sendPlatformMessage(
943    String name,
944    ByteData data,
945    PlatformMessageResponseCallback callback,
946  );
947
948  /// Additional accessibility features that may be enabled by the platform.
949  AccessibilityFeatures get accessibilityFeatures => _accessibilityFeatures;
950  AccessibilityFeatures _accessibilityFeatures = AccessibilityFeatures._(0);
951
952  /// Updates the application's rendering on the GPU with the newly provided
953  /// [Scene]. This function must be called within the scope of the
954  /// [onBeginFrame] or [onDrawFrame] callbacks being invoked. If this function
955  /// is called a second time during a single [onBeginFrame]/[onDrawFrame]
956  /// callback sequence or called outside the scope of those callbacks, the call
957  /// will be ignored.
958  ///
959  /// To record graphical operations, first create a [PictureRecorder], then
960  /// construct a [Canvas], passing that [PictureRecorder] to its constructor.
961  /// After issuing all the graphical operations, call the
962  /// [PictureRecorder.endRecording] function on the [PictureRecorder] to obtain
963  /// the final [Picture] that represents the issued graphical operations.
964  ///
965  /// Next, create a [SceneBuilder], and add the [Picture] to it using
966  /// [SceneBuilder.addPicture]. With the [SceneBuilder.build] method you can
967  /// then obtain a [Scene] object, which you can display to the user via this
968  /// [render] function.
969  ///
970  /// See also:
971  ///
972  ///  * [SchedulerBinding], the Flutter framework class which manages the
973  ///    scheduling of frames.
974  ///  * [RendererBinding], the Flutter framework class which manages layout and
975  ///    painting.
976  void render(Scene scene) {
977    if (engine.experimentalUseSkia) {
978      final engine.LayerScene layerScene = scene;
979      _rasterizer.draw(layerScene.layerTree);
980    } else {
981      engine.domRenderer.renderScene(scene.webOnlyRootElement);
982    }
983  }
984
985  final engine.Rasterizer _rasterizer = engine.experimentalUseSkia
986      ? engine.Rasterizer(engine.Surface((engine.SkCanvas canvas) {
987          engine.domRenderer.renderScene(canvas.htmlCanvas);
988          canvas.skSurface.callMethod('flush');
989        }))
990      : null;
991
992  String get initialLifecycleState => _initialLifecycleState;
993
994  String _initialLifecycleState;
995
996  void setIsolateDebugName(String name) {}
997}
998
999VoidCallback webOnlyScheduleFrameCallback;
1000
1001/// Additional accessibility features that may be enabled by the platform.
1002///
1003/// It is not possible to enable these settings from Flutter, instead they are
1004/// used by the platform to indicate that additional accessibility features are
1005/// enabled.
1006class AccessibilityFeatures {
1007  const AccessibilityFeatures._(this._index);
1008
1009  static const int _kAccessibleNavigation = 1 << 0;
1010  static const int _kInvertColorsIndex = 1 << 1;
1011  static const int _kDisableAnimationsIndex = 1 << 2;
1012  static const int _kBoldTextIndex = 1 << 3;
1013  static const int _kReduceMotionIndex = 1 << 4;
1014
1015  // A bitfield which represents each enabled feature.
1016  final int _index;
1017
1018  /// Whether there is a running accessibility service which is changing the
1019  /// interaction model of the device.
1020  ///
1021  /// For example, TalkBack on Android and VoiceOver on iOS enable this flag.
1022  bool get accessibleNavigation => _kAccessibleNavigation & _index != 0;
1023
1024  /// The platform is inverting the colors of the application.
1025  bool get invertColors => _kInvertColorsIndex & _index != 0;
1026
1027  /// The platform is requesting that animations be disabled or simplified.
1028  bool get disableAnimations => _kDisableAnimationsIndex & _index != 0;
1029
1030  /// The platform is requesting that text be rendered at a bold font weight.
1031  ///
1032  /// Only supported on iOS.
1033  bool get boldText => _kBoldTextIndex & _index != 0;
1034
1035  /// The platform is requesting that certain animations be simplified and
1036  /// parallax effects removed.
1037  ///
1038  /// Only supported on iOS.
1039  bool get reduceMotion => _kReduceMotionIndex & _index != 0;
1040
1041  @override
1042  String toString() {
1043    final List<String> features = <String>[];
1044    if (accessibleNavigation) features.add('accessibleNavigation');
1045    if (invertColors) features.add('invertColors');
1046    if (disableAnimations) features.add('disableAnimations');
1047    if (boldText) features.add('boldText');
1048    if (reduceMotion) features.add('reduceMotion');
1049    return 'AccessibilityFeatures$features';
1050  }
1051
1052  @override
1053  bool operator ==(dynamic other) {
1054    if (other.runtimeType != runtimeType) return false;
1055    final AccessibilityFeatures typedOther = other;
1056    return _index == typedOther._index;
1057  }
1058
1059  @override
1060  int get hashCode => _index.hashCode;
1061}
1062
1063/// Describes the contrast of a theme or color palette.
1064enum Brightness {
1065  /// The color is dark and will require a light text color to achieve readable
1066  /// contrast.
1067  ///
1068  /// For example, the color might be dark grey, requiring white text.
1069  dark,
1070
1071  /// The color is light and will require a dark text color to achieve readable
1072  /// contrast.
1073  ///
1074  /// For example, the color might be bright white, requiring black text.
1075  light,
1076}
1077
1078// Unimplemented classes.
1079// TODO(flutter_web): see https://github.com/flutter/flutter/issues/33614.
1080class CallbackHandle {
1081  CallbackHandle.fromRawHandle(this._handle);
1082
1083  final int _handle;
1084
1085  int toRawHandle() => _handle;
1086
1087  @override
1088  bool operator ==(Object other) => identical(this, other);
1089
1090  @override
1091  int get hashCode => super.hashCode;
1092}
1093
1094// TODO(flutter_web): see https://github.com/flutter/flutter/issues/33615.
1095class PluginUtilities {
1096  static CallbackHandle getCallbackHandle(Function callback) {
1097    throw UnimplementedError();
1098  }
1099
1100  static Function getCallbackFromHandle(CallbackHandle handle) {
1101    throw UnimplementedError();
1102  }
1103}
1104
1105// TODO(flutter_web): see https://github.com/flutter/flutter/issues/33616.
1106class ImageShader {
1107  ImageShader(Image image, TileMode tmx, TileMode tmy, Float64List matrix4);
1108}
1109
1110// TODO(flutter_web): probably dont implement this one.
1111class IsolateNameServer {
1112  static dynamic lookupPortByName(String name) {
1113    assert(name != null, "'name' cannot be null.");
1114    throw UnimplementedError();
1115  }
1116
1117  static bool registerPortWithName(dynamic port, String name) {
1118    assert(port != null, "'port' cannot be null.");
1119    assert(name != null, "'name' cannot be null.");
1120    throw UnimplementedError();
1121  }
1122
1123  static bool removePortNameMapping(String name) {
1124    assert(name != null, "'name' cannot be null.");
1125    throw UnimplementedError();
1126  }
1127}
1128
1129/// Various important time points in the lifetime of a frame.
1130///
1131/// [FrameTiming] records a timestamp of each phase for performance analysis.
1132enum FramePhase {
1133  /// When the UI thread starts building a frame.
1134  ///
1135  /// See also [FrameTiming.buildDuration].
1136  buildStart,
1137
1138  /// When the UI thread finishes building a frame.
1139  ///
1140  /// See also [FrameTiming.buildDuration].
1141  buildFinish,
1142
1143  /// When the GPU thread starts rasterizing a frame.
1144  ///
1145  /// See also [FrameTiming.rasterDuration].
1146  rasterStart,
1147
1148  /// When the GPU thread finishes rasterizing a frame.
1149  ///
1150  /// See also [FrameTiming.rasterDuration].
1151  rasterFinish,
1152}
1153
1154/// Time-related performance metrics of a frame.
1155///
1156/// See [Window.onReportTimings] for how to get this.
1157///
1158/// The metrics in debug mode (`flutter run` without any flags) may be very
1159/// different from those in profile and release modes due to the debug overhead.
1160/// Therefore it's recommended to only monitor and analyze performance metrics
1161/// in profile and release modes.
1162class FrameTiming {
1163  /// Construct [FrameTiming] with raw timestamps in microseconds.
1164  ///
1165  /// List [timestamps] must have the same number of elements as
1166  /// [FramePhase.values].
1167  ///
1168  /// This constructor is usually only called by the Flutter engine, or a test.
1169  /// To get the [FrameTiming] of your app, see [Window.onReportTimings].
1170  FrameTiming(List<int> timestamps)
1171      : assert(timestamps.length == FramePhase.values.length),
1172        _timestamps = timestamps;
1173
1174  /// This is a raw timestamp in microseconds from some epoch. The epoch in all
1175  /// [FrameTiming] is the same, but it may not match [DateTime]'s epoch.
1176  int timestampInMicroseconds(FramePhase phase) => _timestamps[phase.index];
1177
1178  Duration _rawDuration(FramePhase phase) =>
1179      Duration(microseconds: _timestamps[phase.index]);
1180
1181  /// The duration to build the frame on the UI thread.
1182  ///
1183  /// The build starts approximately when [Window.onBeginFrame] is called. The
1184  /// [Duration] in the [Window.onBeginFrame] callback is exactly the
1185  /// `Duration(microseconds: timestampInMicroseconds(FramePhase.buildStart))`.
1186  ///
1187  /// The build finishes when [Window.render] is called.
1188  ///
1189  /// {@template dart.ui.FrameTiming.fps_smoothness_milliseconds}
1190  /// To ensure smooth animations of X fps, this should not exceed 1000/X
1191  /// milliseconds.
1192  /// {@endtemplate}
1193  /// {@template dart.ui.FrameTiming.fps_milliseconds}
1194  /// That's about 16ms for 60fps, and 8ms for 120fps.
1195  /// {@endtemplate}
1196  Duration get buildDuration =>
1197      _rawDuration(FramePhase.buildFinish) -
1198      _rawDuration(FramePhase.buildStart);
1199
1200  /// The duration to rasterize the frame on the GPU thread.
1201  ///
1202  /// {@macro dart.ui.FrameTiming.fps_smoothness_milliseconds}
1203  /// {@macro dart.ui.FrameTiming.fps_milliseconds}
1204  Duration get rasterDuration =>
1205      _rawDuration(FramePhase.rasterFinish) -
1206      _rawDuration(FramePhase.rasterStart);
1207
1208  /// The timespan between build start and raster finish.
1209  ///
1210  /// To achieve the lowest latency on an X fps display, this should not exceed
1211  /// 1000/X milliseconds.
1212  /// {@macro dart.ui.FrameTiming.fps_milliseconds}
1213  ///
1214  /// See also [buildDuration] and [rasterDuration].
1215  Duration get totalSpan =>
1216      _rawDuration(FramePhase.rasterFinish) -
1217      _rawDuration(FramePhase.buildStart);
1218
1219  final List<int> _timestamps; // in microseconds
1220
1221  String _formatMS(Duration duration) => '${duration.inMicroseconds * 0.001}ms';
1222
1223  @override
1224  String toString() {
1225    return '$runtimeType(buildDuration: ${_formatMS(buildDuration)}, rasterDuration: ${_formatMS(rasterDuration)}, totalSpan: ${_formatMS(totalSpan)})';
1226  }
1227}
1228
1229/// The [Window] singleton. This object exposes the size of the display, the
1230/// core scheduler API, the input event callback, the graphics drawing API, and
1231/// other such core services.
1232Window get window => engine.window;
1233