1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 09:58:01 +00:00

GTK 3 prep: write a replacement for gtk_quit_add().

GTK 2 has deprecated it and provided no replacement; a bug tracker
entry I found on the subject suggested that it was functionality that
didn't really belong in GTK, and glib ought to provide a replacement
instead, which would be a perfectly fine thing to suggest if they had
waited for glib to get round to doing so *before* throwing out a
function people were actually using. Sigh.

Anyway, it turns out that subsidiary invocations of gtk_main() don't
happen inside GTK as far as I can see, so all I need to do is to make
sure my own invocations of gtk_main() are followed by a cleanup
function which runs any quit functions that I've registered.

That was the last deprecated GTK function, so we now build cleanly
with -DGTK_DISABLE_DEPRECATED. (But, as mentioned a couple of commits
ago, we still don't build with -DGDK_DISABLE_DEPRECATED, because that
has migrating to Cairo drawing as a prerequisite.)
This commit is contained in:
Simon Tatham 2015-08-09 11:33:43 +01:00
parent 78592116a5
commit 7a80ab14e0
3 changed files with 57 additions and 7 deletions

View File

@ -1094,6 +1094,7 @@ void dlg_error_msg(void *dlg, const char *msg)
set_transient_window_pos(dp->window, window);
gtk_widget_show(window);
gtk_main();
post_main();
}
/*
@ -3209,6 +3210,7 @@ int do_config_box(const char *title, Conf *conf, int midsession,
G_CALLBACK(win_key_press), &dp);
gtk_main();
post_main();
dlg_cleanup(&dp);
sfree(selparams);
@ -3314,6 +3316,7 @@ int messagebox(GtkWidget *parentwin, const char *title, const char *msg,
G_CALLBACK(win_key_press), &dp);
gtk_main();
post_main();
dlg_cleanup(&dp);
ctrl_free_box(ctrlbox);

View File

@ -1435,6 +1435,48 @@ static void exit_callback(void *vinst)
}
}
/*
* Replacement code for the gtk_quit_add() function, which GTK2 - in
* their unbounded wisdom - deprecated without providing any usable
* replacement, and which we were using to ensure that our idle
* function for toplevel callbacks was only run from the outermost
* gtk_main().
*
* We maintain a global variable with a list of 'struct gui_data'
* instances on which we should call inst_post_main() when a
* subsidiary gtk_main() terminates; then we must make sure that all
* our subsidiary calls to gtk_main() are followed by a call to
* post_main().
*
* This is kind of overkill in the sense that at the time of writing
* we don't actually ever run more than one 'struct gui_data' instance
* in the same process, but we're _so nearly_ prepared to do that that
* I want to remain futureproof against the possibility of doing so in
* future.
*/
struct post_main_context {
struct post_main_context *next;
struct gui_data *inst;
};
struct post_main_context *post_main_list_head = NULL;
static void request_post_main(struct gui_data *inst)
{
struct post_main_context *node = snew(struct post_main_context);
node->next = post_main_list_head;
node->inst = inst;
post_main_list_head = node;
}
static void inst_post_main(struct gui_data *inst);
void post_main(void)
{
while (post_main_list_head) {
struct post_main_context *node = post_main_list_head;
post_main_list_head = node->next;
inst_post_main(node->inst);
sfree(node);
}
}
void notify_remote_exit(void *frontend)
{
struct gui_data *inst = (struct gui_data *)frontend;
@ -1444,13 +1486,17 @@ void notify_remote_exit(void *frontend)
static void notify_toplevel_callback(void *frontend);
static gint quit_toplevel_callback_func(gpointer data)
static void inst_post_main(struct gui_data *inst)
{
struct gui_data *inst = (struct gui_data *)data;
if (gtk_main_level() == 1) {
notify_toplevel_callback(inst);
inst->quit_fn_scheduled = FALSE;
} else {
/* Apparently we're _still_ more than one level deep in
* gtk_main() instances, so we'll need another callback for
* when we get out of the next one. */
request_post_main(inst);
}
return 0;
}
@ -1467,7 +1513,7 @@ static gint idle_toplevel_callback_func(gpointer data)
* already arranged one), so we can reschedule ourself then.
*/
if (!inst->quit_fn_scheduled) {
gtk_quit_add(2, quit_toplevel_callback_func, inst);
request_post_main(inst);
inst->quit_fn_scheduled = TRUE;
}
/*

View File

@ -80,6 +80,7 @@ long get_windowid(void *frontend);
/* Things gtkdlg.c needs from pterm.c */
void *get_window(void *frontend); /* void * to avoid depending on gtk.h */
void post_main(void); /* called after any subsidiary gtk_main() */
/* Things pterm.c needs from gtkdlg.c */
int do_config_box(const char *title, Conf *conf,