This fixes all our GObject Introspection issues with GimpUnit which was
both an enum and an int-derived type of user-defined units *completing*
the enum values. GIR clearly didn't like this!
Now GimpUnit is a proper class and units are unique objects, allowing to
compare them with an identity test (i.e. `unit == gimp_unit_pixel ()`
tells us if unit is the pixel unit or not), which makes it easy to use,
just like with int, yet adding also methods, making for nicer
introspected API.
As an aside, this also fixes#10738, by having all the built-in units
retrievable even if libgimpbase had not been properly initialized with
gimp_base_init().
I haven't checked in details how GIR works to introspect, but it looks
like it loads the library to inspect and runs functions, hence
triggering some CRITICALS because virtual methods (supposed to be
initialized with gimp_base_init() run by libgimp) are not set. This new
code won't trigger any critical because the vtable method are now not
necessary, at least for all built-in units.
Note that GimpUnit is still in libgimpbase. It could have been moved to
libgimp in order to avoid any virtual method table (since we need to
keep core and libgimp side's units in sync, PDB is required), but too
many libgimpwidgets widgets were already using GimpUnit. And technically
most of GimpUnit logic doesn't require PDB (only the creation/sync
part). This is one of the reasons why user-created GimpUnit list is
handled and stored differently from other types of objects.
Globally this simplifies the code a lot too and we don't need separate
implementations of various utils for core and libgimp, which means less
prone to errors.
This removes rate limiting of ruler and statusbar updates which were
required to get acceptable performance on mac for drawing on the canvas.
This requires the latest changes on in Gtk 3.24 to be incorporated.
Gets drawing in the canvas speed on retina displays up to the speed
of FullHD displays on macOS, making 2.99 usable on macOS.
Generic change:
Changes the cursor_label to delay the drawing phase to the idle
queue, from immediate draw on all platforms.
Before the fix in 32049afd (using a deprecated function in Gtk3)
any draws on this label forced a full canvas redraw. This is due
to a quirk in how GtkLabel functions.
The redraw occurred because GtkLabels resize themselves and everything
around them by sending a resize message any time they receive new
text. These resizes then trigger the full canvas resize which triggers
a full canvas redraw that cannot be optimized by either Gtk or Big Sur.
MacOS changes:
Only redraws the cursor position label and each of the horizontal and
vertical rules (cursor tracking widgets) 3 times a second max for a
total of 9 redraws a second (ideally out of 60, though I don't believe
under any circumstances that GIMP achieves a 60fps).
Each of the cursor tracking widgets gets its own timeslice, and so
will not redraw when the other cursor tracking widgets are drawing.
This is required because Big Sur is merging all draw rects into
one large rect, dramatically slowing down draws.
This timeslicing ensures that draw rects are maintained at the smallest
possible size. So the typical redraw is a small rect around the
brush. However, 9 times a second, the rect will include one of the
3 cursor tracking widgets (rulers and cursor label).
Additionally, the code tries to minimize resizing the width of the
cursor label by checking if the widget is too small for the text,
then setting the char_width to a greater size so that resizes won't
be that common.
This improves the appearance of the widget as it no longer
constantly jumps about in size on each cursor move.
Here is a discussion of the issue:
https://gitlab.gnome.org/GNOME/gimp/-/merge_requests/572#note_1389445
Reviewer's (Jehan) notes:
* The whole issue about GtkLabel resizing is no more after 32049afd. It
is normal for a widget to request a resize when needed. We just don't
want the statusbar to resize and triggering canvas redraws.
* Changing cursor position text into an idle function generally makes
sense.
Also it reverts commit 6de9ea7022 which had a bug I hadn't realized
when I accepted it: when we test for time, we don't know yet if it
will be the last position change, hence we could "refuse" the last
update. Therefore displayed cursor position would end up outdated
on macOS. This new implementation doesn't have the problem (the last
idle update always happens after the last move).
* The change about giving 1/3 timeslices to side canvas components
(rulers and statusbar) is a complete hack to work around the fact that
macOs doesn't report properly each damaged rectangle. Instead it
returns a huge bounding box. The workaround here is to expose these
area separately.
We have not been able to find a proper solution yet. This is the only
reason why I accept this code, for macOS only, to at least have
something usable there.
See discussions in MRs gimp!572 and gimp-macos-build!86. With these 2
MRs, Lukas reported GIMP 2.99 to perform even better than GIMP 2.10 on
Monterey, though it could not be tested on Big Sur unfortunately.
* Lastly the set_width_chars() thing is also an ugly hack which I will
try later to revisit (see !581). I only accepted it (with mandatory
macOS-only macro) to have an acceptable state for release after seeing
a screencast where the label size indeed "jumps around" on macOS.
`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.
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.
Make better subvision, as well as ruler steps, based on what seems to be
the common trends for rulers of these 3 units (inch, foot and yard), but
also based on common conversion needs.
Main changes are:
- Always subdivide inches by 2, down to 1/256, and get rid of the gap
where inches division jumped from 1/16 to 1/192 (which is not even a
multiple of 2).
- Add the 72 steps to inch ruler (1 fathom).
- Replace the 2 feet by a 3 feet (1 yard) step.
- Use base-10 steps for yard (there don't seem to be bigger units in the
imperial/US measurement system which needs specific steps).
- Add the 1/36 yard (= 1 inch) division.
- Below 1/12 feet and 1/36 yard, divide by multiples of 2 (inch-style).
... 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.
even if we don't have private members (yet). Also make class padding 8
pointers in all headers. This commit moves nothing to private, it just
makes all headers consistent and adjusts .c files accordigly.
Add CSS names using gtk_widget_class_set_css_name(), remove styling in
code and instead do it properly in CSS, so far in the System theme.
All horribly incomplete but a start.
gimp_ruler_draw_pos(): when remembering the just drawn rectangle's
position, don't just unconditionally overwrite the previous position's
rectangle. Instead, if the previous position's rectangle has not been
cleared yet (has a non-zero size), remember the union of old and new
rectangle.
Why this only happened to the vertical ruler with statusbar off is
beyond my mind, it should have always produced artifacts.
Unrelated: make sure the idle function is removed if we decide to
immediately redraw in gimp_ruler_set_position().
Ever since 72617e42b, whenever the user generated a lot of mouse
input, we would constantly queue redraws to the rulers. These redraws
had a higher idle priority than updating the canvas, so we would
rarely get around to canvas updates, which made certain tools
(painting with dynamics, the blend tool) feel very unresponsive.
This fixes it by only redrawing the rulers if the mouse has moved
far from the last location, or if there are no idle handlers with
a priority above LOW.
We now avoid drawing rulers in the position property setter and use
gtk's region invalidation instead. Previously, we were basically
redrawing the ruler inside the mouse event handler, which is pure evil.
because it confuses gtk-doc and breaks some links. Also change the
"Index of new symbols in GIMP 2.x" sections to be what seems to be the
modern standard (looked at the GLib and GTK+ docs), and update some
other stuff.
and completely separate configure and sanity checks for gdk-pixbuf
from GTK+, because it's now distributed as a separate package. Remove
all sorts of conditional compiling based on GDK_CHECK_VERSION() and
CAIRO_VERSION.
Add a list of "track widgets" to GimpRuler and connect to their
motion-notify-event. Correctly translate the motion event's x/y to the
ruler's coordinate system when updating the marker.