Commit Graph

23121 Commits

Author SHA1 Message Date
Thomas Manni 041104b5ec Paint Select tool: enable viewport-based local selection
The tool now takes care of the portion of the layer effectively displayed
on the screen. This allows faster expansion/shrink of the selection since
an area smaller than the whole layer is used.

It will also limit the impact of the incoming multilevels processing, which
tends to decrease the segmentation accuracy on thin structures, since users
often zoom-in to work on such thin details.
2021-01-18 18:43:39 +01:00
Thomas Manni 7d753c6f54 Paint Select tool: apply a threshold on the image mask before triggering...
...the automatic expansion to simplify mask handling in the gegl
paint-select operation.
2021-01-10 15:28:46 +01:00
Thomas Manni 4d0ba4392b Paint Select tool: add a dedicated function to check tool requirements 2021-01-10 13:04:31 +01:00
Niels De Graef c328da6bd3 app: Hide CSD when going fullscreen
By default, GTK keeps on showing client-side decorations when going
fullscreen, as it might contain buttons or other functionality that
would be lost. As such, we have to make sure we hide the titlebar.

Getting to that titlebar to update its "visible" property needs a bit of
effort, since it's an internal child of the GtkWindow that isn't exposed
in any way, so we take a little detour using `gtk_container_forall()`.
2021-01-02 10:27:18 +01:00
Niels De Graef 5a1dd584e9 app: Partially correct gimp_window_get_native_id()
Most important of all, we shouldn't assume that if a given GDK backend
is enabled at compile time, that this is also the one that is being
used. For example, on Linux, both `GDK_WINDOWING_X11` and
`GDK_WINDOWING_WAYLAND` can be set, but you still need to do a runtime
check if you're running under one WM or the the other.

A small cleanup is that we immediately check if a widget is realized by
checking if it's `GdkWindow` is NULL or not and return immediately
(since we need to check its type later on anyway).

Finally, we can remove `GDK_NATIVE_WINDOW_POINTER` as that is a GTK+ 2.0
construct, so it's dead code anyway.
2020-12-30 12:23:22 +01:00
Niels De Graef f1aae9ad6d app: tagpopup: Try to set transient-for property
Setting the `"transient-for`" property for popups is important to
certain window managers (such as Wayland), so that they know what the
parent surface is and can position the popup accordingly.

This fixes the `GimpTagPopup` in wayland giving a critical message, and
getting a random position somewhere on the screen.
2020-12-30 09:15:17 +00:00
Niels De Graef 4d100cc20c app: Use g_object_notify_by_pspec for GimpItem
`g_object_notify()` actually takes a global lock to look up the property
by its name, which means there is a performance hit (albeit tiny) every
time this function is called. For this reason, we should try to use
`g_object_notify_by_pspec()` instead.
2020-12-29 22:37:24 +01:00
Jacob Boerema b3f3120e32 libgimpwidgets, app: silence warnings about State 0 for GimpRuler and GtkScrolledWindow doesn't match state 128 set via gtk_style_context_set_state ()
When run with GIMP_DEBUG=Gtk we get a lot of debug warnings for GimpRuler and once in a while for GtkScrolledWindow that State 0
doesn't match state 128 set via gtk_style_context_set_state (). This happens because we didn't enter the current state flags of
the widget but 0 and apparently Gtk isn't happy about that.

Let's fix this by using the actual state flags by calling gtk_widget_get_state_flags.
2020-12-28 14:05:09 -05:00
Jehan b1abc5b6a6 app: improve Paint Select Tool description.
Based on other tools wording, as well as the algorithm description. In
any case, it looks a bit better than the previous description (with a
typo even).
2020-12-22 23:13:45 +01:00
Érico Rolim dfbf1d5d7b app/widgets/gimpactiongroup: protect against calling gettext with NULL msgid
Use the same conditional that was being used for
g_dpgettext2(entries[i].tooltip) with gettext(entries[i].tooltip).
2020-12-20 22:06:35 -03:00
Érico Rolim aa151a08a0 app/dialogs: protect against calling gettext(NULL).
In gimp_dialog_factory_register_entry(), strings were passed to gettext
without checking for a NULL pointer. The gettext documentation [1]
points out that that's undefined behavior, and musl libc's
implementation of gettext segfaults in that case.

