Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,4 @@ docs/.jekyll-metadata
docs/.bundle/
flatpak/build/
.flatpak-builder/
Elektroid.app/
105 changes: 105 additions & 0 deletions macos-bundle.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/bin/bash
# Build a macOS .app bundle for Elektroid.
# Requires: rsvg-convert (librsvg), Homebrew GTK dependencies.
# The binary resolves its data directory at runtime from the bundle
# location, so no special configure prefix is needed.
set -euo pipefail

APP_NAME="Elektroid"
APP_BUNDLE="${APP_NAME}.app"
CONTENTS="${APP_BUNDLE}/Contents"
MACOS="${CONTENTS}/MacOS"
RESOURCES="${CONTENTS}/Resources"
SRC_DIR="$(cd "$(dirname "$0")" && pwd)"
NPROC=$(sysctl -n hw.ncpu)

cd "${SRC_DIR}"

# Build if needed
if [ ! -f src/elektroid ]; then
echo "==> Configuring..."
test -f configure || autoreconf -fi
./configure 2>&1 | tail -5
echo "==> Building..."
make -j${NPROC} 2>&1 | tail -3
fi

echo "==> Creating app bundle structure..."
rm -rf "${APP_BUNDLE}"
mkdir -p "${MACOS}" "${RESOURCES}/share/elektroid" \
"${RESOURCES}/share/icons/hicolor/scalable/apps"

# Copy binaries
cp src/elektroid "${MACOS}/elektroid-bin"
cp src/elektroid-cli "${MACOS}/"

# Copy data files
cp res/elektroid.ui res/elektroid.css res/libraries.html res/THANKS \
"${RESOURCES}/share/elektroid/"
cp -R res/elektron "${RESOURCES}/share/elektroid/"
test -d res/microbrute && cp -R res/microbrute "${RESOURCES}/share/elektroid/"
test -d res/volca_sample_2 && cp -R res/volca_sample_2 "${RESOURCES}/share/elektroid/"

# Copy icons
cp res/*.svg "${RESOURCES}/share/icons/hicolor/scalable/apps/"

# Generate .icns from SVG
echo "==> Generating app icon..."
ICONSET_DIR=$(mktemp -d)/Elektroid.iconset
mkdir -p "${ICONSET_DIR}"
SVG="res/io.github.dagargo.Elektroid.svg"

for size in 16 32 64 128 256 512; do
rsvg-convert -w ${size} -h ${size} "${SVG}" -o "${ICONSET_DIR}/icon_${size}x${size}.png"
done
for size in 32 64 128 256 512 1024; do
half=$((size / 2))
rsvg-convert -w ${size} -h ${size} "${SVG}" -o "${ICONSET_DIR}/icon_${half}x${half}@2x.png"
done
iconutil -c icns "${ICONSET_DIR}" -o "${RESOURCES}/Elektroid.icns"
rm -rf "$(dirname "${ICONSET_DIR}")"

# Create launcher script
cat > "${MACOS}/Elektroid" << 'LAUNCHER'
#!/bin/bash
DIR="$(cd "$(dirname "$0")" && pwd)"
RESOURCES="$(cd "${DIR}/../Resources" && pwd)"
export XDG_DATA_DIRS="${RESOURCES}/share:${XDG_DATA_DIRS:-/opt/homebrew/share:/usr/local/share:/usr/share}"
exec "${DIR}/elektroid-bin" "$@"
LAUNCHER
chmod +x "${MACOS}/Elektroid"

# Create Info.plist
VERSION=$(grep 'AC_INIT' configure.ac | sed 's/.*\[\([0-9.]*\)\].*/\1/')
cat > "${CONTENTS}/Info.plist" << PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>${APP_NAME}</string>
<key>CFBundleDisplayName</key>
<string>${APP_NAME}</string>
<key>CFBundleIdentifier</key>
<string>io.github.dagargo.Elektroid</string>
<key>CFBundleVersion</key>
<string>${VERSION}</string>
<key>CFBundleShortVersionString</key>
<string>${VERSION}</string>
<key>CFBundleExecutable</key>
<string>Elektroid</string>
<key>CFBundleIconFile</key>
<string>Elektroid</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>LSMinimumSystemVersion</key>
<string>11.0</string>
</dict>
</plist>
PLIST

echo "==> Done! Created ${APP_BUNDLE}"
echo " cp -r ${APP_BUNDLE} /Applications/"
echo " open /Applications/${APP_BUNDLE}"
2 changes: 1 addition & 1 deletion src/connectors/elektron.c
Original file line number Diff line number Diff line change
Expand Up @@ -4009,7 +4009,7 @@ elektron_configure_device (struct backend *backend, guint8 id)

