[Xfce4-commits] [xfce/xfce4-session] 02/02: Optionally run commands on logout, suspend etc. (Bug #10172)

noreply at xfce.org noreply at xfce.org
Thu Apr 25 01:06:01 CEST 2019


This is an automated email from the git hooks/post-receive script.

o   c   h   o   s   i       p   u   s   h   e   d       a       c   o   m   m   i   t       t   o       b   r   a   n   c   h       m   a   s   t   e   r   
   in repository xfce/xfce4-session.

commit 9e7e160d6db39d39283bef6fafb7264f4a65d9e5
Author: Alexander Schwinn <alexxcons at xfce.org>
Date:   Thu Apr 25 01:05:22 2019 +0200

    Optionally run commands on logout, suspend etc. (Bug #10172)
---
 settings/xfae-dialog.c       |  52 +++++++++++++----
 settings/xfae-dialog.h       |  15 +++--
 settings/xfae-model.c        |  97 ++++++++++++++++++++++++++++----
 settings/xfae-model.h        |  84 +++++++++++++++++++---------
 settings/xfae-window.c       | 129 ++++++++++++++++++++++++++++++++++---------
 xfce4-session/xfsm-global.c  |  57 ++++++++++++++++++-
 xfce4-session/xfsm-global.h  |  10 +++-
 xfce4-session/xfsm-manager.c |   2 +
 xfce4-session/xfsm-startup.c |   6 +-
 9 files changed, 364 insertions(+), 88 deletions(-)

diff --git a/settings/xfae-dialog.c b/settings/xfae-dialog.c
index d647657..c94569d 100644
--- a/settings/xfae-dialog.c
+++ b/settings/xfae-dialog.c
@@ -44,6 +44,7 @@ struct _XfaeDialog
   GtkWidget *name_entry;
   GtkWidget *descr_entry;
   GtkWidget *command_entry;
+  GtkWidget *run_hook_combo;
 };
 
 
@@ -62,12 +63,15 @@ xfae_dialog_class_init (XfaeDialogClass *klass)
 static void
 xfae_dialog_init (XfaeDialog *dialog)
 {
-  GtkWidget *content_area;
-  GtkWidget *grid;
-  GtkWidget *label;
-  GtkWidget *hbox;
-  GtkWidget *button;
-  GtkWidget *image;
+  GtkWidget  *content_area;
+  GtkWidget  *grid;
+  GtkWidget  *label;
+  GtkWidget  *hbox;
+  GtkWidget  *button;
+  GtkWidget  *image;
+  GEnumClass *klass;
+  GEnumValue *enum_struct;
+  guint       i;
 
   gtk_dialog_add_buttons (GTK_DIALOG (dialog),
                           _("Cancel"), GTK_RESPONSE_CANCEL,
@@ -128,6 +132,27 @@ xfae_dialog_init (XfaeDialog *dialog)
   gtk_grid_attach (GTK_GRID (grid), hbox, 1, 2, 1, 1);
   gtk_widget_show (hbox);
 
+  label = g_object_new (GTK_TYPE_LABEL,
+                        "label", _("Trigger:"),
+                        "xalign", 0.0f,
+                        NULL);
+  gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 1, 1);
+  gtk_widget_show (label);
+
+  dialog->run_hook_combo = gtk_combo_box_text_new ();
+  gtk_widget_set_margin_bottom (dialog->run_hook_combo, 5);
+  klass = g_type_class_ref (XFSM_TYPE_RUN_HOOK);
+  for (i = 0; i < klass->n_values; ++i)
+    {
+      enum_struct =  g_enum_get_value (klass, i);
+      gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dialog->run_hook_combo), enum_struct->value_nick);
+    }
+  g_type_class_unref (klass);
+  gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->run_hook_combo), 0);
+
+  gtk_grid_attach (GTK_GRID (grid), dialog->run_hook_combo, 1, 3, 1, 1);
+  gtk_widget_show (dialog->run_hook_combo);
+
   dialog->command_entry = g_object_new (GTK_TYPE_ENTRY,
                                         "activates-default", TRUE,
                                         "hexpand", TRUE,
@@ -217,7 +242,8 @@ xfae_dialog_browse (XfaeDialog *dialog)
 GtkWidget*
 xfae_dialog_new (const gchar *name,
                  const gchar *descr,
-                 const gchar *command)
+                 const gchar *command,
+                 XfsmRunHook  run_hook)
 {
   XfaeDialog *dialog = g_object_new (XFAE_TYPE_DIALOG, NULL);
 
@@ -227,6 +253,7 @@ xfae_dialog_new (const gchar *name,
     gtk_entry_set_text (GTK_ENTRY (dialog->descr_entry), descr );
   if (command)
     gtk_entry_set_text (GTK_ENTRY (dialog->command_entry), command);
+  gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->run_hook_combo), run_hook);
   if (name != NULL || descr != NULL || command != NULL)
     gtk_window_set_title (GTK_WINDOW (dialog), _("Edit application"));
 
