Commit Graph

24193 Commits

Author SHA1 Message Date
Alx Sa efa1267f13 actions: Fix layer buttons relative to floating selections
The anchor and merge down buttons are visible at the same time, which should not be the case.
Their visibility is now dependent on the existance of a floating selection.
The New Group and Search/Link buttons are also disabled when there's a floating section.
2023-11-10 20:33:26 +00:00
Jehan 59116d37f8 Issue #10023: don't use the selected text styling to display the selected items label.
The idea initially came from some styling in Thunderbird. It's not that useful anyway.
2023-11-10 15:28:16 +01:00
Jehan 7f15251d2e Issue #10281: layer locks popup is not appearing. 2023-11-09 15:39:21 +01:00
Jehan eb7337d5e4 Issue #3247: make consistent generated brush preview.
This is only a temporary solution meant to be backported to gimp-2-10 branch,
so that at least the preview now matches how angles always worked in at least
the 2.10 series: angles are measured clockwise.

Now there is the question that in the documentation of the Brush Editor, it is
written that angles are supposed to be counter-clockwise. A solution was
proposed to make them so, but only for generated brushes (whereas angles stayed
clockwise for other types of brush) which is a very bad inconsistency.
Furthermore I find the whole tool options vs. brush editor settings mess quite
confusing. Some decision should be made for GIMP 3.

For GIMP 2.10 though, this should be an OK fix: no behavior change on-canvas,
only making the preview actually match what happens on-canvas (even though it
goes against what the docs say but it's probably better than breaking workflows
relying on actual on-canvas behavior).

Note: this commit is based on an initial proposition by Alx Sa in MR !1119,
except that the patch was only working when the preview needed to be scaled.
Instead we must go through this brush transformation code path for generated
brushes, whatever the scale.
2023-11-05 19:13:11 +01:00
Alx Sa b68a86e486 paint: Don't paint with gradient if dynamics not enabled
Resolves #10262.

