Fix g_get_user_special_dir() on macOS

This uses newer methods that support more folders such as Downloads. The
Objective-C code is in a separate file, gosxutils.m.

Based on !85 by Patrick Griffis.
This commit is contained in:
James Westman 2019-01-28 08:27:40 -06:00
parent 66f3016026
commit 11729cdc0c
3 changed files with 69 additions and 50 deletions

58
glib/gosxutils.m Normal file
View File

@ -0,0 +1,58 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 2018-2019 Patrick Griffis, James Westman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#ifndef HAVE_COCOA
#error "Can only build gutils-macos.m on MacOS"
#endif
#include <Cocoa/Cocoa.h>
#include "gutils.h"
#include "gstrfuncs.h"
static gchar *
find_folder (NSSearchPathDirectory type)
{
gchar *filename;
NSString *path;
NSArray *paths;
paths = NSSearchPathForDirectoriesInDomains (type, NSUserDomainMask, YES);
path = [paths firstObject];
if (path == nil)
{
return NULL;
}
filename = g_strdup ([path UTF8String]);
return filename;
}
void
load_user_special_dirs_macos(gchar **table)
{
table[G_USER_DIRECTORY_DESKTOP] = find_folder (NSDesktopDirectory);
table[G_USER_DIRECTORY_DOCUMENTS] = find_folder (NSDocumentDirectory);
table[G_USER_DIRECTORY_DOWNLOAD] = find_folder (NSDownloadsDirectory);
table[G_USER_DIRECTORY_MUSIC] = find_folder (NSMusicDirectory);
table[G_USER_DIRECTORY_PICTURES] = find_folder (NSPicturesDirectory);
table[G_USER_DIRECTORY_PUBLIC_SHARE] = find_folder (NSSharedPublicDirectory);
table[G_USER_DIRECTORY_TEMPLATES] = NULL;
table[G_USER_DIRECTORY_VIDEOS] = find_folder (NSMoviesDirectory);
}

View File

@ -120,10 +120,6 @@
# include <process.h> # include <process.h>
#endif #endif
#ifdef HAVE_CARBON
#include <CoreServices/CoreServices.h>
#endif
#ifdef HAVE_CODESET #ifdef HAVE_CODESET
#include <langinfo.h> #include <langinfo.h>
#endif #endif
@ -1519,56 +1515,15 @@ g_get_user_runtime_dir (void)
return user_runtime_dir; return user_runtime_dir;
} }
#ifdef HAVE_CARBON #ifdef HAVE_COCOA
static gchar * /* Implemented in gutils-macos.m */
find_folder (OSType type) void load_user_special_dirs_macos (gchar **table);
{
gchar *filename = NULL;
FSRef found;
if (FSFindFolder (kUserDomain, type, kDontCreateFolder, &found) == noErr)
{
CFURLRef url = CFURLCreateFromFSRef (kCFAllocatorSystemDefault, &found);
if (url)
{
CFStringRef path = CFURLCopyFileSystemPath (url, kCFURLPOSIXPathStyle);
if (path)
{
filename = g_strdup (CFStringGetCStringPtr (path, kCFStringEncodingUTF8));
if (! filename)
{
filename = g_new0 (gchar, CFStringGetLength (path) * 3 + 1);
CFStringGetCString (path, filename,
CFStringGetLength (path) * 3 + 1,
kCFStringEncodingUTF8);
}
CFRelease (path);
}
CFRelease (url);
}
}
return filename;
}
static void static void
load_user_special_dirs (void) load_user_special_dirs (void)
{ {
g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = find_folder (kDesktopFolderType); load_user_special_dirs_macos (g_user_special_dirs);
g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = find_folder (kDocumentsFolderType);
g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = find_folder (kDesktopFolderType); /* XXX correct ? */
g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = find_folder (kMusicDocumentsFolderType);
g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = find_folder (kPictureDocumentsFolderType);
g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = NULL;
g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = NULL;
g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = find_folder (kMovieDocumentsFolderType);
} }
#elif defined(G_OS_WIN32) #elif defined(G_OS_WIN32)

View File

@ -230,6 +230,10 @@ else
platform_deps = [] platform_deps = []
endif endif
if host_system == 'darwin'
glib_sources += files('gosxutils.m')
endif
glib_sources += files('gthread-@0@.c'.format(threads_implementation)) glib_sources += files('gthread-@0@.c'.format(threads_implementation))
if enable_dtrace if enable_dtrace
@ -254,6 +258,7 @@ else
pcre_objects = [libpcre.extract_all_objects()] pcre_objects = [libpcre.extract_all_objects()]
endif endif
glib_c_args = ['-DG_LOG_DOMAIN="GLib"', '-DGLIB_COMPILATION'] + pcre_static_args + glib_hidden_visibility_args
libglib = library('glib-2.0', libglib = library('glib-2.0',
glib_dtrace_obj, glib_dtrace_hdr, glib_dtrace_obj, glib_dtrace_hdr,
sources : [deprecated_sources, glib_sources], sources : [deprecated_sources, glib_sources],
@ -266,7 +271,8 @@ libglib = library('glib-2.0',
link_args : [noseh_link_args, glib_link_flags, win32_ldflags], link_args : [noseh_link_args, glib_link_flags, win32_ldflags],
include_directories : configinc, include_directories : configinc,
dependencies : pcre_deps + [thread_dep, libintl, librt] + libiconv + platform_deps, dependencies : pcre_deps + [thread_dep, libintl, librt] + libiconv + platform_deps,
c_args : ['-DG_LOG_DOMAIN="GLib"', '-DGLIB_COMPILATION'] + pcre_static_args + glib_hidden_visibility_args c_args : glib_c_args,
objc_args : glib_c_args,
) )
libglib_dep = declare_dependency( libglib_dep = declare_dependency(