plug-ins, extension: goat-exercises becomes a GIMP extension.

This is an extension containing a few demo plug-ins. This is good to
demonstrate the extension format. It will also allow to disable these
plug-ins (if at some point, one doesn't want to show these demo
plug-ins anymore).

And finally it deals with the fact that our plug-in code is stupid, as
it just tries to find the first executable with the same name (minus
extension) as the plug-in folder. This doesn't go well on Windows, where
the permission system is non-existent. So our code just ends up trying
to run the first file with a similar name in a plug-in folder. As the C
goat-exercise contains both an exe and the C source (and the system
probably returns files in alphabetic order), GIMP under Windows tries to
run the C source instead of the executable (this obviously doesn't go
well).
We could try to do more complex logics, like not aborting if the first
file run fails and try the next one in the plug-in folder. Or maybe just
rename the C file to another name. But any of these is just in the end
the proof that our plug-in discovery right now is just bogus. The
extension system is explicit, not based on randomly trying out files.
Plug-ins entry points are explicitly listed in the metadata manifest.
This commit is contained in:
Jehan 2020-10-08 13:58:19 +02:00
parent 45fb76beb4
commit ecbc38f9e9
23 changed files with 213 additions and 102 deletions

View File

@ -35,6 +35,7 @@ SUBDIRS = \
app-tools \ app-tools \
$(GIMP_MODULES) \ $(GIMP_MODULES) \
$(GIMP_PLUGINS) \ $(GIMP_PLUGINS) \
$(GIMP_EXTENSIONS) \
etc \ etc \
devel-docs \ devel-docs \
docs \ docs \

View File

