"intro to gtk 2" document



Hi,

Looking for corrections, additions, etc. to the appended document.
I wrote it a while ago so portions may be out-of-date.

Also - I think I asked about this before - I would like to move
changes-2.0.txt into docs/references/gtk/changes-2.0.sgml and maintain
it as part of the reference manual, so it's on the web site etc.
Sound OK?

Havoc



<!DOCTYPE Article PUBLIC "-//Davenport//DTD DocBook V3.0//EN"[
]>

<article lang="en" id="index">
  <artheader>
    <date>September, 2001</date>
    <authorgroup>
      <author>
	<surname>Pennington</surname>
	<firstname>Havoc</firstname> 
	<affiliation>
	  <address>
	    <email>hp redhat com</email>
	  </address>
	</affiliation>
      </author>
    </authorgroup>
    <copyright>
      <year>2001</year>
      <holder>Havoc Pennington</holder>
    </copyright>
    <title>Crash Course in GTK+ 2.0, for GTK+ 1.2 developers </title>
    <abstract>
      <para>
This document summarizes what you should know if you've been using
GTK+ 1.2 and are moving to GTK+ 2.0, including both new features and
changes to old features. It doesn't give you the big picture on what's
new in GTK+ 2.0 or hype the features; it's a practical/informal
document about the specifics of programming GTK+ 2.0.
      </para>
    </abstract>
  </artheader>

  <sect1 id="docs">
    <title>Documentation</title>
    
    <para>
  The GTK+ reference manual included with version 2.0 is much more
complete and informative than the one included with 1.2, and is
getting better all the time. Check it out if you have questions about
specific functions, widgets, or features.  Also, GTK+ now installs a
program called <literal>gtk-demo</literal>. If you have the GTK+
header files installed, you should have this program as well. It shows
off GTK+ features, alongside example code using those features. So you
can find the feature you want in the demo, then click to see the
implementation code. Unlike <literal>testgtk</literal>, which many
people used for this purpose with GTK+ 1.2, the
<literal>gtk-demo</literal> code was written to be a good example
rather than a torture test for GTK+. <literal>gtk-demo</literal> is
also expanding slowly to include examples of most things you might
want to do with GTK+.
    </para>
  </sect1>

  <sect1 id="text">
    <title>Text Handling</title>

    <para>
    The move to Unicode, along with proper internationalized text
    handling, is the most pervasive change in GTK+ 2.0. However, most
    user code that simply uses existing GTK widgets won't require
    modification. Some string manipulation code will need modification
    to work with UTF-8, and code that draws text directly to the
    screen with functions such as <literal>gdk_draw_string()</literal>
    will compile but will not display international text correctly.
    Similarly, code using <literal>GdkFont</literal> will compile but
    will not internationalize properly.
    </para>

    <sect2 id="utf8">
      <title>UTF-8 Manipulation</title>

      <para>
Most existing GTK+ code probably assumes that natural language strings
are in an 8-bit fixed-length encoding with ASCII as a subset. In
addition to ASCII itself, the most common such encoding is
Latin-1. "Fixed length" means that all characters are represented by
the same number of bits; so each byte corresponds to one character.
This wasn't true even in GTK+ 1.2; user-visible strings in GTK+ 1.2
were normally in the current locale's encoding. Essentially this meant
that there was no way to know the encoding of a string unless you knew
it was ASCII. You could not perform any operations on a per-character
basis, because characters could have been 32 bits long, or a variable
number of bits long. The bit pattern corresponding to an ASCII
character such as <literal>'a'</literal> could actually be part of
encoded Japanese text, not representing the English letter "a" at all.
In practice, most GTK+ 1.2 programs are somewhat broken from an i18n
standpoint.
      </para>

      <para>
In GTK+ 2.0, all user-visible strings are encoded in UTF-8 format.
UTF-8 is an encoding of the Unicode character set. Unicode characters
are 32-bit integers (represented in GLib and GTK+ by the typedef
'<literal>gunichar</literal>'). In UTF-8, the 128 ASCII characters are
encoded as themselves, as a single byte. In addition, the ASCII
character 0 (nul) has its usual role as a string terminator. Because
ASCII is a UTF-8 subset, much existing code will still work fine;
scanning for an ASCII character works fine. C string literals
containing only ASCII continue to work fine. The type of strings
remains '<literal>char*</literal>', rather than
'<literal>wchar_t*</literal>' or some other wide string type.
</para>

      <para>
All ASCII characters have the 8th bit set to 0; UTF-8 uses sequences
of bytes with this bit set to 1 to encode the rest of Unicode. This
variable-length strategy has a couple of important implications:
<itemizedlist>
<listitem>
<para>
Characters do not correspond to bytes. The return value of strlen() 
is the number of <emphasis>bytes</emphasis> in a string. With UTF-8,
the number of characters could be much smaller than the number of
bytes.
</para>
</listitem>
<listitem>
<para>
Strings can be <emphasis>invalid</emphasis>. All possible strings of
bytes are valid Latin-1 text, since 0 to 255 are all valid Latin-1
characters. All possible strings of bytes are not valid UTF-8, because
some sequences of bytes encode a character, and some do not. In
particular, if you "split" a sequence in the middle, the resulting
halves will be invalid; they never form a valid sequence by
themselves.
</para>
</listitem>
</itemizedlist>
      </para>

