Skip to content

Replace hardcoded platform identity checks in the framework with capability-based queries #185227

@jmagman

Description

@jmagman

Description

Currently, the Flutter framework relies on hardcoded platform identity checks (e.g., defaultTargetPlatform or Theme.of(context).platform) to determine behavior. This creates friction for out-of-tree custom embedders, who are forced to spoof their OS identity to inherit basic capabilities.

Proposal:

  • Replace hardcoded platform identity checks within the core framework with capability-based queries (e.g., supportsPhysicsBasedScrolling).
  • Establish and document a mechanism for custom embedders to declare their supported capabilities to the framework.
  • Allow existing Flutter-maintained platforms (like Android) to serve as an extensible "base." This would allow custom platforms that share most (but not all) behaviors with a supported platform to inherit its capabilities and deviate slightly only where needed.

Here are several examples:

  1. FlexibleSpaceBar uses Theme.of(context).platform to decide whether to center titles.

    bool _getEffectiveCenterTitle(ThemeData theme) {
    return widget.centerTitle ??
    switch (theme.platform) {
    TargetPlatform.android ||
    TargetPlatform.fuchsia ||
    TargetPlatform.linux ||
    TargetPlatform.windows => false,
    TargetPlatform.iOS || TargetPlatform.macOS => true,
    };
    }

  2. Drawer relies on platform checks to determine layout, semantics, and system back button presence, ex:

    final String? label = switch (defaultTargetPlatform) {
    TargetPlatform.iOS || TargetPlatform.macOS => semanticLabel,
    TargetPlatform.android ||
    TargetPlatform.fuchsia ||
    TargetPlatform.linux ||
    TargetPlatform.windows => semanticLabel ?? MaterialLocalizations.of(context).drawerLabel,
    };

  3. TextMagnifier hardcodes the magnifier implementation by switching on defaultTargetPlatform, returning null on unrecognized platforms.

    switch (defaultTargetPlatform) {
    case TargetPlatform.iOS:
    return CupertinoTextMagnifier(controller: controller, magnifierInfo: magnifierInfo);
    case TargetPlatform.android:
    return TextMagnifier(magnifierInfo: magnifierInfo);
    case TargetPlatform.fuchsia:
    case TargetPlatform.linux:
    case TargetPlatform.macOS:
    case TargetPlatform.windows:
    return null;
    }

  4. The Radio.adaptive constructor uses a switch statement to return a CupertinoRadio for Apple platforms and defaults to the standard Material radio for all others.

    switch (theme.platform) {
    case TargetPlatform.android:
    case TargetPlatform.fuchsia:
    case TargetPlatform.linux:
    case TargetPlatform.windows:
    break;
    case TargetPlatform.iOS:
    case TargetPlatform.macOS:
    return CupertinoRadio<T>(
    value: widget.value,
    groupValue: widget.groupValue,
    onChanged: widget.onChanged,
    mouseCursor: widget.mouseCursor,
    toggleable: widget.toggleable,
    activeColor: widget.activeColor,
    focusColor: widget.focusColor,
    focusNode: _focusNode,
    autofocus: widget.autofocus,
    useCheckmarkStyle: widget.useCupertinoCheckmarkStyle,
    groupRegistry: _effectiveRegistry,
    enabled: _enabled,
    );
    }

  5. Autocomplete assigns keyboard shortcuts by switching on defaultTargetPlatform.

    ...switch (defaultTargetPlatform) {
    TargetPlatform.iOS => _appleShortcuts,
    TargetPlatform.macOS => _appleShortcuts,
    TargetPlatform.android => _nonAppleShortcuts,
    TargetPlatform.linux => _nonAppleShortcuts,
    TargetPlatform.windows => _nonAppleShortcuts,
    TargetPlatform.fuchsia => _nonAppleShortcuts,
    },

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: proposalA detailed proposal for a change to Flutterframeworkflutter/packages/flutter repository. See also f: labels.team-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