Aus Linux-Magazin 03/2010

Der aufgeräumte Weg zu GTK+ 3.0

Foto: krockenmitte, Photocase.com

Die nächste Hauptversion 3.0 von GTK+ soll in gut einem Jahr erscheinen. Spektakuläre Neuerungen wird es nicht geben. Die Entwickler des GUI-Toolkits arbeiten stattdessen daran, mit frischer Luft im Code sauberes, gesundes Wachstum anzustoßen .

Das ursprünglich an Tk [1] und klassischen Unix-GUIs angelehnte Erscheinungsbild hat sich im Dialog mit den großen GTK+ nutzenden Projekten wie Gimp und Gnome sichtbar weiterentwickelt. Auch die Architektur, die jetzt die Vektorgrafik-Bibliothek Cairo zum Zeichnen verwendet, hat sich seither erheblich verändert. Das führt dazu, dass viele Klassen aus Kompatibilitätsgründen existieren, aber kaum Verwendung finden. Beispielsweise löst der »GtkFileChooser« die »GtkFileSelection« ab.

Aus Entwicklerperspektive steht der Anlauf zu GTK+ 3.0 somit im Zeichen der Notwendigkeit, die historischen Hinterlassenschaften in den Bibliotheken aufzuräumen. Nach Jahren der Diskussion, ob GTK+ 3.0 und vor allem Gnome 3.0 das Gewesene fortschreiben oder revolutionär Neues bringen sollen, hat sich zumindest bei der grafischen Plattform der Evolutionsgedanke durchgesetzt: GTK+ 3.0 hat zum Ziel, die losen Fäden aus über sieben Jahren Entwicklungszeit aufzulesen, es soll die etablierte Architektur nicht umwerfen. Mehr noch als um bloßes Ballastabwerfen geht es darum, die Bibliotheken für die Zukunft fit zu machen, also in erster Linie wartbarer.

Knackt beim Öffnen

Das bedeutet auch, dass Entwickler das API von GTK+ 3.0 jetzt schon verwenden können: Es entspricht dem um alle Kompatibilitätszugeständnisse bereinigten API der demnächst anstehenden Version 2.20 (siehe Kasten “Versionen im Wandel”). Code, der nach Abschalten der Kompatibilität und Einschalten der Objektversiegelung unter 2.20 funktioniert, sollte also auch unter 3.0 laufen.

Versionen im Wandel

Seit der letzten großen GTK+-Release 2.0 vom Frühjahr 2002 hat es neun abwärtskompatible Versionssprünge gegeben, zuletzt im September 2009 auf Nummer 2.18 [3]. Auf der nächsten stabilen GTK+ 2.20 soll Gnome 3.0 aufsetzen. Es erscheint statt des planmäßig anstehenden Gnome 2.30 oder, wenn das QA-Team es für angebracht hält, erst anstelle 2.32 [4].

Bei GTK+ gibt es zusätzlich den Entwicklerbranch 2.90, der auf die nächste Hauptversion 3.0 hinarbeitet. Deren API entspricht dem von 2.20, hat aber weniger Ballast und beherrscht Objektversiegelung. Das erste darauf basierende Gnome soll nach derzeitigem Plan die Nummer 3.2 tragen.

Unter Abschalten der Kompatibilität ist die Definition des Makros »DISABLE_DEPRECATED« zu verstehen. Die Objektversiegelung ist neu: Das Makro »GSEAL_ENABLE« aktiviert sie und bewirkt, dass alle direkten Zugriffe auf Objekte zu Compilerfehlern führen. Damit stellt das API sicher, dass zum Beispiel ein Datenfeld nicht mehr auf folgende Weise zugänglich ist:

Bar *bar = foo->bar;

In Zukunft dient hierzu folgende Lesefunktion:

Bar *bar = foo_get_bar(foo);

Die dadurch nötigen Änderungen lassen sich zwar mit dem Clang-basierten Werkzeug »gtk-rewriter« [2] automatisieren, doch ist dessen Wartungszustand etwas unklar. Das API von GTK+ 3.0 – und letztlich aller Bibliotheken in der G-Welt – soll damit, wie es sich in der objektorientierten Programmierung auch gehört, nur noch aus Methoden respektive Funktionen bestehen, die sich über Eigenschaften ansprechen lassen. Das macht es künftig einfacher, die internen Datenstrukturen neu zu organisieren. Und das wiederum legt den Grundstein für neue Funktionen in Version 3.0 und den folgenden.

Geheime Rezeptur

