Commit Graph

25059 Commits

Author SHA1 Message Date
Bruno Lopes 941fc0000b
apps/tests : Fix IconsRoot path on gimp-data era 2025-04-18 19:41:19 -03:00
Gabriele Barbero 9989dfe933 Issue #13752 - Handle GTK_RESPONSE_HELP in about dialog
Previously, the Help button triggered the default dialog close behavior, without showing any help.
This change ensures that pressing Help triggers the expected help function.
2025-04-18 16:36:33 +02:00
Bruno Lopes d88966b272
app, app-tools, data, plug-ins, tools: Do not hardcode python executable
Use 'python' module instead.
2025-04-17 14:32:06 -03:00
Bruno Lopes 455dc1faa6
app, app-tools, tools: Port Windows's enable_default_bin to Python 2025-04-17 09:39:00 -03:00
Bruno Lopes 63f5ea9dc5
build, meson, gitlab: Generate native .pdb CodeView symbols on Windows
Reverts dc21fb76

The CodeView format introduces some advantages to our Windows build:
- It is way smaller than DWARF, reducing the .exe installer. With
  the strip of COFF symbols too, the installation is 120MB smaller.
- Can be uploaded as .appxsym to be used on demand by MSIX (in thesis)
- Works better with DIA and DbgHelp debuggers like WinDbg and DrMingW,
  respectively. LLDB also works by using LLDB_USE_NATIVE_PDB_READER=1

Context: that was not working before because DrMingw and LLDB seems to
only search for the build-time .pdb path in '.buildid' section of bins.
See: https://github.com/jrfonseca/drmingw/issues/91 and
https://github.com/llvm/llvm-project/issues/125355. So, we will set
_NT_SYMBOL_PATH at least for $PREFIX/bin for now as workaround.
2025-04-14 07:50:43 -03:00
Alx Sa 19bb4a5251 paint: Prevent crash on out-of-bounds smudge tool
The Smudge Tool gets accumulated buffers from its
history via g_list_nth_data (). However, this function can
return NULL if we go out of bounds. We did not check for
this before trying to use it as a GeglBuffer, which caused
crashes if we ran out of accumulated buffers (e.g. if we
were partially smudging off-canvas).
This patch adds NULL checks to prevent the crashes.
2025-04-13 22:55:12 +00:00
Alx Sa c3814125e3 display: Verify GtkWidget is a GimpCanvas object...
...before trying to get its GimpColorConfig.
Resolves #13691

After the color space invasion, various GimpCanvas
functions are now aware of color management settings.
However, these public GimpCanvas functions do not
require the user to pass in a GimpCanvas, just a GtkWidget.
This can lead to crashes if we pass in a different kind of
GtkWidget, since it may not have a GimpColorConfig property.

One example is the Navigation Dockable, which crashes when
it tries to draw boundaries around the image when "Show All"
is turned on, because it passes a GimpView widget instead of
a GimpCanvas.

This patch adds a check if the "canvas" parameter is actually a
GimpCanvas, and sets the config to NULL otherwise.
2025-04-13 15:31:48 +00:00
Alx Sa a331caa9f2 core: Enable resize for GUI layer duplication
Resolves #13633 (for now)
Same rationale as 975d1a4a, as diagnosed by Thomas Manni.

During 3.2 development, we can review and likely just set this as
the default value inside GimpDrawable.
For now, this is a limited bugfix for 3.0.x.
2025-04-12 14:27:51 +00:00
Alx Sa 93c3d83dd0 tools: Hide Force slider for Pencil Tool
The Force option does not affect the Pencil Tool's painting.
While Force is already set to be insensitive, hiding the
option entirely makes it even clearer that it can not
be used with this tool.
2025-04-11 02:58:42 +00:00
Jacob Boerema 5273f26ef0 app, pdb: fix #13480 inconsistent use of maximum radius...
for generated brushes.
The maximum radius we allowed for generated brushes was not used
consistently everywhere.
In the API call we clamped it to 0.0-32767.0, while the param_spec
set min and max to 0.1 and 4000.0, and the brush editor used a
maximum of 1000.0.
Using a large value (probably anything larger than 4000) would
sooner or later lead to a crash.

Instead of manual changes everywhere, let's define a maximum and
minimum in one place and use that wherever we need the min/max values.
Use the values as set in the param_spec for the defines.
The only place we can't easily do that is in brush.pdb, so we add
a comment above our defines that the values need updating there too.

Actually we should probably use more defines for other values too,
that way there is less chance of min/max values getting out of synch
throughout our code.
2025-04-11 02:02:40 +00:00
Alx Sa 5b822032c8 widgets: Include filters in GimpBufferSourceBox buffer
Updates the code to use gimp_pickable_get_buffer_with_effects ()
which copies over the filters that the user sees when choosing
an Aux Input option.
2025-04-09 12:13:37 +00:00
Alx Sa 8b0185ba8f tools: Don't crash when reading invalid Curves preset
When reading a gimp:curves preset file, we assume
that we read in at least 64 bytes for the header. If the
invalid preset file is smaller than that, g_input_stream_read_all ()
can read it just fine but the code fails when comparing the
bytes read in to the size of the header.

This means that the GError object is still NULL, so g_prefix_error ()
has no effect - and thus the calling code crashes when it tries
to get "message" from a NULL GError object.

To resolve this issue, we check if error or *error are NULL.
If so, we set the error with g_set_error () instead.
2025-04-07 18:57:31 +00:00
Jehan c893a96298 Issue #13367: show commit in about dialog in all non-release builds.
The commit hash is not that useful on releases, even for unstable
releases, because a release is always at a known tagged commit anyway.

Note that I only change this for the About dialog where it's less
visible, and not on the canvas, because I do appreciate that stable
series show with a clean empty canvas. I like stable series to be closer
to a release state (even though it's true that having the commit hash
accessible somewhere for dev/continuous build is a useful feature).

Sorry to translators too! I break the string freeze during the stable
series. It's a string only visible on dev builds anyway, so it's not a
very urgent string anyway. Thanks for all the hard translation work! 🤗
2025-04-06 20:19:31 +00:00
Jacob Boerema 257ac87e9f app: fix #13288 crash when opening a recently closed dock
When at least 3 recently closed docks were present in the Windows ->
Recently Closed Docks submenu, then clicking the middle one caused
a crash. Clicking the top or bottom one didn't cause a crash, but
the submenu was then removed so the other closed docks were not
visible anymore (until restarting GIMP).

It turns out we were removing the whole recent menu, instead of
picking the specific action that needed removing. So now we change
this to get the action_name and use that in the remove call.

Although this already fixes the crash, I added an extra check to
make sure action is valid, and if not we generate a critical. This
way we will notice something is wrong if this happens in the future,
without causing a crash here.
2025-04-04 19:29:04 +00:00
Alx Sa 20cf6d553a tools: Connect MoveOptions and TransformOptions to icon size
Resolves #13044
Same code as 816fb1c6, applied to the Move icon box
in GimpMoveOptions and the Transform icon box
in GimpTransformOptions.
2025-04-04 10:46:23 +00:00
Alx Sa 5a43663f09 paint: Prevent crash on expanding with pattern fill
Resolves #13501
When painting with "Expand Layers" on, we call gimp_get_fill_params ()
to get the color to fill in the new area. However, if the user has set the
fill type to Pattern, the color is NULL. This caused a crash because we
immediately try to set the alpha channel of the color to 1.0 if the layer
has no transparency - and if the color is NULL, that's not possible.
This patch checks if we received a valid GeglColor before trying to
set its alpha channel.
2025-04-02 13:57:24 +00:00
Bruno Lopes e975c1625a meson, app, build: Fix Inno wrongly allowing to unninstall with GIMP running
Inno needs an AppMutex to be aware of GIMP execution so
prevent unninstalling or installing GIMP if still running.

(Unninstalling with GIMP running was making GIMP to not be
fully unninstaled since gimp*.exe process file was opened.
It also could cause problems with settings unninstall.)

