Http://blog.csdn.net/maojudong/archive/2008/03/19/2197425.aspx
When the mouse moves on the screen, you can use the mouse to move the event to track its movements. A moving event occurs when the mouse pointer moves in the window. A traversing event occurs when the mouse pointer enters or leaves the gdkwindow. A typical member of a mobile event is gdk_motion_notify. There are two types of traversal events:
Gdk_enter_notify and gdk_leave_notify.
There are two ways to track mouse movement events. If gdk_pointer_motion_mask is specified in event shielding in the window, you can receive as many events as possible generated by X server. If the user moves the pointer quickly, the program will be overwhelmed by the moving events and must be processed quickly. Otherwise, the application will be slow to respond when handling a large number of events.
If gdk_pointer_motion_hint_mask is also specified, only one mobile event is sent at a time. You also need to call the gdk_window_get_pointer () function, move the mouse pointer away and enter the window again, or send the event only when a mouse or keyboard event occurs. That is, each time you receive a moving event, you must call the gdk_window_get_pointer () function to obtain the current position of the mouse pointer and notify the X server that it can receive another event.
The mode to choose depends on the application. If you need to precisely track the trajectory of the pointer, You have to capture all the moving events. To minimize network traffic and maximize application response capabilities, you should include gdk_pointer_motion_hint_mask in Application Event shielding.
The gdk_window_get_pointer () function requires that data be transmitted between the server and the customer to obtain the location of the mouse pointer. Therefore, it imposes great limitations on the application response capability. If you can process mouse motion events as quickly as possible without being overwhelmed by a large number of events, the application looks faster than setting event blocking gdk_pointer_motion_hint_mask. The mouse movement event cannot occur 200 times in one second. Therefore, it would be nice to handle the mouse movement event within 5 milliseconds.
To receive mouse events only when one or more mouse buttons are pressed, use gdk_button_motion_mask instead of gdk_pointer_motion_mask. You can also use gdk_pointer_motion_hint_mask and gdk_button_motion_mask together to limit the number of events to be received, just like using gdk_pointer_motion_mask together. If you are only interested in mouse movement events when a specific mouse button is pressed, you can use events related to a specific mouse key to block gdk_button1_motion_mask, gdk_button2_motion_mask, and gdk_button3_motion_mask. Any combination of these three events is allowed. They can also be used together with gdk_pointer_motion_hint_mask to limit the number of events.
All in all, you can use the following five event blocking values to select the buttons in which to receive the mouse movement event:
Gdk_pointer_motion_mask: receives all events regardless of the button status.
Gdk_button_motion_mask: receives all events when a key is pressed.
Gdk_button1_motion_mask: receives all events when the key 1 is pressed.
Gdk_button2_motion_mask: receives all events when pressing press 2.
Gdk_button3_motion_mask: receives all events when you press 3.
By default, applications will be overwhelmed by events generated by X server. It is best to add a gdk_pointer_motion_hint_mask to event blocking so that the event "occurs once in a certain period of time ".
The gdkeventmotion structure for mobile events is described as follows:
Typedefstruct_gdkeventmotiongdkeventmotion;
Struct_gdkeventmotion
{
Gdkeventtypetype;
Gdkwindow * window;
Gint8send_event;
Guint32time;
Gdoublex;
Gdoubley;
Gdoublepressure;
Gdoublextilt;
Gdoubleytilt;
Guintstate;
Gint16is_hint;
Gdkinputsourcesource;
Guint32deviceid;
Gdoublex_root, y_root;
};
Most members are similar to those in gdkeventbutton. In fact, the only member different from gdkeventmotion is the is_hint sign. If it is true, the gdk_pointer_motion_hint_mask flag is selected.
If you want to write a component for others and want them to choose how to receive a mobile event, you need to set the value of this Member. In the mobile event processing program, you can do this:
Doublex, Y;
X = event-> motion. X;
Y = event-> motion. Y;
If (Event-> motion. is_hint)
Gdk_window_get_pointer (Event-> window, & X, & Y, null );
That is, the gdk_window_get_pointer () function is called only when necessary.
If gdk_pointer_motion_hint_mask is being used, the coordinates of the given event should be obtained from the gdk_window_get_pointer () function because they are updated. If you are receiving each event, it makes no sense to call gdk_window_get_pointer () because it is too slow and will cause a serious backlog of events-in this way, all events will be obtained, however, the performance of the application may be poor.
A traversal event occurs when the mouse pointer enters or leaves a window. If the gdkwindow of the application moves rapidly, the gdk generates a traversal event for each window to be traversed. However, GTK + will try to delete the events in multiple "traversal" processes, and only pass the first exit event and the last entry window event to the component. This optimization can improve the response speed of the program. If the event of entry/exit occurs, it does not actually happen, and may be caused by the above optimization.
The gdkeventcrossing structure is defined as follows:
Typedefstruct_gdkeventcrossinggdkeventcrossing;
Struct_gdkeventcrossing
{
Gdkeventtypetype;
Gdkwindow * window;
Gint8send_event;
Gdkwindow * subwindow;
Guint32time;
Gdoublex;
Gdoubley;
Gdoublex_root;
Gdoubley_root;
Gdkcrossingmodemode;
Gdknotifytypedetail;
Gbooleanfocus;
Guintstate;
};
Many members in the structure shown above should be familiar with it. The X and Y coordinates are relative to the window coordinates in which the event is crossed; The x_root and y_root coordinates are relative to the root window; the time Member specifies the event time. The State Member specifies the mouse and combination keys that are pressed when an event occurs. The first three members in the structure are three standard members in gdkeventany. However, there are several new members.
The window member in the gdkeventcrossing structure is a window pointer pointing to the mouse pointer to enter or exit. The X and Y coordinates are relative to the window. However, before the "exit" event occurs, the mouse pointer may already exist in the subwindow of the window that receives the event. When the "enter" event occurs, the mouse pointer may disappear in a subwindow. In these cases, the subwindow member should be set to this subwindow. Otherwise, you can set subwindow to null. NOTE: If gdk_enter_policy_mask or gdk_leave_policy_mask is set in the event blocking value of the subwindow, The subwindow will also receive its own "go" or "exit" event.
The Mode member in gdkeventcrossing specifies whether the event is caused normally or as part of the pointer monopoly.
When the pointer is exclusive or exclusive, the pointer may move. The value of the mode member of an exclusive mouse movement event is gdk_crossing_grab, and the mode Member of the exclusive movement event is gdk_crossing_ungrab. In all other cases, the mode is gdk_crossing_normal.
Detail members in gdkeventcrossing are rarely used. It provides information about the relative position of the window to exit and enter in the window tree of X system. It has two simple and useful values:
Gdk_policy_inferior indicates a traversal event received by the parent window when the pointer is moved in or out of a subwindow.
Gdk_policy_ancestor indicates a traversal event received by the Child window when the pointer is moved into or out of a parent window. Other values are also possible: gdk_policy_virtual, gdk_policy_inferior, gdk_policy_nonlinear, gdk_policy_nonlinear_virtual, and gdk_policy_unknown. However, they will never be used because they are too complicated.
Keyboard focus
The focus member of gdkeventcrossing points out whether the event window or its subwindow gets the keyboard input focus. Keyboard focus is an X concept used to determine which window should receive button events. The Window Manager determines which top-level window should be focused. Usually, the window that gets the focus is highlighted and displayed at the beginning. Most Window managers allow you to choose between "focus with the mouse" and "focus with the click. When an application has focus, the focus can be moved freely between its subwindows (for example, between different gtktext components ). However, GTK + does not use the X focus mechanism for child windows.
The top-level gtkwindow component is the only window that receives x focus. Therefore, they receive all the original button events from the X server (through gdk. GTK + implements its own component focus concept. It is similar to X's window focus concept, but it is actually completely different. When a top-level window receives a key event, it sends the event to the component with GTK + focus.
In short, if the top-level gtkwindow containing the event window currently has x focus, the value of the Focus member will be true. The focus member has no direct relationship with the GTK + component focus concept.