Ein wenig mehr als bloße Aufräumarbeit geht aber doch vor sich. Unauffällig, aber von großer Wirkung sind die in GTK+ 2.18 eingeführten Client-seitigen Fenster. Damit sind Fenster im Sinne der X11-Terminologie gemeint, also rechteckige Bereiche, in denen Programme zeichnen und die Ereignisse erhalten können. GTK+ verwaltet diese Fensterstrukturen nicht mehr als X-Fenster im X-Server, sondern weitgehend auf der Client-Seite. Im Idealfall beansprucht eine Anwendung also nur noch ein X-Fenster, in dem das GTK+-Backend GDK (Gimp Drawing Kit, [5]) Zeichnungen erstellt und Ereignisse verarbeitet.

Abgesehen von besserer Performance durch weniger Kommunikation mit dem X-Server und reduziertem Flackern eröffnet dies die elegante Möglichkeit, in unsichtbare Fenster zu zeichnen (Off-screen windows), beispielsweise um Widgets auf Canvases zu legen oder sie geometrisch zu transformieren. Auch Systeme, deren X-Server kein Compositing unterstützt, können damit transparente Elementen darstellen. Und ganz nebenbei lässt sich der Grafikcode von GTK+ auch noch besser portieren.

Verborgene Gewürze

Vorangekommen ist auch die Integration von GIO, der I/O-Bibliothek des virtuellen Gnome-Dateisystems GVfs [6]. Die Datei-Auswahl-Widgets, die die Schnittstelle »GtkFileChooser« implementieren, liefern ja schon seit GTK+ 2.14 optional Dateihandles vom Typ »GFile« zurück. Darüber hinaus ist GIO nicht nur schneller geworden, sondern unterstützt auch transparente Kompression und Dekompression von Dateien sowie validierte UTF-8-Zeichenströme. Die Entwickler-Ausrede, Dateizugriffe in der GTK+-Programmierung mit plattformfremden Mechanismen vermeiden zu wollen, gilt also nicht mehr.

Als dritte unsichtbare, für Entwickler aber wichtige Änderung unterstützt GTK+ mittlerweile GObject-Introspection [7], was sich in Zukunft wohl in der ganzen G-Welt durchsetzen wird. GObject-Introspection heißt, dass die formatierten Kommentare für das Javadoc-ähnliche API-Dokumentationswerkzeug Gtk-doc [8] maschinenlesbare Hinweise erhalten: Sie geben beispielsweise an, ob übergebene Zeiger als Eingabe- oder Ausgabeparameter dienen oder welchen Typs die Elemente einer übergebenen Liste sein müssen. Diese Hinweise kompiliert der Programmierer zunächst nach XML und anschließend in ein für schnelle Zugriffe geeignetes Binärformat.

Ziel ist, dass Bibliotheksanbindungen für Skriptsprachen, Plugins oder anderen Code zweiter Ordnung sich zur Laufzeit vollständige Informationen über das API der im gegenwärtigen Moment vorliegenden G-Bibliotheken verschaffen. Dann sind sie nicht mehr darauf angewiesen, solche Informationen selbst zu pflegen. Dies sollte den Klebercode, dessen es bei der Zusammenarbeit verschiedener Sprachen derzeit noch bedarf, stark reduzieren: Im Idealfall wird man beispielsweise eine neue, in C geschriebene Unterklasse von »GtkWidget« ohne weiteren Aufwand in Javascript oder Python verwenden können, sofern sie ihr Schöpfer korrekt dokumentiert hat.

Verbesserte Verpackung

Alles Bisherige bleibt für den Anwender im Hintergrund. Anders verhält es sich rund um sichtbare Widgets. Eigentlich schon überfällig ist ein einfacher Weg, sie neben die Reiter des Containers »GtkNotebook« zu setzen, etwa einen Aktivitätsanzeiger oder einen Knopf zum Hinzufügen neuer Seiten (Listing 1).

Listing 1: Knopf im
»GtkNotebook«

01 GtkNotebook *notiz;
02 GtkButton *actionknopf;
03 
04 actionknopf = GTK_BUTTON(
05     gtk_button_new_with_label("Neue Stadt"));
06 gtk_notebook_set_action_widget(notiz,
07     GTK_WIDGET(actionknopf),
08     GTK_PACK_END);
09 gtk_widget_show(GTK_WIDGET(actionknopf));

Für diese so genannten Action Areas neben den Reitern enthält GTK+ 2.18 zwei neue Funktionen: »gtk_notebook_set_action_widget()« packt ein Widget vor oder hinter die Reiter – wo, spezifiziert das dritte Argument (Zeile 8). Das Ergebnis zeigt Abbildung 1. Die komplementäre Funktion »gtk_notebook_get_action_widget()« nimmt ein »GtkNotebook«-Widget und den »GtkPackType« und liefert das jeweilige Action-Widget zurück.

