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:
parent
78592116a5
commit
7a80ab14e0
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
/*
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user