Commit graph

25627 commits

Author SHA1 Message Date
Gabriele Barbero
f089ed69d7 tools: prevent on-canvas text editor from being dragged outside the image bounds
This commit prevents the on-canvas text editor from being dragged outside
the image bounds by checking the overlay's position and adjusting the
coordinates to keep it within the canvas. Additionally, it checks whether
the overlay is entirely outside the canvas and, if so, pushes it back inside.
2025-10-31 15:39:10 +01:00
Gabriele Barbero
791f9616fe move style_overlay_offset_[xy] to text_layer 2025-10-31 15:39:10 +01:00
Gabriele Barbero
dc1bd701ac tools: add icon to restore on-canvas text editor position
This commit adds a button inside the on-canvas text editor
that restores the editor to its original position after it has
been moved. The button is only visible when the editor has been
moved, and disappears when it returns to its default position.
2025-10-31 15:39:10 +01:00
Gabriele Barbero
a193d45ab8 tools: implement restore option for on-canvas text editor ...
... to reset its position via right-click menu

This commit adds the ability to restore the original position of the
on-canvas text editor after it has been moved, by accessing the option
from the context menu opened with a right-click on the text box.
2025-10-31 15:39:10 +01:00
Gabriele Barbero
83497695fd tools: store the on-canvas text editor position per text layer
Once the on-canvas text editor has been moved, its position should be
preserved across editing sessions. This commit stores the editor's
position per text layer and restores it when the layer is activated again.
2025-10-31 15:39:10 +01:00
Gabriele Barbero
bd6fc8594a tools: fix on-canvas text editor position on screen after being moved
After the on-canvas text editor has been moved, it should remain fixed
on the screen when zooming or panning the canvas. This commit preserves
the current behavior when the editor is in its original position, and
fixes its position on-screen after it has been moved.
2025-10-31 15:39:10 +01:00
Gabriele Barbero
dae8472d58 tools: allow on-canvas text editor to move
This commit implements the ability to freely move the on-canvas
text editor across the screen by introducing a drag-and-drop mechanism.
2025-10-31 15:39:10 +01:00
Jehan
bfd414ead9 Issue #9463: select back the previous tool when halting a layer effect.
This implies both when canceling or committing a filter.

Part of the fix is that we don't store filter tools as part of the tool
history, which means that when we swap back to the previous tool, the
filter tool info is dropped as though we never went through it. This
way, filter tools don't actually look as other tools (even though they
technically still are, since this is how we can implement canvas
interaction for some of the filters).
2025-10-31 13:54:59 +01:00
Jehan
dddca29423 app: move the tool swapping code to tool manager and action to tools-action.
Per review, let's avoid having all the tools history in every
GimpContext.

Also a further commit will work on special-casing filter tools, which is
why we are storing up to 3 tool infos, instead of only 2.
2025-10-31 13:54:59 +01:00
Jehan
eeb419a363 Bug 373060 - allow to easily switch to last used tool.
New action "Last Tool" ("context-tools-swap"), defaulted to <shift>X.
Thanks to Damien de Lemeny for the original patch and Alexander Hämmerle
for the test case in test-ui.c.
2025-10-31 13:54:59 +01:00
Jehan
a5fe4f1ca5 Issue #11613: crashing when freeing window handle (again).
This is a followup of commit 0ff960c45b which was the right fix, except
that we must make sure that gimp_widget_free_native_handle() is called
**before** chaining up with the widget's parent dispose().

Failing to do so, the first parent's dispose() was destroying the
associated GdkWindow, which made it impossible to call
gdk_wayland_window_unexport_handle() on it. And therefore we were still
getting handle callbacks possibly run after the window was destroyed, if
we were very fast enough to destroy a window immediately when it is
being shown.

I was still experiencing a crash when closing the Export file dialog
very fast with Esc while it was reappearing after canceling a plug-in's
export dialog.

This followup commit reorders the one case where we still had the crash
because of this order issue, and adds some docs comment to tell
developers how to use the freeing function.
2025-10-30 18:53:00 +01:00
Alx Sa
b420a7738c app, pdb: fix gimp_drawable_get_sub_thumbnail() on high-bit depth drawable.
Resolves #13598
Applies the same logic designed by Jehan
in f78a0629 to the gimp_drawable_get_sub_thumbnail
function.
This allows GimpZoomPreview and
GimpDrawablePreview in older
plug-ins to show correct previews for
images that are larger than 8-bit.
2025-10-30 01:16:25 +00:00
Jehan
8d37eab190 app: store meta extensions in pluginrc.
This is a followup to commit 9a36698915. Without this, we get shown the
meta extensions only on the first run after an update.
2025-10-29 23:25:36 +01:00
Jehan
f78a062950 app, pdb: fix gimp_drawable_get_thumbnail() on high-bit depth drawable.
This bug had several causes:

* gimp_drawable_get_thumbnail_data() is pretty crappy as it just returns
  dimensions and bpp. You get no real format information.
* When using it to create a GdkPixbuf, which seems like the most common
  usage, only sRGB (with or without alpha) in 8-bit is supported by
  GdkPixbuf.

So I'm just making sure that private _gimp_drawable_thumbnail() PDB proc
is only returning 8-bit sRGB(A) data. For thumbnailing, this is probably
fine anyway.

Fixes when calling gimp_drawable_get_thumbnail() on an item from a
high-bit depth image:

> LibGimp-CRITICAL **: 20:12:21.028: file ../../../../../../../dev/src/gimp/libgimp/gimppixbuf.c: line 112 (_gimp_pixbuf_from_data): should not be reached
2025-10-29 20:13:17 +01:00
Alx Sa
4812fddc5c widgets, actions: Allow multi-select in Document History
This patch enables multiple selections in
the GimpDocumentView widget and dockable.
It also updates the "documents-open" and
"documents-remove" actions to check if the
GimpContainerView has more than
one selection, and if so, tries to load/remove
all of those images. The action wording is
slightly edited to indicate multiple
images can now be opened/removed.
2025-10-29 14:40:19 +00:00
Jehan
578aee8c62 app, libgimp, pdb: make an early check on parasite name.
Let's make sure we won't trigger CRITICALs on core from a plug-in.
2025-10-28 16:17:16 +01:00
Jehan
95d580aa3a Issue #14014: fix removing parasite using already freed parasite's name.
gimp_image_set_simulation_intent() attachs a "image-simulation-intent"
parasite which means that it first detaches and frees the one which was
deserialized from the XCF. When calling gimp_parasite_get_name() on this
later on, we were working on a dangling pointer. It means that the fact
we didn't have crashes most of the time was the unexpected part, not the
crash itself!

Same for gimp_image_set_simulation_bpc() and "image-simulation-bpc"
parasite.

The fix is to swap the order of statements to first detach the parasite.
2025-10-28 15:57:27 +01:00
Jehan
db8310a545 app: indentation fix.
Was just itching when looking at it!
2025-10-28 14:13:13 +01:00
Jehan
1fa3bc8e51 Issue #14014: do not allow NULL or empty parasite name.
This reverts commit 7b023177a8 and reimplement it as a CRITICAL because
if this happens, a bug has occured. If so, we don't want to hide the
bug, we want to be warned of it so that we can investigate further.

Clearly it should simply not be possible to create a parasite with a
NULL name. First if we look at xcf_load_parasite(), we were already
returning early when the name was NULL. Also even the constructor
gimp_parasite_new() has an early check and will return NULL on a NULL or
empty name.

So the question is: how come we had a parasite with NULL name (if that
is really the problem)? I don't have the answer to this and it's
possible that this bug had already been fixed somehow. But in any case,
if it happens again, we'll want this CRITICAL to run.
2025-10-28 13:48:48 +01:00
Jehan
d320b85115 app: also check for an empty name.
I'm looking at #14014. It's probably not the problem either, especially
as gimp_parasite_new() would return a NULL parasite anyway with an empty
name.

But better be thorough and output a sensible error as soon as possible
when loading a XCF.
2025-10-28 13:48:48 +01:00
Jehan
9a36698915 Issue #15152: Export to bzip2, gzip, xz gives warnings.
We could have tweaked further the code to guess what is a meta file
procedure or not (what we have done until now) but I decided to be more
explicit and added gimp_file_procedure_[gs]et_meta() functions to
libgimp to tag a specific import/export procedure to implement a meta
format.

