### ----------------------------------------------------
### -- Gnome::Gtk3
### -- Licenses: Artistic-2.0
### -- Authors: Marcel Timmerman
### -- File: lib/Gnome/Gtk3/Widget.rakumod
### ----------------------------------------------------
### -- Chunk 1 of 8
#TL:1:Gnome::Gtk3::Widget

use v6;
#-------------------------------------------------------------------------------
=begin pod

=head1 Gnome::Gtk3::Widget

Base class for all widgets

=head1 Description

B<Gnome::Gtk3::Widget> is the base class all widgets in this package derive from. It manages the widget lifecycle, states and style.

=head2 Height-for-width Geometry Management

GTK+ uses a height-for-width (and width-for-height) geometry management system. Height-for-width means that a widget can change how much vertical space it needs, depending on the amount of horizontal space that it is given (and similar for width-for-height). The most common example is a label that reflows to fill up the available width, wraps to fewer lines, and therefore needs less height.

Height-for-width geometry management is implemented in GTK+ by way of five virtual methods:

=item C<get_request_mode()>
=item C<get_preferred_width()>
=item C<get_preferred_height()>
=item C<get_preferred_height_for_width()>
=item C<get_preferred_width_for_height()>
=item C<get_preferred_height_and_baseline_for_width()>

There are some important things to keep in mind when implementing height-for-width and when using it in container implementations.

The geometry management system will query a widget hierarchy in only one orientation at a time. When widgets are initially queried for their minimum sizes it is generally done in two initial passes in the C<GtkSizeRequestMode> chosen by the toplevel.

For example, when queried in the normal C<GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH> mode:
=item First, the default minimum and natural width for each widget in the interface will be computed using C<gtk_widget_get_preferred_width()>. Because the preferred widths for each container depend on the preferre1d widths of their children, this information propagates up the hierarchy, and finally a minimum and natural width is determined for the entire toplevel.
=item Next, the toplevel will use the minimum width to query for the minimum height contextual to that width using C<gtk_widget_get_preferred_height_for_width()>, which will also be a highly recursive operation. The minimum height for the minimum width is normally used to set the minimum size constraint on the toplevel (unless C<gtk_window_set_geometry_hints()> is explicitly used instead).

After the toplevel window has initially requested its size in both dimensions it can go on to allocate itself a reasonable size (or a size previously specified with C<gtk_window_set_default_size()>). During the recursive allocation process it’s important to note that request cycles will be recursively executed while container widgets allocate their children. Each container widget, once allocated a size, will go on to first share the space in one orientation among its children and then request each child's height for its target allocated width or its width for allocated height, depending.

In this way a B<Gnome::Gtk3::Widget> will typically be requested its size a number of times before actually being allocated a size. The size a widget is finally allocated can of course differ from the size it has requested. For this reason, B<Gnome::Gtk3::Widget> caches a  small number of results to avoid re-querying for the same sizes in one allocation cycle.

