Blame SOURCES/0011-Tie-session-selector-to-properties-dialog.patch

cf6cdf
From 7a80fca7e35d35eda415d4823ce54a4d45afb136 Mon Sep 17 00:00:00 2001
cf6cdf
From: Ray Strode <rstrode@redhat.com>
cf6cdf
Date: Fri, 20 Dec 2013 11:28:53 -0500
cf6cdf
Subject: [PATCH 11/19] Tie session selector to properties dialog
cf6cdf
cf6cdf
---
cf6cdf
 capplet/gsm-properties-dialog.c |  30 ++++-
cf6cdf
 data/session-selector.ui        |   2 +-
cf6cdf
 tools/gnome-session-selector.c  | 211 +++++++++++++++++++++++++-------
cf6cdf
 tools/meson.build               |   3 +-
cf6cdf
 4 files changed, 200 insertions(+), 46 deletions(-)
cf6cdf
cf6cdf
diff --git a/capplet/gsm-properties-dialog.c b/capplet/gsm-properties-dialog.c
cf6cdf
index d2be778b..51fa5106 100644
cf6cdf
--- a/capplet/gsm-properties-dialog.c
cf6cdf
+++ b/capplet/gsm-properties-dialog.c
cf6cdf
@@ -471,87 +471,113 @@ session_saved_message (GsmPropertiesDialog *dialog,
cf6cdf
 {
cf6cdf
         GtkLabel *label;
cf6cdf
         gchar *markup;
cf6cdf
         label = GTK_LABEL (gtk_builder_get_object (dialog->priv->xml, CAPPLET_SESSION_SAVED_WIDGET_NAME));
cf6cdf
         if (is_error)
cf6cdf
                 markup = g_markup_printf_escaped ("%s", msg);
cf6cdf
         else
cf6cdf
                 markup = g_markup_escape_text (msg, -1);
cf6cdf
         gtk_label_set_markup (label, markup);
cf6cdf
         g_free (markup);
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
 session_saved_cb (DBusGProxy *proxy,
cf6cdf
                   DBusGProxyCall *call_id,
cf6cdf
                   void *user_data)
cf6cdf
 {
cf6cdf
         gboolean res;
cf6cdf
         GsmPropertiesDialog *dialog = user_data;
cf6cdf
 
cf6cdf
         res = dbus_g_proxy_end_call (proxy, call_id, NULL, G_TYPE_INVALID);
cf6cdf
         if (res)
cf6cdf
                 session_saved_message (dialog, _("Your session has been saved."), FALSE);
cf6cdf
         else
cf6cdf
                 session_saved_message (dialog, _("Failed to save session"), TRUE);
cf6cdf
 
cf6cdf
         g_object_unref (proxy);
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
-on_save_session_clicked (GtkWidget           *widget,
cf6cdf
-                         GsmPropertiesDialog *dialog)
cf6cdf
+save_session_directly (GsmPropertiesDialog *dialog)
cf6cdf
 {
cf6cdf
         DBusGConnection *conn;
cf6cdf
         DBusGProxy *proxy;
cf6cdf
         DBusGProxyCall *call;
cf6cdf
 
cf6cdf
         conn = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
cf6cdf
         if (conn == NULL) {
cf6cdf
                 session_saved_message (dialog, _("Could not connect to the session bus"), TRUE);
cf6cdf
                 return;
cf6cdf
         }
cf6cdf
 
cf6cdf
         proxy = dbus_g_proxy_new_for_name (conn, GSM_SERVICE_DBUS, GSM_PATH_DBUS, GSM_INTERFACE_DBUS);
cf6cdf
         if (proxy == NULL) {
cf6cdf
                 session_saved_message (dialog, _("Could not connect to the session manager"), TRUE);
cf6cdf
                 return;
cf6cdf
         }
cf6cdf
 
cf6cdf
         call = dbus_g_proxy_begin_call (proxy, "SaveSession", session_saved_cb, dialog, NULL, G_TYPE_INVALID);
cf6cdf
         if (call == NULL) {
cf6cdf
                 session_saved_message (dialog, _("Failed to save session"), TRUE);
cf6cdf
                 g_object_unref (proxy);
cf6cdf
                 return;
cf6cdf
         }
cf6cdf
 }
cf6cdf
 
cf6cdf
+static void
cf6cdf
+save_session_from_selector (GsmPropertiesDialog *dialog,
cf6cdf
+                            const char          *program_path)
cf6cdf
+{
cf6cdf
+        char *command_line = g_strdup_printf ("%s --action save", program_path);
cf6cdf
+
cf6cdf
+        g_spawn_command_line_sync (command_line, NULL, NULL, NULL, NULL);
cf6cdf
+
cf6cdf
+        g_free (command_line);
cf6cdf
+}
cf6cdf
+
cf6cdf
+static void
cf6cdf
+on_save_session_clicked (GtkWidget           *widget,
cf6cdf
+                         GsmPropertiesDialog *dialog)
cf6cdf
+{
cf6cdf
+        char *program_path;
cf6cdf
+
cf6cdf
+        program_path = g_find_program_in_path ("gnome-session-selector");
cf6cdf
+
cf6cdf
+        if (program_path != NULL) {
cf6cdf
+                save_session_from_selector (dialog, program_path);
cf6cdf
+                g_free (program_path);
cf6cdf
+        } else {
cf6cdf
+                save_session_directly (dialog);
cf6cdf
+        }
cf6cdf
+}
cf6cdf
+
cf6cdf
 static void
cf6cdf
 setup_dialog (GsmPropertiesDialog *dialog)
cf6cdf
 {
cf6cdf
         GtkTreeView       *treeview;
cf6cdf
         GtkWidget         *button;
cf6cdf
         GtkTreeModel      *tree_filter;
cf6cdf
         GtkTreeViewColumn *column;
cf6cdf
         GtkCellRenderer   *renderer;
cf6cdf
         GtkTreeSelection  *selection;
cf6cdf
         GtkTargetList     *targetlist;
cf6cdf
 
cf6cdf
         gtk_dialog_add_buttons (GTK_DIALOG (dialog),
cf6cdf
                                 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
cf6cdf
                                 NULL);
cf6cdf
 
cf6cdf
         dialog->priv->list_store = gtk_list_store_new (NUMBER_OF_COLUMNS,
cf6cdf
                                                        G_TYPE_BOOLEAN,
cf6cdf
                                                        G_TYPE_BOOLEAN,
cf6cdf
                                                        G_TYPE_ICON,
cf6cdf
                                                        G_TYPE_STRING,
cf6cdf
                                                        G_TYPE_OBJECT,
cf6cdf
                                                        G_TYPE_STRING);
cf6cdf
         tree_filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (dialog->priv->list_store),
cf6cdf
                                                  NULL);
cf6cdf
         g_object_unref (dialog->priv->list_store);
cf6cdf
         dialog->priv->tree_filter = tree_filter;
cf6cdf
 
cf6cdf
         gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (tree_filter),
cf6cdf
                                                   STORE_COL_VISIBLE);
cf6cdf
 
cf6cdf
diff --git a/data/session-selector.ui b/data/session-selector.ui
cf6cdf
index 1c55712d..1534a746 100644
cf6cdf
--- a/data/session-selector.ui
cf6cdf
+++ b/data/session-selector.ui
cf6cdf
@@ -20,61 +20,61 @@
cf6cdf
     <child>
cf6cdf
       <object class="GtkFrame" id="frame1">
cf6cdf
         <property name="visible">True</property>
cf6cdf
         <property name="label_xalign">0.5</property>
cf6cdf
         <property name="shadow_type">out</property>
cf6cdf
         <child>
cf6cdf
           <object class="GtkAlignment" id="alignment3">
cf6cdf
             <property name="visible">True</property>
cf6cdf
             <property name="border_width">12</property>
cf6cdf
             <child>
cf6cdf
               <object class="GtkVBox" id="vbox3">
cf6cdf
                 <property name="visible">True</property>
cf6cdf
                 <property name="orientation">vertical</property>
cf6cdf
                 <property name="spacing">6</property>
cf6cdf
 
cf6cdf
                 <child>
cf6cdf
                   <object class="GtkInfoBar" id="info-bar">
cf6cdf
                     <property name="visible">True</property>
cf6cdf
                     <property name="message-type">other</property>
cf6cdf
 
cf6cdf
                     <child internal-child="content_area">
cf6cdf
                       <object class="GtkHBox" id="info-bar-content_area">
cf6cdf
                         <property name="visible">True</property>
cf6cdf
                         <property name="orientation">vertical</property>
cf6cdf
                         <property name="spacing">0</property>
cf6cdf
                         <child>
cf6cdf
                           <object class="GtkLabel" id="info-label">
cf6cdf
                             <property name="visible">True</property>
cf6cdf
                             <property name="xalign">0.0</property>
cf6cdf
                             <property name="yalign">0.5</property>
cf6cdf
-                            <property name="label" translatable="yes">Please select a custom session to run</property>
cf6cdf
+                            <property name="label" translatable="yes">Please select a custom session to use</property>
cf6cdf
                           </object>
cf6cdf
                           <packing>
cf6cdf
                             <property name="expand">True</property>
cf6cdf
                             <property name="fill">True</property>
cf6cdf
                             <property name="position">0</property>
cf6cdf
                           </packing>
cf6cdf
                         </child>
cf6cdf
                       </object>
cf6cdf
                     </child>
cf6cdf
                   </object>
cf6cdf
                   <packing>
cf6cdf
                     <property name="expand">False</property>
cf6cdf
                     <property name="fill">True</property>
cf6cdf
                     <property name="position">0</property>
cf6cdf
                   </packing>
cf6cdf
                 </child>
cf6cdf
                 <child>
cf6cdf
                   <object class="GtkVBox" id="vbox4">
cf6cdf
                     <property name="visible">True</property>
cf6cdf
                     <property name="orientation">vertical</property>
cf6cdf
                     <property name="spacing">12</property>
cf6cdf
                     <child>
cf6cdf
                       <object class="GtkHBox" id="hbox3">
cf6cdf
                         <property name="visible">True</property>
cf6cdf
                         <property name="spacing">12</property>
cf6cdf
                         <child>
cf6cdf
                           <object class="GtkScrolledWindow" id="scrolledwindow2">
cf6cdf
                             <property name="visible">True</property>
cf6cdf
                             <property name="can_focus">True</property>
cf6cdf
                             <property name="hscrollbar_policy">never</property>
cf6cdf
diff --git a/tools/gnome-session-selector.c b/tools/gnome-session-selector.c
cf6cdf
index 71892c43..53822f6c 100644
cf6cdf
--- a/tools/gnome-session-selector.c
cf6cdf
+++ b/tools/gnome-session-selector.c
cf6cdf
@@ -7,126 +7,133 @@
cf6cdf
  * the Free Software Foundation; either version 2 of the License, or
cf6cdf
  * (at your option) any later version.
cf6cdf
  *
cf6cdf
  * This program is distributed in the hope that it will be useful,
cf6cdf
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
cf6cdf
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
cf6cdf
  * GNU General Public License for more details.
cf6cdf
  *
cf6cdf
  * You should have received a copy of the GNU General Public License
cf6cdf
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
cf6cdf
  *
cf6cdf
  * Written by: Matthias Clasen <mclasen@redhat.com>
cf6cdf
  */
cf6cdf
 
cf6cdf
 #include "config.h"
cf6cdf
 
cf6cdf
 #include <fcntl.h>
cf6cdf
 #include <stdlib.h>
cf6cdf
 #include <string.h>
cf6cdf
 #include <sys/types.h>
cf6cdf
 #include <sys/stat.h>
cf6cdf
 #include <unistd.h>
cf6cdf
 
cf6cdf
 #include <glib.h>
cf6cdf
 #include <gtk/gtk.h>
cf6cdf
 #include <gio/gio.h>
cf6cdf
 
cf6cdf
 #include <glib/gi18n.h>
cf6cdf
 #include <glib/gstdio.h>
cf6cdf
 
cf6cdf
+#include <dbus/dbus-glib.h>
cf6cdf
+#include <dbus/dbus-glib-lowlevel.h>
cf6cdf
+
cf6cdf
+#define GSM_SERVICE_DBUS   "org.gnome.SessionManager"
cf6cdf
+#define GSM_PATH_DBUS      "/org/gnome/SessionManager"
cf6cdf
+#define GSM_INTERFACE_DBUS "org.gnome.SessionManager"
cf6cdf
+
cf6cdf
 #define GSM_MANAGER_SCHEMA        "org.gnome.SessionManager"
cf6cdf
 #define KEY_AUTOSAVE_ONE_SHOT     "auto-save-session-one-shot"
cf6cdf
 
cf6cdf
 static GtkBuilder *builder;
cf6cdf
 static GtkWidget *session_list;
cf6cdf
 static GtkListStore *store;
cf6cdf
 static GtkTreeModelSort *sort_model;
cf6cdf
+static char *info_text;
cf6cdf
 
cf6cdf
 static void select_session (const char *name);
cf6cdf
+static gboolean make_session_current (const char *name);
cf6cdf
 
cf6cdf
 static char *
cf6cdf
 get_session_path (const char *name)
cf6cdf
 {
cf6cdf
         return g_build_filename (g_get_user_config_dir (), "gnome-session", name, NULL);
cf6cdf
 }
cf6cdf
 
cf6cdf
 static char *
cf6cdf
 find_new_session_name (void)
cf6cdf
 {
cf6cdf
         char *name;
cf6cdf
         char *path;
cf6cdf
         int i;
cf6cdf
 
cf6cdf
         for (i = 1; i < 20; i++) {
cf6cdf
                 name = g_strdup_printf (_("Session %d"), i);
cf6cdf
                 path = get_session_path (name);
cf6cdf
                 if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
cf6cdf
                         g_free (path);
cf6cdf
                         return name;
cf6cdf
                 }
cf6cdf
                 g_free (path);
cf6cdf
                 g_free (name);
cf6cdf
         }
cf6cdf
 
cf6cdf
         return NULL;
cf6cdf
 }
cf6cdf
 
cf6cdf
 static gboolean
cf6cdf
 is_valid_session_name (const char *name)
cf6cdf
 {
cf6cdf
         GtkTreeIter iter;
cf6cdf
         char *n;
cf6cdf
-        const char *info_text;
cf6cdf
         char *warning_text;
cf6cdf
         gboolean user_tried_dot;
cf6cdf
         gboolean user_tried_slash;
cf6cdf
         GtkWidget *info_bar;
cf6cdf
         GtkWidget *label;
cf6cdf
 
cf6cdf
         if (name[0] == 0) {
cf6cdf
                 return FALSE;
cf6cdf
         }
cf6cdf
 
cf6cdf
         if (name[0] == '.') {
cf6cdf
             user_tried_dot = TRUE;
cf6cdf
         } else {
cf6cdf
             user_tried_dot = FALSE;
cf6cdf
         }
cf6cdf
 
cf6cdf
         if (strchr (name, '/') != NULL) {
cf6cdf
             user_tried_slash = TRUE;
cf6cdf
         } else {
cf6cdf
             user_tried_slash = FALSE;
cf6cdf
         }
cf6cdf
 
cf6cdf
-        info_text = _("Please select a custom session to run");
cf6cdf
         warning_text = NULL;
cf6cdf
         if (user_tried_dot && user_tried_slash) {
cf6cdf
             warning_text = g_strdup_printf ("%s\n<small>Note: %s</small>",
cf6cdf
                                             info_text,
cf6cdf
                                             _("Session names are not allowed to start with “.” or contain “/” characters"));
cf6cdf
         } else if (user_tried_dot) {
cf6cdf
             warning_text = g_strdup_printf ("%s\n<small>Note: %s</small>",
cf6cdf
                                             info_text,
cf6cdf
                                             _("Session names are not allowed to start with “.”"));
cf6cdf
         } else if (user_tried_slash) {
cf6cdf
             warning_text = g_strdup_printf ("%s\n<small>Note: %s</small>",
cf6cdf
                                             info_text,
cf6cdf
                                             _("Session names are not allowed to contain “/” characters"));
cf6cdf
         }
cf6cdf
 
cf6cdf
         gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
cf6cdf
         do {
cf6cdf
                 gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &n, -1);
cf6cdf
                 if (strcmp (n, name) == 0) {
cf6cdf
                         char *message;
cf6cdf
                         message = g_strdup_printf (_("A session named “%s” already exists"), name);
cf6cdf
                         warning_text = g_strdup_printf ("%s\n<small>Note: %s</small>", info_text, message);
cf6cdf
                         g_free (message);
cf6cdf
                         g_free (n);
cf6cdf
                         break;
cf6cdf
                 }
cf6cdf
                 g_free (n);
cf6cdf
         } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
cf6cdf
 
cf6cdf
         info_bar = (GtkWidget *) gtk_builder_get_object (builder, "info-bar");
cf6cdf
@@ -181,518 +188,638 @@ populate_session_list (GtkWidget *session_list)
cf6cdf
 
cf6cdf
         default_name = NULL;
cf6cdf
         if (readlink (saved_session, last_session, PATH_MAX - 1) > 0) {
cf6cdf
                 default_name = g_path_get_basename (last_session);
cf6cdf
         }
cf6cdf
 
cf6cdf
         while ((name = g_dir_read_name (dir)) != NULL) {
cf6cdf
                 if (strcmp (name, "saved-session") == 0)
cf6cdf
                         continue;
cf6cdf
 
cf6cdf
                 gtk_list_store_insert_with_values (store, &iter, 100, 0, name, -1);
cf6cdf
 
cf6cdf
                 if (g_strcmp0 (default_name, name) == 0) {
cf6cdf
                         GtkTreeSelection *selection;
cf6cdf
                         GtkTreeIter child_iter;
cf6cdf
 
cf6cdf
                         gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &child_iter, &iter);
cf6cdf
                         selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (session_list));
cf6cdf
                         gtk_tree_selection_select_iter (selection, &child_iter);
cf6cdf
                 }