gimp_file_procedure_set_extensions() would still be used to list well
known formats using this meta format, for instance "hgt.zip" or
"xcf.xz,xcfxz" but the meta extension (simply "zip" or "xz"
respectively) would be used as such. No more "guessing" using the list
of extensions and assuming that at least one of them would have a dot
within.
2025-10-28 12:34:58 +01:00
Gabriele Barbero
7b023177a8 core: check for NULL name in gimp_parasite_list_remove
Sometimes, probably due to a metadata corruption, a pasarite with a NULL
name can be present in the parasite list. This causes a crash when
trying to remove it, because `gimp_parasite_list_find` does not accept NULL
keys. This commit adds a check for NULL names in `gimp_parasite_list_remove`.
2025-10-28 00:27:51 +00:00
Jehan
8f9b742b51 Issue #14799: sync source and filtered container freeze count at creation.
This one was happening very rarely, which made it hard to track, though
I think it would happen more frequently to people with a lot of fonts
(and therefore font loading would take a lot of time) since the
problematic situation occured when the thread callback
gimp_font_factory_load_async_callback() would run after the
corresponding tagged container was created in constructor
gimp_data_factory_view_constructor().

When this happened, the source and filtered containers were not
synchronized regarding their freeze count. And in particular, the
filtered container would have one less freeze and would try to thaw once
the thread callback ran and thaw the source container, which was
provoking the CRITICAL.
2025-10-27 16:39:55 +01:00
Alx Sa
cb552d3dc0 widgets: Turn off default search in ComponentEditor
Resolves #9324
In GTK3, a default "Search" is enabled by default in GtkTreeView.
While in most places we override this with our own search feature,
it was not explicitly set for the GtkTreeView in the GimpComponentEditor
in the Channel dockable. So, it defaulted to TRUE and created an
unnecessary pop-up whenever you typed after clicking a channel.

This patch calls gtk_tree_view_set_enable_search () and turns off
this default feature.
2025-10-27 13:27:45 +00:00
Alx Sa
0b51633021 text, pdb: Connect text outline unit to PDB 2025-10-25 12:00:52 -04:00
Jehan
81795bfb9f app, libgimp, pdb: also mark images returned by a GimpLoadProcedure as clean…
… and reset their undo stack.

This is a followup to #14463 as I realized that images opened directly
by a load procedure may still be dirty, first if the plug-in developers
didn't think of cleaning themselves the image at the end, but even as we
add some metadata which adds an undo step too. So even if the plug-in
developer made a perfect job, the image would still end up dirty if it
has metadata!

Let's just make so that GimpLoadProcedure clean the image explicitly.

Note that other types of plug-ins creating images won't have such code
as we cannot anticipate every case. In fact, in some use case, maybe
someone may want a plug-in to return a dirty image with undo steps! At
least for load procedures, we can consider these pretty standardized,
knowing we want them clean upon loading.
2025-10-24 03:25:15 +02:00
Jehan
313445b4cf app, libgimp, pdb: fix docs of gimp_file_load() and gimp_image_is_dirty().
See commit 822c26f709. We decided to solve #14463 by having
gimp_file_load() always force-clean the image and reset the undo stack.
Therefore fix the docs again.
2025-10-24 03:00:16 +02:00
Jacob Boerema
9cbc928758 app, libgimp, pdb: improve Image class API docs
This mostly turns references into clickable links in the online
documentation for the Image class.
2025-10-24 00:45:15 +00:00
Jacob Boerema
2d850fe2de pdb, libgimp, app: update API docs for is_dirty and file_load
Closes #14463
2025-10-24 00:45:15 +00:00
Jehan
a9dce982a6 Issue #13787: ignore GimpControllerMouse when migrating controllerrc.
As said in previous commit, this controller was removed as commit
76ddf4421c. Unfortunately we can't easily remove the full
(GimpControllerInfo) record, unless we were to redo or enhance the
migration code, because current code works line by line.

Nevertheless this change is enough to render the GimpControllerInfo
object invalid in a way where we can detect and clean it out (cf.
previous commit).
2025-10-24 02:24:53 +02:00
Jehan
57f8e233f7 app: clean the controller manager off invalid controllers after…
… controllerrc config file deserialization.

This is the first part to handle #13787 and not a bad idea by itself
per-se, since we remove one way to crash GIMP by creating an invalid
controllerrc file.
2025-10-24 02:24:53 +02:00
Jehan
22c8860877 app: fix splash display in certain conditions. 2025-10-24 02:24:53 +02:00
Jehan
a67bd8b9e4 app: fixing more broken parasite name for custom config parasites. 2025-10-24 02:24:53 +02:00
Jehan
822c26f709 Issue #14463: is_dirty() returns wrong value for newly loaded image.
I've been hesitating because we can consider this an API behavior
change. On the other hand, it just feels like an obvious bug. It makes
sense that all images loaded with gimp_file_load() are loaded clean and
without any undo history. So let's just fix it.
2025-10-24 02:24:53 +02:00
Alx Sa
d63a82d53e libgimp: Add GimpParamRasterizable to parameter list 2025-10-23 17:52:58 -04:00
Jehan
a43b894f53 app: fix a string leak. 2025-10-23 01:18:58 +02:00
Jehan
2edd6ccb95 app, pdb: do not push undos on rasterizables when loading a XCF.
Fixing:

> GIMP-CRITICAL: gimp_image_undo_push_rasterizable: assertion 'gimp_item_is_attached (GIMP_ITEM (rasterizable))' failed

… when loading the XCF from #14131.
2025-10-23 01:16:58 +02:00
Jehan
75d9fc6d9a gimp-ux#681: forbid merging pass-through layer groups.
Though I did fix the render bugs with commit 833e5858a3, merging
pass-through groups is still quite confusing. Furthermore, it feels like
whoever would use such group mode would not want to merge it because the
whole point of this mode is having a group which doesn't act like a
group!

So let's just forbid merging these, display a status error and blink the
pass-through group to attract attention to the problem.

Note that it doesn't prevent flattening the whole image, or merging the
visible layers (even if there may be pass-through groups in there).
These will work fine, even with pass-through groups, now. And this is a
case where we don't expect any layer to stay around anyway, so it's not
confusing anymore.
2025-10-23 00:05:49 +02:00
Jehan
a5ac6eb9c1 app: fix merge visible layers when there are pass-through groups. 2025-10-22 23:58:56 +02:00
Jehan
833e5858a3 app: fix merging a pass-through layer group.
See issue raised in gimp-ux#681.
A merged pass-through is typically bigger than its contents' bounding
box.
2025-10-22 23:57:46 +02:00
Jehan
e7842fea26 app, pdb: improve erroring on "Merge Down".
- Merging down a pass-through group onto a layer below does not make any
  sense, considering how the below layer is the input to the
  pass-through.
- Adding ability to blink problematic items when merge down fails. This
  will help people to figure out what is the problem.
2025-10-22 23:34:30 +02:00
Jehan
1235bf00bd app: factorize auto-rename code into GimpRasterizable.
Rasterizable objects are all created from some side data and can be
renamed automatically based on this data (from the link file for link
layers; from the path for vector layers; from the text for text layers).

So let's share code.
2025-10-22 22:29:19 +02:00
Jehan
5356e86a06 app: fix action label casing. 2025-10-22 19:53:52 +02:00
Jehan
eed69f42c0 app: support a GimpPath as GValue.
Fixes on stderr:

> gimp_g_value_get_memsize: unhandled object value type: GimpPath
2025-10-22 19:33:58 +02:00
Jehan
435963324a app: one more file with Windows newline fixed with dos2unix. 2025-10-22 19:33:58 +02:00
Jehan
1a73a4ddc6 app: edit vector layer with path tool as default edit action.
- Getting rid of the dedicated vector layer options dialog (with fill
  and stroke settings) which appeared when double-clicking on a vector
  layer. This is a duplicated with the Path tool options.
- Double-clicking a vector layer instead will simply start the Path tool
  (same as double-clicking a text layer starts the Text tool).
- The path choice settings only is missing from the Path tool options.
  Instead of moving it there, I move it to the generic layer options
  dialog. I don't think it's the kind of setting you really change often
  (most of the time, you likely just make a new vector layer).
- Offsets are ignored too and hidden for vector layers.
- Also making sure that the path changes shows live when editing the
  setting in dialog, but it is properly reverted if canceling the
  attributes edition.