[1] https://www.gnu.org/software/gettext/manual/gettext.html#Interface-to-gettext
2020-12-20 22:06:35 -03:00
Øyvind Kolås 2d5aa81456 depend on GEGL-0.4.28 2020-12-20 13:37:08 +01:00
Jehan d9b25b8b50 app: do not ask about conversion for an image using a preferred profile.
If setting a RGB or Grayscale "preferred" profile, it usually means
these are profiles we are commonly working with, and it is to be
expected that images one might load may already have said profile. In
this case, don't ask what to do with this profile (keep, convert…). The
graphist kind of already answered this by explicitly listing this
profile as a "preferred" one.

Note that I also check for the built-in profile equality, though it
doesn't look like it is useful (gimp_image_get_color_profile() will
return NULL for an imported image which uses the built-in profile).
This is mostly to be thorough.
2020-12-20 02:04:51 +01:00
Jehan 12348f5241 app: fix some RGB/sRGB mixup in 2 labels. 2020-12-19 21:43:09 +01:00
Jehan 2b75b63ab7 app: keep error dialog above.
In some cases, error dialogs may end up below other windows and stay
unnoticed because of how dialogs are raised and hidden on various
platforms. This is not very constructive. It's much better to make sure
one sees an error when it happens (in some cases, it may mean possible
data loss, so it should be at least acknowledged; also seeing it later
may mean you can't know anymore which action triggered this error,
making the whole process kind of meaningless and hard to debug).

So anyway, let's make error messages prominent by having them always
above.
2020-12-17 22:27:01 +01:00
Jehan c0972eebb5 app: hide the export file dialog when showing the plug-in dialog.
We are piling up the export dialog, then the specific plug-in dialog,
then possibly more dialog (cf. upcoming commits for metadata handling).
It's just too much and we end up in a mess of dialogs.
Of course, if the export fails or it is canceled, we are back to the
file dialog, which gets shown again, whereas if it succeeds, the file
dialog is destroyed (just as it already used to be).

Also anyway the file dialog is completely deactivated while the export
dialog is displayed, so it's just useless. Finally some export support
have features where looking at the canvas is useful, for instance JPEG
preview feature. With all these dialogs, it's nearly impossible to look
at the canvas (with a single display at least).
2020-12-17 18:28:14 +01:00
Jehan 670bc35eb9 app: show the "relative edit" cursor on motion with Shift pushed.
If you hover over the GimpSpinScale while clicking Shift, we want to be
able to advertize the fact that it will produce a different action than
the simple click. It makes the widget behavioral rules actually
discoverable.
2020-12-16 18:43:14 +01:00
Jehan 7b0d553511 app: improve GimpSpinScale cursors.
Aryeom noted that current top arrow cursor comes from a time when the
interaction with this widget depended on a lower versus upper region and
doesn't gives anymore any idea of what the click would do.
So let's replace the top-arrow cursor with a "grab" cursor, which even
becomes a "grabbing" cursor when a grab is in progress.

Also let's now use gdk_cursor_new_from_name() with standard names from
the CSS specification, because it is the recommended way. According to
GDK docs, GDK cursor list is taken from the X cursor font and apparently
not all cursors are available on all platforms. So let's use the
standard CSS list, whose cursors are said to be available accross
platforms (at least very very likely, I guess).

