NAME

Gtk2::porting - Guide to porting from Gtk-Perl to Gtk2-Perl


SYNOPSIS

 first change Gtk to Gtk2...
 then fix what's broken until it works.


DESCRIPTION

Gtk-Perl (the project that included the Gtk module) bound gtk+ 1.x, whereas Gtk2-Perl (the project that includes the Gtk2 module) binds gtk+ 2.x. GTK+ itself changed rather substantially from the 1.x series to the 2.x series, resulting in the need to reimplement the Perl bindings completely. Gtk2-Perl uses many precedents from Gtk-Perl in making API decisions (its authors were avid Gtk-Perl users), but retaining complete source compatibility in the face of the changes in the underlying library is something of a lost cause. As an additional wrinkle, Gtk2-Perl attempts to bind only the things that were not deprecated as of gtk+ 2.0.0.

Thus, upgrading your Gtk-Perl programs to Gtk2-Perl is going to require some actual porting work. The GNOME 2.0 porting guide on http://developer.gnome.org has some more detailed discussion of porting from gtk+ 1.2 to gtk+ 2.0. See the sections on GLib and GTK+; it's geared towards the C API, but you can refer to the Gtk2::api manpage for information on how to translate between C and Perl in your head.

The biggest stumbling block for most porting will be the fact that several important widgets have been omitted from Gtk2-Perl because they are deprecated in gtk+-2.0.

  Old Widget          Replacement
  ------------        -------------------------------------
  Gtk::CList          Gtk2::TreeView with a Gtk2::ListStore
  Gtk::CTree          Gtk2::TreeView with a Gtk2::TreeStore
  Gtk::Text           Gtk2::TextView and a Gtk2::TextBuffer
  Gtk::Pixmap         Gtk2::Image
  Gtk::Preview        Gtk2::Image
  Gtk::List           Gtk2::TreeView with a Gtk2::ListStore
  Gtk::Tree           Gtk2::TreeView with a Gtk2::ListStore

Invariably, they have been replaced with far superior widgets, but the porting effort can be daunting for applications which use Gtk::CList, Gtk::CTree, and Gtk::Text heavily. To ease such porting, I created Gtk2::Deprecated; its documentation explains at length how you shouldn't use it. Find it via google. ;-) I recommend it for putting off the porting from CList to TreeView as long as possible in your porting effort, so you can still see something as you work.


PORTING FROM Gtk-Perl TO Gtk2-Perl

Step 1: Just get it to run.

The very first step: you need to use Gtk2, not use Gtk. The -init argument is still supported, but the -locale argument is not necessary (gtk+ handles this automatically). The same goes for Gnome and other modules you may use:

I use vim, so my initial step is usually

  :% s/\<Gtk\>/Gtk2/g
  :% s/\<Gnome\>/Gnome2/g

