<?xml version="1.0"?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<refentry id="chap-input-handling">
<refmeta>
<refentrytitle>The GTK Input Model</refentrytitle>
<manvolnum>3</manvolnum>
<refmiscinfo>GTK Library</refmiscinfo>
</refmeta>

<refnamediv>
<refname>The GTK Input Model</refname>
<refpurpose>
    input and event handling in detail
</refpurpose>
</refnamediv>


  <refsect1 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>

  <refsect2>
    <title>Devices and events</title>

    <!-- input devices: master/slave, keyboard/pointer/touch -->
    <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 #GdkDevice object.
    </para>

    <para>
     To simplify dealing with the variability between these input devices, GTK
     has a concept of master and slave 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 slave devices. Each slave device is
     associated with a virtual master device. Master devices always come in
     pointer/keyboard pairs - you can think of such a pair as a 'seat'.
    </para>
    <para>
     GTK widgets generally deal with the master 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 #GdkEvents.
     Typical input events are button clicks, pointer motion, key presses
     or touch events. These are all represented as #GdkEvents, but you can
     differentiate between different events by looking at their type, using
     gdk_event_get_event_type().
    </para>
    <para>
      Some events, such as touch events or button press-release pairs,
      are connected in to each other in an “event sequence” that
      univocally identifies events that are related to the same
      interaction.
    </para>
    <para>
      When GTK creates a GdkSurface, it connects to the #GdkSurface::event
      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>
  </refsect2>

  <refsect2 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>
      <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>
        The event is sent to widgets.
      </para></listitem>
    </orderedlist>

    <para>
      An event is propagated down and up the widget hierarchy in three phases
      (see #GtkPropagationPhase) towards a target widget.
    </para>

    <informalfigure>
      <mediaobject>
        <imageobject>
          <imagedata fileref="capture-bubble.png" format="PNG"/>
        </imageobject>
      </mediaobject>
    </informalfigure>

    <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 gtk_window_get_focus()).
    </para>

    <para>
      For pointer events, the target widget is determined by picking
      the widget at the events coordinates (see gtk_window_pick()).
    </para>

    <para>In the first phase (the “capture” phase) the event is
      delivered to each widget from the top-most (the top-level
      #GtkWindow or grab widget) down to the target #GtkWidget.
      <link linkend="event-controllers-and-gestures">Event
      controllers</link> that are attached with %GTK_PHASE_CAPTURE
      get a chance to react to the event.
    </para>

    <para>
      After the “capture” phase, the widget that was intended to be the
      destination of the event will run event controllers attached to
      it with %GTK_PHASE_TARGET. This is known as the “target” phase,
      and only happens on that widget.
    </para>

    <para>
      In the last phase (the “bubble” phase), the event is delivered
      to each widget from the target to the top-most, and event
      controllers attached with %GTK_PHASE_BUBBLE 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 “gesture states” section
      below to learn more about gestures and sequences.
    </para>
  </refsect2>

  <refsect2>
    <title>Keyboard input</title>

    <para>
      Every #GtkWindow maintains a single focus location (in the
      #GtkWindow:focus-widget property). The focus widget is the target
      widget for key events sent to the window. Only widgets which have
      #GtkWidget:can-focus set to %TRUE 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
      “keyboard navigation”). 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 “directional navigation” with
      the arrow keys.
    </para>

    <para>
      Many widgets can be “activated” 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
      “shortcuts”. 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:
      <variablelist>
        <varlistentry>
          <term>Accelerators</term>
          <listitem><para>
            Accelerators are any other shortcuts that can be activated regardless
            of where the focus is, and typically trigger global actions, such as
            Ctrl-Q to quit an application.
          </para></listitem>
        </varlistentry>
        <varlistentry>
          <term>Mnmemonics</term>
          <listitem><para>
            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 #GtkPopoverMenu), mnemonics can be
            trigered without the modifier.
          </para></listitem>
        </varlistentry>
        <varlistentry>
          <term>Key bindings</term>
          <listitem><para>
            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></listitem>
        </varlistentry>
      </variablelist>
    </para>
    <para>
      GTK traditionally 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 #GtkShortcut,
      and they are managed by #GtkShortcutController.
    </para>
  </refsect2>

  <refsect2 id="event-controllers-and-gestures">
    <title>Event controllers and gestures</title>

    <para>
      Event controllers are standalone objects that can perform
      specific actions upon received #GdkEvents. These are tied
      to a #GtkWidget, 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 “simple” 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:

      <simplelist>
	<member>
	  A “drag” and a “swipe” 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.
	</member>
	<member>
	  Grouping a “drag” gesture with a “pan” gesture will only
          effectively allow dragging in the panning orientation, as
          both gestures share state.
	</member>
	<member>
	  If “press” and “long press” are wanted simultaneously,
          those would need grouping.
	</member>
      </simplelist>
    </para>

    <para>
      Shortcuts are handled by #GtkShortcutController, which is
      a complex event handler that can either activate shortcuts
      itself, or propagate them to another controller, depending
      on its #GtkShortcutController:scope.
    </para>
  </refsect2>

  <refsect2>
    <title>Gesture states</title>
    <para>
      Gestures have a notion of “state” for each individual touch
      sequence. When events from a touch sequence are first received,
      the touch sequence will have “none” 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 %GDK_TOUCH_BEGIN/%GDK_BUTTON_PRESS 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
      there 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>
  </refsect2>

  </refsect1>
</refentry>
