Skip to content

Commit

Permalink
Add a Linux Shell that uses GTK for rendering.
Browse files Browse the repository at this point in the history
This is a start on a Linux shell, and only supports rendering of Flutter, no
input is currently provided. The API is expected to change as we flesh out
the shell. The shell doesn't build by default yet, to enable it you need to
set the build_linux_flag gn build argument.

This is the first stage of flutter/flutter#30729

The shell only works on X servers, the EGL code will need to be updated to cover
Wayland.

The Flutter engine currently crashes when the widget is destroyed, but this
seems to be an issue in the engine.

The code is designed to match GTK conventions.

A minimal GTK application that uses this looks like:

--------

int
main (int argc, char **argv)
{
    gtk_init (&argc, &argv);

    GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_widget_show (window);

    g_autoptr(FlDartProject) project = fl_dart_project_new ("./build/flutter_assets", "./linux/flutter/ephemeral/icudtl.dat");
    g_autoptr(FlView) view = fl_view_new (project);

    gtk_widget_show (GTK_WIDGET (view));
    gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (view));

    gtk_main ();

    return 0;
}
--------
  • Loading branch information
robert-ancell committed Mar 6, 2020
1 parent 7df0a6e commit 4aeba1b
Show file tree
Hide file tree
Showing 8 changed files with 600 additions and 1 deletion.
52 changes: 51 additions & 1 deletion shell/platform/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,23 @@
assert(is_linux)

import("//flutter/shell/platform/glfw/config.gni")
import("//flutter/shell/platform/linux/config.gni")

group("linux") {
deps = []
if (build_glfw_shell) {
deps = [
deps += [
":flutter_linux_glfw",
"//flutter/shell/platform/glfw:publish_headers_glfw",
"//flutter/shell/platform/glfw/client_wrapper:publish_wrapper_glfw",
]
}
if (build_linux_shell) {
deps += [
":flutter_linux_gtk",
":publish_headers_linux",
]
}
}

# Temporary workaround for the issue describe in
Expand All @@ -37,3 +45,45 @@ if (build_glfw_shell) {
public_configs = [ "//flutter:config" ]
}
}

if (build_linux_shell) {
source_set("flutter_linux") {
sources = [
"fl-dart-project.cc",
"fl-dart-project.h",
"fl-view.cc",
"fl-view.h",
]

configs += [
"//flutter/shell/platform/linux/config:gtk",
"//flutter/shell/platform/linux/config:egl",
]

# Set flag to stop headers being directly included (library users should not do this)
defines = [ "FLUTTER_GTK_COMPILATION" ]

deps = [
"//flutter/shell/platform/embedder:embedder_with_symbol_prefix",
]
}

shared_library("flutter_linux_gtk") {
deps = [
":flutter_linux",
]

public_configs = [ "//flutter:config" ]
}

copy("publish_headers_linux") {
sources = [
"flutter-gtk.h",
"fl-dart-project.h",
"fl-view.h",
]
outputs = [
"$root_out_dir/flutter-gtk/{{source_file_part}}",
]
}
}
7 changes: 7 additions & 0 deletions shell/platform/linux/config.gni
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright 2020 The Flutter Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

declare_args() {
build_linux_shell = false
}
10 changes: 10 additions & 0 deletions shell/platform/linux/config/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,17 @@
# found in the LICENSE file.

import("//build/config/linux/pkg_config.gni")
import("//flutter/shell/platform/linux/config.gni")

pkg_config("x11") {
packages = [ "x11" ]
}

if (build_linux_shell) {
pkg_config("gtk") {
packages = [ "gtk+-3.0" ]
}
pkg_config("egl") {
packages = [ "egl" ]
}
}
149 changes: 149 additions & 0 deletions shell/platform/linux/fl-dart-project.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Copyright 2020 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <gmodule.h>

#include "fl-dart-project.h"

struct _FlDartProject
{
GObject parent_instance;

gchar *assets_path;
gchar *icu_data_path;
};

enum
{
PROP_ASSETS_PATH = 1,
PROP_ICU_DATA_PATH,
PROP_LAST
};

G_DEFINE_TYPE (FlDartProject, fl_dart_project, G_TYPE_OBJECT)