<para>
When a GTK+ 2.0 function takes a human-readable string as an argument, 
that string <emphasis>must</emphasis> be valid UTF-8. If you receive
text from a file or from the network, always validate it with
<literal>g_utf8_validate()</literal> before passing it to
GTK+. Invalid UTF-8 will crash your program if you pass it to GTK+.
</para>

<para>
When iterating over strings interpreting
<emphasis>characters</emphasis>, you must use
<literal>g_utf8_next()</literal> instead of simply incrementing 
pointers. "<literal>++p</literal>" does not advance by one character; 
it may advance into the middle of a character. 
(Caveat: code using the "<literal>++p</literal>" idiom is OK if it's
just scanning for ASCII characters, since they are encoded as a single
byte. e.g., the call "<literal>strchr (s, 'a')</literal>" remains
valid. But if you replace <literal>'a'</literal> with a non-ASCII
character such as an accented "a", the code will not work. You have to
replace such code with something like:
<programlisting>
while (*p)
{
  gunichar ch = g_utf8_get_char (p);

  if (ch == 0xE1)
    /* Found small a with acute accent, Unicode character 0xE1 */;
 
  p = g_utf8_next (p);
}
</programlisting>
Conveniently, the Unicode characters <literal>0xA0</literal> through
<literal>0xFF</literal> are the same as the Latin-1 characters.
However, these are encoded as multiple bytes in UTF-8, so to compare
to a Latin-1 character code you first have to decode the UTF-8 using
<literal>g_utf8_get_char()</literal>.
</para>

<para>
GLib 2.0 contains many useful functions for handling UTF-8 text;
including a <literal>g_utf8_strchr()</literal> that would handle the
just-mentioned example. In addition, GLib 2.0 contains functions for
converting Unicode text to and from the current locale's encoding.
You might want to look over <literal>gunicode.h</literal> or the GLib
documentation on this topic. (Nearly 100% of the newly-added stuff in
GTK+ 2.0 has complete reference documentation.)
</para>

<para>
Reading a file in locale encoding and converting it to UTF-8
on-the-fly is pretty difficult. The simplest solution is to read the
whole file at once with <literal>g_file_get_contents()</literal>
and then call <literal>g_utf8_validate()</literal> on it. However, 
this blocks during the entire read operation,
etc. <literal>GIOChannel</literal> now supports encoding conversion on
streams, which is a bit nicer way to handle it.
</para>

    </sect2>

    <sect2 id="fonts">
      <title>Fonts and Drawing Text</title>

      <para>
If you're using any kind of non-default fonts, you'll want to convert
your code to use the new <literal>PangoFontDescription</literal>
rather than
<literal>GdkFont</literal>. <literal>PangoFontDescription</literal> is
much, much easier to use; to load a <literal>GdkFont</literal> you had
to specify an awkward X font description string, and the resulting
<literal>GdkFont</literal> was specific to a certain locale; it
wouldn't work for all languages. Moreover, there were no fonts you
could choose that everyone using your app was guaranteed to have, 
so a call to <literal>gdk_font_load()</literal> could always fail.
      </para>

<para>
<literal>PangoFontDescription</literal> is much higher-level. The
exact font technology used by GTK+ varies according to GDK target and
how GTK+ was compiled; underneath Pango, the real implementation could
be Win32 fonts, XRender fonts, traditional X fonts, TrueType fonts, or
even a mixture. Pango can even assemble a collection of
locale-specific fonts and use those to emulate a single Unicode
font. Programmers don't have to worry about this; they specify
high-level font details such as "Sans Italic 12".
</para>

<para>
A <literal>PangoFontDescription</literal> has a stringified form,
described in the Pango documentation. "Sans Italic 12" is an example
of such a string. The easiest way to obtain a
<literal>PangoFontDescription</literal> is to call
<literal>pango_font_description_from_string()</literal>. The font
families "Sans", "Monospace", and "Serif" are guaranteed to exist on
all GTK+ installations; these will never fail to load.
</para>

<para>
If you were using the <literal>font</literal> field in
<literal>GtkStyle</literal> to change the font for a widget, you'll
need to use the new <literal>font_desc</literal> field instead.
However, when converting your code from <literal>GdkFont</literal>,
ask yourself if setting <literal>style-&gt;font</literal> remains the
easiest thing to do; <literal>gtk_label_new_from_markup()</literal> is
a handy alternative provided for <literal>GtkLabel</literal>. You can
pass in a string marked up with HTML-like tags affecting text
attributes such as color, text size, font family, and so on. The Pango
documentation describes all the tags you can use. If you do still want
to modify the style, probably you can use the
new <literal>gtk_widget_modify_font()</literal> function
instead of fooling with styles
manually. <literal>gtk_widget_modify_font()</literal> works properly
when the theme changes, and is easier to use.
</para>

<para>
If you were using <literal>gdk_draw_string()</literal>,
<literal>gdk_draw_text()</literal>,
<literal>gtk_paint_string()</literal>, or variants thereof, you'll
want to rework your code to use <literal>PangoLayout</literal>. A
<literal>PangoLayout</literal> represents a paragraph of text to be
rendered to the screen. With English or European text, to render a
paragraph, you just break on spaces and draw each line one font height
below the previous line. When you start to handle languages such as
Arabic, Hindi, Japanese, Hebrew, Thai, or Korean, however, this is
wrong; it simply won't work properly. Pango handles the details with
<literal>PangoLayout</literal>. To render a paragraph of text, create
a <literal>PangoLayout</literal> for that text, then call
<literal>gdk_draw_layout</literal> or
<literal>gtk_paint_layout()</literal>. To create your layout, call
<literal>gtk_widget_create_pango_layout()</literal> on the widget you
intend to draw on.
</para>

<para>
While you'll usually just create a layout and draw it, for more
complex cases <literal>PangoLayout</literal> has a lot of useful
features; it has text attributes, and you can use the HTML-like Pango
markup language mentioned earlier as a convenient way to set those
attributes. (The less-convenient way uses
<literal>PangoAttrList</literal> directly.)
<literal>PangoLayout</literal> can also handle cursors, conversion
from pixel locations to text positions, and that kind of thing.
</para>

<para>
When asking for text metrics, such as the size of a
<literal>PangoLayout</literal>, you'll notice that all Pango objects
have a "logical size" and an "ink size." The logical size corresponds
to the font metrics (ascent and descent), and should be used to
position text. The logical size for a line of text won't change if you
add a new character that's larger than the existing characters. The
ink size of some text describes the actual pixels covered by the font
glyphs, so for example capital letters have a larger ink size than
lowercase, and letters with "descenders" such as lowercase "y", "g",
"p" have a larger ink size than letters without. Usually you don't
need the ink size. Logical size should be used in widget size
requests, and in any other case where you're positioning text.
</para>

<para>
Pango sizes are specified in "Pango units," which are converted to and
from device units (e.g. pixels) using the
<literal>PANGO_SCALE</literal> constant.  There are
<literal>PANGO_SCALE</literal> units per pixel.
</para>

    </sect2>

<sect2 id="complexities">
      <title>General Text Handling</title>
<para>
If your application does anything complicated with text, such as text
editing, you'll want to investigate Pango in more depth.  Some
considerations and definitions to keep in mind:
<itemizedlist>
<listitem>
<para>
Logical and visual direction do not correspond. Logical direction is
the sequence of characters in a string; iterating over a string moves
through it logically. Visual direction is the sequence of font glyphs
on the user's monitor. Overall text direction can be right-to-left
instead of left-to-right; also, individual characters can be
"reordered" on a smaller scale, so that glyphs representing characters
are not in the same sequence as the characters themselves.
</para>
</listitem>

<listitem>
<para>
Glyphs do not correspond to characters. That is, multiple Unicode
characters can be displayed as a single font glyph on the screen. A
<firstterm>cluster</firstterm> is a set of characters represented by a
single glyph. (Glyphs are the graphical characters making up a font.)
</para>
</listitem>

<listitem>
<para>
The process of converting a string of characters into a string of
glyphs is called <firstterm>shaping</firstterm>. The low-level Pango
function <literal>pango_shape()</literal> performs this operation --
<literal>PangoLayout</literal> does shaping for you, so typically you
don't need to think about it.
</para>
</listitem>

<listitem>
<para>
Word, line, sentence, and paragraph breaks do not necessarily follow
English rules. Some languages are written with no spaces, for example,
so you can't use spaces to split up words. Line break rules depend on
the language. Paragraphs can be broken by the newline/linefeed
(<literal>'\n'</literal>) character, by carriage return
(<literal>'\r'</literal>), by a sequence of carriage return and line
feed, or by a special Unicode paragraph separator character. You can
obtain text boundary information for a paragraph of text with the
functions
<literal>pango_break()</literal>,
<literal>pango_get_log_attrs()</literal>,
and <literal>pango_find_paragraph_boundary()</literal>.
</para>
</listitem>

<listitem>
<para>
It's not possible to put the cursor (caret, insertion mark) at all
character positions. Some characters "combine" into a single logical
unit, and the cursor can't go between the combined characters. A group
of combined characters is called a <firstterm>grapheme</firstterm>,
that is, a logical unit of writing. <literal>pango_break()</literal>
and friends report valid cursor positions along with other text
boundary information.
</para>
</listitem>

</itemizedlist>
</para>

<para>
There are plenty of other considerations when rendering
internationalized text; see the Pango documentation and the Unicode
specification for a lot of useful information. Whenever possible, let
<literal>PangoLayout</literal> handle the details, so your application
will work properly around the world. If in doubt, please ask someone!
We're happy to answer internationalization questions on
gtk-list gnome org, and if you don't ask you might end up introducing
bugs that are hard to fix.
</para>

</sect2>

  </sect1>

  <sect1 id="compilation">
    <title>Compiling GTK+ Programs</title>

    <para>
We've moved from a collection of dedicated "-config" scripts to the
generic <literal>pkg-config</literal> tool. So instead of typing
<literal>gtk-config --cflags</literal> you might type
<literal>pkg-config --cflags
gtk+-2.0</literal>. <literal>pkg-config</literal> has several useful
features, have a look at the output from <literal>pkg-config
--help</literal>. The m4 macros still exist, but have been renamed to
include the version number; e.g. <literal>AM_PATH_GTK_2_0</literal>
replaces <literal>AM_PATH_GTK</literal>.
    </para>

    <para>
The GTK+ headers and libraries now live in directories containing the
GTK+ version or have the GTK+ version in their names, so GTK+ 2.0 has
no files in common with GTK+ 1.2, and can be installed
simultaneously. You can develop GTK+ 2.0 applications while GTK+ 1.2
is still installed.
</para>

  </sect1>

  <sect1 id="deprecation">
    <title>Deprecation</title>

    <para>
We have two levels of deprecation. The first kind of deprecated
interface is considered actively harmful to use; these interfaces
are not in the header files by default. You can enable them by
defining the preprocessor symbol <literal>GTK_ENABLE_BROKEN</literal>.
The second kind of deprecated interface works but isn't really 
recommended; we have a better replacement. These interfaces are
available by default, and can be disabled using
<literal>GTK_DISABLE_DEPRECATED</literal>, if you are feeling
ambitious and want to clean up your code.
    </para>

    <para>
<literal>GTK_ENABLE_BROKEN</literal> and
<literal>GTK_DISABLE_DEPRECATED</literal> can be defined on the
compiler command line using an option such as
<literal>-DGTK_DISABLE_DEPRECATED=1</literal>, or you can define them
with <literal>#define</literal> in specific source files prior
to including the GTK+ headers.
    </para>

  </sect1>

  <sect1 id="gobject">
    <title>GObject</title>

    <para>
The GTK+ type system and object system have been moved to GLib, as
"libgobject," and modified somewhat in
transit. <literal>GtkObject</literal> still exists for compatibility
reasons, but should not be used as a base class for new object
implementations.
    </para>

<para>
It's now encouraged to use <literal>GObject</literal> directly
instead of <literal>GtkObject</literal> for many operations. 
(However, the <literal>GtkObject</literal> functions still exist
for compatibility, so you don't have to change immediately.)
Here are some common equivalents:
<itemizedlist>
<listitem><para>
<literal>gtk_signal_connect()</literal> becomes
<literal>g_signal_connect()</literal>
</para></listitem>

<listitem><para>
<literal>gtk_object_ref()</literal> becomes
<literal>g_object_ref()</literal>, 
and same for unref.
</para></listitem>

<listitem><para>
In place of the "destroy" signal, use a weak reference
(<literal>g_object_weak_ref()</literal>). Keep in mind that 
you can't <emphasis>use</emphasis> an object in a weak reference 
handler, though; it's already been mostly finalized. The object's
address will be correct, but its contents and state are undefined.
</para></listitem>

</itemizedlist>


Note in particular that <literal>g_signal_connect_object()</literal>
is totally different from
<literal>gtk_signal_connect_object()</literal> - this promises to be a
FAQ. <literal>g_signal_connect_swapped()</literal> is the equivalent
of <literal>gtk_signal_connect_object()</literal>.
</para>

<para>
<literal>GObject</literal> reference counting differs from
<literal>GtkObject</literal>'s.  It is strictly reference counted,
with no "floating flag"; so when you create a new
<literal>GObject</literal>, you own a reference to it and must always
unref. With <literal>GtkObject</literal>, you don't own a reference on
a new object, there's only the owned-by-no-one floating reference.
</para>

<para>
<literal>GObject</literal> will be most visible to authors of custom
widgets.  The "correct way" to write a widget has changed a bit; look
at some of the widgets new in GTK+ 2.0 to get an idea how signals,
object properties, and so on work with GObject.
</para>

  </sect1>

  <sect1 id="tree">
    <title>New Tree Widget</title>

    <para>
<literal>GtkCList</literal> and <literal>GtkCTree</literal> have a lot
of limitations, and <literal>GtkList</literal> and
<literal>GtkTree</literal> are totally broken, so we set out to create
a new, better-thought-out list/tree widget. The new widget is called
<literal>GtkTreeView</literal>, but the tree API involves a
collection of objects such as <literal>GtkTreeModel</literal>,
<literal>GtkListStore</literal>, <literal>GtkCellRenderer</literal>,
etc.
</para>

<para>
<literal>GtkTreeView</literal> is pretty huge and has tons of
features, so you'll have to refer to the documentation for a full
introduction. As a teaser, here are some cool things about the new
widget:

<itemizedlist>
<listitem>
<para>
Model-view architecture, so you can have multiple widgets displaying
the same data.
</para>
</listitem>

<listitem>
<para>
The model is an abstract interface, so you can write custom models
that use your application's native data structures, instead of copying
data into the tree widget. (Two general-purpose models, 
<literal>GtkListStore</literal> and <literal>GtkTreeStore</literal>,
come with GTK+.)
</para>
</listitem>

<listitem>
<para>
Cells in the tree are drawn by subclasses of
<literal>GtkCellRenderer</literal>. With custom cell renderers, you
can display any kind of data you like in the tree, and even have cells
that respond to mouse events. GTK+ comes with cell renderers to draw
text, images, and check boxes. <literal>GtkCellRenderer</literal> is
intended to be useful for a future sheet widget as well as the tree
view (a couple things in the API might seem odd if you're thinking of
it as tree-specific).
</para>
</listitem>

<listitem>
<para>
 Cell renderer properties can be set per-renderer or per-cell (based
on data in the model). So for example, the text renderer has a
"foreground" property for the foreground color. You could set the
foreground color globally for an entire column, or you could have the
foreground property change per-cell according to data in the model.
</para>
</listitem>

<listitem>
<para>
For a given cell renderer, multiple fields in the model can affect
it. For example, if your mail client model has a boolean field
indicating "unread message," and a string field indicating "subject,"
you can set the "bold" property of the cell from the unread flag and
the "text" property of the cell from the subject.
</para>
</listitem>

</itemizedlist>

    </para>

  </sect1>

  <sect1 id="textwidget">
    <title>New Text Widget</title>

    <para>
Because <literal>GtkText</literal> was a serious piece of junk, we've 
created a new all-singing all-dancing text widget for GTK+ 2.0. This
new widget should be powerful enough to create a nice code editor for
a reasonably advanced IDE, or a simple non-WYSIWYG word processor.
    </para>

<para>
Here are some of the widget's features, refer to the documentation for
the full list.
<itemizedlist>

<listitem>
<para>
Full internationalization support using the Pango engine. Display and
editing of bidirectional and complex text; properly handles grapheme,
word, sentence, and paragraph boundaries according to Unicode
specification; handles various paragraph separator characters; etc.
</para>
</listitem>

<listitem>
<para>
Model-view separation; display the same text buffer in multiple
widgets, for split-screen displays and the like.
</para>
</listitem>


<listitem>
<para>
Tag objects allow complex sets of attributes to be assigned to text;
including many visual features such as color, size, underline,
overstrike, word wrap, spacing, etc., and also behavioral features
such as editability (you can have "locked" text that users can't
modify).
</para>
</listitem>

<listitem>
<para>
Mark objects allow you to "bookmark" positions in the text.
</para>
</listitem>

<listitem>
<para>
A fast BTree data structure, combined with smart iterators, ensures
reasonable algorithmic complexity for nearly all operations on the
text buffer. Also, the widget scales to extremely large buffer sizes;
it's quite usable even while displaying a huge file.
</para>
</listitem>

<listitem>
<para>
Modern UI features such as selection drag-and-drop and double-click to
select a word.
</para>
</listitem>

<listitem>
<para>
Optional "side windows" allow you to draw breakpoints, line numbers,
etc. alongside the text, and handle mouse events to implement features
such as dragging breakpoints.
</para>
</listitem>

<listitem>
<para>
Hooks are provided for implementing an undo feature; you can intercept
all user actions and record them for playback or reversal.
</para>
</listitem>

<listitem>
<para>
Sophisticated buffer navigation using iterators; movement by word,
sentence, line, paragraph, etc.; search for substrings; quick tag
lookup using the buffer's BTree data structure, so you can mark text
with a tag and later find it quickly.
</para>
</listitem>

</itemizedlist>
</para>

  </sect1>

  <sect1 id="accessibility">
    <title>Accessibility</title>

<para>
Sun Microsystems contributed a number of accessibility-related
enhancements to GTK+ 2.0. (See <ulink
url="http://developer.gnome.org/projects/gap/";>this page</ulink> for
detailed information.)
</para>

<sect2 id="atk">
<title>ATK</title>
<para>
GTK+ now depends on a library called ATK (Accessibility Tool Kit),
which allows accessibility tools to navigate the UI of 
an application and present it to disabled users. So for example, a
screen reader application would use ATK to locate notable features of
an app and describe them to blind users.
</para>
<para>
Whenever possible, ATK will use information already stored in widgets
to fill in the information it needs. However, when that fails
application developers may need to use ATK interfaces to provide
additional information about the UI; more guidelines on this are
forthcoming.
</para>
</sect2>

<sect2 id="keynav">
<title>Keyboard Navigation</title>
<para>
Even users who aren't disabled will benefit from the accessibility
work, one of the goals of this work was complete keyboard navigation 
for GTK+, and a nicer framework for making applications keyboard navigable.
</para>
<para>
The biggest advance here is no doubt the new "mnemonic" feature of
<literal>GtkLabel</literal>. Call
<literal>gtk_label_set_mnemonic()</literal> with a string such as
<literal>"_Open"</literal> and the label will have the "O"
underlined. If you then place the label inside a button or other
acceleratable container, the mnemonic will automatically be connected
to it. If you place the label alongside a widget it's accelerating, call
<literal>gtk_label_set_mnemonic_widget()</literal> to connect the
mnemonic to the widget. There are also convenience functions, such as
<literal>gtk_button_new_with_mnemonic()</literal>. Collisions between mnemonics are handled
properly; if two identical mnemonics appear in the same window,
activating the mnemonic will cycle focus between the mnemonic target
widgets. Also, mnemonics for widgets that are hidden (e.g. on a
concealed notebook page) have no effect.
</para>
<para>
Another notable enhancement to keyboard navigation is that nearly all
keybindings are now customizable via gtkrc files or global GTK+
settings.
</para>
<para>
The default keybindings themselves have changed noticeably; they are 
now much more consistent with precedents such as Windows, Motif, and
Java. You'll notice that the numeric keypad works with most
widgets. Also, there are some nice global bindings such as F10 to 
jump to the menubar or Shift+F10 to pop up right-click menus.
</para>
</sect2>

  <sect1 id="fixed">
    <title>Enhancements to Existing Widgets</title>

    <para>

    </para>

    <sect2 id="widget">
      <title><literal>GtkWidget</literal></title>
      <para>
      <literal>GtkWidget</literal> has new convenience functions to
      set colors and fonts, so there's no longer much reason to mess
      around with <literal>widget-&gt;style</literal> or
      <literal>gtk_widget_modify_style()</literal>. In general, 
      <literal>GtkWidget</literal> has not been radically changed from
      an application standpoint. It has had a few changes impacting custom
      widget subclasses.
      </para>
    </sect2>

    <sect2 id="optionmenu">
      <title><literal>GtkOptionMenu</literal></title>
      <para>
The option menu now has a <literal>"changed"</literal> signal, so you
don't have to connect to <literal>"activate"</literal> on each menu
item. This makes it much easier to use.
      </para>
    </sect2>

    <sect2 id="progressbar">
      <title><literal>GtkProgressBar</literal></title>
      <para>
The <literal>GtkProgressBar</literal> interface was huge and
inconvenient. Now there are a few new, non-deprecated functions that
operate on <literal>GtkProgressBar</literal>. The
<literal>GtkProgress</literal> base class has been deprecated, along
with most of the existing methods on the progress bar.
      </para>
    </sect2>

    <sect2 id="image">
      <title><literal>GtkImage</literal></title>
      <para>
<literal>GtkImage</literal> is now a generic image-display widget,
rather than a display engine for <literal>GdkImage</literal>. 
It can display pixmaps, pixbufs, <literal>GdkImage</literal>, 
stock icons, etc. It can even display animations.
      </para>
    </sect2>

    <sect2 id="dialog">
      <title><literal>GtkDialog</literal></title>
      <para>
<literal>GtkDialog</literal> has been enhanced with features similar
to <literal>GnomeDialog</literal>, including stock buttons, a way to
block modally waiting for the user to respond
(<literal>gtk_dialog_run()</literal>), and a
subclass <literal>GtkMessageDialog</literal> that's convenient for
displaying simple messages.
      </para>
    </sect2>

    <sect2 id="popups">
      <title>Right-click menus</title>
      <para>
        All right-click menus should now be popped up in response to
        the <literal>"popup_menu"</literal> signal on
        <literal>GtkWidget</literal>. This ensures that the Shift+F10
        keybinding (as customized by the user) will work. Also, any
        widgets that edit text should add GTK+'s default
        input-method-selection entries to their right-click menu; see
        <literal>GtkEntry</literal> and <literal>GtkTextView</literal>
        source code for examples. The relevant function is <literal>
        gtk_im_multicontext_append_menuitems()</literal> and it should
        be called just before popping up the menu, so that it reflects
        the currently-active input method.
      </para>
    </sect2>

    <sect2 id="">
      <title><literal></literal></title>
      <para>
      </para>
    </sect2>

  </sect1>

  <sect1 id="stock">
    <title>Stock System</title>

    <para>
GTK+ now has a "stock items" system. The most user-visible aspect of
this is the introduction of stock icons. Unlike GNOME stock icons,
GTK+'s stock icons are themeable; so you can expect new GTK+ 2.0
themes to occasionally include matching icons. Not only can
gtkrc-based themes change which icons are used, theme engines can
override the function that derives prelighted/insensitive icons from a
base pixbuf. So a theme engine could make icons black-and-white when
not prelighted, a la Internet Explorer, or it could make icons get
larger when prelighted, or any other possibilities you can think of.
    </para>

<para>
Applications or add-on libraries can register their own stock items,
which are also themeable. Consider making the menu and toolbar icons
from your applications themeable by stuffing them into a
<literal>GtkIconFactory</literal> and adding the icon factory to the
default list of icon factories with
<literal>gtk_icon_factory_add_default()</literal>.  Themes can then
provide an icon for "nautilus-zoom-control" or "gimp-scissors-tool" in
addition to standard GTK icons such as "gtk-open".
</para>

  </sect1>

  <sect1 id="gdkpixbuf">
    <title>GdkPixbuf and image loading</title>

    <para>
The GdkPixbuf library most people are already familiar with now ships
with GTK+. This means you have image loading, scaling, alpha
compositing, etc. built in to GTK+. Many uses of
<literal>GdkPixmap</literal> can be replaced by pixbufs. 
    </para>

<para>
There are only a three major changes to the GdkPixbuf library from
GdkPixbuf 1.0; the first is that <literal>GdkPixbuf</literal>
objects are now <literal>GObject</literal> subclasses; the second is
that many functions now use <literal>GError</literal> to report
errors; the third is that the original GdkPixbufAnimation API was 
broken, and has been replaced.
</para>

<para>
Also, as a new feature, pixbufs can be created from inline RGB
data. Inline RGB data will be faster and use less memory than inline
XPM data. So inline XPMs should be avoided in favor of inline RGB.
GTK+ comes with a binary called <literal>make-inline-pixbuf</literal>
which can be used to create a C variable declaration from an image
file such as a PNG. Typically you'd ship your application with PNG
files, and during the build process convert those to a C include file.
That way you can easily edit the image at any time.
</para>

  </sect1>

  <sect1 id="deprecated">
    <title>Deprecated Features</title>

    <para>

    </para>

    <sect2 id="gtkpixmap">
      <title><literal>GtkPixmap</literal></title>
      <para>
<literal>GtkImage</literal> now displays pixmaps, along with many
other kinds of image. So <literal>GtkPixmap</literal> has no useful
function.
      </para>
    </sect2>

  </sect1>

  <sect1 id="drawing">
    <title>Drawing, Scrolling, and Colors</title>

    <para>
      There are several important <literal>GdkWindow</literal> and
      <literal>GtkWidget</literal> changes related to
      drawing. Briefly:

<itemizedlist>
<listitem>
<para>
GdkWindow's size is no longer limited to 16-bit integers. This means
that you can implement scrolling by simply creating a huge GdkWindow
and calling <literal>gdk_window_scroll()</literal> to move it around.
<literal>gdk_window_scroll()</literal> will perform a fast,
flicker-free scroll.  Look at <literal>GtkTextView</literal> and
<literal>GtkTreeView</literal> for example code. This renders the
<literal>GtkLayout</literal> widget obsolete, pretty much; its purpose
was to implement smooth scrolling and emulate larger-than-65535-pixel
windows.
</para>
</listitem>

<listitem>
<para>
Each <literal>GdkWindow</literal> maintains an "invalid region";
incoming expose events from X (or another target windowing system) are
added to the invalid region, rather than delivered to widgets
immediately. In an idle handler, GTK+ calls
<literal>gdk_window_process_updates()</literal> which converts the
invalid region into a set of rectangles and sends those to widgets as
expose events. Applications should call
<literal>gdk_window_invalidate_rect()</literal> when a portion of a
window needs redrawing; this will add the given area of the window to
the invalid region. Applications that did their own expose compression
or other drawing optimizations can be dramatically simplified; now you
just need to write an expose_event handler, and let GTK+ handle the
efficiency issues.
</para>
</listitem>

<listitem>
<para>
<literal>GdkWindow</literal> has built-in double buffering (backing
store). If you call <literal>gdk_window_begin_paint()</literal> before
you draw to the window, all drawing will be diverted to a backing
store; when you call <literal>gdk_window_end_paint()</literal>, the
backing store will be copied onscreen. GTK+ calls
<literal>gdk_window_begin_paint()</literal> automatically before
emitting expose_event on a widget, so normally there's no need to call
the function yourself; all drawing in an expose_event handler is
automatically double buffered.<footnote><para>But you can call
<literal>gtk_widget_set_double_buffered()</literal> to disable the
double buffering on a per-widget basis.</footnote> This change
eliminates pretty much all flicker in GTK+ applications. Also, because
the backing store is the same size as the exposed area, all drawing in
expose_event handlers will automatically be clipped to the expose
area. So code setting <literal>event-&gt;area</literal> as a clip
rectangle no longer needs to do that, it's done for you. Furthermore,
the backing store is automatically cleared to the background color or
pixmap, so you don't need to explicitly draw the background.
</para>
</listitem>
</itemizedlist>

<listitem>
<para>
The <literal>"draw"</literal> signal on <literal>GtkWidget</literal>
no longer exists. Instead, all drawing goes through expose_event. 
In general, <literal>"draw"</literal> signal handlers or default
implementations can be deleted with no ill effects. One exception:
some widgets called <literal>gtk_widget_draw()</literal> from their
expose handler. <literal>gtk_widget_draw()</literal> now sends expose
events. So you'll get an infinite loop. These widgets should be fixed
by moving the code from the draw handler into the
expose_event handler.
</para>
</listitem>

<listitem>
<para>
The <literal>"draw"</literal> signal on <literal>GtkWidget</literal>
no longer exists. Instead, all drawing goes through expose_event. 
In general, <literal>"draw"</literal> signal handlers or default
implementations can be deleted with no ill effects. One exception:
some widgets called <literal>gtk_widget_draw()</literal> from their
expose handler. <literal>gtk_widget_draw()</literal> now sends expose
events. So you'll get an infinite loop. These widgets should be fixed
by moving the code from the draw handler into the
expose_event handler.
</para>
</listitem>

<listitem>
<para>
The <literal>"draw_focus"</literal> and
<literal>"draw_default"</literal> signals have also been removed;
expose handlers should simply draw the focused or default state if
appropriate. Most expose handlers already did this, usually by calling
the draw_focus handler, so the way you'd normally port a GTK+ 1.2
widget would be to take the code from draw_focus and draw_default and
move it into the expose handler, then delete the draw_focus and
draw_default functions.
</para>
</listitem>

    </para>

    <para>
 The GdkRGB module has become the default and standard way to manage
colors. That is, rather than manually allocating colors, you're now
encouraged to simply use the closest color from the GdkRGB color cube;
<literal>gdk_rgb_find_color()</literal> should thus replace all calls
to <literal>gdk_color_alloc()</literal> or
<literal>gdk_colormap_alloc_color()</literal>, unless your application
is doing something extremely specialized.
<literal>gdk_gc_set_rgb_fg_color()</literal> and
<literal>gdk_gc_set_rgb_bg_color()</literal> are provided as
convenience functions; these call
<literal>gdk_rgb_find_color()</literal> on the passed-in color, then
set the color on the GC.
</para>

<para>
GdkRGB has been modified to work with any colormap and visual, so
<literal>gdk_rgb_init()</literal> has become a no-op and there's no
need to use a special GdkRGB visual. Any calls that push/pop the RGB
visual should simply be removed.
    </para>

  </sect1>

  <sect1 id="glib">
    <title>GLib Enhancements</title>

    <para>
 GLib is 99% backward-compatible, but has a lot of useful API
 additions and enhancements.
    </para>

  <sect2 id="error">
    <title><literal>GError</literal></title>

     <para>
      If you read one piece of documentation, read the 
<literal>GError</literal> section in the GLib reference manual;
otherwise you probably won't handle errors properly. 
<literal>GError</literal> is an error-reporting mechanism that allows
a nice human-readable and context-specific error message to be
reported to the user. You can and should use this feature.
     </para>
<para>
By convention, all functions that can return a
<literal>GError</literal> allow you to pass <literal>NULL</literal>
for the <literal>GError</literal> return location to ignore
errors. Don't get in this habit! Use the exciting new
<literal>GtkMessageBox</literal> widget to report the error to the
user!
</para>
    </sect2>

  <sect2 id="spawn">
    <title>Process spawning</title>

     <para>
      If you're calling <literal>fork()</literal> and
      <literal>exec()</literal>, don't do it; even if you have it
      working well (I bet you're missing some obscure error
      handling), you almost certainly don't have the snazzy error
      reporting of GLib's <literal>g_spawn_*</literal> functions.
     These functions can also automatically set up pipes, or 
     capture the output of a command as a string.
     </para>
    </sect2>


  <sect2 id="threads">
    <title>Portable threads</title>

    <para>
     GLib 1.2 supported cross-platform locks, but you couldn't
     actually create threads with the GLib API. GLib 2.0 offers a 
     cross-platform abstraction for thread creation and use.
    </para>
    </sect2>

  <sect2 id="gstring">
    <title>GString</title>

    <para>
     GString now supports embedded nuls, so can be used with 
     binary data.
    </para>
  </sect2>


  <sect2 id="fileutils">
    <title>File utilities</title>

    <para>
     There are a few utility functions for dealing with files,
     such as <literal>g_file_get_contents()</literal> to slurp a file
     into a string, <literal>g_file_test()</literal> to see if a file
     exists, and functions for creating temporary files.
    </para>
    </sect2>


  <sect2 id="trymalloc">
    <title>Memory allocation</title>

    <para>
     Memory allocation has two new features; first, you can replace
     the allocator virtual table with your own functions; second,
     <literal>g_try_malloc()</literal> and
     <literal>g_try_realloc()</literal> are available which return
     <literal>NULL</literal> on failure instead of exiting with an
     error message.
    </para>
  </sect2>

  <sect2 id="">
    <title></title>

    <para>
    </para>
  </sect2>


  <sect2 id="">
    <title></title>

    <para>
    </para>
  </sect2>


  <sect2 id="">
    <title></title>

    <para>
    </para>
  </sect2>



  </sect1>


  <sect1 id="">
    <title></title>

    <para>

    </para>

  </sect1>

  
</article>






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]