See [Gnome::Gtk3::Container’s geometry management section](https://developer.gnome.org/gtk3/stable/GtkContainer.html) to learn more about how height-for-width allocations are performed by container widgets.

If a widget does move content around to intelligently use up the allocated size then it must support the request in both C<GtkSizeRequestMode>s even if the widget in question only trades sizes in a single orientation.

For instance, a B<Gnome::Gtk3::Label> that does height-for-width word wrapping will not expect to have C<get_preferred_height()> called because that call is specific to a width-for-height request. In this case the label must return the height required for its own minimum possible width. By following this rule any widget that handles height-for-width or width-for-height requests will always be allocated at least enough space to fit its own content.

=begin comment
Here are some examples of how a C<GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH> widget generally deals with width-for-height requests, for C<get_preferred_height()> it will do (A piece of C-code directly from the docs):

  static void foo_widget_get_preferred_height (
    GtkWidget *widget, gint *min_height, gint *nat_height
  ) {
    if (i_am_in_height_for_width_mode) {
      gint min_width, nat_width;

      GTK_WIDGET_GET_CLASS (widget)->get_preferred_width(
        widget, &min_width, &nat_width
      );

      GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width(
        widget, min_width, min_height, nat_height
      );
    }

    else {
      … some widgets do both. For instance, if a GtkLabel is
      rotated to 90 degrees it will return the minimum and
      natural height for the rotated label here.
    }
  }

And in C<get_preferred_width_for_height()> it will simply return
the minimum and natural width:

  static void foo_widget_get_preferred_width_for_height(
    GtkWidget *widget, gint for_height, gint *min_width,
    gint *nat_width
  ) {
    if (i_am_in_height_for_width_mode) {
      GTK_WIDGET_GET_CLASS (widget)->get_preferred_width(
        widget, min_width, nat_width
      );
    }

    else {
      … again if a widget is sometimes operating in
      width-for-height mode (like a rotated GtkLabel) it can go
      ahead and do its real width for height calculation here.
    }
  }
=end comment

=begin comment
Often a widget needs to get its own request during size request or allocation. For example, when computing height it may need to also compute width. Or when deciding how to use an allocation, the widget may need to know its natural size. In these cases, the widget should be careful to call its virtual methods directly, like this:

  GTK_WIDGET_GET_CLASS(widget)->get_preferred_width(
    widget, &min, &natural
  );

It will not work to use the wrapper functions, such as C<gtk_widget_get_preferred_width()> inside your own size request implementation. These return a request adjusted by B<Gnome::Gtk3::SizeGroup> and by the C<adjust_size_request()> virtual method. If a widget used the wrappers inside its virtual method implementations, then the adjustments (such as widget margins) would be applied twice. GTK+ therefore does not allow this and will warn if you try to do it.

Of course if you are getting the size request for another widget, such as a child of a container, you must use the wrapper APIs. Otherwise, you would not properly consider widget margins, B<Gnome::Gtk3::SizeGroup>, and so forth.

=end comment

Since 3.10 GTK+ also supports baseline vertical alignment of widgets. This means that widgets are positioned such that the typographical baseline of widgets in the same row are aligned. This happens if a widget supports baselines, has a vertical alignment of C<GTK_ALIGN_BASELINE>, and is inside a container that supports baselines and has a natural “row” that it aligns to the baseline, or a baseline assigned to it by the grandparent.

Baseline alignment support for a widget is done by the C<get_preferred_height_and_baseline_for_width()> virtual function. It allows you to report a baseline in combination with the minimum and natural height. If there is no baseline you can return -1 to indicate this. The default implementation of this virtual function calls into the C<get_preferred_height()> and C<get_preferred_height_for_width()>, so if baselines are not supported it doesn’t need to be implemented.

If a widget ends up baseline aligned it will be allocated all the space in the parent as if it was C<GTK_ALIGN_FILL>, but the selected baseline can be found via C<gtk_widget_get_allocated_baseline()>. If this has a value other than -1 you need to align the widget such that the baseline appears at the position.

=head2 Style Properties

B<Gnome::Gtk3::Widget> introduces “style properties” - these are basically object properties that are stored not on the object, but in the style object associated to the widget. Style properties are set in gtk resource files. This mechanism is used for configuring such things as the location of the scrollbar arrows through the theme, giving theme authors more control over the look of applications without the need to write a theme engine in C.

Use C<gtk_widget_class_install_style_property()> to install style properties for a widget class, C<gtk_widget_class_find_style_property()> or C<gtk_widget_class_list_style_properties()> to get information about existing style properties and C<gtk_widget_style_get_property()>, C<gtk_widget_style_get()> or C<gtk_widget_style_get_valist()> to obtain the value of a style property.

=head2 Gnome::Gtk3::Widget as Gnome::Gtk3::Buildable

The B<Gnome::Gtk3::Widget> implementation of the B<Gnome::Gtk3::Buildable> interface supports a custom <accelerator> element, which has attributes named ”key”, ”modifiers” and ”signal” and allows to specify accelerators.

An example of a UI definition fragment specifying an accelerator (please note that in this XML the C-Source widget class names must be used; GtkButton instead of Gnome::Gtk3::Button):

  <object class="GtkButton">
    <accelerator key="q" modifiers="GDK_CONTROL_MASK" signal="clicked"/>
  </object>

In addition to accelerators, B<Gnome::Gtk3::Widget> also support a custom <accessible> element, which supports actions and relations. Properties on the accessible implementation of an object can be set by accessing the internal child “accessible” of a B<Gnome::Gtk3::Widget>.

An example of a UI definition fragment specifying an accessible:

  <object class="GtkButton" id="label1"/>
    <property name="label">I am a Label for a Button</property>
  </object>
  <object class="GtkButton" id="button1">
    <accessibility>
      <action action_name="click" translatable="yes">
        Click the button.
      </action>
      <relation target="label1" type="labelled-by"/>
    </accessibility>
    <child internal-child="accessible">
      <object class="AtkObject" id="a11y-button1">
        <property name="accessible-name">
          Clickable Button
        </property>
      </object>
    </child>
  </object>

Finally, B<Gnome::Gtk3::Widget> allows style information such as style classes to be associated with widgets, using the custom <style> element:

  <object class="GtkButton>" id="button1">
    <style>
      <class name="my-special-button-class"/>
      <class name="dark-button"/>
    </style>
  </object>

=begin comment
=head2 Building composite widgets from template XML

B<Gnome::Gtk3::Widget> exposes some facilities to automate the procedure of creating composite widgets using B<Gnome::Gtk3::Builder> interface description language.

To create composite widgets with B<Gnome::Gtk3::Builder> XML, one must associate
the interface description with the widget class at class initialization
time using C<gtk_widget_class_set_template()>.

The interface description semantics expected in composite template descriptions
is slightly different from regular B<Gnome::Gtk3::Builder> XML.

Unlike regular interface descriptions, C<gtk_widget_class_set_template()> will expect a <template> tag as a direct child of the toplevel <interface> tag. The <template> tag must specify the “class” attribute which must be the type name of the widget. Optionally, the “parent” attribute may be specified to specify the direct parent type of the widget type, this is ignored by the B<Gnome::Gtk3::Builder> but required for Glade to introspect what kind of properties and internal children exist for a given type when the actual type does not exist.

The XML which is contained inside the <template> tag behaves as if it were added to the <object> tag defining I<widget> itself. You may set properties on I<widget> by inserting <property> tags into the <template> tag, and also add <child> tags to add children and extend I<widget> in the normal way you would with <object> tags.

Additionally, <object> tags can also be added before and after the initial <template> tag in the normal way, allowing one to define auxiliary objects which might be referenced by other widgets declared as children of the <template> tag.

An example of a B<Gnome::Gtk3::Builder> Template Definition:

  <interface>
    <template class="FooWidget" parent="GtkBox">
      <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
      <property name="spacing">4</property>
      <child>
        <object class="GtkButton" id="hello_button">
          <property name="label">Hello World</property>
          <signal name="clicked" handler="hello_button_clicked" object="FooWidget" swapped="yes"/>
        </object>
      </child>
      <child>
        <object class="GtkButton" id="goodbye_button">
          <property name="label">Goodbye World</property>
        </object>
      </child>
    </template>
  </interface>

Typically, you'll place the template fragment into a file that is bundled with your project, using C<GResource>. In order to load the template, you need to call C<gtk_widget_class_set_template_from_resource()> from the class initialization of your B<Gnome::Gtk3::Widget> type:

=comment TODO replace with Raku code

  static void foo_widget_class_init (FooWidgetClass *klass) {
    // …

    gtk_widget_class_set_template_from_resource (
      GTK_WIDGET_CLASS (klass), "/com/example/ui/foowidget.ui"
    );
  }

You will also need to call C<gtk_widget_init_template()> from the instance
initialization function:

=comment TODO replace with Raku code

  static void foo_widget_init (FooWidget *self) {
    // …
    gtk_widget_init_template (GTK_WIDGET (self));
  }

You can access widgets defined in the template using the C<gtk_widget_get_template_child()> function, but you will typically declare a pointer in the instance private data structure of your type using the same name as the widget in the template definition, and call C<gtk_widget_class_bind_template_child_private()> with that name, e.g.

  typedef struct {
    B<Gnome::Gtk3::Widget> *hello_button;
    B<Gnome::Gtk3::Widget> *goodbye_button;
  } FooWidgetPrivate;

  G_DEFINE_TYPE_WITH_PRIVATE (FooWidget, foo_widget, GTK_TYPE_BOX)

  static void foo_widget_class_init (FooWidgetClass *klass) {
    // …
    gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
                                                 "/com/example/ui/foowidget.ui");
    gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass),
                                                  FooWidget, hello_button);
    gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass),
                                                  FooWidget, goodbye_button);
  }

