[gnome-session] Add "Try Recovery" option to fail whale



commit 2e92bb08bd7b700ae5e385e07292f37b307a36a5
Author: Colin Walters <walters verbum org>
Date:   Sun Mar 13 16:57:31 2011 -0400

    Add "Try Recovery" option to fail whale
    
    Also resize the fail whale dialog to a minimum of 640x480
    to ensure visibility.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=642497

 gnome-session/gsm-app.c               |    1 +
 gnome-session/gsm-fail-whale-dialog.c |   60 ++++++++++++++++++++++++++---
 gnome-session/gsm-manager.c           |   67 ++++++++++++++++++++------------
 gnome-session/gsm-manager.h           |    2 +
 4 files changed, 99 insertions(+), 31 deletions(-)
---
diff --git a/gnome-session/gsm-app.c b/gnome-session/gsm-app.c
index 8086b8a..79917a8 100644
--- a/gnome-session/gsm-app.c
+++ b/gnome-session/gsm-app.c
@@ -31,6 +31,7 @@
 
 #define GSM_APP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_APP, GsmAppPrivate))
 
+/* This number was apparently picked mostly arbitrarily */
 #define APP_RESTART_LIMIT 20
 
 struct _GsmAppPrivate
diff --git a/gnome-session/gsm-fail-whale-dialog.c b/gnome-session/gsm-fail-whale-dialog.c
index 5ad04e1..4a26072 100644
--- a/gnome-session/gsm-fail-whale-dialog.c
+++ b/gnome-session/gsm-fail-whale-dialog.c
@@ -52,6 +52,12 @@ struct _GsmFailWhaleDialogPrivate
 
 static GsmFailWhaleDialog *current_dialog = NULL;
 
+static void gsm_fail_whale_dialog_get_preferred_width (GtkWidget *widget,
+                                                       gint      *minimum_size,
+                                                       gint      *natural_size);
+static void gsm_fail_whale_dialog_get_preferred_height (GtkWidget *widget,
+                                                        gint      *minimum_size,
+                                                        gint      *natural_size);
 static void gsm_fail_whale_dialog_destroy  (GsmFailWhaleDialog *fail_dialog,
                                             gpointer         data);
 
@@ -104,10 +110,14 @@ static void
 gsm_fail_whale_dialog_class_init (GsmFailWhaleDialogClass *klass)
 {
         GObjectClass *gobject_class;
-
+        GtkWidgetClass *widget_class;
+        
         gobject_class = G_OBJECT_CLASS (klass);
+        widget_class = GTK_WIDGET_CLASS (klass);
         gobject_class->set_property = gsm_fail_whale_dialog_set_property;
         gobject_class->get_property = gsm_fail_whale_dialog_get_property;
+        widget_class->get_preferred_width = gsm_fail_whale_dialog_get_preferred_width;
+        widget_class->get_preferred_height = gsm_fail_whale_dialog_get_preferred_height;
 
         g_type_class_add_private (klass, sizeof (GsmFailWhaleDialogPrivate));
 }
@@ -131,6 +141,34 @@ gsm_fail_whale_dialog_init (GsmFailWhaleDialog *fail_dialog)
                           NULL);
 }
 
+static void 
+gsm_fail_whale_dialog_get_preferred_width (GtkWidget *widget,
+                                           gint      *minimum_size,
+                                           gint      *natural_size)
+{
+        GTK_WIDGET_CLASS (gsm_fail_whale_dialog_parent_class)->get_preferred_width (widget,
+                                                              minimum_size,
+                                                              natural_size);
+        if (minimum_size && *minimum_size < 640)
+                *minimum_size = 640;
+        if (natural_size && *natural_size < 640)
+                *natural_size = 640;
+}
+
+static void 
+gsm_fail_whale_dialog_get_preferred_height (GtkWidget *widget,
+                                            gint      *minimum_size,
+                                            gint      *natural_size)
+{
+        GTK_WIDGET_CLASS (gsm_fail_whale_dialog_parent_class)->get_preferred_height (widget,
+                                                                                     minimum_size,
+                                                                                     natural_size);
+        if (minimum_size && *minimum_size < 640)
+                *minimum_size = 480;
+        if (natural_size && *natural_size < 640)
+                *natural_size = 480;
+}
+
 static void
 gsm_fail_whale_dialog_destroy (GsmFailWhaleDialog *fail_dialog,
                                gpointer         data)
