I only translated the undo menu into GtkBuilder's .ui format for now.
The only missing part is that the icon is now shown.
Note that in various parts, I don't rely anymore on a bogus menu action (i.e.
"undo-popup" action in this case) which does nothing but has an associated label
and icon. I simply add the label and icon as submenu attribute directly in the
.ui file, which is translatable and whose strings should be parsed by gettext.
Eventually I'll just get rid of all the various "*-popup" or "*-menu" bogus
actions.
gimp_display_shell_render() writes to a GeglBuffer backed by allocated memory
(shell->profile_data). Unfortunately while converting prevision in
gimp_image_convert_precision(), we change the "precision" property (hence the
source format) first, hence end up trying to write data in a too small buffer.
This crash was hard to find as it was not showing up on my machine (though it
did produce rendering artifacts!), unless I built both GIMP and babl with
`b_sanitize=address`.
Note that an alternate fix was to make sure that the profile_data buffer is big
enough (by calling gimp_display_shell_profile_update() before rendering), but
anyway the image is in an inconsistent state while conversion is in progress:
whereas the `src_format` is the new one, the `src_profile` is still the old one
(and cannot be changed before we finish converting).
Moreover the render happen regularly on progress signals, once after each
converted drawable. So each of these rendering step happens in an inconsistent
state, with the wrong profile set, some of the drawables converted and others
not yet.
We could still render properly if each drawable's buffer used space-aware format
(thus allowing different drawables to use different profiles/spaces), but it
feels over-engineering the problem. It might be much better to ignore rendering
steps while converting the image precision. Moreover it would obviously make a
faster conversion.
See discussions in #9136 for this crash, which didn't have dedicated report
AFAIK.
(cherry picked from commit de25be9210)
Note: on the `master` branch, even with sanitized code, I don't get the crash.
Yet this change seems relevant enough that I'm adding it.
For now GimpModifiersManager returns the same modifiers as what was
previously hardcoded and we have no GUI yet to change the settings. But
the core of the new feature is in place.
Not sure why but adding a handler to the "expose-event" signal of
GimpDisplayShell (similarly to how we do it in master branch on "draw")
just didn't work. But it works on the already existing signal handling
on the canvas instead (which actually is not a bad deal, as we also
remove the coordinates translation so maybe we should test this on
`master` too).
Note: why we are backporting all this logics to gimp-2-10 is because
changes in macOS BigSur broke the selection's marching ants the same way
they broke on Wayland and it was confirmed this fix worked for BigSur as
well, at least on the dev builds.
It is unnecessary to backport for Wayland (because GIMP 2.10 is based on
GTK2 which anyway works only through XWayland, hence doesn't have the
issue), we do it only for macOS BigSur (and further). Well at least the
fix will hopefully work on the stable branch, because I cannot test
myself.
See issue #5952.
(cherry picked from commit 6be014fc59)
Cherry-pick note: it was initially only for gimp-2-10 but actually also
works fine on the GTK3 branch and fixes some selection coordinates issue
when rotating the canvas.
Add an option to keep the normal canvas padding in "show all" mode,
instead of extending the checkerboard pattern indefinitely. This
is useful when wanting to show the image content beyond the canvas,
while still keeping the focus on the canvas; further commits will
extend this mode to behave in more view-related cases as if "show
all" wasn't enabled.
Add a new 'View -> Padding Color -> Keep Padding in "Show All"
Mode" toggle, which controls this behavior, with a corresponding
default-value option in the preferences, under "Image Windows ->
Appearance".
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.
In "show all" mode, the image is thought to be "infinite"; this
commit improves the overall scrolling/zooming behavior in this mode
according to this assumption. In cases where a specific image size
is needed (e.g., for the scrollbar bounds, fit-image-in-window,
etc.), the image's full bounding box is used; however, in cases
where a center point is needed (e.g., for the zoomed-out scrollbar
bounds, center-image-in-window), the canvas center, rather than the
bounding-box center, is still used.
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.
Since introducing gimp_display_shell_canvas_tick() we were setting
shell->disp_width and shell->disp_height in the tick callback, which
was too late and caused redundant rendering and scrolling, but was
never noticed.
Now we clear the render cache and its valid region in
gimp_display_shell_canvas_size_allocate() directly and set
shell->disp_width and shell->disp_height immediately, so other places
that listen to the canvas' size-allocate get the right values.
The old size of the canvas gets to the tick callback using a small
struct as user data.
Must initialize shell->render_buf_width,height before realize(), so
move the code to gimp_display_shell_init(), it doesn't depend on the
shell being realized.
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.
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.
Reset the canvas size request from gimp_display_shell_constructed() in
gimp_display_shell_canvas_size_allocate() so the image window can be
made smaller again. GTK+ 3.x always respects size requests.
Remove all clipping hacks for drawing the canvas background, turns out
they never worked and we were relying on the pattern set on the
window, gah!
Also remove deprecated attempts to get a backgroud color and simply
don't show a color box in the menus for "from theme" cases.
Remove the connect_after() hack from GimpImageWindow again and instead
add gimp_display_shell_canvas_realize_after() and restore the configured
ruler visibility there. Should work for all cases now.
...if "Show rulers" is disabled
Add HACK to gimp_display_shell_canvas_realize() that makes sure the
rulers are always mapped once for each new GimpDisplayShell. This
seems to magically fix all the crashes.
Based on a patch by Massimo.
Move the entire image-space/screen-space transformation logic from
gimp_display_shell_render() to gimp_display_shell_draw_image(), so
that the former works entirely in image space, and do the chunking
and clipping in screen-space, making sure that image-space chunks
are never larger than
GIMP_DISPLAY_RENDER_BUF_WIDTH x GIMP_DISPLAY_RENDER_BUF_HEIGHT,
even when the window's scale factor is greater than 1.
Add a GIMP_BRICK_WALL environment variable, which, when set, shows
the screen-space chunk bounds.
The abbreviated commit hash we show in the shell and the about
dialog is currently just the last 7 characters of 'git describe',
based on the assumption that abbreviated hashes are always 7-digits
long. When the hash is longer than that, we're just showing a
nonsense commit.
This was never a good idea, since users can override this, and
since disambiguation can result in longer hashes, but since git
2.11, the default abbreviated hash length is determined based on
the size of the repository, which currently results in 10 digits
for us.
Let's just do it right.
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".
by not manually intersecting and subtracting regions at all. Simply
clip the cairo_t to the area we want to render, it will automatically
intersect with the clip region from the expose event, and check if the
clip is empty before actually drawing anything.
the changes are simply copied from the gtk3-port branch, reducing the
number of diffs, and enabling hacking on drawing stuff in master while
keeping the branch easily rebasable.
Recent Cairo uses SHM transports when available, and exposes the ability
for its users to manage images shared between it and the display.
This allows us to eliminate copies, and if the architecture supports it
even to upload directly into GPU addressable memory without any copies
(all in normal system memory so we suffer no performance penalty when
applying the filters). The caveat is that we need to be aware of the
synchronize requirements, the cairo_surface_flush and
cairo_surface_mark_dirty, around access to the transport image. To
reduce the frequency of these barriers, we can subdivide the transport
image into small chunks as to satisfy individual updates and delay the
synchronisation barrier until we are forced to reuse earlier pixels.
Note this bumps the required Cairo version to 1.12, and please be aware
that the XSHM transport requires bug fixes from cairo.git (will be
1.12.12)
v2: After further reflections with Mitch, we realized we can share the
transport surface between all canvases by attaching it to the common
screen.
v3: Fix a couple of typos in insert_node() introduced when switching
variables names.
v4: Encapsulating within an image surface rather than a subsurface was
hiding the backing SHM segment from cairo, causing it to allocate
further SHM resources to stream the upload. We should be able to use a
sub-surface here, but it is more convenient to wrap the pixels in an
image surface for rendering the filters (and conveniently masking the
callee flushes from invalidating our parent transport surface).
Cc: Michael Natterer <mitch@gimp.org>
instead of checking for event->button == 3, so context menus
work correctly on the Mac. Didn't change the image menu yet
because thet requires some more refactoring.
And remove all the complicated handling code entirely. This makes
GimpTransformTool a lot less complex. As a nice side effect, the
preview is now always 100% in sync with the grid and handles.
This was only there to make sure XOR drawing works, and is now
complete overhead since cairo drawing is done *in* expose, and not in
some hack around it.