Point the build and runtime paths at src/ and data/.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
pepaskopec-blip 2026-09-17 17:01:17 +02:00
commit 72deed70e8
11 changed files with 134 additions and 260 deletions

197
.gitignore vendored
View file

@ -1,184 +1,25 @@
# ---> C # Binaries and build trees
# Prerequisites /maturita
#.d /maturita.exe
/build/
/dist/
/progress/
*.o
*.d
*.res
*.exe
#jetbrains slop # Generated icon copies (source of truth is data/share/icons)
.idea/ /assets/icons/
# binary # Editor / OS
.DS_Store .DS_Store
sprechen .idea/
maturita .vscode/
cmake-build-*/
*.dSYM/
# Local notes
error.txt error.txt
error.log error.log
CLAUDE.md CLAUDE.md
progress/
dist/
build/
# Generated from assets/app-icon.png (Makefile / CMake POST_BUILD)
assets/icons/
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
# The rule above targets kernel build artifacts such as .foo.o.cmd; the
# Windows installer is a source file that has to be tracked.
!installers/*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# debug information files
*.dwo
# CLion
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#cmake-build-*
# ---> VisualStudioCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
!*.code-workspace
# Built Visual Studio Code Extensions
*.vsix
# ---> JetBrains
# Covers JetBrains IDEs: IntelliJ, GoLand, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
.idea/sonarlint.xml # see https://community.sonarsource.com/t/is-the-file-idea-idea-idea-sonarlint-xml-intended-to-be-under-source-control/121119
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based HTTP Client
.idea/httpRequests
http-client.private.env.json
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
# Apifox Helper cache
.idea/.cache/.Apifox_Helper
.idea/ApifoxUploaderProjectSetting.xml
# Github Copilot persisted session migrations, see: https://github.com/microsoft/copilot-intellij-feedback/issues/712#issuecomment-3322062215
.idea/**/copilot.data.migration.*.xml

View file

