Journal gtk-fortran 20.04 déconfinée, GTK 4 approche

Posté par  (site web personnel) . Licence CC By‑SA.
33
18
mai
2020

Sommaire

Ce journal annonce la sortie de l'interface gtk-fortran 20.04 basée sur GTK 3.24.18 et GLib 2.64.2, mais c'est aussi un bon prétexte pour faire le point sur le développement de GTK 4.

gtk-fortran 20.04

Je vous ai déjà parlé de gtk-fortran il y a un an 1. Pour résumer, comme son nom l'indique il s'agit d'une interface (binding) GTK / Fortran, multi-plateforme (Linux, Windows via MSYS2, BSD, macOS, Raspberry Pi) et sous licence GNU GPLv3, basée sur le module ISO_C_BINDING introduit dans la norme Fortran 2003. Elle permet également d'accéder à la librairie de tracé scientifique PLplot 2.

La version 20.04 est basée sur GTK 3.24.18 et GLib 2.64.2. Mais l'objectif principal de cette version était surtout de commencer à préparer la migration vers le futur GTK 4. Pour cela, un grand nettoyage a été fait dans l'ensemble du projet : scripts, système de build CMake, exemples (retrait de fonctions obsolètes, c'est-à-dire qui disparaîtront dans GTK 4)… Les nombreux changements sont listés dans le fichier CHANGELOG.md du projet.

Dès publication de cette version GTK 3, une branche de développement gtk4 a ainsi pu être créée. Le cœur de la librairie est déjà prêt pour GTK 4 (ou du moins GTK 3.98.3 !). Certains exemples fonctionnent déjà. L'essentiel du travail consistera désormais à mettre à jour chaque exemple en fonction des évolutions introduites dans GTK 4, puis la librairie High Level et ses exemples (plus difficile car c'est une partie du projet dans laquelle je suis personnellement très peu intervenu jusqu'à maintenant).

Si vous voulez jeter un œil au projet, inutile de vous munir d'un lecteur de cartes perforées ;-), il est hébergé sur GitHub : https://github.com/vmagnin/gtk-fortran/wiki

Pour les curieux, j'ai mis en annexe tout en bas de cette page un exemple de code Fortran permettant d'ouvrir une fenêtre GTK 4 vide (exemple gtkzero_gapp.f90 du projet dont j'ai retiré les nombreux commentaires).

GTK 4

Vous noterez que j'utilise dans ce journal la graphie actuelle du projet : le +, relique de l'époque où GTK s'est émancipé de Gimp, a été supprimé il y environ un an 3.

Où en est GTK 4 ?

Le développement de GTK 4 a commencé vers fin 2016, après publication de GTK 3.22 4. En 2018, sa sortie avait été annoncée pour le printemps 2019 5 mais à l'été 2019 elle avait été repoussée à l'automne 2020 6 pour GNOME 3.38.

Je ne m'engagerai pas à affirmer que ce délai sera tenu, mais une sortie à l'automne ou à l'hiver me semble raisonnable au vu du taux de 90 % d'achèvement du projet visible aujourd'hui sur son GitLab : https://gitlab.gnome.org/GNOME/gtk/milestones/1

D'autre part, on constate depuis janvier une forte accélération de la communication de la part de l'équipe de développement sur son blog : https://blog.gtk.org/

La version 3.98.3 a été taguée il y a trois semaines dans le GitLab du projet et est disponible par exemple dans la toute fraîche Fedora 32. Une fois les paquets installés, vous pouvez lancer l'ensemble des exemples et visualiser leur code source via l'application de démonstration :

$ gtk4-demo

Enfin, vous pouvez vous tenir au courant de tout ce qui touche à GTK 4 via ces deux pages :

Migrer vers GTK 4

Les changements, petits et grands, introduits depuis la version 3.90 sont nombreux comme on peut s'y attendre dans une version majeure (la précédente, GTK 3, est sortie il y a quand même neuf ans). Les changements les plus importants sont résumés dans ce tableau : https://en.wikipedia.org/wiki/GTK#GTK4

GTK étant une collection de bibliothèques totalisant plus de dix milles fonctions, je me contenterai de rendre compte rapidement de ma petite expérience personnelle dans mon travail actuel de migration de gtk-fortran vers GTK 4.

Heureusement, la documentation officielle est très complète (j'ai l'impression que sa qualité est bien meilleure qu'il y a dix ans) et une page est en particulier dédiée à la migration des applications de GTK 3 vers GTK 4 : https://developer.gnome.org/gtk4/unstable/gtk-migrating-3-to-4.html

Se préparer dans GTK 3

La première étape consiste, au sein de GTK 3, à se débarrasser autant que possible des fonctions et objets marqués obsolètes ("deprecated") qui disparaîtront dans GTK 4, en suivant ces conseils :
https://developer.gnome.org/gtk4/unstable/gtk-migrating-3-to-4.html#id-1.7.4.3

Les APIs qui disparaîtront entièrement dans GTK 4 sont d'ailleurs regroupées dans des répertoires deprecated, par exemple :
/usr/include/gtk-3.0/gtk/deprecated

Les fichiers d'en-tête .h spécifient pour chaque fonction son statut : GDK_AVAILABLE_IN_ALL, GDK_AVAILABLE_IN_3_10… Et pour certaines sa remplaçante est indiquée :

GDK_DEPRECATED_IN_3_20_FOR(gtk_window_set_default_size)
void gtk_window_set_default_geometry (GtkWindow *window,
                                      gint       width,
                                      gint       height);

Et dans la documentation GTK 3, vous trouverez généralement pour chaque fonction obsolète des conseils pour son remplacement.

Par exemple, la famille de fonctions gtk_main_* disparaît et il est maintenant recommandé d'utiliser une GtkApplication, qui permet d'obtenir une application initialisée au mieux pour s'intégrer au système. Mais il est toujours possible d'accéder directement aux fonctions équivalentes de la GLib : on pourra donc remplacer par exemple gtk_main_iteration(), qui permet de n'exécuter qu'une seule itération de la boucle principale, par g_main_context_iteration(). De même gtk_events_pending(), qui permet de traiter les événements en attente, peut être remplacée par g_main_context_pending().

Lors du passage à GTK 4

La seconde étape de la migration consiste à remplacer tout ce qui a disparu et doit être remplacé par les nouveautés de GTK 4 : https://developer.gnome.org/gtk4/unstable/ch32s02.html

A nouveau, la documentation est bien faite et mise à jour au fil des versions 3.9x, ce qui permet de s'en sortir.

Exemple de changement mineur, les widgets sont désormais visibles par défaut alors que dans GTK 3 il fallait les rendre visibles soit un par un avec gtk_widget_show(), soit pour l'ensemble avec gtk_widget_show_all(). Désormais seule la fenêtre principale doit donc être rendue visible avec gtk_widget_show().

De nombreux autres changements m'attendent, comme par exemple des modifications dans la gestions des événements (gestion de la souris…) ou des menus : https://github.com/vmagnin/gtk-fortran/issues

Annexe "Hello World !"

Ce code source Fortran est l'équivalent du code C disponible ici : https://developer.gnome.org/gtk4/3.98/gtk-getting-started.html#id-1.2.3.5

Vous remarquerez l'utilisation du module ISO_C_BINDING qui permet d'obtenir des types de données compatibles entre C et Fortran. Les modules gtk et g, générés par gtk-fortran, contiennent quant à eux des interfaces Fortran pour les fonctions GTK et GLib. Vous remarquerez aussi l'utilisation de c_null_char pour gérer le fait que les chaînes Fortran ne se terminent pas par un octet nul, contrairement à celles du C.

module handlers
  use iso_c_binding, only: c_ptr, c_null_char
  use gtk, only: gtk_window_set_default_size, gtk_window_set_title, &
               & gtk_widget_show, gtk_application_window_new
  implicit none

contains
  subroutine activate(app, gdata) bind(c)
    type(c_ptr), value, intent(in) :: app, gdata
    type(c_ptr)                    :: window

    window = gtk_application_window_new(app)
    call gtk_window_set_default_size(window, 300, 200)
    call gtk_window_set_title(window, "Hello GLib & GTK world!"//c_null_char)
    call gtk_widget_show(window)  
  end subroutine activate
end module handlers

program gtkzero
  use iso_c_binding, only: c_ptr, c_int, c_null_char, c_null_ptr, c_funloc
  use gtk, only: gtk_application_new, g_signal_connect, G_APPLICATION_FLAGS_NONE
  use g, only: g_application_run, g_object_unref
  use handlers

  implicit none
  integer(c_int)     :: status
  type(c_ptr)        :: app

  app = gtk_application_new("gtk-fortran.examples.gtkzero"//c_null_char, &
                            & G_APPLICATION_FLAGS_NONE)
  call g_signal_connect(app, "activate"//c_null_char, c_funloc(activate), c_null_ptr)
  status = g_application_run(app, 0_c_int, c_null_ptr)
  print *, "You have exited the GLib main loop, bye, bye..."
  call g_object_unref(app)
end program gtkzero

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.