app, build, plug-ins: Run interpreters conditionally on Windows console

Closes: #12642

Now, we will check at runtime if GIMP is not on a console and
use the corresponding _win.interp file on such case only.

(cherry picked from commit 0c70a9fe00)
This commit is contained in:
Bruno Lopes 2025-11-09 12:29:10 -03:00
parent 1759860983
commit b059896975
No known key found for this signature in database
8 changed files with 111 additions and 30 deletions

View file

@ -38,6 +38,10 @@
#include "libgimpbase/gimpbase.h"
#ifdef G_OS_WIN32
#include <windows.h>
#endif
#include "plug-in-types.h"
#include "gimpinterpreterdb.h"
@ -121,11 +125,44 @@ gimp_interpreter_db_new (gboolean verbose)
return db;
}
#ifdef G_OS_WIN32
static gboolean
might_be_console_process (void)
{
/* check for Unix console */
if (g_getenv ("TERM") || g_getenv ("SHELL"))
return TRUE;
/* check for Windows console (taken from gspawn-win32.c) */
gboolean attached_to_self = AttachConsole (GetCurrentProcessId ());
g_return_val_if_fail (! attached_to_self, TRUE);
switch (GetLastError ())
{
case ERROR_ACCESS_DENIED:
return TRUE;
case ERROR_INVALID_HANDLE:
return FALSE;
}
g_return_val_if_reached (FALSE);
}
#endif
void
gimp_interpreter_db_load (GimpInterpreterDB *db,
GList *path)
{
GList *list;
#ifdef G_OS_WIN32
static gboolean console_checked = FALSE;
static gboolean is_console = FALSE;
if (!console_checked)
{
is_console = might_be_console_process ();
console_checked = TRUE;
}
#endif
g_return_if_fail (GIMP_IS_INTERPRETER_DB (db));
@ -168,8 +205,32 @@ gimp_interpreter_db_load (GimpInterpreterDB *db,
{
GFile *file = g_file_enumerator_get_child (enumerator, info);
gimp_interpreter_db_load_interp_file (db, file);
gchar *basename = g_file_get_basename (file);
#ifndef G_OS_WIN32
/* Unix: always load regular .interp file */
if (! g_strrstr (basename, "_win"))
{
gimp_interpreter_db_load_interp_file (db, file);
}
#else
if (! g_strrstr (basename, "_win"))
{
/* Windows: only load regular .interp file if on console */
if (is_console)
{
gimp_interpreter_db_load_interp_file (db, file);
}
}
else
{
/* Windows: load special _win .interp file if not on console */
if (! is_console)
{
gimp_interpreter_db_load_interp_file (db, file);
}
}
#endif
g_free (basename);
g_object_unref (file);
}

View file

@ -158,11 +158,10 @@ bundle(GIMP_PREFIX, "lib/girepository-*/*.typelib")
bundle(MSYSTEM_PREFIX, "lib/girepository-*/*.typelib")
bundle(MSYSTEM_PREFIX, "bin/libgirepository-*.dll")
#### Python support
#####python.exe is needed for plug-ins output in `gimp-console*.exe`
#####python.exe is needed for plug-ins error output if `gimp*.exe` is run from console
bundle(MSYSTEM_PREFIX, "bin/python.exe")
if not os.getenv("GIMP_UNSTABLE") and os.getenv("GIMP_RELEASE"):
#####pythonw.exe is needed to run plug-ins silently in `gimp*.exe`
bundle(MSYSTEM_PREFIX, "bin/pythonw.exe")
#####pythonw.exe is needed to run plug-ins silently if `gimp*.exe` is run from shortcut
bundle(MSYSTEM_PREFIX, "bin/pythonw.exe")
bundle(MSYSTEM_PREFIX, "lib/python*")
clean(GIMP_DISTRIB, "lib/python*/*.pyc")
#####Needed for internet connection on python. See: https://gitlab.gnome.org/GNOME/gimp/-/issues/14722

View file

@ -407,7 +407,7 @@ Source: "{#MAIN_BUNDLE}\*.lua"; DestDir: "{app}"; Excludes: "share\gimp\*.lua";
#ifdef PYTHON
Source: "{#MAIN_BUNDLE}\etc\ssl\*"; DestDir: "{app}\etc\ssl"; Components: {#PY_ARCHS}; Flags: {#COMMON_FLAGS}
Source: "{#MAIN_BUNDLE}\lib\gimp\{#GIMP_PKGCONFIG_VERSION}\environ\py*.env"; DestDir: "{app}\lib\gimp\{#GIMP_PKGCONFIG_VERSION}\environ"; Components: {#PY_ARCHS}; Flags: {#COMMON_FLAGS}
Source: "{#MAIN_BUNDLE}\lib\gimp\{#GIMP_PKGCONFIG_VERSION}\interpreters\pygimp.interp"; DestDir: "{app}\lib\gimp\{#GIMP_PKGCONFIG_VERSION}\interpreters"; Components: {#PY_ARCHS}; Flags: {#COMMON_FLAGS}
Source: "{#MAIN_BUNDLE}\lib\gimp\{#GIMP_PKGCONFIG_VERSION}\interpreters\pygimp*.interp"; DestDir: "{app}\lib\gimp\{#GIMP_PKGCONFIG_VERSION}\interpreters"; Components: {#PY_ARCHS}; Flags: {#COMMON_FLAGS}
Source: "{#MAIN_BUNDLE}\*.py"; DestDir: "{app}"; Components: {#PY_ARCHS}; Flags: {#COMMON_FLAGS}
#endif
Source: "{#MAIN_BUNDLE}\share\locale\*"; DestDir: "{app}\share\locale"; Components: loc; Flags: dontcopy {#COMMON_FLAGS}
@ -523,6 +523,7 @@ Type: filesandordirs; Name: "{app}\include\gexiv2"
Type: files; Name: "{app}\uninst\uninst.inf"
Type: files; Name: "{app}\lib\gimp\{#GIMP_PKGCONFIG_VERSION}\interpreters\lua.interp"
Type: files; Name: "{app}\lib\gimp\{#GIMP_PKGCONFIG_VERSION}\environ\pygimp.env"
Type: files; Name: "{app}\lib\gimp\{#GIMP_PKGCONFIG_VERSION}\environ\pygimp_win.env"
;4.3 KEYS TO BE REGISTERED
@ -1750,23 +1751,28 @@ begin
begin
StatusLabel(CustomMessage('SettingUpPyGimp'),'');
//python.exe is needed for plug-ins error output if `gimp*.exe` is run from console
InterpFile := ExpandConstant('{app}\lib\gimp\{#GIMP_PKGCONFIG_VERSION}\interpreters\pygimp.interp');
DebugMsg('PrepareInterp','Writing interpreter file for gimp-python: ' + InterpFile);
#if Defined(GIMP_UNSTABLE) || !Defined(GIMP_RELEASE)
//python.exe is prefered in unstable versions because of error output
#define PYTHON="python.exe"
#else
//pythonw.exe is prefered in stable releases because it works silently
#define PYTHON="pythonw.exe"
#endif
InterpContent := 'python=' + ExpandConstant('{app}\bin\{#PYTHON}') + #10 +
'python3=' + ExpandConstant('{app}\bin\{#PYTHON}') + #10 +
'/usr/bin/python=' + ExpandConstant('{app}\bin\{#PYTHON}') + #10 +
'/usr/bin/python3=' + ExpandConstant('{app}\bin\{#PYTHON}') + #10 +
DebugMsg('PrepareInterp','Writing interpreter file for gimp-python: ' + InterpFile);
InterpContent := 'python=' + ExpandConstant('{app}\bin\python.exe') + #10 +
'python3=' + ExpandConstant('{app}\bin\python.exe') + #10 +
'/usr/bin/python=' + ExpandConstant('{app}\bin\python.exe') + #10 +
'/usr/bin/python3=' + ExpandConstant('{app}\bin\python.exe') + #10 +
':Python:E::py::python:'#10;
if not SaveStringToUTF8File(InterpFile,InterpContent,False) then
begin
DebugMsg('PrepareInterp','Problem writing the file. [' + InterpContent + ']');
SuppressibleMsgBox(CustomMessage('ErrorUpdatingPython') + ' (2)',mbInformation,mb_ok,IDOK);
end;
//pythonw.exe is needed to run plug-ins silently if `gimp*.exe` is run from shortcut
InterpFile := ExpandConstant('{app}\lib\gimp\{#GIMP_PKGCONFIG_VERSION}\interpreters\pygimp_win.interp');
DebugMsg('PrepareInterp','Writing interpreter file for gimp-python: ' + InterpFile);
InterpContent := 'python=' + ExpandConstant('{app}\bin\pythonw.exe') + #10 +
'python3=' + ExpandConstant('{app}\bin\pythonw.exe') + #10 +
'/usr/bin/python=' + ExpandConstant('{app}\bin\pythonw.exe') + #10 +
'/usr/bin/python3=' + ExpandConstant('{app}\bin\pythonw.exe') + #10 +
':Python:E::py::python:'#10;
if not SaveStringToUTF8File(InterpFile,InterpContent,False) then
begin
DebugMsg('PrepareInterp','Problem writing the file. [' + InterpContent + ']');

View file

@ -1,3 +1,4 @@
#.interp file read by gimp_interpreter_db_load_interp_file in gimpinterpreterdb.c
install_data('default.interp',
install_dir: gimpplugindir / 'interpreters',
)

View file

@ -1,5 +1,6 @@
subdir('goat-exercises')
#.interp file read by gimp_interpreter_db_load_interp_file in gimpinterpreterdb.c
if have_lua and not meson.is_cross_build() and is_variable('lua') and lua.found() and (platform_windows or not relocatable_bundle)
lua_config = configuration_data()
# For Windows, we set the binary name only.

View file

@ -37,17 +37,17 @@ foreach plugin : python_plugins
endforeach
endforeach
# Fallback fix to the problem of non-configured interpreters (needed by MSIX)
#.interp file read by gimp_interpreter_db_load_interp_file in gimpinterpreterdb.c
if (platform_windows or platform_osx) and not meson.is_cross_build() and python.found()
python_config = configuration_data()
if platform_windows
if not stable or not release
#python.exe is prefered in unstable versions because of error output
python_config.set('PYTHON_EXE', 'python.exe')
else
#pythonw.exe is prefered in stable releases because it works silently
python_config.set('PYTHON_EXE', 'pythonw.exe')
endif
# python.exe is needed for plug-ins error output if `gimp*.exe` is run from console
python_config.set('PYTHON_EXE', 'python.exe')
# pythonw.exe is needed to run plug-ins silently if `gimp*.exe` is run from shortcut
install_data('pygimp_win.interp',
install_dir: gimpplugindir / 'interpreters',
)
else
# A 'python3' symlink is created on macOS.
python_config.set('PYTHON_EXE', 'python3')

View file

@ -0,0 +1,5 @@
python=pythonw.exe
python3=pythonw.exe
/usr/bin/python=pythonw.exe
/usr/bin/python3=pythonw.exe
:Python:E::py::python3:

View file

@ -46,7 +46,7 @@ if not meson.is_cross_build()
],
)
# Fallback fix to the problem of non-configured interpreters
#.interp file read by gimp_interpreter_db_load_interp_file in gimpinterpreterdb.c
scriptfu_config = configuration_data()
scriptfu_config.set('SCRIPTFU_PATH', '')
configure_file(
@ -56,6 +56,14 @@ if not meson.is_cross_build()
install: true,
install_dir: gimpplugindir / 'interpreters',
)
configure_file(
input : 'gimp-script-fu-interpreter.interp.in',
output: 'gimp-script-fu-interpreter_win.interp',
configuration: scriptfu_config,
install: true,
install_dir: gimpplugindir / 'interpreters',
)
endif
# Several components use Gtk