1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-05-28 23:34:49 -05:00

Make connection_fatal() nonmodal.

This change requires me to break up the general cleanups in
delete_inst() into two halves: one runs when the error message box is
created, and cleans up the network connection and all the stuff
associated with it, and the other runs when the error message is
dismissed and the window can actually close.
This commit is contained in:
Simon Tatham 2017-11-26 19:59:24 +00:00
parent 813c380470
commit 3e24bb610d
3 changed files with 60 additions and 32 deletions

View File

@ -3691,13 +3691,6 @@ void old_keyfile_warning(void)
*/
}
void fatal_message_box(void *window, const char *msg)
{
message_box(window, "PuTTY Fatal Error", msg,
string_width("REASONABLY LONG LINE OF TEXT FOR BASIC SANITY"),
FALSE, &buttons_ok);
}
void nonfatal_message_box(void *window, const char *msg)
{
char *title = dupcat(appname, " Error", NULL);

View File

@ -167,6 +167,38 @@ static int send_raw_mouse;
static void start_backend(struct gui_data *inst);
static void exit_callback(void *vinst);
static void destroy_inst_connection(struct gui_data *inst);
static void delete_inst(struct gui_data *inst);
static void post_fatal_message_box_toplevel(void *vctx)
{
struct gui_data *inst = (struct gui_data *)vctx;
gtk_widget_destroy(inst->window);
}
static void post_fatal_message_box(void *vctx, int result)
{
struct gui_data *inst = (struct gui_data *)vctx;
unregister_dialog(inst, DIALOG_SLOT_CONNECTION_FATAL);
queue_toplevel_callback(post_fatal_message_box_toplevel, inst);
}
void fatal_message_box(struct gui_data *inst, const char *msg)
{
char *title = dupcat(appname, " Fatal Error", NULL);
GtkWidget *dialog = create_message_box(
inst->window, title, msg,
string_width("REASONABLY LONG LINE OF TEXT FOR BASIC SANITY"),
FALSE, &buttons_ok, post_fatal_message_box, inst);
register_dialog(inst, DIALOG_SLOT_CONNECTION_FATAL, dialog);
sfree(title);
}
static void connection_fatal_callback(void *vinst)
{
struct gui_data *inst = (struct gui_data *)vinst;
destroy_inst_connection(inst);
}
void connection_fatal(void *frontend, const char *p, ...)
{
@ -177,10 +209,11 @@ void connection_fatal(void *frontend, const char *p, ...)
va_start(ap, p);
msg = dupvprintf(p, ap);
va_end(ap);
fatal_message_box(inst->window, msg);
fatal_message_box(inst, msg);
sfree(msg);
queue_toplevel_callback(exit_callback, inst);
inst->exited = TRUE; /* suppress normal exit handling */
queue_toplevel_callback(connection_fatal_callback, frontend);
}
/*
@ -2062,19 +2095,9 @@ static void exit_callback(void *vinst)
if (!inst->exited &&
(exitcode = inst->back->exitcode(inst->backhandle)) >= 0) {
inst->exited = TRUE;
close_on_exit = conf_get_int(inst->conf, CONF_close_on_exit);
if (inst->ldisc) {
ldisc_free(inst->ldisc);
inst->ldisc = NULL;
}
inst->back->free(inst->backhandle);
inst->backhandle = NULL;
inst->back = NULL;
term_provide_resize_fn(inst->term, NULL, NULL);
update_specials_menu(inst);
gtk_widget_set_sensitive(inst->restartitem, TRUE);
destroy_inst_connection(inst);
close_on_exit = conf_get_int(inst->conf, CONF_close_on_exit);
if (close_on_exit == FORCE_ON ||
(close_on_exit == AUTO && exitcode == 0)) {
gtk_widget_destroy(inst->window);
@ -2089,6 +2112,26 @@ void notify_remote_exit(void *frontend)
queue_toplevel_callback(exit_callback, inst);
}
static void destroy_inst_connection(struct gui_data *inst)
{
inst->exited = TRUE;
if (inst->ldisc) {
ldisc_free(inst->ldisc);
inst->ldisc = NULL;
}
if (inst->backhandle) {
inst->back->free(inst->backhandle);
inst->backhandle = NULL;
inst->back = NULL;
}
if (inst->term)
term_provide_resize_fn(inst->term, NULL, NULL);
if (inst->menu) {
update_specials_menu(inst);
gtk_widget_set_sensitive(inst->restartitem, TRUE);
}
}
static void delete_inst(struct gui_data *inst)
{
int dialog_slot;
@ -2106,19 +2149,11 @@ static void delete_inst(struct gui_data *inst)
gtk_widget_destroy(inst->menu);
inst->menu = NULL;
}
if (inst->backhandle) {
inst->back->free(inst->backhandle);
inst->backhandle = NULL;
inst->back = NULL;
}
destroy_inst_connection(inst);
if (inst->term) {
term_free(inst->term);
inst->term = NULL;
}
if (inst->ldisc) {
ldisc_free(inst->ldisc);
inst->ldisc = NULL;
}
if (inst->conf) {
conf_free(inst->conf);
inst->conf = NULL;
@ -4517,7 +4552,7 @@ static void start_backend(struct gui_data *inst)
char *msg = dupprintf("Unable to open connection to %s:\n%s",
conf_dest(inst->conf), error);
inst->exited = TRUE;
fatal_message_box(inst->window, msg);
fatal_message_box(inst, msg);
sfree(msg);
exit(0);
}

View File

@ -155,6 +155,7 @@ enum DialogSlot {
DIALOG_SLOT_NETWORK_PROMPT,
DIALOG_SLOT_LOGFILE_PROMPT,
DIALOG_SLOT_WARN_ON_CLOSE,
DIALOG_SLOT_CONNECTION_FATAL,
DIALOG_SLOT_LIMIT /* must remain last */
};
void register_dialog(void *frontend, enum DialogSlot slot, GtkWidget *dialog);
@ -168,7 +169,6 @@ GtkWidget *create_config_box(const char *title, Conf *conf,
int midsession, int protcfginfo,
post_dialog_fn_t after, void *afterctx);
#endif
void fatal_message_box(void *window, const char *msg);
void nonfatal_message_box(void *window, const char *msg);
void about_box(void *window);
void *eventlogstuff_new(void);