Brush, font, gradient, palette and pattern choices are currently chosen through
a dialog created by the core, which then returns the user choice to the calling
plug-in. This has the unfortunate consequence of having a pile of likely at
least 3 windows (main GIMP window by core process, plug-in window by plug-in
process, then the choice popup by the core process) shared in 2 processes, which
often end up under each other and that's messy. Even more as the choice popup is
kinda expected to be like a sub-part of the plug-in dialog.
So anyway, now the plug-in can send its window handle to the core so that the
resource choice dialog ends up always above the plug-in dialog.
Of course, it will always work only on platforms where we have working
inter-process transient support.
Having windows ID as guint32 is a mistake. Different systems have
different protocols. In Wayland in particular, Windows handles are
exchanged as strings. What this commit does is the following:
In core:
- get_window_id() virtual function in core GimpProgress is changed to
return a GBytes, as a generic "data" to represent a window differently
on different systems.
- All implementations of get_window_id() in various classes implementing
this interface are updated accordingly:
* GimpSubProgress
* GimpDisplay returns the handle of its shell.
* GimpDisplayShell now creates its window handle at construction with
libgimpwidget's gimp_widget_set_native_handle() and simply return
this handle every time it's requested.
* GimpFileDialog also creates its window handle at construction with
gimp_widget_set_native_handle().
- gimp_window_set_transient_for() in core is changed to take a
GimpProgress as argument (instead of a guint32 ID), requests and
process the ID itself, according to the running platform. In
particular, the following were improved:
* Unlike old code, it will work even if the window is not visible yet.
In such a case, the function simply adds a signal handler to set
transient at mapping. It makes it easier to use it at construction
in a reliable way.
* It now works for Wayland too, additionally to X11.
- GimpPdbProgress now exchanges a GBytes too with the command
GIMP_PROGRESS_COMMAND_GET_WINDOW.
- display_get_window_id() in gimp-gui.h also returns a GBytes now.
PDB/libgimp:
- gimp_display_get_window_handle() and gimp_progress_get_window_handle()
now return a GBytes to represent a window handle in an opaque way
(depending on the running platform).
In libgimp:
- GimpProgress's get_window() virtual function changed to return a
GBytes and renamed get_window_handle().
- In particular GimpProgressBar is the only implementation of
get_window_handle(). It creates its handle at object construction with
libgimpwidget's gimp_widget_set_native_handle() and the virtual
method's implementation simply returns the GBytes.
In libgimpUi:
- gimp_ui_get_display_window() and gimp_ui_get_progress_window() were
removed. We should not assume anymore that it is possible to create a
GdkWindow to be used. For instance this is not possible with Wayland
which has its own way to set a window transient with a string handle.
- gimp_window_set_transient_for_display() and
gimp_window_set_transient() now use an internal implementation similar
to core gimp_window_set_transient_for(), with the same improvements
(works even at construction when the window is not visible yet + works
for Wayland too).
In libgimpwidgets:
- New gimp_widget_set_native_handle() is a helper function used both in
core and libgimp* libraries for widgets which we want to be usable as
possible parents. It takes care of getting the relevant window handle
(depending on the running platform) and stores it in a given pointer,
either immediately or after a callback once the widget is mapped. So
it can be used at construction. Also it sets a handle for X11 or
Wayland.
In plug-ins:
- Screenshot uses the new gimp_progress_get_window_handle() directly now
in its X11 code path and creates out of it a GdkWindows itself with
gdk_x11_window_foreign_new_for_display().
Our inter-process transient implementation only worked for X11, and with
this commit, it works for Wayland too.
There is code for Windows but it is currently disabled as it apparently
hangs (there is a comment in-code which links to this old report:
https://bugzilla.gnome.org/show_bug.cgi?id=359538). NikcDC tested
yesterday with re-enabling the code and said they experienced a freeze.
;-(
Finally there is no infrastructure yet to make this work on macOS and
apparently there is no implementation of window handle in GDK for macOS
that I could find. I'm not sure if macOS doesn't have this concept of
setting transient on another processus's window or GDK is simply lacking
the implementation.
In GimpText, The font used to be stored as a string containing its name,
Now, it is stored as a GimpFont object, which makes more sense and makes
operations on fonts easier (such as serialization).
This finds the core resource knowing its type, name, collection and internal
state (in other words, the values returned by _gimp_resource_get_identifiers()).
Rather than reimplementing the same checks for every possible resource data
type, just do it once and redirect to the correct factory container.
For the libgimp API, we leave per-type functions `gimp_*_get_by_name()` (where *
can be brush|gradient|font|palette|pattern so far), but internally they all use
gimp_pdb_get_resource().
Note that eventually we want these functions to return a list of resources as it
should be possible to have several resources of a given type with the same name
(since they are made by third-party who might have had the same idea of a name).
Resources are stored by the plug-in infrastructure and their memory should not
be managed by plug-in code.
My commit 4f69995b46 was crappy and modified a generated function. I was just
too tired with all the heat in here, I guess!
Brushes can't be large enough to actually cause overflow here, but
since the result is gsize, it can't hurt to have the intermediate
results to gsize too.
It looks like we left out the multiplication by 3 when passing the
colormap size to get to the number of bytes in commit 89c359ce
This fixes a crash when saving an XPM file
Fixes: https://gitlab.gnome.org/GNOME/gimp/-/issues/9711
Partially resolves#7211.
plug-in-ripple is a wrapper for the GEGL ripple effect. GEGL allows for
double values for period and amplitude, while the GIMP PDB only allows
integers. This patch aligns the datatypes.
Note that Angle and Phi are still limited to the current design.
As @bootchk noted, gimp-file-load-layers does not check the result of
file_open_layers () but the final return variable
which is always NULL at this point in the function.
This patch corrects the problem so it checks the proper variable.
Much like for images and items. Change the PDB to transmit IDs
instead of names for brush, pattern etc. and refactor a whole
lot of libgimp code to deal with it.
modified: libgimp/gimpplugin-private.h
GLib has a specific type for byte arrays: `GBytes` (and it's underlying
GType `G_TYPE_BYTES`).
By using this type, we can avoid having a `GimpUint8Array` which is a
bit cumbersome to use for both the C API, as well as bindings. By using
`GBytes`, we allow other languages to pass on byte arrays as they are
used to, while the bindings will make sure to do the right thing.
In the end, it makes the API a little bit simpler for everyone, and
reduces confusion for people who are used to working with byte arrays
in other C/GLib based code (and not having 2 different types to denote
the same thing).
Related: https://gitlab.gnome.org/GNOME/gimp/-/issues/5919
- gimp_image_add_sample_point: guide is a left-over from copy-pasting and
add apostrophe
- gimp_image_get_sample_point_position: it was not clear that the
parameter was the y-offset and the return value the x-offset
- fix a typo s/Commponent/Component/.
- Add &std_pdb_compat() to the new PDB procedures (I realize that's probably
what the contributor was asking about, back in !446). Not sure if it's right
as there were none in this file, but these are clearly just wrappers around
GEGL ops, so it seems fitting.
- Some alignment fixes.
- More accurate "$since" variables.
(cherry picked from commit 66ef1ef1ef)
(cherry picked from commit dbf9f277a2)
Committer's (Jehan) updates:
- Component type is now int32 (int8 is not a PDB type available anymore).
- PDB files re-generated to handle changes in API and types.
This is not made to set the imported or exported file, but only the XCF file.
See previous commit to see what happens when this API is used to set non-XCF
file extensions (saving fails unless one edits the filename).
This commit is a fixup commit for MR !790 which had a few issues:
- The args for shadows and highlights adjustments are "shadows-ccorrect" and
"highlights-ccorrect" respectively.
- Also fixing generated code.
(cherry picked from commit e456ab019b)
… moved to the implementation file.
When declaring with G_DECLARE_FINAL_TYPE(), the whole concept is that the struct
is made private (which also allows the type to evolve without breaking ABI if we
some day decide to make the class derivable). For this to make sense, the struct
goes in the implementation file, not the header.
For the rest, it's mostly alignment bugs and the like.
Simplifies chooser widgets (e.g. GimpBrushSelect) by eliminating attributes (e.g. opacity) of chosen resource.
See #8745, but this commit fixes that by first refactoring the code.
Refactors GUI widgets (e.g. GimpBrushSelectButton and GimpBrushSelect etc.)
Refactor by "Extract class" GimpResourceSelectButton from GimpBrushSelectButton etc.
This moves common code into an inherited class (formerly called GimpSelectButton)
but the subclasses still exist.
The subclasses mainly just do drawing now.
Refactor by "Extract module" GimpResourceSelect from GimpBrushSelect etc.
Moves common code into one file, generic at runtime on type of GimpResource,
that is, the new code dispatches on type i.e. switch statements.
In the future, when core is changed some of that can be deleted.
The files gimpbrushselect.[c,h] etc. are deleted.
The module adapts the API from core to the API of callbacks to libgimp.
Note that core is running the resource chooser (select) widgets remotely.
Core is still calling back over the wire via PDB with more attributes
than necessary.
The new design gets the attributes from the resource themselves,
instead of receiving them from core callback.
The libgimp side adapts by discarding unneeded attributes.
In the future, core (running choosers for plugins) can be simplified also.
Fix gimp_prop_chooser_brush_new same as other resources.
Finish changes, and clean style.
Annotations
So procedures can declare args and GimpProcedureDialog show chooser
widgets
Fix so is no error dialog on id_is_valid for resources
Palette.pdb changes and testing
Memory mgt changes
Gradient pdb
Font and Pattern tests
Test brush, palette
Cleanup, remove generator
Rebase, edit docs, install test-dialog.py
Whitespace, and fix failed distcheck
Fix some clang-format, fix fail distcheck
Fix distcheck
Cleanup from review Jehan
When the clipboard contains raw image data or single layers, it's the same as
the normal "Paste" (and "Paste In Place" respectively). These actions are useful
if you want to copy a bunch of layers and paste them "merged" into a single
layers (since now the copy-paste of multiple layers will create multiple
layers).
It is somehow similar to the "Copy Visible" action except that it works on
selected layers only and work at paste time, making the action more versatile.
When several drawables were selected, it was pasting at the top of the layer
stack. Instead, paste over the top selected layer ("top" visually in the Layers
dockable).
There was the question of: what should we do when pasting over a layer group.
Should we consistently paste the new layers above the group or inside the group?
After discussions with Aryeom, we decided to stay consistent and paste above, at
least for now.
It seems I forgot to fix some usage of core gimp_vectors_export*(),
which now take a list of paths (not a single path anymore since commit
9fc8260c7c), as these were used by PDB functions.
Missing functions were:
* gimp_image_get_selected_channels()
* gimp_image_get_selected_vectors()
* gimp_image_list_selected_channels()
* gimp_image_list_selected_vectors()
* gimp_image_set_selected_channels()
* gimp_image_set_selected_vectors()
* gimp_image_take_selected_channels()
* gimp_image_take_selected_vectors()
There are discussions of renaming GimpVectors to GimpPath, which would
also be consistent with the GUI and make the always-plural less akward
in API. We'll see. For now keeping named like this.
Now text layers are proper types, which means that the binding API will also be
nicer (e.g. `txt_layer.set_text('hello world')` in Python).
This commit also adds the param specs allowing to create plug-in procedures with
text layer parameters.
Finally it fixes the few calls in file-pdf-save (apparently the only plug-in
using specific text layer API right now) with explicit type conversion.
After re-reading #534, I realized I missed the discussion about unsupported
markup by the tool. Then I tested and confirmed what Ian Munsie initially said
in a comment: unsupported markups are properly rendered in the text layer, yet
are simply dropped when editing with the text tool.
This is actually the ideal behavior as it means that with the API, you can even
go further than what is currently possible with the GUI. So it gives nice powers
to people who can script GIMP. We still need some warning in the function
documentation to tell developers about this weakness in the tool GUI.
This complements the existing text_layer_get_markup function and allows
scripts to create and modify complex text layers.
It adds the <markup> root tag if it was not supplied and will run the
markup through pango_parse_markup() to check for errors.
Reviewer's (Jehan) note: this is a mostly untouched patch contributed in #534,
except that code moved around. I also fixed the header set in the .pdb, a link
to pango markup docs and added the meson changes.
Now that we bumped our meson requirement, meson is complaining about
several features now deprecated even in the minimum required meson
version:
s/meson.source_root/meson.project_source_root/ to fix:
> WARNING: Project targets '>=0.56.0' but uses feature deprecated since '0.56.0': meson.source_root. use meson.project_source_root() or meson.global_source_root() instead.
s/meson.build_root/meson.project_build_root/ to fix:
> WARNING: Project targets '>=0.56.0' but uses feature deprecated since '0.56.0': meson.build_root. use meson.project_build_root() or meson.global_build_root() instead.
Fixing using path() on xdg_email and python ExternalProgram variables:
> WARNING: Project targets '>=0.56.0' but uses feature deprecated since '0.55.0': ExternalProgram.path. use ExternalProgram.full_path() instead
s/get_pkgconfig_variable *(\([^)]*\))/get_variable(pkgconfig: \1)/ to
fix:
> WARNING: Project targets '>=0.56.0' but uses feature deprecated since '0.56.0': dependency.get_pkgconfig_variable. use dependency.get_variable(pkgconfig : ...) instead
Adds a simulation_bpc and simulation_intent to GimpImage to allow
plug-ins to access it
for CMYK import/export.
Four pdb functions were added to enable this access:
image_get_simulation_bpc (), image_set_simulation_bpc (),
image_get_simulation_intent (), and image_set_simulation_intent ().
Next, it updates menu options and code to support GimpImage's
internal simulation intent and bpc.
New 'simulation-intent-changed' and 'simulation-bpc-changed signal
are emitted via
GimpColorManagedInterface so that relevant tools
(such as the
CYMK color picker, GimpColorFrame, and future pop-overs)
are aware of these changes.
Meson is apparently able to show different warning depending on the
meson version tests we do in specific code paths.
Since our global required meson is 0.53.0 but on some code paths, we
test for 0.57.0, we must use meson.source_root() on older meson and
meson.project_source_root() on newer one.
Fixes:
> pdb/meson.build:141: WARNING: Project targets '>=0.57.0' but uses feature deprecated since '0.56.0': meson.source_root. use meson.project_source_root() or meson.global_source_root() instead.
> pdb/meson.build:141: WARNING: Project targets '>=0.57.0' but uses feature deprecated since '0.56.0': meson.build_root. use meson.project_build_root() or meson.global_build_root() instead.
> po-tips/meson.build:5: WARNING: Project targets '>=0.53.0' but uses feature introduced in '0.56.0': meson.project_source_root.
Plug-in localization was always partially plug-in side, especially for
things like custom GUI. But labels or blurb in GIMP (such as in menus or
action search) were localizing GIMP side.
It had many drawbacks:
- To get menu localization, a plug-in had to set up gettext, even though
they might want to use something else for their GUI (after all, giving
facilities for gettext is a good idea, but there is no reason to force
using this system).
- There was a complex internal system passing the localization domain
name, as well as the catalog file system path to core, then through
various classes which we can now get rid of.
- There could be domain name clashes, if 2 plug-ins were to use the same
i18n domain name. This was handled in now removed functions
gimp_plug_in_manager_get_locale_domains() by simply keeping a unique
one (and gimp_plug_in_manager_bind_text_domains() would just bind the
domain to the kept directory). In other words, one of the duplicate
plug-ins would use the wrong catalog. We could try to make the whole
thing more complicated or try to forbid plug-ins to use any random
name (in particular made easier with the new extension wrapper). But
anyway this whole issue doesn't happen anymore if localization is
fully made plug-in side, so why bother?
I tried to evaluate the advantages of the core-side localization of
plug-in labels/blurbs and could only find one theoretical: if we wanted
to keep access to the original English text. This could be useful
(theoretically) if we wanted to search (e.g. in the action search) in
both localized and English text; or if we wanted to be able to swap
easily en/l10n text in a UI without reload. But even if we were to ever
do this, it would only be possible for plug-ins (GEGL operations in
particular are localized GEGL-side), so it lacks consistency. And it's
unsure why special-casing English should really make sense for other
language natives who want text in their lang, and search in their lang.
They don't necessarily care about original.
So in the end, I decided to simplify the whole thing, make localization
of plug-ins a plug-in side thing. Core will only receive translated text
and that's it. It cuts a lot of code out of the core, simplify runtime
processing and make plug-in creation simpler to understand.
The only think I still want to look at is how exactly menu paths are
translated right now. Note that it still works, but it's possible that
some things may be worth improving/simplifying on this side too.
Adds a simulation_profile to GimpImage to allow plug-ins to access it
for CMYK import/export.
Two pdb functions were added to enable this access:
image_get_simulation_profile () and image_set_simulation_profile()
Next, it updates menu options and code to support GimpImage's
internal simulation profile. Menu items are moved from View to Image's
Color Management section.
New 'simulation-profile-changed' signal is emitted via
GimpColorManagedInterface so that relevant tools (such as the
CYMK color picker, GimpColorFrame, and future dockable
dialogue) are aware of these changes.