sony / flutter-embedded-linux

Embedded Linux embedding for Flutter
BSD 3-Clause "New" or "Revised" License
1.2k stars 127 forks source link

Add FlutterEngineNotifyDisplayUpdate support #369

Closed HidenoriMatsubayashi closed 1 year ago

HidenoriMatsubayashi commented 1 year ago

It looks like the embedder in flutter/engine added FlutterEngineNotifyDisplayUpdate API. I'm not sure how it works, but it looks like it's information for devtool.

https://github.com/flutter/engine/blob/main/shell/platform/embedder/embedder.h#L2777

//------------------------------------------------------------------------------
/// @brief    Posts updates corresponding to display changes to a running engine
///           instance.
///
/// @param[in] update_type      The type of update pushed to the engine.
/// @param[in] displays         The displays affected by this update.
/// @param[in] display_count    Size of the displays array, must be at least 1.
///
/// @return the result of the call made to the engine.
///
FLUTTER_EXPORT
FlutterEngineResult FlutterEngineNotifyDisplayUpdate(
    FLUTTER_API_SYMBOL(FlutterEngine) engine,
    FlutterEngineDisplaysUpdateType update_type,
    const FlutterEngineDisplay* displays,
    size_t display_count);
HidenoriMatsubayashi commented 1 year ago

We can send multiple display information, but it looks like only first entry is being used.

https://github.com/flutter/engine/blob/main/shell/common/display_manager.cc

HidenoriMatsubayashi commented 1 year ago

We can get this information via FlutterView.Display.

import 'dart:ui';

import 'package:flutter/material.dart';

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

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  Display? _display;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _display = View.maybeOf(context)?.display;
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _display = null;
    super.dispose();
  }

  @override
  void didChangeMetrics() {
    final Display? display = _display;
    if (display == null) {
      return;
    }
    print(display.id);
    print(display.devicePixelRatio);
    print(display.refreshRate);
    print(display.size.width);
    print(display.size.height);
  }

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