if (err)
{
filename = strdup (DATADIR DEVICES_FILE);
filename = g_build_filename (get_data_dir (), DEVICES_FILE, NULL);
err = elektron_configure_device_from_file (backend, id, filename);
g_free (filename);
}
Expand Down
6 changes: 5 additions & 1 deletion src/connectors/volca_sample_2.c
Original file line number Diff line number Diff line change
Expand Up @@ -832,8 +832,12 @@ volca_sample_2_pattern_clear (struct backend *backend, const gchar *path)
gint err;
struct idata init_pattern;

err = file_load (DATADIR "/volca_sample_2/init_pattern.vlcsplpattb",
gchar *pattern_path = g_build_filename (get_data_dir (),
"volca_sample_2",
"init_pattern.vlcsplpattb", NULL);
err = file_load (pattern_path,
&init_pattern, NULL);
g_free (pattern_path);
if (err)
{
return err;
Expand Down
20 changes: 13 additions & 7 deletions src/elektroid.c
Original file line number Diff line number Diff line change
Expand Up @@ -1545,11 +1545,14 @@ elektroid_startup (GApplication *gapp, gpointer *user_data)
}

builder = gtk_builder_new ();
gtk_builder_add_from_file (builder, DATADIR "/elektroid.ui", NULL);
gchar *ui_path = g_build_filename (get_data_dir (), "elektroid.ui", NULL);
gtk_builder_add_from_file (builder, ui_path, NULL);
g_free (ui_path);

css_provider = gtk_css_provider_new ();
gtk_css_provider_load_from_path (css_provider, DATADIR "/elektroid.css",
NULL);
gchar *css_path = g_build_filename (get_data_dir (), "elektroid.css", NULL);
gtk_css_provider_load_from_path (css_provider, css_path, NULL);
g_free (css_path);
gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
GTK_STYLE_PROVIDER
(css_provider),
Expand All @@ -1561,11 +1564,14 @@ elektroid_startup (GApplication *gapp, gpointer *user_data)
GTK_ABOUT_DIALOG (gtk_builder_get_object (builder, "about_dialog"));
gtk_about_dialog_set_version (about_dialog, PACKAGE_VERSION);

elektroid_about_add_credit_section (_("Libraries"),
DATADIR "/libraries.html");
gchar *libraries_path = g_build_filename (get_data_dir (),
"libraries.html", NULL);
elektroid_about_add_credit_section (_("Libraries"), libraries_path);
g_free (libraries_path);

elektroid_about_add_credit_section (_("Acknowledgements"),
DATADIR "/THANKS");
gchar *thanks_path = g_build_filename (get_data_dir (), "THANKS", NULL);
elektroid_about_add_credit_section (_("Acknowledgements"), thanks_path);
g_free (thanks_path);

maction_context.box =
GTK_WIDGET (gtk_builder_get_object (builder, "menu_actions_box"));
Expand Down
6 changes: 4 additions & 2 deletions src/mactions/microbrute.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,10 @@ void
microbrute_init ()
{
GtkBuilder *builder = gtk_builder_new ();
gtk_builder_add_from_file (builder, DATADIR "/microbrute/microbrute.ui",
NULL);
gchar *mb_ui_path = g_build_filename (get_data_dir (), "microbrute",
"microbrute.ui", NULL);
gtk_builder_add_from_file (builder, mb_ui_path, NULL);
g_free (mb_ui_path);
config_window = GTK_WIDGET (gtk_builder_get_object (builder,
"config_window"));
gtk_window_resize (GTK_WINDOW (config_window), 1, 1);
Expand Down
42 changes: 42 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
#endif
#include <errno.h>
#include <math.h>
#ifdef __APPLE__
#include <mach-o/dyld.h>
#include <libgen.h>
#endif
#include "utils.h"

#define DEBUG_SHORT_HEX_LEN 64
Expand Down Expand Up @@ -188,6 +192,44 @@ get_user_dir (const char *rel_dir)
}
}

const gchar *
get_data_dir ()
{
#ifdef __APPLE__
static gchar *data_dir = NULL;
if (!data_dir)
{
char path[PATH_MAX];
uint32_t size = sizeof (path);
if (_NSGetExecutablePath (path, &size) == 0)
{
char *real = realpath (path, NULL);
if (real)
{
// Check for .app bundle: MacOS/bin -> Resources/share/elektroid
char *dir = dirname (real);
char *candidate = g_build_filename (dir, "..", "Resources",
"share", PACKAGE, NULL);
char *resolved = realpath (candidate, NULL);
g_free (candidate);
if (resolved)
{
data_dir = resolved;
}
free (real);
}
}
if (!data_dir)
{
data_dir = DATADIR;
}
}
return data_dir;
#else
return DATADIR;
#endif
}

char *
get_system_startup_path (const gchar *local_dir)
{
Expand Down
2 changes: 2 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ gint filename_get_lenght_without_ext (const gchar * name);

gchar *get_user_dir (const gchar *);

const gchar *get_data_dir ();

gchar *get_system_startup_path (const gchar *);

void free_msg (gpointer);
Expand Down