@ -7,8 +7,6 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
# GTK4 is found through pkg-config everywhere: Linux/macOS packages, MSYS2, # GTK4 is found through pkg-config everywhere: Linux/macOS packages, MSYS2,
# vcpkg and the native MSVC (gvsbuild) package all ship .pc files. # vcpkg and the native MSVC (gvsbuild) package all ship .pc files.
if(MSVC) if(MSVC)
# On MSVC the Unix-style flags pkg-config prints are not understood, so
# ask for the native "/I" and ".lib" form instead.
find_program(PKG_CONFIG_EXECUTABLE find_program(PKG_CONFIG_EXECUTABLE
NAMES pkg-config pkg-config.exe pkgconf pkgconf.exe) NAMES pkg-config pkg-config.exe pkgconf pkgconf.exe)
if(NOT PKG_CONFIG_EXECUTABLE) if(NOT PKG_CONFIG_EXECUTABLE)
@ -42,17 +40,18 @@ else()
pkg_check_modules(GTK4 REQUIRED IMPORTED_TARGET gtk4) pkg_check_modules(GTK4 REQUIRED IMPORTED_TARGET gtk4)
endif() endif()
# WIN32 suppresses the console window on Windows; the app still uses main(), file(GLOB MATURITA_SOURCES CONFIGURE_DEPENDS
# so MSVC needs mainCRTStartup as the entry point. "${CMAKE_CURRENT_SOURCE_DIR}/src/*.c")
file(GLOB MATURITA_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.c")
if(WIN32) if(WIN32)
add_executable(maturita WIN32 ${MATURITA_SOURCES} add_executable(maturita WIN32 ${MATURITA_SOURCES}
"${CMAKE_CURRENT_SOURCE_DIR}/maturita.rc") "${CMAKE_CURRENT_SOURCE_DIR}/data/windows/maturita.rc")
else() else()
add_executable(maturita ${MATURITA_SOURCES}) add_executable(maturita ${MATURITA_SOURCES})
endif() endif()
# Mirrors COMMIT in the Makefile: bakes the source commit in for the updater. target_include_directories(maturita PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/src")
if(DEFINED APP_COMMIT AND NOT APP_COMMIT STREQUAL "") if(DEFINED APP_COMMIT AND NOT APP_COMMIT STREQUAL "")
target_compile_definitions(maturita PRIVATE APP_COMMIT="${APP_COMMIT}") target_compile_definitions(maturita PRIVATE APP_COMMIT="${APP_COMMIT}")
endif() endif()
@ -72,22 +71,18 @@ else()
endif() endif()
endif() endif()
# The GTK stylesheet, window icon and Freedesktop share/ tree are loaded at # Runtime assets sit next to the binary after install / cmake --build.
# runtime from the working directory (or next to the binary). set(ICON_512
"${CMAKE_CURRENT_SOURCE_DIR}/data/share/icons/hicolor/512x512/apps/maturita.png")
add_custom_command(TARGET maturita POST_BUILD add_custom_command(TARGET maturita POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/style.css ${CMAKE_CURRENT_SOURCE_DIR}/data/style.css
$<TARGET_FILE_DIR:maturita>/style.css $<TARGET_FILE_DIR:maturita>/style.css
COMMAND ${CMAKE_COMMAND} -E make_directory COMMAND ${CMAKE_COMMAND} -E make_directory
$<TARGET_FILE_DIR:maturita>/icons/hicolor/512x512/apps $<TARGET_FILE_DIR:maturita>/icons/hicolor/512x512/apps
COMMAND ${CMAKE_COMMAND} -E copy_if_different COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/assets/app-icon.png ${ICON_512}
$<TARGET_FILE_DIR:maturita>/icons/hicolor/512x512/apps/maturita.png $<TARGET_FILE_DIR:maturita>/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
COMMAND ${CMAKE_COMMAND} -E copy_directory COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/share ${CMAKE_CURRENT_SOURCE_DIR}/data/share
$<TARGET_FILE_DIR:maturita>/share) $<TARGET_FILE_DIR:maturita>/share)

View file

