`gtk_editable_delete_text` can be called with a
negative `end_pos`, in which case the characters
from the start pos to the end of the text are
removed. [1]
It e.g. gets called this way from
`gtk_editable_set_text`.
So far, that negative index was not converted,
but passed as is in the AT-SPI callback
`delete_text_cb` when calling the `text_changed`
handler (`emit_text_changed` in
`gtk/a11y/gtkatspicontext.c`) which just uses the
index as is, also in it's call to `g_strndup`,
resulting in a crash when negative indices are
used.
Fix this by converting negative values to the
actual end index in `delete_text_cb` before
calling the handler.
[1] https://docs.gtk.org/gtk3/method.Editable.delete_text.htmlFixes: #6149
Updating a Pango context can influence the layout of widget, in
particular that of a GtkLabel, not only its rendering. Make sure to
queue a resize when updating the context.
In particular, this fixes window titles getting suddenly truncated when
moving a window from a HiDPI display to a low DPI one, after
https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/6190 has made font
hinting depend on the widget scale. With hinting enabled on low DPI,
the Pango layout needs ever so slightly more width to not get truncated.
There is plenty of space in the header bar that could be allocated to
the label, but for that to happen, it needs to know to queue a resize.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
The C standard does not specify whether the underlying type of an enum
is signed or unsigned, and until C23 there was no way to control this
explicitly. GCC appears to make enums unsigned unless there is a
negative value among cases of the enum, in which case it becomes signed.
MSCV appears to make enums signed by default.
A bitfield of an enum type (which is not specificied in the C standard
either) behaves as if it was an instance of a numeric type with a
reduced value range. Specifically, a 'signed int val : 2;' bitfield will
have the possible values of -2, -1, 0, and 1, with the usual wraparound
behavior for the values that don't fit (although this too is
implementation-defined).
This causes the following issue, if we have:
typedef enum
{
GTK_ZERO,
GTK_ONE,
GTK_TWO
} GtkFoo;
struct _GtkBar
{
GtkFoo foo : 2;
};
and then assign bar.foo = GTK_TWO and read it back, it will have the
expected value of 2 (aka GTK_TWO) on GCC, but a value of -2 (not
matching any of the enum variants) on MSVC.
There does not seem to be any way to influence signedness of an enum
prior to C23, nor is there a 'unsigned GtkFoo foo : 2;' syntax. The only
remaining options seems to be never using enums in bitfields, which is
what this change implements.
In practice, this fixes GdkPipeIOStream crashing with an assertion when
trying to copy-paste in-app in MSVC builds on GTK.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
This is useful for colorizing in the same fashion we do for the glyph
texture atlas. In fact, for small GdkTexture, you will end up in something
like the icon texture atlas.
The primary motivator for this optimization is to draw various glyph-like
features from VTE such as many forms of boxes, lines, arrows, etc.
As it turns out, ccache accelerates the build so much that it can
trigger a race condition in the gobject-introspection subproject. This
only surfaced recently as the introspection feature was previously
disabled due to missing build time dependencies.
The race condition surfaces as follows: the build breaks because
gobject-introspection starts to build Gdk-4.0.gir before
GdkPixbuf-2.0.gir, despite Gdk-4.0.gir depending on GdkPixbuf-2.0.gir.
The string we're passed here may not be zero-terminated
since our text insertion APIs take string + length. So
So be safe and copy the text we are interested in if
necessary.
Fixes: #6131
Make gtk_print_dialog_setup_finish return a GtkPrintSetup
object, which encapsulates all the data that needs to be
transferred between the setup and print calls, and make
the print_file and print methods take an extra GtkPrintSetup
argument.
Change the print call to return an output stream, rather
than take an input stream. The results are now returned
when the output stream is closed.
With some further cleanup, this makes the GtkPrintDialog
object a proper builder object - you can create multiple
print dialogs from the same GtkPrintDialog object, in
parallel, and they won't interfere with each other.
The portal printoperation inmplementation
relies on the file printbackend to be available.
If it isn't, we should report a proper error
status insetad of running into assertions deep
inside the printoperation code.
We don't need to be calling type node conformity checking from the tight
loop of the renderjob. Hoist that into the private header and use that
intead through via the Class pointer.
Anything that includes gskrendernodeprivate.h will get an alternate form
of ref/unref for render nodes which does not need to do type checking on
the parameter. We can expect that things are correct within GTK itself and
this saves excessive amounts of TypeNode conformities checking.
Let's assert that we schedule the idle callback exactly once.
These assertions are not perfect because if the callback executes before
we schedule it, then the assertion itself would be a use-after-free,
since I'm using the PrinterFinder to track whether the callback that
frees it has been scheduled. But in practice when using loupe's print
dialog, I was noticing the callback scheduled twice before it was
executed. The assertion would have caught this problem.
This is a little tricky. At first, I thought we had a codepath where we
fail to schedule the idle that completes the print operation: if we take
the gtk_print_backend_printer_list_is_done path for each printer
backend, then printer_list_done_cb() is never executed and we never
schedule the idle. But in fact, in this case, then backends == NULL at
the bottom of find_printer(), and we'll schedule the idle there, so it's
OK. Except it's not really OK, because we'll schedule it even if a
printer was already found, resulting in the callback completing twice
and a double free.
Simplify this. Schedule the idle in find_printer() only if there are
*initially* no backends, not also if all backends are immediately ready
and already removed from consideration. Instead, always call
printer_list_done_cb() for every backend in find_printer_init(). After
the previous commit, printer_list_done_cb() will schedule the idle when
appropriate.
printer_list_done_cb() additionally disconnects signals that we did not
connect in this codepath, but it does so using
g_signal_handlers_disconnect_by_func, which is harmless. Otherwise, the
only extra work it's doing is scheduling the idle, and that's exactly
what find_printer_init() is missing.
If we are the final backend, then after removing ourselves there is no
backend remaining. We will schedule the idle even if it has already been
scheduled. This idle is required to run exactly once and executing it
twices results in a double free that crashes loupe when printing. It
also causes the user callback to execute twice, which could cause
similar problems.
Fixes#6122