~ubuntu-branches/ubuntu/vivid/gnome-session/vivid

« back to all changes in this revision

Viewing changes to .pc/52_xdg_current_desktop.patch/gnome-session/gsm-session-fill.c

  • Committer: Package Import Robot
  • Author(s): Tim Lunn
  • Date: 2014-10-31 09:19:52 UTC
  • mfrom: (1.1.86) (245.1.1 vivid-proposed)
  • Revision ID: package-import@ubuntu.com-20141031091952-ci78rlfuztpd0y47
Tags: 3.14.0-2ubuntu1
* Merge from Debian, Remaining Changes:
  - debian/control.in: 
    + Recommend session-migration
    * don't depend on xwayland
  - debian/gnome-session.install: Don't install wayland session for now
    since its not yet possible to run it
  - Split ubuntu-session out of gnome-session.
  - Add upstart user session
  - debian/gnome-session-bin.postinst, debian/gnome-session-bin.prerm:
     Moved registering gnome-session binary as a session manager to 
     gnome-session-bin package
  - don't install defaults.list (installed by desktop-file-utils in ubuntu):
     debian/gnome-session-common.dirs and gnome-session-common.install
 - debian/patches/22_support_autostart_delay.patch:
    Bugzilla patch to support adding a delay to autostart apps, using
    a "X-GNOME-Autostart-Delay" key in the desktop file
 - debian/patches/50_ubuntu_sessions.patch:
    + Add Ubuntu session
    + gnome-shell.desktop adds --session=gnome now that the "ubuntu" session
      is the default. Use TryExec to test if gnome-shell is installed.
 - debian/patches/51_remove_session_saving_from_gui.patch:
    add GNOME_SESSION_SAVE environment variable for people wanting to
    use the save session still, knowing that it can break your system
    if used unwisely (LP: #771896)
 - debian/patches/52_xdg_current_desktop.patch:
    Set XDG_CURRENT_DESKTOP inside gnome-session based on a
    new key 'DesktopName' in gnome-session .desktop files.
 - debian/patches/53_add_sessionmigration.patch, debian/control:
    recommends and launch the session-migration if present at the start
    of the session. This sync tool is running different session migration
    scripts that can be provided in various desktop packages.
 - debian/patches/95_dbus_request_shutdown.patch:
    Add "RequestShutdown" and "RequestReboot" DBus methods to allow other
    applications to shutdown or reboot the machine via the session manager.
  - debian/patches/103_kill_the_fail_whale.patch:
    Kill the Fail Whale as it tends to be more annoying than helpful
* debian/patches/revert_remove_gnome_session_properties.patch
* Dropped Changes:
* debian/patches/52_xdg_current_desktop.patch: Dropped Upsream includes a
  fallback to set this now. 
* Remove patches that have been disabled since 3.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2
 
 *
3
 
 * Copyright (C) 2006, 2010 Novell, Inc.
4
 
 * Copyright (C) 2008 Red Hat, Inc.
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or
7
 
 * modify it under the terms of the GNU General Public License as
8
 
 * published by the Free Software Foundation; either version 2 of the
9
 
 * License, or (at your option) any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful, but
12
 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
 
 * Lesser General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19
 
 * 02111-1307, USA.
20
 
 */
21
 
 
22
 
#include <config.h>
23
 
 
24
 
#include "gsm-session-fill.h"
25
 
 
26
 
#include "gsm-system.h"
27
 
#include "gsm-manager.h"
28
 
#include "gsm-process-helper.h"
29
 
#include "gsm-util.h"
30
 
 
31
 
#define GSM_KEYFILE_SESSION_GROUP "GNOME Session"
32
 
#define GSM_KEYFILE_RUNNABLE_KEY "IsRunnableHelper"
33
 
#define GSM_KEYFILE_FALLBACK_KEY "FallbackSession"
34
 
#define GSM_KEYFILE_REQUIRED_COMPONENTS_KEY "RequiredComponents"
35
 
 
36
 
/* See https://bugzilla.gnome.org/show_bug.cgi?id=641992 for discussion */
37
 
#define GSM_RUNNABLE_HELPER_TIMEOUT 3000 /* ms */
38
 
 
39
 
typedef void (*GsmFillHandleComponent) (const char *component,
40
 
                                        const char *app_path,
41
 
                                        gpointer    user_data);
42
 
 
43
 
static void
44
 
handle_required_components (GKeyFile               *keyfile,
45
 
                            gboolean                look_in_saved_session,
46
 
                            GsmFillHandleComponent  callback,
47
 
                            gpointer                user_data)
48
 
{
49
 
        char **required_components;
50
 
        int    i;
51
 
 
52
 
        g_assert (keyfile != NULL);
53
 
        g_assert (callback != NULL);
54
 
 
55
 
        required_components = g_key_file_get_string_list (keyfile,
56
 
                                                          GSM_KEYFILE_SESSION_GROUP,
57
 
                                                          GSM_KEYFILE_REQUIRED_COMPONENTS_KEY,
58
 
                                                          NULL, NULL);
59
 
 
60
 
        if (!required_components)
61
 
                return;
62
 
 
63
 
        for (i = 0; required_components[i] != NULL; i++) {
64
 
                char *app_path;
65
 
 
66
 
                app_path = gsm_util_find_desktop_file_for_app_name (required_components[i],
67
 
                                                                    look_in_saved_session, TRUE);
68
 
                callback (required_components[i], app_path, user_data);
69
 
                g_free (app_path);
70
 
        }
71
 
 
72
 
        g_strfreev (required_components);
73
 
}
74
 
 
75
 
static void
76
 
check_required_components_helper (const char *component,
77
 
                                  const char *app_path,
78
 
                                  gpointer    user_data)
79
 
{
80
 
        gboolean *error = user_data;
81
 
 
82
 
        if (app_path == NULL) {
83
 
                g_warning ("Unable to find required component '%s'", component);
84
 
                *error = TRUE;
85
 
        }
86
 
}
87
 
 
88
 
static gboolean
89
 
check_required (GKeyFile *keyfile)
90
 
{
91
 
        gboolean error = FALSE;
92
 
 
93
 
        g_debug ("fill: *** Checking required components");
94
 
 
95
 
        handle_required_components (keyfile, FALSE,
96
 
                                    check_required_components_helper, &error);
97
 
 
98
 
        g_debug ("fill: *** Done checking required components");
99
 
 
100
 
        return !error;
101
 
}
102
 
 
103
 
static void
104
 
maybe_load_saved_session_apps (GsmManager *manager)
105
 
{
106
 
        GsmSystem *system;
107
 
        gboolean is_login;
108
 
 
109
 
        system = gsm_get_system ();
110
 
        is_login = gsm_system_is_login_session (system);
111
 
        g_object_unref (system);
112
 
 
113
 
        if (is_login)
114
 
                return;
115
 
 
116
 
        gsm_manager_add_autostart_apps_from_dir (manager, gsm_util_get_saved_session_dir ());
117
 
}
118
 
 
119
 
static void
120
 
append_required_components_helper (const char *component,
121
 
                                   const char *app_path,
122
 
                                   gpointer    user_data)
123
 
{
124
 
        GsmManager *manager = user_data;
125
 
 
126
 
        if (app_path == NULL)
127
 
                g_warning ("Unable to find required component '%s'", component);
128
 
        else
129
 
                gsm_manager_add_required_app (manager, app_path, NULL);
130
 
}
131
 
 
132
 
 
133
 
static void
134
 
load_standard_apps (GsmManager *manager,
135
 
                    GKeyFile   *keyfile)
136
 
{
137
 
        g_debug ("fill: *** Adding required components");
138
 
        handle_required_components (keyfile, !gsm_manager_get_failsafe (manager),
139
 
                                    append_required_components_helper, manager);
140
 
        g_debug ("fill: *** Done adding required components");
141
 
 
142
 
        if (!gsm_manager_get_failsafe (manager)) {
143
 
                char **autostart_dirs;
144
 
                int    i;
145
 
 
146
 
                autostart_dirs = gsm_util_get_autostart_dirs ();
147
 
 
148
 
                if (g_getenv ("GNOME_SESSION_SAVE") != NULL)
149
 
                        maybe_load_saved_session_apps (manager);
150
 
 
151
 
                for (i = 0; autostart_dirs[i]; i++) {
152
 
                        gsm_manager_add_autostart_apps_from_dir (manager,
153
 
                                                                 autostart_dirs[i]);
154
 
                }
155
 
 
156
 
                g_strfreev (autostart_dirs);
157
 
        }
158
 
}
159
 
 
160
 
static GKeyFile *
161
 
get_session_keyfile_if_valid (const char *path)
162
 
{
163
 
        GKeyFile  *keyfile;
164
 
        gsize      len;
165
 
        char     **list;
166
 
 
167
 
        g_debug ("fill: *** Looking if %s is a valid session file", path);
168
 
 
169
 
        keyfile = g_key_file_new ();
170
 
 
171
 
        if (!g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, NULL)) {
172
 
                g_debug ("Cannot use session '%s': non-existing or invalid file.", path);
173
 
                goto error;
174
 
        }
175
 
 
176
 
        if (!g_key_file_has_group (keyfile, GSM_KEYFILE_SESSION_GROUP)) {
177
 
                g_warning ("Cannot use session '%s': no '%s' group.", path, GSM_KEYFILE_SESSION_GROUP);
178
 
                goto error;
179
 
        }
180
 
 
181
 
        /* check that we do have some required components */
182
 
        if (len == 0) {
183
 
                list = g_key_file_get_string_list (keyfile,
184
 
                                                   GSM_KEYFILE_SESSION_GROUP,
185
 
                                                   GSM_KEYFILE_REQUIRED_COMPONENTS_KEY,
186
 
                                                   &len, NULL);
187
 
                if (list)
188
 
                        g_strfreev (list);
189
 
                if (len == 0)
190
 
                        g_warning ("Session '%s': no component in the session.", path);
191
 
        }
192
 
 
193
 
        return keyfile;
194
 
 
195
 
error:
196
 
        g_key_file_free (keyfile);
197
 
        return NULL;
198
 
}
199
 
 
200
 