Abbildung 1: Der Knopf in der Action Area eines GTK-Notebooks ist der neuen Funktion »gtk_notebook_set_action_widget()« zu verdanken.

Abbildung 1: Der Knopf in der Action Area eines GTK-Notebooks ist der neuen Funktion »gtk_notebook_set_action_widget()« zu verdanken.

Vergleichbar unauffällig und nützlich ist die neue Möglichkeit, Widgets in eine Statusbar einzufügen (Listing 2). Die Funktion »gtk_statusbar_get_message_area()« (Zeile 8) setzt eine »GtkHBox« an das Ende der Statusleiste. Hier finden Status-Icons oder ebenfalls ein Knopf Platz, wie in Abbildung 2 zu sehen ist.

Listing 2: Knopf in der
»GtkStatusbar«

01 GtkStatusbar *status;
02 GtkHBox *statusbox;
03 GtkButton *logknopf;
04 
05 logknopf = GTK_BUTTON(
06     gtk_button_new_with_label("Log anzeigen"));
07 statusbox = GTK_HBOX(
08     gtk_statusbar_get_message_area(status));
09 gtk_box_pack_end(
10     GTK_BOX(statusbox), GTK_WIDGET(logknopf),
11                         FALSE, FALSE, 0);
Abbildung 2: Zugriff zur Message Area einer GTK-Statusbar gewährt die Funktion »gtk_statusbar_get_message_area()«.

Abbildung 2: Zugriff zur Message Area einer GTK-Statusbar gewährt die Funktion »gtk_statusbar_get_message_area()«.

Dazu passt, dass GTK+ in der neuesten Version ein einfaches Widget zur Aktivitätsanzeige namens »GtkSpinner« mitliefert. Der kleine, einigermaßen skalierbare Wirbel ist in Web-2.0-Zeiten totschick. Er transferiert aber auch das bisherige Vorgehen von GTK+ in die Moderne, Aktivität unbestimmter Dauer anzuzeigen, nämlich mittels eines Aktivitätsmodus der »GtkProgressBar«.

Stattdessen legt der Entwickler einen Spinner an und startet ihn mit dem Aufruf »gtk_spinner_start()« (Listing 3). Analog führt »gtk_spinner_stop()« zum Ende der Bewegung. Im Ergebnis steckt ein solcher Spinner statt eines Aktionsknopfes in der Statusleiste (Abbildung 4). Im heutigen UI-Design sind Verzögerungen von mehr als einer Sekunde ohne Aktivitätsindikator nicht mehr akzeptabel, »GtkSpinner« leistet da gute Dienste.

Listing 3: Spinner in der
»GtkStatusbar«

01 GtkSpinner *wirbel;
02 
03 wirbel = GTK_SPINNER(gtk_spinner_new());
04 statusbox = GTK_HBOX(
05     gtk_statusbar_get_message_area(status));
06 gtk_box_pack_start(GTK_BOX(statusbox),
07     GTK_WIDGET(wirbel),
08     FALSE, FALSE, 0);
09 gtk_spinner_start(wirbel);
Abbildung 4: Der »GtkSpinner« in GTKs Statusbar: Willkommen in der Moderne.

Abbildung 4: Der »GtkSpinner« in GTKs Statusbar: Willkommen in der Moderne.

Frische Tupfer

Das Äquivalent zum Spinner als Renderer für MVC-Widgets (Model View Controller) wie Listen oder Bäume ist die neue Widget-Klasse »GtkCellRendererSpinner«. Diese Klasse ist wichtig, weil der Benutzer es gerade beim Dateimanagement oft mit Verzögerungen beim Bildaufbau zu tun hat, wenn die Anwendung viele Daten gleichzeitig und oft überraschend ermittelt muss.

Als Letztes verdient die »GtkInfoBar« Erwähnung. Sie ist auch seit GTK+ 2.18 dabei, also keine Zukunftsvision mehr. Allerdings implementiert sie ein vielgefragtes Bedienelement und verdient daher Aufmerksamkeit. Die Infobar-Klasse erzeugt waagerechte Balken mit Hinweisen oder Knöpfen, wie sie spätestens durch Firefox beliebt geworden sind und in Webanwendungen häufig den Platz modaler Popups einnehmen.

Das API ist absichtlich sehr nahe an dem von »GtkDialog« gehalten. Denn letztlich ist ein Informationsbalken ja bloß ein schmaler, horizontal layouteter Dialog ohne eigenes Fenster (Abbildung 3). Bei der Implementierung in Listing 4 ist zu beachten, dass das Objekt »hauptbox« (Zeile 17) die übliche Gtk VBox [9] mit Anwendungsinhalt und Leisten darstellt.