cf6cdf
         }
cf6cdf
 
cf6cdf
         g_free (default_name);
cf6cdf
         g_dir_close (dir);
cf6cdf
 
cf6cdf
  out:
cf6cdf
         g_free (saved_session);
cf6cdf
         g_free (path);
cf6cdf
 }
cf6cdf
 
cf6cdf
+static char *
cf6cdf
+get_last_session (void)
cf6cdf
+{
cf6cdf
+        char *saved_session;
cf6cdf
+        char last_session[PATH_MAX] = "";
cf6cdf
+        char *name = NULL;
cf6cdf
+
cf6cdf
+        saved_session = get_session_path ("saved-session");
cf6cdf
+
cf6cdf
+        if (readlink (saved_session, last_session, PATH_MAX - 1) > 0) {
cf6cdf
+                name = g_path_get_basename (last_session);
cf6cdf
+        }
cf6cdf
+
cf6cdf
+        g_free (saved_session);
cf6cdf
+
cf6cdf
+        return name;
cf6cdf
+}
cf6cdf
+
cf6cdf
 static char *
cf6cdf
 get_selected_session (void)
cf6cdf
 {
cf6cdf
         GtkTreeSelection *selection;
cf6cdf
         GtkTreeModel *model;
cf6cdf
         GtkTreeIter iter;
cf6cdf
         gchar *name;
cf6cdf
 
cf6cdf
         selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (session_list));