(Installing with GIMP running was already not possible
since Inno code in that part is more refined but
that check isn't done before deleting .debug files)
2025-04-01 16:25:47 +00:00
Alx Sa b2b0ad7536 widgets: Set default response to GimpViewableDialog
Resolves #13504
Similar to c997349e, 2.10 users expect that pressing Enter
on dialogues such as Fill/Stroke Path should immediately commit
the operation. This default response may have been lost during the
GTK3 port, so we need to explicitly set the default response with
gtk_dialog_set_default_response () if a GTK_RESPONSE_OK has been
set.
2025-04-01 14:20:22 +00:00
Alx Sa e494538393 pdb: Pass GIMP object when creating text layer via API
After discussing with Idriss, we found that if you create
a GimpTextLayer via the public API, the GIMP object
was not being stored in the GimpText object.
If markup like bold/italics was then applied, GIMP
would crash on saving as XCF because the serialization
code tried to access text->gimp_font_factory.
This patch resolves the issue by passing the GIMP
object into GimpText when we create it via the
API.
2025-03-31 11:07:14 +00:00
Alx Sa 68c7329988 dialogs: "You Installed GIMP" text no longer selectable...
...in Welcome Dialog.
Resolves #13468

Per Jehan, there is no need for this text to be selectable,
especially as the other text on the Welcome Dialog is not.
This patch removes gtk_label_set_selectable () for the
"You installed GIMP x.y.z" text to keep it consistent.
2025-03-30 17:34:50 +00:00
Alx Sa befc8ed444 widget, themes: Highlight selected device in GimpDeviceStatus
Gives GimpDeviceStatus a CSS class so
we can apply custom styling to the
selected device, similar to GIMP 2.10's
style.
2025-03-26 14:35:37 +00:00
Idriss Fekir ea5fff1b3f app: Keep the current font in use if the font searched for doesn't exist
Whenever the font in the Context (e.g. through selecting another font
from the fonts list) changes, a signal is emitted to propagate the
change to the active text layer, but if the font is set to NULL in
Context, we don't want that to propagate (because this would change the
current text's font to some fallback font).

In other similar codepaths (e.g. brushes) this is not a problem because
selecting a brush that doesn't exist will prevent painting until an
existing brush is selected.
2025-03-23 21:35:53 +00:00
Denis Rangelov 292220ff97 app/widgets: Replace confusing Search Actions icons with toggles 2025-03-23 18:56:22 +00:00
Jacob Boerema 5f7a136685 Revert "app: fix #12475 Eraser tip uses same tool as pen tip"
This reverts commit 68422e3c70.
2025-03-23 17:49:45 +00:00
Alx Sa 47224ba1a6 widgets: Improve spacing between toolbox widgets
The default value of the number of
children in a GtkFlowBox row is 7.
Since we only have 3 widgets in the toolbox
area, this caused them to be scrunched
over to the left. This patch improves the
spacing to match the widget count.
2025-03-23 14:37:45 +00:00
Øyvind Kolås aac8656039 meson, app: depend on GEGL 0.4.58 2025-03-23 15:33:25 +01:00
Alx Sa b1d1699f14 widgets: Use different color for Histogram borders
GimpHistogramView uses the widget's foreground color
to draw both the histogram and its border. This causes
clipped values to blend into the sides of the border,
preventing the user from seeing them.

This patch gets the luminance value of the foreground
color, then uses that as a threshold to lighten or
darken the border color for contrast.
2025-03-21 13:25:20 +00:00
Alx Sa 72964efb29 app/tools: Reorder Line Art Detection options
This patch moves the Stroke Threshold spin scale to
be on top, like similar tool option groupings such as
Dynamics Fade Options.
2025-03-20 14:25:59 +00:00
Jehan 187bb014d7 Issue #13138: crash when choosing a brush. 2025-03-20 02:41:33 +01:00
Anders Jonsson 9b708c3f7f app: mark rendering intent strings for translation 2025-03-19 19:06:10 +00:00
Øyvind Kolås fc35864880 meson, app: depend on GEGL-0.4.56 2025-03-16 15:38:41 +01:00
Alx Sa 206273c6b5 core: Add version 23 to XCF switch statement
Resolves #13124
In 3f3b29ba we bumped XCF version to 23 due to
new blending spaces. However, we did not update
the version check switch statement to accept this
version. This patch adds a new case to handle version
23.
2025-03-15 18:23:07 +00:00
Jehan 5272618512 app: fix wrong offset of layer buffer with pass-through groups. 2025-03-14 18:53:57 +01:00
Alx Sa 4d8073a3a0 widgets: Prevent crash when converting to indexed image
Resolves #13092
GIMP crashed when converting an image to indexed mode,
if the user first changed the color in the Configure Grid
Dialogue. This was because signals were not being
properly disconnected from GimpColorMapSelection
after the dialogue was closed.

Jehan found the solution, to replace 
g_signal_connect_swapped () calls with
g_signal_connect_object () and flags set to
G_CONNECT_SWAPPED to retain the original
behavior. This ensures the signals are disconnected
after the widget is destroyed on dialogue close.
2025-03-14 15:18:48 +00:00
Jehan bf144eba1b Issue #13057: partly rendered passthrough layer group inside passthrough layer group.
So the problem was that the duplicated image (as returned by
gimp_export_options_get_image()) was not fully rendered. I think it is
related to the computed size of pass-through group layers (whose borders
may show actually smaller than their actual render which is in fact
composited with below layers).

I am not perfectly happy with my solution as I'd have prefered fixing
the source issue, but it is good enough, just a few before GIMP 3.0
release.
2025-03-14 00:54:31 +01:00
Jehan 8bf314f47a app: use the mode node output on a pass-through group with no filter.
The call to gimp_drawable_merge_filters() on a group set a buffer to the
group layer (a bit like when we rasterize text layer) which was why it
worked fine. But when the group had no filter, we didn't have this side
effect.
So let's make sure we use the mode node output as our merged layer's
buffer in such case.

Also when the bottom layer (to merge) is a pass-through group, we don't
want to disconnect its input.
2025-03-14 00:54:31 +01:00
Alx Sa 731766e9bc vectors: Remove debug printout when Snap to Active Path on
Resolves #13096
In 5a43a464, some debug output was added to help
diagnosis a problem when Snap to Active Path was
turned on. The issue seemed mostly resolved in e57ad0f8,
but the print statements were left in. This leads to
slowdown when moving layers while Snap is enabled
(due to the continuous print statements).

As it's been 19 years since the original commit, it
should be fine to remove these debug statements
to boost performance.
2025-03-12 20:29:54 +00:00
Jehan f628b1715f Issue #13058: passthrough layer groups with filters don't merge correctly. 2025-03-11 17:18:42 +01:00
Jehan 388e346a5c app: further fix merging a pass-through group when opacity < 1.0.
Just using the output of the group is not enough since the pass-through
mode cannot be reused for the normal layer (and anyway all below layers
will have been removed). This still works out with a full-opacity
pass-through, but for lesser opacity, what we want is to replace with
not just the group's render, but in fact the render after the
compositing node.

As far as my tests go, we should now have exactly the same render before
and after merging a pass-through group, whatever the group opacity.
2025-03-11 17:18:42 +01:00
Alx Sa 7013fad34d core: Use selection when updating GimpBrushClipboard...
...and GimpPatternClipboard

Resolves #10046
After 1b64fdf5, gimp_get_clipboard_object () no longer
returns a merged version of the selected area.
This affected the Clipboard Brush, Clipboard Mask,
and Clipboard Pattern, causing them to always use the
entire image instead.

To restore the 2.10 behavior, we check if the pasted
image has a selection. If so, then we call 
gimp_selection_extract () to get the buffer of the
selected area. We also need to unreference this
buffer afterwards, so a boolean check is added once
the buffer has been copied over to the brush and
pattern.
2025-03-11 12:40:08 +00:00
Jehan f3eb02b2f0 app: merging a pass-through group should merge all visible layers below it.
Existing logic to merge a pass-through group layer was wrong because it
was changing the global rendering of the image as though the group was
in fact in Normal mode.

Instead a pass-through group can be kinda considered as a Normal group
which would contain not only its children, but also all visible sister
layers below it. Therefore the new pass-through group merging will be
taking the real pass-through group render into the new layer (we don't
change the original group's mode before copying the render anymore), set
to Normal mode, then we remove not only the pass-through group but all
its big sister layers below it on same level.

Organizational-wise, it may seem unexpected because "merging" this group
leaks outside it (getting rid of not only the children but also the big
sisters and cousins). Nevertheless this is exactly how this group mode
works after all. So let's go full-in.

After discussing on IRC with Wormnest and NikcDC, we decided that it was
worth doing this specific merge the technically proper way, and we would
just educate people through the docs on why this group mode is very
particular this way.
After all, if someone absolutely wants the old-style merge, they can
always manually change the group to Normal mode first before merging.
But if they let to "Pass-Through", we should assume this is the render
they want.
2025-03-11 12:43:43 +01:00
Jehan db8be0c28c app: fix order of context reset when exitting.
Some data in a GimpContext may have a reference to a GimpImage. In
particular there may be a GimpLineArt when the bucket fill tool is ON
when exiting GIMP.

In such a case, gimp_exit_idle_cleanup_stray_images() would see a
remaining GimpImage, would believe it's a stray image left by a plug-in,
output an INFO message and free it, which would in turn produce various
CRITICALs when actually finalizing the GimpContext.

Therefore we move gimp_contexts_exit() into gimp_exit(), and not when
disposing of the Gimp object (which happens too late).
2025-03-11 12:43:43 +01:00
Øyvind Kolås 9f73ecaa6d meson, app: depend on babl-0.1.112 2025-03-10 12:59:12 +01:00
Alx Sa 121a997af5 app/tools:
Resolves #12967

In cdd51740, we added a destructive option
for filters. Since toggling this moves the filter
to the bottom of the stack, we refresh the
layer.
However, layer masks and channels can not
yet have filters applied non-destructively,
so this code created unnecessary undo history
items when commited. This patch adds a
check so that we only refresh layers and
layer groups for now. Once we have NDE
filters for layer masks/channels, we should
revisit this code.
2025-03-10 01:22:12 +00:00
Idriss Fekir 5782643b5c GimpFontFactory: Fix exporting to pdf
Adding xml configs for bold/italic broke exporting to pdf (all fonts
were fallback) because fontconfig considered the xml malformed.
2025-03-09 23:05:07 +01:00
Idriss Fekir 2392709d06 GimpFontFactory: Use family+style as display when possible
Fullname might not be suitable for display (e.g. if contains family and
style with no whitespace between them), so when available,
use "family style" for display instead.
2025-03-09 23:05:07 +01:00
Idriss Fekir 06d2af7b35 GimpFontFactory: Fix display name of some fonts
Sometimes there is more than one name in the font file, the heuristic to
use the second name instead of the first assumed that the first name is
in english and the second is in the font's primary language, but that's
not the case.
e.g. on Windows "Times New Roman Italic" second name is "Times New Roman Cursiva".
2025-03-09 23:05:07 +01:00
Idriss Fekir 1609197792 GimpFontFactory:Fix bold/italic custom xml config
Previously buttons in the style editor meant just "faux" bold/italic,
which is different from the behaviour of 2.10, where real bold/italic
was used if available.

Unfortunately this might break in some cases if fontconfig doesn't return the correct face,
but at least it's consistent with 2.10.
2025-03-09 23:05:07 +01:00
Alx Sa 975d1a4aa3 core, display: Enable resize for GUI layer copying
Resolves #12428 (for now)

As noted by Thomas Manni, GimpDrawable
does not initialize its push_resize_undo value
except via gimp_drawable_new ().
If the drawable is created in some other way,
it defaults to FALSE and does not save the
original size in history when resized or cropped.

Thomas proposed initializing it to TRUE in
the init () function. This is likely the correct
approach, but could cause some new bugs
right before the 3.0 release.

For now, this patch calls 
gimp_drawable_enable_resize_undo () for
GUI-specific operations (like opening as
layers or dragging and dropping layers) to
fix the regression for 3.0. Afterwards, we
can spend time confirming the init ()
approach and switch over to that.
2025-03-09 16:06:35 +00:00
Jehan 691a3d2478 app: fix some memory usage bugs.
- One leak when returning early.
- One possible usage after free in a specific case.
2025-03-08 01:53:36 +01:00