2014-05-20 14:10:31 +00:00
|
|
|
|
<?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>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
<refentrytitle>The GTK Input Model</refentrytitle>
|
2014-05-20 14:10:31 +00:00
|
|
|
|
<manvolnum>3</manvolnum>
|
|
|
|
|
<refmiscinfo>GTK Library</refmiscinfo>
|
|
|
|
|
</refmeta>
|
|
|
|
|
|
|
|
|
|
<refnamediv>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
<refname>The GTK Input Model</refname>
|
2014-05-20 14:10:31 +00:00
|
|
|
|
<refpurpose>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
input and event handling in detail
|
2014-05-20 14:10:31 +00:00
|
|
|
|
</refpurpose>
|
|
|
|
|
</refnamediv>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<refsect1 id="input-overview">
|
2019-02-05 09:14:31 +00:00
|
|
|
|
<title>Overview of GTK input and event handling</title>
|
2014-05-20 14:10:31 +00:00
|
|
|
|
|
2014-05-22 19:16:09 +00:00
|
|
|
|
<para>
|
2019-02-05 09:14:31 +00:00
|
|
|
|
This chapter describes in detail how GTK handles input. If you are interested
|
2014-05-22 19:16:09 +00:00
|
|
|
|
in what happens to translate a key press or mouse motion of the users into a
|
2019-02-05 09:14:31 +00:00
|
|
|
|
change of a GTK widget, you should read this chapter. This knowledge will also
|
2014-05-22 19:16:09 +00:00
|
|
|
|
be useful if you decide to implement your own widgets.
|
|
|
|
|
</para>
|
|
|
|
|
|
2014-05-20 14:10:31 +00:00
|
|
|
|
<refsect2>
|
|
|
|
|
<title>Devices and events</title>
|
|
|
|
|
|
|
|
|
|
<!-- input devices: master/slave, keyboard/pointer/touch -->
|
2014-05-22 19:16:09 +00:00
|
|
|
|
<para>
|
|
|
|
|
The most basic input devices that every computer user has interacted with are
|
2019-02-05 09:14:31 +00:00
|
|
|
|
keyboards and mice; beyond these, GTK supports touchpads, touchscreens and
|
|
|
|
|
more exotic input devices such as graphics tablets. Inside GTK, every such
|
2014-05-22 19:16:09 +00:00
|
|
|
|
input device is represented by a #GdkDevice object.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-02-05 09:14:31 +00:00
|
|
|
|
To simplify dealing with the variability between these input devices, GTK
|
2014-05-22 19:16:09 +00:00
|
|
|
|
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>
|
2019-02-05 09:14:31 +00:00
|
|
|
|
GTK widgets generally deal with the master devices, and thus can be used
|
2014-05-22 19:16:09 +00:00
|
|
|
|
with any pointing device or keyboard.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
When a user interacts with an input device (e.g. moves a mouse or presses
|
2019-02-05 09:14:31 +00:00
|
|
|
|
a key on the keyboard), GTK receives events from the windowing system.
|
2019-05-03 04:22:07 +00:00
|
|
|
|
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.
|
2014-05-22 19:16:09 +00:00
|
|
|
|
</para>
|
|
|
|
|
<para>
|
2014-05-22 19:45:31 +00:00
|
|
|
|
GDK translates these raw windowing system events into #GdkEvents.
|
|
|
|
|
Typical input events are:
|
|
|
|
|
<simplelist>
|
2015-02-18 11:33:36 +00:00
|
|
|
|
<member>#GdkEventButton</member>
|
|
|
|
|
<member>#GdkEventMotion</member>
|
|
|
|
|
<member>#GdkEventCrossing</member>
|
|
|
|
|
<member>#GdkEventKey</member>
|
|
|
|
|
<member>#GdkEventFocus</member>
|
|
|
|
|
<member>#GdkEventTouch</member>
|
2014-05-22 19:45:31 +00:00
|
|
|
|
</simplelist>
|
|
|
|
|
</para>
|
2014-05-28 13:50:06 +00:00
|
|
|
|
<para>
|
|
|
|
|
Additionally, GDK/GTK synthesizes other signals to let know whether
|
|
|
|
|
grabs (system-wide or in-app) are taking input away:
|
|
|
|
|
<simplelist>
|
2015-02-18 11:33:36 +00:00
|
|
|
|
<member>#GdkEventGrabBroken</member>
|
|
|
|
|
<member>#GtkWidget::grab-notify</member>
|
2014-05-28 13:50:06 +00:00
|
|
|
|
</simplelist>
|
|
|
|
|
</para>
|
2014-05-22 19:45:31 +00:00
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
When GTK creates a GdkSurface, it connects to the ::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.
|
2014-05-22 19:16:09 +00:00
|
|
|
|
</para>
|
2014-05-20 14:10:31 +00:00
|
|
|
|
</refsect2>
|
|
|
|
|
|
2015-02-18 11:13:28 +00:00
|
|
|
|
<refsect2 id="event-propagation">
|
2014-05-20 14:10:31 +00:00
|
|
|
|
<title>Event propagation</title>
|
|
|
|
|
|
2014-05-24 05:56:44 +00:00
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
The function which initially receives input events on the GTK
|
2020-02-09 15:38:01 +00:00
|
|
|
|
side is responsible for a number of tasks.
|
2014-05-24 05:56:44 +00:00
|
|
|
|
</para>
|
2020-02-09 15:38:01 +00:00
|
|
|
|
<orderedlist>
|
|
|
|
|
<listitem><para>
|
|
|
|
|
Compress enter/leave notify events. If the event passed build an
|
|
|
|
|
enter/leave pair together with the next event (peeked from GDK), both
|
|
|
|
|
events are thrown away. This is to avoid a backlog of (de-)highlighting
|
|
|
|
|
widgets crossed by the pointer.
|
|
|
|
|
</para></listitem>
|
|
|
|
|
<listitem><para>
|
|
|
|
|
Find the widget which got the event. If the widget can’t be determined
|
|
|
|
|
the event is thrown away unless it belongs to a INCR transaction.
|
|
|
|
|
</para></listitem>
|
|
|
|
|
<listitem><para>
|
|
|
|
|
Then the event is pushed onto a stack so you can query the currently
|
|
|
|
|
handled event with gtk_get_current_event().
|
|
|
|
|
</para></listitem>
|
|
|
|
|
<listitem><para>
|
|
|
|
|
The event is sent to a widget. If a grab is active all events for widgets
|
|
|
|
|
that are not in the contained in the grab widget are sent to the latter
|
|
|
|
|
with a few exceptions:
|
|
|
|
|
<itemizedlist>
|
|
|
|
|
<listitem><para>
|
|
|
|
|
Deletion and destruction events are still sent to the event widget for
|
|
|
|
|
obvious reasons.
|
|
|
|
|
</para></listitem>
|
|
|
|
|
<listitem><para>
|
|
|
|
|
Events which directly relate to the visual representation of the event
|
|
|
|
|
widget.
|
|
|
|
|
</para></listitem>
|
|
|
|
|
<listitem><para>
|
|
|
|
|
Leave events are delivered to the event widget if there was an enter
|
|
|
|
|
event delivered to it before without the paired leave event.
|
|
|
|
|
</para></listitem>
|
|
|
|
|
<listitem><para>
|
|
|
|
|
Drag events are not redirected because it is unclear what the semantics
|
|
|
|
|
of that would be.
|
|
|
|
|
</para></listitem>
|
|
|
|
|
</itemizedlist>
|
|
|
|
|
</para></listitem>
|
|
|
|
|
<listitem><para>
|
|
|
|
|
After finishing the delivery the event is popped from the event stack.
|
|
|
|
|
</para></listitem>
|
|
|
|
|
</orderedlist>
|
2014-05-24 05:56:44 +00:00
|
|
|
|
|
|
|
|
|
<para>
|
2015-02-18 11:13:28 +00:00
|
|
|
|
When a GDK backend produces an input event, it is tied to a #GdkDevice and
|
2018-03-20 10:40:08 +00:00
|
|
|
|
a #GdkSurface, which in turn represents a windowing system surface in the
|
2015-02-18 11:13:28 +00:00
|
|
|
|
backend. If a widget has grabbed the current input device, or all input
|
|
|
|
|
devices, the event is propagated to that #GtkWidget. Otherwise, it is
|
2019-04-19 20:18:57 +00:00
|
|
|
|
propagated to the the #GtkRoot which owns the #GdkSurface receiving the event.
|
2015-02-18 11:13:28 +00:00
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
Grabs are implemented for each input device, and globally. A grab for a
|
|
|
|
|
specific input device (gtk_device_grab_add()), is sent events in
|
|
|
|
|
preference to a global grab (gtk_grab_add()). Input grabs only have effect
|
|
|
|
|
within the #GtkWindowGroup containing the #GtkWidget which registered the
|
2018-03-20 10:40:08 +00:00
|
|
|
|
event’s #GdkSurface. If this #GtkWidget is a child of the grab widget, the
|
2015-02-18 11:13:28 +00:00
|
|
|
|
event is propagated to the child — this is the basis for propagating
|
|
|
|
|
events within modal dialogs.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
2020-02-09 16:00:53 +00:00
|
|
|
|
An event is propagated down and up the widget hierarchy in three phases
|
2019-05-03 04:22:07 +00:00
|
|
|
|
(see #GtkPropagationPhase) towards a target widget.
|
2015-02-18 11:13:28 +00:00
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
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()).
|
2015-02-18 11:13:28 +00:00
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
For pointer events, the target widget is determined by picking
|
|
|
|
|
the widget at the events coordinates (see gtk_window_pick()).
|
2014-05-24 05:56:44 +00:00
|
|
|
|
</para>
|
|
|
|
|
|
2019-05-03 04:22:07 +00:00
|
|
|
|
<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.
|
2014-05-28 13:50:06 +00:00
|
|
|
|
</para>
|
|
|
|
|
|
2014-05-24 05:56:44 +00:00
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
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.
|
2014-05-24 05:56:44 +00:00
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
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.
|
2014-05-24 05:56:44 +00:00
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
Events are not delivered to a widget which is insensitive or
|
|
|
|
|
unmapped.
|
2015-02-18 11:13:28 +00:00
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
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.
|
2014-05-28 13:50:06 +00:00
|
|
|
|
</para>
|
|
|
|
|
</refsect2>
|
|
|
|
|
|
|
|
|
|
<refsect2>
|
|
|
|
|
<title>Touch events</title>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
Touch events are emitted as events of type %GDK_TOUCH_BEGIN,
|
|
|
|
|
%GDK_TOUCH_UPDATE or %GDK_TOUCH_END, those events contain an
|
|
|
|
|
“event sequence” that univocally identifies the physical touch
|
|
|
|
|
until it is lifted from the device.
|
2014-05-28 13:50:06 +00:00
|
|
|
|
</para>
|
|
|
|
|
</refsect2>
|
|
|
|
|
|
|
|
|
|
<refsect2>
|
|
|
|
|
<title>Grabs</title>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
Grabs are a method to claim all input events from a device,
|
|
|
|
|
they happen either implicitly on pointer and touch devices,
|
|
|
|
|
or explicitly. Implicit grabs happen on user interaction, when
|
|
|
|
|
a #GdkEventButtonPress happens, all events from then on, until
|
|
|
|
|
after the corresponding #GdkEventButtonRelease, will be reported
|
|
|
|
|
to the widget that got the first event. Likewise, on touch events,
|
|
|
|
|
every #GdkEventSequence will deliver only events to the widget
|
|
|
|
|
that received its %GDK_TOUCH_BEGIN event.
|
2014-05-28 13:50:06 +00:00
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
Explicit grabs happen programatically (both activation and
|
|
|
|
|
deactivation), and can be either system-wide (GDK grabs) or
|
|
|
|
|
application-wide (GTK grabs). On the windowing platforms that
|
|
|
|
|
support it, GDK grabs will prevent any interaction with any other
|
|
|
|
|
application/window/widget than the grabbing one, whereas GTK grabs
|
|
|
|
|
will be effective only within the application (across all its
|
|
|
|
|
windows), still allowing for interaction with other applications.
|
2014-05-28 13:50:06 +00:00
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
But one important aspect of grabs is that they may potentially
|
|
|
|
|
happen at any point somewhere else, even while the pointer/touch
|
|
|
|
|
device is already grabbed. This makes it necessary for widgets to
|
|
|
|
|
handle the cancellation of any ongoing interaction. Depending on
|
|
|
|
|
whether a GTK or GDK grab is causing this, the widget will
|
|
|
|
|
respectively receive a #GtkWidget::grab-notify signal, or a
|
2015-02-18 11:33:36 +00:00
|
|
|
|
#GdkEventGrabBroken event.
|
2014-05-28 13:50:06 +00:00
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
On gestures, these signals are handled automatically, causing the
|
|
|
|
|
gesture to cancel all tracked pointer/touch events, and signal
|
|
|
|
|
the end of recognition.
|
2014-05-28 13:50:06 +00:00
|
|
|
|
</para>
|
2014-05-20 14:10:31 +00:00
|
|
|
|
</refsect2>
|
|
|
|
|
|
|
|
|
|
<refsect2>
|
|
|
|
|
<title>Keyboard input</title>
|
|
|
|
|
|
2019-05-03 04:22:07 +00:00
|
|
|
|
<para>
|
|
|
|
|
Every #GtkWindow maintains a single focus location (in
|
|
|
|
|
the ::focus-widget property). The focus widget is the
|
|
|
|
|
target widget for key events sent to the window. Only
|
|
|
|
|
widgets which have ::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>
|
|
|
|
|
|
2014-05-20 14:10:31 +00:00
|
|
|
|
<!-- mnemonics, accelerators, bindings -->
|
|
|
|
|
</refsect2>
|
|
|
|
|
|
2015-02-18 11:13:28 +00:00
|
|
|
|
<refsect2 id="event-controllers-and-gestures">
|
2014-05-28 13:50:06 +00:00
|
|
|
|
<title>Event controllers and gestures</title>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
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.
|
2014-05-28 13:50:06 +00:00
|
|
|
|
</para>
|
2014-05-20 14:10:31 +00:00
|
|
|
|
|
2014-05-28 13:50:06 +00:00
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
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.
|
2014-05-28 13:50:06 +00:00
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
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
|
2014-05-28 13:50:06 +00:00
|
|
|
|
gestures. Some examples of grouping may be:
|
|
|
|
|
|
|
|
|
|
<simplelist>
|
|
|
|
|
<member>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
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.
|
2014-05-28 13:50:06 +00:00
|
|
|
|
</member>
|
|
|
|
|
<member>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
Grouping a “drag” gesture with a “pan” gesture will only
|
|
|
|
|
effectively allow dragging in the panning orientation, as
|
|
|
|
|
both gestures share state.
|
2014-05-28 13:50:06 +00:00
|
|
|
|
</member>
|
|
|
|
|
<member>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
If “press” and “long press” are wanted simultaneously,
|
|
|
|
|
those would need grouping.
|
2014-05-28 13:50:06 +00:00
|
|
|
|
</member>
|
|
|
|
|
</simplelist>
|
|
|
|
|
</para>
|
|
|
|
|
</refsect2>
|
|
|
|
|
|
|
|
|
|
<refsect2>
|
|
|
|
|
<title>Gesture states</title>
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
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
|
2014-05-28 13:50:06 +00:00
|
|
|
|
actions, but the event propagation will not be stopped.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
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.
|
2014-05-28 13:50:06 +00:00
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
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,
|
2015-02-18 11:33:36 +00:00
|
|
|
|
a %GDK_TOUCH_BEGIN/%GDK_BUTTON_PRESS event will be emulated and
|
2014-05-28 13:50:06 +00:00
|
|
|
|
propagated downwards, in order to preserve consistency.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
2019-05-03 04:22:07 +00:00
|
|
|
|
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.
|
2014-05-28 13:50:06 +00:00
|
|
|
|
</para>
|
2014-05-20 14:10:31 +00:00
|
|
|
|
</refsect2>
|
|
|
|
|
|
|
|
|
|
</refsect1>
|
|
|
|
|
</refentry>
|