cf6cdf
         if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
cf6cdf
                 gtk_tree_model_get (model, &iter, 0, &name, -1);
cf6cdf
                 return name;
cf6cdf
         }
cf6cdf
 
cf6cdf
         return NULL;
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
 remove_session (const char *name)
cf6cdf
 {
cf6cdf
         char *path1, *path2;
cf6cdf
         char *n, *path;
cf6cdf
         const char *d;
cf6cdf
         GDir *dir;
cf6cdf
         GError *error;
cf6cdf
 
cf6cdf
         path1 = get_session_path ("saved-session");
cf6cdf
         path2 = get_session_path (name);
cf6cdf
 
cf6cdf
         error = NULL;
cf6cdf
         n = g_file_read_link (path1, &error);
cf6cdf
         if (n == NULL) {
cf6cdf
                 g_warning ("Failed to read link: %s", error->message);
cf6cdf
                 g_error_free (error);
cf6cdf
         }
cf6cdf
         else if (strcmp (n, name) == 0) {
cf6cdf
                 unlink (path1);
cf6cdf
         }
cf6cdf
         g_free (n);
cf6cdf
 
cf6cdf
         dir = g_dir_open (path2, 0, NULL);
cf6cdf
         while ((d = g_dir_read_name (dir)) != NULL) {
cf6cdf
                 path = g_build_filename (path2, d, NULL);
cf6cdf
                 unlink (path);
cf6cdf
                 g_free (path);
cf6cdf
         }
cf6cdf
         g_dir_close (dir);
cf6cdf
 
cf6cdf
         remove (path2);
cf6cdf
 
cf6cdf
         g_free (path1);
cf6cdf
         g_free (path2);
cf6cdf
 }