Listing 4: GTK-Anzeige
»GtkInfoBar«

01 GtkVBox *hauptbox;
02 GtkInfoBar *balken;
03 GtkContainer *inhalt;
04 GtkLabel *balkentext;
05
06 balken = GTK_INFO_BAR(
07     gtk_info_bar_new_with_buttons(
08         GTK_STOCK_OK,
09         GTK_RESPONSE_OK,
10         NULL));
11 balkentext = GTK_LABEL(
12     gtk_label_new("Plugin installiert"));
13 inhalt = GTK_CONTAINER(
14     gtk_info_bar_get_content_area(balken));
15 gtk_container_add(inhalt,
16     GTK_WIDGET(balkentext));
17 gtk_box_pack_start(GTK_BOX(hauptbox),
18     GTK_WIDGET(balken),
19     FALSE, FALSE, 0);
20 gtk_widget_show(GTK_WIDGET(balken));
Abbildung 3: Mit der »GtkInfoBar«, seit der Version 2.18 mit an Bord, haben die Entwickler ein vielgefragtes Bedienelement implementiert.

Abbildung 3: Mit der »GtkInfoBar«, seit der Version 2.18 mit an Bord, haben die Entwickler ein vielgefragtes Bedienelement implementiert.

Bewährte Qualität

Die Konsequenz, mit der die Entwickler GTK+ aufräumen, lässt für die rundum aufgefrischte und versiegelte Plattform viel Gutes erwarten. Der frühere technischen Unterschied zwischen GTK+- und Gnome-Anwendungen, bei dem zum Beispiel Gnome die Bibliotheken Libgnome und Libgnomeui verwenden sollte, findet praktisch keine Entsprechung mehr. Ein Gnome-Programm folgt jetzt der Beschreibung eines Programms auf der GTK+-Plattform, das sich an die Design-Richtlinien des Gnome-Projekts [10] hält und sich mit den anderen Gnome-Komponenten verzahnt.

Für Entwickler gibt es keine spektakulären Veränderungen, anders für den Anwender. Dem bietet sich zum Beispiel mit der Gnome-Shell als dem neuen Kernstück der Benutzeroberfläche ein schöner Anblick [11]. Für die Zukunft von Gnome auf mobilen Geräten ist allerdings unklar, welche Konsequenzen es haben wird, dass die Nokia-Plattform Maemo ab Version 5.1 auf Qt und nicht mehr auf GTK+ aufbaut.

Interessenten, die das neue API mit Objektversiegelung heute schon mal ausprobieren möchte, haben zwei Möglichkeiten: Entweder sie definieren bei der aktuellen GTK-Entwicklerversion 2.19 die oben erwähnten Flags »DISABLE_DEPRECATED« und »GSEAL_ENABLE« oder sie besorgen sich aus dem Git-Repository des Projekts den Entwicklerbranch GTK+ 2.90 [12]. Der führt auf direktem Wege zu GTK+ 3.0 und ist von etlichen Altlasten, die im Vergleich zu 2.20 rausfliegen sollen, bereits befreit. (ake)

Infos

[1] Tk: [http://sourceforge.net/projects/tktoolkit]

[2] GTK-Rewriter: [http://people.imendio.com/richard/gtk-rewriter]

[3] GTK+ 2.18: [http://blogs.gnome.org/gtk/2009/09/25/gtk-2-18-stable-release]

[4] Gnome-Roadmap: [http://live.gnome.org/ThreePointZero/Plan]

[5] Gimp Drawing Kit: [http://library.gnome.org/devel/gdk]

[6] GIO: [http://library.gnome.org/devel/gio]

[7] GObject-Introspektion: [http://live.gnome.org/GObjectIntrospection]

[8] Gtk-Doc: [http://www.gtk.org/gtk-doc]

[9] Gtk VBox: [http://library.gnome.org/devel/gtk/unstable/GtkVBox.html]

[10] Gnomes Design-Richtlinien: [http://library.gnome.org/devel/hig-book]

[11] GTK-3.0-Anwärter: [http://git.gnome.org/browse/gtk+/tree/?h=gtk-2-90]

[12] Neue Gnome-Shell: [http://live.gnome.org/GnomeShell]

Der Autor

Matthias Warkus hat mehrere offizielle Entwicklerhandbücher für GTK+ und Gnome veröffentlicht, zuletzt 2008 “Das GTK+/Gnome-Entwicklerhandbuch” im Dpunkt-Verlag. Er promoviert am Institut für Philosophie der Philipps-Universität Marburg und ist beim dortigen Hochschulrechenzentrum tätig.

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben