We were having a problem where property actions were
not getting state updates because prop_actions_connect
was triggered from some instance_init function while
the widget class is not in place yet.
Delay that call until the widget is fully constructed,
so we can guarantee that we are dealing with the
correct class private struct, and see all class actions.
We already dropped this invariant in gtk_widget_verify_invariants()
because it was not true in all cases. Also, it is not really useful
these days as we extended what it means to be a "child" to also
include widgets in different toplevels.
For example, a popup in a popup button need not be realized just
because the button is in a realized window. The main invariants
we want are:
* Parent is realized before child
* Widget is realized before it is mapped
This sounds like its not a huge deal, but in fact it is a massive win
for things like menus, because when we go between menus in a menubar
each switch between two open menus involves a lot of intermingled
crossing events to different surfaces and for each of these the
tooltip window of the toplevel gets assigned to the new surface. This
shouldn't be a huge deal, as the tooltip window is not even visible,
but due to the realized invariant it get re-realized each time it gets
re-assigned.
This gives us a hook to walk the widget tree whenever a global
setting changes and do per-widget invalidations. This will
replace gtk_style_context_reset_widgets().
This was only living in gtkcontainer.c for historic
reasons. Move it closer to where it belongs, and
rename it from 'idle' to 'layout', since it is
really about the layout phase of the frame clock,
nowadays.
GdkEvent has been a "I-can't-believe-this-is-not-OOP" type for ages,
using a union of sub-types. This has always been problematic when it
comes to implementing accessor functions: either you get generic API
that takes a GdkEvent and uses a massive switch() to determine which
event types have the data you're looking for; or you create namespaced
accessors, but break language bindings horribly, as boxed types cannot
have derived types.
The recent conversion of GskRenderNode (which had similar issues) to
GTypeInstance, and the fact that GdkEvent is now a completely opaque
type, provide us with the chance of moving GdkEvent to GTypeInstance,
and have sub-types for GdkEvent.
The change from boxed type to GTypeInstance is pretty small, all things
considered, but ends up cascading to a larger commit, as we still have
backends and code in GTK trying to access GdkEvent structures directly.
Additionally, the naming of the public getter functions requires
renaming all the data structures to conform to the namespace/type-name
pattern.
Make widgets can-focus by default, and change the semantics
of can-focus to be recursive . If it is set to FALSE, focus
can not enter the widget or its descendents at all anymore.
This commit temporarily breaks focus behavior of widgets
that did not expect to receive focus.
The only place where this should be set is when making
a widget the focus-widget of a window. We still keep
the property around in readonly form, since there are
a few places where we rely on property notification
for it.
This property doesn't carry any new information compared
to GtkWindow:focus-widget. We still keep the gtk_widget_is_focus
getter, as a convenient shortcut.
People should use shortcut controllers instead (global, capture).
A side effect of this is that GtkAccelLabel now lost its method to
magically look up accelerators to display. Somebody needs to add that
back later.
When creating shortcuts, there almost always are a trigger and an action
available for use. So make gtk_shortcut_new() take those as arguments.
Also add gtk_shortcut_new_with_arguments() so people can easily pass
those in, too.
Similar to GtkShortcutTrigger, GtkShortCutAction provides all the
different ways to activate a shortcut.
So far, these different ways are supported:
- do nothing
- Call a user-provided callback
- Call gtk_widget_activate()
- Call gtk_widget_mnemonic_activate()
- Emit an action signal
- Activate an action from the widget's action muxer
It's an outdated technology now that everybody is using GActionGroups.
If somebody wanted to support changeable shortcuts, they'd need to
reintroduce it in another way.
This adds an interface for taking care of shortcut controllers with
managed scope.
Only GtkWindow currently implements this interface, so we need to ensure
that we check if any top-level widget we reach is a shortcuts manager
before we call into it.
Allow setting the scope for a controller. The scope determines at what
point in event propagation the shortcuts will be activated.
Local scope is the usual activation, global scope means that the root
widget activates the shortcuts - ie they are activated at the very
start of event propagation (for global capture events) or the very end
(for global bubble events).
Managed scope so far is unimplemented.
This is supposed to be used to replace accelerators and mnemonics.
This is a very barebones controller that currently does nothing but
activate the binding signals. Yay.
And because we have bindings on every widget (Yes, a GtkGrid has a
keybinding - 2 in fact), we need that controller everywhere.
We need to cleanup state here immediately so that we do not potentially
access the g_class private data after it been finalized. This ensures that
the borrowed reference is dropped by the muxer.
Before this commit, adding GtkWidgetAction to class private data would
require copying the actions to each subclass as they were built or
modified. This was convenient in that it is a sort of "copy on write"
semantic.
However, due to the way that GTypeInstance works with base _init()
functions, the "g_class" pointer in GTypeInstance is updated as each
_init() function is called. That means you cannot access the subclasses
class private data, but only the parent class private data.
If instead we use a singly linked list of GtkWidgetAction, each subclass
has their own "head" yet all subclasses share the tail of the
GtkWidgetAction chain.
This creates one bit of complexity though. You need a stable way to know
which "bit" is the "enabled" bit of the action so we can track enabled
GAction state. That is easily solved by calculating the distance to the
end of the chain for a given action so that base classes sort ahead of
subclasses. Since the parent class always knows its parent's actions, the
position is stable.
A new dynamic bitarray helper also helps us avoid allocations in all the
current cases (up to 64 actions per widget) and dynamically switches to
malloc if that is to ever be exceeded.
We want access to the private data from the action muxer so we can just
move the structures to the gtkwidgetprivate.h header. Alternatively we
could create accessors, but given that we'll probably need to use this
in other areas, seems reasonable to just put it there.