Use gtk-mac-integration so app bundle can be created on OS X
This patch adds the gtk-mac-integration library and uses it to adjust various paths in Geany to point it inside the app bundle if Geany runs from inside the bundle. It adds the utils_resource_dir() utility function to return correct directories for various kinds of resources for all supported operating systems. Using this function the patch adjusts all Geany resource, plugin, icon, doc, and locale paths.
This commit is contained in:
parent
87af9597fc
commit
18d517bd95
@ -105,6 +105,7 @@ GEANY_CHECK_MINGW
|
||||
|
||||
GEANY_CHECK_SOCKET
|
||||
GEANY_CHECK_VTE
|
||||
GEANY_CHECK_MAC_INTEGRATION
|
||||
GEANY_CHECK_THE_FORCE dnl hehe
|
||||
|
||||
# i18n
|
||||
|
18
m4/geany-mac-integration.m4
Normal file
18
m4/geany-mac-integration.m4
Normal file
@ -0,0 +1,18 @@
|
||||
dnl GEANY_CHECK_MAC_INTEGRATION
|
||||
dnl Check for gtk-mac-integration to enable improved OS X integration
|
||||
dnl
|
||||
AC_DEFUN([GEANY_CHECK_MAC_INTEGRATION],
|
||||
[
|
||||
AC_ARG_ENABLE([mac-integration],
|
||||
[AS_HELP_STRING([--enable-mac-integration],
|
||||
[use gtk-mac-integration to enable improved OS X integration [default=no]])],
|
||||
[geany_enable_mac_integration="$enableval"],
|
||||
[geany_enable_mac_integration="no"])
|
||||
|
||||
AS_IF([test "x$geany_enable_mac_integration" = "xyes"],
|
||||
[
|
||||
AS_IF([test "x$enable_gtk3" = xyes],
|
||||
[PKG_CHECK_MODULES(MAC_INTEGRATION, gtk-mac-integration-gtk3)],
|
||||
[PKG_CHECK_MODULES(MAC_INTEGRATION, gtk-mac-integration-gtk2)])
|
||||
])
|
||||
])
|
@ -10,6 +10,7 @@ EXTRA_DIST = \
|
||||
keybindingsprivate.h \
|
||||
pluginprivate.h \
|
||||
projectprivate.h \
|
||||
osx.h \
|
||||
makefile.win32
|
||||
|
||||
bin_PROGRAMS = geany
|
||||
@ -89,7 +90,7 @@ AM_CPPFLAGS = \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_srcdir)/scintilla/include \
|
||||
-I$(top_srcdir)/tagmanager/src \
|
||||
@GTK_CFLAGS@ @GTHREAD_CFLAGS@
|
||||
@GTK_CFLAGS@ @GTHREAD_CFLAGS@ $(MAC_INTEGRATION_CFLAGS)
|
||||
|
||||
# tell automake we have a C++ file so it uses the C++ linker we need for Scintilla
|
||||
nodist_EXTRA_geany_SOURCES = dummy.cxx
|
||||
@ -142,6 +143,7 @@ geany_LDADD = \
|
||||
$(top_builddir)/tagmanager/src/libtagmanager.a \
|
||||
@GTK_LIBS@ \
|
||||
@GTHREAD_LIBS@ \
|
||||
$(MAC_INTEGRATION_LIBS) \
|
||||
$(INTLLIBS)
|
||||
|
||||
AM_CFLAGS = -DGEANY_DATADIR=\""$(datadir)"\" \
|
||||
|
64
src/main.c
64
src/main.c
@ -62,6 +62,7 @@
|
||||
#include "utils.h"
|
||||
#include "vte.h"
|
||||
#include "win32.h"
|
||||
#include "osx.h"
|
||||
|
||||
#include "gtkcompat.h"
|
||||
|
||||
@ -224,16 +225,7 @@ static void apply_settings(void)
|
||||
static void main_init(void)
|
||||
{
|
||||
/* add our icon path in case we aren't installed in the system prefix */
|
||||
gchar *path;
|
||||
#ifdef G_OS_WIN32
|
||||
gchar *install_dir = win32_get_installation_dir();
|
||||
path = g_build_filename(install_dir, "share", "icons", NULL);
|
||||
g_free(install_dir);
|
||||
#else
|
||||
path = g_build_filename(GEANY_DATADIR, "icons", NULL);
|
||||
#endif
|
||||
gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), path);
|
||||
g_free(path);
|
||||
gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), utils_resource_dir(RESOURCE_DIR_ICON));
|
||||
|
||||
/* inits */
|
||||
ui_init_stock_items();
|
||||
@ -400,30 +392,9 @@ static void change_working_directory_on_windows(void)
|
||||
|
||||
static void setup_paths(void)
|
||||
{
|
||||
gchar *data_dir;
|
||||
gchar *doc_dir;
|
||||
|
||||
/* set paths */
|
||||
#ifdef G_OS_WIN32
|
||||
/* use the installation directory(the one where geany.exe is located) as the base for the
|
||||
* documentation and data files */
|
||||
gchar *install_dir = win32_get_installation_dir();
|
||||
|
||||
data_dir = g_build_filename(install_dir, "data", NULL); /* e.g. C:\Program Files\geany\data */
|
||||
doc_dir = g_build_filename(install_dir, "doc", NULL);
|
||||
|
||||
g_free(install_dir);
|
||||
#else
|
||||
data_dir = g_build_filename(GEANY_DATADIR, "geany", NULL); /* e.g. /usr/share/geany */
|
||||
doc_dir = g_build_filename(GEANY_DOCDIR, "html", NULL);
|
||||
#endif
|
||||
|
||||
/* convert path names to locale encoding */
|
||||
app->datadir = utils_get_locale_from_utf8(data_dir);
|
||||
app->docdir = utils_get_locale_from_utf8(doc_dir);
|
||||
|
||||
g_free(data_dir);
|
||||
g_free(doc_dir);
|
||||
app->datadir = utils_get_locale_from_utf8(utils_resource_dir(RESOURCE_DIR_DATA));
|
||||
app->docdir = utils_get_locale_from_utf8(utils_resource_dir(RESOURCE_DIR_DOC));
|
||||
}
|
||||
|
||||
|
||||
@ -473,26 +444,15 @@ gboolean main_is_realized(void)
|
||||
**/
|
||||
void main_locale_init(const gchar *locale_dir, const gchar *package)
|
||||
{
|
||||
gchar *l_locale_dir = NULL;
|
||||
|
||||
#ifdef HAVE_LOCALE_H
|
||||
setlocale(LC_ALL, "");
|
||||
#endif
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
{
|
||||
gchar *install_dir = win32_get_installation_dir();
|
||||
/* e.g. C:\Program Files\geany\lib\locale */
|
||||
l_locale_dir = g_build_filename(install_dir, "share", "locale", NULL);
|
||||
g_free(install_dir);
|
||||
}
|
||||
#else
|
||||
l_locale_dir = g_strdup(locale_dir);
|
||||
locale_dir = utils_resource_dir(RESOURCE_DIR_LOCALE);
|
||||
#endif
|
||||
|
||||
(void) bindtextdomain(package, l_locale_dir);
|
||||
(void) bindtextdomain(package, locale_dir);
|
||||
(void) bind_textdomain_codeset(package, "UTF-8");
|
||||
g_free(l_locale_dir);
|
||||
}
|
||||
|
||||
|
||||
@ -647,6 +607,11 @@ static void parse_command_line_options(gint *argc, gchar ***argv)
|
||||
g_printerr("Geany: cannot open display\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef MAC_INTEGRATION
|
||||
/* Create GtkosxApplication singleton - should be created shortly after gtk_init() */
|
||||
gtkosx_application_get();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -1059,7 +1024,7 @@ gint main(gint argc, gchar **argv)
|
||||
setup_gtk2_styles();
|
||||
#endif
|
||||
#ifdef ENABLE_NLS
|
||||
main_locale_init(GEANY_LOCALEDIR, GETTEXT_PACKAGE);
|
||||
main_locale_init(utils_resource_dir(RESOURCE_DIR_LOCALE), GETTEXT_PACKAGE);
|
||||
#endif
|
||||
parse_command_line_options(&argc, &argv);
|
||||
|
||||
@ -1233,6 +1198,11 @@ gint main(gint argc, gchar **argv)
|
||||
* tell other components, mainly plugins, that startup is complete */
|
||||
g_idle_add_full(G_PRIORITY_LOW, send_startup_complete, NULL, NULL);
|
||||
|
||||
#ifdef MAC_INTEGRATION
|
||||
/* OS X application ready - has to be called before entering main loop */
|
||||
gtkosx_application_ready(gtkosx_application_get());
|
||||
#endif
|
||||
|
||||
gtk_main();
|
||||
return 0;
|
||||
}
|
||||
|
30
src/osx.h
Normal file
30
src/osx.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* osx.h - this file is part of Geany, a fast and lightweight IDE
|
||||
*
|
||||
* Copyright 2015 Jiri Techet <techet(at)gmail(dot)com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef GEANY_OSX_H
|
||||
#define GEANY_OSX_H 1
|
||||
|
||||
#ifdef MAC_INTEGRATION
|
||||
|
||||
#include <gtkosxapplication.h>
|
||||
|
||||
#endif /* MAC_INTEGRATION */
|
||||
|
||||
#endif /* GEANY_OSX_H */
|
@ -999,17 +999,7 @@ load_plugins_from_path(const gchar *path)
|
||||
|
||||
static gchar *get_plugin_path(void)
|
||||
{
|
||||
#ifdef G_OS_WIN32
|
||||
gchar *path;
|
||||
gchar *install_dir = win32_get_installation_dir();
|
||||
|
||||
path = g_build_filename(install_dir, "lib", NULL);
|
||||
g_free(install_dir);
|
||||
|
||||
return path;
|
||||
#else
|
||||
return g_build_filename(GEANY_LIBDIR, "geany", NULL);
|
||||
#endif
|
||||
return g_strdup(utils_resource_dir(RESOURCE_DIR_PLUGIN));
|
||||
}
|
||||
|
||||
|
||||
|
59
src/utils.c
59
src/utils.c
@ -38,6 +38,7 @@
|
||||
#include "templates.h"
|
||||
#include "ui_utils.h"
|
||||
#include "win32.h"
|
||||
#include "osx.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
@ -2088,3 +2089,61 @@ gchar *utils_get_user_config_dir(void)
|
||||
return g_build_filename(g_get_user_config_dir(), "geany", NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static gboolean is_osx_bundle(void)
|
||||
{
|
||||
#ifdef MAC_INTEGRATION
|
||||
gchar *bundle_id = gtkosx_application_get_bundle_id();
|
||||
if (bundle_id)
|
||||
{
|
||||
g_free(bundle_id);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
const gchar *utils_resource_dir(GeanyResourceDirType type)
|
||||
{
|
||||
static const gchar *resdirs[RESOURCE_DIR_COUNT] = {NULL};
|
||||
|
||||
if (!resdirs[RESOURCE_DIR_DATA])
|
||||
{
|
||||
#ifdef G_OS_WIN32
|
||||
gchar *prefix = win32_get_installation_dir();
|
||||
|
||||
resdirs[RESOURCE_DIR_DATA] = g_build_filename(prefix, "data", NULL);
|
||||
resdirs[RESOURCE_DIR_ICON] = g_build_filename(prefix, "share", "icons", NULL);
|
||||
resdirs[RESOURCE_DIR_DOC] = g_build_filename(prefix, "doc", NULL);
|
||||
resdirs[RESOURCE_DIR_LOCALE] = g_build_filename(prefix, "share", "locale", NULL);
|
||||
resdirs[RESOURCE_DIR_PLUGIN] = g_build_filename(prefix, "lib", NULL);
|
||||
g_free(prefix);
|
||||
#else
|
||||
if (is_osx_bundle())
|
||||
{
|
||||
# ifdef MAC_INTEGRATION
|
||||
gchar *prefix = gtkosx_application_get_resource_path();
|
||||
|
||||
resdirs[RESOURCE_DIR_DATA] = g_build_filename(prefix, "share", "geany", NULL);
|
||||
resdirs[RESOURCE_DIR_ICON] = g_build_filename(prefix, "share", "icons", NULL);
|
||||
resdirs[RESOURCE_DIR_DOC] = g_build_filename(prefix, "share", "doc", "geany", "html", NULL);
|
||||
resdirs[RESOURCE_DIR_LOCALE] = g_build_filename(prefix, "share", "locale", NULL);
|
||||
resdirs[RESOURCE_DIR_PLUGIN] = g_build_filename(prefix, "lib", "geany", NULL);
|
||||
g_free(prefix);
|
||||
# endif
|
||||
}
|
||||
else
|
||||
{
|
||||
resdirs[RESOURCE_DIR_DATA] = g_build_filename(GEANY_DATADIR, "geany", NULL);
|
||||
resdirs[RESOURCE_DIR_ICON] = g_build_filename(GEANY_DATADIR, "icons", NULL);
|
||||
resdirs[RESOURCE_DIR_DOC] = g_build_filename(GEANY_DOCDIR, "html", NULL);
|
||||
resdirs[RESOURCE_DIR_LOCALE] = g_build_filename(GEANY_LOCALEDIR, NULL);
|
||||
resdirs[RESOURCE_DIR_PLUGIN] = g_build_filename(GEANY_LIBDIR, "geany", NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return resdirs[type];
|
||||
}
|
||||
|
14
src/utils.h
14
src/utils.h
@ -200,6 +200,18 @@ const gchar *utils_find_open_xml_tag_pos(const gchar sel[], gint size);
|
||||
|
||||
#ifdef GEANY_PRIVATE
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RESOURCE_DIR_DATA,
|
||||
RESOURCE_DIR_ICON,
|
||||
RESOURCE_DIR_DOC,
|
||||
RESOURCE_DIR_LOCALE,
|
||||
RESOURCE_DIR_PLUGIN,
|
||||
|
||||
RESOURCE_DIR_COUNT
|
||||
} GeanyResourceDirType;
|
||||
|
||||
|
||||
gint utils_get_line_endings(const gchar* buffer, gsize size);
|
||||
|
||||
gboolean utils_isbrace(gchar c, gboolean include_angles);
|
||||
@ -294,6 +306,8 @@ gchar *utils_parse_and_format_build_date(const gchar *input);
|
||||
|
||||
gchar *utils_get_user_config_dir(void);
|
||||
|
||||
const gchar *utils_resource_dir(GeanyResourceDirType type);
|
||||
|
||||
#endif /* GEANY_PRIVATE */
|
||||
|
||||
G_END_DECLS
|
||||
|
9
wscript
9
wscript
@ -226,6 +226,10 @@ def configure(conf):
|
||||
conf.check_cfg(package='gio-2.0', uselib_store='GIO', args='--cflags --libs', mandatory=True)
|
||||
gtk_version = conf.check_cfg(modversion=gtk_package_name, uselib_store='GTK') or 'Unknown'
|
||||
conf.check_cfg(package='gthread-2.0', uselib_store='GTHREAD', args='--cflags --libs')
|
||||
if conf.options.enable_mac_integration:
|
||||
pkgname = 'gtk-mac-integration-gtk3' if conf.options.use_gtk3 else 'gtk-mac-integration-gtk2'
|
||||
conf.check_cfg(package=pkgname, uselib_store='MAC_INTEGRATION',
|
||||
mandatory=True, args='--cflags --libs')
|
||||
# remember GTK version for the build step
|
||||
conf.env['gtk_package_name'] = gtk_package_name
|
||||
conf.env['minimum_gtk_version'] = minimum_gtk_version
|
||||
@ -347,6 +351,9 @@ def options(opt):
|
||||
opt.add_option('--enable-gtk3', action='store_true', default=False,
|
||||
help='compile with GTK3 support (experimental) [[default: No]',
|
||||
dest='use_gtk3')
|
||||
opt.add_option('--enable-mac-integration', action='store_true', default=False,
|
||||
help='use gtk-mac-integration to enable improved OS X integration [[default: No]',
|
||||
dest='enable_mac_integration')
|
||||
opt.add_option('--disable-html-docs', action='store_true', default=False,
|
||||
help='do not generate HTML documentation using rst2html [[default: No]',
|
||||
dest='no_html_doc')
|
||||
@ -441,7 +448,7 @@ def build(bld):
|
||||
source = geany_sources,
|
||||
includes = ['.', 'scintilla/include', 'tagmanager/src'],
|
||||
defines = ['G_LOG_DOMAIN="Geany"', 'GEANY_PRIVATE'],
|
||||
uselib = ['GTK', 'GLIB', 'GMODULE', 'GIO', 'GTHREAD', 'WIN32', 'SUNOS_SOCKET', 'M'],
|
||||
uselib = ['GTK', 'GLIB', 'GMODULE', 'GIO', 'GTHREAD', 'WIN32', 'MAC_INTEGRATION', 'SUNOS_SOCKET', 'M'],
|
||||
use = ['scintilla', 'ctags', 'tagmanager', 'mio'])
|
||||
|
||||
# geanyfunctions.h
|
||||
|
Loading…
x
Reference in New Issue
Block a user