You can also use C<gtk_widget_class_bind_template_callback()> to connect a signal callback defined in the template with a function visible in the scope of the class, e.g.

  // the signal handler has the instance and user data swapped
  // because of the swapped="yes" attribute in the template XML
  static void hello_button_clicked (FooWidget *self, GtkButton *button) {
    g_print ("Hello, world!\n");
  }

  static void
  foo_widget_class_init (FooWidgetClass *klass)
  {
    // …
    gtk_widget_class_set_template_from_resource (
      GTK_WIDGET_CLASS (klass), "/com/example/ui/foowidget.ui"
    );
    gtk_widget_class_bind_template_callback (
      GTK_WIDGET_CLASS (klass), hello_button_clicked
    );
  }

=end comment


=head1 Synopsis
=head2 Declaration

  unit class Gnome::Gtk3::Widget;
  also is Gnome::GObject::InitiallyUnowned;
  also does Gnome::Gtk3::Buildable;


=head2 Uml Diagram

![](plantuml/Widget.svg)


=head2 Example

  # create a button and set a tooltip
  my Gnome::Gtk3::Button $start-button .= new(:label<Start>);
  $start-button.set-tooltip-text('Nooooo don\'t touch that button!!!!!!!');

=end pod
#-------------------------------------------------------------------------------
use NativeCall;