Finally I renamed the target enum for the widget to be more semantic
than upper/lower which don't mean anything anymore in our new
interaction rules.
2020-12-16 18:05:13 +01:00
Jehan 976b518999 app: improve GimpSpinScale usability for keyboard editing of value.
Currently to edit the value with the keyboard (i.e. get a focus on the
text entry part of the widget), we can click on the scale which gives us
edit focus, but it implies to change the value (which may not be
wanted).

An interaction method exists to do just this, which is the secondary
button (middle click). Unfortunately, though powerful, it is totally
"hidden feature". People expects to be able to click on the numbers they
see and start typing.
This change allows just this. Now when clicking on the number part, it
selects the whole text input contents (same as with middle-click ever
since commit 3449652fe8), without changing the value. You just enter in
text input mode.
To properly advertize the behavior change, the cursor will also change
when hovering, showing a text cursor over the existing number text.

As many of my changes, this change was designed together with Aryeom and
triggered originally by her usability feedbacks and inputs.
2020-12-16 15:06:25 +01:00
Jehan 6d7d73935f app: remove unused (deprecated) property read.
We were also reading "gtk-show-unicode-menu" which has also been
deprecated since GTK+3.10, and we were not even using the read value.
Just remove this piece of unused code.
2020-12-15 03:15:23 +01:00
Jehan f6f94836c1 app, menus: get rid of custom input method menu.
The input menu added with gtk_im_multicontext_append_menuitems() mostly
provides redundant (e.g. the system defaults) or useless options
(e.g. "None" or "Simple" which basically seems to mean the keyboard
mapping straight keys, and I don't see why anyone would want this if one
set a system-wide input system). Worse it can provide unstable options
(e.g. "Wayland" which crashes GIMP when I tried it on my X11 desktop! It
crashes on _gtk_immodule_wayland_init which is probably normal as we are
not on a Wayland client).

Anyway gtk_im_multicontext_append_menuitems() is deprecated since
GTK+3.10, as well as the "gtk-show-input-method-menu" property which we
read from GTK+ settings (and is FALSE anyway nowadays by default, so we
usually never show this submenu) to determine if we should show this
additional text tool submenu or not. Furthermore there is just no reason
not to leave the defaults system input method engine does its job (which
works well as far as I can see, at the very least on my GNU/Linux X11
desktop and on Wayland also, last I tested).
2020-12-15 03:04:15 +01:00
Jehan 2cae9b9acf app: make "gegl:introspect" an optional operation dependency.
Check at runtime for the operation availability and set the "Show Image
Graph" action active depending on this check.

This goes with discussions to make this operation optional with a
runtime check for the tool `dot`.
See: https://gitlab.gnome.org/GNOME/gegl/-/merge_requests/84
2020-12-14 20:01:45 +01:00
Jehan b659d3ba4f app: different undo labels for various "Alpha to Selection" operations.
gimp_channel_select_alpha() was creating the same undo label "Alpha to
Selection" whatever the actual operation (add, remove, replace,
intersect). Select the right label depending on the actual operation.
2020-12-14 14:01:58 +01:00
Jehan d6d8e43cb5 Issue #6030: Mask related Shortcuts conflicting with Multiple Layers…
… Selection.
I first wanted to switch the modifiers to Alt+shift, Alt+Ctrl clicks and
even implemented the changes, but realized the existing "Alpha to
selection" on Alt thumbnail clicks already mapped these for
Add/Remove/Intersect Alpha to Selection (though I broke this with commit
14b4c08881 but re-allows properly with exact modifier recognition in
order not to catch other types of combinations).

