I'm trying to create an application with GtkAda and need the user to select a file from his PC. However, I found no way to create a file chooser without leading to this error: raised PROGRAM_ERROR : unhandled signal.
I tried creating a file chooser button and link it to a file chooser dialog. It leads to the same error.
I tried creating a file chooser dialog and file chooser button in GPS but same error.
Then I found the Gtkada.File_Selection package. Its description says it handles himself the signals and only needs a single function. Sadly, it leads to the same fateful error.
I'm working on Fedora 29. GtkAda version 2018, GPS 2018 and GNAT 8.3.1.
with Gtkada.File_Selection; use Gtkada.File_Selection;
package Log_Filter_Handlers is
Retour : Unbounded_String;
procedure Button_Select_File_Clicked
(Self : access Gtk_Button_Record'Class);
end Log_Filter_Handlers;
procedure Button_Select_File_Clicked
(Self : access Gtk_Button_Record'Class) is
begin
Retour := To_Unbounded_String
(File_Selection_Dialog (Title => "Select your file",
Default_Dir => "",
Dir_Only => False,
Must_Exist => True) );
end Button_Select_File_Clicked;
package Gtkada.File_Selection is
function File_Selection_Dialog
(Title : Glib.UTF8_String := "Select File";
Default_Dir : String := "";
Dir_Only : Boolean := False;
Must_Exist : Boolean := False) return String;
end Gtkada.File_Selection;
As soon as the application creates a file chooser widget (be it dialog or button), in this case by calling Button_Select_File_Clicked. It immediately leads to this error:
raised PROGRAM_ERROR : unhandled signal
I'm having some warnings too
Gtk-Message: 10:43:33.615: Failed to load module "pk-gtk-module"
Gtk-Message: 10:43:33.615: Failed to load module "canberra-gtk-module"
Gtk-Message: 10:43:33.616: Failed to load module "pk-gtk-module"
Gtk-Message: 10:43:33.616: Failed to load module "canberra-gtk-module"
Fontconfig warning: "/home/bob/Applications/Gnat_IDE/Gnat-community/etc/fonts/fonts.conf", line 86: unknown element "blank"
(log_filter_main:24417): Gtk-WARNING **: 10:43:33.841: Could not load a pixbuf from icon theme.
This may indicate that pixbuf loaders or the mime database could not be found.
Thank you.
It's hard to say what causes the unhandled signal error. You could consider making a stack trace to see where the exception is raised (see also the example on Rosetta code).
The example below works on GNAT CE 2019. You could test it in your own environment to see if the problem persists, or test your own code with latest version of GtkAda found on GitHub.
Update
A quick search reveals that a Program_Error
with message "unhandled signal" is never raised from GtkAda. In fact, it seems that this kind of exception can only occur in the GNAT/Ada run-time (see init.c
and seh_init.c
). And while seh_init.c
is used only by the run-times targeting Win32 and Cygwin (see comments near the beginning of that file), init.c
, is used in various other run-times including the one for Linux. Hence, I think that the Program_Error
you observe is raised in init.c
because some kernel signal cannot be handled by the GNAT/Ada run-time.
You might obtain some additional information by tracing the signals send to your application (see also this post on SO):
strace -e 'trace=!all' <program_name>
main.adb
with File_Selection_Demo;
procedure Main is
begin
File_Selection_Demo.Run;
end Main;
file_selection_demo.ads
package File_Selection_Demo is
procedure Run;
end File_Selection_Demo;
file_selection_demo.adb
with Ada.Text_IO;
with Gtk.Main;
with Gtk.Widget;
with Gtk.Builder;
with Gtk.Window;
with Gtk.Button;
with Gtk.GEntry;
with Gtkada.File_Selection;
with Glib; use Glib;
with Glib.Error; use Glib.Error;
package body File_Selection_Demo is
-- Widgets
Builder : Gtk.Builder.Gtk_Builder;
Window : Gtk.Window.Gtk_Window;
Button : Gtk.Button.Gtk_Button;
GEntry : Gtk.GEntry.Gtk_Entry;
procedure Destroy_Event_Callback
(Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
procedure Clicked_Event_Callback
(Button : access Gtk.Button.Gtk_Button_Record'Class);
---------
-- Run --
---------
procedure Run is
use Gtk.Builder;
use Gtk.Window;
use Gtk.Button;
use Gtk.GEntry;
Success : GUint;
Error : aliased GError;
begin
-- Initialize GtkAda.
Gtk.Main.Init;
-- Construct a Gtk_Builder instance and load our UI description.
Gtk_New (Builder);
Success := Builder.Add_From_File ("./example.glade", Error'Access);
if Success = 0 then
Ada.Text_IO.Put_Line ("failed to read Glade file");
Error_Free (Error);
return;
end if;
-- Entry
GEntry := Gtk_Entry (Builder.Get_Object ("Entry"));
-- Button
Button := Gtk_Button (Builder.Get_Object ("Button"));
Button.On_Clicked (Clicked_Event_Callback'Access);
-- Window
Window := Gtk_Window (Builder.Get_Object ("Window"));
Window.On_Destroy (Destroy_Event_Callback'Access);
Window.Show_All;
-- Start the main event loop
Gtk.Main.Main;
end Run;
----------------------------
-- Destroy_Event_Callback --
----------------------------
procedure Destroy_Event_Callback
(Widget : access Gtk.Widget.Gtk_Widget_Record'Class)
is
begin
Gtk.Main.Main_Quit;
end Destroy_Event_Callback;
----------------------------
-- Clicked_Event_Callback --
----------------------------
procedure Clicked_Event_Callback
(Button : access Gtk.Button.Gtk_Button_Record'Class) is
begin
declare
Response : String :=
Gtkada.File_Selection.File_Selection_Dialog
(Title => "Select your file",
Default_Dir => "",
Dir_Only => False,
Must_Exist => True);
begin
GEntry.Set_Text (Response);
end;
end Clicked_Event_Callback;
end File_Selection_Demo;
example.glade
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<object class="GtkWindow" id="Window">
<property name="can_focus">False</property>
<property name="title" translatable="yes">GTK File Selector Demo</property>
<property name="resizable">False</property>
<property name="window_position">center</property>
<child>
<object class="GtkBox" id="HBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkEntry" id="Entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="margin_left">10</property>
<property name="margin_right">10</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="hexpand">True</property>
<property name="editable">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="Button">
<property name="label" translatable="yes">Choose File...</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="margin_left">10</property>
<property name="margin_right">12</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>