@@ -246,19 +273,22 @@ xfae_dialog_new (const gchar *name,
  * from the @dialog.
  **/
 void
-xfae_dialog_get (XfaeDialog *dialog,
-                 gchar     **name,
-                 gchar     **descr,
-                 gchar     **command)
+xfae_dialog_get (XfaeDialog   *dialog,
+                 gchar       **name,
+                 gchar       **descr,
+                 gchar       **command,
+                 XfsmRunHook  *run_hook)
 {
   g_return_if_fail (XFAE_IS_DIALOG (dialog));
   g_return_if_fail (name != NULL);
   g_return_if_fail (descr != NULL);
   g_return_if_fail (command != NULL);
+  g_return_if_fail (run_hook != NULL);
 
   *name = gtk_editable_get_chars (GTK_EDITABLE (dialog->name_entry), 0, -1);
   *descr = gtk_editable_get_chars (GTK_EDITABLE (dialog->descr_entry), 0, -1);
   *command = gtk_editable_get_chars (GTK_EDITABLE (dialog->command_entry), 0, -1);
+  *run_hook = gtk_combo_box_get_active (GTK_COMBO_BOX (dialog->run_hook_combo));
 
   g_strstrip (*name);
   g_strstrip (*descr);
diff --git a/settings/xfae-dialog.h b/settings/xfae-dialog.h
index 9b94f0e..801e437 100644
--- a/settings/xfae-dialog.h
+++ b/settings/xfae-dialog.h
@@ -23,6 +23,7 @@
 #define __XFAE_DIALOG_H__
 
 #include <gtk/gtk.h>
+#include "xfae-model.h" /* Type XfsmRunHook */
 
 G_BEGIN_DECLS;
 
@@ -40,12 +41,14 @@ GType      xfae_dialog_get_type (void) G_GNUC_CONST;
 
 GtkWidget *xfae_dialog_new      (const gchar *name,
                                  const gchar *descr,
-                                 const gchar *command);
-
-void       xfae_dialog_get      (XfaeDialog *dialog,
-                                 gchar     **name,
-                                 gchar     **descr,
-                                 gchar     **command);
+                                 const gchar *command,
+                                 XfsmRunHook  trigger);
+
+void       xfae_dialog_get      (XfaeDialog   *dialog,
+                                 gchar       **name,
+                                 gchar       **descr,
+                                 gchar       **command,
+                                 XfsmRunHook  *trigger);
 
 G_END_DECLS;
 
diff --git a/settings/xfae-model.c b/settings/xfae-model.c
index 59ee10e..d4e508a 100644
--- a/settings/xfae-model.c
+++ b/settings/xfae-model.c
@@ -75,7 +75,29 @@ static XfaeItem          *xfae_item_new               (const gchar        *relpa
 static void               xfae_item_free              (XfaeItem           *item);
 static gboolean           xfae_item_is_removable      (XfaeItem           *item);
 
+GType
+xfsm_run_hook_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
 
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GEnumValue values[] =
+      {
+        { XFSM_RUN_HOOK_LOGIN,        "XFSM_RUN_HOOK_LOGIN",        N_ ("on login"),        },
+        { XFSM_RUN_HOOK_LOGOUT,       "XFSM_RUN_HOOK_LOGOUT",       N_ ("on logout"),       },
+        { XFSM_RUN_HOOK_SHUTDOWN,     "XFSM_RUN_HOOK_SHUTDOWN",     N_ ("on shutdown"),     },
+        { XFSM_RUN_HOOK_RESTART,      "XFSM_RUN_HOOK_RESTART",      N_ ("on restart"),      },
+        { XFSM_RUN_HOOK_SUSPEND,      "XFSM_RUN_HOOK_SUSPEND",      N_ ("on suspend"),      },
+        { XFSM_RUN_HOOK_HIBERNATE,    "XFSM_RUN_HOOK_HIBERNATE",    N_ ("on hibernate"),    },
+        { XFSM_RUN_HOOK_HYBRID_SLEEP, "XFSM_RUN_HOOK_HYBRID_SLEEP", N_ ("on hybrid sleep"), },
+        { XFSM_RUN_HOOK_SWITCH_USER,  "XFSM_RUN_HOOK_SWITCH_USER",  N_ ("on switch user"),  },
+        { 0,                          NULL,                         NULL,                   },
+      };
+      type = g_enum_register_static ("XfsmRunHook", values);
+    }
+  return type;
+}
 
 struct _XfaeModelClass
 {
@@ -92,12 +114,13 @@ struct _XfaeModel
 
 struct _XfaeItem
 {
-  gchar     *name;
-  GdkPixbuf *icon;
-  gchar     *comment;
-  gchar     *relpath;
-  gboolean   hidden;
-  gchar     *tooltip;
+  gchar       *name;
+  GdkPixbuf   *icon;
+  gchar       *comment;
+  gchar       *relpath;
+  gboolean     hidden;
+  gchar       *tooltip;
+  XfsmRunHook  run_hook;
 
   gboolean   show_in_xfce;
   gboolean   show_in_override;
@@ -204,6 +227,7 @@ xfae_model_get_column_type (GtkTreeModel *tree_model,
     {
     case XFAE_MODEL_COLUMN_NAME:
     case XFAE_MODEL_COLUMN_TOOLTIP:
+    case XFAE_MODEL_RUN_HOOK:
       return G_TYPE_STRING;
 
     case XFAE_MODEL_COLUMN_ICON:
@@ -262,16 +286,50 @@ xfae_model_get_path (GtkTreeModel *tree_model,
 
 
 
+gboolean
+xfae_model_set_run_hook (GtkTreeModel  *tree_model,
+                         GtkTreePath   *path,
+                         GtkTreeIter   *iter,
+                         XfsmRunHook    run_hook,
+                         GError       **error)
+{
+  XfaeItem *item = ((GList *) iter->user_data)->data;
+  XfceRc   *rc;
+
+  /* try to open the resource config */
+  rc = xfce_rc_config_open (XFCE_RESOURCE_CONFIG, item->relpath, FALSE);
+  if (G_UNLIKELY (rc == NULL))
+    {
+      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (EIO),
+                   _("Failed to open %s for writing"), item->relpath);
+      return FALSE;
+    }
+
+  xfce_rc_set_group (rc, "Desktop Entry");
+  item->run_hook = run_hook;
+  xfce_rc_write_int_entry (rc, "RunHook", item->run_hook);
+  xfce_rc_close (rc);
+
+  /* tell the view that we have most probably a new state */
+  gtk_tree_model_row_changed (tree_model, path, iter);
+
+  return TRUE;
+}
+
+
+
 static void
 xfae_model_get_value (GtkTreeModel *tree_model,
                       GtkTreeIter  *iter,
                       gint          column,
                       GValue       *value)
 {
-  XfaeModel *model = XFAE_MODEL (tree_model);
-  XfaeItem  *item = ((GList *) iter->user_data)->data;
-  gchar     *name;
-  gchar     *cursive;
+  XfaeModel  *model = XFAE_MODEL (tree_model);
+  XfaeItem   *item = ((GList *) iter->user_data)->data;
+  gchar      *name;
+  gchar      *cursive;
+  GEnumClass *klass;
+  GEnumValue *enum_struct;
 
   g_return_if_fail (XFAE_IS_MODEL (model));
   g_return_if_fail (iter->stamp == model->stamp);
@@ -319,6 +377,14 @@ xfae_model_get_value (GtkTreeModel *tree_model,
       g_value_set_static_string (value, item->tooltip);
       break;
 
+    case XFAE_MODEL_RUN_HOOK:
+      g_value_init (value, G_TYPE_STRING);
+      klass = g_type_class_ref (XFSM_TYPE_RUN_HOOK);
+      enum_struct =  g_enum_get_value (klass, item->run_hook);
+      g_type_class_unref (klass);
+      g_value_set_static_string (value, enum_struct->value_nick);
+      break;
+
     default:
       g_assert_not_reached ();
     }
@@ -481,6 +547,7 @@ xfae_item_new (const gchar *relpath)
           if (G_LIKELY (value != NULL))
             item->tooltip = g_markup_printf_escaped ("<b>%s</b> %s", _("Command:"), value);
 
+          item->run_hook = xfce_rc_read_int_entry (rc, "RunHook", XFSM_RUN_HOOK_LOGIN);
           item->hidden = xfce_rc_read_bool_entry (rc, "Hidden", FALSE);
         }
       else
@@ -644,6 +711,7 @@ xfae_model_new (void)
  * @name        : the user visible name of the new item.
  * @description : the description for the new item.
  * @command     : the command for the new item.
+ * @run_hook    : hook/trigger on which the command should be executed.
  * @error       : return locations for errors or %NULL.
  *
  * Attempts to add a new item with the given parameters
@@ -656,6 +724,7 @@ xfae_model_add (XfaeModel   *model,
                 const gchar *name,
                 const gchar *description,
                 const gchar *command,
+                XfsmRunHook  run_hook,
                 GError     **error)
 {
   GtkTreePath *path;
@@ -713,6 +782,7 @@ xfae_model_add (XfaeModel   *model,
   xfce_rc_write_entry (rc, "Comment", description);
   xfce_rc_write_entry (rc, "Exec", command);
   xfce_rc_write_entry (rc, "OnlyShowIn", "XFCE;");
+  xfce_rc_write_int_entry (rc, "RunHook", run_hook);
   xfce_rc_write_bool_entry (rc, "StartupNotify", FALSE);
   xfce_rc_write_bool_entry (rc, "Terminal", FALSE);
   xfce_rc_write_bool_entry (rc, "Hidden", FALSE);
@@ -763,6 +833,7 @@ xfae_model_get (XfaeModel    *model,
                 gchar       **name,
                 gchar       **description,
                 gchar       **command,
+                XfsmRunHook  *run_hook,
                 GError      **error)
 {
   XfaeItem    *item;
@@ -799,6 +870,9 @@ xfae_model_get (XfaeModel    *model,
   if (command != NULL)
     *command = g_strdup (value);
 
+  if (run_hook != NULL)
+    *run_hook = xfce_rc_read_int_entry (rc, "RunHook", XFSM_RUN_HOOK_LOGIN);
+
   xfce_rc_close (rc);
 
   return TRUE;
@@ -859,6 +933,7 @@ xfae_model_remove (XfaeModel   *model,
  * @name        : the user visible name of the new item.
  * @description : the description for the new item.
  * @command     : the command for the new item.
+ * @run_hook    : hook/trigger on which the command should be executed.
  * @error       : return locations for errors or %NULL.
  *
  * Attempts to edit an item with the given parameters
@@ -872,6 +947,7 @@ xfae_model_edit (XfaeModel   *model,
                  const gchar *name,
                  const gchar *description,
                  const gchar *command,
+                 XfsmRunHook  run_hook,
                  GError     **error)
 {
   GtkTreePath *path;
@@ -903,6 +979,7 @@ xfae_model_edit (XfaeModel   *model,
   xfce_rc_write_entry (rc, "Name", name);
   xfce_rc_write_entry (rc, "Comment", description);
   xfce_rc_write_entry (rc, "Exec", command);
+  xfce_rc_write_int_entry (rc, "RunHook", run_hook);
   xfce_rc_close (rc);
 
   /* tell the view that we have most probably a new state */
diff --git a/settings/xfae-model.h b/settings/xfae-model.h
index 731a691..74ac144 100644
--- a/settings/xfae-model.h
+++ b/settings/xfae-model.h
@@ -36,6 +36,26 @@ typedef struct _XfaeModel      XfaeModel;
 #define XFAE_IS_MODEL_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), XFAE_TYPE_MODEL))
 #define XFAE_MODEL_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), XFAE_TYPE_MODEL, XfaeModelClass))
 
+#define XFSM_TYPE_RUN_HOOK (xfsm_run_hook_get_type ())
+
+/**
+ * XfsmRunHook:
+ * The trigger / hook on which a specific command should be executed
+ **/
+typedef enum
+{
+  XFSM_RUN_HOOK_LOGIN,
+  XFSM_RUN_HOOK_LOGOUT,
+  XFSM_RUN_HOOK_SHUTDOWN,
+  XFSM_RUN_HOOK_RESTART,
+  XFSM_RUN_HOOK_SUSPEND,
+  XFSM_RUN_HOOK_HIBERNATE,
+  XFSM_RUN_HOOK_HYBRID_SLEEP,
+  XFSM_RUN_HOOK_SWITCH_USER,
+} XfsmRunHook;
+
+GType xfsm_run_hook_get_type (void) G_GNUC_CONST;
+
 /**
  * XfaeModelColumn:
  *
@@ -49,6 +69,7 @@ typedef enum
   XFAE_MODEL_COLUMN_ENABLED,
   XFAE_MODEL_COLUMN_REMOVABLE,
   XFAE_MODEL_COLUMN_TOOLTIP,
+  XFAE_MODEL_RUN_HOOK,
   XFAE_MODEL_N_COLUMNS,
 } XfaeModelColumn;
 
@@ -56,33 +77,42 @@ GType         xfae_model_get_type (void) G_GNUC_CONST;
 
 GtkTreeModel *xfae_model_new      (void);
 
-gboolean      xfae_model_add      (XfaeModel   *model,
-                                   const gchar *name,
-                                   const gchar *description,
-                                   const gchar *command,
-                                   GError     **error);
-
-gboolean      xfae_model_get      (XfaeModel   *model,
-                                   GtkTreeIter *iter,
-                                   gchar      **name,
-                                   gchar      **description,
-                                   gchar      **command,
-                                   GError     **error);
-
-gboolean      xfae_model_remove   (XfaeModel   *model,
-                                   GtkTreeIter *iter,
-                                   GError     **error);
-
-gboolean      xfae_model_edit     (XfaeModel   *model,
-                                   GtkTreeIter *iter,
-                                   const gchar *name,
-                                   const gchar *description,
-                                   const gchar *command,
-                                   GError     **error);
-
-gboolean      xfae_model_toggle   (XfaeModel   *model,
-                                   GtkTreeIter *iter,
-                                   GError     **error);
+gboolean      xfae_model_add      (XfaeModel    *model,
+                                   const gchar  *name,
+                                   const gchar  *description,
+                                   const gchar  *command,
+                                   XfsmRunHook   run_hook,
+                                   GError      **error);
+
+gboolean      xfae_model_get      (XfaeModel    *model,
+                                   GtkTreeIter  *iter,
+                                   gchar       **name,
+                                   gchar       **description,
+                                   gchar       **command,
+                                   XfsmRunHook  *run_hook,
+                                   GError      **error);
+
+gboolean      xfae_model_remove   (XfaeModel    *model,
+                                   GtkTreeIter  *iter,
+                                   GError      **error);
+
+gboolean      xfae_model_edit     (XfaeModel    *model,
+                                   GtkTreeIter  *iter,
+                                   const gchar  *name,
+                                   const gchar  *description,
+                                   const gchar  *command,
+                                   XfsmRunHook   run_hook,
+                                   GError      **error);
+
+gboolean      xfae_model_toggle   (XfaeModel    *model,
+                                   GtkTreeIter  *iter,
+                                   GError      **error);
+
+gboolean xfae_model_set_run_hook  (GtkTreeModel *tree_model,
+                                   GtkTreePath  *path,
+                                   GtkTreeIter  *iter,
+                                   XfsmRunHook   run_hook,
+                                   GError      **error);
 
 G_END_DECLS;
 
diff --git a/settings/xfae-window.c b/settings/xfae-window.c
index 5f05188..88ce845 100644
--- a/settings/xfae-window.c
+++ b/settings/xfae-window.c
@@ -28,18 +28,22 @@
 #include "xfae-dialog.h"
 #include "xfae-model.h"
 
+#include <xfce4-session/xfsm-global.h>
 #include <libxfce4ui/libxfce4ui.h>
 
-static void     xfae_window_add                 (XfaeWindow       *window);
-static void     xfae_window_remove              (XfaeWindow       *window);
-static void     xfae_window_edit                (XfaeWindow       *window);
-static gboolean xfae_window_button_press_event  (GtkWidget        *treeview,
-                                                 GdkEventButton   *event,
-                                                 XfaeWindow       *window);
-static void     xfae_window_item_toggled        (XfaeWindow       *window,
-                                                 gchar            *path_string);
-static void     xfae_window_selection_changed   (GtkTreeSelection *selection,
-                                                 GtkWidget        *remove_button);
+static void          xfae_window_add                          (XfaeWindow       *window);
+static void          xfae_window_remove                       (XfaeWindow       *window);
+static void          xfae_window_edit                         (XfaeWindow       *window);
+static gboolean      xfae_window_button_press_event           (GtkWidget        *treeview,
+                                                               GdkEventButton   *event,
+                                                               XfaeWindow       *window);
+static void          xfae_window_item_toggled                 (XfaeWindow       *window,
+                                                               gchar            *path_string);
+static void          xfae_window_selection_changed            (GtkTreeSelection *selection,
+                                                               GtkWidget        *remove_button);
+static GtkTreeModel* xfae_window_create_run_hooks_combo_model (void);
+
+
 
 
 
@@ -71,6 +75,36 @@ xfae_window_class_init (XfaeWindowClass *klass)
 
 
 static void
+run_hook_changed (GtkCellRenderer *render,
+                  const gchar     *path_str,
+                  const gchar     *new_text,
+                  gpointer         user_data)
+{
+    GEnumClass   *klass;
+    GEnumValue   *enum_struct;
+    GtkTreeView  *treeview = user_data;
+    GtkTreeModel *model = gtk_tree_view_get_model (treeview);
+    GtkTreePath  *path = gtk_tree_path_new_from_string (path_str);
+    GtkTreeIter   iter;
+    GError       *error = NULL;
+
+    if (gtk_tree_model_get_iter (model, &iter, path))
+      {
+        klass = g_type_class_ref (XFSM_TYPE_RUN_HOOK);
+        enum_struct = g_enum_get_value_by_nick (klass, new_text);
+        g_type_class_unref (klass);
+        if (!xfae_model_set_run_hook (model, path, &iter, enum_struct->value, &error))
+          {
+            xfce_dialog_show_error (NULL, error, _("Failed to set run hook"));
+            g_error_free (error);
+          }
+      }
+    gtk_tree_path_free (path);
+}
+
+
+
+static void
 xfae_window_init (XfaeWindow *window)
 {
   GtkTreeViewColumn *column;
@@ -102,12 +136,12 @@ xfae_window_init (XfaeWindow *window)
 
   label = g_object_new (GTK_TYPE_LABEL,
                         "justify", GTK_JUSTIFY_LEFT,
-                        "label", _("Below is the list of applications that will be started "
-                                   "automatically when you login to your Xfce desktop, "
-                                   "in addition to the applications that were saved when "
-                                   "you logged out last time. Cursive applications belong "
-                                   "to another desktop environment, but you can still enable "
-                                   "them if you want."),
+                        "label", _("List of applications that will be started "
+                                   "automatically on specific events like login, logout, shutdown, etc.\n"
+                                   "On login additionally all applications that were saved "
+                                   "on your last logout will be started.\n"
+                                   "Cursive applications belong to another desktop environment, "
+                                   "but you can still enable them if you want."),
                         "xalign", 0.0f,
                         NULL);
   gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
@@ -159,6 +193,27 @@ xfae_window_init (XfaeWindow *window)
                          "reorderable", FALSE,
                          "resizable", FALSE,
                          NULL);
+  renderer = gtk_cell_renderer_combo_new ();
+  model = xfae_window_create_run_hooks_combo_model ();
+  g_object_set (renderer,
+                "has-entry", FALSE,
+                "model", model,
+                "text-column", 0,
+                "editable", TRUE,
+                "mode", GTK_CELL_RENDERER_MODE_EDITABLE,
+                NULL);
+  g_signal_connect (renderer, "edited", G_CALLBACK (run_hook_changed), window->treeview);
+
+  gtk_tree_view_column_pack_start (column, renderer, FALSE);
+  gtk_tree_view_column_set_attributes (column, renderer,
+                                       "text", XFAE_MODEL_RUN_HOOK,
+                                       NULL);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (window->treeview), column);
+  g_object_unref (model);
+  column = g_object_new (GTK_TYPE_TREE_VIEW_COLUMN,
+                         "reorderable", FALSE,
+                         "resizable", FALSE,
+                         NULL);
   renderer = gtk_cell_renderer_pixbuf_new ();
   gtk_tree_view_column_pack_start (column, renderer, FALSE);
   gtk_tree_view_column_set_attributes (column, renderer,
@@ -206,6 +261,28 @@ xfae_window_init (XfaeWindow *window)
 
 
 
+static GtkTreeModel *
+xfae_window_create_run_hooks_combo_model (void)
+{
+    GtkListStore *ls = gtk_list_store_new (1, G_TYPE_STRING);
+    GEnumClass   *klass;
+    GEnumValue   *enum_struct;
+    GtkTreeIter   iter;
+    guint i;
+
+    klass = g_type_class_ref (XFSM_TYPE_RUN_HOOK);
+    for (i = 0; i < klass->n_values; ++i)
+      {
+        gtk_list_store_append (ls, &iter);
+        enum_struct = g_enum_get_value (klass, i);
+        gtk_list_store_set (ls, &iter, 0, enum_struct->value_nick, -1);
+      }
+    g_type_class_unref (klass);
+    return GTK_TREE_MODEL (ls);
+}
+
+
+
 static gboolean
 xfae_window_button_press_event (GtkWidget      *treeview,
                                 GdkEventButton *event,
@@ -281,18 +358,19 @@ xfae_window_add (XfaeWindow *window)
   gchar        *name;
   gchar        *descr;
   gchar        *command;
+  XfsmRunHook   run_hook;
 
-  dialog = xfae_dialog_new (NULL, NULL, NULL);
+  dialog = xfae_dialog_new (NULL, NULL, NULL, XFSM_RUN_HOOK_LOGIN);
   parent = gtk_widget_get_toplevel (GTK_WIDGET (window));
   gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent));
   if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
     {
       gtk_widget_hide (dialog);
 
-      xfae_dialog_get (XFAE_DIALOG (dialog), &name, &descr, &command);
+      xfae_dialog_get (XFAE_DIALOG (dialog), &name, &descr, &command, &run_hook);
 
       model = gtk_tree_view_get_model (GTK_TREE_VIEW (window->treeview));
-      if (!xfae_model_add (XFAE_MODEL (model), name, descr, command, &error))
+      if (!xfae_model_add (XFAE_MODEL (model), name, descr, command, run_hook, &error))
         {
           xfce_dialog_show_error (GTK_WINDOW (parent), error, _("Failed adding \"%s\""), name);
           g_error_free (error);
@@ -323,7 +401,7 @@ xfae_window_remove (XfaeWindow *window)
   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->treeview));
   if (gtk_tree_selection_get_selected (selection, &model, &iter))
     {
-      if (!xfae_model_get (XFAE_MODEL (model), &iter, &name, NULL, NULL, &error))
+      if (!xfae_model_get (XFAE_MODEL (model), &iter, &name, NULL, NULL, NULL, &error))
         {
           xfce_dialog_show_error (GTK_WINDOW (parent), error, _("Failed to remove item"));
           g_error_free (error);
@@ -334,7 +412,7 @@ xfae_window_remove (XfaeWindow *window)
                                          _("This will permanently remove the application "
                                            "from the list of automatically started applications"),
                                          _("Are you sure you want to remove \"%s\""), name);
-*/  
+*/
       g_free (name);
 
       if (remove_item && !xfae_model_remove (XFAE_MODEL (model), &iter, &error))
@@ -357,6 +435,7 @@ xfae_window_edit (XfaeWindow *window)
   gchar            *name;
   gchar            *descr;
   gchar            *command;
+  XfsmRunHook       run_hook;
   GtkWidget        *parent;
   GtkWidget        *dialog;
 
@@ -365,14 +444,14 @@ xfae_window_edit (XfaeWindow *window)
   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->treeview));
   if (gtk_tree_selection_get_selected (selection, &model, &iter))
     {
-      if (!xfae_model_get (XFAE_MODEL (model), &iter, &name, &descr, &command, &error))
+      if (!xfae_model_get (XFAE_MODEL (model), &iter, &name, &descr, &command, &run_hook, &error))
         {
           xfce_dialog_show_error (GTK_WINDOW (parent), error, _("Failed to edit item"));
           g_error_free (error);
           return;
         }
 
-      dialog = xfae_dialog_new (name, descr, command);
+      dialog = xfae_dialog_new (name, descr, command, run_hook);
       gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent));
 
       g_free (command);
@@ -383,9 +462,9 @@ xfae_window_edit (XfaeWindow *window)
         {
 	  gtk_widget_hide (dialog);
 
-	  xfae_dialog_get (XFAE_DIALOG (dialog), &name, &descr, &command);
+	  xfae_dialog_get (XFAE_DIALOG (dialog), &name, &descr, &command, &run_hook);
 
-          if (!xfae_model_edit (XFAE_MODEL (model), &iter, name, descr, command, &error))
+          if (!xfae_model_edit (XFAE_MODEL (model), &iter, name, descr, command, run_hook, &error))
             {
               xfce_dialog_show_error (GTK_WINDOW (parent), error, _("Failed to edit item \"%s\""), name);
               g_error_free (error);
diff --git a/xfce4-session/xfsm-global.c b/xfce4-session/xfsm-global.c
index c10ab97..6aa8ef6 100644
--- a/xfce4-session/xfsm-global.c
+++ b/xfce4-session/xfsm-global.c
@@ -258,7 +258,7 @@ xfsm_check_valid_exec (const gchar *exec)
 
 
 static void
-xfsm_startup_autostart_migrate (void)
+xfsm_autostart_migrate (void)
 {
   const gchar *entry;
   gchar        source_path[4096];
@@ -360,10 +360,55 @@ xfsm_startup_autostart_migrate (void)
 
 
 gint
-xfsm_startup_autostart_xdg (gboolean     start_at_spi)
+xfsm_launch_desktop_files_on_shutdown (gboolean         start_at_spi,
+                                       XfsmShutdownType shutdown_type)
+{
+  switch (shutdown_type)
+    {
+    case XFSM_SHUTDOWN_LOGOUT:
+      return xfsm_launch_desktop_files_on_run_hook (start_at_spi, XFSM_RUN_HOOK_LOGOUT);
+
+    case XFSM_SHUTDOWN_SHUTDOWN:
+      return xfsm_launch_desktop_files_on_run_hook (start_at_spi, XFSM_RUN_HOOK_SHUTDOWN);
+
+    case XFSM_SHUTDOWN_RESTART:
+      return xfsm_launch_desktop_files_on_run_hook (start_at_spi, XFSM_RUN_HOOK_RESTART);
+
+    case XFSM_SHUTDOWN_SUSPEND:
+      return xfsm_launch_desktop_files_on_run_hook (start_at_spi, XFSM_RUN_HOOK_SUSPEND);
+
+    case XFSM_SHUTDOWN_HIBERNATE:
+      return xfsm_launch_desktop_files_on_run_hook (start_at_spi, XFSM_RUN_HOOK_HIBERNATE);
+
+    case XFSM_SHUTDOWN_HYBRID_SLEEP:
+      return xfsm_launch_desktop_files_on_run_hook (start_at_spi, XFSM_RUN_HOOK_HYBRID_SLEEP);
+
+    case XFSM_SHUTDOWN_SWITCH_USER:
+      return xfsm_launch_desktop_files_on_run_hook (start_at_spi, XFSM_RUN_HOOK_SWITCH_USER);
+
+    default:
+      g_error ("Failed to convert shutdown type '%d' to run hook name.", shutdown_type);
+      return FALSE;
+    }
+}
+
+
+
+gint
+xfsm_launch_desktop_files_on_login (gboolean start_at_spi)
+{
+  return xfsm_launch_desktop_files_on_run_hook (start_at_spi, XFSM_RUN_HOOK_LOGIN);
+}
+
+
+
+gint
+xfsm_launch_desktop_files_on_run_hook (gboolean    start_at_spi,
+                                       XfsmRunHook run_hook)
 {
   const gchar *try_exec;
   const gchar *type;
+  XfsmRunHook  run_hook_from_file;
   const gchar *exec;
   gboolean     startup_notify;
   gboolean     terminal;
@@ -379,7 +424,7 @@ xfsm_startup_autostart_xdg (gboolean     start_at_spi)
   const gchar *pattern;
 
   /* migrate the old autostart location (if still present) */
-  xfsm_startup_autostart_migrate ();
+  xfsm_autostart_migrate ();
 
   /* pattern for only at-spi desktop files or everything */
   if (start_at_spi)
@@ -398,6 +443,12 @@ xfsm_startup_autostart_xdg (gboolean     start_at_spi)
 
       /* check the Hidden key */
       skip = xfce_rc_read_bool_entry (rc, "Hidden", FALSE);
+      run_hook_from_file = xfce_rc_read_int_entry (rc, "RunHook", XFSM_RUN_HOOK_LOGIN);
+
+      /* only execute scripts with match the requested run hook */
+      if (run_hook != run_hook_from_file)
+        skip = TRUE;
+
       if (G_LIKELY (!skip))
         {
           xfsm_verbose("hidden set\n");
diff --git a/xfce4-session/xfsm-global.h b/xfce4-session/xfsm-global.h
index 6bce6ff..3adeba8 100644
--- a/xfce4-session/xfsm-global.h
+++ b/xfce4-session/xfsm-global.h
@@ -27,6 +27,9 @@
 #include <X11/SM/SMlib.h>
 
 #include <xfce4-session/xfsm-splash-screen.h>
+#include <xfce4-session/xfsm-shutdown.h> /* XfsmShutdownType */
+
+#include "settings/xfae-model.h" /* XfsmRunHook */
 
 typedef struct _FailsafeClient FailsafeClient;
 struct _FailsafeClient
@@ -74,7 +77,10 @@ GdkPixbuf *xfsm_load_session_preview (const gchar *name);
 GValue *xfsm_g_value_new (GType gtype);
 void    xfsm_g_value_free (GValue *value);
 
-
-gint xfsm_startup_autostart_xdg (gboolean start_at_spi);
+gint    xfsm_launch_desktop_files_on_login    (gboolean         start_at_spi);
+gint    xfsm_launch_desktop_files_on_shutdown (gboolean         start_at_spi,
+                                               XfsmShutdownType shutdown_type);
+gint    xfsm_launch_desktop_files_on_run_hook (gboolean         start_at_spi,
+                                               XfsmRunHook      run_hook);
 
 #endif /* !__XFSM_GLOBAL_H__ */
diff --git a/xfce4-session/xfsm-manager.c b/xfce4-session/xfsm-manager.c
index b9f258a..2419aab 100644
--- a/xfce4-session/xfsm-manager.c
+++ b/xfce4-session/xfsm-manager.c
@@ -1166,6 +1166,8 @@ xfsm_manager_save_yourself_global (XfsmManager     *manager,
       if (shutdown_type != XFSM_SHUTDOWN_ASK)
         manager->shutdown_type = shutdown_type;
 
+      xfsm_launch_desktop_files_on_shutdown (FALSE, manager->shutdown_type);
+
       /* we only save the session and quit if we're actually shutting down;
        * suspend, hibernate, hybrid sleep and switch user will (if successful) return us to
        * exactly the same state, so there's no need to save session */
diff --git a/xfce4-session/xfsm-startup.c b/xfce4-session/xfsm-startup.c
index 04d3853..1f93100 100644
--- a/xfce4-session/xfsm-startup.c
+++ b/xfce4-session/xfsm-startup.c
@@ -472,7 +472,7 @@ xfsm_startup_autostart (XfsmManager *manager)
 {
   gint n;
 
-  n = xfsm_startup_autostart_xdg (FALSE);
+  n = xfsm_launch_desktop_files_on_login (FALSE);
 
   if (n > 0)
     {
@@ -578,7 +578,7 @@ xfsm_startup_at (XfsmManager *manager)
   gint n, i;
 
   /* start at-spi-dbus-bus and/or at-spi-registryd */
-  n = xfsm_startup_autostart_xdg (TRUE);
+  n = xfsm_launch_desktop_files_on_login (TRUE);
 
   if (n > 0)
     {
@@ -913,5 +913,3 @@ xfsm_startup_handle_failed_startup (XfsmProperties *properties,
       xfsm_startup_session_continue (manager);
     }
 }
-
-

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list