<p>I have been trying to implement Win32's <code>MessageBox</code> using GTK. The app uses SDL/OpenGL, so this isn't a GTK app.</p>
<p>I handle the initialization (<code>gtk_init</code>) sort of stuff inside the <code>MessageBox</code> function as follows:</p>
<pre><code>int MessageBox(HWND hwnd, const char* text, const char* caption, UINT type)
{
    GtkWidget *window = NULL;
    GtkWidget *dialog = NULL;

    gtk_init(&amp;gtkArgc, &amp;gtkArgv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(G_OBJECT(window), &quot;delete_event&quot;, G_CALLBACK(delete_event), NULL);
    g_signal_connect(G_OBJECT(window), &quot;destroy&quot;, G_CALLBACK(destroy), NULL);
    // gcallback calls gtk_main_quit()
    gtk_init_add((GtkFunction)gcallback, NULL);

    if (type &amp; MB_YESNO) {
        dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, text);
    } else {
        dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, text);
    }

    gtk_window_set_title(GTK_WINDOW(dialog), caption);
    gint result = gtk_dialog_run(GTK_DIALOG(dialog));

    gtk_main();

    gtk_widget_destroy(dialog);

    if (type &amp; MB_YESNO) {
        switch (result) {
        default:
        case GTK_RESPONSE_DELETE_EVENT:
        case GTK_RESPONSE_NO:
            return IDNO;
            break;
        case GTK_RESPONSE_YES:
            return IDYES;
            break;
        }
    }

    return IDOK;
} 
</code></pre>
<p>Now, I am by no means an experienced GTK programmer, and I realize that I'm probably doing something horribly wrong.</p>
<p>However, my problem is that the last dialog popped up with this function staying around until the process exits. Any ideas?</p>

[{'answer_id': 537, 'author': 'Joe Shaw', 'author_id': 156, 'author_profile': 'https://Stackoverflow.com/users/156', 'pm_score': 3, 'selected': False, 'text': '<p>A few things:</p>\n\n<p>You are creating (and not using) an unnecessary toplevel window, named <code>window</code>.  You can just delete these lines:</p>\n\n<pre><code>window = gtk_window_new(GTK_WINDOW_TOPLEVEL);\ng_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);\ng_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);\n</code></pre>\n\n<p>Also, the flow doesn\'t seem quite right.  <code>gtk_main()</code> starts the GTK main loop, which blocks until something exits it.  <code>gtk_dialog_run()</code> also starts a main loop, but it exits as soon as one of the buttons is clicked.</p>\n\n<p>I think it might be enough for you to remove the <code>gtk_init_add()</code> and <code>gtk_main()</code> calls, and simply deal with the return value.  Also the <code>gtk_widget_destroy()</code> call is unnecessary, as the dialog window is automatically destroyed when gtk_dialog_run() returns.</p>\n'}, {'answer_id': 607, 'author': 'Joe Shaw', 'author_id': 156, 'author_profile': 'https://Stackoverflow.com/users/156', 'pm_score': 5, 'selected': True, 'text': '<p>Hmm, ok. I\'d suggest code like this, then:</p>\n<pre class="lang-c prettyprint-override"><code>typedef struct {\n    int type;\n    int result;\n} DialogData;\n    \nstatic gboolean\ndisplay_dialog(gpointer user_data)\n{\n    DialogData *dialog_data = user_data;\n    GtkWidget *dialog;\n    \n    if (dialog_data-&gt;type &amp; MB_YESNO)\n        dialog = gtk_message_dialog_new(...);\n    else\n        dialog = gtk_message_dialog_new(...);\n    \n    // Set title, etc.\n    \n    dialog_data-&gt;result = gtk_dialog_run(...);\n    \n    gtk_main_quit();  // Quits the main loop run in MessageBox()\n    \n    return FALSE;\n}\n    \nint MessageBox(...)\n{\n    DialogData dialog_data;\n    \n    dialog_data.type = type;\n    \n    gtk_idle_add(display_dialog, &amp;dialog_data);\n    \n    gtk_main();\n    \n    // Do stuff based on dialog_data.result\n}\n</code></pre>\n<p>The struct is required because you need to pass around a couple pieces of data. The <code>gtk_idle_add()</code> call adds a method to be run when the main loop is running and idle, and the <code>FALSE</code> return value from the <code>display_dialog()</code> call means that it\'s only run once.  After we get the result from the dialog, we quit the main loop. That\'ll cause the <code>gtk_main()</code> in your main <code>MessageBox()</code> method to return, and you\'ll be able to access the result from there.</p>\n'}, {'answer_id': 2959398, 'author': 'Platypus', 'author_id': 356325, 'author_profile': 'https://Stackoverflow.com/users/356325', 'pm_score': 3, 'selected': False, 'text': '<p>To manage a dialog box with GTK+, use a GtkDialog and <a href="http://library.gnome.org/devel/gtk/stable/GtkDialog.html#gtk-dialog-run" rel="noreferrer">gtk_dialog_run()</a> instead of managing a window and a main loop by yourself.</p>\n\n<p><strong>EDIT / ADDENDUM :</strong></p>\n\n<p>What I mean is "just use" : I don\'t understand why you create a windows you never use and a main loop which seems useless (at least from the piece of code you posted). You can write something as short as :</p>\n\n<pre><code>int MessageBox(HWND hwnd, const char* text, const char* caption, UINT type)\n{\n    GtkWidget *dialog ;\n\n    /* Instead of 0, use GTK_DIALOG_MODAL to get a modal dialog box */\n\n    if (type &amp; MB_YESNO)\n        dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, text );\n    else\n        dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, text );\n\n\n    gtk_window_set_title(GTK_WINDOW(dialog), caption);\n    gint result = gtk_dialog_run(GTK_DIALOG(dialog));\n    gtk_widget_destroy( GTK_WIDGET(dialog) );\n\n    if (type &amp; MB_YESNO)\n    {\n        switch (result)\n        {\n        default:\n        case GTK_RESPONSE_DELETE_EVENT:\n        case GTK_RESPONSE_NO:\n            return IDNO;\n        case GTK_RESPONSE_YES:\n            return IDYES;\n        }\n        return IDOK;\n    } \n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/263', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/61/']