Skip to content

Architecture

Alex Rosca edited this page Jul 5, 2022 · 6 revisions

The embedder

The project is made of 2 big parts:

  • Dart code using the Flutter framework
  • C++ code playing the role of the embedder for the Flutter engine

The Flutter engine is written in a platform-agnostic way, which means that Flutter doesn't know how to read user input or display something to the screen. Every OS has a different API for this kind of stuff. This is where the embedder comes into play. The embedder itself will be platform dependent and will act as a bridge between the platform and the Flutter engine.

When you compile a regular Flutter app on Linux, an embedder written in C++ is bundled with your app. When you run your app, the embedder runs first (the C++ main function) which will initialize the Flutter engine and run your Dart code. This embedder makes use of GTK to show a window on the screen and capture input events from the platform which will be forwarded to the Flutter engine.

I highly recommend reading the following resources to learn more about how embedders work:

The default embedder will try to use GTK to communicate and spawn a window using the current display server, either X.Org or some Wayland server. We cannot use this embedder because we are the display server hosting other clients, and this is why a custom embedder is required. We need exclusive access to the display and all input devices. Instead of writing all the code by myself for interfacing with the Linux kernel and other Linux libraries, I chose to use a library called wlroots. It implements the Wayland protocol and provides some useful abstractions over display and input hardware, which makes writing a Wayland compositor easier. I recommend giving the readme a read: https://gitlab.freedesktop.org/wlroots/wlroots.

The embedder lives in src/.

The Flutter engine

When you install the development dependencies, is also downloads a precompiled version of the Flutter engine from this repo from Sony: https://github.com/sony/flutter-embedded-linux/releases/. This repo contains much more than the engine precompiled binary libflutter_engine.so, but this is all we need, so only this .so file is extracted from the downloaded archive. Google also seem to provide some precompiled binaries but only in release mode unfortunately.

This shared library is linked to the embedder and it's used with this header file: https://github.com/flutter/engine/blob/main/shell/platform/embedder/embedder.h. A copy of this header file can be found in src/third_party.

The header contains lots of documentation about every function exposed by the Flutter Engine, but lacks examples. I found myself sometimes browsing through the code of https://github.com/go-flutter-desktop/go-flutter in order to figure out how to set up the engine.

Clone this wiki locally