cf6cdf
 
cf6cdf
+static gboolean
cf6cdf
+make_session_current (const char *name)
cf6cdf
+{
cf6cdf
+        char *path1;
cf6cdf
+        gboolean ret = TRUE;
cf6cdf
+
cf6cdf
+        path1 = g_build_filename (g_get_user_config_dir (), "gnome-session", "saved-session", NULL);
cf6cdf
+
cf6cdf
+        unlink (path1);
cf6cdf
+        if (symlink (name, path1) < 0) {
cf6cdf
+                g_warning ("Failed to make session '%s' current", name);
cf6cdf
+                ret = FALSE;
cf6cdf
+        }
cf6cdf
+
cf6cdf
+        g_free (path1);
cf6cdf
+
cf6cdf
+        return ret;
cf6cdf
+}
cf6cdf
+
cf6cdf
 static void
cf6cdf
 on_remove_session_clicked (GtkButton *button,
cf6cdf
                            gpointer   data)
cf6cdf
 {
cf6cdf
         GtkTreeSelection *selection;
cf6cdf
         GtkTreeModel *model;
cf6cdf
         GtkTreeIter iter;
cf6cdf
         char *name;
cf6cdf
 
cf6cdf
         selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (session_list));
cf6cdf
         if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
cf6cdf
                 GtkTreeIter child_iter;
cf6cdf
                 gtk_tree_model_get (model, &iter, 0, &name, -1);
cf6cdf
                 remove_session (name);
cf6cdf
                 g_free (name);
cf6cdf
 
cf6cdf
                 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (model), &child_iter, &iter);
cf6cdf
                 gtk_list_store_remove (GTK_LIST_STORE (store), &child_iter);
cf6cdf
 
cf6cdf
                 if (!gtk_tree_selection_get_selected (selection, NULL, NULL)) {
cf6cdf
                         gtk_tree_model_get_iter_first (model, &iter);
cf6cdf
                         gtk_tree_model_get (model, &iter, 0, &name, -1);
cf6cdf
                         select_session (name);
cf6cdf
+                        make_session_current (name);
cf6cdf
                         g_free (name);
cf6cdf
                 }
cf6cdf
         }
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
 begin_rename (void)