@@ -193,7 +231,14 @@ gsm_fail_whale_dialog_on_response (GsmFailWhaleDialog *fail_dialog,
                                     GSM_MANAGER_LOGOUT_MODE_FORCE,
                                     NULL);
                 break;
+        case GSM_FAIL_WHALE_DIALOG_RESPONSE_TRY_RECOVERY:
+                gsm_manager_try_recovery (gsm_manager_get ());
+                break;
+        default:
+                g_warning ("gsm-fail-whale-dialog: invalid response");
+                break;
         }
+        gtk_widget_destroy (GTK_WIDGET (fail_dialog));
 }
 
 void
@@ -223,10 +268,6 @@ gsm_fail_whale_dialog_we_failed (GsmFailWhaleDialogFailType fail_type,
 
         gtk_window_set_title (GTK_WINDOW (fail_dialog), "");
 
-        gtk_dialog_add_button (GTK_DIALOG (fail_dialog),
-                               _("_Log Out"),
-                               GSM_FAIL_WHALE_DIALOG_RESPONSE_LOG_OUT);
-
         gtk_window_set_icon_name (GTK_WINDOW (fail_dialog), "gtk-error");
         gtk_window_set_position (GTK_WINDOW (fail_dialog), GTK_WIN_POS_CENTER_ALWAYS);
         
@@ -235,7 +276,7 @@ gsm_fail_whale_dialog_we_failed (GsmFailWhaleDialogFailType fail_type,
                 gtk_dialog_add_button (GTK_DIALOG (fail_dialog),
                                        _("Try _Recovery"),
                                        GSM_FAIL_WHALE_DIALOG_RESPONSE_TRY_RECOVERY);
-                primary_text = g_strdup_printf (_("A non-fatal system error has occurred: %s"), additional_text);
+                primary_text = g_strdup_printf (_("A system error has occurred: %s"), additional_text);
                 break;
         case GSM_FAIL_WHALE_DIALOG_FAIL_TYPE_FATAL:
                 primary_text = g_strdup_printf (_("A fatal system error has occurred: %s"), additional_text);
@@ -244,6 +285,11 @@ gsm_fail_whale_dialog_we_failed (GsmFailWhaleDialogFailType fail_type,
                 g_assert_not_reached ();
                 return;
         }
+
+        gtk_dialog_add_button (GTK_DIALOG (fail_dialog),
+                               _("_Log Out"),
+                               GSM_FAIL_WHALE_DIALOG_RESPONSE_LOG_OUT);
+
         gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (fail_dialog),
                                        primary_text);
         gtk_dialog_set_default_response (GTK_DIALOG (fail_dialog),
@@ -262,6 +308,8 @@ gsm_fail_whale_dialog_we_failed (GsmFailWhaleDialogFailType fail_type,
         g_signal_connect (fail_dialog, "response",
                           G_CALLBACK (gsm_fail_whale_dialog_on_response),
                           fail_dialog);
+        /* A minimum size to ensure we're seen */
+        gtk_window_set_default_size (GTK_WINDOW (fail_dialog), 640, 480);
         gtk_widget_show (GTK_WIDGET (fail_dialog));
 }
 
diff --git a/gnome-session/gsm-manager.c b/gnome-session/gsm-manager.c
index 8b35f14..62649eb 100644
--- a/gnome-session/gsm-manager.c
+++ b/gnome-session/gsm-manager.c
@@ -226,6 +226,23 @@ gsm_manager_error_get_type (void)
 }
 
 static gboolean
+start_app_or_warn (GsmManager *manager,
+                   GsmApp     *app)
+{
+        gboolean res;
+        GError *error = NULL;
+
+        g_debug ("GsmManager: starting app '%s'", gsm_app_peek_id (app));
+
+        res = gsm_app_start (app, &error);
+        if (error != NULL) {
+                g_warning ("Failed start app: %s", error->message);
+                g_clear_error (&error);
+        }
+        return res;
+}
+
+static gboolean
 is_app_required (GsmManager *manager,
                  GsmApp     *app)
 {
@@ -241,7 +258,7 @@ on_required_app_failure (GsmManager  *manager,
         full_msg = g_strdup_printf ("Component '%s': %s",
                                     gsm_app_peek_app_id (app),
                                     msg);
-        gsm_fail_whale_dialog_we_failed (GSM_FAIL_WHALE_DIALOG_FAIL_TYPE_FATAL,
+        gsm_fail_whale_dialog_we_failed (GSM_FAIL_WHALE_DIALOG_FAIL_TYPE_RECOVERABLE,
                                          full_msg);
         g_free (full_msg);
 }
@@ -329,18 +346,7 @@ app_condition_changed (GsmApp     *app,
 
         if (condition) {
                 if (!gsm_app_is_running (app) && client == NULL) {
-                        GError  *error;
-                        gboolean res;
-
-                        g_debug ("GsmManager: starting app '%s'", gsm_app_peek_id (app));
-
-                        error = NULL;
-                        res = gsm_app_start (app, &error);
-                        if (error != NULL) {
-                                g_warning ("Not able to start app from its condition: %s",
-                                           error->message);
-                                g_error_free (error);
-                        }
+                        start_app_or_warn (manager, app);
                 } else {
                         g_debug ("GsmManager: not starting - app still running '%s'", gsm_app_peek_id (app));
                 }
@@ -634,7 +640,6 @@ _start_app (const char *id,
             GsmApp     *app,
             GsmManager *manager)
 {
-        GError  *error;
         gboolean res;
 
         if (gsm_app_peek_phase (app) != manager->priv->phase) {
@@ -654,18 +659,8 @@ _start_app (const char *id,
                 goto out;
         }
 
-        error = NULL;
-        res = gsm_app_start (app, &error);
-        if (!res) {
-                if (error != NULL) {
-                        g_warning ("Could not launch application '%s': %s",
-                                   gsm_app_peek_app_id (app),
-                                   error->message);
-                        g_error_free (error);
-                        error = NULL;
-                }
+        if (!start_app_or_warn (manager, app))
                 goto out;
-        }
 
         if (manager->priv->phase < GSM_MANAGER_PHASE_APPLICATION) {
                 /* Historical note - apparently,
@@ -3364,6 +3359,28 @@ gsm_manager_logout (GsmManager *manager,
         return TRUE;
 }
 
+/**
+ * gsm_manager_try_recovery:
+ * @manager: a #GsmManager
+ *
+ * Attempt to restart any required components which aren't running.
+ */
+void
+gsm_manager_try_recovery (GsmManager     *manager)
+{
+        GSList *iter;
+        
+        g_debug ("trying recovery");
+
+        for (iter = manager->priv->required_apps; iter; iter = iter->next) {
+                GsmApp *app = iter->data;
+
+                if (gsm_app_is_running (app))
+                        continue;
+                start_app_or_warn (manager, app);
+        }
+}
+
 gboolean
 gsm_manager_register_client (GsmManager            *manager,
                              const char            *app_id,
diff --git a/gnome-session/gsm-manager.h b/gnome-session/gsm-manager.h
index c878280..704f157 100644
--- a/gnome-session/gsm-manager.h
+++ b/gnome-session/gsm-manager.h
@@ -170,6 +170,8 @@ gboolean            gsm_manager_logout                         (GsmManager     *
                                                                 guint           logout_mode,
                                                                 GError        **error);
 
+void                gsm_manager_try_recovery                   (GsmManager     *manager);
+
 gboolean            gsm_manager_setenv                         (GsmManager     *manager,
                                                                 const char     *variable,
                                                                 const char     *value,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]