Plug-ins are not prepared to handle high-precision brushes/
patterns, even when they're otherwise aware of high-precision
drawables, so make sure to always use compat formats when
communicating brush/pattern data to plug-ins.
Allowing plug-ins to handle high-precision brush/pattern data would
require some additional API.
gimplanguagestore-parser.c (parse_iso_codes): instead of
special-casing Windows and OS X, use ENABLE_RELOCATABLE_RESOURCES and
find the package relative to ${gimp_installation_directory}, so
relocating it works on all platforms (also flatpack, snap, whatever),
given the --enable-relocatable-bundle configure switch is used.
In paint options as well in layer list.
I also updated an opacity spin scale in GimpBrushSelect core widget, but
this one doesn't look like it is used anywhere anymore.
... tools' brush options.
After discussions, it turned out that many people disliked that the spin
scale for brush size (and some other options) get you fractional values.
How often do you actually need to get a 4.32 pixel-size brush? And even
how meaningful is it? On the other hand, you usually want a 4 or a 5
pixel size brush and it's nearly impossible to get (exactly) by dragging
the scale widget.
It is so annoying that some even resort to edit the value with keyboard!
So I am adding an optional "constrain" feature to GimpSpinScale. It will
still be possible to get fractional values when constraining is on, for
instance with keyboard edit (the arrow incrementation also will keep any
fractional part). So the interaction for such scales is simply reversed
so that you get integers easily, and fractional parts with a bit more
effort.
It is not turned on by default (some feature actually need precision and
we don't want to break the sliders for these) and for the time being, I
only applied it to all the brush settings in paint tools. Now that it
exist, we may want to apply this to more scales in various parts of
GIMP.
We were doing it all the wrong way, fixing one combo box object at a
time. So this commit basically reverses commits 68a33ab5bd, 6dfca83c2a
and a9a979b2d0 and instead runs the same code in the class code. This
way, all objects based on these base classes will have the fix from
scratch.
These improved various other drop-down lists (I found some of them, and
probably not all) as I fixed all GIMP custom widgets based on
GtkComboBox.
Note that it has to be run after filling the list apparently (I had the
problem especially with GimpIntComboBox if running in the _init() code,
then the list widget showed wrong).
The main window height was always bigger than my screen height on
startup, overriding my previous session's window size.
I could retrace the memorized size being changed when adding the display
shell with gimp_image_window_add_shell() in gimp_display_new(), just
before showing the window. Unfortunately this happens after we applied
the session position/size (in gimp_image_window_session_update() at end
of image window construction). I'm not sure why adding the shell
increases the size of the window, especially since the window can be
manually sized at the expected dimension without any graphical glitch.
Maybe we could investigate this, but simply forcing any session managed
window to behave as expected upon showing is not a bad move anyway and
in this specific case, it works fine.
Request pixbufs in double size and cache the created surface instead
of the pixbuf. This affects rendering icons and image thumbnails.
All other rendering (which is most previews) is not ported yet, but
just lacks HiDPI quality, there are no actual bugs.
The problem was not happening with the master code of
gimpdisplayshell-tool-events.c, but I encountered it in gimp-2-10 with
the layer picking code.
Even then, it still works, but I need to protect calls to
gdk_event_get_axis() to avoid CRITICALs.
(cherry picked from commit b1fe1675ce)
Note: this was not absolutely necessary on master (no CRITICALs), but I
can see that the same piece of code applies, so I may as well sync.
The scratch allocator has been moved to GEGL (commit
gegl@b99032d799dda3436ffa8c1cc28f8b0d34fb965d). Remove gimp-
scratch, and replace all its uses with gegl-scratch.
In GimpHistogramEditor, when the drawable preview is frozen, don't
duplicate the main histogram as the bg histogram if calculation is
still ongoing, since this will block until histogram calculation is
complete. In particular, this creates a noticeable stall when
beginning a paint stroke while the histogram is being calculated.
Instead, defer the creation of the bg histogram to the completion
of the calculation of the main histogram.
Set the "x-dpi" and "y-dpi" options on the GdkPixbuf set on the
clipboard. There is not much more we can do, getting that value across
the clipboard is out of our control, but at least we set the vlaues
now.
In gimp_histogram_editor_update(), cancel any ongoing histogram-
calculation async before restarting the idle source. The async
will have been canceled anyway when recalculating the histogram
once the idle source is run, but we can cancel it as soon as we
know the histogram is outdated.
...closing this image while the file is being loaded
Ref the image around all calls to file_open_layers() and
gimp_image_add_layers() so it stays around even if the user closes the
display in the meantime.
...palette views despite selected color being in the currently
selected pallette
As suggested by Massimo, changing the color comparison EPSILON in
gimppalette.c from 1e-10 to 1e-6 fixes this, and is really small
enough.
Also, generally clean up color comparison epsilons:
- use a #define, not hardcoded values for all uses of
gimp_rgb[a]_distance()
- call the #defines RGB_EPSILON and RGBA_EPSILON
- make them all 1e-6 or larger
In GimpDrawableTreeView, show an error message when attempting to
select a different drawable while the image has an active floating
selection. In GimpLayerTreeView, also blink the editor button-row
when this happens, as a hint that the floating selection can be
committed/canceled through the buttons (we already highlight the
relevant ones.)
If the scale factor is 2 or larger, look for cursor images named
"filename-x2.png" and use them via
gdk_cairo_surface_create_from_pixbuf() and
gdk_cursor_new_from_surface().
Manually scale up the default cursor if there is no "x2" image, using
NEAREST interpolation, which looks better than the default smooth
scaling done by gdk_cursor_new_from_pixbuf() on HiDPI monitors.
Next: adding better HiDPI cursor images.
This commit completely removes the "Edit -> Fade..." feature,
because...
- The main reason is that "fade" requires us to keep two buffers,
instead of one, for each fadeable undo step, doubling (or worse,
since the extra buffer might have higher precision than the
drawable) the space consumed by these steps. This has notable
impact when editing large images. This overhead is incurred even
when not actually using "fade", and since it seems to be very
rarely used, this is too wasteful.
- "Fade" is broken in 2.10: when comitting a filter, we copy the
cached parts of the result into the apply buffer. However, the
result cache sits after the mode node, while the apply buffer
should contain the result of the filter *before* the mode node,
which can lead to wrong results in the general case.
- The same behavior can be trivially achieved "manually", by
duplicating the layer, editing the duplicate, and changing its
opacity/mode.
- If we really want this feature, now that most filters are GEGL
ops, it makes more sense to just add opacity/mode options to the
filter tool, instead of having this be a separate step.
Showing it was only displaying the top modes, with a lot of top space,
and you had to slowly scroll down the list. This is the same as #2642
(as Alexandre noted in a comment), so I just use the same "fix" though I
don't fully understand it. It feels more of a side effect of
gtk_combo_box_set_wrap_width() working around a bug of GtkComboBox. So
if anyone has a better fix and understand the issue, feel free to patch
(maybe GTK+ directly?). In the meantime, it works well enough. :-)
Update the definition of the "cache-compressed" and "swap-
compressed" dashboard variables, to reflect the changes made by
GEGL commit gegl@dc22e997757ab91c180244d5290d094d2ea8572f.
Zlib is a "better" compression in the meaning that it is a more advanced
and complex algorithm than RLE. And in most cases, it should end up in
smaller file sizes. But as any algorithm, there may be cases when the
expectations are not met (worst cases or such). That's the nature of the
maths. Still we should not make the checkbox text over-complicated (it
is not the place to teach algorithmic), yet we can at least add a small
tooltip text.
After discussing with Mitch, it turn out commit 717c183a3e was fixing
(or rather working around) actual issues of broken device/usb stack
issues on Linux, as expected.
Nevertheless on Windows, this broke in turn many tablets (see commit
ce24e16083). Therefore we do a very ugly #ifdef to bail from duplicate
devices on Windows whereas we continue on Linux. This fix and difference
of behavior is completely empirical, rather than based on actual good
logics, so that's quite annoying, but well… not much choice here.
Also note that since we had no report of breakage on other OSes (such as
macOS/BSD), at least that I know of, I let them with the Linux code
path.
Since commit fe139e5662, when
blinking a widget, we cancel blinking for all its ancestors. Avoid
redrawing all the ancestors as a result, unless they're actually
blinking. This prevents some noticeable lag when blinking a
widget.
We had many reports of tablets from various brands (Huion, Gaomon,
XP-Pen…) broken in the last release (though working fine when
downgrading to 2.10.6). Latest Huion drivers seem to fix the issue
(according to at least one report), but this is not the case for other
tablets.
Though unable to test myself, provided stderr logs indicate that we hit
the case when 2 devices with the same name are registered. Therefore
this commit is basically reverting commit 717c183a3e (though keeping and
completing the comments). I don't think there is an ultimate solution
here but with this regression, experience shows us there seem to be a
lot more breakage when overwriting the device with newer occurences (at
least on Windows). It is unclear though if commit 717c183a3e was also
supposed to fix another case actually encountered. If so, we will need
to get an even more advanced solution.
Use gimp_async_add_callback_for_object(), added in the previous
commit, instead of gimp_async_add_callback(), in cases where the
destructor of the object owning the async doesn't wait for the
async to finish. This avoids leaking such ongoing asyncs on
shutdown, during which gimp-parallel either finishes or aborts the
asyncs: if at this point an async has any registered callbacks, an
idle source is added for running the callbacks, extending the
lifetime of the async; however, since we're not getting back into
the main loop, the idle is never run, and the async (and any
associated resources) are never freed.
When an error occurs, we want to prevent overwriting any previous
version of the file by incomplete contents. So run
g_output_stream_close() with a cancelled GCancellable to do so.
See also discussion in #2565.
Include instrumentation-variable descriptions in the var-defs
section of performance logs, so that they can be displayed
alongside their names when viewing the log.
Simplify gimp_view_renderer_drawable_render(), by consolidating
common code paths. In particular, when rendering the preview as
part of an image, always crop the preview to the bounds of the
image, even when downscaling, to avoid unnecessarily downscaling/
convering cropped-out regions. We previously only did this when
upscaling the preview by a factor of 2 or more; whatever the reason
for this used to be, it's no longer there.
In gimp_view_renderer_drawable_render(), avoid overflow in preview-
area calculation. This prevents erroneously setting 'scaling_up'
to FALSE while upscaling the drawable by a very large amount, which
can lead to the creation of a very large GimpTempBuf for the
preview, causing memory allocation to fail.
...via hover tooltips
Use the GtkWidget::query_tooltip() signal on GimpFgBgEditor to emit an
own signal "tooltip" that has the hovered widget area as parameter.
Connect to GimpFgBgEditor::tooltip() in gimptoolbox-color-area.c and
set separate tooltips on the widget's areas, including the shortcuts
for "Swap colors" and "Default colors".
Add xyY color space to the color spaces for sampling colors.
Also add code to xcf-load.c that makes sure the sample point loading
code handles unknown future GimpColorPickMode values (fall back to
PIXEL pick mode).
In gimp_file_proc_view_get_proc(), when there is no selected
procedure (which can happen, in particular, when searching the
list), return the "automatic" procedure and its corresponding name/
filter, if one exists, instead of bailing.
Additionally, in GimpFileDialog, use a match-all filter when
gimp_file_proc_view_get_proc() returns no filter, avoiding
CRITICALs/segfault.
In GimpDeviceInfo, make sure that the info->axes and info->keys arrays
always have info->n_axes and info->n_keys members. Also sync axes and
keys between GdkDevice and GimpDeviceInfo more often, and some
cleanup.