Commit graph

25795 commits

Author SHA1 Message Date
Alx Sa
4cff7cc2b5 widgets: Allow DnD pattern for vector layers in dock
Building on d8d8e7a0, we add a gimp_layer_tree_drop_viewables ()
function to handle dragging and dropping a pattern onto a Vector
layer in the layer dock.
2026-03-14 03:52:46 +00:00
Alx Sa
d8d8e7a0e8 widgets: Allow DnD for vector layers in dock
916cf84e handles dragging and dropping colors
onto vector layers on the canvas. However, we did
not handle what happens if you drag and drop onto
the layer dock.
This patch adds logic to gimp_layer_tree_view_drop_color ()
so that it also updates the vector layer fill, instead of
treating the vector layer like a raster layer and filling the
whole layer with the color.
2026-03-14 02:13:54 +00:00
Jacob Boerema
04ff553746 app: improve clipboard shutdown on Windows
On Windows gtk_clipboard_store ignores the number of items we have
set to be stored, instead storing all. Since this can be a long list,
shutting down GIMP on Windows can take considerable time when you
have a larger selection on the clipboard.

So we manually stop handling every target larger than 1 (png) and even
stop handling png after the first time, since it often gets called
multiple times for png.
2026-03-13 09:05:55 -04:00
balooii balooii
e0d70d4dc9 Issue #12357: Fix navigation popup positioning and dragging on Wayland 2026-03-12 22:36:25 +00:00
Jehan
483a2e0eed app, libgimp, pdb: fix setting NULL to gimp_image_set_color_profile() and…
… gimp_image_set_simulation_profile().

It looks like NULL through the PDB for 'bytes' argument gets passed as a
GBytes of size 0 (which might be something I did, and to be fair, that's
fine; I just forgot having done this).
As a consequence, testing for NULL was wrong, and these 2 functions were
always failing with NULL. Now they behave appropriately.

I also improve the docs for both functions.
2026-03-11 21:39:50 +01:00
Jehan
ef4c0a9504 app, libgimp, pdb: fix gimp_image_convert_color_profile() to allow NULL profile.
The function's documentation was already saying that we could set no
profile, except that in reality, setting NULL for the profile was simply
failing. Unless one checked the return value, the failure is also quite
silent. So let's actually implement what the docs say.

Also the concept of "default" profile might be a bit unclear in GIMP as
it could mean either built-in profiles or preferred ones (as set in
Preferences). I chose the former for this function, so I reword this
part of the docs.
2026-03-11 19:29:06 +01:00
Bruno Lopes
6fab4e2a81 app: GEGL is now relocatable on macOS 2026-03-11 11:21:05 -03:00
balooii balooii
b0ee5ddfce Issue #12491: Fix GimpUnitComboBox immediately closing on certain platforms
I noticed that the issue of the combo box popup getting immeidately
closed on Linux X11 (and probably macOS as well) only happens when using
GimpUnitComboBox as used in gimppropwidgets.c and gimpsizeentry.c while
there is no issue when used in gimpstatusbar.c

The only noticable difference I saw was that in status bar was that
the wrap width of combo box was set to 1 via
gtk_combo_box_set_wrap_width. Which was added as a hack for another
issue.

I did the same for the other two uses of GimpUnitComboBox and the issue
disappeared so I moved this hack to GimpUnitComboBox itself as it seems
to be generally useful.

The change doesn't make much sense to me and is a workaround for
something that should probably be changed in GTK but well.

As explored in !2654 I think we shouldn't use GtkComboBox but reimplement
using a Popover. This would get rid of these workarounds as we wouldn't rely
on internal behaviour of GtkComboBox.

Couldn't test macOS or Windows but Linux X11 and Wayland work just fine.
Tested by: GDK_BACKEND=x11 gimp and GDK_BACKEND=wayland gimp

Fixes #12491

Superseedes !2654
2026-03-10 00:11:37 +01:00
Jacob Boerema
a8b30b17d7 app: fix #12867 crash when exporting grayscale .gih
With a cell size half the width of a grayscale image with an alpha
channel, we get a crash because we write outside our buffer.

When computing the offset in the buffer, we added the offset of the
tile, but since we are just writing this tile. We should not add that
offset.
2026-03-09 17:18:43 -04:00
Alx Sa
5b6f1b481a file-data: Prevent crash with GIH and empty groups
Empty layer groups have no dimensions,
which can cause the GIH exporter to
crash when splitting cells (as it produces
negative width & height dimensions).

