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.
It was not doing anything right since space invasion. We now treat the
built-in sRGB profile like any other profile and never bypass
conversions based on some weird toggle.
Instead, introduce a "Use sRGB Profile" toggle which, when enabled,
hides whatever profile away so the image actually uses the built-in
sRGB profile.
This is different from discarding and then re-assigning the same
profile only by being faster and more convenient.
We currently construct the tool-options GUI for all the tools at
startup, which takes a significant amount of time. Instead,
only register the GUI construction function with the tool-options
object, using the new gimp_tools_set_tool_options_gui_func()
function, and use the registered function to construct the GUI when
actually needed.
... and G_TYPE_INSTANCE_GET_PRIVATE()
g_type_class_add_private() and G_TYPE_INSTANCE_GET_PRIVATE() were
deprecated in GLib 2.58. Instead, use
G_DEFINE_[ABSTRACT_]TYPE_WITH_PRIVATE(), and
G_ADD_PRIVATE[_DYNAMIC](), and the implictly-defined
foo_get_instance_private() functions, all of which are available in
the GLib versions we depend on.
This commit only covers types registered using one of the
G_DEFINE_FOO() macros (i.e., most types), but not types with a
custom registration function, of which we still have a few -- GLib
currently only provides a (non-deprecated) public API for adding a
private struct using the G_DEFINE_FOO() macros.
Note that this commit was 99% auto-generated (because I'm not
*that* crazy :), so if there are any style mismatches... we'll have
to live with them for now.
In addition to the verbose GIMP version, include in performance
logs the values of all environment variables beginning with BABL_,
GEGL_, or GIMP_, and of all the GEGL config options.
* The minimum GIMP version for this XCF is always written down when it
is GIMP 2.8 or over.
* The list of features warrating the minimum version is now listed in an
expander container rather than as tooltip (making the list actually
discoverable!).
* The warning on compression is now displayed as its own text under the
checkbox (only when checking the box actually changes anything
compatibility-wise), and not as additional text to the minimum GIMP
version label. Otherwise it had far too much weight on the minimum
compatible GIMP version text and people were wondering what it meant.
We should not tell people what the checkbox cannot do (it cannot
improve compatibility in some cases), only what it can do (it can
improve compatibility in other cases).
* Update the feature list real-time when checking the compression box
(making it even more obvious that tile compression may have a say in
compatibility).
* Metadata info is still added on the GIMP version label as it does not
limit compatibility of the XCF file itself.
The "running" attribute (readable through
gimp_backtrace_is_thread_running(), and recorded in the performance
log) specifies if the thread was in a running or suspended state at
the time the backtrace was taken. It is accurate on Linux, but
only approximated on Windows.
Adapt the performance-log-expand.py tool to maintain this attribute
(and any future thread attributes we might add).
Add source filename and line number fields to the
GimpBacktraceAddressInfo struct, populated through
gimp_backtrace_get_address_info(). This is not currently supported
by the Linux backend, but is supported by the Windows backend,
which we'll be added in the next commit.
This function returns information about the given address, which
is currently mostly limited to the corresponding symbol
information, but we might want to add address-specific information
in the future, such as a line number.
Add an option to record a performance log through the dashboard.
The log contains a series of samples of the dashboard variables, as
well as the full program backtrace, when available. As such, it
essentially acts as a built-in profiler, which allows us to
correlate program execution with the information available through
the dashboard. It is meant to be used for creating logs to
accompany perofrmance-related bug reports, as well as for profiling
GIMP during development.
The sample frequency defaults to 10 samples per second, but can be
overridden using the GIMP_PERFORMANCE_LOG_SAMPLE_FREQUENCY
environment variable. Backtraces are included by default when
available, but can be suppressed using the
GIMP_PERFORMANCE_LOG_NO_BACKTRACE environment variable.
Logs are created through the new "record" button at the bottom of
the dashboard dialog. When pressed, a file dialog is opened to
select the log file, and, once confirmed, data is being recorded to
the selected file. Recording is stopped by pressing the "record"
button again (we use a highlight to indicate that recording is
active.)
While recording, the "reset" button is replaced with an "add marker"
button, which can be used to add event markers to the log. These
can be used to mark events of interest, such as "started painting"
and "stopped painting", which then appear in the log as part of the
sample stream. Markers are numbered sequentually, and the number
of the next (to-be-added) marker appears on the button. Shift-
clicking the button adds an empty (description-less) marker, which
is only identified by its number; this can be used when markers
need to be added quickly.
The log is an XML file, containing some extra information (such as
the output of "$ gimp -v", and symbol information) in addition to
the samples. The data in the file is delta-encoded to reduce the
file size, meaning that samples (as well as some other elements)
only specify the changes since the previous sample. This adds a
necessary decoding step before data can be processed; the next
commit adds a tool that does that.
There are currently no tools to actually analyze the data -- that's
still TBD -- but at least we can start gathering it.
gimp_device_info_set_device(): don't just bail out if a device with
the same name is added again, instead, simply continue and overwrite
the info's old device with the new one.
NOTE that this only happens if something is wrong on the USB or udev
or libinput or whatever side and the same device is present multiple
times. The only "safe" thing is to assume that devices listed earlier
are dead and dangling entities and that the last registered device is
the one actually delivering events.
... which reports the amount of data queued for writing to the
swap (see GEGL commit 64021786ee067cf66c038622719acc590e6341db.)
When the swap queue is full, a yellow color underlay is shown in
the history graph.
The "compression" field reports the ratio between the total size of
the data in the swap, and the total size the data would have had if
all tiles in the swap occupied a unique data block.
See GEGL commit 185f4450f2a51690b39112973c61f894c1ec3e41.
AM_PATH_GLIB_2_0 m4 macro actually computes this value using
$PKG_CONFIG. Yet $PKG_CONFIG variable is the pkg-config tool looking for
target libraries (not host), hence it would return the executable
`glib-compile-resources` built for the target.
Also using the same variable name invalidates our test: our own
AC_PATH_PROG was never run as the variable was already set. And no
environment variable could override this test anymore either. This is
why I rename the test variable to HOST_GLIB_COMPILE_RESOURCES.
(cherry picked from commit d1d9eb17e5)
AppStream spec says it can only contain <p>, <ol> and <ul> markups.
Unfortunately these are not pango markups (nor is there any equivalent).
So I just use newlines and spaces until I figure out anything fancier.
That's all still quite ugly, but whatever, I'm still in the start.
It was using deprecated functions regarding how icons used to work, such
as gtk_icon_set_get_sizes() or gtk_style_context_lookup_icon_set().
The last uses of this function disappeared in last commit.
... GimpCellRendererToggle into "icon-size".
In particular making it a pixel size instead of a GtkIconSize. This enum
is limited to a few presets (registering new values is deprecated since
GTK+ 3.10), with names completely semantically wrong. It is better to
specify icon sizes (before scaling) in pixels directly, which goes also
with named icons instead of stock ones.
Squashed commit of the following:
commit ee1ff7d502658cfa1248a13a3f0348495db07eda
Author: ONO Yoshio <ohtsuka.yoshio@gmail.com>
Date: Sun Jul 29 00:31:47 2018 +0900
Fixed that gimp-text-dir-ttb-* icons are lacked in Symbolic.
commit d87d012d697628da28fe90199cc04b95b72ba8ef
Author: ONO Yoshio <ohtsuka.yoshio@gmail.com>
Date: Sat Jul 28 16:23:10 2018 +0900
Fix a typo.
commit cf0238bf7df56c384cdf3b7ec69557d14740f853
Author: ONO Yoshio <ohtsuka.yoshio@gmail.com>
Date: Sat Jul 28 15:50:57 2018 +0900
Fixed seg fault error.
commit b07f60d06f
Author: ONO Yoshio <ohtsuka.yoshio@gmail.com>
Date: Fri Jul 27 17:15:34 2018 +0900
Add support for vertical text writing.
https://gitlab.gnome.org/GNOME/gimp/issues/641
Adjust size negotiation of GimpToolPalette to take the monitor's
workarea into account: request space for enough columns so that the
widget's height is never more than 70% of the workarea height, and
enough rows so that it's never wider than 90% of the workarea.
Just like it was until now, the default filtering should not be all
files, but only relevant files (i.e. XCF when saving, exportable images
when exporting and loadable images/XCF when opening).
Now all files will only be available through the "Show All Files"
checkbox.
This is simpler than previous implementations where the list was
proposing "All Files", "All Images" and "All XCF/export images". That is
just too much.
With this default, I get the "All Files" checkbox out of the expander so
that it is visible immediately even when the format list is unexpanded
(you don't want people to get pissed when not finding how to display all
their files).
... format selection.
Second step: add a "Show All Files" checkbox so that one can still
prevent view filtering even when forcing a load format.
This is useful when loading files with unusual extensions, for instance.
... format selection.
As discussed, the first step is to get rid of the filter list. Our extra
widget now has both roles of filtering the file list and forcing a
loading procedure.
... and rename "clockwise" to "clockwise-delta"
Add a boolean "clockwise-angles" property to GimpDial, which, when
set, causes the dial legs' angles to be measured clockwise, rather
than counter-clockwise. The property is FALSE by default.
Rename the "clockwise" property, which controls the direction of
the measured delta between the two angles, to "clockwise-delta", to
avoid confusion, and adapt the rest of the code.
All babl formats now have a space equivalent to a color profile,
determining the format's primaries and TRCs. This commit makes GIMP
aware of this.
libgimp:
- enum GimpPrecision: rename GAMMA values to NON_LINEAR and keep GAMMA
as deprecated aliases, add PERCEPTUAL values so we now have LINEAR,
NON_LINEAR and PERCPTUAL for each encoding, matching the babl
encoding variants RGB, R'G'B' and R~G~B~.
- gimp_color_transform_can_gegl_copy() now returns TRUE if both
profiles can return a babl space, increasing the amount of fast babl
color conversions significantly.
- TODO: no solution yet for getting libgimp drawable proxy buffers in
the right format with space.
plug-ins:
- follow the GimpPrecision change.
- TODO: everything else unchanged and partly broken or sub-optimal,
like setting a new image's color profile too late.
app:
- add enum GimpTRCType { LINEAR, NON_LINEAR, PERCEPTUAL } as
replacement for all "linear" booleans.
- change gimp-babl functions to take babl spaces and GimpTRCType
parameters and support all sorts of new perceptual ~ formats.
- a lot of places changed in the early days of goat invasion didn't
take advantage of gimp-babl utility functions and constructed
formats manually. They all needed revisiting and many now use much
simpler code calling gimp-babl API.
- change gimp_babl_format_get_color_profile() to really extract a
newly allocated color profile from the format, and add
gimp_babl_get_builtin_color_profile() which does the same as
gimp_babl_format_get_color_profile() did before. Visited all callers
to decide whether they are looking for the format's actual profile,
or for one of the builtin profiles, simplifying code that only needs
builtin profiles.
- drawables have a new get_space_api(), get_linear() is now get_trc().
- images now have a "layer space" and an API to get it,
gimp_image_get_layer_format() returns formats in that space.
- an image's layer space is created from the image's color profile,
change gimpimage-color-profile to deal with that correctly
- change many babl_format() calls to babl_format_with_space() and take
the space from passed formats or drawables
- add function gimp_layer_fix_format_space() which replaces the
layer's buffer with one that has the image's layer format, but
doesn't change pixel values
- use gimp_layer_fix_format_space() to make sure layers loaded from
XCF and created by plug-ins have the right space when added to the
image, because it's impossible to always assign the right space upon
layer creation
- "assign color profile" and "discard color profile" now require use
of gimp_layer_fix_format_space() too because the profile is now
embedded in all formats via the space. Add
gimp_image_assign_color_profile() which does all that and call it
instead of a simple gimp_image_set_color_profile(), also from the
PDB set-color-profile functions, which are essentially "assign" and
"discard" calls.
- generally, make sure a new image's color profile is set before
adding layers to it, gimp_image_set_color_profile() is more than
before considered know-what-you-are-doing API.
- take special precaution in all places that call
gimp_drawable_convert_type(), we now must pass a new_profile from
all callers that convert layers within the same image (such as
image_convert_type, image_convert_precision), because the layer's
new space can't be determined from the image's layer format during
the call.
- change all "linear" properties to "trc", in all config objects like
for levels and curves, in the histogram, in the widgets. This results
in some GUI that now has three choices instead of two.
TODO: we might want to reduce that back to two later.
- keep "linear" boolean properties around as compat if needed for file
pasring, but always convert the parsed parsed boolean to
GimpTRCType.
- TODO: the image's "enable color management" switch is currently
broken, will fix that in another commit.
When a user extension with same id as a system extension is installed,
set the system extension unsensitive in the GUI (as well as extensions
with missing requirements, though it is not implemented yet).
The reason why I broke this change in 2 commits (with the previous
commit) is because it will allow to easily cherry-pick the core code
commits whereas the GTK+ code will have to be reimplemented for
gimp-2-10 since this widget uses GTK+3 API.
In the dynamics editor, use the neutral curve color, which depends
on the current theme, for the "fade" curve, instead of hard-coding
it to dark gray, which is hardly visible with dark themes.
Remember the sample point's GimpColorPickMode in the sample point
itself, so it is remembered across switching between images.
Not persistent in the XCF yet tho...
This is just some preparation for fixing issue #1805, but actually
"target" is a much better name so I went the full way and also changed
GUI labels and the color picker tool options config property
accordingly.
If anyone notices at all, how horrible is it to lose your saved pick
target...
gimp_controller_wheel_scroll(): attempt to translate smooth scroll
deltas to GdkScrollDirection, controller events are always discrete
steps.
Works fine on X11, no idea how it behaves on other backends, please
check and report.
Don't destroy the color frames when the number of points changes.
Instead, simply hide them so they keep their color model, but add an
upper limit of an arbitrary number of 16 frames to keep around.
The extension dialog will show details about an extension (long
description, screenshot, upstream URLs, etc.) with this widget.
Update the GimpExtensionList to send a "extension-activated" signal on
double click, and make the extensions dialog react on it to display the
extension details for the activated extension.
This is all still mostly a skeleton GUI, but it is starting to get into
shape.
This is using GTK+3 widgets, so I make sure to keep it well separated
from core code. The gimp-2-10 version will have to rework the GUI, but
the GtkListBox and GtkSwitch are nice and make things easier, so it is
worth using them here).
In GimpAction, instead of connecting the action-history log
function to the action's "activate" signal as a user-provided
handler, call it directly from the default handler.
In subclasses of GimpAction, chain to the parent's activate()
function before emitting the "selected" signal, so that we always
log the action in the history before responding to it.
This allows us to avoid the hack in commit
6544ce4301.
In gimp_action_history_activate_callback(), bail if history.gimp is
NULL, instead of dereferencing it. This can happen if GIMP is shut
down during the execution of a temporary procedure, such as a
script-fu script. See the code comment for details.
In GimpMeter, use cairo_path_extents() for getting the history
graph's extents, rather than cairo_clip_extents(), since the latter
may also include clipping applied by GTK.
Add an "async" field to the dashboard's "misc" group, showing the
number of async operations currently in the "running" state (i.e.,
all those GimpAsync objects for which gimp_async_finish[_full]() or
gimp_async_abort() haven't been called yet).
Preview generation for layer groups is more expensive than for
other types of drawables, mostly since we can't currently generate
layer-group previews asynchronously. Add a preferences option for
enabling layer-group previews separately from the rest of the
layer/channel previews; both of these options are enabled by
default. This can be desirable regardless of performance
considerations, since it makes layer groups easily distinguishable
from ordinary layers.
In GimpViewRendererDrawable, use
gimp_drawable_get_sub_preview_async(), added in the previous
commit, to render drawable previews asynchronously. While the
preview is being rendered, either keep showing the previous
preview, or render a placeholder icon.
This commit also fixes an issue where, under certain conditions, a
drawable preview would be rendered, even when layer/channel
previews are disabled in the preferences.
- remove gimp_widget_flush_expose()
- remove the "now" argument to gimp_display_shell_flush() and make it
only update widget states
- rename gimp_display_flush_whenever() to gimp_display_flush_update_region()
and call gimp_display_shell_flush() separately in the only case we
passed FALSE to flush_whenever()
- remove th flush_now interval logic from GimpDisplay, as soon as we
have exposed the canvas, we are in the loop for the next frame clock
tick anyway, so delaying a useless and removed process_updates serves
no purpose
- in gimptool-progress.c, create the invisible grab widget also for
non-cencelable cases, so we can always safely run the main loop
manually to make the progress updates visible
- in gimp-gegl-apply-operation.c, always run the main loop manually
to make the progress updates visible
- in gimpstatusbar.c, leave some FIXME comments as reminder that
we might need the same logic as in gimptool-progress.c
When defining a dashboard group, allow specifying multiple
variables as input to the group meter's LED. The LED is active
when any of the specified variables evaluates to TRUE, and its
color is the combination of the active variable colors.
Remove the swap-busy variable, and use swap-reading and
swap-writing as inputs to the swap group's LED instead, so that the
LED's color indicates whether the swap is currently being read-
from, written-to, or both.
Actually since we make this function so that it should never return
NULL, we may as well return a test at the end. If pixbuf is NULL, then
it is an implementation bug somewhere and we should fix it.
Massimo spotted some warning with clang in #1608 about pixbuf being used
initialized. Rather than just initializing it, I am actually
reorganizing a bit more the function because there was a bit of a logics
bug. In some weird case, it would have still been possible for this
function to return NULL instead of a magenta square (the case was: the
icon was not present in the icon theme; then wilber-eek was either not
present or failed to load).
This new code organization is more clearer, as a step by step, should
better identify the various failure cases and always return an allocated
GdkPixbuf.
This is the only place where such a check occured. All other calls
seemed to expect the return value to be non-NULL already.
(cherry picked from commit a9d851070a)
When the "gimp-wilber-eek" fallback will fail to load, we just create an
ugly magenta square instead.
See Mitch's review at #1608.
Master adaptation for commit 32931c4606.
We were already doing so when an icon was simply absent from the icon
theme. But we may still end up in cases where the icon is seemingly
present, yet it fails to load (for instance the image file is
corrupted). When this happens, let's also try to load the wilber-eek
fallback.
Note that it doesn't completely stops gimp_widget_load_icon() from
possibly returning NULL (in the case where "gimp-wilber-eek" is also
missing/corrupted for instance), so calling code must still account for
possible NULL return value.
Basically the same as commit 9c6237b182
except that I just redid it instead of cherry-picking because the code
was a bit too different.
If "gimp-swap-colors" or "gimp-default-colors" are present in the theme,
yet broken somehow, GIMP would crash because it was not checking if the
icons had been successfully loaded.
Just make the relevant checks and output on standard error that the swap
and/or default color areas are invisible.
(cherry picked from commit d997b2b897 with
conflicts resolved)
Let the split and replicate segments dialogs keep their own data and
don't use GimpGradientEditor struct members. Remove redundant members
and indent the struct.
- remove redundant frames, 3d-frames are gone anyway, so no need to
keep double out/in frames around
- give all color selector classes CSS names
- add/fix some theme CSS styles
Set the tooltip in GimpColorHexEntry itself and remove all other
tooltip setting. This just moves the translatable string sround in
libgimpwidgets/, and even removes it from app/.
... to satisfy the inter-variable dependencies, so that the READING/
WRITING variables are based on the READ/WRITTEN values of the
current sample, and not the previous one.
Add "read" and "written" fields to the dashboard swap group, which
report the total amount of data read-from/written-to the tile swap,
respetively. These fields are non-active by default. When these
fields are active, show a color underlay in the swap group's meter,
indicating when data was beging read-from/written-to the swap.
Improve the swap busy indicator (used as the meter's LED), so that
it's active whenever data has been read-from/written-to the swap
during the last sampling interval, rather than at the point of
sampling.
...while other windows are on the second monitor if window positions
are saved at exit
Add some lines of code to color_area_color_clicked() which position
the already existing color dialog exactly like a newly created dialog
would be positioned by gimp_dialog_factory_add_dialog().
This should be part of GimpDialogFactory but let's wait for another
case before we generalize it.
The memory group shows memory-usage information: the currently used
memory size, the available physical memory size, and the total
physical memory size. It can also show the tile-cache size, for
comparison against the other memory stats. The memory group is
active but contracted by default.
Note that the upper-bound of the meter is the physical memory size,
so the memory usage may be > 100% when GIMP uses the swap.
This is currently implemented for *nix systems with Linux-like
procfs, and Windows.
and remove all other calls to gtk_widget_show(child). We used to do
this in gimp_dockbook_add() before (which is gone), and missed to add
a few show(). Since we have no invisible pages, simply show them
gemerically.
when the GimpDeviceInfo already has a device. This is not a programming
error that should trigger a bug report popup, it's something else about
non-uniqueness of device names, or whatever. Simply g_printerr() a more
useful message that can help to debug this and bail out.
Make the bottom-left entry request only minimal width, it expands
anyway. Also replace the "Columns:" label by a "grid" icon and set a
tooltip on the columns spinbutton.
Never return an internal image/buffer/svg/curve from any
gimp_clipboard function if we are not the owner of the display's
clipboard. The clipboard is supposed to be a global thing, and we must
only offer to ourselves what would be pasted in any other app.
and use GtkNotebook's implementation instead. This is mostly moving
dockable adding and removing code to GtkNotebook::page_added() and
::page_removed() and removing lots of code.
...won't work with older GIMP?
Make gimp_image_get_xcf_version() return a "reason" string which lists
all reasons why the image can't be saved with compatibility for older
GIMP versions. Display the reason as tooltip on the compat hint label
in the save dialog.
this looks correct now, but I doubt it still works 100% as with GTK+
2.x when the tag popup starts scrolling, we still measure the popup
size wrongly imo.
gimp_container_tree_view_clear_items(): GTK+ 3.x always keeps the row
with the cursor selected, so we get a gazillion selection changed
during gtk_tree_store_clear(), block our selection changed handler
during the clear.