From 0397519801995dd7d68b07ee2751c9066e8557d5 Mon Sep 17 00:00:00 2001 From: pepaskopec-blip Date: Tue, 15 Sep 2026 12:46:52 +0200 Subject: [PATCH] Wire app icon into the GTK window and build. Co-authored-by: Cursor --- .gitignore | 3 +++ CMakeLists.txt | 16 +++++++++++++--- Makefile | 11 ++++++++++- main.c | 23 +++++++++++++++++++++++ maturita.h | 3 +++ 5 files changed, 52 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index e5c945d..7e776a5 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,9 @@ progress/ dist/ build/ +# Generated from assets/app-icon.png (Makefile / CMake POST_BUILD) +assets/icons/ + # Object files *.o *.ko diff --git a/CMakeLists.txt b/CMakeLists.txt index 2804da5..3810f57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,9 +62,19 @@ else() -Wall -Wextra -Wno-deprecated-declarations) endif() -# The GTK stylesheet is loaded at runtime from the working directory, so keep -# a copy next to the built binary as well. +# The GTK stylesheet and window icon are loaded at runtime from the working +# directory (or next to the binary), so keep copies beside the built binary. add_custom_command(TARGET maturita POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/style.css - $/style.css) + $/style.css + COMMAND ${CMAKE_COMMAND} -E make_directory + $/icons/hicolor/512x512/apps + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/assets/app-icon.png + $/icons/hicolor/512x512/apps/maturita.png + COMMAND ${CMAKE_COMMAND} -E make_directory + ${CMAKE_CURRENT_SOURCE_DIR}/assets/icons/hicolor/512x512/apps + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/assets/app-icon.png + ${CMAKE_CURRENT_SOURCE_DIR}/assets/icons/hicolor/512x512/apps/maturita.png) diff --git a/Makefile b/Makefile index a816ed5..187e2eb 100644 --- a/Makefile +++ b/Makefile @@ -28,9 +28,16 @@ endif SRC = $(wildcard *.c) OBJ = $(SRC:.c=.o) +ICON_SRC = assets/app-icon.png +ICON_DST = assets/icons/hicolor/512x512/apps/maturita.png + all: $(TARGET) -$(TARGET): $(SRC) +$(ICON_DST): $(ICON_SRC) + mkdir -p $(dir $@) + cp "$(ICON_SRC)" "$@" + +$(TARGET): $(SRC) $(ICON_DST) $(CC) $(CFLAGS) -o $(TARGET) $(SRC) $(LIBS) clean: @@ -48,6 +55,8 @@ bundle: $(TARGET) @mkdir -p dist @cp $(TARGET) dist/ @cp style.css dist/ + @mkdir -p dist/icons/hicolor/512x512/apps + @cp "$(ICON_DST)" dist/icons/hicolor/512x512/apps/ @ldd $(TARGET) | grep -Ei '/(ucrt64|mingw64)/bin/' | awk '{print $$3}' \ | xargs -r -I{} cp -f {} dist/ @echo "Bundled into dist/ - run dist/$(TARGET)" diff --git a/main.c b/main.c index 188c797..28abcc5 100644 --- a/main.c +++ b/main.c @@ -185,6 +185,28 @@ static gboolean ui_scale_tick(GtkWidget *w, GdkFrameClock *clock, return G_SOURCE_CONTINUE; } +/* GTK4 has no gtk_window_set_icon_from_file(); register a local hicolor + * theme dir and set the window icon by name instead. */ +static void setup_window_icon(GtkWindow *window) { + GtkIconTheme *theme; + static const char *dirs[] = { ICON_THEME_DIR, ICON_THEME_DIR_ALT, NULL }; + + theme = gtk_icon_theme_get_for_display(gdk_display_get_default()); + for (int i = 0; dirs[i]; i++) { + if (g_file_test(dirs[i], G_FILE_TEST_IS_DIR)) + gtk_icon_theme_add_search_path(theme, dirs[i]); + } + + if (!gtk_icon_theme_has_icon(theme, ICON_NAME)) { + g_warning("App icon '%s' not found (tried %s/ and %s/)", + ICON_NAME, ICON_THEME_DIR, ICON_THEME_DIR_ALT); + return; + } + + gtk_window_set_default_icon_name(ICON_NAME); + gtk_window_set_icon_name(window, ICON_NAME); +} + void activate(GtkApplication *app, gpointer user_data) { GtkWindow *window; GtkWidget *headerbar; @@ -208,6 +230,7 @@ void activate(GtkApplication *app, gpointer user_data) { main_window = window; gtk_window_set_title(window, "maturita.c"); gtk_window_set_default_size(window, 760, 560); + setup_window_icon(window); headerbar = gtk_header_bar_new(); gtk_widget_add_css_class(headerbar, "titlebar"); diff --git a/maturita.h b/maturita.h index f8ec7c6..f828f14 100644 --- a/maturita.h +++ b/maturita.h @@ -15,6 +15,9 @@ #define HW_SUBJ 2 /* index of "Technické vybavení" */ #define CZ_SUBJ 3 /* index of "Český jazyk a literatura" */ #define CSS_FILE "style.css" +#define ICON_NAME "maturita" +#define ICON_THEME_DIR "assets/icons" /* cwd when run from source tree */ +#define ICON_THEME_DIR_ALT "icons" /* next to the binary after install */ #define PROGRESS_DIR "progress" #define PROGRESS_U1 "progress/unit1.conf" #define PROGRESS_U2 "progress/unit2.conf"