/**
201
 
 * find_valid_session_keyfile:
202
 
 * @session: name of session
203
 
 *
204
 
 * We look for the session file in XDG_CONFIG_HOME, XDG_CONFIG_DIRS and
205
 
 * XDG_DATA_DIRS. This enables users and sysadmins to override a specific
206
 
 * session that is shipped in XDG_DATA_DIRS.
207
 
 */
208
 
static GKeyFile *
209
 
find_valid_session_keyfile (const char *session)
210
 
{
211
 
        GPtrArray          *dirs;
212
 
        const char * const *system_config_dirs;
213
 
        const char * const *system_data_dirs;
214
 
        int                 i;
215
 
        GKeyFile           *keyfile;
216
 
        char               *basename;
217
 
        char               *path;
218
 
 
219
 
        dirs = g_ptr_array_new ();
220
 
 
221
 
        g_ptr_array_add (dirs, (gpointer) g_get_user_config_dir ());
222
 
 
223
 
        system_config_dirs = g_get_system_config_dirs ();
224
 
        for (i = 0; system_config_dirs[i]; i++)
225
 
                g_ptr_array_add (dirs, (gpointer) system_config_dirs[i]);
226
 
 
227
 
        system_data_dirs = g_get_system_data_dirs ();
228
 
        for (i = 0; system_data_dirs[i]; i++)
229
 
                g_ptr_array_add (dirs, (gpointer) system_data_dirs[i]);
230
 
 
231
 
        keyfile = NULL;
232
 
        basename = g_strdup_printf ("%s.session", session);
233
 
        path = NULL;
234
 
 
235
 
        for (i = 0; i < dirs->len; i++) {
236
 
                path = g_build_filename (dirs->pdata[i], "gnome-session", "sessions", basename, NULL);
237
 
                keyfile = get_session_keyfile_if_valid (path);
238
 
                if (keyfile != NULL)
239
 
                        break;
240
 
        }
241
 
 
242
 
        if (dirs)
243
 
                g_ptr_array_free (dirs, TRUE);
244
 
        if (basename)
245
 
                g_free (basename);
246
 
        if (path)
247
 
                g_free (path);
248
 
 
249
 
        return keyfile;
250
 
}
251
 
 
252
 