- Also make sure the undo step changes the path back.
2025-10-22 19:33:58 +02:00
Alx Sa
f302d42f5d display: Allow URI drag-n-drop to image tab bar
This patch connects GimpImageWindow's notebook
header to respond to external file/URI drag-n-drop.
If you drag files onto the image tab bar, it will create a
new image for each file.
Code based on a similar feature in gimpdisplayshell-dnd.c.
2025-10-21 01:06:53 +00:00
Gabriele Barbero
6719f28319 tools: use primary_mask for unformatted paste in text tool
The analogue of Control key on macOS is the Command key, this means that
`GDK_CONTROL_MASK` has not the expected behavior on macOS. This commit
changes the modifier for unformatted paste in text tool from Control to
Primary, which maps to Command on macOS and Control on other platforms.
2025-10-19 14:28:30 +02:00
megakite
ac13449142 app, menus: Support pasting unformatted text in Text Tool
This patch adds a Paste Unformatted Text item inside the
right-click menu of Text Tool, which allows user to paste
previously copied, possibly formatted (marked) text as plain
text with no markup.
2025-10-19 03:22:49 +00:00
Jehan
f175004be3 Issue #15099: --no-interface mode broken on macOS. 2025-10-16 01:26:25 +02:00
Jehan
11dc1c6b47 app: revert to previously selected drawables when getting out of quick mask. 2025-10-16 01:03:25 +02:00
Alx Sa
931f60923a core: Commit NDE filters on Quick Mask exit
Per Reju, NDE filters are not factored into the selection
created when turning off the Quick Mask.
This patch adds a call to gimp_drawable_merge_filters ()
on exit so that all active filters are merged down before
the selection is made.
2025-10-15 19:36:41 +00:00
Jehan
0358625b1c app: merge button should be insensitive on non-rasterized GimpRasterizable. 2025-10-15 21:07:55 +02:00
Jehan
5622708c0a app: improve layer and path selection logic.
- The "Create New Vector Layer" button is now always active, as long as
  there is an image.
- When a path is selected with no matching vector layer, the button's
  label will be "Create Vector Layer from Path", indicating that it will
  create a new vector layer from the current path.
- When selecting a path while the Path tool is active, let's update the
  selected layers to all the layers (it may be several layers!) tied to
  this path. Otherwise, this can be quite confusing, showing a path
  while another layer is selected, or worse, showing a path while the
  selected layer is a vector layer (but not tied to this path).
2025-10-15 21:07:55 +02:00
Jehan
e960ed0d12 app, menus: delete "layers-vector-fill-stroke" action.
Cf. discussions on IRC with Alx.
Since this is editable directly in the Path tool options, we likely
don't need to have the separate action for it. It feels redundant.

It is still available on a double-click, though I am not sure if it's a
good idea. Maybe the double-click should rather activate the path tool,
from which you can edit all these (just as what happens with the text
tool). To be continued after more UX discussions?
2025-10-15 15:11:03 +02:00
Jehan
0f65d3923e app: show a menu path to advertize how to "Rasterize" and blink the selected layer.
This is the result of a UX session with Aryeom. Just showing a message
forbidding editing of non-rasterized text/link/vector layers is
problematic, because it doesn't help people understand how to unblock
their situation (if they really want to just edit directly the layer).
Additionally we are now blinking the layer.

A possible alternative could have been to pop a dialog up, with the
same message but also with a quick-action button to allow rasterize in a
click (similar to how we are popping a dialog up to revert the
rasterization when clicking on a text layer with the text tool or a
vector layer with the path tool). The problem is that even though the
need to edit directly a non-raster layer arises from time to time, most
of the time, when you use such layers, you don't intend to edit these
(unlike editing text/path with matching tools, you more often wanted to
edit the relevant data).
Therefore it is more often than not just a mistake when you try to paint
directly on such a layer. I.e. that very often, you were intending to
paint on another layer, or add a new layer above your non-raster layer.
Therefore a dialog popping up every time you made such a mistake would
be annoying and workflow-breaking. A simple error message and some
blinking leave for a fluid process.
2025-10-15 14:57:36 +02:00
Jehan
50fd97b28b app: better logic to generically prevent drawing on rasterizable drawables.
The previous code was preventing initializing, but some succession of
actions could go round this check: Rasterize then Revert Rasterize. In
this state, the next click would not try to initialize again, which
first is not very good if the initialization was necessary, and second
would allow drawing on a non-rasterized text/link/vector layer.

So let's just have all the code blocking drawing on rasterizable
drawables in the generic gimp_tool_button_press() code only.
2025-10-15 13:00:44 +02:00
James Addison
ea0574b86c app: allow gimp command-line to run in console mode
When non-interactive mode is requested (the -i command-line flag),
_and_ we've compiled the app with UI support enabled, allow `gimp`
to branch into the console-based version of the app -- equivalent to
running it using `gimp-console`.