@ -8,13 +8,15 @@ ifeq ($(PKG_CONFIG),)
PKG_CONFIG := pkg-config PKG_CONFIG := pkg-config
endif endif
# Use $(shell ...) instead of backticks so the flags are expanded by make
# itself; IDEs that import the Makefile via a dry run then see the real
# include paths.
GTK_CFLAGS := $(shell $(PKG_CONFIG) --cflags gtk4) GTK_CFLAGS := $(shell $(PKG_CONFIG) --cflags gtk4)
GTK_LIBS := $(shell $(PKG_CONFIG) --libs gtk4) GTK_LIBS := $(shell $(PKG_CONFIG) --libs gtk4)
CFLAGS = -Wall -Wextra -Wno-deprecated-declarations $(GTK_CFLAGS) SRC_DIR := src
DATA_DIR := data
BUILD_DIR := build
CFLAGS = -Wall -Wextra -Wno-deprecated-declarations -I$(SRC_DIR) \
-MMD -MP $(GTK_CFLAGS)
LIBS = $(GTK_LIBS) -lm LIBS = $(GTK_LIBS) -lm
# Published builds pass the commit they were made from (the CI workflow # Published builds pass the commit they were made from (the CI workflow
@ -25,69 +27,67 @@ ifneq ($(COMMIT),)
CFLAGS += -DAPP_COMMIT='"$(COMMIT)"' CFLAGS += -DAPP_COMMIT='"$(COMMIT)"'
endif endif
# Windows (MSYS2 / MinGW): .exe suffix, no console window, embed .ico.
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
TARGET = maturita.exe TARGET = maturita.exe
LIBS += -mwindows LIBS += -mwindows
WINDRES ?= windres WINDRES ?= windres
RC_OBJ = maturita_rc.o RC_SRC = $(DATA_DIR)/windows/maturita.rc
RC_OBJ = $(BUILD_DIR)/maturita_rc.o
UNAME_S := UNAME_S :=
else else
TARGET = maturita TARGET = maturita
RC_SRC =
RC_OBJ = RC_OBJ =
UNAME_S := $(shell uname -s 2>/dev/null) UNAME_S := $(shell uname -s 2>/dev/null)
# macOS Dock icon is set via AppKit (see macos_dock.c).
ifeq ($(UNAME_S),Darwin) ifeq ($(UNAME_S),Darwin)
LIBS += -framework AppKit -framework Foundation LIBS += -framework AppKit -framework Foundation
endif endif
endif endif
SRC = $(wildcard *.c) SRC = $(wildcard $(SRC_DIR)/*.c)
OBJ = $(SRC:.c=.o) OBJ = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SRC))
DEP = $(OBJ:.o=.d)
ICON_SRC = assets/app-icon.png ICON_DST = $(DATA_DIR)/share/icons/hicolor/512x512/apps/maturita.png
# Always use the real 512×512 asset — copying app-icon.png (1024×1024) breaks
# linuxdeploy, which rejects non-standard icon resolutions.
ICON_DST = share/icons/hicolor/512x512/apps/maturita.png
ICON_RUNTIME = assets/icons/hicolor/512x512/apps/maturita.png
ICON_ICO = assets/app-icon.ico ICON_ICO = assets/app-icon.ico
all: $(TARGET) all: $(TARGET)
$(ICON_RUNTIME): $(ICON_DST) $(BUILD_DIR):
mkdir -p $(dir $@) mkdir -p $(BUILD_DIR)
cp "$(ICON_DST)" "$@"
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR)
$(CC) $(CFLAGS) -c -o $@ $<
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
$(RC_OBJ): maturita.rc $(ICON_ICO) $(RC_OBJ): $(RC_SRC) $(ICON_ICO) | $(BUILD_DIR)
$(WINDRES) maturita.rc -o $(RC_OBJ) $(WINDRES) -I. -o $@ $<
$(TARGET): $(SRC) $(ICON_RUNTIME) $(RC_OBJ) $(TARGET): $(OBJ) $(RC_OBJ)
$(CC) $(CFLAGS) -o $(TARGET) $(SRC) $(RC_OBJ) $(LIBS) $(CC) $(CFLAGS) -o $@ $(OBJ) $(RC_OBJ) $(LIBS)
else else
$(TARGET): $(SRC) $(ICON_RUNTIME) $(TARGET): $(OBJ)
$(CC) $(CFLAGS) -o $(TARGET) $(SRC) $(LIBS) $(CC) $(CFLAGS) -o $@ $(OBJ) $(LIBS)
endif endif
clean: clean:
rm -f $(TARGET) maturita.exe $(OBJ) $(RC_OBJ) maturita_rc.o rm -f $(TARGET) maturita.exe
rm -rf $(BUILD_DIR)
run: $(TARGET) run: $(TARGET)
./$(TARGET) ./$(TARGET)
# Self-contained package for the current platform into dist/.
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
bundle: $(TARGET) bundle: $(TARGET)
@rm -rf dist @rm -rf dist
@mkdir -p dist @mkdir -p dist
@cp $(TARGET) dist/ @cp $(TARGET) dist/
@cp style.css dist/ @cp $(DATA_DIR)/style.css dist/
@mkdir -p dist/icons/hicolor/512x512/apps @mkdir -p dist/icons/hicolor/512x512/apps
@cp "$(ICON_DST)" dist/icons/hicolor/512x512/apps/ @cp "$(ICON_DST)" dist/icons/hicolor/512x512/apps/
@cp -R share dist/ @cp -R $(DATA_DIR)/share dist/
@ldd $(TARGET) | grep -Ei '/(ucrt64|mingw64)/bin/' | awk '{print $$3}' \ @ldd $(TARGET) | grep -Ei '/(ucrt64|mingw64)/bin/' | awk '{print $$3}' \
| xargs -r -I{} cp -f {} dist/ | xargs -r -I{} cp -f {} dist/
@# GTK runtime data (schemas / pixbuf loaders) next to the exe.
@GTK_PREFIX="$$($(PKG_CONFIG) --variable=prefix gtk4)"; \ @GTK_PREFIX="$$($(PKG_CONFIG) --variable=prefix gtk4)"; \
if [ -d "$$GTK_PREFIX/share/glib-2.0" ]; then \ if [ -d "$$GTK_PREFIX/share/glib-2.0" ]; then \
mkdir -p dist/share && cp -R "$$GTK_PREFIX/share/glib-2.0" dist/share/; \ mkdir -p dist/share && cp -R "$$GTK_PREFIX/share/glib-2.0" dist/share/; \
@ -106,4 +106,6 @@ bundle:
@./scripts/bundle-linux.sh @./scripts/bundle-linux.sh
endif endif
-include $(DEP)
.PHONY: all clean run bundle .PHONY: all clean run bundle

View file

@ -125,12 +125,12 @@ make bundle # dist/maturita.exe jde spustit i z Průzkumník
### Struktura ### Struktura
``` ```
*.c / maturita.h zdroj aplikace src/ C zdroje a maturita.h
style.css GTK styl (barvy se vkládají za běhu) data/ style.css, share/, podpisy, Windows .rc
assets/ zdrojová ikona a screenshoty
installers/ instalátory, které stáhnou aktuální build installers/ instalátory, které stáhnou aktuální build
scripts/ balení AppImage a .app scripts/ balení AppImage a .app
.github/workflows/build.yml CI: push na main → větev builds .github/workflows/ CI: push na main → větev builds
assets/ ikona a screenshoty
progress/ vzniká za běhu (cvičení, nastavení) progress/ vzniká za běhu (cvičení, nastavení)
``` ```
@ -256,12 +256,12 @@ make bundle # dist/maturita.exe can be double-clicked
### Layout ### Layout
``` ```
*.c / maturita.h application sources src/ C sources and maturita.h
style.css GTK stylesheet (palette injected at runtime) data/ style.css, share/, signing files, Windows .rc
assets/ source icon and screenshots
installers/ fetch-the-latest installers installers/ fetch-the-latest installers
scripts/ AppImage / .app bundlers scripts/ AppImage / .app bundlers
.github/workflows/build.yml CI: push to main → builds branch .github/workflows/ CI: push to main → builds branch
assets/ icon and screenshots
progress/ created at runtime (exercises, settings) progress/ created at runtime (exercises, settings)
``` ```

View file

@ -75,15 +75,16 @@ if not exist "assets\app-icon.ico" (
REM --- 4. Compile resources + sources --------------------------------------- REM --- 4. Compile resources + sources ---------------------------------------
echo Building maturita.exe with MSVC... echo Building maturita.exe with MSVC...
rc /nologo /fo maturita.res maturita.rc if not exist build mkdir build
rc /nologo /fo build\maturita.res data\windows\maturita.rc
if errorlevel 1 ( if errorlevel 1 (
echo [error] Resource compile failed. echo [error] Resource compile failed.
exit /b 1 exit /b 1
) )
cl /nologo /O2 /MD /W3 /std:c11 /D_CRT_SECURE_NO_WARNINGS ^ cl /nologo /O2 /MD /W3 /std:c11 /I src /D_CRT_SECURE_NO_WARNINGS ^
%GTK_CFLAGS% *.c maturita.res ^ %GTK_CFLAGS% src\*.c build\maturita.res ^
/Fe:maturita.exe ^ /Fe:maturita.exe /Fo:build\ ^
/link /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup %GTK_LIBS% /link /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup %GTK_LIBS%
if errorlevel 1 ( if errorlevel 1 (

View file

@ -1,3 +1,3 @@
/* Windows application icon embedded into maturita.exe. /* Windows application icon embedded into maturita.exe.
* The first ICON resource becomes the Explorer / taskbar icon. */ * The first ICON resource becomes the Explorer / taskbar icon. */
1 ICON "assets/app-icon.ico" 1 ICON "../../assets/app-icon.ico"

View file

@ -20,7 +20,7 @@ OUT_NAME="maturita-linux-${ARCH}.AppImage"
APPDIR="$ROOT/dist/AppDir" APPDIR="$ROOT/dist/AppDir"
TOOLS="$ROOT/dist/tools" TOOLS="$ROOT/dist/tools"
# Real 512×512 PNG (assets/app-icon.png is 1024×1024 and linuxdeploy rejects it). # Real 512×512 PNG (assets/app-icon.png is 1024×1024 and linuxdeploy rejects it).
ICON_512="$ROOT/share/icons/hicolor/512x512/apps/maturita.png" ICON_512="$ROOT/data/share/icons/hicolor/512x512/apps/maturita.png"
echo "==> Building maturita" echo "==> Building maturita"
make -C "$ROOT" clean make -C "$ROOT" clean
@ -35,16 +35,16 @@ mkdir -p "$APPDIR/usr/bin" \
"$APPDIR/share" "$APPDIR/share"
cp -f "$ROOT/maturita" "$APPDIR/usr/bin/maturita" cp -f "$ROOT/maturita" "$APPDIR/usr/bin/maturita"
cp -f "$ROOT/style.css" "$APPDIR/style.css" cp -f "$ROOT/data/style.css" "$APPDIR/style.css"
cp -f "$ICON_512" "$APPDIR/icons/hicolor/512x512/apps/maturita.png" cp -f "$ICON_512" "$APPDIR/icons/hicolor/512x512/apps/maturita.png"
cp -f "$ICON_512" "$APPDIR/usr/share/icons/hicolor/512x512/apps/maturita.png" cp -f "$ICON_512" "$APPDIR/usr/share/icons/hicolor/512x512/apps/maturita.png"
cp -f "$ICON_512" "$APPDIR/maturita.png" cp -f "$ICON_512" "$APPDIR/maturita.png"
cp -R "$ROOT/share/." "$APPDIR/share/" cp -R "$ROOT/data/share/." "$APPDIR/share/"
cp -R "$ROOT/share/." "$APPDIR/usr/share/" cp -R "$ROOT/data/share/." "$APPDIR/usr/share/"
cp -f "$ROOT/share/applications/org.maturita.Maturita.desktop" \ cp -f "$ROOT/data/share/applications/org.maturita.Maturita.desktop" \
"$APPDIR/usr/share/applications/org.maturita.Maturita.desktop" "$APPDIR/usr/share/applications/org.maturita.Maturita.desktop"
# AppImage desktop entry must live at AppDir root and Exec= must be AppRun-compatible. # AppImage desktop entry must live at AppDir root and Exec= must be AppRun-compatible.
cp -f "$ROOT/share/applications/org.maturita.Maturita.desktop" \ cp -f "$ROOT/data/share/applications/org.maturita.Maturita.desktop" \
"$APPDIR/org.maturita.Maturita.desktop" "$APPDIR/org.maturita.Maturita.desktop"
# linuxdeploy expects Icon= without path and a matching PNG at AppDir root. # linuxdeploy expects Icon= without path and a matching PNG at AppDir root.
sed -i.bak 's|^Exec=.*|Exec=maturita|' "$APPDIR/org.maturita.Maturita.desktop" sed -i.bak 's|^Exec=.*|Exec=maturita|' "$APPDIR/org.maturita.Maturita.desktop"

View file

@ -21,7 +21,7 @@ APP="$ROOT/dist/$APP_NAME"
MACOS="$APP/Contents/MacOS" MACOS="$APP/Contents/MacOS"
RES="$APP/Contents/Resources" RES="$APP/Contents/Resources"
FW="$APP/Contents/Frameworks" FW="$APP/Contents/Frameworks"
ICON_512="$ROOT/share/icons/hicolor/512x512/apps/maturita.png" ICON_512="$ROOT/data/share/icons/hicolor/512x512/apps/maturita.png"
OUT_ZIP="maturita-macos-${ARCH_TAG}.zip" OUT_ZIP="maturita-macos-${ARCH_TAG}.zip"
BREW_PREFIX="$(brew --prefix 2>/dev/null || echo /opt/homebrew)" BREW_PREFIX="$(brew --prefix 2>/dev/null || echo /opt/homebrew)"
@ -34,9 +34,9 @@ rm -rf "$APP"
mkdir -p "$MACOS" "$RES/icons/hicolor/512x512/apps" "$RES/share" "$FW" mkdir -p "$MACOS" "$RES/icons/hicolor/512x512/apps" "$RES/share" "$FW"
cp -f "$ROOT/maturita" "$MACOS/maturita-bin" cp -f "$ROOT/maturita" "$MACOS/maturita-bin"
cp -f "$ROOT/style.css" "$RES/style.css" cp -f "$ROOT/data/style.css" "$RES/style.css"
cp -f "$ICON_512" "$RES/icons/hicolor/512x512/apps/maturita.png" cp -f "$ICON_512" "$RES/icons/hicolor/512x512/apps/maturita.png"
cp -R "$ROOT/share/." "$RES/share/" cp -R "$ROOT/data/share/." "$RES/share/"
# Resolve an absolute Homebrew-style dependency to a real file on disk. # Resolve an absolute Homebrew-style dependency to a real file on disk.
resolve_lib() { resolve_lib() {
@ -246,7 +246,7 @@ fi
# Developer ID + notarization is what lets a downloaded app open without # Developer ID + notarization is what lets a downloaded app open without
# System Settings. Without a certificate the bundle stays ad-hoc signed, which # System Settings. Without a certificate the bundle stays ad-hoc signed, which
# is enough for local runs but Gatekeeper still blocks internet downloads. # is enough for local runs but Gatekeeper still blocks internet downloads.
ENTITLEMENTS="$ROOT/macos/Maturita.entitlements" ENTITLEMENTS="$ROOT/data/macos/Maturita.entitlements"
pick_sign_identity() { pick_sign_identity() {
if [[ -n "${MACOS_SIGN_IDENTITY:-}" ]]; then if [[ -n "${MACOS_SIGN_IDENTITY:-}" ]]; then

View file

@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Regenerate assets/app-icon.ico and share/icons from assets/app-icon.png. """Regenerate assets/app-icon.ico and data/share/icons from assets/app-icon.png.
Uses macOS `sips` when available; otherwise requires Pillow. Uses macOS `sips` when available; otherwise requires Pillow.
Run from the repository root. Run from the repository root.
@ -71,13 +71,9 @@ def main() -> int:
print(f"wrote {ICO.relative_to(ROOT)}") print(f"wrote {ICO.relative_to(ROOT)}")
for size in SHARE_SIZES: for size in SHARE_SIZES:
dest = ROOT / "share" / "icons" / "hicolor" / f"{size}x{size}" / "apps" / "maturita.png" dest = ROOT / "data" / "share" / "icons" / "hicolor" / f"{size}x{size}" / "apps" / "maturita.png"
resize_png(SRC, dest, size) resize_png(SRC, dest, size)
print(f"wrote {dest.relative_to(ROOT)}") print(f"wrote {dest.relative_to(ROOT)}")
assets_icon = ROOT / "assets" / "icons" / "hicolor" / "512x512" / "apps" / "maturita.png"
resize_png(SRC, assets_icon, 512)
print(f"wrote {assets_icon.relative_to(ROOT)}")
return 0 return 0

View file

@ -188,6 +188,7 @@ static gboolean ui_scale_tick(GtkWidget *w, GdkFrameClock *clock,
static const char *find_app_icon_file(void) { static const char *find_app_icon_file(void) {
static const char *paths[] = { static const char *paths[] = {
ICON_FILE, ICON_FILE,
"../assets/app-icon.png",
ICON_THEME_DIR "/hicolor/512x512/apps/" ICON_NAME ".png", ICON_THEME_DIR "/hicolor/512x512/apps/" ICON_NAME ".png",
SHARE_DIR "/icons/hicolor/512x512/apps/" ICON_NAME ".png", SHARE_DIR "/icons/hicolor/512x512/apps/" ICON_NAME ".png",
ICON_FILE_ALT, ICON_FILE_ALT,

View file

@ -80,6 +80,22 @@ static gboolean dir_has_stylesheet(const char *dir) {
return ok; return ok;
} }
/* Source tree keeps runtime files in data/; installed copies put them
* next to the binary (or in Contents/Resources on macOS). */
static char *stylesheet_dir(const char *dir) {
char *child;
if (!dir || !dir[0])
return NULL;
if (dir_has_stylesheet(dir))
return g_strdup(dir);
child = g_build_filename(dir, "data", NULL);
if (dir_has_stylesheet(child))
return child;
g_free(child);
return NULL;
}
static char *macos_resources_dir(const char *exe) { static char *macos_resources_dir(const char *exe) {
char *macos_dir; char *macos_dir;
char *contents; char *contents;
@ -167,16 +183,22 @@ void setup_portable_paths(void) {
char *write_root = NULL; char *write_root = NULL;
char *cwd; char *cwd;
if (appdir && dir_has_stylesheet(appdir)) if (appdir)
data_dir = g_strdup(appdir); data_dir = stylesheet_dir(appdir);
if (!data_dir) if (!data_dir)
data_dir = macos_resources_dir(exe); data_dir = macos_resources_dir(exe);
if (!data_dir && exe_dir && dir_has_stylesheet(exe_dir)) if (!data_dir)
data_dir = g_strdup(exe_dir); data_dir = stylesheet_dir(exe_dir);
if (!data_dir && exe_dir) {
char *parent = dup_dirname(exe_dir);
data_dir = stylesheet_dir(parent);
g_free(parent);
}
cwd = g_get_current_dir(); cwd = g_get_current_dir();
if (!data_dir && dir_has_stylesheet(cwd)) if (!data_dir)
data_dir = g_strdup(cwd); data_dir = stylesheet_dir(cwd);
if (!data_dir && cwd) if (!data_dir && cwd)
data_dir = g_strdup(cwd); data_dir = g_strdup(cwd);
@ -184,10 +206,26 @@ void setup_portable_paths(void) {
write_root = dup_dirname(appimage); write_root = dup_dirname(appimage);
if (!write_root) if (!write_root)
write_root = macos_app_parent_dir(exe); write_root = macos_app_parent_dir(exe);
/* Keep progress/ at the project root when the binary lives in build/. */
if (!write_root && exe_dir) {
char *parent = dup_dirname(exe_dir);
char *from_parent = stylesheet_dir(parent);
if (from_parent) {
write_root = parent;
parent = NULL;
g_free(from_parent);
}
g_free(parent);
}
if (!write_root && exe_dir) if (!write_root && exe_dir)
write_root = g_strdup(exe_dir); write_root = g_strdup(exe_dir);
if (!write_root && data_dir) if (!write_root && data_dir) {
if (g_str_has_suffix(data_dir, G_DIR_SEPARATOR_S "data"))
write_root = dup_dirname(data_dir);
else
write_root = g_strdup(data_dir); write_root = g_strdup(data_dir);
}
if (!write_root) if (!write_root)
write_root = g_strdup("."); write_root = g_strdup(".");