Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 34 additions & 59 deletions shell/platform/linux/fl_application.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,15 @@
#include "flutter/shell/platform/linux/public/flutter_linux/fl_view.h"

struct FlApplicationPrivate {
// Default window title to use.
gchar* window_title;

// Arguments to pass to Dart.
gchar** dart_entrypoint_arguments;

// Default width of a Flutter window in pixels.
int window_width;

// Default height of a Flutter window in pixels.
int window_height;

// The main window.
GtkApplicationWindow* window;
};

#define FL_APPLICATION_GET_PRIVATE(app) \
((FlApplicationPrivate*)fl_application_get_instance_private( \
FL_APPLICATION(app)))

enum { kSignalRegisterPlugins, kSignalLastSignal };
enum { kSignalRegisterPlugins, kSignalCreateWindow, kSignalLastSignal };

static guint fl_application_signals[kSignalLastSignal];

Expand All @@ -44,23 +32,23 @@ G_DEFINE_TYPE_WITH_CODE(FlApplication,
G_ADD_PRIVATE(FlApplication))

// Called when the first frame is received.
static void first_frame_cb(FlApplication* self) {
FlApplicationPrivate* priv = FL_APPLICATION_GET_PRIVATE(self);
static void first_frame_cb(FlApplication* self, FlView* view) {
GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(view));

// Show the main window.
gtk_window_present(GTK_WINDOW(priv->window));
if (window != nullptr && GTK_IS_WINDOW(window)) {
gtk_window_present(GTK_WINDOW(window));
}
}

// Default implementation of FlApplication::register_plugins
static void fl_application_register_plugins(FlApplication* self,
FlPluginRegistry* registry) {}

// Implements GApplication::activate.
static void fl_application_activate(GApplication* application) {
FlApplication* self = FL_APPLICATION(application);
FlApplicationPrivate* priv = FL_APPLICATION_GET_PRIVATE(self);

priv->window =
// Default implementation of FlApplication::create_window
static GtkWindow* fl_application_create_window(FlApplication* self,
FlView* view) {
GtkApplicationWindow* window =
GTK_APPLICATION_WINDOW(gtk_application_window_new(GTK_APPLICATION(self)));

// Use a header bar when running in GNOME as this is the common style used
Expand All @@ -72,7 +60,7 @@ static void fl_application_activate(GApplication* application) {
// if future cases occur).
gboolean use_header_bar = TRUE;
#ifdef GDK_WINDOWING_X11
GdkScreen* screen = gtk_window_get_screen(GTK_WINDOW(priv->window));
GdkScreen* screen = gtk_window_get_screen(GTK_WINDOW(window));
if (GDK_IS_X11_SCREEN(screen)) {
const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
Expand All @@ -83,15 +71,19 @@ static void fl_application_activate(GApplication* application) {
if (use_header_bar) {
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar));
gtk_header_bar_set_title(header_bar, priv->window_title);
gtk_header_bar_set_show_close_button(header_bar, TRUE);
gtk_window_set_titlebar(GTK_WINDOW(priv->window), GTK_WIDGET(header_bar));
} else {
gtk_window_set_title(GTK_WINDOW(priv->window), priv->window_title);
gtk_window_set_titlebar(GTK_WINDOW(window), GTK_WIDGET(header_bar));
}

gtk_window_set_default_size(GTK_WINDOW(priv->window), priv->window_width,
priv->window_height);
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));

return GTK_WINDOW(window);
}

