mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-25 09:12:24 +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);
|
set_transient_window_pos(dp->window, window);
|
||||||
gtk_widget_show(window);
|
gtk_widget_show(window);
|
||||||
gtk_main();
|
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);
|
G_CALLBACK(win_key_press), &dp);
|
||||||
|
|
||||||
gtk_main();
|
gtk_main();
|
||||||
|
post_main();
|
||||||
|
|
||||||
dlg_cleanup(&dp);
|
dlg_cleanup(&dp);
|
||||||
sfree(selparams);
|
sfree(selparams);
|
||||||
@ -3314,6 +3316,7 @@ int messagebox(GtkWidget *parentwin, const char *title, const char *msg,
|
|||||||
G_CALLBACK(win_key_press), &dp);
|
G_CALLBACK(win_key_press), &dp);
|
||||||
|
|
||||||
gtk_main();
|
gtk_main();
|
||||||
|
post_main();
|
||||||
|
|
||||||
dlg_cleanup(&dp);
|
dlg_cleanup(&dp);
|
||||||
ctrl_free_box(ctrlbox);
|
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)
|
void notify_remote_exit(void *frontend)
|
||||||
{
|
{
|
||||||
struct gui_data *inst = (struct gui_data *)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 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);
|
||||||
notify_toplevel_callback(inst);
|
inst->quit_fn_scheduled = FALSE;
|
||||||
|
} else {
|
||||||
inst->quit_fn_scheduled = FALSE;
|
/* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1467,7 +1513,7 @@ static gint idle_toplevel_callback_func(gpointer data)
|
|||||||
* already arranged one), so we can reschedule ourself then.
|
* already arranged one), so we can reschedule ourself then.
|
||||||
*/
|
*/
|
||||||
if (!inst->quit_fn_scheduled) {
|
if (!inst->quit_fn_scheduled) {
|
||||||
gtk_quit_add(2, quit_toplevel_callback_func, inst);
|
request_post_main(inst);
|
||||||
inst->quit_fn_scheduled = TRUE;
|
inst->quit_fn_scheduled = TRUE;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -80,6 +80,7 @@ long get_windowid(void *frontend);
|
|||||||
|
|
||||||
/* Things gtkdlg.c needs from pterm.c */
|
/* Things gtkdlg.c needs from pterm.c */
|
||||||
void *get_window(void *frontend); /* void * to avoid depending on gtk.h */
|
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 */
|
/* Things pterm.c needs from gtkdlg.c */
|
||||||
int do_config_box(const char *title, Conf *conf,
|
int do_config_box(const char *title, Conf *conf,
|
||||||
|
Loading…
Reference in New Issue
Block a user