vmagnin / gtk-fortran

A GTK / Fortran binding, and its documentation in the Wiki tab.
GNU General Public License v3.0
256 stars 43 forks source link

gtkf-sketcher.f90: important features are still missing in the GTK 4 version #207

Open vmagnin opened 4 years ago

vmagnin commented 4 years ago
[ 87%] Building Fortran object sketcher/CMakeFiles/gtkf-sketcher.dir/gtkf-sketcher.f90.o
/home/osboxes/gtk-fortran/sketcher/gtkf-sketcher.f90:151:43:

  151 |   use gtk, only: gtk_builder_add_from_file, gtk_builder_connect_signals, gtk_buil&
      |                                           1
Error: Symbol ‘gtk_builder_connect_signals’ referenced at (1) not found in module ‘gtk’
/home/osboxes/gtk-fortran/sketcher/gtkf-sketcher.f90:153:75:

  153 |   &FALSE, c_null_char, c_null_ptr, TRUE, gtk_init, gtk_builder_get_objects, gtk_builder_connect_signals_full,&
      |                                                                           1
Error: Symbol ‘gtk_builder_connect_signals_full’ referenced at (1) not found in module ‘gtk’
/home/osboxes/gtk-fortran/sketcher/gtkf-sketcher.f90:157:76:

  157 |   gtk_toggle_button_get_active, gtk_toggle_button_set_active,GTK_BUTTONS_OK,&
      |                                                                            1
Error: Symbol ‘gtk_widget_is_toplevel’ referenced at (1) not found in module ‘gtk’
/home/osboxes/gtk-fortran/sketcher/gtkf-sketcher.f90:158:96:

  158 |   gtk_widget_is_toplevel, gtk_list_store_append, gtk_list_store_set_value, gtk_list_store_clear,&
      |                                                                                                1
Error: Symbol ‘gtk_dialog_run’ referenced at (1) not found in module ‘gtk’
/home/osboxes/gtk-fortran/sketcher/gtkf-sketcher.f90:231:7:

  231 |   use connect
      |       1
Fatal Error: Cannot open module file ‘connect.mod’ for reading at (1): No such file or directory
compilation terminated.

Concerning GtkBuilder see: https://github.com/vmagnin/gtk-fortran/issues/178

The *.glade will also need to be ported (deprecated properties, widgets...). There is a tool to help: https://github.com/vmagnin/gtk-fortran/issues/188

Concerning gtk_dialog_run see: https://github.com/vmagnin/gtk-fortran/commit/07771a8262d3961f8a5af274635c7262041a325e#diff-97fecfaa97d43167048d8b722f36eb71

https://developer.gnome.org/gtk4/unstable/ch40s02.html#id-1.7.4.4.62

gtk_widget_is_toplevel has been removed gtk_widget_is_toplevel() has been removed. Use GTK_IS_ROOT, GTK_IS_NATIVE or GTK_IS_WINDOW instead, as appropriate.

See also the hl_gtk_file_chooser_show issue: https://github.com/vmagnin/gtk-fortran/issues/202

vmagnin commented 4 years ago

https://developer.gnome.org/gtk3/stable/GtkWidget.html#gtk-widget-is-toplevel

gtk_widget_is_toplevel () gboolean gtk_widget_is_toplevel (GtkWidget *widget); Determines whether widget is a toplevel widget. Currently only GtkWindow and GtkInvisible (and out-of-process GtkPlugs) are toplevel widgets. Toplevel widgets have no parent widget.

vmagnin commented 4 years ago

I have commented:

I have replaced:

    integer(c_int) :: dialog
    dialog = gtk_dialog_run (about_dialog)
    call gtk_widget_hide (about_dialog)

by this code (already used in bazaar.f90):

    call gtk_widget_show(widget)
    call g_signal_connect_swapped (widget, "response"//c_null_char, &
                              & c_funloc(gtk_window_destroy), widget)

As a result, gtkf-sketcher.f90 is built by CMake, but of course it does no function. At the moment, 10 critical errors appears on launch and no window appears:

[osboxes@localhost sketcher]$ ./gtkf-sketcher
 PWD: /home/osboxes/gtk-fortran/build/sketcher

(gtkf-sketcher:4348): Gtk-CRITICAL **: 10:05:27.875: gtk_combo_box_set_active: assertion 'GTK_IS_COMBO_BOX (combo_box)' failed
...
vmagnin commented 4 years ago

In GTK 3.99.2, gtk_buildable_get_name() has become gtk_buildable_get_buildable_id() The change was made in the gtk4-vmagnin branch.

vmagnin commented 3 years ago

I used $ gtk4-builder-tool simplify --3to4 gtkf-sketcher.glade to identify and remove deprecated properties from that Glade file. Then $ gtk4-builder-tool validate gtkf-sketcher.glade to identify and remove deprecated signals and objects. Finally I used $ gtk4-builder-tool simplify --3to4 --replace gtkf-sketcher.glade to port it to GTK 4. And I have done some more cleanup. By now in the gtk4-sketcher branch. I replaced the deprecated GtkMenuBar by simply two buttons, "File open" and "About". It's far more simple than to create a menu with GTK 4... As a result, gtkf-sketcher can be launched with its GUI.

vmagnin commented 3 years ago

The only big remaining problem is how to parse the signals of each object in the UI file: we need to store them in that array:

type signal_connection
    character(len=64)::object_name
    character(len=64)::signal_name
    character(len=64)::handler_name
  end type signal_connection

  type(signal_connection), dimension(:), allocatable::connections

Example of an object in a UI file:

          <object class="GtkButton" id="button1">
            <property name="hexpand">1</property>
            <property name="label" translatable="yes">Button1</property>
            <property name="receives_default">1</property>
            <signal name="clicked" handler="hello" swapped="no"/>
          </object>

Note that there could also be several signals.

In GTK3, it was made using two times gtk_builder_connect_signals_full() (removed from GTK 4): the subroutines count_connections (builder, object, signal_name, handler_name, connect_object, flags, user_data) and get_connections (builder, object, signal_name, handler_name, connect_object, flags, user_data) were defined as callback functions which were launched for each signal by gtk_builder_connect_signals_full().

I am not sure the answer given in the GTK Discourse is an answer to our problem: https://discourse.gnome.org/t/gtk-4-how-to-replace-gtk-builder-connect-signals/3561/2

vmagnin commented 3 years ago

Another problem in gtkf-sketcher is that in GTK 3, gtk_widget_is_toplevel() was used to identify the toplevel object in the UI file. In GTK 4, that function is gone. Updated: replaced by this code which give the name of the toplevel widget of a widget:

root =  gtk_buildable_get_buildable_id(gtk_widget_get_root(gpointer))
call C_F_string_ptr(root, f_string)
vmagnin commented 3 years ago

See also https://discourse.gnome.org/t/need-help-in-understanding-autoconnecting-signals-from-builder-in-gtk-4/7420