1 <!doctype book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" []>
5 <date>June 28th 2000</date>
6 <title>GTK+ FAQ</title>
9 <firstname>Tony</firstname>
10 <surname>Gale</surname>
13 <firstname>Shawn</firstname>
14 <surname>Amundson</surname>
17 <firstname>Emmanuel</firstname>
18 <surname>Deloget</surname>
22 <para> This document is intended to answer questions that are
23 likely to be frequently asked by programmers using GTK+ or
24 people who are just looking at using GTK+. </para>
30 <!-- ***************************************************************** -->
32 <title>General Information</title>
33 <para>Here's a paragraph of text because it is stylistically poor
34 to start a section right after the chapter title.</para>
38 <!-- ----------------------------------------------------------------- -->
41 <title>Before anything else: the greetings</title>
42 <para>The FAQ authors want to thank:</para>
43 <itemizedlist spacing=Compact>
45 <simpara>Havoc Pennington</simpara>
48 <simpara>Erik Mouw</simpara>
51 <simpara>Owen Taylor</simpara>
54 <simpara>Tim Janik</simpara>
57 <simpara>Thomas Mailund Jensen</simpara>
60 <simpara>Joe Pfeiffer</simpara>
63 <simpara>Andy Kahn</simpara>
66 <simpara>Federico Mena Quntero</simpara>
69 <simpara>Damon Chaplin</simpara>
72 <simpara>and all the members of the GTK+ lists</simpara>
73 </listitem></itemizedlist>
74 <para> If we forgot you, please email us! Thanks again (I know,
75 it's really short :) </para>
78 <!-- ----------------------------------------------------------------- -->
81 <title>Authors</title>
82 <para>The original authors of GTK+ were:</para>
83 <itemizedlist spacing=Compact>
85 <simpara>Peter Mattis</simpara>
88 <simpara>Spencer Kimball</simpara>
91 <simpara>Josh MacDonald</simpara>
94 <para>Since then, much has been added by others. Please see the
95 AUTHORS file in the distribution for the GTK+ Team.</para>
98 <!-- ----------------------------------------------------------------- -->
101 <title>What is GTK+?</title>
102 <para>GTK+ is a small and efficient widget set designed with
103 the general look and feel of Motif. In reality, it looks much
104 better than Motif. It contains common widgets and some more
105 complex widgets such as a file selection, and color selection
107 <para>GTK+ provides some unique features. (At least, I know of
108 no other widget library which provides them). For example, a
109 button does not contain a label, it contains a child widget,
110 which in most instances will be a label. However, the child
111 widget can also be a pixmap, image or any combination possible
112 the programmer desires. This flexibility is adhered to
113 throughout the library.</para>
116 <!-- ----------------------------------------------------------------- -->
119 <title>What is the + in GTK+?</title>
120 <para>Peter Mattis informed the gtk mailing list that:</para>
121 <para><quote>I originally wrote gtk which included the three
122 libraries, libglib, libgdk and libgtk. It featured a flat
123 widget hierarchy. That is, you couldn't derive a new widget
124 from an existing one. And it contained a more standard
125 callback mechanism instead of the signal mechanism now present
126 in gtk+. The + was added to distinguish between the original
127 version of gtk and the new version. You can think of it as
128 being an enhancement to the original gtk that adds object
129 oriented features.</quote></para>
132 <!-- ----------------------------------------------------------------- -->
135 <title>Does the G in GTK+, GDK and GLib stand for?</title>
136 <para>GTK+ == Gimp Toolkit</para>
137 <para>GDK == GTK+ Drawing Kit</para>
138 <para>GLib == G Libray</para>
141 <!-- ----------------------------------------------------------------- -->
144 <title>Where is the documentation for GTK+?</title>
145 <para>In the GTK+ distribution's doc/ directory you will find
146 the reference material for both GTK and GDK, this FAQ and the
148 <para>In addition, you can find links to HTML versions of
149 these documents by going to <ulink url="http://www.gtk.org/">
150 http://www.gtk.org/</ulink>. A
151 packaged version of the GTK Tutorial, with SGML, HTML,
152 Postscript, DVI and text versions can be found in <ulink
153 url="ftp://ftp.gtk.org/pub/gtk/tutorial">ftp://ftp.gtk.org/pub/gtk/tutorial
155 <para>There are now a couple of books available that deal with
156 programming GTK+, GDK and GNOME:</para>
158 <listitem><simpara>Eric Harlows book entitled "Developing
159 Linux Applications with GTK+ and GDK". The ISBN is 0-7357-0021-4</simpara>
161 <listitem><simpara>The example code from Eric's book is
162 available on-line at <ulink
163 url="http://www.bcpl.net/~eharlow/book">
164 http://www.bcpl.net/~eharlow/book</ulink></simpara>
166 <listitem><simpara>Havoc Pennington has released a book called
167 "GTK+/GNOME Application Development". The ISBN is 0-7357-0078-8</simpara>
168 <simpara>The free version of the book lives here: <ulink
169 url="http://developer.gnome.org/doc/GGAD/">http://developer.gnome.org/doc/GGAD/
171 <simpara>And Havoc maintains information about it and
173 url="http://pobox.com/~hp/gnome-app-devel.html">http://pobox.com/~hp/gnome-app-devel.html
179 <!-- ----------------------------------------------------------------- -->
182 <title>Is there a mailing list (or mailing list archive) for
184 <para>Information on mailing lists relating to GTK+ can be
186 url="http://www.gtk.org/mailinglists.html">http://www.gtk.org/mailinglists.html
190 <!-- ----------------------------------------------------------------- -->
193 <title>How to get help with GTK+</title>
194 <para>First, make sure your question isn't answered in the
195 documentation, this FAQ or the tutorial. Done that? You're
196 sure you've done that, right? In that case, the best place to
197 post questions is to the GTK+ mailing list.</para>
200 <!-- ----------------------------------------------------------------- -->
203 <title>How to report bugs in GTK+</title>
204 <para>Bugs should be reported to the GNOME bug tracking system
206 url="http://bugs.gnome.org">http://bugs.gnome.org</ulink>). To
207 report a problem about GTK+, send mail to submit@bugs.gnome.org.</para>
208 <para>The subject of the mail should describe your problem. In
209 the body of the mail, you should first include a
210 "pseudo-header" that gives the package and version
211 number. This should be separated by a blank line from the
212 actual headers.</para>
214 <para><literallayout><literal>Package: gtk+</literal>
215 <literal>Version: 1.2.0</literal></literallayout></para>
217 <para>Substitute 1.2.0 with the version of GTK+ that you have installed.</para>
218 <para>Then describe the bug. Include:</para>
221 <listitem><simpara> Information about your system. For instance:</simpara>
222 <itemizedlist spacing=compact>
223 <listitem><simpara> What operating system and version</simpara>
225 <listitem><simpara> What version of X</simpara>
227 <listitem><simpara> For Linux, what version of the C library</simpara>
230 <para>And anything else you think is relevant.</para>
232 <listitem><simpara> How to reproduce the bug.</simpara>
233 <simpara>If you can reproduce it with the testgtk program
234 that is built in the gtk/ subdirectory, that will be most
235 convenient. Otherwise, please include a short test program
236 that exhibits the behavior. As a last resort, you can also
237 provide a pointer to a larger piece of software that can
238 be downloaded.</simpara>
239 <simpara>(Bugs that can be reproduced within the GIMP are
240 almost as good as bugs that can be reproduced in
241 testgtk. If you are reporting a bug found with the GIMP,
242 please include the version number of the GIMP you are
245 <listitem><simpara> If the bug was a crash, the exact text that was
246 printed out when the crash occured.</simpara>
248 <listitem><simpara> Further information such as stack traces
249 may be useful, but are not necessary. If you do send a stack trace,
250 and the error is an X error, it will be more useful if the stacktrace is produced running
251 the test program with the <literal>--sync</literal> command line option.</simpara>
256 <!-- ----------------------------------------------------------------- -->
259 <title>Is there a Windows version of GTK+?</title>
260 <para>There is an on going port of GTK+ to the Windows
261 platform which is making impressive progress.</para>
263 url="http://www.iki.fi/tml/gimp/win32">http://www.iki.fi/tml/gimp/win32</ulink>
264 for more information.</para>
267 <!-- ----------------------------------------------------------------- -->
270 <title>What applications have been written with GTK+?</title>
271 <para>A list of some GTK+ based application can be found on
272 the GTK+ web server at <ulink
273 url="http://www.gtk.org/apps/">http://www.gtk.org/apps/</ulink>
274 and contains more than 350 applications.</para>
275 <para>Failing that, look for a project to work on for the
276 GNOME project, <ulink
277 url="http://www.gnome.org/">http://www.gnome.org/</ulink>
278 Write a game. Write something that is useful.</para>
279 <para>Some of these are:</para>
282 <listitem><simpara> GIMP (<ulink
283 url="http://www.gimp.org/">http://www.gimp.org/</ulink>), an
284 image manipulation program</simpara>
286 <listitem><simpara> AbiWord (<ulink
287 url="http://www.abisource.com/">http://www.abisource.com/</ulink>),
288 a professional word processor</simpara>
290 <listitem><simpara> Gzilla (<ulink
291 url="http://www.levien.com/gzilla/">http://www.levien.com/gzilla/</ulink>),
292 a web browser</simpara>
294 <listitem><simpara> XQF (<ulink
295 url="http://www.botik.ru/~roma/quake/">http://www.botik.ru/~roma/quake/</ulink>),
296 a QuakeWorld/Quake2 server browser and launcher</simpara>
298 <listitem><simpara> GDK Imlib (<ulink
299 url="http://www.rasterman.com/imlib.html">http://www.rasterman.com/imlib.html</ulink>),
300 a fast image loading and manipulation library for GDK</simpara>
302 <listitem><simpara> Glade (<ulink
303 url="http://glade.pn.org/">http://glade.pn.org/</ulink>), a
304 GTK+ based RAD tool which produces GTK+ applications</simpara>
309 <!-- ----------------------------------------------------------------- -->
312 <title>I'm looking for an application to write in GTK+. How
313 about an IRC client?</title>
314 <para>Ask on gtk-list for suggestions. There are at least
315 three IRC clients already under development (probably more in fact. The server at
316 <ulink url="http://www.forcix.cx/irc-clients.html">
317 http://www.forcix.cx/irc-clients.html</ulink> list a bunch of them).</para>
319 <itemizedlist spacing=compact>
320 <listitem><simpara> X-Chat.</simpara>
322 <listitem><simpara> girc. (Included with GNOME)</simpara>
324 <listitem><simpara> gsirc. (In the gnome CVS tree)</simpara>
331 <!-- ***************************************************************** -->
333 <title>How to find, configure, install, and troubleshoot GTK+</title>
337 <!-- ----------------------------------------------------------------- -->
340 <title>What do I need to run GTK+?</title>
341 <para>To compile GTK+, all you need is a C compiler (gcc) and
342 the X Window System and associated libraries on your system.</para>
345 <!-- ----------------------------------------------------------------- -->
348 <title>Where can I get GTK+?</title>
349 <para>The canonical site is <ulink
350 url="ftp://ftp.gtk.org/pub/gtk">ftp://ftp.gtk.org/pub/gtk</ulink>.</para>
351 <para>This site tends to get busy around the time of a new
352 GTK+ release so try and use one of the mirror sites that are
354 url="ftp://ftp.gtk.org/etc/mirrors">ftp://ftp.gtk.org/etc/mirrors</ulink></para>
355 <para>Here's a few mirror sites to get you started:</para>
357 <itemizedlist spacing=compact>
358 <listitem><simpara> Africa - ftp://ftp.is.co.za/applications/gimp/</simpara>
360 <listitem><simpara> Australia - ftp://ftp.au.gimp.org/pub/gimp/</simpara>
362 <listitem><simpara> Finland - ftp://ftp.funet.fi/pub/sci/graphics/packages/gimp</simpara>
364 <listitem><simpara> Germany - ftp://infosoc.uni-koeln.de/pub/ftp.gimp.org/</simpara>
366 <listitem><simpara> Japan - ftp://SunSITE.sut.ac.jp/pub/archives/packages/gimp/</simpara>
368 <listitem><simpara> UK - ftp://ftp.flirble.org/pub/X/gimp/</simpara>
370 <listitem><simpara> US - ftp://ftp.insync.net/pub/mirrors/ftp.gimp.org/</simpara>
375 <!-- ----------------------------------------------------------------- -->
378 <title>How do I configure/compile GTK+?</title>
379 <para>Generally, all you will need to do is issue the commands:</para>
381 <para><literallayout><literal>./configure</literal>
382 <literal>make</literal></literallayout></para>
384 <para>in the gtk+-version/ directory.</para>
387 <!-- ----------------------------------------------------------------- -->
390 <title>When compiling GTK+ I get an error like: <literal>make:
391 file `Makefile' line 456: Syntax error</literal></title>
392 <para>Make sure that you are using GNU make (use <literal>make
394 to check). There are many weird and wonderful versions of make
395 out there, and not all of them handle the automatically
396 generated Makefiles.</para>
399 <!-- ----------------------------------------------------------------- -->
402 <title>I've compiled and installed GTK+, but I can't get any
403 programs to link with it!</title>
404 <para>This problem is most often encountered when the GTK+
405 libraries can't be found or are the wrong version. Generally,
406 the compiler will complain about an 'unresolved symbol'.
407 There are two things you need to check:</para>
410 <listitem><simpara>Make sure that the libraries can be
411 found. You want to edit <filename>/etc/ld.so.conf</filename> to
412 include the directories which contain the GTK libraries,
413 so it looks something like:</simpara>
414 <para><literallayout><literal>/usr/X11R6/lib</literal>
415 <literal>/usr/local/lib</literal></literallayout></para>
417 <para>Then you need to run /sbin/ldconfig as root. You can
418 find what directory GTK is in using</para>
420 <para><literallayout><literal>gtk-config --libs</literal>
421 </literallayout></para>
423 <para>If your system doesn't use ld.so to find libraries
424 (such as Solaris), then you will have to use the LD_LIBRARY_PATH
425 environment variable (or compile the path into your program, which I'm
426 not going to cover here). So, with a Bourne type shell you can do (if
427 your GTK libraries are in /usr/local/lib):</para>
429 <para><literallayout><literal>export LD_LIBRARY_PATH=/usr/local/lib</literal></literallayout></para>
431 <para>and in a csh, you can do:</para>
433 <para><literallayout><literal>setenv LD_LIBRARY_PATH /usr/local/lib</literal></literallayout></para>
436 <listitem><simpara>Make sure the linker is finding the
437 correct set of libraries. If you have a Linux distribution that
438 installs GTK+ (e.g. RedHat 5.0) then this older version may be
439 used. Now (assuming you have a RedHat system), issue the
442 <para><literallayout><literal>rpm -e gtk gtk-devel</literal></literallayout></para>
444 <para>You may also want to remove the packages that depend
445 on gtk (rpm will tell you which ones they are). If you don't have a RedHat Linux system, check to make sure
446 that neither <filename>/usr/lib</filename> or <filename>/usr/local/lib</filename> contain any of
447 the libraries libgtk, libgdk, libglib, or libgck. If they do exist, remove them
448 (and any gtk include files, such as <filename>/usr/include/gtk</filename> and <filename>/usr/include/gdk</filename>)
449 and reinstall gtk+.</para>
455 <!-- ----------------------------------------------------------------- -->
458 <title>When compiling programs with GTK+, I get compiler error
459 messages about not being able to find
460 <literal>glibconfig.h</literal>.</title>
461 <para>The header file "glibconfig.h" was moved to the
462 directory $exec_prefix/lib/glib/include/. $exec_prefix is the
463 directory that was specified by giving the --exec-prefix flags
464 to ./configure when compiling GTK+. It defaults to $prefix,
465 (specified with --prefix), which in turn defaults to /usr/local/.</para>
467 <para>This was done because "glibconfig.h" includes
468 architecture dependent information, and the rest of the
469 include files are put in $prefix/include, which can be shared
470 between different architectures.</para>
472 <para>GTK+ includes a shell script, <literal>/gtk-config/</literal>, that makes it
473 easy to find out the correct include paths. The GTK+ Tutorial
474 includes an example of using <literal>/gtk-config/</literal> for simple
475 compilation from the command line. For information about more
476 complicated configuration, see the file docs/gtk-config.txt in
477 the GTK+ distribution.</para>
479 <para>If you are trying to compile an old program, you may be
480 able to work around the problem by configuring it with a
481 command line like:</para>
483 <para><literallayout><literal>setenv CPPFLAGS "-I/usr/local/include/glib/include"</literal>
484 <literal>./configure</literal></literallayout></para>
486 <para>(Substitute the appropriate value of $exec_prefix for
490 <!-- ----------------------------------------------------------------- -->
493 <title>When installing a GTK+ application, configure reports
494 that it can't find GTK.</title>
495 <para>There are several common reasons for this:</para>
497 <listitem><simpara>You have an old version of GTK installed
498 somewhere. RedHat 5.0, for example, installs an older copy of GTK that
499 may not work with the latest applications. You should remove this old
500 copy, but note that in the case of RedHat 5.0 this will
501 break the <literal>control-panel</literal> applications.</simpara>
503 <listitem><simpara><literal>gtk-config</literal> (or another
504 component of GTK) isn't in your path, or there is an old
505 version on your system. Type:</simpara>
506 <para><literallayout><literal>gtk-config --version</literal></literallayout></para>
508 <para>to check for both of these. If it returns a value
509 different from what you expect, then you have an old
510 version of GTK on your system.</para>
512 <listitem><simpara>The ./configure script can't find the GTK
513 libraries. As ./configure compiles various test programs, it needs to
514 be able to find the GTK libraries. See the question above
515 for help on this. </simpara></listitem>
518 <para>If none of the above help, then have a look in
519 config.log, which is generated by ./configure as it runs. At the
520 bottom will be the last action it took before failing. If it is a
521 section of source code, copy the source code to a file and compile it
522 with the line just above it in config.log. If the compilation is
523 successful, try executing it.</para>
529 <!-- ***************************************************************** -->
531 <title>Development of GTK+</title>
535 <!-- ----------------------------------------------------------------- -->
538 <title>Whats this CVS thing that everyone keeps talking about,
539 and how do I access it?</title>
540 <para>CVS is the Concurent Version System and is a very
541 popular means of version control for software projects. It is
542 designed to allow multiple authors to be able to
543 simultanously operate on the same source tree. This source
544 tree is centrally maintained, but each developer has a local
545 mirror of this repository that they make there changes to.</para>
546 <para>The GTK+ developers use a CVS repository to store the
547 master copy of the current development version of GTK+. As
548 such, people wishing to contribute patches to GTK+ should
549 generate them against the CVS version. Normal people should
550 use the packaged releases.</para>
551 <para>The CVS toolset is available as RPM packages from the
552 usual RedHat sites. The latest version is available at <ulink
553 url="http://download.cyclic.com/pub/">http://download.cyclic.com/pub/
555 <para>Anyone can download the latest CVS version of GTK+ by
556 using anonymous access using the following steps:</para>
558 <listitem><simpara> In a bourne shell descendant (e.g. bash) type:</simpara>
559 <para><literallayout><literal>CVSROOT=':pserver:anonymous@anoncvs.gnome.org:/cvs/gnome'</literal>
560 <literal>export CVSROOT</literal></literallayout></para>
562 <listitem><simpara>Next, the first time the source tree is
563 checked out, a cvs login is needed. </simpara>
564 <para><literallayout><literal>cvs login</literal></literallayout></para>
565 <para>This will ask you for a password. There is no
566 password for cvs.gimp.org, so just enter a carriage return.</para>
568 <listitem><simpara>To get the tree and place it in a subdir of your
569 current working directory, issue the command:</simpara>
570 <para><literallayout><literal>cvs -z3 get gtk+</literal></literallayout></para>
571 <para>Note that with the GTK+ 1.1 tree, glib has been moved to
572 a separate CVS module, so if you don't have glib installed you will
573 need to get that as well:</para>
574 <para><literallayout><literal>cvs -z3 get glib</literal></literallayout></para>
579 <!-- ----------------------------------------------------------------- -->
582 <title>How can I contribute to GTK+?</title>
583 <para>It's simple. If something doesn't work like you think it
584 should in a program, check the documentation to make sure
585 you're not missing something. If it is a true bug or missing
586 feature, track it down in the GTK+ source, change it, and
587 then generate a patch in the form of a 'context diff'. This
588 can be done using a command such as <literal>diff -ru
589 <oldfile> <newfile>.</literal> Then upload the patchfile to:</para>
590 <para><literallayout><literal>ftp://ftp.gtk.org/incoming</literal></literallayout></para>
591 <para>along with a README file. Make sure you follow the
592 naming conventions or your patch will just be deleted! The
593 filenames should be of this form:</para>
594 <para><literallayout><literal>gtk<username>-<date yymmdd-n>.patch.gz</literal>
595 <literal>gtk-<username>-<date yymmdd-n>.patch.README</literal></literallayout></para>
596 <para>The "n" in the date indicates a unique number (starting
597 from 0) of patches you uploaded that day. It should be 0,
598 unless you upload more than one patch in the same day.</para>
600 <para>Example:</para>
601 <para><literallayout><literal>gtk-gale-982701-0.patch.gz</literal>
602 <literal>gtk-gale-982701-0.patch.README</literal></literallayout></para>
603 <para>Once you upload <emphasis>anything</emphasis>, send the README to ftp-admin@gtk.org</para>
606 <!-- ----------------------------------------------------------------- -->
609 <title>How do I know if my patch got applied, and if not, why
611 <para>Uploaded patches will be moved to
612 <filename>ftp://ftp.gtk.org/pub/gtk/patches</filename> where one of the
613 GTK+ development team will pick them up. If applied, they will
614 be moved to <filename>/pub/gtk/patches/old</filename>.</para>
615 <para>Patches that aren't applied, for whatever reason, are
616 moved to <filename>/pub/gtk/patches/unapplied</filename> or
617 <filename>/pub/gtk/patches/outdated</filename>. At this point you can ask
618 on the <literal>gtk-list</literal> mailing list why your patch wasn't
619 applied. There are many possible reasons why patches may not
620 be applied, ranging from it doesn't apply cleanly, to it isn't
621 right. Don't be put off if your patch didn't make it first
625 <!-- ----------------------------------------------------------------- -->
628 <title>What is the policy on incorporating new widgets into
630 <para>This is up to the authors, so you will have to ask them
631 once you are done with your widget. As a general guideline,
632 widgets that are generally useful, work, and are not a
633 disgrace to the widget set will gladly be included.</para>
636 <!-- ----------------------------------------------------------------- -->
639 <title>Is anyone working on bindings for languages other than
641 <para>The GTK+ home page (<ulink
642 url="http://www.gtk.org/">http://www.gtk.org/</ulink>)
643 presents a list of GTK+ bindings.</para>
645 <listitem><simpara>There are several C++ wrappers for GTK+.</simpara>
647 <listitem><simpara>the gtk-- package, which is a very small wrapper for GTK+.
648 You can find the home page at <ulink
649 url="http://www.cs.tut.fi/~p150650/gtk/gtk--.html">
650 http://www.cs.tut.fi/~p150650/gtk/gtk--.html</ulink>. The FTP site is
651 <ulink url="ftp://ftp.gtk.org/pub/gtk/gtk--">
652 ftp://ftp.gtk.org/pub/gtk/gtk--</ulink>.</simpara>
654 <listitem><simpara>the VDK package, which was built as
655 the base package of a GTK+ application Borland-like
656 builder. The home page can be found at <ulink
657 url="http://www.guest.net/homepages/mmotta/VDKHome">
658 http://www.guest.net/homepages/mmotta/VDKHome</ulink>.</simpara>
661 <listitem><simpara>The wxWindows/Gtk package, a free C++ library for cross-platform
662 GUI development. The home page of this package is
663 <ulink url="http://www.freiburg.linux.de/~wxxt/">
664 http://www.freiburg.linux.de/~wxxt/</ulink>.</simpara>
668 <listitem><simpara>There are three known Objective-c
669 bindings currently in development:</simpara>
671 <listitem><simpara>The <ulink
672 url="http://www.gnome.org/">http://www.gnome.org/</ulink>
673 package of choice is objgtk. Objgtk is based on the Object class and is maintained by
674 <ulink url="mailto:sopwith@cuc.edu">Elliot Lee</ulink>. Apparently,
675 objgtk is being accepted as the `standard' Objective-C binding for GTK+.</simpara>
678 <listitem><simpara>If you are more inclined towards the
679 <ulink url="http://www.gnustep.org/">GNUstep project</ulink>,
680 you may want to check out GTKKit by
681 <ulink url="mailto:helge@mdlink.de">Helge Heß</ulink>.
682 The intention is to setup a GTK+ binding using the FoundationKit.
683 GTKKit includes nicities like writing a XML-type template file to
684 construct a GTK+ interface.</simpara>
687 <listitem><simpara>The GToolKit package, which can be found at
688 <ulink url="ftp://ftp.gtk.org/pub/gtk/objc-gtoolkit/">
689 ftp://ftp.gtk.org/pub/gtk/objc-gtoolkit/</ulink>.</simpara>
693 <listitem><simpara>Perl bindings <ulink
694 url="ftp://ftp.gtk.org/pub/gtk/perl">ftp://ftp.gtk.org/pub/gtk/perl</ulink></simpara>
696 <listitem><simpara>Guile bindings. The home page is at
697 <ulink url="http://www.ping.de/sites/zagadka/guile-gtk">http://www.ping.de/sites/zagadka/guile-gtk</ulink>.
698 By the way, Guile is the GNU Project's implemention of R4RS Scheme (the
699 standard). If you like Scheme, you may want to take a look at this.</simpara>
701 <listitem><simpara>David Monniaux reports:
702 <quote>I've started a gtk-O'Caml binding system.
703 The basics of the system, including callbacks, work fine.
705 The current development is in
706 <ulink url="http://www.ens-lyon.fr/~dmonniau/arcs">http://www.ens-lyon.fr/~dmonniau/arcs</ulink>
709 <listitem><simpara>Several python bindings have been done:</simpara>
711 <listitem><simpara>pygtk is at
712 <ulink url="http://www.daa.com.au/~james/pygtk">http://www.daa.com.au/~james/pygtk</ulink> and
713 <ulink url="ftp://ftp.gtk.org/pub/gtk/python">ftp://ftp.gtk.org/pub/gtk/python</ulink></simpara>
716 <listitem><simpara>python-gtk is at
717 <ulink url="http://www.ucalgary.ca/~nascheme/python-gtk">http://www.ucalgary.ca/~nascheme/python-gtk</ulink></simpara>
721 <listitem><simpara>There's are a couple of OpenGL/Mesa
722 widgets available for GTK+. I suggest you start at
723 <ulink url="http://www.student.oulu.fi/~jlof/gtkglarea/index.html">http://www.student.oulu.fi/~jlof/gtkglarea/index.html</ulink></simpara>
725 <listitem><simpara>Last, there are a lot of other language
726 bindings for languages such as Eiffel, TOM, Pascal, Pike, etc.</simpara>
734 <!-- ***************************************************************** -->
736 <title>Development with GTK+: the begining</title>
740 <!-- ----------------------------------------------------------------- -->
743 <title>How do I get started?</title>
744 <para>So, after you have installed GTK+ there are a couple of
745 things that can ease you into developing applications with
746 it. There is the GTK+ Tutorial <ulink
747 url="http://www.gtk.org/tutorial/">
748 http://www.gtk.org/tutorial/</ulink>, which is undergoing
749 development. This will introduce you to writing applications
752 <para>The Tutorial doesn't (yet) contain information on all of
753 the widgets that are in GTK+. For example code on how to use
754 the basics of all the GTK+ widgets you should look at the file
755 gtk/testgtk.c (and associated source files) within the GTK+
756 distribution. Looking at these examples will give you a good
757 grounding on what the widgets can do.</para>
760 <!-- ----------------------------------------------------------------- -->
763 <title>I tried to compile a small <command>Hello World</command> of mine,
764 but it failed. Any clue?</title>
765 <para>Since you are good at coding, we will not deal with
766 compile time error here :)</para>
768 <para>The classic command line to compile a GTK+ based program is</para>
769 <para><literallayout><literal>gcc -o myprog [c files list] `gtk-config --cflags --libs`</literal></literallayout></para>
771 <para>You should notice the backquote character which is used
772 in this command line. A common mistake when you start a GTK+
773 based development is to use quote instead of backquotes. If
774 you do so, the compiler will complain about an unknown file
775 called <filename>gtk-config --cflags --libs</filename>. The
776 text in backquotes is an instruction to your shell to
777 substitute the output of executing this text into the
780 <para>The command line above ensure that:</para>
783 <listitem><simpara>the correct C compiler flags will be used
784 to compile the program (including the complete C header
785 directory list)</simpara>
788 <listitem><simpara>your program will be linked with the
789 needed libraries.</simpara>
794 <!-- ----------------------------------------------------------------- -->
797 <title>What about using the <command>make</command>
800 <para>This is a sample makefile which compile a GTK+ based
802 <programlisting role="C">
803 # basic GTK+ app makefile
804 SOURCES = myprg.c foo.c bar.c
805 OBJS = ${SOURCES:.c=.o}
806 CFLAGS = `gtk-config --cflags`
807 LDADD = `gtk-config --libs`
812 ${CC} -o ${PACKAGE} ${OBJS} ${LDADD}
815 ${CC} ${CFLAGS} -c $<
820 <para>For more information about the <command>make</command> utility, you
821 should read either the related man page or the relevant info file.</para>
824 <!-- ----------------------------------------------------------------- -->
827 <title>I use the backquote stuff in my makefiles, but my make
828 process failed.</title>
830 <para>The backquote construction seems to not be accepted by
831 some old <command>make</command> utilities. If you use one of these, the
832 make process will probably fail. In order to have the
833 backquote syntax working again, you should use the GNU make
834 utility (get it on the GNU ftp server at <ulink
835 url="ftp://ftp.gnu.org/">ftp://ftp.gnu.org/"</ulink>).</para>
838 <!-- ----------------------------------------------------------------- -->
841 <title>I want to add some configure stuff, how could I do
844 <para>To use autoconf/automake, you must first install the
845 relevant packages. These are:</para>
847 <itemizedlist spacing=Compact>
848 <listitem><simpara>the m4 preprocessor v1.4 or better</simpara>
850 <listitem><simpara>autoconf v2.13 or better</simpara>
852 <listitem><simpara>automake v1.4 or better</simpara>
856 <para>You'll find these packages on the GNU main ftp server
857 (<ulink url="ftp://ftp.gnu.org/">ftp://ftp.gnu.org/</ulink>)
858 or on any GNU mirror.</para>
860 <para>In order to use the powerful autoconf/automake scheme,
861 you must create a configure.in which may look like:</para>
863 <programlisting role="C">
864 dnl Process this file with autoconf to produce a configure script.
865 dnl configure.in for a GTK+ based program
868 AM_INIT_AUTOMAKE(mypkgname,0.0.1)dnl
869 AM_CONFIG_HEADER(config.h)dnl
871 dnl Checks for programs.
872 AC_PROG_CC dnl check for the c compiler
873 dnl you should add CFLAGS="" here, 'cos it is set to -g by PROG_CC
875 dnl Checks for libraries.
876 AM_PATH_GTK(1.2.0,,AC_MSG_ERROR(mypkgname 0.1 needs GTK))dnl
883 <para>You must add a Makefile.am file:</para>
885 <programlisting role="C">
887 myprg_SOURCES = myprg.c foo.c bar.c
888 INCLUDES = @GTK_CFLAGS@
891 DISTCLEANFILES = .deps/*.P
894 <para>If your project contains more than one subdirectory,
895 you'll have to create one Makefile.am in each directory plus a
896 master Makefile.am which will look like:</para>
898 <programlisting role="C">
899 SUBDIRS = mydir1 mydir2 mydir3
902 <para>then, to use these, simply type the following
905 <programlisting role="C">
909 automake --add-missing --include-deps --foreign
912 <para>For further information, you should look at the autoconf
913 and the automake documentation (the shipped info files are
914 really easy to understand, and there are plenty of web
915 resources that deal with autoconf and automake).</para>
918 <!-- ----------------------------------------------------------------- -->
921 <title>I try to debug my GTK+ application with gdb, but it
922 hangs my X server when I hit some breakpoint. Any
925 <para>From Federico Mena Quintero:
926 <quote>X is not locked up. It is likely that you are hitting a breakpoint
927 inside a callback that is called from a place in Gtk that has a mouse grab.
929 Run your program with the <literal>--sync</literal>
930 option; it will make it easier to debug. Also, you may want to
931 use the console for running the debugger, and just let the
932 program run in another console with the X server.</quote></para>
934 <para>Eric Mouw had another solution:
935 <quote>An old terminal connected to an otherwise unused serial
936 port is also great for debugging X programs. Old vt100/vt220
937 terminals are dirt cheap but a bit hard to get (here in The
938 Netherlands, YMMV).</quote></para>
943 <!-- ***************************************************************** -->
945 <title>Development with GTK+: general questions</title>
949 <!-- ----------------------------------------------------------------- -->
952 <title>What widgets are in GTK?</title>
954 <para>The GTK+ Tutorial lists the following widgets:</para>
955 <programlisting role="C">
966 | | | `GtkAspectFrame
971 | | | | `GtkCheckMenuItem
972 | | | | `GtkRadioMenuItem
976 | | +GtkColorSelectionDialog
978 | | | `GtkInputDialog
979 | | `GtkFileSelection
988 | | +GtkColorSelection
1006 | +GtkScrolledWindow
1040 <!-- ----------------------------------------------------------------- -->
1043 <title>Is GTK+ thread safe? How do I write multi-threaded GTK+
1044 applications?</title>
1046 <para>The GLib library can be used in a thread-safe mode by
1047 calling g_thread_init() before making any other GLib
1048 calls. In this mode GLib automatically locks all internal
1049 data structures as needed. This does not mean that two
1050 threads can simultaneously access, for example, a single hash
1051 table, but they can access two different hash tables
1052 simultaneously. If two different threads need to access the
1053 same hash table, the application is responsible for locking
1056 <para>When GLib is intialized to be thread-safe, GTK+ is
1057 <emphasis>thread aware</emphasis>. There is a single global
1058 lock that you must acquire with gdk_threads_enter() before
1059 making any GDK calls, and release with gdk_threads_leave()
1062 <para>A minimal main program for a threaded GTK+ application
1065 <programlisting role="C">
1067 main (int argc, char *argv[])
1071 g_thread_init(NULL);
1072 gtk_init(&argc, &argv);
1074 window = create_window();
1075 gtk_widget_show(window);
1077 gdk_threads_enter();
1079 gdk_threads_leave();
1085 <para>Callbacks require a bit of attention. Callbacks from
1086 GTK+ (signals) are made within the GTK+ lock. However
1087 callbacks from GLib (timeouts, IO callbacks, and idle
1088 functions) are made outside of the GTK+ lock. So, within a
1089 signal handler you do not need to call gdk_threads_enter(),
1090 but within the other types of callbacks, you do.</para>
1092 <para>Erik Mouw contributed the following code example to
1093 illustrate how to use threads within GTK+ programs.</para>
1095 <programlisting role="C">
1096 /*-------------------------------------------------------------------------
1097 * Filename: gtk-thread.c
1099 * Copyright: Copyright (C) 1999, Erik Mouw
1100 * Author: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
1101 * Description: GTK threads example.
1102 * Created at: Sun Oct 17 21:27:09 1999
1103 * Modified by: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
1104 * Modified at: Sun Oct 24 17:21:41 1999
1105 *-----------------------------------------------------------------------*/
1109 * cc -o gtk-thread gtk-thread.c `gtk-config --cflags --libs gthread`
1111 * Thanks to Sebastian Wilhelmi and Owen Taylor for pointing out some
1116 #include <stdio.h>
1117 #include <stdlib.h>
1118 #include <unistd.h>
1119 #include <time.h>
1120 #include <gtk/gtk.h>
1121 #include <glib.h>
1122 #include <pthread.h>
1124 #define YES_IT_IS (1)
1125 #define NO_IT_IS_NOT (0)
1133 G_LOCK_DEFINE_STATIC (yes_or_no);
1134 static volatile int yes_or_no = YES_IT_IS;
1136 void destroy(GtkWidget *widget, gpointer data)
1141 void *argument_thread(void *args)
1143 yes_or_no_args *data = (yes_or_no_args *)args;
1144 gboolean say_something;
1149 sleep(rand() / (RAND_MAX / 3) + 1);
1151 /* lock the yes_or_no_variable */
1154 /* do we have to say something? */
1155 say_something = (yes_or_no != data->what);
1159 /* set the variable */
1160 yes_or_no = data->what;
1163 /* Unlock the yes_or_no variable */
1164 G_UNLOCK(yes_or_no);
1168 /* get GTK thread lock */
1169 gdk_threads_enter();
1171 /* set label text */
1172 if(data->what == YES_IT_IS)
1173 gtk_label_set_text(GTK_LABEL(data->label), "O yes, it is!");
1175 gtk_label_set_text(GTK_LABEL(data->label), "O no, it isn't!");
1177 /* release GTK thread lock */
1178 gdk_threads_leave();
1185 int main(int argc, char *argv[])
1189 yes_or_no_args yes_args, no_args;
1190 pthread_t no_tid, yes_tid;
1193 g_thread_init(NULL);
1196 gtk_init(&argc, &argv);
1198 /* init random number generator */
1199 srand((unsigned int)time(NULL));
1201 /* create a window */
1202 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1204 gtk_signal_connect(GTK_OBJECT (window), "destroy",
1205 GTK_SIGNAL_FUNC(destroy), NULL);
1207 gtk_container_set_border_width(GTK_CONTAINER (window), 10);
1209 /* create a label */
1210 label = gtk_label_new("And now for something completely different ...");
1211 gtk_container_add(GTK_CONTAINER(window), label);
1213 /* show everything */
1214 gtk_widget_show(label);
1215 gtk_widget_show (window);
1217 /* create the threads */
1218 yes_args.label = label;
1219 yes_args.what = YES_IT_IS;
1220 pthread_create(&yes_tid, NULL, argument_thread, &yes_args);
1222 no_args.label = label;
1223 no_args.what = NO_IT_IS_NOT;
1224 pthread_create(&no_tid, NULL, argument_thread, &no_args);
1226 /* enter the GTK main loop */
1227 gdk_threads_enter();
1229 gdk_threads_leave();
1236 <!-- ----------------------------------------------------------------- -->
1239 <title>Why does this strange 'x io error' occur when I
1240 <literal>fork()</literal> in my GTK+ app?</title>
1242 <para>This is not really a GTK+ problem, and the problem is
1243 not related to <literal>fork()</literal> either. If the 'x io
1244 error' occurs then you probably use the <literal>exit()</literal> function
1245 in order to exit from the child process.</para>
1247 <para>When GDK opens an X display, it creates a socket file
1248 descriptor. When you use the <literal>exit()</literal>
1249 function, you implicitly close all the open file descriptors,
1250 and the underlying X library really doesn't like this.</para>
1252 <para>The right function to use here is
1253 <literal>_exit()</literal>.</para>
1255 <para>Erik Mouw contributed the following code example to
1256 illustrate handling fork() and exit().</para>
1258 <programlisting role="C">
1259 /*-------------------------------------------------------------------------
1260 * Filename: gtk-fork.c
1262 * Copyright: Copyright (C) 1999, Erik Mouw
1263 * Author: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
1264 * Description: GTK+ fork example
1265 * Created at: Thu Sep 23 21:37:55 1999
1266 * Modified by: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
1267 * Modified at: Thu Sep 23 22:39:39 1999
1268 *-----------------------------------------------------------------------*/
1272 * cc -o gtk-fork gtk-fork.c `gtk-config --cflags --libs`
1276 #include <stdio.h>
1277 #include <stdlib.h>
1278 #include <signal.h>
1279 #include <sys/types.h>
1280 #include <sys/wait.h>
1281 #include <unistd.h>
1282 #include <gtk/gtk.h>
1284 void sigchld_handler(int num)
1286 sigset_t set, oldset;
1288 int status, exitstatus;
1290 /* block other incoming SIGCHLD signals */
1291 sigemptyset(&set);
1292 sigaddset(&set, SIGCHLD);
1293 sigprocmask(SIG_BLOCK, &set, &oldset);
1295 /* wait for child */
1296 while((pid = waitpid((pid_t)-1, &status, WNOHANG)) > 0)
1298 if(WIFEXITED(status))
1300 exitstatus = WEXITSTATUS(status);
1303 "Parent: child exited, pid = %d, exit status = %d\n",
1304 (int)pid, exitstatus);
1306 else if(WIFSIGNALED(status))
1308 exitstatus = WTERMSIG(status);
1311 "Parent: child terminated by signal %d, pid = %d\n",
1312 exitstatus, (int)pid);
1314 else if(WIFSTOPPED(status))
1316 exitstatus = WSTOPSIG(status);
1319 "Parent: child stopped by signal %d, pid = %d\n",
1320 exitstatus, (int)pid);
1325 "Parent: child exited magically, pid = %d\n",
1330 /* re-install the signal handler (some systems need this) */
1331 signal(SIGCHLD, sigchld_handler);
1333 /* and unblock it */
1334 sigemptyset(&set);
1335 sigaddset(&set, SIGCHLD);
1336 sigprocmask(SIG_UNBLOCK, &set, &oldset);
1339 gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
1344 void destroy(GtkWidget *widget, gpointer data)
1349 void fork_me(GtkWidget *widget, gpointer data)
1357 /* ouch, fork() failed */
1364 fprintf(stderr, "Child: pid = %d\n", (int)getpid());
1366 execlp("ls", "ls", "-CF", "/", NULL);
1368 /* if exec() returns, there is something wrong */
1371 /* exit child. note the use of _exit() instead of exit() */
1377 fprintf(stderr, "Parent: forked a child with pid = %d\n", (int)pid);
1381 int main(int argc, char *argv[])
1386 gtk_init(&argc, &argv);
1388 /* the basic stuff: make a window and set callbacks for destroy and
1391 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1393 gtk_signal_connect(GTK_OBJECT (window), "delete_event",
1394 GTK_SIGNAL_FUNC(delete_event), NULL);
1396 gtk_signal_connect(GTK_OBJECT (window), "destroy",
1397 GTK_SIGNAL_FUNC(destroy), NULL);
1399 #if (GTK_MAJOR_VERSION == 1) && (GTK_MINOR_VERSION == 0)
1400 gtk_container_border_width(GTK_CONTAINER (window), 10);
1402 gtk_container_set_border_width(GTK_CONTAINER (window), 10);
1405 /* add a button to do something usefull */
1406 button = gtk_button_new_with_label("Fork me!");
1408 gtk_signal_connect(GTK_OBJECT (button), "clicked",
1409 GTK_SIGNAL_FUNC(fork_me), NULL);
1411 gtk_container_add(GTK_CONTAINER(window), button);
1413 /* show everything */
1414 gtk_widget_show (button);
1415 gtk_widget_show (window);
1418 /* install a signal handler for SIGCHLD signals */
1419 signal(SIGCHLD, sigchld_handler);
1430 <!-- ----------------------------------------------------------------- -->
1433 <title>Why don't the contents of a button move when the button
1434 is pressed? Here's a patch to make it work that way...</title>
1436 <para>From: Peter Mattis
1437 <quote>The reason buttons don't move their child down and to
1438 the right when they are depressed is because I don't think
1439 that's what is happening visually. My view of buttons is
1440 that you are looking at them straight on. That is, the user
1441 interface lies in a plane and you're above it looking
1442 straight at it. When a button gets pressed it moves directly
1443 away from you. To be absolutely correct I guess the child
1444 should actually shrink a tiny amount. But I don't see why
1445 the child should shift down and to the left. Remember, the
1446 child is supposed to be attached to the buttons surface. Its
1447 not good for it to appear like the child is slipping on the
1448 surface of the button.
1450 On a more practical note, I did implement this at one point
1451 and determined it didn't look good and removed
1455 <!-- ----------------------------------------------------------------- -->
1458 <title>How to I identifiy a widgets top level window or other
1461 <para>There are a couple of ways to find the top level parent
1462 of a widget. The easier way is to call the
1463 <literal>gtk_widget_top_level()</literal> function that
1464 returns pointer to a GtkWidget that is the top level
1467 <para>A more complicated way to do this (but less limited, as
1468 it allows the user to get the closest ancestor of a known type) is to use
1469 <literal>gtk_widget_get_ancestor()</literal> as in:</para>
1471 <programlisting role="C">
1473 widget = gtk_widget_get_ancestor(w, GTK_TYPE_WINDOW);
1476 <para>Since virtually all the GTK_TYPEs can be used as the
1477 second parameter of this function, you can get any parent
1478 widget of a particular widget. Suppose you have an hbox which
1479 contains a vbox, which in turn contains some other atomic
1480 widget (entry, label, etc. To find the master hbox using the
1481 <literal>entry</literal> widget simply use:</para>
1483 <programlisting role="C">
1485 hbox = gtk_widget_get_ancestor(w, GTK_TYPE_HBOX);
1489 <!-- ----------------------------------------------------------------- -->
1492 <title>How do I get the Window ID of a GtkWindow?</title>
1494 <para>The actual Gdk/X window will be created when the widget
1495 gets realized. You can get the Window ID with:</para>
1497 <programlisting role="C">
1498 #include <gdk/gdkx.h>
1500 Window xwin = GDK_WINDOW_XWINDOW (GTK_WIDGET (my_window)->window);
1504 <!-- ----------------------------------------------------------------- -->
1507 <title>How do I catch a double click event (in a list widget,
1508 for example)?</title>
1510 <para>Tim Janik wrote to gtk-list (slightly modified):</para>
1512 <para>Define a signal handler:</para>
1514 <programlisting role="C">
1516 signal_handler_event(GtkWiget *widget, GdkEvenButton *event, gpointer func_data)
1518 if (GTK_IS_LIST_ITEM(widget) &&
1519 (event->type==GDK_2BUTTON_PRESS ||
1520 event->type==GDK_3BUTTON_PRESS) ) {
1521 printf("I feel %s clicked on button %d\",
1522 event->type==GDK_2BUTTON_PRESS ? "double" : "triple",
1529 <para>And connect the handler to your object:</para>
1531 <programlisting role="C">
1533 /* list, list item init stuff */
1535 gtk_signal_connect(GTK_OBJECT(list_item),
1536 "button_press_event",
1537 GTK_SIGNAL_FUNC(signal_handler_event),
1542 gtk_signal_connect(GTK_OBJECT(list_item),
1543 "button_release_event",
1544 GTK_SIGNAL_FUNC(signal_handler_event),
1547 /* something else */
1551 <para>and, Owen Taylor wrote:
1552 <quote>Note that a single button press will be received
1553 beforehand, and if you are doing this for a button, you will
1554 therefore also get a "clicked" signal for the button. (This
1555 is going to be true for any toolkit, since computers aren't
1556 good at reading one's mind.)</quote></para>
1559 <!-- ----------------------------------------------------------------- -->
1562 <title>By the way, what are the differences between signals
1565 <para>First of all, Havoc Pennington gives a rather complete
1566 description of the differences between events and signals in
1567 his free book (two chapters can be found at <ulink
1568 url="http://www106.pair.com/rhp/sample_chapters.html">
1569 http://www106.pair.com/rhp/sample_chapters.html</ulink>).</para>
1571 <para>Moreover, Havoc posted this to the <literal>gtk-list</literal>
1572 <quote>Events are a stream of messages received from the X
1573 server. They drive the Gtk main loop; which more or less
1574 amounts to "wait for events, process them" (not exactly, it
1575 is really more general than that and can wait on many
1576 different input streams at once). Events are a Gdk/Xlib
1577 concept.</quote></para>
1579 <para><quote>Signals are a feature of GtkObject and its subclasses. They have
1580 nothing to do with any input stream; really a signal is just a way
1581 to keep a list of callbacks around and invoke them ("emit" the
1582 signal). There are lots of details and extra features of
1583 course. Signals are emitted by object instances, and are entirely
1584 unrelated to the Gtk main loop. Conventionally, signals are emitted
1585 "when something changes" about the object emitting the signal.</quote></para>
1587 <para><quote>Signals and events only come together because GtkWidget happens to
1588 emit signals when it gets events. This is purely a convenience, so
1589 you can connect callbacks to be invoked when a particular widget
1590 receives a particular event. There is nothing about this that makes
1591 signals and events inherently related concepts, any more than
1592 emitting a signal when you click a button makes button clicking and
1593 signals related concepts.</quote></para>
1596 <!-- ----------------------------------------------------------------- -->
1599 <title>Data I pass to the <literal>delete_event</literal> (or other event)
1600 handler gets corrupted.</title>
1602 <para>All event handlers take an additional argument which
1603 contains information about the event that triggered the
1604 handler. So, a <literal>delete_event</literal> handler must
1605 be declared as:</para>
1608 <programlisting role="C">
1609 gint delete_event_handler (GtkWidget *widget,
1615 <!-- ----------------------------------------------------------------- -->
1618 <title>I have my signal connected to the the (whatever) event,
1619 but it seems I don't catch it. What's wrong?</title>
1621 <para>There is some special initialisation to do in order to
1622 catch some particular events. In fact, you must set the
1623 correct event mask bit of your widget before getting some
1624 particular events.</para>
1626 <para>For example,</para>
1628 <programlisting role="C">
1629 gtk_widget_add_events(window, GDK_KEY_RELEASE_MASK);
1632 <para>lets you catch the key release events. If you want to
1633 catch every events, simply us the GDK_ALL_EVENTS_MASK event
1636 <para>All the event masks are defined in the
1637 <filename>gdktypes.h</filename> file.</para>
1640 <!-- ----------------------------------------------------------------- -->
1643 <title>I need to add a new signal to a GTK+ widget. Any
1646 <para>If the signal you want to add may be beneficial for
1647 other GTK+ users, you may want to submit a patch that
1648 presents your changes. Check the tutorial for more
1649 information about adding signals to a widget class.</para>
1651 <para>If you don't think it is the case or if your patch is
1652 not applied you'll have to use the
1653 <literal>gtk_object_class_user_signal_new</literal>
1654 function. <literal>gtk_object_class_user_signal_new</literal> allows you to
1655 add a new signal to a predefined GTK+ widget without any
1656 modification of the GTK+ source code. The new signal can be
1657 emited with <literal>gtk_signal_emit</literal> and can be
1658 handled in the same way as other signals.</para>
1660 <para>Tim Janik posted this code snippet:</para>
1662 <programlisting role="C">
1663 static guint signal_user_action = 0;
1665 signal_user_action =
1666 gtk_object_class_user_signal_new (gtk_type_class (GTK_TYPE_WIDGET),
1668 GTK_RUN_LAST | GTK_RUN_ACTION,
1669 gtk_marshal_NONE__POINTER,
1674 gtk_widget_user_action (GtkWidget *widget,
1677 g_return_if_fail (GTK_IS_WIDGET (widget));
1679 gtk_signal_emit (GTK_OBJECT (widget), signal_user_action, act_data);
1683 <para>If you want your new signal to have more than the
1684 classical gpointer parameter, you'll have to play with GTK+
1688 <!-- ----------------------------------------------------------------- -->
1691 <title>Is it possible to get some text displayed which is
1692 truncated to fit inside its allocation?</title>
1694 <para>GTK's behavior (no clipping) is a consequence of its
1695 attempts to conserve X resources. Label widgets (among
1696 others) don't get their own X window - they just draw their
1697 contents on their parent's window. While it might be possible
1698 to have clipping occur by setting the clip mask before
1699 drawing the text, this would probably cause a substantial
1700 performance penalty.</para>
1702 <para>Its possible that, in the long term, the best solution
1703 to such problems might be just to change gtk to give labels X
1704 windows. A short term workaround is to put the label widget
1705 inside another widget that does get its own window - one
1706 possible candidate would be the viewport widget.</para>
1708 <programlisting role="C">
1709 viewport = gtk_viewport (NULL, NULL);
1710 gtk_widget_set_usize (viewport, 50, 25);
1711 gtk_viewport_set_shadow_type (GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
1712 gtk_widget_show(viewport);
1714 label = gtk_label ("a really long label that won't fit");
1715 gtk_container_add (GTK_CONTAINER(viewport), label);
1716 gtk_widget_show (label);
1719 <para>If you were doing this for a bunch of widgets, you might
1720 want to copy gtkviewport.c and strip out the adjustment and
1721 shadow functionality (perhaps you could call it
1725 <!-- ----------------------------------------------------------------- -->
1728 <title>How do I make my window modal? / How do I make a single
1729 window active?</title>
1731 <para>After you create your window, do
1732 <literal>gtk_grab_add(my_window)</literal>. And after closing
1734 <literal>gtk_grab_remove(my_window)</literal>.</para>
1737 <!-- ----------------------------------------------------------------- -->
1740 <title>Why doesn't my widget (e.g. progressbar)
1743 <para>You are probably doing all the changes within a function without
1744 returning control to <literal>gtk_main()</literal>. This may
1745 be the case if you do some lengthy calculation in your
1746 code. Most drawing updates are only placed on a queue, which
1747 is processed within <literal>gtk_main()</literal>. You can force the
1748 drawing queue to be processed using something like:</para>
1751 <programlisting role="C">
1752 while (gtk_main_iteration());
1755 <para>inside you're function that changes the widget.</para>
1757 <para>What the above snippet does is run all pending events
1758 and high priority idle functions, then return immediately
1759 (the drawing is done in a high priority idle function).</para>
1762 <!-- ----------------------------------------------------------------- -->
1765 <title>How do I attach data to some GTK+ object/widget?</title>
1767 <para>First of all, the attached data is stored in the
1768 object_data field of a GtkObject. The type of this field is
1769 GData, which is defined in glib.h. So you should read the
1770 gdataset.c file in your glib source directory very
1773 <para>There are two (easy) ways to attach some data to a gtk
1774 object. Using <literal>gtk_object_set_data()</literal> and
1775 <literal>gtk_object_get_data()</literal> seems to be the most
1776 common way to do this, as it provides a powerful interface to
1777 connect objects and data.</para>
1779 <programlisting role="C">
1780 void gtk_object_set_data(GtkObject *object, const gchar *key, gpointer data);
1782 gpointer gtk_object_get_data(GtkObject *object, const gchar *key);
1785 <para>Since a short example is better than any lengthy speech:</para>
1787 <programlisting role="C">
1788 struct my_struct p1,p2,*result;
1791 gtk_object_set_data(GTK_OBJECT(w),"p1 data",(gpointer)&p1);
1792 gtk_object_set_data(GTK_OBJECT(w),"p2 data",(gpointer)&p2);
1794 result = gtk_object_get_data(GTK_OBJECT(w),"p1 data");
1797 <para>The <literal>gtk_object_set_user_data()</literal> and
1798 <literal>gtk_object_get_user_data()</literal> functions does
1799 exactly the same thing as the functions above, but does not
1800 let you specify the "key" parameter.Instead, it uses a
1801 standard "user_data" key. Note that the use of these functions
1802 is deprecated in 1.2. They only provide a compatibility mode
1803 with some old gtk packages.</para>
1806 <!-- ----------------------------------------------------------------- -->
1809 <title>How do I remove the data I have attached to an
1812 <para>When attaching the data to the object, you can use the
1813 <literal>gtk_object_set_data_full()</literal> function. The three
1814 first arguments of the function are the same as in
1815 <literal>gtk_object_set_data()</literal>. The fourth one is a
1816 pointer to a callback function which is called when the data
1817 is destroyed. The data is destroyed when you:</para>
1820 <listitem><simpara> destroy the object</simpara>
1822 <listitem><simpara> replace the data with a new one (with
1823 the same key)</simpara>
1825 <listitem><simpara> replace the data with NULL (with the
1831 <!-- ----------------------------------------------------------------- -->
1834 <title>How do I reparent a widget?</title>
1836 <para>The normal way to reparent (ie change the owner) of a
1837 widget should be to use the function:</para>
1839 <programlisting role="C">
1840 void gtk_widget_reparent (GtkWidget *widget,
1841 GtkWidget *new_parent)
1844 <para>But this is only a "should be" since this function does
1845 not correctly do its job on some specific widgets. The main
1846 goal of gtk_widget_reparent() is to avoid unrealizing widget
1847 if both widget and new_parent are realized (in this case,
1848 widget->window is successfully reparented). The problem here
1849 is that some widgets in the GTK+ hierarchy have multiple
1850 attached X subwindows and this is notably the case for the
1851 GtkSpinButton widget. For those, gtk_widget_reparent() will
1852 fail by leaving an unrealized child window where it should
1855 <para>To avoid this problem, simply use the following code
1858 <programlisting role="C">
1859 gtk_widget_ref(widget);
1860 gtk_container_remove(GTK_CONTAINER(old_parent), widget);
1861 gtk_container_add(GTK_CONTAINER(new_parent), widget);
1862 gtk_widget_unref(widget);
1866 <!-- ----------------------------------------------------------------- -->
1869 <title>How could I get any widgets position?</title>
1871 <para>As Tim Janik pointed out, there are different cases, and
1872 each case requires a different solution.</para>
1875 <listitem><simpara> If you want the position of a widget
1876 relative to its parent, you should use
1877 <literal>widget->allocation.x</literal> and
1878 <literal>widget->allocation.y</literal>.</simpara>
1880 <listitem><simpara> If you want the position of a window
1881 relative to the X root window, you should use <literal>gdk_window_get_geometry()</literal>
1882 <literal>gdk_window_get_position()</literal> or
1883 <literal>gdk_window_get_origin()</literal>.</simpara>
1885 <listitem><simpara> If you want to get the position of the
1886 window (including the WM decorations), you should use
1887 <literal>gdk_window_get_root_origin()</literal>.</simpara>
1889 <listitem><simpara> Last but not least, if you want to get a Window Manager frame
1890 position, you should use
1891 <literal>gdk_window_get_deskrelative_origin()</literal>.</simpara>
1895 <para>Your choice of Window Manager will have an effect of the
1896 results of the above functions. You should keep this in mind
1897 when writing your application. This is dependant upon how the
1898 Window Managers manage the decorations that they add around
1902 <!-- ----------------------------------------------------------------- -->
1905 <title>How do I set the size of a widget/window? How do I
1906 prevent the user resizing my window?</title>
1908 <para>The <literal>gtk_widget_set_uposition()</literal>
1909 function is used to set the position of any widget.</para>
1911 <para>The <literal>gtk_widget_set_usize()</literal> function
1912 is used to set the size of a widget. In order to use all the
1913 features that are provided by this function when it acts on a
1914 window, you may want to use the
1915 <literal>gtk_window_set_policy</literal> function. The
1916 definition of these functions are:</para>
1918 <programlisting role="C">
1919 void gtk_widget_set_usize (GtkWidget *widget,
1923 void gtk_window_set_policy (GtkWindow *window,
1929 <para><literal>Auto_shrink</literal> will automatically shrink
1930 the window when the requested size of the child widgets goes
1931 below the current size of the
1932 window. <literal>Allow_shrink</literal> will give the user the
1933 authorisation to make the window smaller that it should
1934 normally be. <literal>Allow_grow</literal> will give the user
1935 will have the ability to make the window bigger. The default
1936 values for these parameters are:</para>
1938 <programlisting role="C">
1939 allow_shrink = FALSE
1944 <para>The <literal>gtk_widget_set_usize()</literal> functions
1945 is not the easiest way to set a window size since you cannot
1946 decrease this window size with another call to this function
1947 unless you call it twice, as in:</para>
1949 <programlisting role="C">
1950 gtk_widget_set_usize(your_widget, -1, -1);
1951 gtk_widget_set_usize(your_widget, new_x_size, new_y_size);
1954 <para>Another way to set the size of and/or move a window is to use
1955 the <literal>gdk_window_move_resize()</literal> function which
1956 uses to work fine both to grow or to shrink the window:</para>
1958 <programlisting role="C">
1959 gdk_window_move_resize(window->window,
1965 <!-- ----------------------------------------------------------------- -->
1968 <title>How do I add a popup menu to my GTK+
1969 application?</title>
1971 <para>The <literal>menu</literal> example in the examples/menu
1972 directory of the GTK+ distribution implements a popup menu
1973 with this technique:</para>
1976 <programlisting role="C">
1977 static gint button_press (GtkWidget *widget, GdkEvent *event)
1980 if (event->type == GDK_BUTTON_PRESS) {
1981 GdkEventButton *bevent = (GdkEventButton *) event;
1982 gtk_menu_popup (GTK_MENU(widget), NULL, NULL, NULL, NULL,
1983 bevent->button, bevent->time);
1984 /* Tell calling code that we have handled this event; the buck
1989 /* Tell calling code that we have not handled this event; pass it on. */
1995 <!-- ----------------------------------------------------------------- -->
1998 <title>How do I disable or enable a widget, such as a
2001 <para>To disable (or to enable) a widget, use the
2002 <literal>gtk_widget_set_sensitive()</literal> function. The
2003 first parameter is you widget pointer. The second parameter is
2004 a boolean value: when this value is TRUE, the widget is
2008 <!-- ----------------------------------------------------------------- -->
2011 <title>Shouldn't the text argument in the gtk_clist_*
2012 functions be declared const?</title>
2014 <para>For example:</para>
2016 <programlisting role="C">
2017 gint gtk_clist_prepend (GtkCList *clist,
2021 <para>Answer: No, while a type "gchar*" (pointer to char) can
2022 automatically be cast into "const gchar*" (pointer to const
2023 char), this does not apply for "gchar *[]" (array of an
2024 unspecified number of pointers to char) into "const gchar *[]"
2025 (array of an unspecified number of pointers to const char).</para>
2027 <para>The type qualifier "const" may be subject to automatic
2028 casting, but in the array case, it is not the array itself
2029 that needs the (const) qualified cast, but its members, thus
2030 changing the whole type.</para>
2033 <!-- ----------------------------------------------------------------- -->
2036 <title>How do I render pixels (image data) to the
2039 <para>There are several ways to approach this. The simplest
2040 way is to use GdkRGB, see gdk/gdkrgb.h. You create an RGB
2041 buffer, render to your RGB buffer, then use GdkRGB routines to
2042 copy your RGB buffer to a drawing area or custom widget. The
2043 book "GTK+/Gnome Application Development" gives some details;
2044 GdkRGB is also documented in the GTK+ reference
2045 documentation.</para>
2047 <para>If you're writing a game or other graphics-intensive
2048 application, you might consider a more elaborate
2049 solution. OpenGL is the graphics standard that will let you
2050 access hardware accelaration in future versions of XFree86; so
2051 for maximum speed, you probably want to use OpenGL. A
2052 GtkGLArea widget is available for using OpenGL with GTK+ (but
2053 GtkGLArea does not come with GTK+ itself). There are also
2054 several open source game libraries, such as ClanLib and Loki's
2055 Simple DirectMedia Layer library (SDL).</para>
2057 <para>You do NOT want to use
2058 <literal>gdk_draw_point()</literal>, that will be extremely
2062 <!-- ----------------------------------------------------------------- -->
2065 <title>How do I create a pixmap without having my window being
2066 realized/shown?</title>
2068 <para>Functions such as
2069 <literal>gdk_pixmap_create_from_xpm()</literal> require a
2070 valid window as a parameter. During the initialisation phase
2071 of an application, a valid window may not be available without
2072 showing a window, which may be inappropriate. In order to
2073 avoid this, a function such as
2074 <literal>gdk_pixmap_colormap_create_from_xpm</literal> can be
2077 <programlisting role="C">
2078 char *pixfile = "foo.xpm";
2079 GtkWidget *top, *box, *pixw;
2080 GdkPixmap *pixmap, *pixmap_mask;
2082 top = gtk_window_new (GKT_WINDOW_TOPLEVEL);
2083 box = gtk_hbox_new (FALSE, 4);
2084 gtk_conainer_add (GTK_CONTAINER(top), box);
2086 pixmap = gdk_pixmap_colormap_create_from_xpm (
2087 NULL, gtk_widget_get_colormap(top),
2088 &pixmap_mask, NULL, pixfile);
2089 pixw = gtk_pixmap_new (pixmap, pixmap_mask);
2090 gdk_pixmap_unref (pixmap);
2091 gdk_pixmap_unref (pixmap_mask);
2097 <!-- ***************************************************************** -->
2099 <title>Development with GTK+: widget specific questions</title>
2103 <!-- ----------------------------------------------------------------- -->
2106 <title>How do I find out about the selection of a GtkList?</title>
2108 <para>Get the selection something like this:</para>
2110 <programlisting role="C">
2112 sel = GTK_LIST(list)->selection;
2115 <para>This is how GList is defined (quoting glist.h):</para>
2117 <programlisting role="C">
2118 typedef struct _GList GList;
2128 <para>A GList structure is just a simple structure for doubly
2129 linked lists. there exist several g_list_*() functions to
2130 modify a linked list in glib.h. However the
2131 GTK_LIST(MyGtkList)->selection is maintained by the
2132 gtk_list_*() functions and should not be modified.</para>
2135 <para>The selection_mode of the GtkList determines the
2136 selection facilities of a GtkList and therefore the contents
2137 of GTK_LIST(AnyGtkList)->selection:</para>
2138 <informaltable frame="all">
2142 <entry><literal>selection_mode</literal></entry>
2143 <entry><literal> GTK_LIST()->selection</literal>
2149 <entry><literal>GTK_SELECTION_SINGLE</literal></entry>
2150 <entry>selection is either NULL or contains a GList*
2151 pointer for a single selected item.</entry>
2154 <entry><literal>GTK_SELECTION_BROWSE</literal></entry>
2155 <entry>selection is NULL if the list contains no
2156 widgets, otherwise it contains a GList*
2157 pointer for one GList structure.</entry>
2160 <entry><literal>GTK_SELECTION_MULTIPLE</literal></entry>
2161 <entry>selection is NULL if no listitems are selected
2162 or a a GList* pointer for the first selected
2163 item. that in turn points to a GList structure
2164 for the second selected item and so
2168 <entry><literal>GTK_SELECTION_EXTENDED</literal></entry>
2169 <entry>selection is NULL.</entry>
2175 <para>The data field of the GList structure
2176 GTK_LIST(MyGtkList)->selection points to the first
2177 GtkListItem that is selected. So if you would like to
2178 determine which listitems are selected you should go like
2181 <programlisting role="C">
2183 gchar *list_items[]={
2189 guint nlist_items=sizeof(list_items)/sizeof(list_items[0]);
2190 GtkWidget *list_item;
2193 list=gtk_list_new();
2194 gtk_list_set_selection_mode(GTK_LIST(list), GTK_SELECTION_MULTIPLE);
2195 gtk_container_add(GTK_CONTAINER(AnyGtkContainer), list);
2196 gtk_widget_show (list);
2198 for (i = 0; i < nlist_items; i++)
2200 list_item=gtk_list_item_new_with_label(list_items[i]);
2201 gtk_object_set_user_data(GTK_OBJECT(list_item), (gpointer)i);
2202 gtk_container_add(GTK_CONTAINER(list), list_item);
2203 gtk_widget_show(list_item);
2208 <para>To get known about the selection:</para>
2210 <programlisting role="C">
2214 items=GTK_LIST(list)->selection;
2216 printf("Selected Items: ");
2218 if (GTK_IS_LIST_ITEM(items->data))
2219 printf("%d ", (guint)
2220 gtk_object_get_user_data(items->data));
2229 <!-- ----------------------------------------------------------------- -->
2232 <title>How do I stop the column headings of a GtkCList
2233 disappearing when the list is scrolled?</title>
2235 <para>This happens when a GtkCList is packed into a
2236 GtkScrolledWindow using the function
2237 <literal>gtk_scroll_window_add_with_viewport()</literal>. The prefered
2238 method of adding a CList to a scrolled window is to use the
2239 function <literal>gtk_container_add</literal>, as in:</para>
2241 <programlisting role="C">
2242 GtkWidget *scrolled, *clist;
2243 char *titles[] = { "Title1" , "Title2" };
2245 scrolled = gtk_scrolled_window_new(NULL, NULL);
2247 clist = gtk_clist_new_with_titles(2, titles);
2248 gtk_container_add(GTK_CONTAINER(scrolled), clist);
2253 <!-- ----------------------------------------------------------------- -->
2256 <title>I don't want the user of my applications to enter text
2257 into a GtkCombo. Any idea?</title>
2259 <para>A GtkCombo has an associated entry which can be accessed
2260 using the following expression:</para>
2262 <programlisting role="C">
2263 GTK_COMBO(combo_widget)->entry
2266 <para>If you don't want the user to be able to modify the
2267 content of this entry, you can use the
2268 gtk_entry_set_editable() function:</para>
2271 <programlisting role="C">
2272 void gtk_entry_set_editable(GtkEntry *entry,
2276 <para>Set the editable parameter to FALSE to disable typing
2277 into the entry.</para>
2280 <!-- ----------------------------------------------------------------- -->
2283 <title>How do I catch a combo box change?</title>
2285 <para>The entry which is associated to your GtkCombo send a
2286 "changed" signal when:</para>
2289 <listitem><simpara>some text is typed in</simpara>
2291 <listitem><simpara>the selection of the combo box is changed</simpara>
2295 <para>To catch any combo box change, simply connect your
2296 signal handler with</para>
2298 <programlisting role="C">
2299 gtk_signal_connect(GTK_COMBO(cb)->entry,
2301 GTK_SIGNAL_FUNC(my_cb_change_handler),
2306 <!-- ----------------------------------------------------------------- -->
2309 <title>How can I define a separation line in a menu?</title>
2311 <para>See the <ulink
2312 url="http://www.gtk.org/tutorial/">Tutorial</ulink> for
2313 information on how to create menus. However, to create a
2314 separation line in a menu, just insert an empty menu item:</para>
2316 <programlisting role="C">
2317 menuitem = gtk_menu_item_new();
2318 gtk_menu_append(GTK_MENU(menu), menuitem);
2319 gtk_widget_show(menuitem);
2324 <!-- ----------------------------------------------------------------- -->
2327 <title>How can I right justify a menu, such as Help?</title>
2329 <para>Depending on if you use the MenuFactory or not, there
2330 are two ways to proceed. With the MenuFactory, use something
2331 like the following:</para>
2333 <programlisting role="C">
2334 menu_path = gtk_menu_factory_find (factory, "<MyApp>/Help");
2335 gtk_menu_item_right_justify(menu_path->widget);
2338 <para>If you do not use the MenuFactory, you should simply
2342 <programlisting role="C">
2343 gtk_menu_item_right_justify(my_menu_item);
2348 <!-- ----------------------------------------------------------------- -->
2351 <title>How do I add some underlined accelerators to menu
2354 <para>Damon Chaplin, the technical force behind the Glade
2355 project, provided the following code sample (this code is an
2356 output from Glade). It creates a small <GUIMenu>File</guimenu> menu item
2357 with only one child (<guimenu>New</guimenu>). The F in <guimenu>File</guimenu> and the N
2358 in <guimenu>New</guimenu> are underlined, and the relevant accelerators are
2361 <programlisting role="C">
2362 menubar1 = gtk_menu_bar_new ();
2363 gtk_object_set_data (GTK_OBJECT (window1), "menubar1", menubar1);
2364 gtk_widget_show (menubar1);
2365 gtk_box_pack_start (GTK_BOX (vbox1), menubar1, FALSE, FALSE, 0);
2367 file1 = gtk_menu_item_new_with_label ("");
2368 tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (file1)->child),
2370 gtk_widget_add_accelerator (file1, "activate_item", accel_group,
2371 tmp_key, GDK_MOD1_MASK, 0);
2372 gtk_object_set_data (GTK_OBJECT (window1), "file1", file1);
2373 gtk_widget_show (file1);
2374 gtk_container_add (GTK_CONTAINER (menubar1), file1);
2376 file1_menu = gtk_menu_new ();
2377 file1_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (file1_menu));
2378 gtk_object_set_data (GTK_OBJECT (window1), "file1_menu", file1_menu);
2379 gtk_menu_item_set_submenu (GTK_MENU_ITEM (file1), file1_menu);
2381 new1 = gtk_menu_item_new_with_label ("");
2382 tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (new1)->child),
2384 gtk_widget_add_accelerator (new1, "activate_item", file1_menu_accels,
2386 gtk_object_set_data (GTK_OBJECT (window1), "new1", new1);
2387 gtk_widget_show (new1);
2388 gtk_container_add (GTK_CONTAINER (file1_menu), new1);
2393 <!-- ----------------------------------------------------------------- -->
2396 <title>How can I retrieve the text from a GtkMenuItem?</title>
2398 <para>You can usually retrieve the label of a specific
2399 GtkMenuItem with:</para>
2401 <programlisting role="C">
2402 if (GTK_BIN (menu_item)->child)
2404 GtkWidget *child = GTK_BIN (menu_item)->child;
2406 /* do stuff with child */
2407 if (GTK_IS_LABEL (child))
2411 gtk_label_get (GTK_LABEL (child), &text);
2412 g_print ("menu item text: %s\n", text);
2417 <para>To get the active menu item from a GtkOptionMenu you can
2420 <programlisting role="C">
2421 if (GTK_OPTION_MENU (option_menu)->menu_item)
2423 GtkWidget *menu_item = GTK_OPTION_MENU (option_menu)->menu_item;
2427 <para>But, there's a catch. For this specific case, you can
2428 <emphasis>not</emphasis> get the label widget from
2429 <literal>menu_item</literal> with the above code, because the
2430 option menu reparents the menu_item's child temporarily to
2431 display the currently active contents. So to retrive the child
2432 of the currently active menu_item of an option menu, you'll
2436 <programlisting role="C">
2437 if (GTK_BIN (option_menu)->child)
2439 GtkWidget *child = GTK_BIN (option_menu)->child;
2441 /* do stuff with child */
2446 <!-- ----------------------------------------------------------------- -->
2449 <title>How do I right (or otherwise) justify a
2452 <para>Are you sure you want to <emphasis>justify</emphasis>
2453 the labels? The label class contains the
2454 <literal>gtk_label_set_justify()</literal> function that is
2455 used to control the justification of a multi-line
2458 <para>What you probably want is to set the <emphasis>alignment</emphasis>
2459 of the label, ie right align it, center it or left align
2460 it. If you want to do this, you should use:</para>
2462 <programlisting role="C">
2463 void gtk_misc_set_alignment (GtkMisc *misc,
2468 <para>where the <literal>xalign</literal> and
2469 <literal>yalign</literal> values are floats in
2473 <programlisting role="C">
2476 /* horizontal : left align, vertical : top */
2477 gtk_misc_set_alignment(GTK_MISK(label), 0.0f, 0.0f);
2479 /* horizontal : centered, vertical : centered */
2480 gtk_misc_set_alignment(GTK_MISK(label), 0.5f, 0.5f);
2482 /* horizontal : right align, vertical : bottom */
2483 gtk_misc_set_alignment(GTK_MISK(label), 1.0f, 1.0f);
2487 <!-- ----------------------------------------------------------------- -->
2490 <title>How do I set the background color of a GtkLabel
2493 <para>The Gtklabel widget is one of a few GTK+ widgets that
2494 don't create their own window to render themselves
2495 into. Instead, they draw themselves directly onto their
2496 parents window.</para>
2498 <para>This means that in order to set the background color for
2499 a GtkLabel widget, you need to change the background color of
2500 its parent, i.e. the object that you pack it into.</para>
2506 <!-- ----------------------------------------------------------------- -->