diff --git a/configure.ac b/configure.ac index 1e03042cd..33e79db90 100644 --- a/configure.ac +++ b/configure.ac @@ -117,6 +117,7 @@ AC_CHECK_FUNCS(JS_NewGlobalObject XFixesCreatePointerBarrier) CFLAGS=$saved_CFLAGS LIBS=$saved_LIBS +PKG_CHECK_MODULES(GNOME_SHELL_JS, glib-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION) PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.2 gnome-desktop-3.0 >= 2.90.0 x11) PKG_CHECK_MODULES(TRAY, gtk+-3.0) PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0) diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js index 9aadb3afd..23470e153 100644 --- a/js/ui/extensionSystem.js +++ b/js/ui/extensionSystem.js @@ -8,6 +8,7 @@ const GLib = imports.gi.GLib; const Gio = imports.gi.Gio; const St = imports.gi.St; const Shell = imports.gi.Shell; +const ShellJS = imports.gi.ShellJS; const Soup = imports.gi.Soup; const Config = imports.misc.config; @@ -388,7 +389,7 @@ function loadExtension(dir, type, enabled) { let extensionModule; let extensionState = null; try { - global.add_extension_importer('imports.ui.extensionSystem.extensions', meta.uuid, dir.get_path()); + ShellJS.add_extension_importer('imports.ui.extensionSystem.extensions', meta.uuid, dir.get_path()); extensionModule = extensions[meta.uuid].extension; } catch (e) { if (stylesheetPath != null) diff --git a/src/Makefile.am b/src/Makefile.am index 6ec1f06dd..a46d779b4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -86,7 +86,7 @@ gnome_shell_cflags = \ -DJSDIR=\"$(pkgdatadir)/js\" privlibdir = $(pkglibdir) -privlib_LTLIBRARIES = libgnome-shell.la +privlib_LTLIBRARIES = libgnome-shell.la libgnome-shell-js.la shell_built_sources = \ shell-enum-types.h \ @@ -182,6 +182,23 @@ EXTRA_DIST += test-gapplication.js ######################################## +libgnome_shell_js_la_SOURCES = \ + shell-js.h \ + shell-js.c \ + $(NULL) + +libgnome_shell_js_la_LIBADD = \ + $(GNOME_SHELL_JS_LIBS) \ + $(NULL) + +libgnome_shell_js_la_LDFLAGS = \ + -avoid-version + +libgnome_shell_js_la_CPPFLAGS = \ + $(GNOME_SHELL_JS_CFLAGS) + +######################################## + shell_recorder_sources = \ shell-recorder.c \ shell-recorder.h @@ -275,6 +292,13 @@ Shell_0_1_gir_SCANNERFLAGS = --include-uninstalled=$(builddir)/St-1.0.gir \ INTROSPECTION_GIRS += Shell-0.1.gir CLEANFILES += Shell-0.1.gir +ShellJS-0.1.gir: libgnome-shell-js.la +ShellJS_0_1_gir_CFLAGS = $(libgnome_shell_la_CPPFLAGS) -I $(srcdir) +ShellJS_0_1_gir_LIBS = libgnome-shell-js.la +ShellJS_0_1_gir_FILES = $(libgnome_shell_js_la_SOURCES) +INTROSPECTION_GIRS += ShellJS-0.1.gir +CLEANFILES += ShellJS-0.1.gir + St-1.0.gir: libst-1.0.la St_1_0_gir_INCLUDES = Clutter-1.0 Gtk-3.0 St_1_0_gir_CFLAGS = $(st_cflags) -DST_COMPILATION diff --git a/src/shell-global.c b/src/shell-global.c index e41a883fb..2e7e20075 100644 --- a/src/shell-global.c +++ b/src/shell-global.c @@ -1177,70 +1177,6 @@ shell_global_destroy_pointer_barrier (ShellGlobal *global, guint32 barrier) #endif } - -/** - * shell_global_add_extension_importer: - * @target_object_script: JavaScript code evaluating to a target object - * @target_property: Name of property to use for importer - * @directory: Source directory: - * @error: A #GError - * - * This function sets a property named @target_property on the object - * resulting from the evaluation of @target_object_script code, which - * acts as a GJS importer for directory @directory. - * - * Returns: %TRUE on success - */ -gboolean -shell_global_add_extension_importer (ShellGlobal *global, - const char *target_object_script, - const char *target_property, - const char *directory, - GError **error) -{ - jsval target_object; - JSContext *context = gjs_context_get_native_context (global->js_context); - char *search_path[2] = { 0, 0 }; - - JS_BeginRequest (context); - - // This is a bit of a hack; ideally we'd be able to pass our target - // object directly into this function, but introspection doesn't - // support that at the moment. Instead evaluate a string to get it. - if (!JS_EvaluateScript(context, - JS_GetGlobalObject(context), - target_object_script, - strlen (target_object_script), - "", - 0, - &target_object)) - { - char *message; - gjs_log_exception(context, - &message); - g_set_error(error, - G_IO_ERROR, - G_IO_ERROR_FAILED, - "%s", message ? message : "(unknown)"); - g_free(message); - goto out_error; - } - - if (!JSVAL_IS_OBJECT (target_object)) - { - g_error ("shell_global_add_extension_importer: invalid target object"); - goto out_error; - } - - search_path[0] = (char*)directory; - gjs_define_importer (context, JSVAL_TO_OBJECT (target_object), target_property, (const char **)search_path, FALSE); - JS_EndRequest (context); - return TRUE; - out_error: - JS_EndRequest (context); - return FALSE; -} - /* Code to close all file descriptors before we exec; copied from gspawn.c in GLib. * * Authors: Padraig O'Briain, Matthias Clasen, Lennart Poettering diff --git a/src/shell-global.h b/src/shell-global.h index ba87f46ad..6456c9e74 100644 --- a/src/shell-global.h +++ b/src/shell-global.h @@ -119,12 +119,6 @@ void shell_global_run_at_leisure (ShellGlobal *global, /* Misc utilities / Shell API */ -gboolean shell_global_add_extension_importer (ShellGlobal *global, - const char *target_object_script, - const char *target_property, - const char *directory, - GError **error); - void shell_global_sync_pointer (ShellGlobal *global); GAppLaunchContext * diff --git a/src/shell-js.c b/src/shell-js.c new file mode 100644 index 000000000..8267fdc98 --- /dev/null +++ b/src/shell-js.c @@ -0,0 +1,81 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +#include "config.h" + +#include "shell-js.h" + +#include +#include +#include +#include + +/** + * shell_js_add_extension_importer: + * @target_object_script: JavaScript code evaluating to a target object + * @target_property: Name of property to use for importer + * @directory: Source directory: + * @error: A #GError + * + * This function sets a property named @target_property on the object + * resulting from the evaluation of @target_object_script code, which + * acts as a GJS importer for directory @directory. + * + * Returns: %TRUE on success + */ +gboolean +shell_js_add_extension_importer (const char *target_object_script, + const char *target_property, + const char *directory, + GError **error) +{ + jsval target_object; + GList *contexts; + JSContext *context; + char *search_path[2] = { 0, 0 }; + gboolean ret = FALSE; + + /* Take the first GjsContext from all of them -- + * we should only ever have one context, so this + * should be alright. */ + contexts = gjs_context_get_all (); + context = gjs_context_get_native_context (contexts->data); + g_list_free_full (contexts, g_object_unref); + + JS_BeginRequest (context); + + /* This is a bit of a hack; ideally we'd be able to pass our target + * object directly into this function, but introspection doesn't + * support that at the moment. Instead evaluate a string to get it. */ + if (!JS_EvaluateScript(context, + JS_GetGlobalObject(context), + target_object_script, + strlen (target_object_script), + "", + 0, + &target_object)) + { + char *message; + gjs_log_exception(context, + &message); + g_set_error(error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "%s", message ? message : "(unknown)"); + g_free(message); + goto out; + } + + if (!JSVAL_IS_OBJECT (target_object)) + { + g_error ("shell_js_add_extension_importer: invalid target object"); + goto out; + } + + search_path[0] = (char*)directory; + gjs_define_importer (context, JSVAL_TO_OBJECT (target_object), target_property, (const char **)search_path, FALSE); + ret = TRUE; + + out: + JS_EndRequest (context); + return ret; +} diff --git a/src/shell-js.h b/src/shell-js.h new file mode 100644 index 000000000..26cbf4d82 --- /dev/null +++ b/src/shell-js.h @@ -0,0 +1,16 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +#ifndef __SHELL_JS_H__ +#define __SHELL_JS_H__ + +#include + +G_BEGIN_DECLS + +gboolean shell_js_add_extension_importer (const char *target_object_script, + const char *target_property, + const char *directory, + GError **error); + +G_BEGIN_DECLS + +#endif /* __SHELL_JS_H__ */