Four different event types result in a GdkEventButton:
-
GDK_BUTTON_PRESS
means a mouse button was pressed down.
-
GDK_BUTTON_RELEASE
means a button was released after being pressed down.
Will not necessarily be received after a button press
event: if the user moves the mouse to a different
GdkWindow, that
window will receive it instead.
-
GDK_2BUTTON_PRESS
means a mouse button was pressed down twice in a
short interval---a "double click." Always preceded by
a
GDK_BUTTON_PRESS/GDK_BUTTON_RELEASE pair for the
first click.
-
GDK_3BUTTON_PRESS
means a mouse button was pressed down three times in
a short interval; a "triple click." Preceded by two
GDK_BUTTON_PRESS/GDK_BUTTON_RELEASE pairs and
GDK_2BUTTON_PRESS.
If you click three times quickly, on the same GdkWindow, the following events
are received in order:
-
GDK_BUTTON_PRESS
-
GDK_BUTTON_RELEASE
-
GDK_BUTTON_PRESS
-
GDK_2BUTTON_PRESS
-
GDK_BUTTON_RELEASE
-
GDK_BUTTON_PRESS
-
GDK_3BUTTON_PRESS
-
GDK_BUTTON_RELEASE
The X server automatically causes a pointer grab when a
button is pressed, and releases it when it is released.
This means that the button release event always goes to
the same window that received the button press event.
Xlib allows you to change this behavior, but GDK does
not. (In the Xlib documentation, this automatic grab is
referred to as a "passive" grab. It's distinct from an
"active" grab initiated with
gdk_pointer_grab(), described in the section called
Grabbing the Pointer.)
A button event is defined as follows:
typedef struct _GdkEventButton GdkEventButton;
struct _GdkEventButton
{
GdkEventType type;
GdkWindow *window;
gint8 send_event;
guint32 time;
gdouble x;
gdouble y;
gdouble pressure;
gdouble xtilt;
gdouble ytilt;
guint state;
guint button;
GdkInputSource source;
guint32 deviceid;
gdouble x_root, y_root;
};
|
Button events are marked with a time stamp (time) by the X server. The time is
given in milliseconds of "server time"; every few weeks
the integer overflows and timestamps begin again at 0.
Thus, you should not rely on the value as an absolute
measure of time; it is intended only to determine
relative time between events.
The mouse pointer's X and Y coordinates (relative to the
window the event occurred in) are included in GdkEventButton. Keep in mind
that the pointer may be outside the window (if a pointer
grab is in effect; see the
section called The Mouse Pointer). If the
pointer is outside the window, its coordinates could be
negative or larger than the window's size. Coordinates
are given as doubles rather than integers, because some
input devices such as graphics tablets have sub-pixel
resolution. For most purposes, you will want to cast the
doubles to integers.
pressure, xtilt,
and ytilt are also
special features of some input devices; they can be
ignored almost all the time.
The state member of GdkEventButton indicates which
modifier keys or mouse buttons were held down an instant
before the button was pressed. It is a bitfield, with one
or more of the flags in Table 5 set. Since
the modifiers are read just before the button press, it
follows that button press events do not have the pressed
button in state, but
button release events do have it.
Be careful to check for the presence of certain bit
masks, rather than the exact value of state. That is, prefer this:
if ( (state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK )
|
and avoid this:
if ( state == GDK_SHIFT_MASK )
|
If you check the exact value of
state, your application will mysteriously stop
working if the user has Num Lock or some other obscure
modifier turned on.
Table 5. Modifier Masks for Key and Button
Events
Modifier Mask
|
Meaning
|
GDK_SHIFT_MASK
|
Shift
|
GDK_LOCK_MASK
|
Caps Lock
|
GDK_CONTROL_MASK
|
Control
|
GDK_MOD1_MASK
|
Mod1 (often Meta or Alt)
|
GDK_MOD2_MASK
|
Mod2
|
GDK_MOD3_MASK
|
Mod3
|
GDK_MOD4_MASK
|
Mod4
|
GDK_MOD5_MASK
|
Mod5
|
GDK_BUTTON1_MASK
|
Button 1
|
GDK_BUTTON2_MASK
|
Button 2
|
GDK_BUTTON3_MASK
|
Button 3
|
GDK_BUTTON4_MASK
|
Button 4
|
GDK_BUTTON5_MASK
|
Button 5
|
GDK_RELEASE_MASK
|
Key releases
|
The button member of
GdkEventButton indicates
which button triggered the event (i.e., the button which
was pressed or released). Buttons are numbered from one
to five; most of the time, button one is the left button,
button two is the middle button, and button three is the
right button. Left-handed users might reverse these.
Button four and five events are generated by some scroll
wheel mice when you spin the scroll wheel; GTK+ attempts
to send capture these events and move nearby scroll bars.
You should probably ignore any events you receive for
buttons four or five.
The three standard mouse buttons have conventional
meanings in Gnome. Button one is used for selection, drag
and drop, and operating widgets: the most common tasks.
Button three typically activates a pop-up menu. Button
two is traditionally used to move objects, such as the
panel. Sometimes button one moves objects also; for
example, desktop icons can be moved with either button
one or two. It is a good idea to be consistent with other
applications whenever possible.
The source and deviceid members are used to
determine which device triggered the event; the user may
have a graphics tablet and a mouse connected
simultaneously, for example. You can ignore these fields
unless you are writing an application that can take
advantage of non-mouse devices.
The last two members of
GdkEventButton,
x_root and y_root,
are the x and y coordinates translated to be
relative to the root window rather than the window
receiving the event. You can use these as "absolute"
coordinates to compare events from two different windows.