[geany/geany] 18d517: Use gtk-mac-integration so app bundle can be created on OS X

Jiří Techet git-noreply at xxxxx
Wed Mar 4 11:40:27 UTC 2015


Branch:      refs/heads/master
Author:      Jiří Techet <techet at gmail.com>
Committer:   Jiří Techet <techet at gmail.com>
Date:        Wed, 04 Mar 2015 11:40:27 UTC
Commit:      18d517bd95ea29cb04e7652631c56a0376e6f098
             https://github.com/geany/geany/commit/18d517bd95ea29cb04e7652631c56a0376e6f098

Log Message:
-----------
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.


Modified Paths:
--------------
    configure.ac
    m4/geany-mac-integration.m4
    src/Makefile.am
    src/main.c
    src/osx.h
    src/plugins.c
    src/utils.c
    src/utils.h
    wscript

Modified: configure.ac
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -105,6 +105,7 @@ GEANY_CHECK_MINGW
 
 GEANY_CHECK_SOCKET
 GEANY_CHECK_VTE
+GEANY_CHECK_MAC_INTEGRATION
 GEANY_CHECK_THE_FORCE dnl hehe
 
 # i18n


Modified: m4/geany-mac-integration.m4
18 lines changed, 18 insertions(+), 0 deletions(-)
===================================================================
@@ -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)])
+	])
+])


Modified: src/Makefile.am
4 lines changed, 3 insertions(+), 1 deletions(-)
===================================================================
@@ -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)"\" \


Modified: src/main.c
64 lines changed, 17 insertions(+), 47 deletions(-)
===================================================================
@@ -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;
 }


Modified: src/osx.h
30 lines changed, 30 insertions(+), 0 deletions(-)
===================================================================
@@ -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 */


Modified: src/plugins.c
12 lines changed, 1 insertions(+), 11 deletions(-)
===================================================================
@@ -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));
 }
 
 


Modified: src/utils.c
59 lines changed, 59 insertions(+), 0 deletions(-)
===================================================================
@@ -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];
+}


Modified: src/utils.h
14 lines changed, 14 insertions(+), 0 deletions(-)
===================================================================
@@ -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


Modified: wscript
9 lines changed, 8 insertions(+), 1 deletions(-)
===================================================================
@@ -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



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Commits mailing list