Re: emitting the "delete_event" in a "key_press_event" --> crash
- From: Olexiy Avramchenko <ath beast stu cn ua>
- To: Olivier Sessink <olivier lx student wau nl>
- Cc: Owen Taylor <otaylor redhat com>, gtk-app-devel-list gnome org
- Subject: Re: emitting the "delete_event" in a "key_press_event" --> crash
- Date: Thu, 07 Nov 2002 14:41:06 +0200
Olivier wrote:
Hi all,
I want my dialogs to close when the user presses the escape key. So I
attached to the key_press_event, and if the key is escape I emit the
delete event. Immediately the delete event destroys the window, and then
the programs continues with the key-press-event (on a widget that doesn't
exist anymore!!) and crashes (tha backtrace says it segfaults somewhere
inside gtk).
how do I do this in a way that doesn't crash gtk?
The usual solution is to pass gtk_main_quit as callback to "delete_event"
of root window of your app. This trivial solution will always work, I
changed
this way the code you posted (look at attach). This doesnt explain
however why app not terminated when hitting ESC in root.
BTW: you code produce no seg faults in my system, just not exit to console
after main window unmaps.
Olexiy
/*
escape_testcase.c
compile with
gcc escape_testcase.c -o escape_testcase `pkg-config --cflags --libs gtk+-2.0
*/
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
static void create_testwin();
static gboolean create_window_key_press_event_lcb(GtkWidget *widget, GdkEventKey *event,GtkWidget *win)
{
if (event->keyval == GDK_Escape) {
g_signal_emit_by_name(G_OBJECT(win), "delete_event");
/* gtk_widget_destroy(win);*/
return TRUE;
}
return FALSE;
}
GtkWidget *create_window(GCallback close_func,gpointer close_data) {
GtkWidget *returnwidget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(returnwidget), "delete_event", close_func, close_data);
g_signal_connect(G_OBJECT(returnwidget), "destroy", close_func, close_data);
g_signal_connect(G_OBJECT(returnwidget), "key_press_event",
G_CALLBACK(create_window_key_press_event_lcb), returnwidget);
return returnwidget;
}
GtkWidget *create_root_window(GCallback close_func,gpointer close_data) {
GtkWidget *returnwidget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(returnwidget), "delete_event", gtk_main_quit, NULL);
/* g_signal_connect(G_OBJECT(returnwidget), "destroy", close_func, close_data); */
g_signal_connect(G_OBJECT(returnwidget), "key_press_event",
G_CALLBACK(create_window_key_press_event_lcb), returnwidget);
return returnwidget;
}
typedef struct {
GtkWidget *win;
int various_other_data;
} TestWinStruct;
void testwin_destroy_cb(GtkWidget * widget, GdkEvent *event, TestWinStruct *testwin) {
g_signal_handlers_destroy(G_OBJECT(testwin->win));
gtk_widget_destroy(testwin->win);
g_free(testwin);
}
static void testwin_button_clicked_cb(GtkWidget *widget, gpointer data) {
create_testwin();
}
static void create_testwin() {
GtkWidget *button;
TestWinStruct *testwin;
testwin = g_new(TestWinStruct,1);
testwin->win = create_window(G_CALLBACK(testwin_destroy_cb), testwin);
button = gtk_button_new_with_label("create another testwin\n");
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(testwin_button_clicked_cb), NULL);
gtk_container_add(GTK_CONTAINER(testwin->win), button);
gtk_widget_show_all(testwin->win);
}
static void create_root_testwin() {
GtkWidget *button;
TestWinStruct *testwin;
testwin = g_new(TestWinStruct,1);
testwin->win = create_root_window(G_CALLBACK(testwin_destroy_cb), testwin);
button = gtk_button_new_with_label("create another testwin\n");
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(testwin_button_clicked_cb), NULL);
gtk_container_add(GTK_CONTAINER(testwin->win), button);
gtk_widget_show_all(testwin->win);
}
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
create_root_testwin();
gtk_main();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]