@ -2263,6 +2263,8 @@ PKG_CHECK_MODULES(JSON_GLIB, json-glib-1.0 >= json_glib_required_version,,
# Check for python runtime dependencies # Check for python runtime dependencies
####################################### #######################################
GOAT_EXERCISES="goat-exercise-c$BUILD_EXEEXT"
# By default, we want packagers to install Python plug-ins to get the # By default, we want packagers to install Python plug-ins to get the
# optimum experience. --with-python=yes will check for a Python 3 # optimum experience. --with-python=yes will check for a Python 3
# interpreter and PyGObject, and fails without. # interpreter and PyGObject, and fails without.
@ -2331,6 +2333,8 @@ if test "x$with_python" = "xyes"; then
PYBIN_PATH="$PYTHON" PYBIN_PATH="$PYTHON"
fi fi
AC_SUBST(PYBIN_PATH) AC_SUBST(PYBIN_PATH)
GOAT_EXERCISES="$GOAT_EXERCISES:goat-exercise-py3.py"
fi fi
AM_CONDITIONAL(HAS_PYTHON_INTERP, test "x$PYBIN_PATH" != "x") AM_CONDITIONAL(HAS_PYTHON_INTERP, test "x$PYBIN_PATH" != "x")
AM_CONDITIONAL(BUILD_PYTHON, test "x$with_python" != xno) AM_CONDITIONAL(BUILD_PYTHON, test "x$with_python" != xno)
@ -2378,6 +2382,10 @@ else
fi fi
fi fi
if test "x$with_javascript" = "xyes"; then
GOAT_EXERCISES="$GOAT_EXERCISES:goat-exercise-gjs.js"
fi
AM_CONDITIONAL(HAS_JAVASCRIPT_INTERP, test "x$GJS" != "xno") AM_CONDITIONAL(HAS_JAVASCRIPT_INTERP, test "x$GJS" != "xno")
AM_CONDITIONAL(BUILD_JAVASCRIPT, test "x$with_javascript" != xno) AM_CONDITIONAL(BUILD_JAVASCRIPT, test "x$with_javascript" != xno)
@ -2424,6 +2432,10 @@ else
fi fi
fi fi
if test "x$with_lua" = "xyes"; then
GOAT_EXERCISES="$GOAT_EXERCISES:goat-exercise-lua.lua"
fi
AM_CONDITIONAL(HAS_LUA_INTERP, test "x$LUA" != "xno") AM_CONDITIONAL(HAS_LUA_INTERP, test "x$LUA" != "xno")
AM_CONDITIONAL(BUILD_LUA, test "x$with_lua" != xno) AM_CONDITIONAL(BUILD_LUA, test "x$with_lua" != xno)
@ -2450,7 +2462,12 @@ else
fi fi
fi fi
if test "x$with_vala" = "xyes"; then
GOAT_EXERCISES="$GOAT_EXERCISES:goat-exercise-vala$BUILD_EXEEXT"
fi
AM_CONDITIONAL(BUILD_VALA, test "x$with_vala" != xno) AM_CONDITIONAL(BUILD_VALA, test "x$with_vala" != xno)
AC_SUBST(GOAT_EXERCISES)
########################################################### ###########################################################
# Some plug-ins don't build on Win32, others are Win32-only # Some plug-ins don't build on Win32, others are Win32-only
@ -2862,8 +2879,10 @@ fi
################## ##################
# easy way to skip the plug-in build # easy way to skip the plug-in build
GIMP_EXTENSIONS=extensions
GIMP_PLUGINS=plug-ins GIMP_PLUGINS=plug-ins
GIMP_MODULES=modules GIMP_MODULES=modules
AC_SUBST(GIMP_EXTENSIONS)
AC_SUBST(GIMP_PLUGINS) AC_SUBST(GIMP_PLUGINS)
AC_SUBST(GIMP_MODULES) AC_SUBST(GIMP_MODULES)
@ -3015,6 +3034,9 @@ build/windows/gimp.rc
build/windows/gimp-plug-ins.rc build/windows/gimp-plug-ins.rc
build/windows/installer/Makefile build/windows/installer/Makefile
build/windows/installer/lang/Makefile build/windows/installer/lang/Makefile
extensions/Makefile
extensions/goat-exercises/Makefile
extensions/goat-exercises/org.gimp.extension.goat-exercises.metainfo.xml.in
plug-ins/Makefile plug-ins/Makefile
plug-ins/file-bmp/Makefile plug-ins/file-bmp/Makefile
plug-ins/file-dds/Makefile plug-ins/file-dds/Makefile
@ -3064,7 +3086,6 @@ plug-ins/script-fu/tinyscheme/Makefile
plug-ins/selection-to-path/Makefile plug-ins/selection-to-path/Makefile
plug-ins/twain/Makefile plug-ins/twain/Makefile
plug-ins/common/Makefile plug-ins/common/Makefile
plug-ins/goat-exercises/Makefile
modules/Makefile modules/Makefile
devel-docs/Makefile devel-docs/Makefile
devel-docs/version devel-docs/version

2
extensions/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/Makefile.in
/Makefile

2
extensions/Makefile.am Normal file
View File

@ -0,0 +1,2 @@
SUBDIRS = \
goat-exercises

View File

@ -36,12 +36,14 @@ AM_CPPFLAGS = \
# C version. # C version.
goat_exercise_c_libexecdir = $(gimpplugindir)/plug-ins/goat-exercise-c goat_exercise_c_libexecdir = $(gimpplugindir)/extensions/org.gimp.extension.goat-exercises
goat_exercise_c_datadir = $(goat_exercise_c_libexecdir) goat_exercise_c_datadir = $(goat_exercise_c_libexecdir)
goat_exercise_c_libexec_PROGRAMS = goat-exercise-c goat_exercise_c_libexec_PROGRAMS = goat-exercise-c
goat_exercise_c_libexec_DATA = goat-exercise-c.c goat_exercise_c_libexec_DATA = goat-exercise-c.c
PLUG_INS = 'goat-exercise-c$(EXEEXT)'
goat_exercise_c_SOURCES = \ goat_exercise_c_SOURCES = \
goat-exercise-c.c goat-exercise-c.c
@ -64,21 +66,21 @@ goat_exercise_c_LDADD = \
# Javascript (GJS) version. # Javascript (GJS) version.
if BUILD_JAVASCRIPT if BUILD_JAVASCRIPT
goat_exercise_gjsdir = $(gimpplugindir)/plug-ins/goat-exercise-gjs goat_exercise_gjsdir = $(goat_exercise_c_libexecdir)
goat_exercise_gjs_SCRIPTS = goat-exercise-gjs.js goat_exercise_gjs_SCRIPTS = goat-exercise-gjs.js
endif endif
# Lua (lua-jit + LGI) version. # Lua (lua-jit + LGI) version.
if BUILD_LUA if BUILD_LUA
goat_exercise_luadir = $(gimpplugindir)/plug-ins/goat-exercise-lua goat_exercise_luadir = $(goat_exercise_c_libexecdir)
goat_exercise_lua_SCRIPTS = goat-exercise-lua.lua goat_exercise_lua_SCRIPTS = goat-exercise-lua.lua
endif endif
# Python 3 (pygobject) version. # Python 3 (pygobject) version.
if BUILD_PYTHON if BUILD_PYTHON
goat_exercise_py3dir = $(gimpplugindir)/plug-ins/goat-exercise-py3 goat_exercise_py3dir = $(goat_exercise_c_libexecdir)
goat_exercise_py3_SCRIPTS = goat-exercise-py3.py goat_exercise_py3_SCRIPTS = goat-exercise-py3.py
endif endif
@ -86,7 +88,7 @@ endif
if ENABLE_VAPIGEN if ENABLE_VAPIGEN
goat_exercise_vala_libexecdir = $(gimpplugindir)/plug-ins/goat-exercise-vala goat_exercise_vala_libexecdir = $(goat_exercise_c_libexecdir)
goat_exercise_vala_datadir = $(goat_exercise_vala_libexecdir) goat_exercise_vala_datadir = $(goat_exercise_vala_libexecdir)
goat_exercise_vala_libexec_PROGRAMS = goat-exercise-vala goat_exercise_vala_libexec_PROGRAMS = goat-exercise-vala
@ -118,7 +120,20 @@ goat_exercise_vala_VALAFLAGS = \
endif endif
appstream_in_files = \
org.gimp.extension.goat-exercises.metainfo.xml.in
appstream_files = $(appstream_in_files:.xml.in=.xml)
appdatadir = $(goat_exercise_c_libexecdir)
appdata_DATA = $(appstream_files)
@INTLTOOL_XML_RULE@
EXTRA_DIST = \ EXTRA_DIST = \
goat-exercise-gjs.js \ goat-exercise-gjs.js \
goat-exercise-lua.lua \ goat-exercise-lua.lua \
goat-exercise-py3.py goat-exercise-py3.py \
$(appstream_in_files)
DISTCLEANFILES = $(appstream_files)

View File

@ -193,8 +193,8 @@ goat_run (GimpProcedure *procedure,
gtk_widget_set_vexpand (GTK_WIDGET (scrolled), TRUE); gtk_widget_set_vexpand (GTK_WIDGET (scrolled), TRUE);
gtk_widget_show (scrolled); gtk_widget_show (scrolled);
path = g_build_filename (gimp_plug_in_directory (), "plug-ins", path = g_build_filename (gimp_plug_in_directory (), "extensions",
PLUG_IN_BINARY, PLUG_IN_SOURCE, "org.gimp.extension.goat-exercises", PLUG_IN_SOURCE,
NULL); NULL);
file = g_file_new_for_path (path); file = g_file_new_for_path (path);
g_free (path); g_free (path);

View File

@ -91,7 +91,7 @@ public class Goat : Gimp.PlugIn {
label.show(); label.show();
string file = Path.build_filename(Gimp.PlugIn.directory(), "plug-ins", PLUG_IN_BINARY, PLUG_IN_SOURCE); string file = Path.build_filename(Gimp.PlugIn.directory(), "extensions", "org.gimp.extension.goat-exercises", PLUG_IN_SOURCE);
string contents; string contents;
try { try {
FileUtils.get_contents(file, out contents); FileUtils.get_contents(file, out contents);

View File

@ -0,0 +1,122 @@
# C version
extension_name = 'org.gimp.extension.goat-exercises'
plug_in_name = 'goat-exercise'
plugin_sources = [
'goat-exercise-c.c',
]
if platform_windows
plugin_sources += windows.compile_resources(
gimp_plugins_rc,
args: [
'--define', 'ORIGINALFILENAME_STR="@0@"'.format(plug_in_name + '-c.exe'),
'--define', 'INTERNALNAME_STR="@0@"' .format(plug_in_name),
'--define', 'TOP_SRCDIR="@0@"' .format(meson.source_root()),
],
include_directories: [
rootInclude, appInclude,
],
)
endif
exe = executable(plug_in_name + '-c',
plugin_sources,
dependencies: [
libgimpui_dep,
math,
],
install: true,
install_dir: gimpplugindir / 'extensions' / extension_name,
)
# XXX This is so ugly!
# From meson 0.54.0, we will be able to use exe.name().
plug_ins = exe.full_path().split('/')[-1].split('\\')[-1]
install_data(
'goat-exercise-c.c',
install_dir: gimpplugindir / 'extensions' / extension_name,
)
# Vala version
if have_vala
exe = executable('goat-exercise-vala',
'goat-exercise-vala.vala',
include_directories: [ rootInclude, ],
dependencies: [
libgimp_vapi, libgimpui_vapi, gtk3, gegl, math,
],
c_args: [
'-DGETTEXT_PACKAGE="@0@"'.format(gettext_package),
],
install: true,
install_dir: gimpplugindir / 'extensions' / extension_name,
)
plug_ins = plug_ins + ':' + exe.full_path().split('/')[-1].split('\\')[-1]
install_data(
'goat-exercise-vala.vala',
install_dir: gimpplugindir / 'extensions' / extension_name,
)
endif
# Python 3 (pygobject) version.
if have_python
install_data(
'goat-exercise-py3.py',
install_dir: gimpplugindir / 'extensions' / extension_name,
)
plug_ins = plug_ins + ':goat-exercise-py3.py'
endif
# Javascript (GJS) version.
if have_javascript
install_data(
'goat-exercise-gjs.js',
install_dir: gimpplugindir / 'extensions' / extension_name,
)
plug_ins = plug_ins + ':goat-exercise-gjs.js'
endif
# Lua (lua-jit + LGI) version.
if have_lua
install_data(
'goat-exercise-lua.lua',
install_dir: gimpplugindir / 'extensions' / extension_name,
)
plug_ins = plug_ins + ':goat-exercise-lua.lua'
endif
# Generate the AppData.
conf = configuration_data()
conf.set('GOAT_EXERCISES', plug_ins)
appdatafilename = 'org.gimp.extension.goat-exercises.metainfo.xml'
appdatafilein = configure_file(
input : appdatafilename + '.in.in',
output: appdatafilename + '.in',
configuration: conf,
)
appdatafile = custom_target(appdatafilename,
input : [ appdatafilein, ],
output: [ appdatafilename, ],
command: [
intltool_merge,
po_dir,
'@INPUT@',
'@OUTPUT@',
'--xml-style',
'--utf8',
'--cache=' + '@OUTDIR@' / 'intltool-merge-cache',
],
install: true,
install_dir: gimpplugindir / 'extensions' / extension_name,
)

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="addon">
<id>org.gimp.extension.goat-exercises</id>
<extends>org.gimp.GIMP</extends>
<_name>Goat Exercises</_name>
<_summary>Official Demo Plug-ins</_summary>
<description>
<_p>
This extension provides a set of basic examples to demonstrate
how to create your own plug-ins.
Each plug-in does the same thing, except it is developed in a
different programming language.
They all create a GTK+ dialog with a text view displaying their own code
(hence also demonstrating how to package data) and a button which calls
a GEGL operation on the active layer.
</_p>
</description>
<url type="homepage">https://gimp.org</url>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0+</project_license>
<releases>
<release version="1.0.0" date="2020-10-08" />
</releases>
<requires>
<id version="2.99.0" compare="ge">org.gimp.GIMP</id>
</requires>
<metadata>
<value key="GIMP::plug-in-path">@GOAT_EXERCISES@</value>
</metadata>
</component>

1
extensions/meson.build Normal file
View File

@ -0,0 +1 @@
subdir('goat-exercises')

View File

@ -1701,6 +1701,7 @@ subdir('libgimpwidgets')
subdir('libgimp') subdir('libgimp')
# Executables, plugins # Executables, plugins
subdir('extensions')
subdir('modules') subdir('modules')
subdir('plug-ins') subdir('plug-ins')
subdir('app') subdir('app')

View File

@ -44,7 +44,6 @@ SUBDIRS = \
fractal-explorer \ fractal-explorer \
gfig \ gfig \
gimpressionist \ gimpressionist \
goat-exercises \
gradient-flare \ gradient-flare \
help \ help \
$(help_browser) \ $(help_browser) \

View File

@ -1,85 +0,0 @@
# C version
plugin_name = 'goat-exercise'
plugin_sources = [
'goat-exercise-c.c',
]
if platform_windows
plugin_sources += windows.compile_resources(
gimp_plugins_rc,
args: [
'--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name + '-c.exe'),
'--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
'--define', 'TOP_SRCDIR="@0@"' .format(meson.source_root()),
],
include_directories: [
rootInclude, appInclude,
],
)
endif
executable(plugin_name + '-c',
plugin_sources,
dependencies: [
libgimpui_dep,
math,
],
install: true,
install_dir: gimpplugindir / 'plug-ins' / plugin_name + '-c',
)
install_data(
'goat-exercise-c.c',
install_dir: gimpplugindir / 'plug-ins' / plugin_name + '-c',
)
# Vala version
if have_vala
goat_exercise_vala = executable('goat-exercise-vala',
'goat-exercise-vala.vala',
include_directories: [ rootInclude, ],
dependencies: [
libgimp_vapi, libgimpui_vapi, gtk3, gegl, math,
],
c_args: [
'-DGETTEXT_PACKAGE="@0@"'.format(gettext_package),
],
install: true,
install_dir: gimpplugindir / 'plug-ins' / plugin_name + '-vala',
)
install_data(
'goat-exercise-vala.vala',
install_dir: gimpplugindir / 'plug-ins' / plugin_name + '-vala',
)
endif
# Python 3 (pygobject) version.
if have_python
install_data(
'goat-exercise-py3.py',
install_dir: gimpplugindir / 'plug-ins' / plugin_name + '-py3',
)
endif
# Javascript (GJS) version.
if have_javascript
install_data(
'goat-exercise-gjs.js',
install_dir: gimpplugindir / 'plug-ins' / plugin_name + '-gjs',
)
endif
# Lua (lua-jit + LGI) version.
if have_lua
install_data(
'goat-exercise-lua.lua',
install_dir: gimpplugindir / 'plug-ins' / plugin_name + '-lua',
)
endif

View File

@ -16,7 +16,6 @@ subdir('flame')
subdir('fractal-explorer') subdir('fractal-explorer')
subdir('gfig') subdir('gfig')
subdir('gimpressionist') subdir('gimpressionist')
subdir('goat-exercises')
subdir('gradient-flare') subdir('gradient-flare')
subdir('help') subdir('help')
subdir('help-browser') subdir('help-browser')

View File

@ -3,6 +3,10 @@
[encoding: UTF-8] [encoding: UTF-8]
extensions/goat-exercises/goat-exercise-c.c
extensions/goat-exercises/goat-exercise-vala.vala
extensions/goat-exercises/org.gimp.extension.goat-exercises.metainfo.xml.in.in
plug-ins/common/align-layers.c plug-ins/common/align-layers.c
plug-ins/common/animation-optimize.c plug-ins/common/animation-optimize.c
#plug-ins/common/animation-play.c #plug-ins/common/animation-play.c
@ -141,9 +145,6 @@ plug-ins/gimpressionist/repaint.c
plug-ins/gimpressionist/size.c plug-ins/gimpressionist/size.c
plug-ins/gimpressionist/sizemap.c plug-ins/gimpressionist/sizemap.c
plug-ins/gimpressionist/utils.c plug-ins/gimpressionist/utils.c
plug-ins/goat-exercises/goat-exercise-c.c
plug-ins/goat-exercises/goat-exercise-py3.py
plug-ins/goat-exercises/goat-exercise-vala.vala
[type: gettext/glade]plug-ins/ui/plug-in-metadata-editor.ui [type: gettext/glade]plug-ins/ui/plug-in-metadata-editor.ui
[type: gettext/glade]plug-ins/ui/plug-in-metadata-viewer.ui [type: gettext/glade]plug-ins/ui/plug-in-metadata-viewer.ui
plug-ins/gradient-flare/gradient-flare.c plug-ins/gradient-flare/gradient-flare.c

View File

@ -5,6 +5,7 @@ data/tags
data/tips data/tips
desktop desktop
desktop/gimp.desktop.in desktop/gimp.desktop.in
extensions/goat-exercises/org.gimp.extension.goat-exercises.metainfo.xml.in
libgimp libgimp
libgimpbase libgimpbase
libgimpcolor libgimpcolor

View File

@ -3,6 +3,8 @@
[encoding: UTF-8] [encoding: UTF-8]
extensions/goat-exercises/goat-exercise-py3.py
plug-ins/python/benchmark-foreground-extract.py plug-ins/python/benchmark-foreground-extract.py
plug-ins/python/colorxhtml.py plug-ins/python/colorxhtml.py
plug-ins/python/foggify.py plug-ins/python/foggify.py

View File

@ -36,7 +36,6 @@ plug-ins/flame
plug-ins/fractal-explorer plug-ins/fractal-explorer
plug-ins/gfig plug-ins/gfig
plug-ins/gimpressionist plug-ins/gimpressionist
plug-ins/goat-exercises
plug-ins/gradient-flare plug-ins/gradient-flare
plug-ins/help plug-ins/help
plug-ins/help-browser plug-ins/help-browser

View File

@ -5,6 +5,7 @@ data/tags
data/tips data/tips
desktop desktop
desktop/gimp.desktop.in desktop/gimp.desktop.in
extensions/goat-exercises
libgimp libgimp
libgimpbase libgimpbase
libgimpcolor libgimpcolor
@ -35,7 +36,6 @@ plug-ins/flame
plug-ins/fractal-explorer plug-ins/fractal-explorer
plug-ins/gfig plug-ins/gfig
plug-ins/gimpressionist plug-ins/gimpressionist
plug-ins/goat-exercises
plug-ins/gradient-flare plug-ins/gradient-flare
plug-ins/help plug-ins/help
plug-ins/help-browser plug-ins/help-browser