We are poking again into the event propagation machinery, which
expects events in toplevel coordinates. Since we can't fetch the
original event back at this point, translate the coordinates
back to the toplevel so the emulated press ends up in the right
place.
https://gitlab.gnome.org/GNOME/gtk/issues/1159Closes: #1159
Instead declare a priv local. We should do this even if we don't remove
the priv pointer from GtkWidget entirely, just to stay consistent with
new code we introduce.
We were mutating the list while iterating over it. This was not a
problem before since remove_controller just set the controller pointer
to NULL instead of actually removing it from the list of controllers.
We can avoid a signal connection per event controller (and the
EventControllerData struct) since every event controller knows the
widget it's attached to.
We no longer set the widget on construction, but instead require an
explicit call to gtk_widget_add_controller().
This way, the reference handling becomes explicit and bindable.
Because gtk_widget_add_controller() is (transfer: full), we don't
even need to unref the controller after adding it.
And we don't need to keep track of it, because controllers get cleaned
up by GtkWidget.
This is the first step towards refactoring how widgets deal with event
controllers.
In the future, the widget will treat controllers the same way it treats
child widgets:
1. The controllers will be created without a widget.
2. There will be gtk_widget_add/remove_controller() functions to add
or remove controllers.
3. The widget will hold a reference to all its controllers.
This way we will ultimately be able to automate controllers with ui
files.
Well, they don't require a redraw of the widget, because the widget
itself didn't change.
They require a redraw of the parent, because that now displays the
widget in a different position.
And this means we can keep the cache of the widget's render node.
My fishbowl numbers are through the roof^W water surface. Vulkan gets
4000 now.
Due to the few type checks in gtk_widget_get_display(), it was the
slowest part of a call to gtk_widget_query_size_for_orientation if the
in case of a cache hit.
If widgets want to clip things, they now need to do it themselves.
By not taking care of clip, we avoid the need to track clip. And by not
tracking clip, we can avoid all unnecessary cache invalidations that we
were doing for render nodes whenever the clip changed.
And when you are scrolling, the clip changes *a lot*.
Instead of connecting to / disconnecting from the frame clock, do it
inside the vfuncs next to changing the priv->realized boolean.
This removes a race between those 2 cases that could cause child
widgets' unrealize handlers to reconnect this widget to the frame clock
because it was still marked as realize when the widget had already
disconnected from the frame clock.
Fixes#168
But in turn, also allow it to work on widgets with their own surface.
This way, we can chain up from everywhere and won't have to export
gtk_widget_set_realized().