diff options
author | Dan Winship <danw@gnome.org> | 2014-03-25 09:54:52 -0400 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2014-03-25 09:54:52 -0400 |
commit | 370b60bcaa660aa8db4a6330a8f53db3205a143c (patch) | |
tree | e3039cd5d3e6b527c616cb97d1d9d3bd45e8353d | |
parent | d0c380ea684951a9e328bea6e4c019cf23840256 (diff) | |
parent | ce26445b6f720fb8261e18b7fbda08dfd153e5e3 (diff) | |
download | NetworkManager-370b60bcaa660aa8db4a6330a8f53db3205a143c.tar.gz |
tui: allow cancelling "nmtui connect", make ^Z work (rh #1080059)
-rw-r--r-- | tui/newt/nmt-newt-form.c | 4 | ||||
-rw-r--r-- | tui/newt/nmt-newt-utils.c | 10 | ||||
-rw-r--r-- | tui/newt/nmt-newt-widget.c | 16 | ||||
-rw-r--r-- | tui/newt/nmt-newt-widget.h | 1 | ||||
-rw-r--r-- | tui/nmtui-connect.c | 73 |
5 files changed, 86 insertions, 18 deletions
diff --git a/tui/newt/nmt-newt-form.c b/tui/newt/nmt-newt-form.c index dec3d9a62a..0c2063be7a 100644 --- a/tui/newt/nmt-newt-form.c +++ b/tui/newt/nmt-newt-form.c @@ -199,7 +199,7 @@ nmt_newt_form_build (NmtNewtForm *form) int i; priv->dirty = FALSE; - nmt_newt_widget_realize (priv->content); + nmt_newt_widget_realize (NMT_NEWT_WIDGET (form)); nmt_newt_widget_size_request (priv->content, &form_width, &form_height); newtGetScreenSize (&screen_width, &screen_height); @@ -268,7 +268,7 @@ nmt_newt_form_destroy (NmtNewtForm *form) priv->form = NULL; newtPopWindowNoRefresh (); - nmt_newt_widget_unrealize (priv->content); + nmt_newt_widget_unrealize (NMT_NEWT_WIDGET (form)); } /* A "normal" newt program would call newtFormRun() to run newt's main loop diff --git a/tui/newt/nmt-newt-utils.c b/tui/newt/nmt-newt-utils.c index 10e8484927..68d8c449e5 100644 --- a/tui/newt/nmt-newt-utils.c +++ b/tui/newt/nmt-newt-utils.c @@ -110,6 +110,14 @@ nmt_newt_basic_g_log_handler (const char *log_domain, newtResume (); } +static void +nmt_newt_suspend_callback (gpointer user_data) +{ + newtSuspend (); + kill (getpid (), SIGTSTP); + newtResume (); +} + /** * nmt_newt_init: * @@ -132,6 +140,8 @@ nmt_newt_init (void) g_log_set_default_handler (nmt_newt_dialog_g_log_handler, NULL); else g_log_set_default_handler (nmt_newt_basic_g_log_handler, NULL); + + newtSetSuspendCallback (nmt_newt_suspend_callback, NULL); } /** diff --git a/tui/newt/nmt-newt-widget.c b/tui/newt/nmt-newt-widget.c index ba37f173fe..24ee8b0a61 100644 --- a/tui/newt/nmt-newt-widget.c +++ b/tui/newt/nmt-newt-widget.c @@ -133,6 +133,22 @@ nmt_newt_widget_unrealize (NmtNewtWidget *widget) } /** + * nmt_newt_widget_get_realized: + * @widget: an #NmtNewtWidget + * + * Checks if @widget is realized or not. + * + * Returns: whether @widget is realized. + */ +gboolean +nmt_newt_widget_get_realized (NmtNewtWidget *widget) +{ + NmtNewtWidgetPrivate *priv = NMT_NEWT_WIDGET_GET_PRIVATE (widget); + + return priv->realized; +} + +/** * nmt_newt_widget_get_components: * @widget: an #NmtNewtWidget * diff --git a/tui/newt/nmt-newt-widget.h b/tui/newt/nmt-newt-widget.h index 265f2455d1..a526a674c3 100644 --- a/tui/newt/nmt-newt-widget.h +++ b/tui/newt/nmt-newt-widget.h @@ -67,6 +67,7 @@ GType nmt_newt_widget_get_type (void); void nmt_newt_widget_realize (NmtNewtWidget *widget); void nmt_newt_widget_unrealize (NmtNewtWidget *widget); +gboolean nmt_newt_widget_get_realized (NmtNewtWidget *widget); newtComponent *nmt_newt_widget_get_components (NmtNewtWidget *widget); diff --git a/tui/nmtui-connect.c b/tui/nmtui-connect.c index a6a4e96ba8..a86b8df57d 100644 --- a/tui/nmtui-connect.c +++ b/tui/nmtui-connect.c @@ -65,6 +65,18 @@ secrets_requested (NmtSecretAgent *agent, } static void +connect_cancelled (NmtNewtForm *form, + gpointer user_data) +{ + NmtSyncOp *op = user_data; + GError *error = NULL; + + error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED, "Cancelled"); + nmt_sync_op_complete_boolean (op, FALSE, error); + g_clear_error (&error); +} + +static void activate_ac_state_changed (GObject *object, GParamSpec *pspec, gpointer user_data) @@ -82,9 +94,6 @@ activate_ac_state_changed (GObject *object, _("Activation failed")); } - g_signal_handlers_disconnect_by_func (object, G_CALLBACK (activate_ac_state_changed), op); - g_object_unref (object); - nmt_sync_op_complete_boolean (op, error == NULL, error); g_clear_error (&error); } @@ -97,14 +106,10 @@ activate_callback (NMClient *client, { NmtSyncOp *op = user_data; - if (error || nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { - nmt_sync_op_complete_boolean (op, error == NULL, error); - return; - } - - g_object_ref (ac); - g_signal_connect (ac, "notify::" NM_ACTIVE_CONNECTION_STATE, - G_CALLBACK (activate_ac_state_changed), op); + if (error) + nmt_sync_op_complete_pointer (op, NULL, error); + else + nmt_sync_op_complete_pointer (op, g_object_ref (ac), NULL); } static void @@ -128,9 +133,12 @@ activate_connection (NMConnection *connection, NmtNewtWidget *label; NmtSyncOp op; const char *specific_object_path; + NMActiveConnection *ac; GError *error = NULL; - form = g_object_new (NMT_TYPE_NEWT_FORM, NULL); + form = g_object_new (NMT_TYPE_NEWT_FORM, + "escape-exits", TRUE, + NULL); label = nmt_newt_label_new (_("Connecting...")); nmt_newt_form_set_content (form, label); @@ -140,7 +148,11 @@ activate_connection (NMConnection *connection, specific_object_path = specific_object ? nm_object_get_path (specific_object) : NULL; - /* FIXME: cancel button */ + /* There's no way to cancel an nm_client_activate_connection() / + * nm_client_add_and_activate_connection() call, so we always let them + * complete, even if the user hits Esc; they shouldn't normally take long + * to complete anyway. + */ nmt_sync_op_init (&op); if (connection) { @@ -155,12 +167,41 @@ activate_connection (NMConnection *connection, nmt_newt_form_show (form); - if (!nmt_sync_op_wait_boolean (&op, &error)) { + ac = nmt_sync_op_wait_pointer (&op, &error); + if (!ac) { nmt_newt_message_dialog (_("Could not activate connection: %s"), error->message); - g_error_free (error); + g_clear_error (&error); + goto done; + } else if (nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { + /* Already active */ + goto done; + } else if (!nmt_newt_widget_get_realized (NMT_NEWT_WIDGET (form))) { + /* User already hit Esc */ + goto done; } - nmt_newt_form_quit (form); + /* Now wait for the connection to actually reach the ACTIVATED state, + * allowing the user to cancel if it takes too long. + */ + + nmt_sync_op_init (&op); + + g_signal_connect (form, "quit", G_CALLBACK (connect_cancelled), &op); + g_signal_connect (ac, "notify::" NM_ACTIVE_CONNECTION_STATE, + G_CALLBACK (activate_ac_state_changed), &op); + + if (!nmt_sync_op_wait_boolean (&op, &error)) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + nmt_newt_message_dialog (_("Could not activate connection: %s"), error->message); + g_clear_error (&error); + } + + g_signal_handlers_disconnect_by_func (form, G_CALLBACK (connect_cancelled), &op); + g_signal_handlers_disconnect_by_func (ac, G_CALLBACK (activate_ac_state_changed), &op); + + done: + if (nmt_newt_widget_get_realized (NMT_NEWT_WIDGET (form))) + nmt_newt_form_quit (form); g_object_unref (form); /* If the activation failed very quickly, then agent won't be registered yet, |