This avoids GTK-related failures open a display when one is not
not available (for example, when running `gimp` within a container
or a VM without a graphical display).
2025-10-14 23:20:12 +00:00
Jehan
cf9cfbb4ab app, libgimp, pdb: new procedures gimp_vector_layer_get_(fill|stroke)_pattern(). 2025-10-15 00:12:42 +02:00
Jehan
c5cdea4842 app: copy the rasterization state for all 3 types implementing GimpRasterizable. 2025-10-14 22:06:04 +02:00
Jehan
58d84dfc2b app, pdb: check the real instance type to determine text, link and vector layers.
Without this, libgimp was creating raster GimpLayer objects when these
had been rasterized, which only made kinda sense when the old "discard"
procedures were not reversible. Yet even this was not entirely true,
since it was still possible to undo, but unfortunately these objects are
long lived. Once you get a GimpLayer, it won't ever change into a
GimpTextLayer (or others)!

So we need to have an object of the correct child type then we'll use
gimp_rasterizable_is_rasterized() to decide how to make use of the
object.
2025-10-14 22:06:04 +02:00
Jehan
8c07034dcf app, libgimp, pdb: fix authorship and initial version for vector layer API. 2025-10-14 21:11:09 +02:00
Jehan
58262ceda8 app, menus: rename layers-retrieve to layers-revert-rasterize.
Based on the label, and also "retrieve" was just too generic. It made
sense in the context of rasterizable items, but with the more generic
"layers" context, it would raise uncertainty.
2025-10-13 18:00:10 +02:00
Jehan
172d4356c5 app, libgimp, pdb: convert several files newlines with dos2unix. 2025-10-13 18:00:10 +02:00
Jehan
6f69a16e0a app, libgimp, pdb: remove specific functions now in shared GimpRasterizable API. 2025-10-13 18:00:10 +02:00
Jehan
67a04ba3b2 app, libgimp, pdb: port GimpRasterizable interface to libgimp too. 2025-10-13 16:37:25 +02:00
Jehan
d593cb3230 app, pdb, po: new GimpRasterizable interface.
Share the whole rasterize logic of the text, link and vector layer into
an interface. I didn't write it as an abstract parent class, because we
might have more rasterizable items in the future, which may not be
layers (e.g. there were discussions of vector masks).
2025-10-13 15:37:11 +02:00
Jehan
59c0e1ae6e app: remove useless heading newline. 2025-10-13 15:37:11 +02:00
Jehan
9d45f41868 app: properly react to the currently selected vector layer being rasterized.
Also properly factorize the set_layer() code, avoiding duplicating the
(dis)connecting signal handler code in various places.
2025-10-12 19:58:28 +02:00
Jehan
2962362884 app, libgimp, pdb: fix markdown-like syntax.
We need 2 lines in the PDB for it to be an empty line in the C file,
which in turn will be interpreted as markdown-like lists for the
gi-docgen generated HTML docs.
2025-10-12 17:22:18 +02:00
Alx Sa
e224278517 app, modules: Resolve unused Windows variable warnings
This patch adds moves several variables that are not used
on Windows to #ifndef G_OS_WIN32 blocks to prevent
warnings on Windows builds.
2025-10-12 14:06:04 +00:00
Idriss Fekir
c5bd321570 GimpFontFactory: don't match postscript name on Skia font family
Pango shows all fonts in the family as "Skia Bold", unless the psname is not matched
so we make an exception for skia and don't match on psname in the custom fontconfig xml.
see issue 14659.
2025-10-12 10:10:29 +02:00
Jehan
a46d0c3117 app, libgimp, pdb: further improve function documentation.
- Consistently add the text about inserting items into the image after
  creation, with correct function links/references.
- Consistent grammar for function blurb.
- Make @name argument nullable for gimp_path_new().
2025-10-11 22:10:30 +02:00
Jehan
93fa9ca32e app, libgimp, pdb: make for more consistent function documentation. 2025-10-11 18:54:30 +02:00
Jehan
4752246f8a app: minor coding style cleanup. 2025-10-11 00:04:45 +02:00
Jehan
e86e0fb54c app: sync undo label with action label. 2025-10-11 00:02:38 +02:00
Jehan
1e88cfd70f app: make the "Create New Layer" option work properly.
It will duplicate the current path, create a new vector layer based on
it and will let one start editing it.
2025-10-10 23:40:54 +02:00
Jehan
0725b023cd app: add "Confirm Path Editing" dialog on Path tool similar to the…
… "Confirm Text Editing" one on Text tool.