use Gnome::N::NativeLib:api<1>;
use Gnome::N::N-GObject:api<1>;
use Gnome::N::GlibToRakuTypes:api<1>;

use Gnome::GObject::InitiallyUnowned:api<1>;
use Gnome::GObject::Type:api<1>;

use Gnome::Glib::List:api<1>;

use Gnome::Gdk3::Device:api<1>;
use Gnome::Gdk3::Display:api<1>;
use Gnome::Gdk3::Types:api<1>;
use Gnome::Gdk3::Events:api<1>;
use Gnome::Gdk3::Screen:api<1>;
use Gnome::Gdk3::Visual:api<1>;

use Gnome::Gtk3::Enums:api<1>;
use Gnome::Gtk3::Buildable:api<1>;
use Gnome::Gtk3::WidgetPath:api<1>;

use Gnome::Cairo;
use Gnome::Cairo::Enums:api<1>;
use Gnome::Cairo::Types:api<1>;
#use Gnome::Cairo::FontOptions:api<1>;

#-------------------------------------------------------------------------------
# /usr/include/gtk-3.0/gtk/gtkwidget.h
# https://developer.gnome.org/gtk3/stable/GtkWidget.html
unit class Gnome::Gtk3::Widget:auth<github:MARTIMM>:api<1>;
also is Gnome::GObject::InitiallyUnowned;
also does Gnome::Gtk3::Buildable;

#-------------------------------------------------------------------------------
=begin pod
=head1 Types
=end pod
#-------------------------------------------------------------------------------
=begin pod
=head2 enum GtkWidgetHelpType

Kinds of widget-specific help. Used by the ::show-help signal.

=item GTK_WIDGET_HELP_TOOLTIP: Tooltip.
=item GTK_WIDGET_HELP_WHATS_THIS: What’s this.

=end pod

#TE:0:GtkWidgetHelpType:
enum GtkWidgetHelpType is export (
  'GTK_WIDGET_HELP_TOOLTIP',
  'GTK_WIDGET_HELP_WHATS_THIS'
);

#-------------------------------------------------------------------------------
#TODO refactor into Boxed type class
=begin pod
=head2 class N-GtkRequisition

A B<Gnome::Gtk3::Requisition>-struct represents the desired size of a widget. See [B<Gnome::Gtk3::Widget>’s geometry management section][geometry-management] for more information.

=item Int $.width: the widget’s desired width
=item Int $.height: the widget’s desired height

=end pod

#TT:1:N-GtkRequisition:
class N-GtkRequisition is export is repr('CStruct') {
  has int32 $.width;
  has int32 $.height;
}