To prevent this, this patch initializes
potential brushes to NULL, verifies the
dimensions are positive before trying to
create GimpTempBuf with then, and prevents
a possible NULL brush from being added
to the exported brush list.
2026-03-09 16:21:30 +00:00
Gabriele Barbero
0d3ea5f4f1 display: fix wrong assertion in gimp_display_shell_set_child 2026-03-09 14:39:32 +00:00
Gabriele Barbero
eb52c529ff display: push on-canvas text editor fully inside the display
Previously, the on-canvas text editor would be repositioned only if it was completely
outside the display. If it was partially off-screen, it could be hard to
move it back inside (e.g.  when only a small part of the editor was visible
and difficult to grab). Now, the editor is always adjusted to remain fully
visible within the display
2026-03-09 14:39:32 +00:00
Jehan
045c818d0e Issue #15962: initialize Levels dialog in Perceptual.
Unlike for Curves (commit 7b4f0993e8), we cannot just change the "trc"
default of "gimp:levels", because then it could break any existing
script, made during the 3.0 series, which was applying this filter on
layers.
Instead, the "trc" stays linear by default for the op, but the tool's
dialog will override it to perceptual.

When we'll have implemented proper op versioning, we will be able to
change the default.
2026-03-09 14:26:58 +01:00
Jehan
21e7e4e576 app: remove "linear" property from "gimp:curves" op.
This property is fully ignored right now and was only kept for
compatibility reasons. One of the compatibility issue was config
parsing, but config migration rules were added on commit 955ff5b765.

The second compatibility issue was the case where this op may have been
used in existing scripts. Yet "gimp:curves" could not have been used in
the GIMP 3.0 API since GimpCurve type did not exist in libgimp. It could
even less be used directly though GEGL API because a plug-in process
doesn't see the "gimp:*" ops (only through our GimpDrawableFilter API).

So we can safely remove this arg now. Unfortunately we can't do the same
for "gimp:levels" because it was usable during the GIMP 3.0 series.
2026-03-09 14:26:58 +01:00
Alx Sa
c2f87513d6 app/tools: Fix ordering of selection mode options
In 046c8f27, we added a new function
gimp_selection_options_get_mode_box () so that the
Paint Select tool would use the same enum as other
selection tools. Code was added to move the
GIMP_CHANNEL_OP_REPLACE enum to the front only if
it was greater than the min value and less than the max value
that was passed in. This was to allow the Paint Select tool to
keep GIMP_CHANNEL_OP_ADD at the front while leaving the
other selection tools as they are.

However, the original call used 0, 0 for those values, so the
rearrangement code never ran at all. This patch changes the
parameter max value to GIMP_CHANNEL_OP_INTERSECT so
that Replace is moved for non-Paint Select tools.
2026-03-09 10:26:46 +00:00
Alx Sa
8e4e83911c dialogs: Set "Quit Save" icon size based on theme
The "Save"/"Save as" icons that appear in the Quit
Dialog when there are two or more images with unsaved
changes were always sized as GTK_ICON_SIZE_MENU,
or 16px, regardless of icon theme settings.

This patch adds code on Quit Dialog creation to check
the current theme and update the icon size accordingly
via `quit_style_updated ()`.

Note that this is a limited implementation due to the pending
release of GIMP 3.2. It is not connected to notify::custom-icon-size
signals to reduce complexity and potential issues.
In the future, we may move this to the parent GimpMessageDialog
if other dialogs would also benefit from getting a button icon size from
the theme.
2026-03-09 01:53:00 +00:00
Jehan
8e71b62f78 app: blurb cleanup.
Found all now unused blurbs with:

for macro in `grep -rI '^#define \([A-Z0-9_]*\)' app/config/gimprc-blurbs.h | sed 's/#define \([A-Z0-9_]*\).*$/\1/'`; do
  grep -rIq "$macro" * --exclude=gimprc-blurbs.h;
  if [ $? -ne 0 ]; then
    echo $macro;
  fi;
done

Only exception was LAST_REVISION_BLURB, which was not used, but should
have been.
2026-03-07 14:45:50 +01:00
Anders Jonsson
e0910337d0 docs, etc: gimprc memsize without suffix is just bytes 2026-03-06 23:29:14 +01:00
Jehan
7b4f0993e8 Issue #15962: "gimp:curves" set to Perceptual by default.
Per discussions with Pippin, Linear as default may not be the most
expected, though it has scenarios where it is still better.