cf6cdf
 {
cf6cdf
         GtkTreePath *path;
cf6cdf
         GtkTreeViewColumn *column;
cf6cdf
         GList *cells;
cf6cdf
 
cf6cdf
         gtk_widget_grab_focus (session_list);
cf6cdf
 
cf6cdf
         gtk_tree_view_get_cursor (GTK_TREE_VIEW (session_list),
cf6cdf
                                   &path, &column);
cf6cdf
 
cf6cdf
         cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
cf6cdf
 
cf6cdf
         if (cells != NULL) {
cf6cdf
             GtkCellRenderer *cell;
cf6cdf
 
cf6cdf
             cell = (GtkCellRenderer *) cells->data;
cf6cdf
             g_list_free (cells);
cf6cdf
 
cf6cdf
             g_object_set (cell, "editable", TRUE, NULL);
cf6cdf
             gtk_tree_view_set_cursor_on_cell (GTK_TREE_VIEW (session_list), path,
cf6cdf
                                               column, cell, TRUE);
cf6cdf
         }
cf6cdf
         gtk_tree_path_free (path);
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
 on_rename_session_clicked (GtkButton *button,
cf6cdf
                            gpointer   data)
cf6cdf
 {
cf6cdf
     begin_rename ();
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
 on_continue_clicked (GtkButton *button,
cf6cdf
                      gpointer    data)
cf6cdf
 {
cf6cdf
         char *name;
cf6cdf
 
cf6cdf
         name = get_selected_session ();
cf6cdf
         g_free (name);
cf6cdf
 
cf6cdf
         gtk_main_quit ();
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
 create_session (const char *name)
cf6cdf
 {
cf6cdf
         char *path;
cf6cdf
         GtkTreeIter iter;
cf6cdf
 
cf6cdf
         path = get_session_path (name);
cf6cdf
 
cf6cdf
-        if (mkdir (path, 0755) < 0) {
cf6cdf
+        if (g_mkdir_with_parents (path, 0755) < 0) {
cf6cdf
                 g_warning ("Failed to create directory %s", path);
cf6cdf
         }
cf6cdf
         else {
cf6cdf
                 char *marker;
cf6cdf
 
cf6cdf
                 gtk_list_store_insert_with_values (store, &iter, 100, 0, name, -1);
cf6cdf
 
cf6cdf
                 marker = g_build_filename (path, ".new-session", NULL);
cf6cdf
                 creat (marker, 0600);
cf6cdf
                 g_free (marker);
cf6cdf
         }
cf6cdf
 
cf6cdf
         g_free (path);
cf6cdf
 }
cf6cdf
 
cf6cdf
 static gboolean
cf6cdf
 rename_session (const char *old_name,
cf6cdf
                 const char *new_name)
cf6cdf
 {
cf6cdf
         char *old_path, *new_path;
cf6cdf
         int result;
cf6cdf
 
cf6cdf
         if (g_strcmp0 (old_name, new_name) == 0) {
cf6cdf
                 return TRUE;
cf6cdf
         }
cf6cdf
 
cf6cdf
         if (!is_valid_session_name (new_name)) {
cf6cdf
                return FALSE;
cf6cdf
         }
cf6cdf
 
cf6cdf
         old_path = get_session_path (old_name);
cf6cdf
         new_path = get_session_path (new_name);
cf6cdf
 
cf6cdf
         result = g_rename (old_path, new_path);
cf6cdf
 
cf6cdf
         if (result < 0) {
cf6cdf
                 g_warning ("Failed to rename session from '%s' to '%s': %m", old_name, new_name);
cf6cdf
+        } else {
cf6cdf
+                char *last_session;
cf6cdf
+                last_session = get_last_session ();
cf6cdf
+                if (g_strcmp0 (old_name, last_session) == 0) {
cf6cdf
+                        make_session_current (new_name);
cf6cdf
+                }
cf6cdf
+                g_free (last_session);
cf6cdf
         }
cf6cdf
 
cf6cdf
         g_free (old_path);
cf6cdf
         g_free (new_path);
cf6cdf
-
cf6cdf
         return result == 0;
cf6cdf
 }
cf6cdf
 
cf6cdf
-static gboolean
cf6cdf
-make_session_current (const char *name)
cf6cdf
-{
cf6cdf
-        char *path1;
cf6cdf
-        gboolean ret = TRUE;
cf6cdf
-
cf6cdf
-        path1 = g_build_filename (g_get_user_config_dir (), "gnome-session", "saved-session", NULL);
cf6cdf
-
cf6cdf
-        unlink (path1);
cf6cdf
-        if (symlink (name, path1) < 0) {
cf6cdf
-                g_warning ("Failed to make session '%s' current", name);
cf6cdf
-                ret = FALSE;
cf6cdf
-        }
cf6cdf
-
cf6cdf
-        g_free (path1);
cf6cdf
-
cf6cdf
-        return ret;
cf6cdf
-}
cf6cdf
-
cf6cdf
 static gboolean
cf6cdf
 create_and_select_session (const char *name)
cf6cdf
 {
cf6cdf
         gchar *path;
cf6cdf
 
cf6cdf
         if (name[0] == 0 || name[0] == '.' || strchr (name, '/')) {
cf6cdf
                 g_warning ("Invalid session name");
cf6cdf
                 return FALSE;
cf6cdf
         }
cf6cdf
 
cf6cdf
         path = g_build_filename (g_get_user_config_dir (), "gnome-session", name, NULL);
cf6cdf
         if (!g_file_test (path, G_FILE_TEST_IS_DIR)) {
cf6cdf
-                if (mkdir (path, 0755) < 0) {
cf6cdf
+                if (g_mkdir_with_parents (path, 0755) < 0) {
cf6cdf
                         g_warning ("Failed to create directory %s", path);
cf6cdf
                         g_free (path);
cf6cdf
                         return FALSE;
cf6cdf
                 }
cf6cdf
         }
cf6cdf
 
cf6cdf
         g_free (path);
cf6cdf
 
cf6cdf
         return make_session_current (name);
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
 select_session (const char *name)
cf6cdf
 {
cf6cdf
         GtkTreeIter iter;
cf6cdf
         char *n;
cf6cdf
 
cf6cdf
-        make_session_current (name);
cf6cdf
-
cf6cdf
         /* now select it in the list */
cf6cdf
         gtk_tree_model_get_iter_first (GTK_TREE_MODEL (sort_model), &iter);
cf6cdf
         do {
cf6cdf
                 gtk_tree_model_get (GTK_TREE_MODEL (sort_model), &iter, 0, &n, -1);
cf6cdf
                 if (strcmp (n, name) == 0) {
cf6cdf
                         GtkTreePath *path;
cf6cdf
 
cf6cdf
                         path = gtk_tree_model_get_path (GTK_TREE_MODEL (sort_model), &iter);
cf6cdf
                         gtk_tree_view_set_cursor (GTK_TREE_VIEW (session_list), path, NULL, FALSE);
cf6cdf
                         gtk_tree_path_free (path);
cf6cdf
                         g_free (n);
cf6cdf
                         break;
cf6cdf
                 }
cf6cdf
                 g_free (n);
cf6cdf
         } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (sort_model), &iter));
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
-on_new_session_clicked (GtkButton *button,
cf6cdf
-                        gpointer   data)
cf6cdf
+create_session_and_begin_rename (void)
cf6cdf
 {
cf6cdf
         gchar *name;
cf6cdf
 
cf6cdf
         name = find_new_session_name ();
cf6cdf
         create_session (name);
cf6cdf
         select_session (name);
cf6cdf
 
cf6cdf
         begin_rename ();
cf6cdf
 }
cf6cdf
 
cf6cdf
+static void
cf6cdf
+on_new_session_clicked (GtkButton *button,
cf6cdf
+                        gpointer   data)
cf6cdf
+{
cf6cdf
+	create_session_and_begin_rename ();
cf6cdf
+}
cf6cdf
+
cf6cdf
 static void
cf6cdf
 on_selection_changed (GtkTreeSelection *selection,
cf6cdf
                       gpointer          data)
cf6cdf
 {
cf6cdf
         char *name;
cf6cdf
 
cf6cdf
         name = get_selected_session ();
cf6cdf
 
cf6cdf
         if (name == NULL) {
cf6cdf
                 return;
cf6cdf
         }
cf6cdf
 
cf6cdf
-        make_session_current (name);
cf6cdf
-
cf6cdf
         g_free (name);
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
 update_remove_button (void)
cf6cdf
 {
cf6cdf
         GtkWidget *button;
cf6cdf
 
cf6cdf
         button = (GtkWidget *)gtk_builder_get_object (builder, "remove-session");
cf6cdf
         if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) > 1) {
cf6cdf
                 gtk_widget_set_sensitive (button, TRUE);
cf6cdf
         } else {
cf6cdf
                 gtk_widget_set_sensitive (button, FALSE);
cf6cdf
         }
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
 on_row_edited (GtkCellRendererText *cell,
cf6cdf
                const char          *path_string,
cf6cdf
                const char          *new_name,
cf6cdf
                gpointer             data)
cf6cdf
 {
cf6cdf
         GtkTreePath *path;
cf6cdf
         GtkTreeIter  sort_iter, items_iter;
cf6cdf
         char        *old_name;
cf6cdf
         gboolean     was_renamed;
cf6cdf
 
cf6cdf
         path = gtk_tree_path_new_from_string (path_string);
cf6cdf
         gtk_tree_model_get_iter (GTK_TREE_MODEL (sort_model), &sort_iter, path);
cf6cdf
 
cf6cdf
         gtk_tree_model_get (GTK_TREE_MODEL (sort_model), &sort_iter, 0, &old_name, -1);
cf6cdf
 
cf6cdf
         was_renamed = rename_session (old_name, new_name);
cf6cdf
 
cf6cdf
         if (was_renamed) {
cf6cdf
                 gtk_tree_model_sort_convert_iter_to_child_iter (sort_model, &items_iter, &sort_iter);
cf6cdf
 
cf6cdf
                 gtk_list_store_set (store, &items_iter, 0, g_strdup (new_name), -1);
cf6cdf
                 g_free (old_name);
cf6cdf
-                make_session_current (new_name);
cf6cdf
         } else {
cf6cdf
                 begin_rename ();
cf6cdf
         }
cf6cdf
 
cf6cdf
         gtk_tree_path_free (path);
cf6cdf
 
cf6cdf
         g_object_set (cell, "editable", FALSE, NULL);
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
 on_row_deleted (GtkTreeModel *model,
cf6cdf
                 GtkTreePath  *path,
cf6cdf
                 gpointer      data)
cf6cdf
 {
cf6cdf
         update_remove_button ();
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
 on_row_inserted (GtkTreeModel *model,
cf6cdf
                  GtkTreePath  *path,
cf6cdf
                  GtkTreeIter  *iter,
cf6cdf
                  gpointer      data)
cf6cdf
 {
cf6cdf
         update_remove_button ();
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
 on_row_activated (GtkTreeView       *tree_view,
cf6cdf
                   GtkTreePath       *path,
cf6cdf
                   GtkTreeViewColumn *column,
cf6cdf
                   gpointer           data)
cf6cdf
 {
cf6cdf
-        char *name;
cf6cdf
-
cf6cdf
-        name = get_selected_session ();
cf6cdf
-        g_free (name);
cf6cdf
-
cf6cdf
         gtk_main_quit ();
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
 auto_save_next_session (void)
cf6cdf
 {
cf6cdf
         GSettings *settings;
cf6cdf
 
cf6cdf
         settings = g_settings_new (GSM_MANAGER_SCHEMA);
cf6cdf
         g_settings_set_boolean (settings, KEY_AUTOSAVE_ONE_SHOT, TRUE);
cf6cdf
         g_object_unref (settings);
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
 auto_save_next_session_if_needed (void)
cf6cdf
 {
cf6cdf
         char *marker;
cf6cdf
 
cf6cdf
         marker = g_build_filename (g_get_user_config_dir (),
cf6cdf
                                    "gnome-session", "saved-session",
cf6cdf
                                    ".new-session", NULL);
cf6cdf
 
cf6cdf
         if (g_file_test (marker, G_FILE_TEST_EXISTS)) {
cf6cdf
                 auto_save_next_session ();
cf6cdf
                 unlink (marker);
cf6cdf
         }
cf6cdf
         g_free (marker);
cf6cdf
 }
cf6cdf
 
cf6cdf
+static void
cf6cdf
+save_session (void)
cf6cdf
+{
cf6cdf
+        DBusGConnection *conn;
cf6cdf
+        DBusGProxy *proxy;
cf6cdf
+        GError *error;
cf6cdf
+
cf6cdf
+        conn = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
cf6cdf
+        if (conn == NULL) {
cf6cdf
+                g_warning ("Could not connect to the session bus");
cf6cdf
+                return;
cf6cdf
+        }
cf6cdf
+
cf6cdf
+        proxy = dbus_g_proxy_new_for_name (conn, GSM_SERVICE_DBUS, GSM_PATH_DBUS, GSM_INTERFACE_DBUS);
cf6cdf
+        if (proxy == NULL) {
cf6cdf
+                g_warning ("Could not connect to the session manager");
cf6cdf
+                return;
cf6cdf
+        }
cf6cdf
+
cf6cdf
+        error = NULL;
cf6cdf
+        if (!dbus_g_proxy_call (proxy, "SaveSession", &error, G_TYPE_INVALID, G_TYPE_INVALID)) {
cf6cdf
+                g_warning ("Failed to save session: %s", error->message);
cf6cdf
+                g_error_free (error);
cf6cdf
+                return;
cf6cdf
+        }
cf6cdf
+
cf6cdf
+        g_object_unref (proxy);
cf6cdf
+}
cf6cdf
+
cf6cdf
 static int
cf6cdf
 compare_sessions (GtkTreeModel *model,
cf6cdf
                   GtkTreeIter  *a,
cf6cdf
                   GtkTreeIter  *b,
cf6cdf
                   gpointer      data)
cf6cdf
 {
cf6cdf
     char *name_a, *name_b;
cf6cdf
     int result;
cf6cdf
 
cf6cdf
     gtk_tree_model_get (model, a, 0, &name_a, -1);
cf6cdf
     gtk_tree_model_get (model, b, 0, &name_b, -1);
cf6cdf
 
cf6cdf
     result = g_utf8_collate (name_a, name_b);
cf6cdf
 
cf6cdf
     g_free (name_a);
cf6cdf
     g_free (name_b);
cf6cdf
 
cf6cdf
     return result;
cf6cdf
 }
cf6cdf
 
cf6cdf
 static void
cf6cdf
 on_map (GtkWidget *widget,
cf6cdf
         gpointer   data)
cf6cdf
 {
cf6cdf
         gdk_window_focus (gtk_widget_get_window (widget), GDK_CURRENT_TIME);
cf6cdf
 }
cf6cdf
 
cf6cdf
 int
cf6cdf
 main (int argc, char *argv[])
cf6cdf
 {
cf6cdf
         GtkWidget *window;
cf6cdf
         GtkWidget *widget;
cf6cdf
+        GtkWidget *label;
cf6cdf
         GtkCellRenderer *cell;
cf6cdf
         GtkTreeViewColumn *column;
cf6cdf
         GtkTreeSelection *selection;
cf6cdf
         GError *error;
cf6cdf
+        char *selected_session;
cf6cdf
+
cf6cdf
+        static char *action = NULL;
cf6cdf
+        static char **remaining_args = NULL;
cf6cdf
+        static GOptionEntry entries[] = {
cf6cdf
+                {"action", '\0', 0, G_OPTION_ARG_STRING, &action, N_("What to do with session selection (save|load|print)"), NULL},
cf6cdf
+{ G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &remaining_args, N_("[session-name]"), NULL}
cf6cdf
+        };
cf6cdf
+
cf6cdf
+        if (action == NULL) {
cf6cdf
+            if (getenv ("SESSION_MANAGER") != NULL)
cf6cdf
+                action = "print";
cf6cdf
+            else
cf6cdf
+                action = "load";
cf6cdf
+        }
cf6cdf
 
cf6cdf
-        if (getenv ("SESSION_MANAGER") != NULL)
cf6cdf
+        if (getenv ("SESSION_MANAGER") != NULL && strcmp (action, "load") == 0) {
cf6cdf
+            g_warning ("Cannot load new session when session currently loaded");
cf6cdf
             return 1;
cf6cdf
+        }
cf6cdf
+
cf6cdf
+        if (getenv ("SESSION_MANAGER") == NULL && strcmp (action, "save") == 0) {
cf6cdf
+            g_warning ("Can only save session when session loaded");
cf6cdf
+            return 1;
cf6cdf
+        }
cf6cdf
+
cf6cdf
+        if (strcmp (action, "load") != 0 && strcmp (action, "save") != 0 && strcmp (action, "print") != 0) {
cf6cdf
+            g_warning ("'%s' is not a supported action.  Supported actions are load, save, and print.\n", action);
cf6cdf
+            return 1;
cf6cdf
+        }
cf6cdf
 
cf6cdf
-        gtk_init (&argc, &argv);
cf6cdf
-        if (argc > 1) {
cf6cdf
-                g_print ("create and select session\n");
cf6cdf
-                if (!create_and_select_session (argv[1]))
cf6cdf
+        error = NULL;
cf6cdf
+        gtk_init_with_args (&argc, &argv,
cf6cdf
+                            NULL, entries, GETTEXT_PACKAGE, &error);
cf6cdf
+
cf6cdf
+        if (remaining_args != NULL) {
cf6cdf
+                if (g_strv_length (remaining_args) > 1) {
cf6cdf
+                        g_warning ("gnome-session-selector takes at most one session argument");
cf6cdf
+                        return 1;
cf6cdf
+                }
cf6cdf
+
cf6cdf
+                if (!create_and_select_session (remaining_args[0]))
cf6cdf
                         return 1;
cf6cdf
                 else
cf6cdf
                         return 0;
cf6cdf
         }
cf6cdf
 
cf6cdf
         builder = gtk_builder_new ();
cf6cdf
         gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE);
cf6cdf
 
cf6cdf
         error = NULL;
cf6cdf
         if (!gtk_builder_add_from_file (builder, GTKBUILDER_DIR "/" "session-selector.ui",  &error)) {
cf6cdf
                 g_warning ("Could not load file 'session-selector.ui': %s", error->message);
cf6cdf
                 exit (1);
cf6cdf
         }
cf6cdf
 
cf6cdf
         window = (GtkWidget *) gtk_builder_get_object (builder, "main-window");
cf6cdf
 
cf6cdf
         store = (GtkListStore *) gtk_builder_get_object (builder, "session-store");
cf6cdf
         sort_model = (GtkTreeModelSort *) gtk_builder_get_object (builder, "sort-model");
cf6cdf
 
cf6cdf
         gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sort_model),
cf6cdf
                                          0, compare_sessions, NULL, NULL);
cf6cdf
         gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
cf6cdf
                                               0, GTK_SORT_ASCENDING);
cf6cdf
         g_signal_connect (store, "row-deleted", G_CALLBACK (on_row_deleted), NULL);
cf6cdf
         g_signal_connect (store, "row-inserted", G_CALLBACK (on_row_inserted), NULL);
cf6cdf
         session_list = (GtkWidget *) gtk_builder_get_object (builder, "session-list");
cf6cdf
 
cf6cdf
         selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (session_list));
cf6cdf
         gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
cf6cdf
 
cf6cdf
         populate_session_list (session_list);
cf6cdf
 
cf6cdf
         cell = gtk_cell_renderer_text_new ();
cf6cdf
         g_signal_connect (cell, "edited", G_CALLBACK (on_row_edited), NULL);
cf6cdf
 
cf6cdf
         column = gtk_tree_view_column_new_with_attributes ("", cell, "text", 0, NULL);
cf6cdf
         gtk_tree_view_append_column (GTK_TREE_VIEW (session_list), GTK_TREE_VIEW_COLUMN (column));
cf6cdf
 
cf6cdf
         g_signal_connect (session_list, "row-activated", G_CALLBACK (on_row_activated), NULL);
cf6cdf
 
cf6cdf
         g_signal_connect (selection, "changed",
cf6cdf
                           G_CALLBACK (on_selection_changed), NULL);
cf6cdf
 
cf6cdf
         widget = (GtkWidget *) gtk_builder_get_object (builder, "new-session");
cf6cdf
         g_signal_connect (widget, "clicked", G_CALLBACK (on_new_session_clicked), NULL);
cf6cdf
         widget = (GtkWidget *) gtk_builder_get_object (builder, "remove-session");
cf6cdf
         g_signal_connect (widget, "clicked", G_CALLBACK (on_remove_session_clicked), NULL);
cf6cdf
         widget = (GtkWidget *) gtk_builder_get_object (builder, "rename-session");
cf6cdf
         g_signal_connect (widget, "clicked", G_CALLBACK (on_rename_session_clicked), NULL);
cf6cdf
         widget = (GtkWidget *) gtk_builder_get_object (builder, "continue-button");
cf6cdf
         g_signal_connect (widget, "clicked", G_CALLBACK (on_continue_clicked), NULL);
cf6cdf
 
cf6cdf
         g_signal_connect (window, "map", G_CALLBACK (on_map), NULL);
cf6cdf
         gtk_widget_show (window);
cf6cdf
 
cf6cdf
+        if (g_strcmp0 (action, "load") == 0) {
cf6cdf
+            info_text = _("Please select a custom session to run");
cf6cdf
+        } else if (g_strcmp0 (action, "print") == 0) {
cf6cdf
+            info_text = _("Please select a session to use");
cf6cdf
+        } else if (g_strcmp0 (action, "save") == 0) {
cf6cdf
+            info_text = _("Please select a session to save to");
cf6cdf
+        }
cf6cdf
+
cf6cdf
+        label = (GtkWidget*) gtk_builder_get_object (builder, "info-label");
cf6cdf
+        gtk_label_set_markup (GTK_LABEL (label), info_text);
cf6cdf
+
cf6cdf
+        selected_session = get_selected_session ();
cf6cdf
+
cf6cdf
+        if (selected_session == NULL) {
cf6cdf
+		create_session_and_begin_rename ();
cf6cdf
+	} else {
cf6cdf
+		g_free (selected_session);
cf6cdf
+        }
cf6cdf
+
cf6cdf
         gtk_main ();
cf6cdf
 
cf6cdf
-        auto_save_next_session_if_needed ();
cf6cdf
+        selected_session = get_selected_session ();
cf6cdf
+
cf6cdf
+        if (g_strcmp0 (action, "load") == 0) {
cf6cdf
+                make_session_current (selected_session);
cf6cdf
+                auto_save_next_session_if_needed ();
cf6cdf
+        } else if (g_strcmp0 (action, "save") == 0) {
cf6cdf
+                char *last_session;
cf6cdf
+
cf6cdf
+                last_session = get_last_session ();
cf6cdf
+                make_session_current (selected_session);
cf6cdf
+                save_session ();
cf6cdf
+                if (last_session != NULL)
cf6cdf
+                    make_session_current (last_session);
cf6cdf
+        } else if (g_strcmp0 (action, "print") == 0) {
cf6cdf
+                g_print ("%s\n", selected_session);
cf6cdf
+        }
cf6cdf
+        g_free (selected_session);
cf6cdf
 
cf6cdf
         return 0;
cf6cdf
 }
cf6cdf
diff --git a/tools/meson.build b/tools/meson.build
cf6cdf
index 10ee918c..4bd24220 100644
cf6cdf
--- a/tools/meson.build
cf6cdf
+++ b/tools/meson.build
cf6cdf
@@ -1,52 +1,53 @@
cf6cdf
 install_data(
cf6cdf
   'gnome-session-custom-session',
cf6cdf
   install_dir: session_bindir
cf6cdf
 )
cf6cdf
 
cf6cdf
 deps = session_deps + [
cf6cdf
   sm_dep,
cf6cdf
   ice_dep
cf6cdf
 ]
cf6cdf
 
cf6cdf
 cflags = ['-DLOCALE_DIR="@0@"'.format(session_localedir)]
cf6cdf
 
cf6cdf
 programs = [
cf6cdf
   # name, deps, cflags, install_dir
cf6cdf
   ['gnome-session-quit', deps, cflags, session_bindir],
cf6cdf
   ['gnome-session-inhibit', session_deps, cflags, session_bindir]
cf6cdf
 ]
cf6cdf
 
cf6cdf
 if enable_session_selector
cf6cdf
   deps = [
cf6cdf
     glib_dep,
cf6cdf
-    gtk_dep
cf6cdf
+    gtk_dep,
cf6cdf
+    dbus_glib_dep
cf6cdf
   ]
cf6cdf
 
cf6cdf
   cflags += '-DGTKBUILDER_DIR="@0@"'.format(session_pkgdatadir)
cf6cdf
 
cf6cdf
   programs += [['gnome-session-selector', deps, cflags, session_bindir]]
cf6cdf
 endif
cf6cdf
 
cf6cdf
 deps = [
cf6cdf
   gtk_dep,
cf6cdf
   x11_dep,
cf6cdf
   dependency('egl'),
cf6cdf
   dependency('glesv2')
cf6cdf
 ]
cf6cdf
 
cf6cdf
 cflags = '-DPKGDATADIR="@0@"'.format(session_pkgdatadir)
cf6cdf
 
cf6cdf
 programs += [['gnome-session-check-accelerated-gles-helper', deps, cflags, session_libexecdir]]
cf6cdf
 
cf6cdf
 deps = [
cf6cdf
   glib_dep,
cf6cdf
   x11_dep,
cf6cdf
   dependency('gl'),
cf6cdf
   dependency('epoxy'),
cf6cdf
   dependency('xcomposite')
cf6cdf
 ]
cf6cdf
 
cf6cdf
 programs += [['gnome-session-check-accelerated-gl-helper', deps, cflags, session_libexecdir]]
cf6cdf
 
cf6cdf
 deps += [gtk_dep]
cf6cdf
 
cf6cdf
-- 
cf6cdf
2.17.0
cf6cdf