static GKeyFile *
253
 
get_session_keyfile (const char *session,
254
 
                     char      **actual_session,
255
 
                     gboolean   *is_fallback)
256
 
{
257
 
        GKeyFile *keyfile;
258
 
        gboolean  session_runnable;
259
 
        char     *value;
260
 
        GError *error = NULL;
261
 
 
262
 
        *actual_session = NULL;
263
 
 
264
 
        g_debug ("fill: *** Getting session '%s'", session);
265
 
 
266
 
        keyfile = find_valid_session_keyfile (session);
267
 
 
268
 
        if (!keyfile)
269
 
                return NULL;
270
 
 
271
 
        session_runnable = TRUE;
272
 
 
273
 
        value = g_key_file_get_string (keyfile,
274
 
                                       GSM_KEYFILE_SESSION_GROUP, GSM_KEYFILE_RUNNABLE_KEY,
275
 
                                       NULL);
276
 
        if (!IS_STRING_EMPTY (value)) {
277
 
                g_debug ("fill: *** Launching helper '%s' to know if session is runnable", value);
278
 
                session_runnable = gsm_process_helper (value, GSM_RUNNABLE_HELPER_TIMEOUT, &error);
279
 
                if (!session_runnable) {
280
 
                        g_warning ("Session '%s' runnable check failed: %s", session,
281
 
                                   error->message);
282
 
                        g_clear_error (&error);
283
 
                }
284
 
        }
285
 
        g_free (value);
286
 
 
287
 
        if (session_runnable) {
288
 
                session_runnable = check_required (keyfile);
289
 
        }
290
 
 
291
 
        if (session_runnable) {
292
 
                *actual_session = g_strdup (session);
293
 
                if (is_fallback)
294
 
                        *is_fallback = FALSE;
295
 
                return keyfile;
296
 
        }
297
 
 
298
 
        g_debug ("fill: *** Session is not runnable");
299
 
 
300
 
        /* We can't run this session, so try to use the fallback */
301
 
        value = g_key_file_get_string (keyfile,
302
 
                                       GSM_KEYFILE_SESSION_GROUP, GSM_KEYFILE_FALLBACK_KEY,
303
 
                                       NULL);
304
 
 
305
 
        g_key_file_free (keyfile);
306
 
        keyfile = NULL;
307
 
 
308
 
        if (!IS_STRING_EMPTY (value)) {
309
 
                if (is_fallback)
310
 
                        *is_fallback = TRUE;
311
 
                keyfile = get_session_keyfile (value, actual_session, NULL);
312
 
        }
313
 
        g_free (value);
314
 
 
315
 
        return keyfile;
316
 
}
317
 
 
318
 
gboolean
319
 
gsm_session_fill (GsmManager  *manager,
320
 
                  const char  *session)
321
 
{
322
 
        GKeyFile *keyfile;
323
 
        gboolean is_fallback;
324
 
        char *actual_session;
325
 
 
326
 
        keyfile = get_session_keyfile (session, &actual_session, &is_fallback);
327
 
 
328
 
        if (!keyfile)
329
 
                return FALSE;
330
 
 
331
 
        _gsm_manager_set_active_session (manager, actual_session, is_fallback);
332
 
 
333
 
        g_free (actual_session);
334
 
 
335
 
        load_standard_apps (manager, keyfile);
336
 
 
337
 
        g_key_file_free (keyfile);
338
 
 
339
 
        return TRUE;
340
 
}