Curves is easier because it was not possible to call it through the API
at all in the 3.0 series. I'll verify a bit for Levels, but I may just
do a GUI-only change for this one.
2026-03-06 21:39:17 +01:00
Jehan
0074bef0ea Revert "Issue #15824: better detect the first filter."
This reverts commit 75e665f0ed.

In fact, this commit was wrong too and was creating new issues with
pass-through group layers. See #15956.
2026-03-06 21:13:52 +01:00
Bruno Lopes
755642e76a meson, app, tools: Organize ISO_CODES* macros after build failure report
I don't get how this could be failing because config.h is included on main.c,
but it it: https://gitlab.gnome.org/GNOME/gimp/-/merge_requests/2664#note_2699194
So, I noticed that that the macro prefix ISOCODES_ is "new", being introduced
with aba7316e. The pre-existing is ISOE_CODES. Let's unify trying to fix build.
2026-03-06 14:09:35 -03:00
Jehan
9d7266c4ed Issue #15242: on a flush, only update actions for the active image.
Though my previous commit is not absolutely wrong (so I'll leave it in;
it does make sense that we don't set any lock actions as ACTIVE when
there are no items), this new commit is actually the real issue. The
previous commit was getting rid of the extra lock actions, but I
realized that the "edit-undo" action was made insensitive too.

This is because in multi-window mode, a flush was updating all action
groups for the visible image of all opened windows (in single window
mode too, but there is only 1 window, hence only 1 visible image, so no
bug happening). Depending on order of these updates, we could end up
updating actions based on items or undo stack of a non-active image. And
worse, this could even affect the active image itself (which was what
was happening with the locks).
2026-03-06 16:45:04 +01:00
Jehan
56b859546c Issue #15242: Multi Window mode creates extra 'lock' actions. 2026-03-06 16:27:14 +01:00
Jehan
0587cbbc9b Issue #15713: Text tool "Language" names not localized on relocatable builds. 2026-03-05 16:29:14 -03:00
Bruno Lopes
6246735966 app: migrate also from ~/snap/ if the 3.0 folder is not found in XDG config home. 2026-03-03 21:33:38 -03:00
Jehan
6283ec669d app: verify all playground features to forcibly show the playground tab.
Maybe I should find a more "automatic" logic…
2026-03-02 22:25:07 +01:00
Jehan
7b3052dcdd app: fix a crash in GIMP when calling gimp:curves with GIMP_HISTOGRAM_LUMINANCE…
… from a plug-in.

The value is accepted by the current specification of "channel" but it
is actually not supported and would end up crashing the core process.

The real fix which should happen would be to make GimpParamSpecEnum
usable in libgimp, and be able to pass its spec through the PDB. Then we
could use this param spec instead of GParamSpecEnum for such property
not supporting all values in an enum.

Note that with the current fix, the "gimp:curves" filter will silently
refuse the Luminance channel when passed as "channel". It is not ideal.
But it's better than crashing the whole of GIMP!
2026-03-02 16:58:11 +01:00
Jehan
e9e2bb1b2e app: GimpEditor buttons will have the associated action name as identifier. 2026-03-01 23:48:57 +01:00
Jehan
51ac9d7f2a Issue #15681: deprecate gimp_drawable_curves_explicit() and…
… gimp_drawable_curves_spline().

We can now run directly "gimp:curves" operation, both destructively or
non-destructively, but also setting the TRC, as well as individual point
types (when the curve is of type "smooth" instead of freehand).
This is much more powerful!
2026-03-01 22:33:58 +01:00
Jehan
b87bab9e8c app, libgimp*: add GimpCurve sample API in libgimp and PDB. 2026-03-01 22:33:58 +01:00
Bruno Lopes
24f8f6f68b app: Do not unconditionally force Playground on macOS
Very weird line of code.
2026-03-01 11:15:06 -03:00
Alx Sa
804991a215 libgimp, pdb: Allow access to GimpCurve in PDB
Adds a GimpCurve object and functions in libgimp.
Rather than creating a GimpCurve object in core and
passing it back and forth, we just pass the attributes
and reconstruct it across.
In the future, we may combine this with the app/core one
and put it in libgimpbase.
2026-03-01 13:41:35 +00:00
Jehan
3a53e4743e app: copy the buffer rather than using it as source.
I think the previous code should be OK, but I had some criticals when
painting with a paint tool in the area which got extended:

> (gimp:577203): GLib-GObject-CRITICAL **: 21:37:08.402: value "-31" of type 'gint' is invalid or out of range for property 'y' of type 'gint'

It looks like there lingering pieces from the negative offset in the
buffer, which is probably a bug in GEGL?
Anyway let's go the shorter route for now, which is to copy the buffer
with a different offset. I don't think it's less efficient either
anyway.
2026-02-28 21:52:10 +01:00
Jehan
4c15be6a56 app: fix merging filters with negative top-left point.
When merging filters whose rendering was expanding in negative
ccordinates, I realized that the drawable was not properly resized (it
was resized properly when the width/height increased, but not when the x
or y points became negative, even though this "cropped" part still
showed… until you saved and reloaded your XCF!).

The problem is that drawable buffers are always stored with (0, 0)
top-left and this was just confusing our existing code. So let's check
when trying to set a buffer with a non-(0, 0) origin, and update the
offset subsequently.

I hesitated with an alternative implementation which was to edit the
buffer applied to the drawable in gimp_drawable_merge_filters(). But I
figured this would be more future-proof for other similar cases, though
I hope I did not break any use case where this was actually considered a
normal case.
2026-02-28 21:04:05 +01:00
Bruno Lopes
b7d89728c4 app, libgimpthumb, plug-ins, tools: Fix POSIX namespace warnings on MSVC 2026-02-28 10:06:46 -03:00
Bruno Lopes
dc1771918b app: Only show the installed locales for GIMP
Closes: #15468

There is no point on showing languages that can not be used.
This was confusing distro package and Windows installer users.
2026-02-26 20:51:09 -03:00
Alx Sa
3a4bd57da6 widgets: Turn off default search in GimpPrefsBox
Same patch as cb552d3d, just applied to GimpPrefsBox.
This was visible in the Preferences Dialog, where the same
unnecessary pop-up appeared in the side panel.
2026-02-26 19:15:13 +00:00
balooii balooii
d80ad177af Issue #13401: Fix crash opening channels after apply/undo drawable filter 2026-02-26 15:06:14 +00:00
Alx Sa
90273fe90a path: Add gimp_vector_layer_convert ()
When we copy and paste a vector layer,
we need to reattach its path to the
(potentially) new image. Similar to what
we did for NDE filters in 8db97f4e,
we convert the existing path if necessary
before continuing with the gimp_item_convert ()
process. This prevents several CRITICALs,
for instance when copying a group that
contains vector layers rather than the
vector layers directly.
2026-02-26 03:20:05 +00:00
Jehan
ad936482a2 Revert "Issue #15824: waterpixels filter on a selection appears to hang GIMP."
This reverts commit d91a8b2abe.

As reported by Liam on #15824, this commit was clearly wrong and
reintroduced the old cropping bug with multiple filters. Reverting.

The next commit was likely good, though the real hanging bug is — as far
as my test go — in the GEGL op itself. This second commit 75e665f0ed was
improving things, but obviously, as the bug is still in the op, it can
still be triggered. We'll have to fix the source bug next.
2026-02-25 23:51:56 +01:00
Alx Sa
918aea3df5 dialogs: Replace custom widget in Path Export dialog
This patch replaces adding a custom widget
to the Path Export dialog with a built-in
combobox from gtk_file_chooser_add_choice ().
This makes our code more compatible
with a future port to native file dialogs
in GTK3, without a loss of functionality.
2026-02-25 21:35:52 +00:00
Jehan
75e665f0ed Issue #15824: better detect the first filter.
Ah my previous commit was working fine with a selection in the "Use the
selection as input" case, but was still hanging when "Use the entire
layer as input" was chosen.

The detection of whether we were the first filter was not working fine
when adding a new filter. Now this should work in all cases.

I don't revert the previous commit, because I think it's fine anyway.
When we have a selection, unconditionally adding a cropping-before node
on the selection boundaries seems logical to me.
Hopefully it doesn't bring back any of the cropping issues we had on
filters, but so far I could not reproduce any.
2026-02-25 15:44:29 +01:00
Jehan
d91a8b2abe Issue #15824: waterpixels filter on a selection appears to hang GIMP. 2026-02-25 15:38:23 +01:00
Alx Sa
664729a55c text: Reverting 03443ffc
Resolves #11409
After Jehan's update to
gimp_drawable_filter_refresh_crop () in
0157a958, it no longer calls the cropping
functions which this commit was intended
to work around.

