GtkEv wants to receive key
press events so it can report information about them. As
discussed in the
section called Focus in the chapter called GTK+
Basics and the section called
Keyboard Focus in the chapter called GDK
Basics, only toplevel windows receive key events
from GDK. GtkWindow keeps
track of a current focus widget
and forwards key events to it.
If a widget wants to receive key events, it must:
-
Set its GTK_CAN_FOCUS
flag, so GTK+ will consider it as a possible focus
widget.
-
Respond to "focus_in" and
"focus_out" signals by
drawing and erasing a visual indication that it has
the focus.
GtkEv set the GTK_CAN_FOCUS flag in gtk_ev_init(); it implements focus in and
focus out methods as follows:
static gint
gtk_ev_focus_in (GtkWidget *widget,
GdkEventFocus *event)
{
g_return_val_if_fail(widget != NULL, FALSE);
g_return_val_if_fail(GTK_IS_EV(widget), FALSE);
GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
gtk_widget_draw_focus (widget);
return FALSE;
}
static gint
gtk_ev_focus_out (GtkWidget *widget,
GdkEventFocus *event)
{
g_return_val_if_fail(widget != NULL, FALSE);
g_return_val_if_fail(GTK_IS_EV(widget), FALSE);
GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
gtk_widget_draw_focus (widget);
return FALSE;
}
|
These implementations are the minimal ones; all focusable
widgets must set or unset the
GTK_HAS_FOCUS flag when they gain or lose the
focus, and they must emit the
"draw_focus" signal.
GtkEv has a lazy
implementation of the
"draw_focus" signal; it just calls the same gtk_ev_paint() used to respond to
expose events and redraw requests. Recall that gtk_ev_paint() checks whether the GtkEv has the focus and draws a
focus frame if so. Here is the code:
static void
gtk_ev_draw_focus (GtkWidget *widget)
{
GdkRectangle rect;
GtkEv* ev;
g_return_if_fail(widget != NULL);
g_return_if_fail(GTK_IS_EV(widget));
ev = GTK_EV(widget);
rect.x = 0;
rect.y = 0;
rect.width = widget->allocation.width;
rect.height = widget->allocation.height;
if (GTK_WIDGET_DRAWABLE (ev))
gtk_ev_paint(ev, &rect);
}
|
Notice that widget implementations are responsible for
emitting the "draw_focus"
signal themselves; GTK+ does not emit it as the focus
moves. Contrast this with the
"draw_default" signal, which GTK+ automatically
emits whenever a widget gains or loses the default. GtkEv cannot be the default
widget, so it does not implement this signal.