The gradient color was being used if Confetti or Color from Gradient
dynamics had been set, even if dynamics had been disabled.
This adds an additional check to make sure dynamics are enabled
first - otherwise, the brush's existing stamp or color is used to paint.
2023-11-02 11:19:16 +00:00
Idriss Fekir b503a3dc1d Fix bug when font is from a .ttc file
When loading an xcf file, if a a font has already
been used, its file's hash is compared against the hashes
from the xcf file (to speedup loading), but if the font is from a .ttc file (a font
collection), then all fonts from that file will have the same file
hash, so the wrong font might be selected. a simple solution is to not
use the hash except as a last resort if every other field is identical.
2023-10-27 15:48:58 +00:00
Jehan 2dcc8eea93 app, libgimp, pdb: remove the internal PDB function _gimp_pdb_get_data_size().
We exchange GBytes structs which know their own data size already and is much
safer.
2023-10-27 10:16:45 +00:00
Jehan 83a5998547 app: do not assume that a procedure is still registered after running.
I had the case when "Sphere" script crashed, bringing down the whole script-fu
plug-in (while trying to reproduce #10214). Then after being run, we get a
dangling pointer to a finalized action object.

Even in successful use cases, we will want to give the ability to unregister
normal plug-ins/procedures wrapped as GIMP extensions, and there is also the use
case of temporary procedures, so I'm sure this bug could be reproducible even in
normal non-problematic runs.
2023-10-26 22:44:07 +02:00
Jehan 4e9a077219 app: data tree views are in single selection mode.
I am pretty sure that this should be in single selection mode because we don't
even really have code to handle cases with multiple brushes or font selected.
Right now, we assume in many places that there is only one font or brush (or
other data) active at a given time.
Yet this code (or older versions of it) is old apparently and I realize that
even in 2.10, I can ctrl/shift click to select several data objects. This is the
weird part.

Anyway let's put this in single selection mode and see how it goes. If there
were actually use cases which I didn't know about, I'm sure we'll soon have
reports.
2023-10-26 20:59:48 +02:00
Jehan 40811be562 app: further improves the cursor choice heuristic with multi-selection.
I could still see annoying scrolling up/down happening when we are deselecting
an item (typically with ctrl-click). In such a case, the cursor is on a
deselected item. Just make it bump to a closest item, preferably a visible one.
2023-10-26 20:50:37 +02:00
Jehan 195ac684a7 app: avoid scrolling up to top item of multi-selected items.
My first versions were commits 98f0c448 then 1d8782915e but the more I go, the
better I understand the implications of the selection vs. the cursor. In
particular, when setting a cursor, which also initializes the selection to this
item only, the tree view would also scroll to this item. The current
implementation, which sets the top item as cursor, is therefore particularly bad
for multi-selection which doesn't fit fully in the view, because we also end up
scrolling up. Say you have a long list of layers, you first select the top
layer, then scroll down to the bottom layer and ctrl-click it: the selection
(now 2 items) works but you end up scrolled back all the way up.

This alternate version is much better, by ensuring that your cursor is at least
within the selection (hence avoiding the discrepancy between keyboard navigation
and pointer navigation, and which was fixed with commit 98f0c448), so that we
don't try to change the cursor when possible.
2023-10-26 18:32:59 +02:00
Jehan 636b38be4f app: fix broken multi-selection.
This was broken in commit 3e101922. Setting a cursor basically resets to a
single selection, invalidating pointer-made multi-selection.

But then we got back the bug it fixes, which is that we must grab focus after
the selection is actually made. So we now grab at the end.

This also had a bad consequence for multi-selection (again): if the focus was
not already on the tree view, gimp_container_tree_view_selection_changed() was
not called. This function was where the actual selection-changing is meant to
happen. So we had to shift-click (or ctrl-click) twice. The first time, nothing
would happen (but focus was given to the tree view). The second time, we could
finally update the selection.

This is why we add 2 different cases of focus grab, which should hopefully
handle all cases correctly, though this code is really extra-complex. This
replaces MR !1128.
2023-10-26 17:19:08 +02:00
Alx Sa f2bf2b7fe3 app: Fix initialization warnings
Initialized values in gimpruler.c and
gimptoolrectangle.c to remove warnings
about uninitialized variables.
2023-10-25 16:15:04 +00:00
Jehan 0383ad350e Issue #9800: GimpAlignOptions' finalize() not properly chaining up.
Since we were not chaining up with parent's finalize(), we were not
removing the instance from the gimp-debug infrastructure which assumed
the object was leaked and would try to read its reference count for
debugging purpose, when GIMP_DEBUG=all was set.

In fact, the object was not leaked, therefore we got into a segfault
when dereferencing already freed memory.
2023-10-21 03:44:32 +02:00
Massimo Valentini 3e101922d8 widgets: Prevent Toolbox autoscroll bug
In Preferences > Toolbox, clicking on an item below the
initial scroll window view causes it to jump to the top
automatically. This patch prevents this by setting the
clicked index in the GtkTreeView before grabbing focus.
2023-10-20 19:19:39 +00:00
Jehan a4b68c5244 app: don't call gimp_align_options_image_changed() on finalized options object.
I had this one crash upon exit, inside gimp_align_options_update_area() as a
consequence of gimp_align_options_image_changed() being called on an image
change. I could not reproduce after this one time and it's very likely a race
condition when everything is getting finalized, and the tool options object is
getting finalized earlier than the user context.

Anyway this should fix the potential crash.
2023-10-20 19:54:30 +02:00
James Golden 22b28df391 app: save dialog now adjusts size up to monitor height
Fixes: #9373
2023-10-20 14:28:30 +00:00
Alx Sa 85d8322c00 widgets: Restore layer/mask highlight on select
Changes were made to the click code for layers & masks
due to the introduction of multi-select, and this seems to
have caused the view highlight to be inconsistent.
This patch adds the gimp_layer_tree_view_update_borders ()
call after a click or selection to fix this.
2023-10-19 10:53:07 +00:00
Alx Sa ad8b47bff7 gui: Change Windows title bar based on theme
On Windows, the title bar can be set to light or dark mode via DwmSetWindowAttribute ().
This adds code to update the main title bar and dialogue title bars based on the current theme.
The main title bar uses "prefer-dark-theme", while the dialogue title bars
uses the color of the widget background to assume the correct color.
2023-10-18 16:48:25 +00:00
Jehan 70438028aa libgimp: PDB procedure arguments are not order-based anymore (API-wise).
As far as plug-in API is concerned, at least the calling API, order of arguments
when calling PDB procedures doesn't matter anymore.

Order still matters for creating procedures with standard arguments (for
instance, "run-mode" is first, then image, or file, drawables or whatnot,
depending on the subtype of procedure), but not for calling with libgimp.

Concretely in this commit:

- gimp_pdb_run_procedure_argv() was removed as it's intrinsically order-based.
- gimp_pdb_run_procedure() and gimp_pdb_run_procedure_valist() stay but their
  semantic changes. Instead of an ordered list of (type, value) couple, it's now
  an unordered list of (name, type, value) triplets. This way, you can also
  ignore as many args as you want if you intend to keep them default. For
  instance, say you have a procedure with 20 args and you only want to change
  the last one and keep the 19 first with default values: while you used to have
  to write down all 20 args annoyingly, now you can just list the only arg you
  care about.

There are 2 important consequences here:

1. Calling PDB procedures becomes much more semantic, which means scripts with
   PDB calls are simpler (smaller list of arguments) and easier to read (when
   you had 5 int arguments in a row, you couldn't know what they refer to,
   except by always checking the PDB source; now you'll have associated names,
   such as "width", "height" and so on) hence maintain.
2. We will have the ability to add arguments and even order the new arguments in
   middle of existing arguments without breaking compatibility. The only thing
   which will matter will be that default values of new arguments will have to
   behave like when the arg didn't exist. This way, existing scripts will not be
   broken. This will avoid us having to always create variants of PDB procedure
   (like original "file-bla-save", then variant "file-bla-save-2" and so on)
   each time we add arguments.

Note: gimp_pdb_run_procedure_array() was not removed yet because it's currently
used by the PDB. To be followed.
2023-10-16 21:56:37 +02:00
Jehan 61e2faed1b app, plug-ins: port "file-gbr-save-internal" to multi-drawable API.
Similar to commit 6905b0bbef for "file-pat-save-internal". For interactive
usage, nothing is changed, but for non-interactive ones, we can now choose a
list of drawables to export.

Pending more changes, relative to the discussion in #7370.
2023-10-16 16:21:42 +02:00
Jehan 2728294063 app: rename "dummy-param" to "run-mode".
Since now the name of arguments will become more important, over order, let's
name the first parameter "run-mode" even in cases when this is a dummy argument
(most often the case when a procedure always acts the same, whether interactive
or not). I keep the mention of the parameter being useless in the nick and blurb
strings, as it's useful information. But let's keep using our "standard" arg
name "run-mode" for this first argument.
2023-10-16 14:49:17 +02:00
Jehan 8e66e5ae58 app: use "num-drawables" consistently for the array size argument of "drawables".
This is the naming we use everywhere else.
2023-10-16 14:45:04 +02:00
Alx Sa bd7423915c gui: Use "minimize" window hint on Windows
Resolves the second half of #300.

This adds conditional code to the gtk_window_present () call in gui.c
to prevent it from running if the user requested it stay minimized in the shortcut
or commandline call on Windows.
It also keeps the splashscreen minimized in that case.
2023-10-15 14:14:06 +00:00
Jehan 6d36e38018 app: fix a quite-random crash on exit with a race condition.
In some very hard-to-reproduce conditions, I experienced
tool_manager_selected_layers_changed() running on an invalid GimpToolManager
pointer (because tool_manager_exit() had already run) and therefore segfaulting
on quit. Let's make sure we disconnect the signal handler.
2023-10-15 11:45:16 +02:00
bootchk 039b25eb6e Fix clang build error void function should not return value 2023-10-11 08:09:54 -04:00
Jehan 1d8782915e Issue #10143: shift selecting is failing to highlight selected layers.
This is a consequence of commit 98f0c448. Apparently setting the tree view
cursor also reset visually the selection. So I make sure I only set the cursor
on the first path in the list of selected items.
2023-10-09 15:59:13 +02:00
Jehan 8f06421781 app: fix gimp-gegl-loops algorithm from commit dbaa8b6a1c.
Using gegl_parallel_distribute_area() for gimp_gegl_is_index_used() is just far
too slow by 2 order of magnitudes compared to a threaded implementation where I
process each buffer at once (but each in their own thread from a pool).
I guess the basic value check is too basic to warrant being done in threads
(note: even growing the distributed area by bumping the thread cost a lot was
not enough).

I didn't fixup commit dbaa8b6a1c directly so that we keep a trace of the
gegl_parallel_distribute_area() implementation in case we can do better later.

Additionally I fixed gimp_gegl_shift_index() to use the full drawable format,
including the possible alpha channel. Otherwise shifting indexes may result in
dropping the alpha value.
2023-10-09 15:44:31 +02:00
Jehan c8de818349 app, menus: Colormap dockable now shows a delete button.
This comes with a "colormap-delete-color" into the "colormap" action group. The
action/button will be insensitive when the selected color is used in the image,
since it is only possible to delete unused colors.
2023-10-09 15:28:20 +02:00
Jehan dbaa8b6a1c app, pdb: make it possible to delete a color from a colormap if unused.
Until now, it was not really possible to delete a colormap color, but since we
now use GimpPalette, people would definitely try to do so. It just makes sense
to allow doing this, but only if the color is unused.

Additionally when we do this, all the pixels refering to bigger indexes will be
edited so that they continue to refer to the same color (bigger indexes are
shifted by -1). Therefore removing an unused color does not change the image
render.

I wondered if we might want more options, e.g. the ability to delete a color
without fixing indexes (i.e. that colors over the deleted color index would
shift to the next color). This would even allow to delete used colors (though
now the last index would have to be unused one, unless we cycle colors).
Yet I don't think this should belong to this basic API. The most expected
behavior when deleting a color from an image colormap is to fix all indexes
stored in pixels so that the image still shows the same. So that's what this
function will do in this generic usage.
2023-10-09 15:28:20 +02:00
Jehan c3c0a70dd5 app: reset the selected index when active palette changes.
This fixes some CRITICAL when switching active image while an item is selected.
2023-10-09 15:28:20 +02:00
Jehan 4d03f7b04b app: also generate filename and save file of duplicate data immediately.
This fixes a CRITICAL when duplicating a resource data.
2023-10-08 23:22:58 +02:00
Jehan d931098d36 app, libgimp, pdb: new gimp_image_get_palette().
This is meant to replace gimp_image_get_colormap() (see also #9477).

We likely won't need a gimp_image_set_palette() because we can simply edit the
image's colormap/palette with GimpPalette API now and it is directly updated.

For instance, the following code changes the first entry in the image palette to
red, immediately:

```python
i = Gimp.list_images()[0]
p = i.get_palette()
c = Gimp.RGB()
c.r = 1.0
p.entry_set_color(0, c)
```

For this to work fine, I added a new concept to GimpData, which is that they can
be tied to a GimpImage (instead of a GFile). Image palettes are not considered
internals, they are just tied to their image, therefore they can be edited by
scripts/plug-ins.

Additionally with this commit, editing an image's colormap from libgimp API also
generates undo steps now.
2023-10-06 22:04:34 +02:00
Alx Sa c54a33f0ff config: Clarify color profile policy (@ellestone)
Original patch by @ellestone.
The current tooltip is somewhat confusing for two reasons: It doesn't 
mention the word "ICC", leaving room for doubt as to what a "color 
profile" might be. And as @TheTooleMan suggested, it's easier to read
and understand if the action (opening a file . . .) is in front of the 
modifier (. . . with an embedded ICC profile) instead of vice versa.
2023-10-06 19:08:40 +00:00
Jehan 98f0c44881 app: set keyboard focus to selected item in GimpContainerTreeView.
When the selection changes, the focus must be on one of the selected items. Not
doing this was creating a very annoying behavior where you would select an item
in the tree view with the pointer first, but then when moving up/down with the
keyboard arrow, the move originated from the previously set item. This was
because the arrow move used the "cursor path", i.e. the keyboard focus, and not
the item selection as origin.

In our case, let's make sure these match (i.e. the cursor path is the path of at
least one of the selected items, which is the most expected behavior for mixed
pointer/keyboard interactions).

See code in gtk_tree_view_move_cursor_up_down() from GTK code.
2023-10-04 15:17:43 +02:00
Idriss Fekir 68aadf4a27 Issue #9979:bold and italic broken 2023-10-04 12:01:06 +00:00
Jehan 04dcd11fd6 app: complete !1073 for case when transformed <shift>num action clashes…
… with another default shortcut.

This won't happen with the standard US layout, but among all the layouts which
exist (or will exist), there is no say that the characters behing <shift>2-5
keys are not another one of our default shortcuts for other actions. We don't
want to print this case, because it is special enough that it's really not a
bug. In this case, we just ignore the transformed shortcut on the zoom action
and be done with it.
2023-10-04 00:11:35 +02:00
programmer_ceds 13ec70bb16 Make Numeric Shift Shortcuts Work (Fixes issue #9798) 2023-10-03 21:44:59 +00:00
Jehan ef65087c2b app: save new data to file immediately.
Calling gimp_resource_delete() on a data with a file which was not stored yet
would fail on missing file as reported by Lloyd in a comment in #9976. We could
just special-case the code to make the already-inexisting case acceptable on
deletion, but there are a few more issues.

In particular gimp_data_create_filename() relies on actually checking file
existence on the file system. Therefore generating the file path too early
(before any possible rename, i.e. for uniqueness or other formatting need) would
easily generate duplicate paths (which means one of the data object would be
overwritten on exit). It's better to kinda *reserve* the set file path
immediately by saving the data file.

The only drawback I could see on saving early is possible I/O slowdown if a
script were to create many data, but I actually don't think it's a valid use
case (no script should likely create enough data files that we would notice a
slowdown, i.e. likely creating hundreds of data objects at once) anyway. So
let's go with it, at least for now.
2023-10-03 14:40:33 +02:00
Jehan fc6c0974ea Issue #9976: gimp-brush-new throws critical. 2023-10-03 00:02:33 +02:00
Jehan eab9d8da28 app, libgimp, pdb: new PDB function gimp_fonts_get_by_name().
It returns all the fonts (possibly more than 1) with a given name. I left the
function gimp_font_get_by_name() as a utility when one don't want to choose (or
is not able anyway, e.g. a script with minimal information), though I wondered
if we should not simplify with a single function (the new one, which is the
correct one now that it is possible to have several fonts with a given name).

It is easy to test with fonts named the same. For instance I could find 2
different fonts, both named 'Holiday'. This call in the Python console returns
both:

> Gimp.fonts_get_by_name('Holiday')

As part of this commit, I also implemented resource arrays (or subtype arrays)
as PDB arguments and return types.
2023-10-02 23:22:49 +02:00
Jehan adce3179d4 app, libgimp, pdb: further fix gimp_text_get_extents_font() and improve…
… description.

- The returned value as width/height/etc. of the glyph extents (or bounding
  box), not "of the font" (which doesn't mean much).
- Adding some definition for ascent and descent. This text is straight out
  copied from Pango documentation comments in pango/pango-types.h.
- I don't see why we were negating the descent value. Let's keep the value sign
  as defined in Pango.
2023-10-02 21:30:20 +02:00
Jehan a898641cd1 app: fix return type.
Fixes:

> warning: returning ‘void *’ from a function with return type ‘gboolean’
2023-10-02 20:56:19 +02:00
Jehan 24a85eebd6 Issue #9987: text related functions crash using string for font name.
- Fonctions were renamed: s/gimp_text_fontname/gimp_text_font/ and
  s/gimp_text_get_extents_fontname/gimp_text_get_extents_font/
- The size_type arguments were removed. Even in 2.10, this argument was marked
  as "dead" and ignored. It was only kept for API compatibility.
- The font name (string) was replaced by a GimpFont argument.

gimp_text_font() is easily tested in the Python console with:

> Gimp.text_font(Gimp.list_images()[0], None, 10, 40, "Hello World!", 1.0, True, 100, Gimp.context_get_font())

And gimp_text_get_extents_font() with:

> Gimp.text_get_extents_font("Hello World!", 100, Gimp.context_get_font())
2023-10-02 20:49:53 +02:00
Jehan a186220e58 app: be more forgiving in reading shortcutsrc.
- First do not write the protocol-version (and therefore don't read it either
  nor compare it to the current one). This file does not depend on the protocol
  version.
- Secondly when reading an unknown identifier, simply print a message on stderr
  for debugging/reference, but ignore it up to the next closing parenthese.
- Finally do not use the file-version as a terminal error as well. When we read
  a shortcutsrc with the wrong version, we still try to read it as best as we
  can. There might be issues, but it's better than fully dropping the whole list
  of shortcuts as it's a pretty important file (people might have spent a lot of
  time tweaking their shortcuts!).
2023-10-02 01:30:02 +02:00
Jehan 0273c1031c app, libgimp, pdb: gimp_text_layer_new() now uses GimpFont.
This function is not perfect and in particular doesn't seem usable with binding
because of GimpUnit being some weird mix between an enum and some kind of class.

So this will have to be fixed too. See #8900.
2023-10-01 21:02:34 +02:00
Jehan ea55b7a11a app, devel-docs, libgimp: updating gimp_text_layer_[gs]et_font() and new…
… function gimp_font_get_pango_font_description().

Also updating file-pdf-save which is the only plug-in using these right now.

Note that I am not fully happy with the new function
gimp_font_get_pango_font_description() because I experienced some weird behavior
in file-pdf-save which is that some fonts were wrong if this is called after
pango_cairo_font_map_set_resolution().
But let's say this is a first step looking for improvements.
2023-10-01 21:02:34 +02:00
Jehan 2f4d625059 app, libgimp, pdb: generate widgets for GIMP_PROC_ARG_LAYER|CHANNEL arguments.
I am using the same GimpDrawableChooser with an additional drawable_type
argument to only show the appropriate tab if we want to limit what can be
chosen.

None of our plug-ins actually use a GimpLayer or GimpChannel only arg so far,
but if we have some day, or if some third-party plug-ins want to have such arg,
now they quite easily can!
2023-10-01 21:02:34 +02:00
Jehan 4be1166982 app, libgimp: disable again cross-process transient setting.
After testing, setting a window as transient to another from another process is
still broken on Windows and it's hard to diagnose without using Windows
directly. Since it's not just broken, but it even hangs the whole process, which
is quite a blocker issue, let's disable again the whole code on Windows.
2023-10-01 21:02:34 +02:00
Jehan 63a97d3be6 app, libgimp, pdb: new PDB group gimpdrawableselect.
Similarly to the various GimpResource select PDB calls, this allows to call a
core dialog in order to choose a drawable which will be returned back to the
calling plug-in.

This new GimpPickableSelect dialog is a subclass of GimpPdbDialog and uses the
same GimpPickableChooser widget as GimpPickablePopup, except that since it's
inter-process window management, it is harder to make a popup positioned
accurately relatively to a parent (especially on Wayland). This is why it's a
separate widget as a simpler dialog (which we will still try to make transient
as much as possible across platforms).
2023-10-01 21:02:33 +02:00