From af8ed5ac783dcfd5e939069801cd5507ab1f9a8f Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Sun, 4 Jun 2023 17:50:34 -0700 Subject: [PATCH] update _FlDartProject struct and use new flutter apis for some settings --- linux/CMakeLists.txt | 35 ++++++++++++++++++++++++----- linux/my_application.cc | 49 ++++++++++++++++++----------------------- 2 files changed, 51 insertions(+), 33 deletions(-) diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 62315a01..26f75c20 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -1,11 +1,19 @@ +# Project-level configuration. cmake_minimum_required(VERSION 3.10) project(runner LANGUAGES CXX) +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. set(BINARY_NAME "cwtch") +# The unique GTK application identifier for this application. See: +# https://wiki.gnome.org/HowDoI/ChooseApplicationID set(APPLICATION_ID "im.cwtch.cwtch") +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. cmake_policy(SET CMP0063 NEW) +# Load bundled libraries from the lib/ directory relative to the binary. set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") # Root filesystem for cross-building. @@ -18,7 +26,7 @@ if(FLUTTER_TARGET_PLATFORM_SYSROOT) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) endif() -# Configure build options. +# Define build configuration options. if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Flutter build mode" FORCE) @@ -27,6 +35,10 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) endif() # Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_14) target_compile_options(${TARGET} PRIVATE -Wall -Werror) @@ -34,6 +46,7 @@ function(APPLY_STANDARD_SETTINGS TARGET) target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") endfunction() +# Flutter library and tool build rules. set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") # Flutter library and tool build rules. @@ -45,16 +58,27 @@ pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") -# Application build +# Define the application target. To change its name, change BINARY_NAME above, +# not the value here, or `flutter run` will no longer work. +# +# Any new source files that you add to the application should be added here. add_executable(${BINARY_NAME} "main.cc" "my_application.cc" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" ) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. apply_standard_settings(${BINARY_NAME}) + +# Add dependency libraries. Add any application-specific dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter) target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) + +# Run the Flutter tool portions of the build. This must not be removed. add_dependencies(${BINARY_NAME} flutter_assemble) + # Only the install-generated bundle's copy of the executable will launch # correctly, since the resources must in the right relative locations. To avoid # people trying to run the unbundled copy, put it in a subdirectory instead of @@ -64,6 +88,7 @@ set_target_properties(${BINARY_NAME} RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" ) + # Generated plugin build rules, which manage building the plugins and adding # them to the application. include(flutter/generated_plugins.cmake) @@ -94,11 +119,11 @@ install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR} install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) -if(PLUGIN_BUNDLED_LIBRARIES) - install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" +foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) + install(FILES "${bundled_library}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) -endif() +endforeach(bundled_library) # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. diff --git a/linux/my_application.cc b/linux/my_application.cc index 86d95331..fb5a63eb 100644 --- a/linux/my_application.cc +++ b/linux/my_application.cc @@ -10,6 +10,7 @@ #include #include +#include #ifdef GDK_WINDOWING_X11 #include #endif @@ -28,7 +29,6 @@ struct _MyApplication { struct _FlDartProject { GObject parent_instance; - gboolean enable_mirrors; gchar* aot_library_path; gchar* assets_path; gchar* icu_data_path; @@ -65,29 +65,29 @@ static void my_application_activate(GApplication* application) { // if future cases occur). gboolean use_header_bar = TRUE; #ifdef GDK_WINDOWING_X11 - GdkScreen *screen = gtk_window_get_screen(window); + GdkScreen* screen = gtk_window_get_screen(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) { - use_header_bar = FALSE; - } + const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); + if (g_strcmp0(wm_name, "GNOME Shell") != 0) { + use_header_bar = FALSE; + } } #endif if (use_header_bar) { - GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); + GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); gtk_widget_show(GTK_WIDGET(header_bar)); gtk_header_bar_set_title(header_bar, "cwtch"); gtk_header_bar_set_show_close_button(header_bar, TRUE); gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); - } - else { + } else { gtk_window_set_title(window, "cwtch"); } gtk_window_set_default_size(window, 1280, 720); gtk_widget_show(GTK_WIDGET(window)); - g_signal_connect(G_OBJECT(window), + // custom hook to catch app exit and send notification to flutter to cleanup + g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(on_shutdown), NULL); g_autoptr(FlDartProject) project = fl_dart_project_new(); @@ -98,58 +98,51 @@ static void my_application_activate(GApplication* application) { if (stat(fl_dart_project_get_assets_path(project), &info ) != 0 ) { if( stat("lib/cwtch", &info) == 0) { // use local dir structure - project->assets_path = g_build_filename("data", "flutter_assets", nullptr); + fl_dart_project_set_assets_path(project, g_build_filename("data", "flutter_assets", nullptr)); project->aot_library_path = g_build_filename("lib", "libapp.so", nullptr); - project->icu_data_path = g_build_filename("data", "icudtl.dat", nullptr); + fl_dart_project_set_icu_data_path(project, g_build_filename("data", "icudtl.dat", nullptr)); gtk_window_set_icon_from_file(window, "./cwtch.png", NULL); } else if( stat("/usr/share/cwtch/data/flutter_assets", &info ) != 0 ) { // if we're non in sys installed structure, use home dir structure struct passwd *pw = getpwuid(getuid()); const char *homedir = pw->pw_dir; // /home/$USER/.local/share/cwtch/data/flutter_assets - project->assets_path = g_build_filename(homedir, ".local", "share", "cwtch", "data", "flutter_assets", nullptr); + fl_dart_project_set_assets_path(project, g_build_filename(homedir, ".local", "share", "cwtch", "data", "flutter_assets", nullptr)); // /home/$USER/.local/lib/cwtch/ project->aot_library_path = g_build_filename(homedir, ".local", "lib", "cwtch", "libapp.so", nullptr); // /home/$USER/.local/share/cwtch/data - project->icu_data_path = g_build_filename(homedir, ".local", "share", "cwtch", "data", "icudtl.dat", nullptr); + fl_dart_project_set_icu_data_path(project, g_build_filename(homedir, ".local", "share", "cwtch", "data", "icudtl.dat", nullptr)); gtk_window_set_icon_from_file(window, g_build_filename(homedir, ".local", "share", "icons", "cwtch.png", nullptr), NULL); } else { // else assume we are in sys installed structure // /usr/share/cwtch/data/flutter_assets - project->assets_path = g_build_filename("/", "usr", "share", "cwtch", "data", "flutter_assets", nullptr); + fl_dart_project_set_assets_path(project, g_build_filename("/", "usr", "share", "cwtch", "data", "flutter_assets", nullptr)); // /usr/lib/cwtch project->aot_library_path = g_build_filename("/", "usr", "lib", "cwtch", "libapp.so", nullptr); // /usr/share/cwtch/data - project->icu_data_path = g_build_filename("/", "usr", "share", "cwtch", "data", "icudtl.dat", nullptr); + fl_dart_project_set_icu_data_path(project, g_build_filename("/", "usr", "share", "cwtch", "data", "icudtl.dat", nullptr)); gtk_window_set_icon_from_file(window, "/usr/share/icons/cwtch.png", NULL); } } - printf("my_application.cc: using aot_library_path or '%s'\n", project->aot_library_path); fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); - FlView* view = fl_view_new(project); gtk_widget_show(GTK_WIDGET(view)); gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); - fl_register_plugins(FL_PLUGIN_REGISTRY(view)); // Create a specific channel for shutting down cwtch when the close button is triggered // We have registered the "destroy" handle above for this reason FlEngine *engine = fl_view_get_engine(view); - g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new(); - g_autoptr(FlBinaryMessenger) messenger = fl_engine_get_binary_messenger(engine); - channel = fl_method_channel_new(messenger, "im.cwtch.linux.shutdown", FL_METHOD_CODEC(codec)); - - + g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new(); + g_autoptr(FlBinaryMessenger) messenger = fl_engine_get_binary_messenger(engine); + channel = fl_method_channel_new(messenger, "im.cwtch.linux.shutdown", FL_METHOD_CODEC(codec)); gtk_widget_grab_focus(GTK_WIDGET(view)); } - - // Implements GApplication::local_command_line. -static gboolean my_application_local_command_line(GApplication* application, gchar ***arguments, int *exit_status) { +static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { MyApplication* self = MY_APPLICATION(application); // Strip out the first argument as it is the binary name. self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); @@ -168,7 +161,7 @@ static gboolean my_application_local_command_line(GApplication* application, gch } // Implements GObject::dispose. -static void my_application_dispose(GObject *object) { +static void my_application_dispose(GObject* object) { MyApplication* self = MY_APPLICATION(object); g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); G_OBJECT_CLASS(my_application_parent_class)->dispose(object);