<chapter id="input-overview">
  <title>Overview of GTK input and event handling</title>
  <para>
    This chapter describes in detail how GTK handles input. If you are
    interested in what happens to translate a key press or mouse motion
    of the users into a change of a GTK widget, you should read this
    chapter. This knowledge will also be useful if you decide to
    implement your own widgets.
  </para>
  <sect1>
    <title>Devices and events</title>
    <para>
      The most basic input devices that every computer user has
      interacted with are keyboards and mice; beyond these, GTK supports
      touchpads, touchscreens and more exotic input devices such as
      graphics tablets. Inside GTK, every such input device is
      represented by a <link linkend="GdkDevice"><type>GdkDevice</type></link> object.
    </para>
    <para>
      To simplify dealing with the variability between these input
      devices, GTK has a concept of logical and physical devices. The
      concrete physical devices that have many different characteristics
      (mice may have 2 or 3 or 8 buttons, keyboards have different
      layouts and may or may not have a separate number block, etc) are
      represented as physical devices. Each physical device is
      associated with a virtual logical device. Logical devices always
      come in pointer/keyboard pairs - you can think of such a pair as a
      <quote>seat</quote>.
    </para>
    <para>
      GTK widgets generally deal with the logical devices, and thus can
      be used with any pointing device or keyboard.
    </para>
    <para>
      When a user interacts with an input device (e.g. moves a mouse or
      presses a key on the keyboard), GTK receives events from the
      windowing system. These are typically directed at a specific
      surface - for pointer events, the surface under the pointer (grabs
      complicate this), for keyboard events, the surface with the
      keyboard focus.
    </para>
    <para>
      GDK translates these raw windowing system events into <link linkend="GdkEvents"><type>GdkEvents</type></link>.
      Typical input events are button clicks, pointer motion, key
      presses or touch events. These are all represented as <link linkend="GdkEvents"><type>GdkEvents</type></link>,
      but you can differentiate between different events by looking at
      their type, using <link linkend="gdk-event-get-event-type"><function>gdk_event_get_event_type()</function></link>.
    </para>
    <para>
      Some events, such as touch events or button press-release pairs,
      are connected in to each other in an <quote>event sequence</quote>
      that univocally identifies events that are related to the same
      interaction.
    </para>
    <para>
      When GTK creates a GdkSurface, it connects to the
      <link linkend="GdkSurface-event"><type>“event”</type></link> signal on it, which receives all of these input
      events. Surfaces have have signals and properties, e.g. to deal
      with window management related events.
    </para>
  </sect1>
  <sect1 id="event-propagation">
    <title>Event propagation</title>
    <para>
      The function which initially receives input events on the GTK side
      is responsible for a number of tasks.
    </para>
    <orderedlist numeration="arabic" spacing="compact">
      <listitem>
        <para>
          Find the widget which got the event.
        </para>
      </listitem>
      <listitem>
        <para>
          Generate crossing (i.e. enter and leave) events when the focus
          or hover location change from one widget to another.
        </para>
      </listitem>
      <listitem>
        <para>
          Send the event to widgets.
        </para>
      </listitem>
    </orderedlist>
    <para>
      An event is propagated down and up the widget hierarchy in three
      phases (see <link linkend="GtkPropagationPhase"><type>GtkPropagationPhase</type></link>) towards a target widget.
    </para>
    <figure>
      <title>Event propagation phases</title>
      <mediaobject>
        <imageobject>
          <imagedata fileref="capture-bubble.png" />
        </imageobject>
        <textobject><phrase>Event propagation
        phases</phrase></textobject>
      </mediaobject>
    </figure>
    <para>
      For key events, the top-level window gets a first shot at
      activating mnemonics and accelerators. If that does not consume
      the events, the target widget for event propagation is window’s
      current focus widget (see <link linkend="gtk-window-get-focus"><function>gtk_window_get_focus()</function></link>).
    </para>
    <para>
      For pointer events, the target widget is determined by picking the
      widget at the events coordinates (see <link linkend="gtk-widget-pick"><function>gtk_widget_pick()</function></link>).
    </para>
    <para>
      In the first phase (the <quote>capture</quote> phase) the event is
      delivered to each widget from the top-most (the top-level
      <link linkend="GtkWindow"><type>GtkWindow</type></link> or grab widget) down to the target <link linkend="GtkWidget"><type>GtkWidget</type></link>.
      <ulink url="event-controllers-and-gestures">Event
      controllers</ulink> that are attached with <link linkend="GTK-PHASE-CAPTURE:CAPS"><literal>GTK_PHASE_CAPTURE</literal></link> get
      a chance to react to the event.
    </para>
    <para>
      After the <quote>capture</quote> phase, the widget that was
      intended to be the destination of the event will run event
      controllers attached to it with <link linkend="GTK-PHASE-TARGET:CAPS"><literal>GTK_PHASE_TARGET</literal></link>. This is known
      as the <quote>target</quote> phase, and only happens on that
      widget.
    </para>
    <para>
      In the last phase (the <quote>bubble</quote> phase), the event is
      delivered to each widget from the target to the top-most, and
      event controllers attached with <link linkend="GTK-PHASE-BUBBLE:CAPS"><literal>GTK_PHASE_BUBBLE</literal></link> are run.
    </para>
    <para>
      Events are not delivered to a widget which is insensitive or
      unmapped.
    </para>
    <para>
      Any time during the propagation phase, a controller may indicate
      that a received event was consumed and propagation should
      therefore be stopped. If gestures are used, this may happen when
      the gesture claims the event touch sequence (or the pointer
      events) for its own. See the <quote>gesture states</quote> section
      below to learn more about gestures and sequences.
    </para>
  </sect1>
  <sect1>
    <title>Keyboard input</title>
    <para>
      Every <link linkend="GtkWindow"><type>GtkWindow</type></link> maintains a single focus location (in the
      <link linkend="GtkWindow--focus-widget"><type>“focus-widget”</type></link> property). The focus widget is the target
      widget for key events sent to the window. Only widgets which have
      <link linkend="GtkWidget--can-focus"><type>“can-focus”</type></link> set to <link linkend="TRUE:CAPS"><literal>TRUE</literal></link> can become the focus. Typically
      these are input controls such as entries or text fields, but e.g.
      buttons can take the focus too.
    </para>
    <para>
      Input widgets can be given the focus by clicking on them, but
      focus can also be moved around with certain key events (this is
      known as <quote>keyboard navigation</quote>). GTK reserves the Tab
      key to move the focus to the next location, and Shift-Tab to move
      it back to the previous one. In addition many containers allow
      <quote>directional navigation</quote> with the arrow keys.
    </para>
    <para>
      Many widgets can be <quote>activated</quote> to trigger and
      action. E.g., you can activate a button or switch by clicking on
      them, but you can also activate them with the keyboard, by using
      the Enter or Space keys.
    </para>
    <para>
      Apart from keyboard navigation, activation and directly typing
      into entries or text views, GTK widgets can use key events for
      activating <quote>shortcuts</quote>. Shortcuts generally act as a
      quick way to move the focus around or to activate a widget that
      does not currently have the focus.
    </para>
    <para>
      GTK has traditionally supported different kinds of shortcuts:
    </para>
    <variablelist spacing="compact">
      <varlistentry>
        <term>
          Accelerators
        </term>
        <listitem>
          <para>
            Accelerators are any other shortcuts that can be activated
            regardless
          </para>
        </listitem>
      </varlistentry>
    </variablelist>
    <para>
      of where the focus is, and typically trigger global actions, such
      as Ctrl-Q to quit an application. Mnmemonics : Mnemonics are
      usually triggered using Alt as a modifier for a letter. They are
      used in places where a label is associated with a control, and are
      indicated by underlining the letter in the label. As a special
      case, inside menus (i.e. inside <link linkend="GtkPopoverMenu"><type>GtkPopoverMenu</type></link>), mnemonics can be
      triggered without the modifier. Key bindings : Key bindings are
      specific to individual widgets, such as Ctrl-C or Ctrl-V in an
      entry copy to or paste from the clipboard. They are only triggered
      when the widget has focus.
    </para>
    <para>
      GTK handles accelerators and mnemonics in a global scope, during
      the capture phase, and key bindings locally, during the target
      phase.
    </para>
    <para>
      Under the hood, all shortcuts are represented as instances of
      <link linkend="GtkShortcut"><type>GtkShortcut</type></link>, and they are managed by <link linkend="GtkShortcutController"><type>GtkShortcutController</type></link>.
    </para>
  </sect1>
  <sect1 id="event-controllers-and-gestures">
    <title>Event controllers and gestures</title>
    <para>
      Event controllers are standalone objects that can perform specific
      actions upon received <link linkend="GdkEvents"><type>GdkEvents</type></link>. These are tied to a <link linkend="GtkWidget"><type>GtkWidget</type></link>,
      and can be told of the event propagation phase at which they will
      manage the events.
    </para>
    <para>
      Gestures are a set of specific controllers that are prepared to
      handle pointer and/or touch events, each gesture implementation
      attempts to recognize specific actions out the received events,
      notifying of the state/progress accordingly to let the widget
      react to those. On multi-touch gestures, every interacting touch
      sequence will be tracked independently.
    </para>
    <para>
      Since gestures are <quote>simple</quote> units, it is not uncommon
      to tie several together to perform higher level actions, grouped
      gestures handle the same event sequences simultaneously, and those
      sequences share a same state across all grouped gestures. Some
      examples of grouping may be:
    </para>
    <itemizedlist spacing="compact">
      <listitem>
        <para>
          A <quote>drag</quote> and a <quote>swipe</quote> gestures may
          want grouping. The former will report events as the dragging
          happens, the latter will tell the swipe X/Y velocities only
          after recognition has finished.
        </para>
      </listitem>
      <listitem>
        <para>
          Grouping a <quote>drag</quote> gesture with a
          <quote>pan</quote> gesture will only effectively allow
          dragging in the panning orientation, as both gestures share
          state.
        </para>
      </listitem>
      <listitem>
        <para>
          If <quote>press</quote> and <quote>long press</quote> are
          wanted simultaneously, those would need grouping.
        </para>
      </listitem>
    </itemizedlist>
    <para>
      Shortcuts are handled by <link linkend="GtkShortcutController"><type>GtkShortcutController</type></link>, which is a
      complex event handler that can either activate shortcuts itself,
      or propagate them to another controller, depending on its
      <link linkend="GtkShortcutController--scope"><type>“scope”</type></link>.
    </para>
  </sect1>
  <sect1>
    <title>Gesture states</title>
    <para>
      Gestures have a notion of <quote>state</quote> for each individual
      touch sequence. When events from a touch sequence are first
      received, the touch sequence will have <quote>none</quote> state,
      this means the touch sequence is being handled by the gesture to
      possibly trigger actions, but the event propagation will not be
      stopped.
    </para>
    <para>
      When the gesture enters recognition, or at a later point in time,
      the widget may choose to claim the touch sequences (individually
      or as a group), hence stopping event propagation after the event
      is run through every gesture in that widget and propagation phase.
      Anytime this happens, the touch sequences are cancelled downwards
      the propagation chain, to let these know that no further events
      will be sent.
    </para>
    <para>
      Alternatively, or at a later point in time, the widget may choose
      to deny the touch sequences, thus letting those go through again
      in event propagation. When this happens in the capture phase, and
      if there are no other claiming gestures in the widget, a
      <link linkend="GDK-TOUCH-BEGIN:CAPS"><literal>GDK_TOUCH_BEGIN</literal></link>/<link linkend="GDK-BUTTON-PRESS:CAPS"><literal>GDK_BUTTON_PRESS</literal></link> event will be emulated and
      propagated downwards, in order to preserve consistency.
    </para>
    <para>
      Grouped gestures always share the same state for a given touch
      sequence, so setting the state on one does transfer the state to
      the others. They also are mutually exclusive, within a widget
      where may be only one gesture group claiming a given sequence. If
      another gesture group claims later that same sequence, the first
      group will deny the sequence:
    </para>
  </sect1>
</chapter>
