2 <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
3 "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
5 <chapter id="gtk-migrating-checklist">
6 <title>Migration Details Checklist</title>
9 This chapter includes a checklist of smaller things you need to do to
10 ensure that your programs are good citizens in the GTK+ world. By
11 paying attention to the points in the checklist, you ensure that
12 many automatic features of GTK+ will work correctly in your
16 <section id="checklist-popup-menu">
17 <title>Implement GtkWidget::popup_menu</title>
22 By handling this signal, you let widgets have
23 context-sensitive menus that can be invoked with the standard
29 The #GtkWidget::popup-menu signal instructs the widget for which
30 it is emitted to create a context-sensitive popup menu. By default,
31 the <link linkend="gtk-bindings">key binding mechanism</link> is set to
32 emit this signal when the
33 <keycombo><keycap>Shift</keycap><keycap>F10</keycap></keycombo>
34 or <keycap>Menu</keycap> keys are pressed while a widget has the
35 focus. If a widget in your application shows a popup menu when
36 you press a mouse button, you can make it work as well through
37 the normal key binding mechanism in the following fahion:
43 Write a function to create and show a popup menu. This
44 function needs to know the button number and the event's
45 time to pass them to gtk_menu_popup(). You can implement
46 such a function like this:
49 <programlisting id="do_popup_menu">
51 do_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
54 int button, event_time;
56 menu = gtk_menu_new (<!-- -->);
57 g_signal_connect (menu, "deactivate",
58 G_CALLBACK (gtk_widget_destroy), NULL);
60 /* ... add menu items ... */
64 button = event->button;
65 event_time = event->time;
70 event_time = gtk_get_current_event_time (<!-- -->);
73 gtk_menu_attach_to_widget (GTK_MENU (menu), my_widget, NULL);
74 gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
82 In your #GtkWidget::button-press-event handler, call this function
83 when you need to pop up a menu:
88 my_widget_button_press_event_handler (GtkWidget *widget, GdkEventButton *event)
90 /* Ignore double-clicks and triple-clicks */
91 if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
93 do_popup_menu (widget, event);
104 Implement a handler for the #GtkWidget::popup-menu signal:
109 my_widget_popup_menu_handler (GtkWidget *widget)
111 do_popup_menu (widget, NULL);
120 If you do not pass a positioning function to gtk_menu_popup(),
121 it will show the menu at the mouse position by default. This
122 is what you usually want when the menu is shown as a result of
123 pressing a mouse button. However, if you press the
124 <keycombo><keycap>Shift</keycap><keycap>F10</keycap></keycombo>
125 or <keycap>Menu</keycap> keys while the widget is focused, the
126 mouse cursor may not be near the widget at all. In the <link
127 linkend="do_popup_menu">example above</link>, you may want to
128 provide your own <link
129 linkend="GtkMenuPositionFunc">menu-positioning function</link>
130 in the case where the <parameter>event</parameter> is
131 %NULL. This function should compute the desired position for
132 a menu when it is invoked through the keyboard. For example,
133 #GtkEntry aligns the top edge of its popup menu with the bottom
140 For the standard key bindings to work, your widget must be
141 able to take the keyboard focus. In general, widgets should
142 be fully usable through the keyboard and not just the mouse.
143 The very first step of this is to ensure that your widget
144 turns on the %GTK_CAN_FOCUS <link linkend="gtkwidgetflags">flag</link>.
149 <section id="checklist-gdkeventexpose-region">
150 <title>Use GdkEventExpose.region</title>
155 The <structfield>region</structfield> field of
156 <structname>GdkEventExpose</structname> allows you to redraw
157 less than the traditional <structfield>GdkEventRegion.area</structfield>.
162 In early GTK+ versions, the <structname>GdkEventExpose</structname>
163 structure only had an <structfield>area</structfield> field to
164 let you determine the region that you needed to redraw. In current
165 GTK+, this field still exists for compatibility and as a simple
166 interface. However, there is also a <structfield>region</structfield>
167 field which contains a fine-grained region. The
168 <structfield>area</structfield> field is simply the bounding rectangle
169 of the <structfield>region</structfield>.
173 Widgets that are very expensive to re-render, such as an image
174 editor, may prefer to use the
175 <structfield>GdkEventExpose.region</structfield> field to paint
176 as little as possible. Widgets that just use a few drawing
177 primitives, such as labels and buttons, may prefer to use the
178 traditional <structfield>GdkEventExpose.area</structfield> field
183 Regions have an internal representation that is accessible as a
184 list of rectangles. To turn the
185 <structfield>GdkEventExpose.region</structfield> field into such
186 a list, use gdk_region_get_rectangles():
189 <programlisting id="gdkregion-get-rectangles">
191 my_widget_expose_event_handler (GtkWidget *widget, GdkEventExpose *event)
197 gdk_region_get_rectangles (event->region, &rects, &n_rects);
199 for (i = 0; i < n_rects; i++)
201 /* Repaint rectangle: (rects[i].x, rects[i].y),
202 * (rects[i].width, rects[i].height)
213 <section id="checklist-modifiers">
214 <title>Test for modifier keys correctly</title>
219 With gtk_accelerator_get_default_mod_mask() you can test for
220 modifier keys reliably; this way your key event handlers will
221 work correctly even if <keycap>NumLock</keycap> or
222 <keycap>CapsLock</keycap> are activated.
227 In a <structname>GdkEventKey</structname>, the
228 <structfield>state</structfield> field is a bit mask which
229 indicates the modifier state at the time the key was pressed.
230 Modifiers are keys like <keycap>Control</keycap> and
231 <keycap>NumLock</keycap>. When implementing a
232 #GtkWidget::key-press-event handler, you should use
233 gtk_accelerator_get_default_mod_mask() to
234 test against modifier keys. This function returns a bit mask
235 which encompasses all the modifiers which the user may be
236 actively pressing, such as <keycap>Control</keycap>,
237 <keycap>Shift</keycap>, and <keycap>Alt</keycap>, but ignores
238 "innocuous" modifiers such as <keycap>NumLock</keycap> and
239 <keycap>CapsLock</keycap>.
243 Say you want to see if
244 <keycombo><keycap>Control</keycap><keycap>F10</keycap></keycombo>
245 was pressed. Doing a simple test like
246 <literal>event->keysym == GDK_F10 &&
247 event->state == GDK_CONTROL_MASK</literal> is not
248 enough. If <keycap>CapsLock</keycap> is pressed, then
249 <structfield>event->state</structfield> will be equal to
250 <literal>GDK_CONTROL_MASK | GDK_LOCK_MASK</literal>, and the
251 simple test will fail. By taking the logical-and of
252 <structfield>event->state</structfield> and
253 gtk_accelerator_get_default_mod_mask(), you
254 can ignore the modifiers which are not actively pressed by the
255 user at the same time as the base key.
259 The following example correctly tests for
260 <keycombo><keycap>Control</keycap><keycap>F10</keycap></keycombo>
264 <programlisting id="default-mod-mask">
266 my_widget_key_press_event_handler (GtkWidget *widget, GdkEventKey *event)
268 GdkModifierType modifiers;
270 modifiers = gtk_accelerator_get_default_mod_mask (<!-- -->);
272 if (event->keysym == GDK_F10
273 && (event->state & modifiers) == GDK_CONTROL_MASK)
275 g_print ("Control-F10 was pressed\n");
284 <section id="checklist-named-icons">
285 <title>Use named icons</title>
290 Named icons automatically adapt to theme changes, giving your
291 application a much more integrated appearance.
296 Named icons can be used for window icons (see gtk_window_set_icon_name())
297 and images (see gtk_image_set_icon_name()). You can also use named icons
298 for drag-and-drop (see gtk_drag_source_set_icon_name()) and in treeview
299 cells (see the #GtkCellRendererPixbuf:icon-name property).
307 sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")