Events
Events are identified the small integer argument passed to the handle() method on an object. Unless
you are subclassing an object, you cannot see this event type. Other
information about the most recent event is stored in static locations
and aquired by calling Fl::event_*()
. This other
information remains valid until another event is read from the X
server (and thus is valid inside a callback or other function called
from handle()).
FL_PUSH (1)
A mouse button has gone down with the mouse pointing at this object.
You can find out what button by calling Fl::event_button(). You find
out the mouse position by calling Fl::event_x() and Fl::event_y(). If
your object wants to receive FL_DRAG and the matching FL_RELEASE
events then handle() must return non-zero, in which case this becomes
the Fl::pushed() object.
FL_DRAG (5)
The mouse has moved with the button held down.
FL_RELEASE (2)
A mouse button has been released. You can find out what button by
calling Fl::event_button().
FL_ENTER (3)
The mouse has been moved to point at this object. You can use this
for highlighting feedback. If your object wants to receive the
FL_MOVE and FL_EXIT events then it must return non-zero from handle(),
in which case it becomes the Fl::belowmouse() object.
FL_MOVE (10)
The mouse has moved without any mouse buttons held down. This event
is sent (sort of) to the belowmouse() object.
FL_LEAVE (4)
The mouse has moved out of the object.
FL_FOCUS (6)
This indicates an attempt to give your object the keyboard focus. If
your object wants to receive FL_KEYBOARD events, your handle() method
must return non-zero, in which case it becomes the Fl::focus() object.
If you return 0, then another object is tried.
The focus will change either because the window manager changed
which window gets the focus, or because the user tried to navigate
using tab, arrows, or other keys. You can check Fl::event_key() to
figure out why it moved. For navigation it will be the key pressed,
for instructions from the window manager it will be zero.
FL_UNFOCUS (7)
Sent to the old Fl::focus() when something else gets the focus.
FL_KEYBOARD (8)
A key press. The key pressed can be found in Fl::event_key(), or,
more usefully, the text that the key should insert can be found with
Fl::event_text(). If you use the key handle() should return 1. If
you return zero then Fl assummes you ignored the key. It will then
attempt to send it to a parent object. If none of them want it, it
will try passing it as an FL_SHORTCUT event.
FL_SHORTCUT (11)
If the Fl::focus() is zero or ignores an FL_KEYBOARD event then FL
tries sending these events. If your object uses the shortcut it's
handle() routine should return non-zero. If it returns zero FL will
continue trying until it has tried every object it knows about.
FL_SHORTCUT is first sent to the belowmouse object, then all parents
and siblings of them, then all other windows. Fl tries real hard to
not let any keystrokes be ignored!
FL_DEACTIVATE (13)
This object is no longer active, due to deactivate() being called on
it or one of it's parents. Notice that active() may still be true, as
the object is only active if active() is true on it and all it's
parents.
FL_ACTIVATE (14)
This object is now active, due to activate() being called on it or one
of it's parents.
FL_HIDE (15)
This object is no longer visible, due to hide() being called, or a
parent group or window having hide() be called, or due to a parent
window being iconized. Notice that visible() may still be true, as
the object is only active if visible() is true on it and all it's
parents.
FL_SHOW (16)
This object is visible again, due to show() being called on it or one
of it's parents, or due to a parent window being deiconized.
FL_PASTE (17)
You should get this event some time after you call
Fl::request_paste(). The contents of Fl::event_text() is the text to
insert.
FL_SELECTIONCLEAR (18)
The Fl::selection_owner() will get this event before the selection is
moved to another object. This indicates that some other object or program
has claimed the selection.
Fl::event_*() methods
FL keeps the information about the most recent event in static
storage. This information is good until the next event is processed.
Thus it is valid inside handle() and callback() methods.
These are all trivial inline functions and thus very fast and
small. The data is stored in static locations and remains valid until
the next X event is handled.
int Fl::event_button();
Returns which mouse button was pressed. This returns garbage if the
most recent event was not a FL_PUSH or FL_RELEASE.
int Fl::event_x()
int Fl::event_y()
Returns the mouse position of the event (relative to the Fl_Window it
was passed to).
int Fl::event_x_root()
int Fl::event_y_root()
Returns the mouse position on the screen of the event. To find the
absolute position of an Fl_Window on the screen, use the difference
between event_x_root and event_x.
unsigned int Fl::event_state()
Return a bitfield of what shift keys were held down during the most
recent event. The values are system-specific, except zero means no
keys are held down.
int Fl::event_shift();
int Fl::event_capslock();
int Fl::event_ctrl();
int Fl::event_alt();
Returns non-zero if the corresponding shift key was held down during
the most recent event. Under X this value is not correct until the
event after the FL_KEYBOARD event generated by pushing a shift
key.
int Fl::event_buttons();
int Fl::event_button1();
int Fl::event_button2();
int Fl::event_button3();
Returns non-zero if the given (or any) mouse button was held down
during the most recent event. FL fixes the bug in X where this is
incorrect for FL_PUSH or FL_RELEASE events: it reflects the result of
the event rather than the state before the event.
int Fl::event_key()
Returns a number identifying the last keyboard key pushed. For all
the ascii keys on the main keyboard this is the ascii character value,
including the effect of the Shift key. The values are
system-specific, but the following symbols are defined in Fl.H:
FL_BackSpace, FL_Tab, FL_Return, FL_Pause, FL_Scroll_Lock,
FL_Sys_Req, FL_Escape, FL_Delete, FL_Home, FL_Left, FL_Up, FL_Right,
FL_Down, FL_Page_Up, FL_Page_Down, FL_End, FL_Insert, FL_Break,
FL_F
(add N for function key N), FL_F_Last
Mouse button events, mouse moved events, and focus in/out events
cause this to return values that cannot be confused with any legal
keyboard keys.
On X systems the value is equal to the keysym returned by
XLookupString().
int Fl::event_keypad()
Returns non-zero if the key was on the keypad (under X this is all
the keysyms that start with XK_KP).
char * Fl::event_text()
ASCII text (in the future this may be UTF-8) produced by the last
FL_KEYBOARD or FL_PASTE or possibly other event. A zero-length string
is returned for any keyboard function keys that do not produce text.
This pointer points at a static buffer and is only valid until the
next event is processed.
Under X this is the result of XLookupString, except if the Alt key
was held down the high bit is turned on in the first character.
int Fl::event_is_click()
Returns non-zero if the mouse has not moved far enough and not enough
time has passed since the last FL_PUSH or FL_KEYBOARD event for it
to be considered a "drag" rather than a "click". You can test this on
FL_DRAG, FL_RELEASE, and FL_MOVE events.
void Fl::event_is_click(0)
Clear the value returned by Fl::event_is_click(). Useful to prevent
the next click from being counted as a double-click. Passing
values other than zero does not work.
int Fl::event_clicks()
Returns non-zero if the most recent FL_PUSH or FL_KEYBOARD was a
"double click". Returns N-1 for N clicks. A double click is counted
if the same button is pressed again while event_is_click() is true.
void Fl::event_clicks(int)
Directly set the number returned by Fl::event_clicks(). This can be
used to set it to zero so that later code does not think an item was
double-clicked.
int Fl::event_inside(const Fl_Object *) const ;
int Fl::event_inside(int,int,int,int);
Returns non-zero if the current event_x and event_y put it inside the
object or inside an arbitrary bounding box. You should always call
this rather than doing your own comparison so you are consistent about
edge effects.
int Fl::test_shortcut(const char *) const ;
Test the current event, which must be an FL_KEYBOARD or FL_SHORTCUT,
against a shortcut string (described in Fl_Button). Returns non-zero if there is a
match. Not to be confused with Fl_Object::test_shortcut().
ulong Fl::event_time()
Returns the X timestamp of the last keystroke or mouse click or mouse
movement. Some Xlib calls need this as an argument. May not work on
non-X systems.
extern XEvent fl_xvent;
The most recent or current X event. You will have to include the
header file <FL/x.H> to use this.
Event Propagation
FL follows very simple and unchangeable rules for sending events.
The major innovation is that objects can indicate (by returning 0 from
the handle() method) that they are not interested in an event, and FL
can then send that event elsewhere. This eliminates the need for
"interests" (event masks or tables), and this is probably the main
reason FL is much smaller than other X toolkits.
Most events are sent directly to the handle() method of the
Fl_Window that X says they belong to. The window (actually the
Fl_Group that Fl_Window is a subclass of) is responsible for sending
the events on to any child objects. To make the Fl_Group code
somewhat easier, FL sends some events (FL_DRAG, FL_RELEASE,
FL_KEYBOARD, FL_SHORTCUT, FL_UNFOCUS, FL_LEAVE) directly to leaf
objects. These procedures control those leaf objects:
Fl_Object *Fl::focus() const;
void Fl::focus(Fl_Object *);
Get or set the object that will receive FL_KEYBOARD events.
If you change Fl::focus(), the old one and all parents (that don't
contain the new object) are sent FL_UNFOCUS events. Changing the
focus does not send FL_FOCUS to this or any object, because
sending FL_FOCUS is supposed to test if the object wants the
focus (by it returning non-zero from handle()).
int Fl_Object::take_focus();
Try to make this object be the Fl::focus(), by first sending it an
FL_FOCUS event, and if it returns non-zero, setting Fl::focus() to
this object. You should use this method to assign the focus to an
object. Returns true if the object accepted the focus.
Fl_Object *Fl::belowmouse() const;
void Fl::belowmouse(Fl_Object *);
Get or set the object that is below the mouse. This is for
highlighting buttons. It is not used to send FL_PUSH or FL_MOVE
directly, for several obscure reasons, but those events typically go
to this object. This is also the first object tried for FL_SHORTCUT
events.
If you change the belowmouse object, the old one and all parents (that
don't contain the new object) are sent FL_LEAVE events. Changing this
does not send FL_ENTER to this or any object, because
sending FL_ENTER is supposed to test if the object wants the
mouse (by it returning non-zero from handle()).
Fl_Object *Fl::pushed() const;
void Fl::pushed(Fl_Object *);
Get or set the object that is being pushed. FL_DRAG or FL_RELEASE
(and any more FL_PUSH) events will be sent to this object.
If you change the pushed object, the old one and all parents (that
don't contain the new object) are sent FL_RELEASE events. Changing
this does not send FL_PUSH to this or any object, because
sending FL_PUSH is supposed to test if the object wants the
mouse (by it returning non-zero from handle()).
void Fl::add_handler(int (*f)(int));
Install a function to parse unrecognized events. If FL cannot figure
out what to do with an event, it calls each of these functions (most
recent first) until one of them returns non-zero. If none of them
returns non zero then the event is ignored. Events that cause this to
be called are:
- X events that FL does not recognize, or X events with a window id
that FL does not recognize. The handler is called with zero as the
event number. You can look at the xevent with the
fl_xevent
pointer, declared in <FL/x.H>
.
- FL_SHORTCUT events that are not recognized by any object. This
lets you provide global shortcut keys.
- Some other events when the object FL selected returns zero
from it's handle() method. Exactly which ones may change in future
versions, however.
void Fl::grab()
Do whatever is necessary so that when the user clicks the mouse or
types keys on the keyboard, no matter where it is on the screen, the
program will get FL_MOUSE or FL_KEYBOARD events. It is undefined what
window the events go to, unless you have a modal() window up.
Under X an "Active Grab" of both the mouse and keyboard is done.
This has rather foul effects on other programs, particularily if your
program goes into an infinite loop. The grab will belong to whatever
window received the last event, so you cannot unmap that window or you
will lose the grab. The best way to use it is to call Fl::grab(),
then show() a modal() window. All events will go to the modal window.
When you are done, call hide() on that window and then call
Fl::release().
void Fl::release()
Turn off the grab() behavior.
(back to contents)