Additionally, thanks to other changes in
the filter code since then, reverting this
commit resolves an issue where some
Render filters would not update as you
typed more characters.
2026-02-25 13:01:25 +00:00
Jehan
7296099388 Issue #13368: pressure curve is missing from the GimpDeviceInfoEditor.
This was happening on Wayland in my tests, and apparently on Windows
too, according to the report. I widely simplified the code. Now we don't
list of axis anymore, and therefore we don't allow to change these
(which was not working anyway, for as long as I remember, at least on
Linux, both X11 and Wayland).

As for the pressure curve, we just show it unconditionally for any
device of type "Pen". It may mean that it might show on some rare stylus
devices with no pressure support, but in such case, it will just be a
bogus curve (it won't break the device).
And then we'll avoid all the flimsy heuristic trying to guess if a
device is supposed to have pressure sensitivity, which especially became
bad in Wayland as we have this information only on proximity. It means
that if you don't approach the stylus and were trying to set up your
pen's pressure curve with a mouse, no curve would appear!

Add to this that gdk_device_list_axes() seems very broken on Wayland and
was always returning GDK_NONE for all axis (even when only using it on
various device signal handlers, per advices by Carlos on IRC), at least
anyhow I tried to make it work, our heuristic to detect when an axis
should be ignored was completely broken on Wayland as well.

A simpler logic should work better and makes the code simpler to read
too.

It's also one less usage of GtkListStore, which is good for future GTK
versions where it got deprecated!
2026-02-24 22:54:48 +01:00
Alx Sa
1282384417 core: Update filter area if changed
Previously, we only updated an NDE filter's
`filter_area` if the filter itself contained a
width or height property.
However, the filter_area is also used by
GimpDrawableFilter to indicate where we
should draw the filter, and needs to be
updated if we scale/rotate/shear the layer
and change its dimensions.

This patch moves the code so that the
filter_area width and height is always
updated if we pass a GeglRectangle in to
gimp_drawable_filter_refresh_crop ().
2026-02-24 11:32:08 +00:00
Jehan
87810ae6fe app: make explicit that "White Balance" auto effect works in linear space.
This commit doesn't actually changes anything, but it fixes the
gimp_histogram_new() call, since the argument is supposed to be a
GimpTRCType, not a boolean. Yet GIMP_TRC_LINEAR is the first value in
the enum type, so it's indeed the same as FALSE.
I also set the "trc" property to "gimp:levels" config object explicitly,
to the same TRC value as the histogram, so that this doesn't depend on
the default anymore (which is linear too, right now; so this part
doesn't change a thing here again), and therefore would survive to any
possible default change in the future.

Note that it was considered to set this all to non-linear, just as it
used to be in 2.10, as requested in #15738. After discussing it with
Øyvind on IRC, we concluded that working in linear space may be a nicer
default for this feature, as we'd be doing a "meaningful rebalancing of
photon count per component". Now there may be cases where doing a
white-balancing in non-linear may yield better result, of course. For
these case, you may still go to "Levels", set to non-linear, and hit
"Auto Input Levels". This is exactly the same code runing (but in
non-linear space). The "White Balance" action still needs to be the
simple non-GUI option and keeping work in linear seems like the more
appropriate default here.
2026-02-24 01:36:32 +01:00
Alx Sa
bc02381f14 widgets: Hide move handle in Text Editor window
Since the Text Editor window uses the same
GimpTextStyleEditor widget as the on-canvas editor,
it also shows the Move handle (which doesn't work
in the Text Editor window). This patch simply hides it
so it doesn't confuse users.
2026-02-23 17:42:28 +00:00
Alx Sa
b9d4e315e8 core: Adjust logic for gimp_drawable_filter_refresh_crop ()
In 0157a958, we prevent the NDE crop refresh
code from running unless the filter's crop
enabled is TRUE. However, this prevents
the width and height settings built into
certain filters from running, separate from
the crop nodes in GimpDrawableFilter.
This patch moves the check to only cover
the calls to gimp_drawable_filter_set_crop ().
This should fix the width/height update issue
without causing a regression to #14442.
2026-02-22 18:10:15 +00:00
Alx Sa
581afd1516 core: Fix GEGL warning after bucket fill
In 6279d7b7, I did not free the GEGL buffer created
by gimp_pickable_get_buffer_with_effects ().
This resulted in an "EEEEeEeek! 1 GeglBuffers leaked"
warning on exit, which of course could cumulate.

This patch makes to sure to clear out the src_buffer
both times it's used.
2026-02-22 00:28:16 +00:00