Migration Checklist
This chapter includes a checklist of things you need to do to
ensure that your programs are good citizens in the GTK+ world. By
paying attention to the points in the checklist, you ensure that
many automatic features of GTK+ will work correctly in your
program.
Use GdkEventExpose.region
Why
The region field of
GdkEventExpose allows you to redraw
less than the traditional GdkEventRegion.area.
In early GTK+ versions, the GdkEventExpose
structure only had an area field to
let you determine the region that you needed to redraw. In current
GTK+, this field still exists for compatibility and as a simple
interface. However, there is also a region
field which contains a fine-grained region. The
area field is simply the bounding rectangle
of the region.
Widgets that are very expensive to re-render, such as an image
editor, may prefer to use the
GdkEventExpose.region field to paint
as little as possible. Widgets that just use a few drawing
primitives, such as labels and buttons, may prefer to use the
traditional GdkEventExpose.area field
for simplicity.
Regions have an internal representation that is accessible as a
list of rectangles. To turn the
GdkEventExpose.region field into such
a list, use gdk_region_get_rectangles():
static gboolean
my_widget_expose_event_handler (GtkWidget *widget, GdkEventExpose *event)
{
GdkRectangle *rects;
int n_rects;
int i;
gdk_region_get_rectangles (event->region, &rects, &n_rects);
for (i = 0; i < n_rects; i++)
{
/* Repaint rectangle: (rects[i].x, rects[i].y),
* (rects[i].width, rects[i].height)
*/
}
g_free (rects);
return FALSE;
}
Test for modifier keys correctly
Why
With gtk_accelerator_get_default_mod_mask() you can test for
modifier keys reliably; this way your key event handlers will
work correctly even if NumLock or
CapsLock are activated.
In a GdkEventKey, the
state field is a bit mask which
indicates the modifier state at the time the key was pressed.
Modifiers are keys like Control and
NumLock. When implementing a
#GtkWidget::key-press-event handler, you should use
gtk_accelerator_get_default_mod_mask() to
test against modifier keys. This function returns a bit mask
which encompasses all the modifiers which the user may be
actively pressing, such as Control,
Shift, and Alt, but ignores
"innocuous" modifiers such as NumLock and
CapsLock.
Say you want to see if
ControlF10
was pressed. Doing a simple test like
event->keysym == GDK_F10 &&
event->state == GDK_CONTROL_MASK is not
enough. If CapsLock is pressed, then
event->state will be equal to
GDK_CONTROL_MASK | GDK_LOCK_MASK, and the
simple test will fail. By taking the logical-and of
event->state and
gtk_accelerator_get_default_mod_mask(), you
can ignore the modifiers which are not actively pressed by the
user at the same time as the base key.
The following example correctly tests for
ControlF10
being pressed.
static gboolean
my_widget_key_press_event_handler (GtkWidget *widget, GdkEventKey *event)
{
guint modifiers;
modifiers = gtk_accelerator_get_default_mod_mask ();
if (event->keysym == GDK_F10
&& (event->state & modifiers) == GDK_CONTROL_MASK)
{
g_print ("Control-F10 was pressed\n");
return TRUE;
}
return FALSE;
}
Use named icons
Why
Named icons automatically adapt to theme changes, giving your
application a much more integrated appearance.
Named icons can be used for window icons (see gtk_window_set_icon_name())
and images (see gtk_image_set_icon_name()). You can also use named icons
for drag-and-drop (see gtk_drag_source_set_icon_name()) and in treeview
cells (see the #GtkCellRendererPixbuf:icon-name property).