Segfault when closing AdwMessageDialog with focused GtkPasswordEntry in it
Running this minimal reproducer and pressing escape causes a segmentation fault:
#!/usr/bin/env python
import gi
gi.require_version("Gtk", "4.0")
gi.require_version("Adw", "1")
from gi.repository import Gtk
from gi.repository import Adw
xml = """
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="AdwMessageDialog" id="dialog">
<property name="extra-child">
<object class="GtkPasswordEntry">
</object>
</property>
</object>
</interface>
"""
def on_activate(app):
win = Adw.ApplicationWindow(application=app)
builder = Gtk.Builder().new_from_string(xml, -1)
builder.get_object("dialog").present()
app = Gtk.Application()
app.connect('activate', on_activate)
app.run(None)
C reproducer
#include <gtk/gtk.h>
#define OBJ_TYPE_TESTW (obj_testw_get_type ())
G_DECLARE_FINAL_TYPE (ObjTestw, obj_testw, OBJ, TESTW, GtkWindow)
struct _ObjTestwClass
{
GtkWindowClass parent_class;
};
typedef struct _ObjTestwPrivate ObjTestwPrivate;
struct _ObjTestwPrivate {
GtkWidget* entry;
};
struct _ObjTestw {
GtkWindow parent;
};
G_DEFINE_TYPE_WITH_PRIVATE (ObjTestw, obj_testw, GTK_TYPE_WINDOW)
GtkWidget *
obj_testw_new ()
{
GtkWidget *dialog;
dialog = g_object_new (OBJ_TYPE_TESTW, NULL);
ObjTestw *self = OBJ_TESTW (dialog);
ObjTestwPrivate *priv = obj_testw_get_instance_private (self);
GtkWidget *entry = gtk_password_entry_new ();
priv->entry = entry;
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_append (GTK_BOX (box), entry);
gtk_window_set_child (GTK_WINDOW (dialog), box);
gtk_window_set_focus (GTK_WINDOW (dialog), entry);
return dialog;
}
void
obj_testw_dispose (GObject *object) {
GtkWindow *win = GTK_WINDOW (object);
ObjTestw *self = OBJ_TESTW (object);
ObjTestwPrivate *priv = obj_testw_get_instance_private (self);
GtkWidget *box = gtk_window_get_child (win);
gtk_box_remove (GTK_BOX (box), priv->entry);
priv->entry = NULL;
G_OBJECT_CLASS (obj_testw_parent_class)->dispose (object);
}
static void
obj_testw_class_init (ObjTestwClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = obj_testw_dispose;
gtk_widget_class_add_binding_action (
GTK_WIDGET_CLASS (klass),
GDK_KEY_Escape,
0,
"window.close",
NULL
);
}
static void
obj_testw_init (ObjTestw *self)
{
}
void
activate (GtkApplication *app)
{
GtkWidget* win = gtk_application_window_new (app);
GtkWidget* dialog = obj_testw_new ();
gtk_window_present (GTK_WINDOW (win));
gtk_window_present (GTK_WINDOW (dialog));
}
int
main (int argc, char *argv[])
{
g_autoptr (GtkApplication) app = NULL;
app = gtk_application_new ("org.example.Test", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
return g_application_run (G_APPLICATION (app), argc, argv);
}
gcc `pkg-config --cflags gtk4` main.c `pkg-config --libs gtk4` -o main
This actually happens in Pika Backup 0.5.0-beta.3 password dialog which I did not release yet for this reason.
Edited by Sophie Herold