When selecting a rasterized vector layer, this will suggest to edit it
anyway (hence losing any modification since rasterization), create a new
layer based off the same path, or cancel.
2025-10-10 23:34:37 +02:00
Jehan
7c7f7b4898 app, libgimpwidgets: add 2 new icon macros.
New libgimpwidgets icon macros: GIMP_ICON_LAYER_LINK_LAYER and
GIMP_ICON_LAYER_VECTOR_LAYER. Note that the actual icons still need to
be done so I use temporary actual icon designs for now.

Also adding some TODOs for these.

Fix run warning:

> WARNING: icon theme has no icon 'gimp-vector-layer'.
2025-10-10 23:34:37 +02:00
Jehan
c3075f9ee9 gimp-ux#252: update "layers-retrieve" label.
Per discussions with Alx, this wording would increase connection with
the "Rasterize" action. Also, even though it feels slightly improper
English, if we treat "Rasterize" like an action name, then it does make
sense in English too.
2025-10-10 21:25:39 +02:00
Jehan
8e9c6d7e3c Issue gimp-ux#252: simpler, more to the point, dialog text. 2025-10-10 21:22:48 +02:00
Jehan
0fea05af78 app: indentation fixes. 2025-10-10 20:23:46 +02:00
Jehan
144ce9b897 app: fix updating sessionrc from 2.x to GIMP 3.2.
While "gimp-vectors-list" migration to newer name "gimp-path-list" was
correctly happening from GIMP 3.0 to 3.2, there is a different code path
from 2.x to 3.2 (because the scale factor update can only happen in this
latter codepath). So this part of the migration needs to be duplicated
in both update functions.
2025-10-10 19:39:14 +02:00
Jehan
432c3089fd app: fix migration of "vectors"->"path" renamed action from 2.10.
While the migration code did exist from 3.0 shortcutsrc, we need to
duplicate this for the menurc migration, in case someone were to migrate
from 2.10, 2.8 or older (i.e. installing 3.2 after GIMP 2 without having
ever installed 3.0 in-between).
2025-10-10 12:16:50 +02:00
Jehan
c392d8ea7f app: remove various layers discard action in favor of layers-rasterize.
The following actions are removed: layers-link-discard,
layers-text-discard and layers-vector-discard. The new action
"layers-rasterize" introduced previously will handle all of these.

Since layers-text-discard is the only one which existed until GIMP 3.0,
we are migrating any custom shortcut which may have been set to
layers-rasterize (both from 3.0 shortcutsrc or older menurc).

Action layers-link-monitor is also removed (in favor of layers-retrieve)
but no migration code is added, since this didn't exist in 3.0.
2025-10-10 12:16:50 +02:00
Jehan
a54e13c105 app: fix converting 2.10 menurc to 3.0 shortcutsrc.
Ugh. How did this happen?!
2025-10-10 12:16:50 +02:00
Alx Sa
0cb00e6c5b app/tests: Fix build warning on Windows
A GLogLevelFlags fatal_mask variable was
created inside an #if defined (G_OS_WIN32)
block, below a function call to
gimp_test_utils_set_gimp3_directory (). This
resulted in build warnings on Windows:
"ISO C90 forbids mixing declarations and code"
This patch adds another #if defined (G_OS_WIN32)
at the top and moves the variable declaration there.
2025-10-10 01:01:47 +00:00
Alx Sa
5539a03e2c pdb: Add PDB for text layer outline
This patch adds PDB API to get and set text outline properties,
modelled after similar API for getting vector layer stroke
settings.
2025-10-09 22:41:25 +00:00
Jehan
94568edb64 app: fix Windows-style line breaks with dos2unix. 2025-10-09 21:03:59 +02:00
Jehan
ac46ece4e3 app: make it possible to retrieve discarded vector layers too. 2025-10-09 21:03:59 +02:00
Jehan
3cafc52129 app: fix typo. 2025-10-09 20:46:10 +02:00
Jehan
1ca6faab0d app, menus: new actions layers-rasterize and layers-retrieve.
These 2 new actions are meant to be usable on all 3 types of non-raster
(and non-group) layers, i.e. link, text and vector layers, to
respectively rasterize and un-rasterize them.

This will also work with multiple selected layers, and is not specific
to one type of layers.