#-------------------------------------------------------------------------------
=begin pod
=head2 class N-GtkAllocation

A N-GtkAllocation of a widget represents a region which has been allocated to the widget by its parent. It is a subregion of its parents allocation. See GtkWidget’s geometry management section for more information.

=item Int $.x;
=item Int $.y;
=item Int $.width;
=item Int $.height;

=end pod

# use of this statement works but will show the N-GdkRectangle type, not
# the N-GtkAllocation type, so we define like the rectangle
#my constant N-GtkAllocation is export = N-GdkRectangle;

#TT:1:N-GtkAllocation:
class N-GtkAllocation is export is repr('CStruct') {
  has int32 $.x;
  has int32 $.y;
  has int32 $.width;
  has int32 $.height;

  submethod TWEAK ( :$!x = 0, :$!y = 0, :$!width = 1, :$!height = 1 ) { }
}

#-------------------------------------------------------------------------------
my Bool $signals-added = False;
#-------------------------------------------------------------------------------
=begin pod
=head1 Methods
=end pod

submethod BUILD ( *%options ) {

  # add signal info in the form of group<signal-name>.
  # groups are e.g. signal, event, nativeobject etc
  $signals-added = self.add-signal-types( $?CLASS.^name,
    :w0<accel-closures-changed destroy show hide map unmap realize unrealize style-updated grab-focus popup-menu>,

    :w1<delete-event show-help size-allocate state-flags-changed parent-set hierarchy-changed direction-changed grab-notify child-notify draw mnemonic-activate focus move-focus keynav-failed event event-after button-press-event button-release-event scroll-event motion-notify-event destroy-event key-press-event key-release-event enter-notify-event leave-notify-event configure-event focus-in-event focus-out-event map-event unmap-event property-notify-event selection-clear-event selection-request-event selection-notify-event proximity-out-event drag-end drag-data-delete drag-begin window-state-event damage-event grab-broken-event can-activate-accel screen-changed can-activate-accel touch-event>,

    :w2<drag-leave selection-received drag-failed>,
    :w3<selection-get proximity-in-event>,
    :w4<drag-drop drag-data-get drag-motion query-tooltip>,
    :w6<drag-data-received>
  ) unless $signals-added;

  # prevent creating wrong native-objects
#  return unless self.^name eq 'Gnome::Gtk3::Widget';

  # only after creating the native-object, the gtype is known
  self._set-class-info('GtkWidget');
}

#-------------------------------------------------------------------------------
# no pod. user does not have to know about it.
method _fallback ( $native-sub is copy --> Callable ) {

  my Callable $s;
  try { $s = &::("gtk_widget_$native-sub"); };
  try { $s = &::("gtk_$native-sub"); } unless ?$s;
  try { $s = &::($native-sub); } if !$s and $native-sub ~~ m/^ 'gtk_' /;
  try { $s = self._buildable_interface($native-sub); } unless ?$s;

  self._set-class-name-of-sub('GtkWidget');
  $s = callsame unless ?$s;

  $s;
}

#-------------------------------------------------------------------------------
#TM:1:activate:
=begin pod
=head2 activate

For widgets that can be “activated” (buttons, menu items, etc.) this function activates them. Activation is what happens when you press Enter on a widget during key navigation. If I<widget> isn't activatable, the function returns C<False>.

Returns: C<True> if the widget was activatable

  method activate ( --> Bool )

=end pod

method activate ( --> Bool ) {
  gtk_widget_activate(self._f('GtkWidget')).Bool
}

sub gtk_widget_activate (
  N-GObject $widget --> gboolean
) is native(&gtk-lib)
  { * }

#`{{
#-------------------------------------------------------------------------------
#TM:0:add-accelerator:
=begin pod
=head2 add-accelerator

Installs an accelerator for this I<widget> in I<accel-group> that causes I<accel-signal> to be emitted if the accelerator is activated. The I<accel-group> needs to be added to the widget’s toplevel via C<gtk-window-add-accel-group()>, and the signal must be of type C<G-SIGNAL-ACTION>. Accelerators added through this function are not user changeable during runtime. If you want to support accelerators that can be changed by the user, use C<gtk-accel-map-add-entry()> and C<set-accel-path()> or C<gtk-menu-item-set-accel-path()> instead.

  method add-accelerator ( Str $accel_signal, N-GObject $accel_group, UInt $accel_key, GdkModifierType $accel_mods, GtkAccelFlags $accel_flags )

