E.6. Using GTK+ From Plugins

With the use of the gtk3-perl bindings, it is possible to use the full power of the GTK+ library in KildClient plugins. This allows you to create dialogs, windows, message boxes, and anything else your plugin needs.

Using gtk3-perl in a KildClient plugin is straightforward, there is just a couple of points to be observed. Import the Perl modules as usual, generally with a line like this: "use Gtk3 -init;". Create windows and display them as usual. The biggest difference is that you must not call Gtk3->main. Since KildClient is a GTK+ application, it already runs a main loop, and starting another one would lock KildClient and make it unresponsive. Also, you must never call Gtk3->main_quit, because that would cause KildClient to quit. Even tough the world would be saved, the user certainly wouldn't want that.

All features of GTK+ are supported, as are all of gtk3-modules (this includes modules for the base libraries Glib and GDK, and also for other libraries such as the Gnome ones). Notably, Gtk3::Builder is supported, which allows you to create complex user interfaces visually and load them from the .ui file in the plugin.

Note that having the gtk3-perl bindings is not necessary to run KildClient. If they are not present, however, it will not be possible to run plugins that use it, naturally. The plugins will not be loaded because an error will be generated when the modules are loaded (in the "use Gtk3 -init;" line).

The example below shows a very simple (and not very useful) plugin using gtk3-perl. It should show how simple it is to use the gtk3-perl bindings in KildClient plugin.

Example E.4. A plugin that uses gtk3-perl
package gtksample;
#: Version: 1.0.0
#: Description: A Plugin Using gtk3-perl
#: Author: Eduardo M Kalinowski

use Gtk3 -init;

# Is the window being displayed?
our $window_displayed = 0;

# Widgets
our $window;
our $entry;
our $button;

sub help {
  $::world->echonl("This plugins demonstrates the use of gtk3-perl under KildClient.",
                   "It does nothing really useful.",
                   "",
                   "Enter /gtksample::run to try it.");
}


sub run {
  return if $window_displayed;

  $window = Gtk3::Window->new();
  $window->set_title("gtk3-perl test");
  $window->signal_connect(delete_event => sub {
                            $window_displayed = 0;
                            return 0;
                          });

  my $vbox = Gtk3::Box->new('vertical', 8);

  $entry = Gtk3::Entry->new();
  $entry->set_text("Type something here");
  $vbox->pack_start($entry, 0, 1, 0);

  $button = Gtk3::Button->new("And click me");
  $button->signal_connect(clicked => \&on_button_clicked);
  $vbox->pack_start($button, 0, 1, 0);

  $window->add($vbox);

  $window->show_all();
  $window_displayed = 1;
}


sub on_button_clicked {
  $button->set_label($entry->get_text());
}


sub UNLOAD {
  $window->destroy if $window_displayed;
}

Notice how it defines a UNLOAD function that destroys the window if it is being displayed. Plugins that open windows almost always need such a function to delete the windows that are still open when the World is closed. If these windows are not closed, the program will most likely crash if the user tries to use them after the Worlds has been closed, so make sure they get deleted.

For more information on gtk3-perl, see https://metacpan.org/release/Gtk3/.