From years of discussions, it turns out that:
- The thumbnailed-Wilber icon replacing the generic icon of GIMP often
makes the application harder to spot in the icon list of running
processes.
- In single-window mode in particular, it makes even less sense as we
just show the one active image anyway.
- Even in multi-window mode, nowadays many OSes or desktop group windows
of a same application under one icon. So we end up with several image
windows under a thumbnail only showing the top image. This happens in
KDE, GNOME, Cinnamon and Windows at least apparently (as far as is
being reported).
- Some platforms would just use only the OS-declared icon and not care
about runtime-declared ones. This is apparently the case on macOS, and
also on GNOME when the desktop file is seen by the desktop
environment. So all our code about generating thumbnailed icon is
wasted on these platform anyway.
- When intensively testing the current behavior, I had cases when the
icon was not properly updated. We could of course investigate and fix
the issues, but considering all the previous points, it might make
more sense to simply drop the feature which is mostly useless, or
worse bothersome, hence simplify the code greatly.
- Finally API to set icons from GdkPixbuf data has been removed in GTK4.
So long term, trying to keep this whole machinery feels like just
making our life difficult for a feature which all OSes seem to
deprecate and which might not be possible anymore soon (or just get
harder and harder to implement).
Note that I don't use gtk_window_set_default_icon_name() because it
would use the icon from our theme, yet so far we are not sure it makes
sense for the application icon which we probably always want to be the
same, whatever the chosen theme. Finally I just list various common icon
sizes because GTK API doesn't seem to be clever enough yet. I can't just
give it 1 SVG image (e.g. with gtk_window_set_default_icon_from_file())
and hope it does the resizing at the last minute. It turns out it
doesn't and we get an extra-small icon. So instead, let's generate
common sizes ourselves from the same SVG.
As suggested in a comment (itself coming from an IRC discussion), we
should not use gdk_window_(begin|end)_draw_frame() functions as this
works on X, but not on Wayland anymore. Instead draw directly during
draw() call of the shell widget, and force it to happen regularly, to
update the marching ants, via gtk_widget_queue_draw_region().
This is tested and works on Wayland. Please everyone, test thoroughly to
make sure it works well in all situations, and also that we don't get
any unexpected slowdowns.
Since the symptoms are very similar, it is highly possible that it also
fixes the issue #5952 too, for selection not showing on macOS since Big
Sur 11 (maybe they changed the same way as Wayland did). Unfortunately I
can't check this myself. Please test, whoever has access to a macOS Big
Sur and can build GIMP!
... which is similar to gimp_display_shell_get_pickable(), however,
it returns the projection, rather than the image, only when
gimp_display_shell_get_infinite_canvas() is TRUE, i.e., when the
shell is in "show all" mode *and* canvas padding is disabled.
In GimpDisplayShell, scale the render cache by the window's scale
factor, and render its content in device pixels, instead of scaled
application pixels. When painting the cache to the screen, unscale
the cairo context by the same factor, so that it's painted in the
native resolution. Note that the various
gimp_display_shell_render_foo() functions still speak in
application pixels, and the scaling happens internally in
gimp_display_shell_render().
Aside from rendering at native resolution on HiDPI, this also fixes
an issue where grid-like display artifacts would appear when the
render cache was not fully validated due to the non-native scaling.
Update the image-projection priority rect to the current display's
viewport when the display becomes active, so that the right region
is rendered first when switching between different displays of the
same image.
Add a "show canvas boundary" display option, and a corresponding
"View" menu item and default-apperance preferences option. When
enabled (the default), the canvas boundary is shown as an orange/
black dashed line in "show all" mode.
Add a "show all" mode to GimpDisplayShell, controlled through a
corresponding "View -> Show All" menu item. When enabled, the
entire image content is displayed, instead of cropping the image
to the canvas size. More generally, the display behaves as if the
canvas were infinite. The following commits improve the overall
behavior in this mode.
Add a prefernces option to control the default "show all" state.
... which controls whether or not the image is rendered by the
shell. We'll use this to hide the image while showing its
transform preview in the next commits.
Introduce a render cache that keeps the result of scaling, color
management, display filters and shell mask (for tools like fuzzy
select).
Change gimpdisplayshell-render.[ch] to only render to the cache and
manage a cairo region of the cache's valid area. Call cache
invalidation functions form various places. Change the API of all
render functions to be in display coordinates.
Also get rid of gimpdisplayxfer.[ch] because we now have a
canvas-sized cairo surface which is a surface similar to the
destination surface.
Instead of having layer picking only on paint tools with alt-click, make
it available everywhere with alt-middle click. Moving through layers is
also a way to navigate an image, so it actually makes sense to be with
other modifiers (panning, zooming, rotating), while making the feature
more generic (this is definitely useful whatever the selected tool).
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.
- 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
which means we can't setup scrollbars there. Move the code to a
GtkTickCallback which runs before the next frame after the
size-allocate.
Also put the center_image_on_size_allocate() code there because it has
to run after the canvas' tick callback, and the order of tick
callbacks can't be controlled.
As a side effect we now have a flag in GimpDisplayShell which
indicates that there will be a size allocate before the next frame, so
simply skip drawing the canvas completely. This fixes new images
jumping around when they are first shown.
When Control-Button2-Zooming, remember the start point, pass it to
gimp_display_shell_scale_drag() and force gimp_display_shell_scale()
to zoom around that point by passing GIMP_ZOOM_FOCUS_POINTER and
faking the point using gimp_display_shell_push_zoom_focus_pointer_pos().
- add new "device from event" apparatus that works on GTK+ 3.x
- fix the active device selection mechanism
- use the new device grabbing functions
- make sure we don't process events while we have a grab on
another device
- compensate for some really obscure (and likely broken) behavior
of XI2, it feels like we are the first real users...
Commit b279c2d217 was breaking a specific use case, which I oversaw:
when space bar activates the move tool, you may want to release the
space bar while mouse button is pressed, and expect to still be able to
move the layer/selection/guide, but releasing space was stopping the
move immediately. The move tool must only be deactivated when both space
and button 1 are released, and the move itself must continue as long as
button 1 is pressed (when started while space was pressed).
As a nice side effect of this commit, panning and canvas rotation are
also improved since now they can be continued while releasing space
(respectively shift-space) if mouse button 1 was pressed, and up until
the mouse button is released. Pressing space again, then releasing the
mouse, back and forth, also work as expected (i.e. move tool stay
activated though the move stops; and panning or rotation continue).
Of course now we don't get anymore panning/rotation stuck while neither
space nor mouse buttons are pressed (which was the original bug). At
least one of these need to stay pressed for panning/rotation/move to
stay activated. And initial activation is obviously always through
(shift-)space only.
The bug was affecting actually both canvas rotation and panning when
done with space key. If the first mouse button was also clicked, then
released after the space key, we ended up in some stuck action. It could
only be unstuck by hitting/releasing space again.
I am actually unsure that this was not originally done on purpose,
especially since the code has these 2 status variables space_pressed and
space_release_pending, but really apart from looking at this code, the
behavior just looks very buggy and impracticable.
The new behavior is to just stop the canvas panning/rotation as soon as
space is released (which is also how it is documented in our manual, and
how everyone seems to use the feature). I only kept the variable
space_release_pending, which I use as was used space_pressed before.
...outside area of Crop Tool -> Highlight option
Add "highlight-opacity" property and turn the controlling GUI into an
expanding toggle that reveals an opacity slider.
When we have display filters, break the color profile transform in
two: first, convert from the image profile to sRGB, then apply the
filters, then convert from sRGB to the monitor profile.
.. due to gdk_pixbuf_scale() with themes using the pixbuf engine
Make GimpDisplayShell a subclass of GtkEventBox, so that it gets its
own window, isolating its events from those of its ancestors.
In particular, the "expose" event handler of GtkNotebook, which the
shell is a child of in SWM, is particularly slow with themes that
use the pixbuf engine. If the notebook and the shell use the same
window, this can cause notable, and somtimes severe, lag when the
rulers or scrollbars are updated frequently, such as when rapidly
moving the cursor.
which encapsulates a cmsHTRANSFORM and does all the pixel format
conversion magic. It has API to create transforms and proofing
transforms, and to convert pixels arrays and GeglBuffers.
Before, each place which has a transform had to keep around the
transform and its input and output Babl formats, and had to implement
lots of stuff itself. Now all that lives in GimpColorTransform,
removing lots of logic from many places, and pretty much removing lcms
from the public API entirely.
This removes including <lcms2.h>, LCMS_LIBS and LCMS_CFLAGS from
almost all directories and potentially allows to replace lcms by
something else.
Add a View -> Color Management submenu that allows to change
the color management mode per-display.
Internally, keep a GimpColorConfig object around per-display that
is synchronized with the global config except for the properties
that have a per-display GUI (currently the mode).
Also provide an "As in Preferences" menu item to follow the global
settings again.
Use the shell's color config for color managing the display and
various auxiliary widgets attached to it, like the notebook tab widget
and navigation popup.
The config is currently just a reference to the global prefs config,
so no behavior changed.
Change gimp_get_display_name() to also return the screen, and its
implementation in the GUI to return the initial monitor during
startup. Retrieve that information in app.c using a weird callback
construct and pass the monitor to file_open_from_command_line().
Half-related, add screen and monitor parameters to GimpDisplayShell
and use these initial values for calculating the canvas's initial
extents.
The image windows still don't position themselves correctly though
because we have no mechanism for that whatsoever just yet, but we now
at least pass the needed monitor information to the right objects.
Disable extended input events when the cursor moves to a child of
the canvas widget. Otherwise GTK will try and fail to deliver an
extended event to the child widget, and end up sending it to the
canvas instead.
Along with this change, the snap preferences have been moved from
GimpDisplayConfig to GimpDisplayOptions, where it makes much more sense.
One of the consequences is that there is no need to duplicate these
values in GimpDisplayShell anymore to differenciate defaults and
current settings.
This removes the obsolete check which makes the tool fail from
gimp_display_shell_set_mask(). Also change the foreground select tool
and the display mask from using GimpChannel to GeglBuffer, because
that's what it needs, simply buffers. Most changed files simply newly
include <gegl.h> because a GeglBuffer appeared in two headers.
First version of display rotation, inspired by gimp-painter.
The rotation always happens around the image's center.
The only "UI" for rotating is currently shift+middle-drag and
shift+space-drag. Control constrains the angle to 15 degrees
and is currently the only way to go back to "no rotation".