Note that the Gnome2 module does not contain everything -- some things are now in other, separate modules, such as Gnome2::Canvas, Gnome2::VFS, and Gnome2::GConf. Pick and choose as you need. (This document really only describes Gtk => Gtk2, so i won't go into detail on the others.)

Of course, this is not enough. Now you'll start hitting all the API problems. The section Incompatible changes made between Gtk-Perl and Gtk2-Perl lists in excruciating detail the sorts of things you need to look out for. Things of note not included there are

o The format of Gtk2::ItemFactory entries has changed.
o Several Gtk functions have moved to Glib:
  Gtk::timeout_add()        Glib::Timeout::add()
  Gtk::timeout_remove()     Glib::Source::remove()
  Gtk::idle_add()           Glib::Idle::add()
  Gtk::idle_remove()        Glib::Source::remove()
o Deriving widgets with signals and properties is completely different.
It's mostly for the better. See the Glib::Object::Subclass manpage and the Glib::Type manpage.

o ...

If your program is basically a wrapper around Gtk::CList or Gtk::Text, you will want to use Gtk2::Deprecated to allow yourself to get the program up and running so that you can port incrementally to the replacement widgets. I'll be really annoying and say it again -- do not use Gtk2::Deprecated to avoid porting your program! The replacement widgets truly are much nicer than their forebears!

Step 2: Take advantage of new features.

(Warning: this part usually involves reducing the amount of code in your program while increasing the amount of cool features it provides.)

Port from deprecated widgets to good widgets, and remove Gtk2::Deprecated.

Use Mnemonics everywhere. It's as simple as adding underscores to the strings passed to activatable widget constructors.

Use Stock Icons. E.g., $button = Gtk2::Button->new_from_stock ('gtk-ok');. However don't bother using this to create buttons for your dialogs.

Use Gtk2::Dialog's response API. (See the Gtk2::Dialog manpage for more info.)

Use Gtk2::MessageDialog instead of rolling your own alert, error, and other message-only dialogs.

Use Pango markup to add attributes to your text. If your program fiddles with Gtk::Styles to make bold headings or larger text and things like that, you can now strip all that code out and do something like

  $label = Gtk2::Label->new;
  $label->set_markup ('<em>Pango Markup</em> is '
                     .'<span color="red"><big>REALLY</big></span> '
                     .'<b>cool</b>!');

The Pango API reference has a description of this simple html-like markup language. http://developer.gnome.org/doc/API/2.0/pango/PangoMarkupFormat.html

If you're the type who hates magic numbers, ask Glib to export the TRUE and FALSE constants.

gtk+ 2.4 stuff -- Gtk2::UIManager, Gtk2::FileChooser, Gtk2::ComboBox, Gtk2::Expander, the new Gtk2::Toolbar API, etc, etc.

FIXME finish me

Step 3: Beef it up!

I leave this step as an exercise for the reader. Use the docs and examples to figure out how to make your user interface better. Convert your user interface to follow the Gnome Human Interface Guidelines. Learn about usability and accessibility and try to make your UI better. Make things simpler, faster, leaner, cooler, more featureful, whatever you like. Join gtk-perl-list@gnome.org and hang out in #gtk-perl on irc.gnome.org.

Incompatible changes made between Gtk-Perl and Gtk2-Perl

(This is adapted from the gtk+ API reference's ``Changes from 1.2 to 2.0'' Chapter.)

GTK+ changed fairly substantially from version 1.2 to 2.0, much more so than from 1.0 to 1.2. Subsequent updates (possibilities are 2.0 to 2.2, 2.2 to 2.4, then to 3.0) will almost certainly be much, much smaller. Nonetheless, most programs written for 1.2 compile against 2.0 with few changes. The bulk of changes listed below are to obscure features or very specialized features, and compatibility interfaces exist whenever possible.

o
Gtk::Container::get_toplevels() was removed and replaced with Gtk2::Window::list_toplevels().

o
The Gtk::Gdk::time* functions have been removed. This functionality has been unused since the main loop was moved into GLib prior to 1.2.

o
Gtk::Paned::set_gutter_size() has been removed, since the small handle tab has been changed to include the entire area previously occupied by the gutter.

o
Gtk::Paned::set_handle_size() has been removed, in favor of a style property, since this is an option that only makes sense for themes to adjust.

o
GDK no longer selects OwnerGrabButtonMask for button presses. This means that the automatic grab that occurs when the user presses a button will have owner_events = FALSE, so all events are redirected to the grab window, even events that would normally go to other windows of the window's owner.

o Type system changes:
The GTK+ type system was moved to GLib in 2.0, and the base object is now GObject rather than GtkObject. GLib is wrapped separately by the Glib module (see Glib), and thus GObject is Glib::Object in Perl.

o Object system changes:
GtkObject derives from GObject, so is not the basic object type anymore. This imposes the following source incompatible changes:
-
Subclassing of Gtk::Objects was a mess in Gtk-Perl. Subclassing of Glib::Objects is a mess in Gtk2-Perl, but a completely different mess. See the Glib::Object::Subclass manpage and the Glib::Type manpage for more information.

-
In particular, code that uses GTK_SET_ARG, GTK_GET_ARG, GTK_CLASS_INIT, GTK_OBJECT_INIT, etc, will have to be rewritten to use the corresponding Glib::Object stuff, which is not terribly complicated, but too involved to document here.

-
The GtkObject::destroy signal can now be emitted multiple times on an object. ::destroy implementations should make sure that they take this into account, by checking to make sure that resources are there before freeing them.

o Signal system changes:
In GTK+ 2.0, the signal system moved from GTK to GLib along with the introduction of GObject. The method names are mostly the same, but there are a few very important differences:
- Method churn:
 Old Method                    Replacement
 ----------------------------  ----------------------------
 signal_connect_object         signal_connect_swapped
 signal_disconnect             signal_handler_disconnect
 signal_emit_by_name           signal_emit
 signal_emit_stop              signal_emission_stop_by_name
 signal_emit_stop_by_name      signal_emission_stop_by_name
 signal_handlers_destroy       (no replacement necessary)
 signal_handler_pending        signal_handler_is_connected
 signal_handler_pending_by_id  signal_handler_is_connected
- Different user-data semantics
Gtk-Perl allowed you to pass an arbitrary list as user data to signal_connect(), and inserted this list into the handler's @_ after the instance and before the other arguments. This meant that the predefined arguments were not in a constant position, and the call signatures differed wildly from the C API documentation.

Gtk2-Perl addresses both of these issues by allowing only a signal (optional) user-data argument to signal_connect() and friends, and puts this optional value in its right place -- last -- in the handlers' @_. In order to pass more than one item to a handler, just use an anonymous array or hash reference.

For example:

  # old code:
  $widget->signal_connect (button_press_event => \&handler, $a, $b, $c);
  sub handler {
      my ($widget, $a, $b, $c, $event) = @_;
      # $instance, @user_data, @args
  }
  # new code:
  $widget->signal_connect (button_press_event => \&handler,
                           {a => $a, b => $b, c => $c});
  sub handler {
      my ($widget, $event, $things) = @_;
      # $instance, @args, $user_data
      # $things->{a}, etc
  }

This will be annoying while porting, but in the end makes things much better.

-

Some functions were removed from the GTK+ signal API, and have no replacements in the Glib signal API: Gtk2::Object::signal_n_emissions() and Gtk2::Object::signal_handler_pending_by_id() are the ones that are relevant to Gtk-Perl. For the most part, the remainder were not bound, so you don't need to worry about replacing them. :-)

The GSignal system performs emissions in a slightly different manner than the old GtkSignal code. Signal handlers that are connected to signal ``foo'' on object ``bar'' while ``foo'' is being emitted, will not be called during the current emission.

o
Inserting and deleting text in Gtk2::Entry though functions such as Gtk2::Entry::insert_text() now leave the cursor at its original position in the text instead of moving it to the location of the insertion/deletion.

o
The 'font' and 'font_set' declarations in RC files are now ignored. There is a new 'font_name' field that holds the string form of a Pango font.

o
A number of types in GDK have become subclasses of Glib::Object. For the most part, this should not break anyone's code. However, it's now possible/encouraged to use Glib::Object features with these GDK types. The converted types are: Gtk2::Gdk::Window, Gtk2::Gdk::Drawable, Gtk2::Gdk::Pixmap, Gtk2::Gdk::Image, Gtk2::Gdk::GC, Gtk2::Gdk::DragContext, Gtk2::Gdk::Colormap.

o
Gtk2::Style and Gtk2::RcStyle are now subclasses of Glib::Object as well. This requires fairly extensive changes to theme engines, but shouldn't affect most other code.

o
Some Gtk::Style draw_* methods have been removed (cross, oval, ramp) and others have been added (expander, layout). This will require changes to theme engines. If you had implemented a theme engine in Perl, you have my deepest respect.

o
The visual for a widget, and also the default visual is now derived from the colormap for the widget and the default colormap. Gtk::Widget::set_visual(), Gtk::Widget::set_default_visual(), Gtk::Widget::push_visual() and Gtk::Widget::pop_visual() now do nothing in gtk+, and are not included in Gtk2-Perl. It is safe to simply delete all references to these functions.

o
A number of functions in GDK have been renamed for consistency and clarity. Many of these are picked up automatically by inheritance, but the rest require changes to your code:
 Old Function                     New Function
 -------------------------------  -----------------------------------
 Gtk::Gdk::Pixmap::draw_pixmap    Gtk2::Gdk::Drawable::draw_drawable
 Gtk::Gdk::Pixmap::draw_bitmap    Gtk2::Gdk::Drawable::draw_drawable
 Gtk::Gdk::Pixmap::get_type       Gtk2::Gdk::Window::get_window_type
 Gtk::Gdk::GC::destroy            (no replacement, not needed)
 Gtk::Gdk::Image::destroy         (no replacement, not needed)
 Gtk::Gdk::Cursor::destroy        (no replacement, not needed)
 Gtk::Gdk::Window::copy_area      Gtk2::Gdk::Drawable::draw_drawable
 Gtk::Gdk::Rgb::get_cmap          (replacement get_colormap is not bound)

Note that the automatic memory management of Glib::Object removes the need for the ->destroy functions that were bound for many of the old GDK objects; in fact, they weren't really necessary in Gtk-Perl, either. Gtk::Widget::popup() was removed; it was only usable for Gtk2::Windows, and there the same effect can be achieved by Gtk2::Window::move() and Gtk2::Widget::show().

o
gdk_pixmap_foreign_new(), the C function called by Gtk::Gdk::Pixmap::foreign_new(), no longer calls XFreePixmap() on the pixmap when the GdkPixmap is finalized. This change fixes a lot of problems with code where the pixmap wasn't supposed to be freed; unfortunately, this function won't be available in Gtk2-Perl until 1.060, so if you need it right away, you will want to talk to us in #gtk-perl on irc.gnome.org or on the gtk-perl mailing list.

o
GtkProgress/GtkProgressBar had serious problems in GTK+ 1.2.
-
Only 3 or 4 functions are really needed for 95% of progress interfaces; Gtk::Progress/Gtk::ProgressBar had about 25 functions, and didn't even include these 3 or 4.

-
In activity mode, the API involves setting the adjustment to any random value, just to have the side effect of calling the progress bar update function - the adjustment is totally ignored in activity mode.

-
You set the activity step as a pixel value, which means to set the activity step you basically need to connect to size_allocate.

-
There are ctree_set_expander_style()-functions, to randomly change look-and-feel for no good reason.

-
The split between Gtk::Progress and Gtk::ProgressBar makes no sense whatsoever.

This was a big wart on GTK+ and made people waste lots of time, both learning and using the interface. So, GTK+ added what they felt is the correct API, and marked all the rest deprecated. Gtk2-Perl therefore does not include the old-style API. Since your code is going to be broken for other reasons, we thought this was a good time to make the change and just leave the broken stuff out altogether. The following 5 methods are the new programming interface:

  $progressbar->pulse ();
  $progressbar->set_text ($text);
  $progressbar->set_fraction ($fraction);
  $progressbar->set_pulse_step ($fraction);
  $progressbar->set_orientation ($orientation);

You have to admit, that's a lot simpler.

o
The GtkNotebookPage structure has been removed from gtk+'s public API, so there are no Gtk::NotebookPage objects in Gtk2-Perl. They were never supposed to be public in the first place, so gtk+ does not apologize.

o
Negative values of the position parameter to Gtk2::Notebook::reorder_child() now cause the page to be appended, not inserted at the beginning. (This gives consistency with Gtk2::Box::reorder_child(), Gtk2::Menu::reorder_child().)

o
GtkMenuPositionFunc (the menu position callback for Gtk2::Menu::popup()) has a new parameter, ``push_in'', which controls how menus placed outside the screen is handled. If this is set to TRUE and part of the menu is outside the screen then GTK+ pushes it into the visible area. Otherwise the menu is cut of at the end of the visible screen area.

o
Regardless of what happens to the size of the menu, the result is always that the items are placed in the same place as if the menu was placed outside the screen, using menu scrolling if necessary.

o
The ``draw'' signal and virtual method on Gtk::Widget have been removed. All drawing should now occur by invalidating a region of the widget (call Gtk2::Gdk::Window::invalidate_rect() or Gtk2::Widget::queue_draw() for example to invalidate a region). GTK+ merges all invalid regions, and sends expose events to the widget in an idle handler for the invalid regions. Gtk::Widget::draw() is deprecated and thus not part of Gtk2. (but still works; it adds the passed-in area to the invalid region and immediately sends expose events for the current invalid region.) Most widgets will work fine if you just delete their ``draw'' implementation, since they will already have working expose_event implementations. The draw method was rarely called in practice anyway.

o
The Gtk2::Gdk::Event::Expose has a new ``region'' field. This can be used instead of the ``area'' field if you want a more exact representation of the area to update.

o
Sending synthetic exposes using Gtk2::Widget::event() is no longer allowed. If you just need an expose call you should use Gtk2::Gdk::Window::invalidate_rect() or Gtk2::Gdk::Window::invalidate_region() instead. For the case of container widgets that need to propagate expose events to NO_WINDOW children you can either use Gtk2::Container::propagate_expose(), or chain to the default container expose handler.

o
The ``draw_default'' and ``draw_focus'' methods/signals on Gtk::Widget are gone; simply draw things in your expose handler. Gtk::Widget::draw_focus() and Gtk::Widget::draw_default() wrapper functions are also gone; just queue a draw on the widget, or the part affected by the focus/default anyway. Also, Gtk::Widget now has default implementations for focus_in_event and focus_out_event. These set/unset the 'has-focus' flag, and queue a draw. So if your focus in/out handler just does that, you can delete it.

o
Gtk::Text and Gtk::Tree were buggy and broken. GTK+ doesn't recommend using them, and in fact they plan to remove them from future versions, so we didn't bind them in Gtk2-Perl. The recommended alternatives are Gtk2::TextView and Gtk2::TreeView; have a look also at Gtk2::SimpleList.

o
Gtk::Gdk::ColorContext is gone; you probably weren't using it anyway. Use Gtk2::Gdk::Colormap and the Gtk2::Gdk::Rgb functions instead.

o
Gtk2::MenuBar now draws the container's border_width space outside the frame, not inside the frame.

o
In GTK+ 1.2 (and Gtk-Perl), if an event handler returned TRUE it prevented propagation of that event to parent widgets. That is, the event signal would not be emitted on parent widgets. In GTK+ 2.0 (and Gtk2-Perl), if an event handler returns TRUE, the current signal emission on the current widget is immediately stopped. That is, other callbacks connected to the signal will not be invoked.

o
Gtk2::Toolbar::new() no longer has arguments. This function was broken because the default GtkToolbarStyle (icons, text, both) is now a user preference, which is overridden when you call Gtk2::Toolbar::set_style(). The constructor forced everyone to override the preference, which was undesirable. So to port your app, decide if you want to force the toolbar style or conform to the user's global defaults; if you want to force it, call Gtk2::Toolbar::set_style().

The orientation arg was removed from Gtk2::Toolbar::new() as well, just because it wasn't very useful and we were breaking the function anyway so had an opportunity to lose it. Call Gtk2::Toolbar::set_orientation() to set toolbar orientation.

o
GtkRange/GtkScrollbar/GtkScale were rewritten; this means that most theme engines won't draw them properly, and any custom subclasses of these widgets will need a rewrite (though if you could figure out how to subclass the old version of GtkRange, you have our respect). Also, GtkTroughType is gone.

Here are some notable changes:

-
stepper_size style property is the height for vertical ranges, width for horizontal; the other dimension matches the trough size.

-
Added the ability to do NeXT-style steppers (and several other styles that don't make any sense).

-
Added min_slider_length, fixed_slider_length properties to Gtk2::Scrollbar.

-
Cleaned some private (or at least useless) functions out of gtkscale.h, e.g. Gtk::Scale::value_width().

-
Digits rounds the values a range will input to the given number of decimals, but will not try to force adjustment values set by other controllers. That is, we no longer modify adjustment->value inside a value_changed handler.

-
Added getters for Gtk2::Scale setters.

-
Middle-click begins a slider drag.

o
The Gtk::Container's ``focus'' signal/virtual function and Gtk::Container::focus() call were replaced by Gtk2::Widget's ``focus'' signal and Gtk2::Widget::child_focus(). The semantics are the same, so you should be able to just replace Gtk::Container::focus() calls with Gtk2::Widget::child_focus() calls.

The purpose of this change was to allow non-containers to have focusable elements.

Lots of other stuff changed in GtkContainer, but Gtk-Perl didn't bind it, and Gtk2-Perl doesn't bind it yet, so never you worry your pretty little head about it. :-)

o
Gtk::Gdk::Image::get() (or rather its replacement, Gtk2::Gdk::Drawable::get_image()) now handles errors properly by returning undef, whereas previously it would crash. Also, a window being offscreen is no longer considered an error; instead, the area contains undefined contents for the offscreen areas. In most cases, code using Gtk::Gdk::Image::get() should really be ported to Gtk2::Gdk::Pixbuf::get_from_drawable().

o
Gtk::Widget::set_usize() has been renamed to Gtk2::Widget::set_size_request().

o
Gtk::Widget::set_uposition() has been deprecated and is not bound anymore; use Gtk2::Window::move(), Gtk2::Fixed::put(), or Gtk2::Layout::put() instead.

o
Gtk::Window::set_policy() is deprecated. To get the effect of ``allow_shrink'', call $window->set_size_request (0, 0). To get the effect of ``allow_grow'', call $window->set_resizable (TRUE). You didn't want the effect of ``auto_shrink'', it made no sense. But maybe if you were using it you want to use $window->resize (1, 1) to snap a window back to its minimum size (the 1, 1 will be rounded up to the minimum window size).

o
The core GTK+ now takes care of handling mapping, unmapping and realizing the child widgets of containers in Gtk2::Widget::set_parent(). In most cases, this allows container implementations to be simplified by removing the code in add() methods to map and realize children. However, there are a couple of things to watch out for here:

o
If the parent is realized before the add() happens, Gtk2::Widget::set_parent_window() must be called before Gtk2::Widget::set_parent(), since Gtk2::Widget::set_parent() will realize the child.

o
If a container depended on its children not being mapped unless it did so itself (for example, Gtk::Notebook only mapped the current page), then the new function Gtk2::Widget::set_child_visible() must be called to keep widgets that should not be mapped not mapped.

As part of this change, most containers also will no longer need custom implementations of the map() and unmap() virtual functions. The only cases where this is necessary are:

-
For !NO_WINDOW widgets, if you create children of $widget->window and don't map them in realize() then you must map them in map(). [ In almost all cases, you can simply map the windows in realize(). ]

-
For NO_WINDOW widgets, if you create windows in your realize() method, you must map then in map() and unmap them in unmap().

o
Gtk::Widget::set_default_style(), Gtk::Widget::push_style(), and Gtk::Widget::pop_style() have been removed, since they did not work properly with themes and there were better alternatives for modifying the appearance of widgets. You should generally use Gtk2::Widget::modify_*() instead.

o
Gtk2::Image::new() now takes no arguments and creates an empty Gtk2::Image widget. To create a Gtk2::Image widget from a Gtk2::Gdk::Image (the least common usage of Gtk2::Gdk::Image), use Gtk2::Image::new_from_image().

o
GTK_SELECTION_EXTENDED is now deprecated, and neither the GtkList/GtkTree nor the GtkCList/GtkCTree support GTK_SELECTION_EXTENDED anymore. However, the old extended behavior replaces MULTIPLE behavior.

o
The handling of colormaps and widgets has been changed:

The default colormap for widgets is now the GdkRGB colormap, not the system default colormap. If you try to use resources created for a widget (e.g., $widget->style) with a window using the system colormap, errors will result on some machines.

Gtk2::Widget::push_colormap()/Gtk2::Widget::pop_colormap() only cause the colormap to be explicitly set on toplevel widgets, not on all widgets. The colormap for other widgets (when not set using Gtk2::Widget::set_colormap()), is determined by finding the nearest ancestor with a colormap set on it explicitly, or if that fails, the default colormap.

o
The default selected day for Gtk2::Calendar is now the current day in the month, not the first day in the month. The current month and year were already used.

o
GDK is no longer put into threaded mode automatically when g_thread_init() has been called (g_thread_init() is called automatically by Glib if your bindings have been built with threading enabled). In order to use the global GDK thread mutex with Gtk2::Gdk::Threads::enter() and Gtk2::Gdk::Threads::leave(), you must call Gtk2::Gdk::Threads::init() explicitly. If you aren't using GDK and GTK+ functions from multiple threads, there is no reason to call Gtk2::Gdk::Threads::init().

o
The Gtk::Preview is deprecated; just use a Gtk2::Image to display a Gtk2::Gdk::Pixbuf, instead. -- The GtkPreviewInfo struct has had its visual and colormap fields removed. Also, gtk_preview_get_cmap() and gtk_preview_get_visual() are deprecated, as GdkRGB works on any colormap and visual. You no longer need to gtk_widget_push_cmap (gtk_preview_get_cmap ()) in your code.

o
The Gtk2::Box, Gtk2::Table, and Gtk2::Alignment widgets now call < $widget-set_redraw_on_allocate (FALSE) >> on themselves. If you want to actually draw contents in a widget derived from one of these widgets, you'll probably want to change this in your INIT_INSTANCE() function.

o
A number of widgets are now NO_WINDOW widgets (most importantly Gtk2::Button, but also Gtk2::Range and Gtk2::Notebook). This has a couple of effects:
-
If you are deriving from one of these widgets, you need to adapt your code appropriately -- for instance, drawing coordinates start from widget->allocation.x, widget->allocation.y.

-
If you are embedding one of these widgets in a custom widget, you must make sure you call Gtk2::Container::propagate_expose() correctly, as you must for any NO_WINDOW widgets.

GtkFixed is a little special; it is now created by default as a NO_WINDOW widget, but if you do

  $fixed->set_has_window (TRUE);

after creating a fixed widget, it will create a window and handle it properly.

o
Gtk2::Layout no longer has the xoffset, yoffset fields, which used to store the difference between world and window coordinates for layout->bin_window. These coordinate systems are now always the same.

o
Gtk2::paint_focus(), Gtk2::draw_focus() and Gtk2::Style's draw_focus virtual function have been changed a bit:
-
A Gtk2::StateType argument has been added to Gtk2::paint_focus().

-
The default implementation of Gtk2::Style's draw_focus() virtual function now draws a focus rectangle whose width is determined by Gtk2::Widget's focus-width style property.

-
The rectangle passed in is the bounding box, instead of the rectangle used in the Gtk2::Gdk::draw_rectangle() call, so it is no longer necessary to subtract 1 from the width and height.


AUTHOR

Blame muppet <scott@asofyet.org> for not writing this sooner.

The ``Incompatible Changes from 1.2 to 2.0'' section is adapted from the GTK+ Reference Manual, with the parts that referred to stuff not included in Gtk-Perl just ripped out.