I also change how gimp_text_layer_discard() used to work, by marking the
text layer as modified instead of actually discarding all text
information. The main consequence of this was that a layer rasterized
this way was forever lost. Now it can actually be revived as a text
layer, not only through the new layers-retrieve action, but also by
trying to edit it with the Text tool, which will trigger the same dialog
as when a text layer had been rasterized by editing it with a paint
tool.

Whereas the label of "layers-rasterize" seem to be quite straightforward
(simply "Rasterize" per discussions in gimp-ux#252), I am really unsure
of the label for "layers-retrieve". Further UX discussions should help
on this front.
2025-10-09 20:41:11 +02:00
Jehan
42783ace78 app: also apply the no-edit on non-raster layers to text layers! 2025-10-08 23:26:24 +02:00
Jehan
5ddb853964 app: globally block editing vector and link layers.
Instead of blocking various drawable-editing tools to work on vector or
link layers, per tool (as in commits 38c379cd92 or 36330a271a), let's
have a more generic logic in GimpTool. We will now block the tool
initialization early when it's destructive and tries to work on link or
vector layers.

By default, all tools are set as being destructive, but we can override
this per-class by setting the class' is_destructive flag. For instance,
text and path tools, or the Zoom or Color picker tools, etc. are
non-destructive.
Filter tools also are non-destructive (they may be destructive, but have
their internal code to disable this path on these types of layers).

Source tools are special-cased because we may allow them to be
initialized on a link/vector layer as sources. For this special-case, I
make a second check on gimp_tool_button_press().
2025-10-08 23:21:59 +02:00
Alx Sa
221a50741a text, libgimpbase: Move text enums
This patch moves the enums for GimpTextOutline
and GimpTextOutlineDirection so that they are
accessible to plug-ins/scripts. This will allow
for us to add PDB functions to get/set text outline
properties.
2025-10-08 11:34:57 +00:00
Jehan
0ae163e43c app: fix partial canvas update when hiding or removing filter on…
… pass-through group layer.

Because of the strength-reduce pass-through to normal mode, we had case
when the effective layer mode of a pass-through group ended up to
Normal, which may shrink the effective bounding box.

Note that getting rid of the GimpGroupLayer's get_effective_mode()
(gimp_group_layer_get_effective_mode()) implementation was also fixing
this issue. I did hesitate a lot because it is also simplifying the code
a lot. But I was also wary about getting rid of the optimization
previously made by Ell (see commit fa9a023c270; note that I haven't
actually tested how efficient this optimization is).

This seems like a good compromise.
2025-10-08 01:23:07 +02:00
Jehan
6095b247be app: special-case pass-through groups' drawable area.
On empty pass-through groups, it was returning a 1×1 area, which
triggered effects with X/Y distance arguments to have no set min/max
values. For instance, a gaussian blue's X/Y scale widgets end up showing
a [0, 1.5] range, making it very impractical to set higher values.
2025-10-07 23:34:55 +02:00
Jehan
85d381bd0c Issue #15004: empty pass-through groups have no size, making it…
… impossible to use them like adjustment layers without additional step.

Even without the "adjustment layer" look-alike use case, this is wrong,
because an effect on an adjustment layer will be only applied on the
area contained in child layers, whereas by definition, a pass-through
layer would use the below render as input, and therefore its output
could be bigger than its child layers box.

I could find commit aa9ae1c65c as a culprit commit, and reverting it
would in fact also fix this issue, though by doing this, we'd regress on
the issue #4634 (I tested with one of the contributed XCF and can indeed
reproduce the bug).

Instead I return the unioned bounding box of the node, and of the
computed one. I do not feel like it's optimal, but this feels like a
complicated issue. It looks to me like there might be another deeper
issue in how both these bounding boxes are computed (not optimally!).

In any case, it also makes empty pass-through groups now usable to apply
directly an effect on the whole below render, as a side effect.
2025-10-07 23:34:55 +02:00
Jehan
f5b94bdc03 app: we also have alias links for RC releases. 2025-10-07 23:34:55 +02:00
Alx Sa
a5182a010f tools: Fix missing cursor for MyPaint Brush tool
Resolves #15001
In the MyPaint Brushes v2 port (ea8b9dc1),
I implemented a cursor_update () function from the
parent class. However, I did not call the parent's
version of the function afterwards, so the MyPaint
Brush cursor was not being redrawn. This patch
adds the call to fix the cursor display issue.
2025-10-03 22:14:52 +00:00