fix(app): the app has its own icon instead of Flutter's
All checks were successful
CI / check (push) Successful in 5s
CI / deploy (push) Successful in 1m3s

The launcher showed Flutter's logo: the project template's icons were
never replaced. tool/app_icons.py now makes every icon from the
kingfisher (assets/icon/halkyon_icon.png), through flutter_launcher_icons
v0.14.4 configured in the app's pubspec: Android's adaptive icon (the
kingfisher inset 16 % on white, for each launcher to cut to its shape)
and the square one before Android 8; iOS's, without transparency;
macOS's, the rounded tile on Apple's grid (824 of 1024 pixels); and
Windows', the rounded tile, its .ico with every size from 16 to 256
pixels (the tool writes only 256). It keeps the iOS project file as it
was, which the tool would break (flutter_launcher_icons issue 634), and
writes the snap's icon as tool/snap_icon.py did, which it replaces.

The Linux runner gives its window the bundled icon too, for desktops
that don't take it from the desktop file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-06 22:49:25 +02:00
commit e291d3af7a
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -19,6 +19,32 @@ static void first_frame_cb(MyApplication* self, FlView* view) {
gtk_widget_show(gtk_widget_get_toplevel(GTK_WIDGET(view)));
}
// Gives the window the app's icon.
//
// Desktops take an application's icon from the icon theme, by its application
// ID, once it's installed with a desktop file and an icon, as the snap is. A
// bundle run as it is has neither, so the window falls back to the PNG the app
// bundles anyway (pubspec.yaml declares it an asset): data/flutter_assets/
// beside the executable. On Wayland the compositor takes the icon of the
// window's desktop file and ignores this.
static void set_window_icon(GtkWindow* window) {
gtk_window_set_icon_name(window, APPLICATION_ID);
g_autofree gchar* executable = g_file_read_link("/proc/self/exe", nullptr);
if (executable == nullptr) {
return;
}
g_autofree gchar* bundle = g_path_get_dirname(executable);
g_autofree gchar* icon_path =
g_build_filename(bundle, "data", "flutter_assets", "assets", "icon",
"halkyon_icon.png", nullptr);
g_autoptr(GError) error = nullptr;
if (!gtk_window_set_icon_from_file(window, icon_path, &error)) {
g_warning("Couldn't load the window icon %s: %s", icon_path,
error->message);
}
}
// Implements GApplication::activate.
static void my_application_activate(GApplication* application) {
MyApplication* self = MY_APPLICATION(application);
@ -52,6 +78,7 @@ static void my_application_activate(GApplication* application) {
gtk_window_set_title(window, "Halkyon Learn");
}
set_window_icon(window);
gtk_window_set_default_size(window, 1280, 720);
g_autoptr(FlDartProject) project = fl_dart_project_new();