In the end, I see no other solutions than actually removing the mask
add/remove modifiers (#if-ed 0 for now, we'll see) in favor of the most
ancient feature.
2020-12-14 12:44:53 +01:00
Jehan a3eba9fbad app: new default dynamics is "Pressure Size".
Another sensible default change proposed by Aryeom. Until now, all tools
which could make use of dynamics started with "Dynamics Off". This makes
it very hard for beginners to start using GIMP with a tablet directly
without actually knowing the technical settings of the software.
This is even more anticlimactic in GIMP 3 as tablet are supposed to work
from scratch (and they do), but without a proper dynamics, you can't see
it. And same as it used to in GIMP 2.x, at first launch, it looks like
your tablet is not recognized.

We hesitated between "Pressure Size" and "Pressure Opacity". Both are
sensible choices and would directly show your tablet works. Also they
rely entirely on tablet-specific input (pressure), unlike e.g. speed or
direction, which is much better for the purpose of showing the tablet
works and is properly supported.
2020-12-14 02:15:12 +01:00
Jehan f4d39f8c72 app: mask alternative click modifiers must not clash with…
… multi-selection modifiers. Also they will work from now on on the
clicked mask only.

Shift and Ctrl clicks are reserved for multi-selection. We do not want
these to do other actions if you shift|ctrl-click on a mask (even more
as these alternative actions are hardly discoverable so it would make
for bug-like behavior to the person not knowing these alternative
actions).
So Alt-click is still used for showing/hiding the mask, but
enabling/disabling changes from Ctrl-click to Alt-Ctrl-click.

The second change is that these actions will not run the actions on
selected layers' mask, but on the clicked layer mask. This will at least
make these interaction different from the actions (e.g. with contextual
menu) and therefore it's not even redundant anymore. We will now have a
way to work on all selected layers vs a way to work on a clicked layer
(without changing the existing selection).
2020-12-14 01:50:05 +01:00
Jehan 14b4c08881 app: catch Alt-click exact combination on GimpItemTreeView preview.
When Alt-clicking on an item thumbnail (for instance a layer thumbnail),
we can trigger an "Alpha to Selection" action on the clicked item. Yet
the check was not accurate and would work on Alt+any modifier(s)+click.
Let's catch exactly Alt-click only in order to allow for more actions on
other combinations.
2020-12-14 00:37:24 +01:00
Jehan f5d9856125 app: be more accurate to ascertain in we are multi-selecting.
In particular, we should not check if the extend/modify (shift/ctrl)
modifiers are ON, but also that no other modifier is ON. For instance an
Alt-Shift-click should not trigger multi-selection actions, allowing it
to be useful for other actions without also changing the selection in
the same time.
2020-12-14 00:30:05 +01:00
Jehan 305dcdcccc app: do not popup a viewable preview when modifiers are active.
Long press on a viewable cell (such as the small layer or mask preview)
pops up a slightly bigger preview. We don't want this feature to be
triggered when any modifier is active, such as ctrl/shift (common with
multi selection in a tree view) or alt combinations (for various
alternative actions).
2020-12-13 20:39:47 +01:00
Jehan d4e501919e app: revert to "gimp-paintbrush-tool" as default tool.
A UI unit test (paintbrush_is_standard_tool()) was expecting the
paintbrush tool to be the default tool. This actually does not fit with
my tests as the crop tool was always the default tool if I were to
delete my config folder and start anew. Yet it was working for the unit
testing at the very least since `make check` used to work until now, and
was broken by my change.

Anyway with my new code (commit 31e38fe869) and this additional one, now
it should work both for unit tests and real usage. So this commit fixes
both the CI and the originally expected default tool.

For the record, Aryeom also agrees that paintbrush is a good default
tool for first usage/discovery of GIMP.
2020-12-12 13:06:37 +01:00
Jehan 31e38fe869 app: better tool defaults depending on the device source.
This code is the result of discussions with and propositions by Aryeom
who thinks (and I agree obviously) better defaults should be set for
beginners and first time users. This is only a first change, more
similar defaults updates will likely come in the next few months on
various parts of GIMP.

Existing code was only making a differenciation for eraser-type devices,
setting them to the eraser tool (which is fine of course).
So far, I only added 2 types of device source, which we should
definitely special-case as well: pen tools (tablet styluses) should
definitely map to the Paintbrush (pencil could be a reasonable defaults
too, though brush seems much more common); as for touchscreen, I chose
to map to the Smudge tool (though to be fair, if we had gesture
recognition, this should not map to any tool). I also set a generic
default now because it seems that right now, we don't specify anything
(it ends up defaulting to the Crop tool for first uses, at least in my
case). I set the rectangle select tool. I'm not sure it actually makes
particular sense, but at least it's probably better to default to
something not destructive for first time users.
2020-12-11 00:30:50 +01:00
Jehan 273972bc4d app: do not reuse stored configuration on virtual devices.
Virtual devices are only reflection on the various physical devices
attached to it (mouse, touchpads, styluses, etc.). Keeping settings when
the device is updated just makes no sense. Worse it can actually cause
issues by setting axis uses from one device where an axis use is 'none'
(and it's normal) to another where 'none' ends up disabling the axis.
2020-12-10 23:54:24 +01:00
Jehan 1c06751c08 app: update when device axes/keys change.
Earlier code was assuming it should not happen. Actually it can happen,
in particular with virtual devices (on which several physical devices
can be attached and switching to one or the other would update the
virtual device to mimick its features).
2020-12-08 23:17:23 +01:00
Jehan e3ee463815 app: move GimpDeviceInfo variables to a private structure.
It's just better practice to not leave all these variables public,
implicitly allowing various code to use these directly (also making
debugging harder).
2020-12-08 21:07:37 +01:00
Jehan de739bde23 app: better code to handle GimpDeviceInfo axes.
Axis names can now be returned with gimp_device_info_get_axis_name() and
I added a dedicated function gimp_device_info_ignore_axis() to handle
the case of an axis to ignore.
I also improved the code with less redundancy to handle the axes data
(both the use and name arrays will always exist and be created and will
be n_axes size, hence avoiding bad out-of-bound reads). This includes
some code refactorization avoiding near code duplication to make sure we
always have the same logics, by creating the gimp_device_info_updated()
static function.
2020-12-08 20:28:25 +01:00
Jehan cd6e777dcd Issue #6045: File > Debug > Show Image Graph == GIMP_Crash.
The issue has also been fixed on GEGL side (see commit 5ac40e3c3 in
GEGL), but since the fact that "gegl:introspect" relies on a runtime
tool (which is not the best thing), let's make an additional check
within GIMP to make sure we have a proper buffer as a result to
"gegl:introspect". Otherwise we might crash when trying to use this
NULL buffer.
2020-12-05 18:55:59 +01:00
Jehan 1ed87e2d17 app: improve input device axes display "Input Devices" dialog.
- First only show the axes returned by GDK (which means the axes
  returned by the driver if I understand correctly), and even within
  these, ignore the ones set as "ignore" because they are likely bogus
  axes (Carlos said drivers sometimes add a bunch of axis; I am guessing
  this is because many are generic drivers for various models of tablets
  so instead of have variable length of axes, they just set some to be
  ignored).
- Also use the names returned by GDK instead of our fixed set of names.
  The main advantage is that these are more accurate. For instance
  rather than showing just "X" for the firxt axis, the GDK names would
  be "Abs X" for a tablet and "Rel X" for a mouse. The drawbacks is that
  it doesn't look like GDK is actually translating these, and since we
  don't have the strings in our code, we don't either. This will have to
  be figured out.
  Note that we still need to use the fixed set of names
  (axis_use_strings array) when a device is disconnected.
- If some device didn't have any axes at all, don't show an empty list.
  Don't show the curve widget either.
- In the Axes list, select by default the first axis with curve (which
  would be only pressure so far if a device has this axis), because this
  is one of the main feature still doable with this dialog, so it's a
  bit of a time-waste if we don't show this directly. In no axes has a
  curve, just show the first axis in the list.
2020-12-05 01:03:59 +01:00
Thomas Manni 6a169e289f Paint Select tool: add a temporary option to show painted scribbles
For debugging purpose, will be removed on the final tool.
2020-12-04 18:56:28 +01:00
Thomas Manni 69b03cf363 Paint Select tool: correctly handle drawable offsets 2020-12-04 11:57:21 +01:00
Thomas Manni ff23b2c809 Paint Select tool: regroup image mask updates in one place
Also remove the temporary resulting buffer from the tool structure.
2020-12-04 10:09:35 +01:00
Jehan 7ec05c3a50 app: do not show virtual devices and XTEST device in the Input Devices…
… editor.
As discussed with Carlos Garnacho back a few months ago. These devices
are useless from a configuration point of view.
2020-12-03 23:14:49 +01:00
Jehan c85e4c8db4 Issue #5813: Hidden rulers in GIMP 2.99 still take the same place. 2020-11-29 12:46:29 +01:00
Thomas Manni b94121f53f app/actions: fix Apply Layer Mask 2020-11-26 17:54:41 +01:00
Jehan 6f09e099d6 Issue #5992: Mask to Selection isn't selecting the right place. 2020-11-26 16:18:04 +01:00
Jehan 0e8acc5dd6 Issue #5985: GIMP crashed when deleting paths. 2020-11-26 02:16:59 +01:00
Jehan 2ea5dec56e libgimpwidgets: improved gimp_prop_scale_entry_new(), new function…
… gimp_label_spin_set_digits() and deleted gimp_prop_opacity_entry_new()

- The "digits" argument for the number of decimal places in
  gimp_prop_scale_entry_new() is now mostly useless since GimpLabelSpin
  (hence GimpScaleEntry too) got a nice estimation algorithm of sensible
  values.
- Add gimp_label_spin_set_digits() function to manually set the digits
  property when we don't like the estimated value.
- Also add a new "factor" argument to gimp_prop_scale_entry_new(). Its
  role is to allow a GimpScaleEntry showing a factored range, typically
  a [0, 100] range for some types of [0, 1] properties.
- Remove gimp_prop_opacity_entry_new() which was basically a
  special-case of gimp_prop_scale_entry_new() and which can now be
  easily reproduced by simply set factor=100.0.
- Update all usage of gimp_prop_scale_entry_new() in app/ and plug-ins/
  with updated arguments. It is interesting to note that all existing
  usage were either integers (digits=1) or when double, the estimated
  decimal places are the same as the ones which were manually set (hence
  showing the generic estimation is not too bad). So the new function
  gimp_label_spin_set_digits() was not even needed once in current code.
2020-11-25 02:32:22 +01:00
Jehan 31111d2802 app: mark the paint select tool as experimental.
Otherwise it breaks the toolbox organization with a "missing tools in
toolrc file" error while scanning toolrc.
2020-11-24 21:43:11 +01:00
Jehan 9f6fbe8aca app: fix generated tool-enums.c and deactivate Paint Select tool…
… checkbox in Preferences when GEGL operation "gegl:paint-select" is
missing.

Otherwise the tool won't appear and you don't understand why.
2020-11-24 21:26:04 +01:00
Thomas Manni 9e391bc3b6 app: Paint Select tool, reflect changes applied to the gegl operation...
...related to fluctuations removal.
2020-11-24 19:02:30 +01:00
Thomas Manni e1cdb9f54e app, icons: add Paint Select tool in the playground
A -quick done- first step towards the addition of a smart selection tool.
Require the gegl:paint-select workshop operation.
Still LOT of work to do (wip):
- fluctuations removal (GEGL side)
- multilevels pyramid approach + banded graphcut for instant result on large
   image (GEGL ? GIMP ?)
- Gaussian Mixtures for color models (GEGL side)
- drawable offsets (GIMP side)
- undo / redo (GIMP side)
- scribbles edition mode (GIMP side)
- dedicated icons
- ...
2020-11-24 12:10:40 +01:00