// Implements GApplication::activate.
static void fl_application_activate(GApplication* application) {
FlApplication* self = FL_APPLICATION(application);
FlApplicationPrivate* priv = FL_APPLICATION_GET_PRIVATE(self);

g_autoptr(FlDartProject) project = fl_dart_project_new();
fl_dart_project_set_dart_entrypoint_arguments(
Expand All @@ -101,7 +93,10 @@ static void fl_application_activate(GApplication* application) {
g_signal_connect_swapped(view, "first-frame", G_CALLBACK(first_frame_cb),
self);
gtk_widget_show(GTK_WIDGET(view));
gtk_container_add(GTK_CONTAINER(priv->window), GTK_WIDGET(view));

GtkWindow* window;
g_signal_emit(self, fl_application_signals[kSignalCreateWindow], 0, view,
&window);

// Make the resources for the view so rendering can start.
// We'll show the view when we have the first frame.
Expand Down Expand Up @@ -141,7 +136,6 @@ static void fl_application_dispose(GObject* object) {
FlApplication* self = FL_APPLICATION(object);
FlApplicationPrivate* priv = FL_APPLICATION_GET_PRIVATE(self);

g_clear_pointer(&priv->window_title, g_free);
g_clear_pointer(&priv->dart_entrypoint_arguments, g_strfreev);

G_OBJECT_CLASS(fl_application_parent_class)->dispose(object);
Expand All @@ -154,20 +148,20 @@ static void fl_application_class_init(FlApplicationClass* klass) {
G_OBJECT_CLASS(klass)->dispose = fl_application_dispose;

klass->register_plugins = fl_application_register_plugins;
klass->create_window = fl_application_create_window;

fl_application_signals[kSignalRegisterPlugins] = g_signal_new(
"register-plugins", fl_application_get_type(), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(FlApplicationClass, register_plugins), NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
fl_plugin_registry_get_type());
G_STRUCT_OFFSET(FlApplicationClass, register_plugins), nullptr, nullptr,
nullptr, G_TYPE_NONE, 1, fl_plugin_registry_get_type());
fl_application_signals[kSignalCreateWindow] = g_signal_new(
"create-window", fl_application_get_type(), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(FlApplicationClass, create_window),
g_signal_accumulator_first_wins, nullptr, nullptr, GTK_TYPE_WINDOW, 1,
fl_view_get_type());
}

static void fl_application_init(FlApplication* self) {
FlApplicationPrivate* priv = FL_APPLICATION_GET_PRIVATE(self);
priv->window_title = g_strdup("");
priv->window_width = 1280;
priv->window_height = 720;
}
static void fl_application_init(FlApplication* self) {}

G_MODULE_EXPORT
FlApplication* fl_application_new(const gchar* application_id,
Expand All @@ -176,22 +170,3 @@ FlApplication* fl_application_new(const gchar* application_id,
"application-id", application_id, "flags",
flags, nullptr));
}

G_MODULE_EXPORT
void fl_application_set_default_window_title(FlApplication* self,
const gchar* window_title) {
g_return_if_fail(FL_IS_APPLICATION(self));
FlApplicationPrivate* priv = FL_APPLICATION_GET_PRIVATE(self);
g_free(priv->window_title);
priv->window_title = g_strdup(window_title);
}

G_MODULE_EXPORT
void fl_application_set_default_window_size(FlApplication* self,
int width,
int height) {
g_return_if_fail(FL_IS_APPLICATION(self));
FlApplicationPrivate* priv = FL_APPLICATION_GET_PRIVATE(self);
priv->window_width = width;
priv->window_height = height;
}
36 changes: 14 additions & 22 deletions shell/platform/linux/public/flutter_linux/fl_application.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@ struct _FlApplicationClass {
*/
void (*register_plugins)(FlApplication* application,
FlPluginRegistry* registry);

/**
* FlApplication::create_window:
* @application: the application
* @view: the view to add to this window.
*
* The ::create_window signal is emitted when a needs to be created for a
* view. By handling this signal the application can create the appropriate
* window for the given view and set any window properties or additional
* widgets required.
*
* If this signal is not handled a standard GTK window will be created.
*/
GtkWindow* (*create_window)(FlApplication* application, FlView* view);
};

/**
Expand All @@ -62,28 +76,6 @@ struct _FlApplicationClass {
FlApplication* fl_application_new(const gchar* application_id,
GApplicationFlags flags);

/**
* fl_application_set_default_window_title:
* @application: an #FlApplication.
* @window_title: window title text.
*
* Sets the title to apply to Flutter windows.
*/
void fl_application_set_default_window_title(FlApplication* application,
const gchar* window_title);

/**
* fl_application_set_default_window_size:
* @application: an #FlApplication.
* @width: width in pixels or -1 to set the default width.
* @height: height in pixels or -1 to set the default height.
*
* Sets the dimensions to apply to Flutter windows.
*/
void fl_application_set_default_window_size(FlApplication* application,
int width,
int height);

G_END_DECLS

#endif // FLUTTER_SHELL_PLATFORM_LINUX_PUBLIC_FLUTTER_LINUX_FL_APPLICATION_H_