=item Str $accel_signal; widget signal to emit on accelerator activation
=item N-GObject $accel_group; accel group for this widget, added to its toplevel
=item UInt $accel_key; GDK keyval of the accelerator
=item GdkModifierType $accel_mods; modifier key combination of the accelerator
=item GtkAccelFlags $accel_flags; flag accelerators, e.g. C<GTK-ACCEL-VISIBLE>

=end pod

method add-accelerator ( Str $accel_signal, $accel_group is copy, UInt $accel_key, GdkModifierType $accel_mods, GtkAccelFlags $accel_flags ) {
  $accel_group .= _get-native-object-no-reffing unless $accel_group ~~ N-GObject;

  gtk_widget_add_accelerator(
    self._f('GtkWidget'), $accel_signal, $accel_group, $accel_key, $accel_mods, $accel_flags
  );
}

sub gtk_widget_add_accelerator (
  N-GObject $widget, gchar-ptr $accel_signal, N-GObject $accel_group, guint $accel_key, GEnum $accel_mods, GtkAccelFlags $accel_flags
) is native(&gtk-lib)
  { * }
}}

#-------------------------------------------------------------------------------
#TM:0:add-device-events:
=begin pod
=head2 add-device-events

Adds the device events in the bitfield I<events> to the event mask for I<widget>. See C<set-device-events()> for details.

  method add-device-events ( N-GObject $device, Int $events )

=item N-GObject $device; a B<Gnome::Gdk3::Device>
=item Int $events; an event mask. Mask bit values are from GdkEventMask.

=end pod

method add-device-events ( $device is copy, Int $events ) {
  $device .= _get-native-object-no-reffing unless $device ~~ N-GObject;

  gtk_widget_add_device_events(
    self._f('GtkWidget'), $device, $events
  );
}

sub gtk_widget_add_device_events (
  N-GObject $widget, N-GObject $device, GEnum $events
) is native(&gtk-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:1:add-events:
=begin pod
=head2 add-events

Adds the events in the bitfield I<$events> to the event mask for I<widget>. See C<set-events()> and the L<input handling overview|https://developer.gnome.org/gtk3/stable/chap-input-handling.html#event-masks> for details.

  method add-events ( Int $events )

=item Int $events; an event mask, see GdkEventMask in B<Gnome::Gdk3::Types>.

=end pod

method add-events ( Int $events ) {
  gtk_widget_add_events( self._f('GtkWidget'), $events);
}

sub gtk_widget_add_events (
  N-GObject $widget, gint $events
) is native(&gtk-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:1:add-mnemonic-label:
=begin pod
=head2 add-mnemonic-label

Adds a widget to the list of mnemonic labels for this widget. (See C<list-mnemonic-labels()>). Note the list of mnemonic labels for the widget is cleared when the widget is destroyed, so the caller must make sure to update its internal state at this point as well, by using a connection to the  I<destroy> signal or a weak notifier.

  method add-mnemonic-label ( N-GObject $label )

=item N-GObject $label; a B<Gnome::Gtk3::Widget> that acts as a mnemonic label for I<widget>

=end pod

method add-mnemonic-label ( $label is copy ) {
  $label .= _get-native-object-no-reffing unless $label ~~ N-GObject;
  gtk_widget_add_mnemonic_label(self._f('GtkWidget'), $label);
}

sub gtk_widget_add_mnemonic_label (
  N-GObject $widget, N-GObject $label
) is native(&gtk-lib)
  { * }

#`{{
#-------------------------------------------------------------------------------
#TM:0:add-tick-callback:
=begin pod
=head2 add-tick-callback

Queues an animation frame update and adds a callback to be called before each frame. Until the tick callback is removed, it will be called frequently (usually at the frame rate of the output device or as quickly as the application can be repainted, whichever is slower). For this reason, is most suitable for handling graphics that change every frame or every few frames. The tick callback does not automatically imply a relayout or repaint. If you want a repaint or relayout, and aren’t changing widget properties that would trigger that (for example, changing the text of a B<Gnome::Gtk3::Label>), then you will have to call C<queue-resize()> or C<queue-draw-area()> yourself.

C<gdk-frame-clock-get-frame-time()> should generally be used for timing continuous animations and C<gdk-frame-timings-get-predicted-presentation-time()> if you are trying to display isolated frames at particular times.

This is a more convenient alternative to connecting directly to the  I<update> signal of B<Gnome::Gdk3::FrameClock>, since you don't have to worry about when a B<Gnome::Gdk3::FrameClock> is assigned to a widget.

Returns: an id for the connection of this callback. Remove the callback by passing it to C<remove-tick-callback()>

  method add-tick-callback ( GtkTickCallback $callback, Pointer $user_data, GDestroyNotify $notify --> UInt )

=item GtkTickCallback $callback; function to call for updating animations
=item Pointer $user_data; data to pass to I<callback>
=item GDestroyNotify $notify; function to call to free I<user-data> when the callback is removed.

=end pod

method add-tick-callback (
  Any:D $handler-obj, $method, *%options, GDestroyNotify $notify
  --> UInt
) {
  gtk_widget_add_tick_callback(
    self._f('GtkWidget'),
    , $user_data, $notify
  )
}

sub gtk_widget_add_tick_callback (
  N-GObject $widget, GtkTickCallback $callback, gpointer $user_data, GDestroyNotify $notify --> guint
) is native(&gtk-lib)
  { * }
}}

