Events are identified the small integer argument passed to the Fl_Widget::handle() virtual method.
Other information about the most recent event is stored in static
locations and aquired by calling Fl::event_*()
. This static
information remains valid until the next event is read from the X
server (that is, it is ok to look at it outside the handle() method).
FL_PUSH (1)
A widget indicates that it "wants" the mouse click by returning non-zero from it's handle() method. It will then become the Fl::pushed() widget and will get FL_DRAG and the matching FL_RELEASE events. If handle() returns zero then fltk will try sending the FL_PUSH to another widget.
FL_DRAG (5)
FL_RELEASE (2)
FL_ENTER (3)
FL_MOVE (10)
FL_LEAVE (4)
FL_FOCUS (6)
If a widget wants the focus, it should change itself to display the fact that it has the focus, and return non-zero from it's handle() method. It then becomes the Fl::focus() widget and gets FL_KEYBOARD and FL_UNFOCUS events.
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)
FL_KEYBOARD (8)
FL_SHORTCUT (11)
If the Fl::event_text() is a lower or upper-case letter, and nothing wants the shortcut
You can also make "global" shortcuts by using Fl::add_handler(). A global shortcut will work no matter what windows are displayed or which one has the focus.
FL_DEACTIVATE (13)
FL_ACTIVATE (14)
FL_HIDE (15)
FL_SHOW (16)
FL_PASTE (17)
FL_SELECTIONCLEAR (18)
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.
Return where the mouse is on the screen by doing a round-trip query
to the server. You should use Fl::event_x/y_root() if possible, but this is
necessary if you are not sure if a mouse event has been processed
recently (such as to position your first window). If the display is
not open, this will open it.
X servers do not agree on shift states and FL_NUM_LOCK, FL_META,
and FL_SCROLL_LOCK may not work. The values were selected to match
the XFree86 server on Linux. In addition there is a bug in the way
Xlib works so that the shift state is not correctly reported until the
first event after the shift key is pressed or released.
Fl::event_key(int) returns true if the given key was held down (or
pressed) during the last event. This is constant until the
next event is read from the server.
Fl::get_key(int) returns true if the given key is held down
now. Under X this requires a round-trip to the server and is
much slower than Fl::event_key(int).
Keys are identified by the unshifted X keysym values.
However fltk defines a set of symbols that should work on most modern
machines for every key on the generic PC keyboard:
Known bugs: on X 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.
Length of the text in Fl::event_text(). There will always be a
null at this position in the text. However there may be a nul before
that if the keystroke translates to a nul character or you paste a nul
character.
Fltk follows very simple and unchangeable rules for sending events.
The major innovation is that widgets can indicate (by returning 0 from
the handle() method) that they are not interested in an event, and fltk
can then send that event elsewhere. This eliminates the need for
"interests" (event masks or tables), and this is probably the main
reason fltk 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 widgets. To make the Fl_Group code
somewhat easier, fltk sends some events (FL_DRAG, FL_RELEASE,
FL_KEYBOARD, FL_SHORTCUT, FL_UNFOCUS, FL_LEAVE) directly to leaf
widgets. These procedures control those leaf widgets:
If you change Fl::focus(), the old one and all parents (that don't
contain the new widget) are sent FL_UNFOCUS events. Changing the
focus does not send FL_FOCUS to this or any widget, because
sending FL_FOCUS is supposed to test if the widget wants the
focus (by it returning non-zero from handle()).
Try to make this widget be the Fl::focus(), by first sending it an
FL_FOCUS event, and if it returns non-zero, setting Fl::focus() to
this widget. You should use this method to assign the focus to an
widget. Returns true if the widget accepted the focus.
If you change the belowmouse widget, the old one and all parents (that
don't contain the new widget) are sent FL_LEAVE events. Changing this
does not send FL_ENTER to this or any widget, because
sending FL_ENTER is supposed to test if the widget wants the
mouse (by it returning non-zero from handle()).
Get or set the widget that is being pushed. FL_DRAG or FL_RELEASE
(and any more FL_PUSH) events will be sent to this widget.
If you change the pushed widget, the old one and all parents (that
don't contain the new widget) are sent FL_RELEASE events. Changing
this does not send FL_PUSH to this or any widget, because
sending FL_PUSH is supposed to test if the widget wants the
mouse (by it returning non-zero from handle()).
Fl::event_x() and y() are undefiend if the passed widget is not a
mapped Fl_Window. Use Fl::event_x_root() and Fl::event_y_root()
instead.
Be careful that your program does not enter an infinite loop
while grab() is on. On X this will lock up your screen!
The second function returns the current grab window, or null if
none.
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.
void Fl::get_mouse(int &,int &)
ulong Fl::event_state();
unsigned int Fl::event_state(int);
This is a bitfield of what shift states were on and what mouse buttons
were held down during the most recent event. The second version
returns non-zero if any of the passed bits are turned on. The legal
bits are
FL_SHIFT, FL_CAPS_LOCK, FL_CTRL, FL_ALT, FL_NUM_LOCK,
FL_META, FL_SCROLL_LOCK, FL_BUTTON1, FL_BUTTON2, FL_BUTTON3
.
int Fl::event_key();
int Fl::event_key(int);
int Fl::get_key(int);
Fl::event_key() returns which key on the keyboard was last pushed.
FL_KP
. The highest possible value is
FL_KP_Last
so you can range-check to see if something is
on the keypad.
FL_F
. The highest possible number is
FL_F_Last
, so you can range-check a value.
FL_Button
.
FL_Escape,
FL_BackSpace, FL_Tab, FL_Enter, FL_Print, FL_Scroll_Lock, FL_Pause,
FL_Insert, FL_Home, FL_Page_Up, FL_Delete, FL_End, FL_Page_Down,
FL_Left, FL_Up, FL_Right, FL_Down, FL_Shift_L, FL_Shift_R,
FL_Control_L, FL_Control_R, FL_Caps_Lock, FL_Alt_L, FL_Alt_R,
FL_Meta_L, FL_Meta_R, FL_Menu, FL_Num_Lock, FL_KP_Enter
. Be
careful not to confuse these with the very similar, but all-caps,
symbols used by Fl::event_state().
Fl::get_key(FL_Button+n)
does not
work. On MSWindows Fl::get_key(FL_KP_Enter)
and
Fl::event_key(FL_KP_Enter)
do not work.
char * Fl::event_text()
char * Fl::event_length()
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 or to make
a popup menu pick an item with a single click. Don't pass non-zero to
this.
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_Widget *) const ;
int Fl::event_inside(int,int,int,int);
Returns non-zero if the current event_x and event_y put it inside the
widget 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(ulong) const ;
Test the current event, which must be an FL_KEYBOARD or FL_SHORTCUT,
against a shortcut value (described in Fl_Button). Returns non-zero if
there is a match. Not to be confused with Fl_Widget::test_shortcut().
Event Propagation
Fl_Widget *Fl::focus() const;
void Fl::focus(Fl_Widget *);
Get or set the widget that will receive FL_KEYBOARD events.
int Fl_Widget::take_focus();
Fl_Widget *Fl::belowmouse() const;
void Fl::belowmouse(Fl_Widget *);
Get or set the widget 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 widget. This is also the first widget tried for FL_SHORTCUT
events.
Fl_Widget *Fl::pushed() const;
void Fl::pushed(Fl_Widget *);
void Fl::add_handler(int (*f)(int));
Install a function to parse unrecognized events. If fltk 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:
Fl_Window* Fl::modal();
The modal() window has it's handle() method called for all events, and
no other windows will have handle() called. If grab() has been done then this is equal to grab().
Otherwise this is the most recently shown() window with modal() true, or null if there are no
modal() windows shown().
void Fl::grab(Fl_Window&);
Fl_Window* Fl::grab();
This is used when pop-up menu systems are active. Send all events to
the passed window no matter where the pointer or focus is (including
in other programs). The window does not have to be shown(),
this lets the handle() method of a "dummy" window override all event
handling and allows you to map and unmap a complex set of windows
(under both X and NT some window must be mapped because the
system interface needs a window id).
void Fl::release()
Turn off the grab() behavior.