summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2014-03-25 09:54:52 -0400
committerDan Winship <danw@gnome.org>2014-03-25 09:54:52 -0400
commit370b60bcaa660aa8db4a6330a8f53db3205a143c (patch)
treee3039cd5d3e6b527c616cb97d1d9d3bd45e8353d
parentd0c380ea684951a9e328bea6e4c019cf23840256 (diff)
parentce26445b6f720fb8261e18b7fbda08dfd153e5e3 (diff)
downloadNetworkManager-370b60bcaa660aa8db4a6330a8f53db3205a143c.tar.gz
tui: allow cancelling "nmtui connect", make ^Z work (rh #1080059)
-rw-r--r--tui/newt/nmt-newt-form.c4
-rw-r--r--tui/newt/nmt-newt-utils.c10
-rw-r--r--tui/newt/nmt-newt-widget.c16
-rw-r--r--tui/newt/nmt-newt-widget.h1
-rw-r--r--tui/nmtui-connect.c73
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,