#-------------------------------------------------------------------------------
#TM:1:can-activate-accel:
=begin pod
=head2 can-activate-accel

Determines whether an accelerator that activates the signal identified by I<signal-id> can currently be activated. This is done by emitting the  I<can-activate-accel> signal on I<widget>; if the signal isn’t overridden by a handler or in a derived widget, then the default check is that the widget must be sensitive, and the widget and all its ancestors mapped.

Returns: C<True> if the accelerator can be activated.

  method can-activate-accel ( UInt $signal_id --> Bool )

=item UInt $signal_id; the ID of a signal installed on I<widget>

=end pod

method can-activate-accel ( UInt $signal_id --> Bool ) {

  gtk_widget_can_activate_accel(
    self._f('GtkWidget'), $signal_id
  ).Bool
}

sub gtk_widget_can_activate_accel (
  N-GObject $widget, guint $signal_id --> gboolean
) is native(&gtk-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:child-focus:
=begin pod
=head2 child-focus

This function is used by custom widget implementations; if you're writing an app, you’d use C<grab-focus()> to move the focus to a particular widget, and C<gtk-container-set-focus-chain()> to change the focus tab order. So you may want to investigate those functions instead.

C<child-focus()> is called by containers as the user moves around the window using keyboard shortcuts. I<direction> indicates what kind of motion is taking place (up, down, left, right, tab forward, tab backward). C<child-focus()> emits the  I<focus> signal; widgets override the default handler for this signal in order to implement appropriate focus behavior.

The default I<focus> handler for a widget should return C<True> if moving in I<direction> left the focus on a focusable location inside that widget, and C<False> if moving in I<direction> moved the focus outside the widget. If returning C<True>, widgets normally call C<grab-focus()> to place the focus accordingly; if returning C<False>, they don’t modify the current focus location.

Returns: C<True> if focus ended up inside I<widget>

  method child-focus ( GtkDirectionType $direction --> Bool )

=item GtkDirectionType $direction; direction of focus movement

=end pod

method child-focus ( GtkDirectionType $direction --> Bool ) {

  gtk_widget_child_focus(
    self._f('GtkWidget'), $direction
  ).Bool
}

sub gtk_widget_child_focus (
  N-GObject $widget, GEnum $direction --> gboolean
) is native(&gtk-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:child-notify:
=begin pod
=head2 child-notify

Emits a  I<child-notify> signal for the [child property][child-properties] I<child-property> on I<widget>.

This is the analogue of C<g-object-notify()> for child properties.

Also see C<gtk-container-child-notify()>.

  method child-notify ( Str $child_property )

=item Str $child_property; the name of a child property installed on the class of I<widget>’s parent

=end pod

method child-notify ( Str $child_property ) {

  gtk_widget_child_notify(
    self._f('GtkWidget'), $child_property
  );
}

sub gtk_widget_child_notify (
  N-GObject $widget, gchar-ptr $child_property
) is native(&gtk-lib)
  { * }

#`{{
#-------------------------------------------------------------------------------
#TM:0:class-bind-template-callback-full:
=begin pod
=head2 class-bind-template-callback-full

Declares a I<callback-symbol> to handle I<callback-name> from the template XML defined for I<widget-type>. See C<gtk-builder-add-callback-symbol()>.

Note that this must be called from a composite widget classes class initializer after calling C<class-set-template()>.

  method class-bind-template-callback-full ( GtkWidgetClass $widget_class, Str $callback_name, GCallback $callback_symbol )

=item GtkWidgetClass $widget_class; A B<Gnome::Gtk3::WidgetClass>
=item Str $callback_name; The name of the callback as expected in the template XML
=item GCallback $callback_symbol; (scope async): The callback symbol

=end pod

method class-bind-template-callback-full ( GtkWidgetClass $widget_class, Str $callback_name, GCallback $callback_symbol ) {

  gtk_widget_class_bind_template_callback_full(
    self._f('GtkWidget'), $widget_class, $callback_name, $callback_symbol
  );
}

sub gtk_widget_class_bind_template_callback_full (
  GtkWidgetClass $widget_class, gchar-ptr $callback_name, GCallback $callback_symbol
) is native(&gtk-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:0:class-bind-template-child-full:
=begin pod
=head2 class-bind-template-child-full

Automatically assign an object declared in the class template XML to be set to a location on a freshly built instance’s private data, or alternatively accessible via C<get-template-child()>.

The struct can point either into the public instance, then you should use G-STRUCT-OFFSET(WidgetType, member) for I<struct-offset>, or in the private struct, then you should use G-PRIVATE-OFFSET(WidgetType, member).

An explicit strong reference will be held automatically for the duration of your instance’s life cycle, it will be released automatically when B<Gnome::Gtk3::ObjectClass>.C<dispose()> runs on your instance and if a I<struct-offset> that is != 0 is specified, then the automatic location in your instance public or private data will be set to C<undefined>. You can however access an automated child pointer the first time your classes B<Gnome::Gtk3::ObjectClass>.C<dispose()> runs, or alternatively in B<Gnome::Gtk3::WidgetClass>.C<destroy()>.

If I<internal-child> is specified, B<Gnome::Gtk3::BuildableIface>.C<get-internal-child()> will be automatically implemented by the B<Gnome::Gtk3::Widget> class so there is no need to implement it manually.

The wrapper macros C<class-bind-template-child()>, C<class-bind-template-child-internal()>, C<class-bind-template-child-private()> and C<class-bind-template-child-internal-private()> might be more convenient to use.

Note that this must be called from a composite widget classes class initializer after calling C<class-set-template()>.

  method class-bind-template-child-full ( GtkWidgetClass $widget_class, Str $name, Bool $internal_child, Int $struct_offset )

=item GtkWidgetClass $widget_class; A B<Gnome::Gtk3::WidgetClass>
=item Str $name; The “id” of the child defined in the template XML
=item Bool $internal_child; Whether the child should be accessible as an “internal-child” when this class is used in GtkBuilder XML
=item Int $struct_offset; The structure offset into the composite widget’s instance public or private structure where the automated child pointer should be set, or 0 to not assign the pointer.

=end pod

method class-bind-template-child-full ( GtkWidgetClass $widget_class, Str $name, Bool $internal_child, Int $struct_offset ) {

  gtk_widget_class_bind_template_child_full(
    self._f('GtkWidget'), $widget_class, $name, $internal_child, $struct_offset
  );
}

sub gtk_widget_class_bind_template_child_full (
  GtkWidgetClass $widget_class, gchar-ptr $name, gboolean $internal_child, gssize $struct_offset
) is native(&gtk-lib)
  { * }


#-------------------------------------------------------------------------------
#TM:0:class-find-style-property:
=begin pod
=head2 class-find-style-property

Finds a style property of a widget class by name.

Returns: the B<Gnome::Gtk3::ParamSpec> of the style