flutter_native_view 0.0.2 copy "flutter_native_view: ^0.0.2" to clipboard
flutter_native_view: ^0.0.2 copied to clipboard

PlatformWindows

Flutter plugin to embed native windows into Flutter window.

flutter_native_view #

MITDonatepub package

Embedding native windows & components directly into Flutter window.

Example #

Video showing a Flutter Windows app running with embedded webview & VLC using flutter_native_view.

Notice how AppBar is on-top of the the native surfaces & both native surfaces scroll perfectly.

https://user-images.githubusercontent.com/28951144/159073594-813700fb-0988-424f-86b5-381beccf4247.mp4

[slight lag & delay can be observed due to screen recording. the actual experience is very seamless]

Try running the example application by cloning the repository.

You may sponsor this project's future development & research at:

It'll be a great motivation for me to continue.

💖 Current Sponsors #

Used By #

Description #

This setup only uses Win32 APIs & no texture, intermediate buffers or copying of pixel buffers. Thus, it is very performant.

A Flutter plugin / Win32 setup to embed other native Windows (HWND on Windows) into Flutter window.

Current API design allows to embed any arbitrary HWND completely from Dart as a Widget. This can be a good choice when client code wants to embed any third-party window (which is already opened) into the Flutter window. However, this is not ideal in most cases, because there is almost no point of embedding a window without having a programmatic control to it (via some API).

On the other hand, a window created by the client code itself e.g. a webview instance window or a video-output window etc. (on which the client code has full programmatic control) will be an ideal window to embed, in that case:

  • If client code decides to create an HWND through platform channel interface, they can use the setup present in core to embed a window (or send back the HWND as int64_t to the plugin throught Dart).
  • Since dart:ffi is very capable now, one can pass the HWND directly as int of the window they created using dart:ffi or package:win32 through existing plugin API to embed it.

Future #

In future, I will create natively rendered, performant & less-bundle-sized webview & video playback plugins, if I get enough community support. Currently I'm only targetting Windows to limit the scope of work, though I plan for Linux support at some point.

Setup #

Add following lines to your windows/runner/main.cpp file:

  #include <flutter/dart_project.h>
  #include <flutter/flutter_view_controller.h>
  #include <windows.h>

+ #include "flutter_native_view/flutter_native_view_plugin.h"
  #include "flutter_window.h"
  #include "utils.h"
  window.SetQuitOnClose(true);

+ flutternativeview::NativeViewContainer::GetInstance()->Create();

  ::MSG msg;
  while (::GetMessage(&msg, nullptr, 0, 0)) {
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
  }

Docs #

Initialize the plugin

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  /// Initialize.
  await FlutterNativeView.ensureInitialized();
  runApp(const MyApp());
}

Create a controller & render a window

class _MyAppState extends State<MyApp> {
  /// Create a [NativeViewController].
  final controller = NativeViewController(
    /// Using [FindWindow] from `package:win32` to retrieve `HWND` as [int].
    handle: FindWindow(nullptr, 'VLC Media Player'.toNativeUtf16()),
    /// Make the [NativeView] interactable.
    hitTestBehavior: HitTestBehavior.translucent,
  );

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
            child: Padding(
              padding: const EdgeInsets.all(24.0),
              child: Stack(
                children: [
                  LayoutBuilder(
                    /// Create a [NativeView].
                    builder: (context, constraints) => NativeView(
                      /// Pass [NativeViewController] to render the window.
                      controller: controller,
                      width: constraints.maxWidth,
                      height: constraints.maxHeight,
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: FloatingActionButton(
                      onPressed: () {},
                      child: const Icon(Icons.edit),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Dispose the native view & destory the window

controller.dispose();

Features #

Currently Implemented

  • Placement of other Flutter Widgets on top of the NativeView.
  • Multiple instances of NativeView.
  • Window movement handling & NativeViews positioning.
  • Window resize handling & NativeViews sizing.
  • Windows 10 & higher support.
  • Proper disposing of HWND and instances.
  • Semi transparent Widgets on top of NativeView.
  • Placement of NativeViews inside scrollables like ListViews.
  • [UNSTABLE] Customizable hit-test i.e. optional interactability with the NativeViews.

Under Progress

  • Stable support for interactability with the NativeViews [maybe switching to programmatic approach].
  • Support for older Windows versions.
  • Defining z-order for each NativeViewController.
  • Finalized API.
  • General stability.

Motivation #

https://github.com/flutter/flutter/issues/31713

Absence of official Platform View APIs in Flutter for Windows, Linux & macOS.

Platforms #

The plugin currently works on following platforms:

Platform State
Windows Working

I plan to add Linux support soon. For now, limiting the scope of work to just Windows.

License #

MIT License

Copyright (C) 2022, Hitesh Kumar Saini <saini123hitesh@gmail.com>

33
likes
130
points
1.27k
downloads

Publisher

unverified uploader

Weekly Downloads

Flutter plugin to embed native windows into Flutter window.

Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

flutter, path

More

Packages that depend on flutter_native_view