This will almost certainly overwritten before the widget gets
to the screen, but while we are doing this, we might as well
use the same state that we initialize the widgets state to.
e8aa9b0440 introduced a new debug mode
that highlights resizes. Unfortunately it has the side effect of
always queueing redraws even when the debug mode is not enabled.
Make the redraw conditional.
When a gtk_widget_queue_allocate() on some widget increases the clip,
widget->parent's clip was not updated. This appraoch naively just
unions widget's new clip with widget->parent's clip.
This of course only works if widget and parent share the same GDK
window. In the cases where they don't we can't do anything and need a
better fix.
Fixes label-text-shadow-changes-modify-clip.ui reftest.
The g_print documentation explicitly says not to do this, since
g_print is meant to be redirected by applications. Instead use
g_message for logging that can be triggered via GTK_DEBUG.
GtkWidget uses gtk_container_foreach() to iterate over children and
check whether they need their allocation reset.
However, that leaves out internal children, such as scrollbars of a
GtkScrolledWindow. Use gtk_container_forall() instead.
Now selecting a widget by class name no longer works.
This is probably most relevant for users outside of GTK that want to
style their own widgets. Those widgets should now either add their own
style classes (if they want to adjust existing CSS) or use
gtk_widget_class_set_css_name() themselves (if they want to get rid of
all "upstream" styling).
Check that non-native window are indeed children of the event window and
only then confirm that they should be drawn.
Fixes Glade thinking that it's okay to have the draw function do
different things depending on what window to draw. (This should really
be fixed in Glade.)
... and remove the also forgotten void function that lingered around
with it.
Fixes opacity=0 parts like inactive spinners or sort indicators in
treeview headers being drawn since last commit.
Oops.
Previously, we had a special cae to draw subwindows of widgets.
This is not necessary as conformant widgets should be able to properly
render themselves when all windows need to be painted.
From now on assume that is the case.
We therefore paint nonnative GDK windows "inline" by just returning TRUE
for gtk_cairo_should_draw_window() for those windows.
This speeds up hilighting different rows in the listbox gtk-demo example
tremendously (by a factor of 10 or more) as the previous code was
O(<number of non-window subwidgets> *
<number of subwindows>) which in the listbox example were ~15,000 and
~2,000 respectively.
If a GtkGestureSingle is set as touch-only, pointer events would be
discarded without giving an opportunity to the regular GtkGesture
handler to manage those.
Because the pointer events weren't actually managed by the gesture,
gtk_gesture_get_sequence_state() (rather unhelpfully here) will resort
to returning GTK_EVENT_SEQUENCE_NONE, which is in turn interpreted
by _gtk_widget_consumes_motion() as "may be handling the events for
this sequence", because gestures in this state presumably handle
the events, just that it's not "claimed" yet.
Instead, use gtk_gesture_handles_sequence(), which will perform the
expected check on the event sequence being managed, as we expect
here.
In https://bugzilla.gnome.org/show_bug.cgi?id=601425 the annotations
were changed to int as they not only take the predefined enum values
but also user defined values registered through gtk_icon_size_register()
As a result the typelib doesn't contain any information about
GtkIconSize for those arguments and the Python docstring only
shows the corresponding Python type "int".
This changes the argument docs to mention the type explicitly
so the Python doc generator can add a link to Gtk.IconSize
which contains the most useful predefined values.
https://bugzilla.gnome.org/show_bug.cgi?id=757411
Previously, the ID was only set on the CSS node as a side-effect
of calling gtk_widget_get_style_context. This was showing up
in CSS style tests as nodes lacking their IDs.
gdk_widget_get_frame_clock can return NULL. In particular,
this can happen when the drag window is destroyed at the end
of a DND operation. Handle this gracefully when it happens.
When setting the parent of a widget, queue_resize() on the widget will
be optimized away if the widget already had a resize queued.
Plus, we do not need to resize the widget as its size request is not
going to change.
This makes sure that hidden widgets always have priv->alloc_needed set
on them.
The constructor sets that flag, so we want to have it back when we
revert to this state.
This fixes GtkWindow skipping a size_allocate() when reshowing a
previously hidden window and thereby not updating its allocation and
clip. And that in turn would lead to draws not happening and us beig
left with a black window.
There are currently three widget that implement such a property, and
there are other widgets for which the behavior can make sense. It
seems like a good time to add the property to GtkWidget itself so
subclasses can choose to respect it without adding their own property.
https://bugzilla.gnome.org/show_bug.cgi?id=757269
Mirror the behavior of gtk_widget_queue_resize() and always queue a
redraw. If we ever want to cause allocates without redraws we can add
gtk_widget_queue_allocate_no_redraw() then.
I had initially assumed gtk_widget_size_allocate() would take care of
queueing redraws, but it does not do that when neither size nor position
change. And that is obviously what's happening after
gtk_widget_queue_allocate().
Fixes buttons sometimes not redrawing (the record button in
widget-factory after locking it, all buttons when switching to the dark
theme).
When gtk_widget_show() or gtk_widget_hide() is called, don't queue a
resize on the widget itself but on the parent.
The widget itself may already be marked as in need of a resize and
the call would be optimized out and never reach the parent.
The parent size will change though because a child widget just changed
its visibility.
Fixes a bunch of issues with menus appearing black, toolbas not hiding
in widget-factory and also various reftests.
This commit toggles the big switch. We now don't run size_allocate()
from the toplevel up anymore in cases where we don't need to.
Things might be broken in subtle ways as a result of this commit. We'll
have to find them and fix them.
This happens way too much, so it's disabled unless GTK_DEBUG=geometry is
on.
Also, we can't detect it in the call to queue_resize() yet, only during
size_allocate(), so the warning comes after the signal emission.
... and API to set and unset it.
It is set when gtk_widget_queue_resize() is called.
It is unset when gtk_widget_get_preferred_width/height() is called.
So far it is not used.
This is so widgets can queue a rerun of their allocation logic, but
without triggering resizes everywhere.
For now, it just calls gtk_widget_queue_resize().
This changes widget paths for widgets with a CSS name to return that CSS
name, now that we have added API for it.
This means that style properties are now matches using the CSS name.
Also fix the theme to use the correct name when matching style properties.
See the previous commit for why this is necessary.
Also make gtk_widget_class_set_css_name work by looking at
the correct class for the name.
Note for future reference: GTK_WIDGET_GET_CLASS() does not
work in the instance init function.
Almost all callers of _gtk_widget_draw already did their own
cairo_save/restore, so drop the save/restore calls inside
_gtk_widget_draw and instead fix the last caller, gtk_widget_draw,
to do the same.
We can use gdk_window_peek_children here, instead of copying
the list. Note that we preserve the bottom-to-top ordering by
iterating the list from the end.
gdk_window_get_children_with_user_data was doing a list
reversal while filtering the list.
The default event bubbling paths are prone to just running event controllers
even after the widget was potentially unrealized/destroyed in an event
handler callback, so bail out early if that's the case.
https://bugzilla.gnome.org/show_bug.cgi?id=755352
It makes no sense to skip denied sequences here, the gestures are
still carrying out the accounting for these, which must be also put
to an end if we're possibly not receiving any further events from
this sequence.
https://bugzilla.gnome.org/show_bug.cgi?id=754098
At the time event_check_cancel_sequence_on_hierarchy() is called, the widget
has been already unparented. Given the widget itself is being destroyed,
cancellation on it is impending in one way or another, we still must
propagate cancellation across all parents, so retrieve it early before
possible widget destruction.
https://bugzilla.gnome.org/show_bug.cgi?id=754098
The GtkEventController event mask is private, and set early by GtkGesture
implementations. Being this private data, there is no corresponding
property, so this code is a no-op, there is just no need to listen to
changes there.
We use to rely on grab broken events for most of the event sequence
lifetime, this breaks though on GDK_BUTTON_RELEASE/GDK_TOUCH_END, as there's
no longer a grab at that time.
For these cases (and all others where there's destroy/unrealize calls
involved during event dispatching), catch this on the late
WIDGET_REALIZED_FOR_EVENT calls on widget event handling functions.
https://bugzilla.gnome.org/show_bug.cgi?id=754098
This avoids a lot of overhead in the common case where a signal
is not connected and we're just using the class vfunc (which is true
for all in-libgtk widgets). Additionally it makes backtraces in
debuggers and profiles much much nicer to look at.
https://bugzilla.gnome.org/show_bug.cgi?id=754986
Merge it into GtkWidgetPrivate. In my measurements, about half
of all widgets have a non-default auxinfo struct, and we use this
information in size allocation, so it is nice to avoid the gdata
overhead.
We only use widget paths for a few widgets nowadays (notebook,
treeview, pathbar, combobox), so we can save some space by
not having this field in GtkWidgetPrivate.
The hash table is only accessed at creation and destruction time,
and many widgets don't use templates at all, so no need to have
this permanently occupying space.
This reverts commit 3eacfa88f2.
Apart from the patch not being correct, we don't want to expose private
structures in header files if we can avoid it.
And this type-checking overhead is not an optimization that is even
measurable.
https://bugzilla.gnome.org/show_bug.cgi?id=754932
The logic here is that G_ENABLE_DEBUG is for compiling out
debug spew that can be triggered at runtime with the GTK_DEBUG
environment variable, while G_ENABLE_CONSISTENCY_CHECKS is for
consistency checks that are applied unconditionally.
For all other events, we run the bubble phase deep in the specific
::motion/button-press/release/touch handlers.
For touchpad events, it doesn't make sense to use GtkWidgetClass
slots if the intended way to deal with these are gestures, so we
run the bubble phase directly from gtk_widget_event_internal().
Properties like transition-property might change when hovering over
something, even if the property itself does not change. These properties
don't affect drawing, so don't queue redraws for them.
This allows a widget to override global font_options, such as hinting and
subpixel order. The widget's PangoContext is updated when this is set.
Some update code from gtk_widget_update_pango_context was moved to
update_pango_context so that gtk_widget_update_pango_context runs it.
http://bugzilla.gnome.org/show_bug.cgi?id=751677
Also make them more scary so people really really don't use it as a
random knob when trying to make things go fast.
//bugzilla.gnome.org/show_bug.cgi?id=750505
Instead of issuing g_warning, fill the provided GError.
This lets us test this error handling, and is the right
thing to do. Use the new GtkBuilder helpers and
g_markup_collect_attributes to do so.
When recomputing CSS, we need a correct widget path in the fallback mode
where we're still using widget paths.
So we need to invalidate it everytime it actually changes, and not just
when emitting the style-updated signal.
Fixes css-match-regions reftest.
... and pass it to the API that computes new styles.
A special timestamp of 0 means "please don't animate" and is used when
no frame clock is available for a node.
We don't want to add the current classes to the widget path - which
might potentially be different after a gtk_style_context_save() - but
the root node's ones. So what better thing to do than actually using the
root node?
This ensures the widget data stays live long enough to perform invariants
check after emission if the widget happens to be destroyed on a callback.
https://bugzilla.gnome.org/show_bug.cgi?id=745829
They are a bit terse, and they should point to the preferred way of
overriding the theme, i.e. using a GtkStyleProvider for your
application, and custom style classes.
Postpone until the last moment whether the target widget still
potentially uses updates from this sequence, or window dragging
actually applies because all gestures on the target went to denied
state.
This fixes window dragging on empty space in a headerbar that is
contained in a paned (as in e.g. gedit).
https://bugzilla.gnome.org/show_bug.cgi?id=745562
The gesture is hooked to the capture phase, so it works for buttons in
header bars and whatnot. In order to be friendly to the widget it is
capturing events from, an ugly hack is in place to avoid capturing
events when the target widget has a gesture that would consume motion
events.
There are two scenarios. A widget sub-class owns a GtkEventController
and passes itself to it, or a controller owned by something else is
passed a widget.
In the second case, if the widget is destroyed before the controller,
we will have a crash when destructing the controller because we will
be accessing invalid memory. Adding a weak reference on the widget
addresses that problem.
This leads to a crash in the first case. When the widget is getting
destroyed, it will drop the reference to its own controller. The
controller will skip touching the widget because the weak reference
would have turned it to NULL. However, when the widget sub-class chains
up to GtkWidget it will try to free all the controllers in its list.
Unfortunately, all these controllers have already been destroyed. So
we need to guard against this too.
https://bugzilla.gnome.org/show_bug.cgi?id=745225
Also try and clarify a few things about event propagation. Move
input-handling.xml into gtk-doc’s expand_content_files variable so it
automatically links to widget documentation. Add links from
gtk_widget_add_events() and friends to the new documentation.
https://bugzilla.gnome.org/show_bug.cgi?id=744054
This property is necessary to ensure widgets automatically update after
the text scale factor is changed desktop-wide.
And if I'm already doing a property like this, I can make it
overridable. So now you can override the dpi per-widget with CSS like
GtkSwitch {
-gtk-dpi: 48;
}
if you want to debug things.
Long-term, we want to get rid of this property and insist on dpi being
96 everywhere and people can change the font size to get larger fonts.
Previously, we would not include any child widget on the first
allocation, which happens right after realize(), but before map(). No
widget is drawable at that point.
If this is done on dispose(), the widget may be destroyed (and its
controllers list NULLified) within _gtk_widget_run_controllers(),
causing warnings/crashes when it just tried to hop on the next
controllers.
Freeing the controllers here should be a safety net for implementations,
so it also makes sense to do this late. The widgets that choose to
free their controllers on dispose can still do so, and get
_gtk_widget_remove_controller() called for these as an indirect result.
There is no good reason to assign the value directly.
Also, this fixes d23f3254b7
where widgets that chained up instead of calling
gtk_widget_set_allocation() would not draw becaues of empty clip.
(1) Get rid of supports_clip flag. All widgets (implicitly) support
clip.
(2) Don't reset the clip to { 0, 0, 0, 0 } before the "size-allocate"
signal.
(3) Make gtk_widget_set_allocation() set the clip (to the allocation).
This ensures that eveyr widget has a clip set.
Note: It overrides previous calls to gtk_widget_set_clip(), while in
3.14 this didn't happen.
(4) As the clip is set by gtk_widget_set_allocation() now, don't set
it after the "size-allocate" signal anymore.
This fixes calls to gtk_widget_queue_draw() from inside the
size_allocate vfunc.
These functions, while added for use by the GTK inspector, are generally
useful to applications that need to resolve what action groups are
available to a particular GtkWidget.
https://bugzilla.gnome.org/show_bug.cgi?id=741386
Currently we only take into account the window GActionGroup for
activating the accels.
However, the application could have some custom GActionGroup in the
chain of focused widgets that could want to activate some action if
some accel is activated while that widget is focused.
To allow applications to set accels on widgets that use custom
GActionGroups, simply use the muxer of the focused widget, which
already contains the actions of the parents.
https://bugzilla.gnome.org/show_bug.cgi?id=740682
I checked Cairo source code (actually pixman, as Cairo just passes
through) to make sure that the behavior stays identical: negative values
cause an error message from pixman, zero is allowed. Both return an
empty region which gtk_widget_queue_draw_region() would then proceed to
ignore.
Under wayland, the compositor doesn't have a 'overall window alpha'
knob, we just need to add the alpha to the buffers we send.
Client-side alpha, if you want to call it that.
Implement this by reusing the existing alpha support for non-toplevel
widgets. As a side-effect of the implementation, windows with RGBA
visual under X will now also use per-pixel alpha, instead of
overall alpha.
This is a new function that gets called every time we're drawing
some area in the Gtk paint machinery. It is a no-op right now, but
it will be required later to keep track of what areas which
we previously rendered with GL was overwritten with cairo contents.
... just because there is no style context instantiated yet. Instead,
instantiate a style context during realize() and ask it.
Fixes problems with dim labels not being dimmed on first show.
Testcase included.
https://bugzilla.gnome.org/show_bug.cgi?id=735240