static void
fl_dart_project_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
FlDartProject *self = FL_DART_PROJECT (object);

switch (prop_id) {
case PROP_ASSETS_PATH:
g_free (self->assets_path);
self->assets_path = g_strdup (g_value_get_string (value));
break;
case PROP_ICU_DATA_PATH:
g_free (self->icu_data_path);
self->icu_data_path = g_strdup (g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}

static void
fl_dart_project_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
FlDartProject *self = FL_DART_PROJECT (object);

switch (prop_id) {
case PROP_ASSETS_PATH:
g_value_set_string (value, self->assets_path);
break;
case PROP_ICU_DATA_PATH:
g_value_set_string (value, self->icu_data_path);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}

static void
fl_dart_project_dispose (GObject *object)
{
FlDartProject *self = FL_DART_PROJECT (object);

g_clear_pointer (&self->assets_path, g_free);
g_clear_pointer (&self->icu_data_path, g_free);

G_OBJECT_CLASS (fl_dart_project_parent_class)->dispose (object);
}

static void
fl_dart_project_class_init (FlDartProjectClass *klass)
{
G_OBJECT_CLASS (klass)->set_property = fl_dart_project_set_property;
G_OBJECT_CLASS (klass)->get_property = fl_dart_project_get_property;
G_OBJECT_CLASS (klass)->dispose = fl_dart_project_dispose;

g_object_class_install_property (G_OBJECT_CLASS (klass),
PROP_ASSETS_PATH,
g_param_spec_string ("assets-path",
"assets-path",
"Path to Flutter assets",
NULL,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (G_OBJECT_CLASS (klass),
PROP_ICU_DATA_PATH,
g_param_spec_string ("icu-data-path",
"icu-data-path",
"Path to ICU data",
NULL,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)));
}

static void
fl_dart_project_init (FlDartProject *self)
{
}

/**
* fl_dart_project_new:
* @assets_path: a file path, e.g. "build/assets"
* @icu_data_path: a file path, e.g. "build/icudtl.dat"
*
* Create a Flutter project.
*
* Returns: a new #FlDartProject
*/
G_MODULE_EXPORT FlDartProject *
fl_dart_project_new (const gchar *assets_path, const gchar *icu_data_path)
{
return (FlDartProject *) g_object_new (fl_dart_project_get_type (),
"assets-path", assets_path,
"icu-data-path", icu_data_path,
NULL);
}

/**
* fl_dart_project_get_assets_path:
* @view: a #FlDartProject
*
* Get the path to the directory containing the assets used in the Flutter application.
*
* Returns: a file path, e.g. "build/assets"
*/
G_MODULE_EXPORT const gchar *
fl_dart_project_get_assets_path (FlDartProject *self)
{
g_return_val_if_fail (FL_IS_DART_PROJECT (self), NULL);
return self->assets_path;
}

/**
* fl_dart_project_get_icu_data_path:
* @view: a #FlDartProject
*
* Get the path to the ICU data file in the Flutter application.
*
* Returns: a file path, e.g. "build/icudtl.dat"
*/
G_MODULE_EXPORT const gchar *
fl_dart_project_get_icu_data_path (FlDartProject *self)
{
g_return_val_if_fail (FL_IS_DART_PROJECT (self), NULL);
return self->icu_data_path;
}
23 changes: 23 additions & 0 deletions shell/platform/linux/fl-dart-project.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2020 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <glib-object.h>

#if !defined(__FLUTTER_GTK_INSIDE__) && !defined(FLUTTER_GTK_COMPILATION)
#error "Only <flutter-gtk/flutter-gtk.h> can be included directly."
#endif

G_BEGIN_DECLS

G_DECLARE_FINAL_TYPE (FlDartProject, fl_dart_project, FL, DART_PROJECT, GObject)

FlDartProject *fl_dart_project_new (const gchar *assets_path, const gchar *icu_data_path);

const gchar *fl_dart_project_get_assets_path (FlDartProject *project);

const gchar *fl_dart_project_get_icu_data_path (FlDartProject *project);

G_END_DECLS
Loading

0 comments on commit 4aeba1b

Please sign in to comment.