~ubuntu-branches/ubuntu/oneiric/gnome-panel/oneiric

« back to all changes in this revision

Viewing changes to gnome-panel/panel-layout.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher, Sebastien Bacher, Jeremy Bicha
  • Date: 2011-05-30 11:04:49 UTC
  • mfrom: (1.13.10 upstream) (2.2.5 experimental)
  • Revision ID: james.westby@ubuntu.com-20110530110449-hinl17kxkcefjw6x
Tags: 1:3.0.2-0ubuntu1
[ Sebastien Bacher ]
* New upstream version
* debian/control.in:
  - the new libgweather version is in oneiric, use it
  - drop the python and python-gconf depends, 
    they were added for gnome-panel-add which is still using gconf and buggy
* debian/gnome-panel-data.install:
  - don't install the apport hook, it's only getting gconf datas which 
    doesn't work since gnome-panel uses gsettings
* debian/patches/90_build_fixes.patch:
  - restore build fix from git not applied in the new serie
* debian/patches/01_panel_submenus.patch:
  - don't take that Debian diff, the .menus use the upstream naming in Ubuntu
* debian/patches/06_no_resize_grip.patch:
  - dropped, the issue is fixed in the new version
* debian/patches/50_fix-potfiles.patch:
  - dropped, the issue is fixed in the new version
* debian/watch:
  - track unstable series as well

Drop those delta, since gnome-panel is not the default Ubuntu session now we
can go back to an experience closer to the upstream one: 
* debian/control.in:
  - drop the indicators recommends, unity-2d is the ubuntu fallback session
    so we can get back to use an upstream config for gnome-panel and reduce
    the delta we carry
* debian/patches/04_default_panel_config.patch:
  - don't modify the upstream layout
* debian/patches/05_no_session_delay.patch:
  - no need to tweak the upstream session to optimize it
* debian/patches/16_compiz_workspace_switcher.patch:
  - go back to the upstream switcher behaviour    
* debian/patches/25_dynamic_fusa_detection.patch:
  - not needed since we use the upstream layout, could be ported if someone
    is wanting to do the work though
* debian/patches/30_disable-initial-animation.patch, debian/rules:
  - drop the --disable-initial-animation, that was some login optimization
    but since it's not the default desktop you should go back to the 
    upstream behaviour

[ Jeremy Bicha ]   
* New upstream version
* Merge from Debian experimental, remaining Ubuntu changes:
* debian/control:
  - Recommends gnome-settings-daemon which has the timezone polkit service
* debian/rules:
  - Update translations template.
* debian/gnome-panel-data.install:
  - Install apport hook
  - Install the "About Ubuntu" menu item.
* debian/patches/01_layout.patch:
  - Disabled, Help & About Ubuntu don't fit as well in Gnome Panel 3
* debian/patches/01_panel_submenus.patch.
  - Dropped
* debian/patches/03_dnd_places_link.patch:
  - Disabled, when using Drag'n'Drop from Places menu, install a link launcher
    (.desktop file) instead of copying the entire directory.
* debian/patches/17_about-ubuntu-translation.patch:
  - List ubuntu-about.desktop for translation.
* debian/patches/40_unset_menuproxy.patch:
  - Make sure gnome-panel and the applets don't pick up menu proxies.
* debian/patches/50_fix-potfiles.patch
  - Fix i18n
* debian/patches/85_disable_shutdown_on_ltsp.patch:
  - Suppress the shutdown option in the panel if LTSP_CLIENT is set.
* debian/patches/71_change_bookmark_submenu_limit_value.patch
  - Dropped, picked up by Debian
* debian/patches/18_lockdown_lock_editor.patch:
* debian/patches/90_git_wnck_show_realize.patch:
* debian/patches/90_fix_linking_DSO_link.patch:
* debian/patches/91_gir_annotations.patch
* debian/patches/92_git_calendar_day.patch
* debian/patches/92_git_fix_applets_in_multiscreen.patch:
  - Dropped, applied upstream
* debian/watch:
  - watch unstable versions

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * panel-layout.c:
 
3
 * vim: set et:
 
4
 *
 
5
 * Copyright (C) 2011 Novell, Inc.
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU General Public License as
 
9
 * published by the Free Software Foundation; either version 2 of the
 
10
 * License, or (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful, but
 
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
20
 * 02111-1307, USA.
 
21
 *
 
22
 * Authors:
 
23
 *      Vincent Untz <vuntz@gnome.org>
 
24
 */
 
25
 
 
26
 
 
27
#include <string.h>
 
28
 
 
29
#include <glib/gi18n.h>
 
30
#include <gio/gio.h>
 
31
#include <gdk/gdk.h>
 
32
 
 
33
#include <libpanel-util/panel-cleanup.h>
 
34
#include <libpanel-util/panel-dconf.h>
 
35
#include <libpanel-util/panel-glib.h>
 
36
#include <libpanel-util/panel-gsettings.h>
 
37
 
 
38
#include "panel.h"
 
39
#include "panel-gconf.h"
 
40
#include "panel-multiscreen.h"
 
41
#include "panel-object-loader.h"
 
42
#include "panel-schemas.h"
 
43
#include "panel-toplevel.h"
 
44
 
 
45
#include "panel-layout.h"
 
46
 
 
47
static GSettings *layout_settings = NULL;
 
48
 
 
49
#define PANEL_LAYOUT_ERROR panel_layout_error_quark ()
 
50
#define PANEL_LAYOUT_OBJECT_GCONF_PATH_TEMPLATE "/apps/panel3-applets/%s"
 
51
 
 
52
static void panel_layout_load_toplevel    (const char *toplevel_id);
 
53
static void panel_layout_load_object      (const char *object_id);
 
54
static void panel_layout_changed_toplevel (void);
 
55
static void panel_layout_changed_object   (void);
 
56
 
 
57
static GQuark
 
58
panel_layout_error_quark (void)
 
59
{
 
60
        static GQuark ret = 0;
 
61
 
 
62
        if (ret == 0)
 
63
                ret = g_quark_from_static_string ("panel_layout_error");
 
64
 
 
65
        return ret;
 
66
}
 
67
 
 
68
static void
 
69
panel_layout_init (void)
 
70
{
 
71
        if (layout_settings == NULL) {
 
72
                layout_settings = g_settings_new (PANEL_LAYOUT_SCHEMA);
 
73
                panel_cleanup_register (panel_cleanup_unref_and_nullify,
 
74
                                        &layout_settings);
 
75
        }
 
76
}
 
77
 
 
78
 
 
79
/************************************\
 
80
 * Adding to the layout from a file *
 
81
\************************************/
 
82
 
 
83
 
 
84
typedef struct {
 
85
        const char *name;
 
86
        GType       type;
 
87
} PanelLayoutKeyDefinition;
 
88
 
 
89
static PanelLayoutKeyDefinition panel_layout_toplevel_keys[] = {
 
90
        { PANEL_TOPLEVEL_NAME_KEY,            G_TYPE_STRING   },
 
91
        { PANEL_TOPLEVEL_SCREEN_KEY,          G_TYPE_INT      },
 
92
        { PANEL_TOPLEVEL_MONITOR_KEY,         G_TYPE_INT      },
 
93
        { PANEL_TOPLEVEL_EXPAND_KEY,          G_TYPE_BOOLEAN  },
 
94
        { PANEL_TOPLEVEL_ORIENTATION_KEY,     G_TYPE_STRING   },
 
95
        { PANEL_TOPLEVEL_SIZE_KEY,            G_TYPE_INT      },
 
96
        { PANEL_TOPLEVEL_X_KEY,               G_TYPE_INT      },
 
97
        { PANEL_TOPLEVEL_Y_KEY,               G_TYPE_INT      },
 
98
        { PANEL_TOPLEVEL_X_RIGHT_KEY,         G_TYPE_INT      },
 
99
        { PANEL_TOPLEVEL_Y_BOTTOM_KEY,        G_TYPE_INT      },
 
100
        { PANEL_TOPLEVEL_X_CENTERED_KEY,      G_TYPE_BOOLEAN  },
 
101
        { PANEL_TOPLEVEL_Y_CENTERED_KEY,      G_TYPE_BOOLEAN  },
 
102
        { PANEL_TOPLEVEL_AUTO_HIDE_KEY,       G_TYPE_BOOLEAN  },
 
103
        { PANEL_TOPLEVEL_ENABLE_BUTTONS_KEY,  G_TYPE_BOOLEAN  },
 
104
        { PANEL_TOPLEVEL_ENABLE_ARROWS_KEY,   G_TYPE_BOOLEAN  },
 
105
        { PANEL_TOPLEVEL_HIDE_DELAY_KEY,      G_TYPE_INT      },
 
106
        { PANEL_TOPLEVEL_UNHIDE_DELAY_KEY,    G_TYPE_INT      },
 
107
        { PANEL_TOPLEVEL_AUTO_HIDE_SIZE_KEY,  G_TYPE_INT      },
 
108
        { PANEL_TOPLEVEL_ANIMATION_SPEED_KEY, G_TYPE_STRING   }
 
109
};
 
110
 
 
111
static PanelLayoutKeyDefinition panel_layout_object_keys[] = {
 
112
        { PANEL_OBJECT_IID_KEY,         G_TYPE_STRING   },
 
113
        { PANEL_OBJECT_TOPLEVEL_ID_KEY, G_TYPE_STRING   },
 
114
        { PANEL_OBJECT_PACK_TYPE_KEY,   G_TYPE_STRING   },
 
115
        { PANEL_OBJECT_PACK_INDEX_KEY,  G_TYPE_INT      }
 
116
};
 
117
 
 
118
static gboolean
 
119
panel_layout_append_self_check (GSettings                 *settings,
 
120
                                PanelLayoutKeyDefinition  *key_definitions,
 
121
                                int                        key_definitions_len,
 
122
                                GError                   **error)
 
123
{
 
124
        char **settings_keys = NULL;
 
125
        int    i, j;
 
126
 
 
127
        /* Don't do those checks twice; we use a static array with a boolean
 
128
         * for each set of key definitions we might want to check, and mark the
 
129
         * booleans to TRUE once we've entered this function once for a set. */
 
130
        static gboolean self_check_done[2] = {FALSE, FALSE};
 
131
 
 
132
        g_assert (key_definitions == panel_layout_toplevel_keys ||
 
133
                  key_definitions == panel_layout_object_keys);
 
134
 
 
135
        if (key_definitions == panel_layout_toplevel_keys) {
 
136
            if (self_check_done[0])
 
137
                    return TRUE;
 
138
            else
 
139
                    self_check_done[0] = TRUE;
 
140
        }
 
141
        if (key_definitions == panel_layout_object_keys) {
 
142
            if (self_check_done[1])
 
143
                    return TRUE;
 
144
            else
 
145
                    self_check_done[1] = TRUE;
 
146
        }
 
147
        /* End hacky way of avoiding double-checks */
 
148
 
 
149
        g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
150
 
 
151
        settings_keys = g_settings_list_keys (settings);
 
152
 
 
153
        for (i = 0; settings_keys[i] != NULL; i++) {
 
154
                gboolean found = FALSE;
 
155
 
 
156
                for (j = 0; j < key_definitions_len; j++) {
 
157
                        if (g_strcmp0 (settings_keys[i],
 
158
                                       key_definitions[j].name) == 0) {
 
159
                                found = TRUE;
 
160
                                break;
 
161
                        }
 
162
                }
 
163
 
 
164
                if (!found) {
 
165
                        g_set_error (error, PANEL_LAYOUT_ERROR, 0,
 
166
                                     "Mismatch between keys defined in schema and keys known to gnome-panel ('%s' is not known)",
 
167
                                     settings_keys[i]);
 
168
                        g_strfreev (settings_keys);
 
169
                        return FALSE;
 
170
                }
 
171
        }
 
172
 
 
173
        g_strfreev (settings_keys);
 
174
 
 
175
        if (i != key_definitions_len) {
 
176
                g_set_error (error, PANEL_LAYOUT_ERROR, 0,
 
177
                             "Mismatch between keys defined in schema and keys known to gnome-panel (%d keys in schema, %d keys known to gnome-panel)",
 
178
                             i, j);
 
179
                return FALSE;
 
180
        }
 
181
 
 
182
        return TRUE;
 
183
}
 
184
 
 
185
static char *
 
186
panel_layout_find_free_id (const char *id_list_key,
 
187
                           const char *schema,
 
188
                           const char *path_prefix,
 
189
                           const char *try_id,
 
190
                           int         screen_for_toplevels)
 
191
{
 
192
        char      *unique_id;
 
193
        char     **existing_ids;
 
194
        char     **existing_dirs;
 
195
        gboolean   existing;
 
196
        int        index;
 
197
        int        i;
 
198
 
 
199
        existing_ids = g_settings_get_strv (layout_settings,
 
200
                                            id_list_key);
 
201
        existing_dirs = panel_dconf_list_subdirs (path_prefix, TRUE);
 
202
 
 
203
        index = 0;
 
204
        existing = TRUE;
 
205
 
 
206
        /* If a specific id is specified, try to use it; it might be
 
207
         * free */
 
208
        if (try_id) {
 
209
                if (screen_for_toplevels != -1 &&
 
210
                    g_strcmp0 (schema, PANEL_TOPLEVEL_SCHEMA) == 0)
 
211
                        unique_id = g_strdup_printf ("%s-screen%d",
 
212
                                                     try_id,
 
213
                                                     screen_for_toplevels);
 
214
                else
 
215
                        unique_id = g_strdup (try_id);
 
216
 
 
217
                existing = FALSE;
 
218
 
 
219
                for (i = 0; !existing && existing_ids[i] != NULL; i++) {
 
220
                        if (g_strcmp0 (unique_id,
 
221
                                       existing_ids[i]) == 0)
 
222
                                existing = TRUE;
 
223
                }
 
224
                for (i = 0; !existing && existing_dirs[i] != NULL; i++) {
 
225
                        if (g_strcmp0 (unique_id,
 
226
                                       existing_dirs[i]) == 0)
 
227
                                existing = TRUE;
 
228
                                break;
 
229
                }
 
230
 
 
231
                if (existing)
 
232
                        g_free (unique_id);
 
233
 
 
234
        } else {
 
235
                if (g_strcmp0 (schema, PANEL_TOPLEVEL_SCHEMA) == 0)
 
236
                        try_id = "toplevel";
 
237
                else if (g_strcmp0 (schema, PANEL_OBJECT_SCHEMA) == 0)
 
238
                        try_id = "object";
 
239
                else
 
240
                        g_assert_not_reached ();
 
241
        }
 
242
 
 
243
        /* Append an index at the end of the id to find a unique
 
244
         * id, not used yet */
 
245
        while (existing) {
 
246
                if (screen_for_toplevels != -1 &&
 
247
                    g_strcmp0 (schema, PANEL_TOPLEVEL_SCHEMA) == 0)
 
248
                        unique_id = g_strdup_printf ("%s-screen%d-%d",
 
249
                                                     try_id,
 
250
                                                     screen_for_toplevels,
 
251
                                                     index);
 
252
                else
 
253
                        unique_id = g_strdup_printf ("%s-%d", try_id, index);
 
254
 
 
255
                existing = FALSE;
 
256
 
 
257
                for (i = 0; !existing && existing_ids[i] != NULL; i++) {
 
258
                        if (g_strcmp0 (unique_id,
 
259
                                       existing_ids[i]) == 0)
 
260
                                existing = TRUE;
 
261
                }
 
262
                for (i = 0; !existing && existing_dirs[i] != NULL; i++) {
 
263
                        if (g_strcmp0 (unique_id,
 
264
                                       existing_dirs[i]) == 0)
 
265
                                existing = TRUE;
 
266
                }
 
267
 
 
268
                if (existing)
 
269
                        g_free (unique_id);
 
270
                index++;
 
271
        }
 
272
 
 
273
        g_strfreev (existing_dirs);
 
274
        g_strfreev (existing_ids);
 
275
 
 
276
        return unique_id;
 
277
}
 
278
 
 
279
static gboolean
 
280
panel_layout_append_group_helper (GKeyFile                  *keyfile,
 
281
                                  const char                *group,
 
282
                                  int                        set_screen_to,
 
283
                                  const char                *group_prefix,
 
284
                                  const char                *id_list_key,
 
285
                                  const char                *schema,
 
286
                                  const char                *path_prefix,
 
287
                                  const char                *default_prefix,
 
288
                                  PanelLayoutKeyDefinition  *key_definitions,
 
289
                                  int                        key_definitions_len,
 
290
                                  gboolean                   dry_run,
 
291
                                  GError                   **error,
 
292
                                  const char                *type_for_error_message)
 
293
{
 
294
        gboolean    retval = FALSE;
 
295
        const char *id;
 
296
        char       *unique_id = NULL;
 
297
        char       *path = NULL;
 
298
        GSettings  *settings = NULL;
 
299
        char      **keyfile_keys = NULL;
 
300
        char       *value_str;
 
301
        int         value_int;
 
302
        gboolean    value_boolean;
 
303
        int         i, j;
 
304
 
 
305
        g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
306
 
 
307
        /* Try to extract an id from the group, by stripping the prefix,
 
308
         * and create a unique id out of that */
 
309
        id = group + strlen (group_prefix);
 
310
        while (g_ascii_isspace (*id))
 
311
                id++;
 
312
 
 
313
        if (!*id)
 
314
                id = NULL;
 
315
 
 
316
        if (id && !panel_gsettings_is_valid_keyname (id, error))
 
317
                return FALSE;
 
318
 
 
319
        unique_id = panel_layout_find_free_id (id_list_key, schema, path_prefix,
 
320
                                               id, set_screen_to);
 
321
 
 
322
        path = g_strdup_printf ("%s%s/", path_prefix, unique_id);
 
323
        settings = g_settings_new_with_path (schema, path);
 
324
        g_free (path);
 
325
 
 
326
        /* Check that what the code knows matches what the schemas say */
 
327
        if (!panel_layout_append_self_check (settings,
 
328
                                             key_definitions,
 
329
                                             key_definitions_len,
 
330
                                             error))
 
331
                goto out;
 
332
 
 
333
        keyfile_keys = g_key_file_get_keys (keyfile, group, NULL, error);
 
334
 
 
335
        if (!keyfile_keys)
 
336
                goto out;
 
337
 
 
338
        /* Now do the real work: we validate/add keys from the keyfile */
 
339
        for (i = 0; keyfile_keys[i] != NULL; i++) {
 
340
                gboolean found = FALSE;
 
341
 
 
342
                for (j = 0; j < key_definitions_len; j++) {
 
343
                        if (g_strcmp0 (keyfile_keys[i],
 
344
                                       key_definitions[j].name) == 0) {
 
345
                                found = TRUE;
 
346
                                break;
 
347
                        }
 
348
                }
 
349
 
 
350
                if (!found) {
 
351
                        g_set_error (error, PANEL_LAYOUT_ERROR, 0,
 
352
                                     "Unknown key '%s' for %s",
 
353
                                     keyfile_keys[i],
 
354
                                     type_for_error_message);
 
355
                        return FALSE;
 
356
                }
 
357
 
 
358
                switch (key_definitions[j].type) {
 
359
                        case G_TYPE_STRING:
 
360
                                value_str = g_key_file_get_string (
 
361
                                                        keyfile,
 
362
                                                        group, keyfile_keys[i],
 
363
                                                        error);
 
364
                                if (!value_str)
 
365
                                        goto out;
 
366
 
 
367
                                if (!dry_run)
 
368
                                        g_settings_set_string (settings,
 
369
                                                               key_definitions[j].name,
 
370
                                                               value_str);
 
371
                                g_free (value_str);
 
372
                                break;
 
373
 
 
374
                        case G_TYPE_INT:
 
375
                                value_int = g_key_file_get_integer (
 
376
                                                        keyfile,
 
377
                                                        group, keyfile_keys[i],
 
378
                                                        error);
 
379
                                if (error && *error)
 
380
                                        goto out;
 
381
 
 
382
                                if (!dry_run)
 
383
                                        g_settings_set_int (settings,
 
384
                                                            key_definitions[j].name,
 
385
                                                            value_int);
 
386
                                break;
 
387
 
 
388
                        case G_TYPE_BOOLEAN:
 
389
                                value_boolean = g_key_file_get_boolean (
 
390
                                                        keyfile,
 
391
                                                        group, keyfile_keys[i],
 
392
                                                        error);
 
393
                                if (error && *error)
 
394
                                        goto out;
 
395
 
 
396
                                if (!dry_run)
 
397
                                        g_settings_set_boolean (settings,
 
398
                                                                key_definitions[j].name,
 
399
                                                                value_boolean);
 
400
                                break;
 
401
                        default:
 
402
                                g_assert_not_reached ();
 
403
                                break;
 
404
                }
 
405
        }
 
406
 
 
407
        if (!dry_run) {
 
408
                if (set_screen_to != -1 &&
 
409
                    g_strcmp0 (schema, PANEL_TOPLEVEL_SCHEMA) == 0)
 
410
                        g_settings_set_int (settings,
 
411
                                            PANEL_TOPLEVEL_SCREEN_KEY,
 
412
                                            set_screen_to);
 
413
 
 
414
                panel_gsettings_append_strv (layout_settings,
 
415
                                             id_list_key,
 
416
                                             unique_id);
 
417
        }
 
418
 
 
419
        retval = TRUE;
 
420
 
 
421
out:
 
422
        if (keyfile_keys)
 
423
                g_strfreev (keyfile_keys);
 
424
        if (settings)
 
425
                g_object_unref (settings);
 
426
        if (unique_id)
 
427
                g_free (unique_id);
 
428
 
 
429
        return retval;
 
430
}
 
431
 
 
432
static gboolean
 
433
panel_layout_append_group (GKeyFile    *keyfile,
 
434
                           const char  *group,
 
435
                           int          screen_for_toplevels,
 
436
                           gboolean     dry_run,
 
437
                           GError     **error)
 
438
{
 
439
        g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
440
 
 
441
        if (g_strcmp0 (group, "Toplevel") == 0 ||
 
442
            g_str_has_prefix (group, "Toplevel "))
 
443
                return panel_layout_append_group_helper (
 
444
                                        keyfile, group,
 
445
                                        screen_for_toplevels,
 
446
                                        "Toplevel",
 
447
                                        PANEL_LAYOUT_TOPLEVEL_ID_LIST_KEY,
 
448
                                        PANEL_TOPLEVEL_SCHEMA,
 
449
                                        PANEL_LAYOUT_TOPLEVEL_PATH,
 
450
                                        PANEL_LAYOUT_TOPLEVEL_DEFAULT_PREFIX,
 
451
                                        panel_layout_toplevel_keys,
 
452
                                        G_N_ELEMENTS (panel_layout_toplevel_keys),
 
453
                                        dry_run, error, "toplevel");
 
454
        else if (g_strcmp0 (group, "Object") == 0 ||
 
455
                 g_str_has_prefix (group, "Object "))
 
456
                return panel_layout_append_group_helper (
 
457
                                        keyfile, group,
 
458
                                        -1,
 
459
                                        "Object",
 
460
                                        PANEL_LAYOUT_OBJECT_ID_LIST_KEY,
 
461
                                        PANEL_OBJECT_SCHEMA,
 
462
                                        PANEL_LAYOUT_OBJECT_PATH,
 
463
                                        PANEL_LAYOUT_OBJECT_DEFAULT_PREFIX,
 
464
                                        panel_layout_object_keys,
 
465
                                        G_N_ELEMENTS (panel_layout_object_keys),
 
466
                                        dry_run, error, "object");
 
467
 
 
468
        g_set_error (error, PANEL_LAYOUT_ERROR, 0,
 
469
                     "Unknown group '%s'", group);
 
470
 
 
471
        return FALSE;
 
472
}
 
473
 
 
474
static void
 
475
panel_layout_append_from_file_real (const char *layout_file,
 
476
                                    int         screen_for_toplevels,
 
477
                                    gboolean    error_fatal)
 
478
{
 
479
        GError    *error = NULL;
 
480
        GKeyFile  *keyfile = NULL;
 
481
        char     **groups = NULL;
 
482
        gboolean   found_one = FALSE;
 
483
        int        i;
 
484
 
 
485
        panel_layout_init ();
 
486
 
 
487
        keyfile = g_key_file_new ();
 
488
 
 
489
        error = NULL;
 
490
        if (!g_key_file_load_from_file (keyfile, layout_file,
 
491
                                        G_KEY_FILE_NONE, &error))
 
492
                goto out;
 
493
 
 
494
        groups = g_key_file_get_groups (keyfile, NULL);
 
495
 
 
496
        /* First pass to validate: we don't want to add only a subset of the
 
497
         * layout; the whole layout has to be valid */
 
498
        for (i = 0; groups[i] != NULL; i++) {
 
499
                if (!panel_layout_append_group (keyfile, groups[i],
 
500
                                                screen_for_toplevels,
 
501
                                                TRUE, &error))
 
502
                        goto out;
 
503
                else
 
504
                        found_one = TRUE;
 
505
        }
 
506
 
 
507
        if (!found_one) {
 
508
                error = g_error_new (PANEL_LAYOUT_ERROR, 0,
 
509
                                     "No defined toplevel or object");
 
510
                goto out;
 
511
        }
 
512
 
 
513
        /* Second pass to really add the layout. We know there'll be no error
 
514
         * since the first pass worked. */
 
515
        for (i = 0; groups[i] != NULL; i++)
 
516
                panel_layout_append_group (keyfile, groups[i],
 
517
                                           screen_for_toplevels,
 
518
                                           FALSE, NULL);
 
519
 
 
520
out:
 
521
        if (error) {
 
522
                g_printerr ("Error while parsing default layout from '%s': %s\n",
 
523
                            layout_file, error->message);
 
524
                g_error_free (error);
 
525
 
 
526
                if (error_fatal)
 
527
                        g_assert_not_reached ();
 
528
        }
 
529
 
 
530
        if (groups)
 
531
                g_strfreev (groups);
 
532
 
 
533
        if (keyfile)
 
534
                g_key_file_free (keyfile);
 
535
}
 
536
 
 
537
static void
 
538
panel_layout_append_from_file_for_screen (const char *layout_file,
 
539
                                          GdkScreen  *screen)
 
540
{
 
541
        int screen_n = gdk_screen_get_number (screen);
 
542
 
 
543
        panel_layout_append_from_file_real (layout_file, screen_n, FALSE);
 
544
}
 
545
 
 
546
void
 
547
panel_layout_append_from_file (const char *layout_file,
 
548
                               gboolean    error_fatal)
 
549
{
 
550
        panel_layout_append_from_file_real (layout_file, -1, error_fatal);
 
551
}
 
552
 
 
553
 
 
554
/***********************\
 
555
 * New toplevel/object *
 
556
\***********************/
 
557
 
 
558
 
 
559
void
 
560
panel_layout_toplevel_create (GdkScreen *screen)
 
561
{
 
562
        char             *unique_id;
 
563
        char             *path;
 
564
        GSettings        *settings;
 
565
        PanelOrientation  orientation;
 
566
        int               monitor;
 
567
 
 
568
        unique_id = panel_layout_find_free_id (PANEL_LAYOUT_TOPLEVEL_ID_LIST_KEY,
 
569
                                               PANEL_TOPLEVEL_SCHEMA,
 
570
                                               PANEL_LAYOUT_TOPLEVEL_PATH,
 
571
                                               NULL, -1);
 
572
 
 
573
        path = g_strdup_printf ("%s%s/", PANEL_LAYOUT_TOPLEVEL_PATH, unique_id);
 
574
        settings = g_settings_new_with_path (PANEL_TOPLEVEL_SCHEMA, path);
 
575
        g_free (path);
 
576
 
 
577
        g_settings_set_int (settings,
 
578
                            PANEL_TOPLEVEL_SCREEN_KEY,
 
579
                            gdk_screen_get_number (screen));
 
580
 
 
581
        if (panel_toplevel_find_empty_spot (screen, &orientation, &monitor)) {
 
582
                g_settings_set_enum (settings,
 
583
                                     PANEL_TOPLEVEL_ORIENTATION_KEY,
 
584
                                     orientation);
 
585
                g_settings_set_int (settings,
 
586
                                    PANEL_TOPLEVEL_MONITOR_KEY,
 
587
                                    monitor);
 
588
        }
 
589
 
 
590
        g_object_unref (settings);
 
591
 
 
592
        panel_gsettings_append_strv (layout_settings,
 
593
                                     PANEL_LAYOUT_TOPLEVEL_ID_LIST_KEY,
 
594
                                     unique_id);
 
595
 
 
596
        g_free (unique_id);
 
597
}
 
598
 
 
599
void
 
600
panel_layout_object_create (PanelObjectType      type,
 
601
                            const char          *type_detail,
 
602
                            const char          *toplevel_id,
 
603
                            PanelObjectPackType  pack_type,
 
604
                            int                  pack_index)
 
605
{
 
606
        char *id;
 
607
 
 
608
        id = panel_layout_object_create_start (type, type_detail,
 
609
                                               toplevel_id, pack_type, pack_index,
 
610
                                               NULL);
 
611
 
 
612
        if (!id)
 
613
                return;
 
614
 
 
615
        panel_layout_object_create_finish (id);
 
616
 
 
617
        g_free (id);
 
618
}
 
619
 
 
620
char *
 
621
panel_layout_object_get_gconf_path (const char *object_id)
 
622
{
 
623
        char *ret;
 
624
        char *gconfied_id;
 
625
 
 
626
        /* gconf uses '_' and not '-' */
 
627
        gconfied_id = g_strdup (object_id);
 
628
        g_strdelimit (gconfied_id, "-", '_');
 
629
 
 
630
        ret = g_strdup_printf (PANEL_LAYOUT_OBJECT_GCONF_PATH_TEMPLATE,
 
631
                               gconfied_id);
 
632
 
 
633
        g_free (gconfied_id);
 
634
 
 
635
        return ret;
 
636
}
 
637
 
 
638
GSettings *
 
639
panel_layout_get_instance_settings (GSettings  *settings_object,
 
640
                                    const char *schema)
 
641
{
 
642
        char      *path;
 
643
        char      *path_instance;
 
644
        GSettings *settings_instance;
 
645
 
 
646
        g_return_val_if_fail (G_IS_SETTINGS (settings_object), NULL);
 
647
 
 
648
        g_object_get (settings_object, "path", &path, NULL);
 
649
        path_instance = g_strdup_printf ("%s%s", path,
 
650
                                         PANEL_LAYOUT_OBJECT_CONFIG_SUFFIX);
 
651
        g_free (path);
 
652
 
 
653
        settings_instance = g_settings_new_with_path (schema, path_instance);
 
654
        g_free (path_instance);
 
655
 
 
656
        return settings_instance;
 
657
}
 
658
 
 
659
char *
 
660
panel_layout_object_create_start (PanelObjectType       type,
 
661
                                  const char           *type_detail,
 
662
                                  const char           *toplevel_id,
 
663
                                  PanelObjectPackType   pack_type,
 
664
                                  int                   pack_index,
 
665
                                  GSettings           **settings)
 
666
{
 
667
        char      *unique_id;
 
668
        char      *path;
 
669
        GSettings *settings_object;
 
670
        char      *iid;
 
671
 
 
672
        if (settings)
 
673
                *settings = NULL;
 
674
 
 
675
        iid = panel_object_type_to_iid (type, type_detail);
 
676
        if (!iid)
 
677
                return NULL;
 
678
 
 
679
        unique_id = panel_layout_find_free_id (PANEL_LAYOUT_OBJECT_ID_LIST_KEY,
 
680
                                               PANEL_OBJECT_SCHEMA,
 
681
                                               PANEL_LAYOUT_OBJECT_PATH,
 
682
                                               NULL, -1);
 
683
 
 
684
        path = g_strdup_printf ("%s%s/", PANEL_LAYOUT_OBJECT_PATH, unique_id);
 
685
        settings_object = g_settings_new_with_path (PANEL_OBJECT_SCHEMA, path);
 
686
        g_free (path);
 
687
 
 
688
        g_settings_set_string (settings_object,
 
689
                               PANEL_OBJECT_IID_KEY,
 
690
                               iid);
 
691
        g_settings_set_string (settings_object,
 
692
                               PANEL_OBJECT_TOPLEVEL_ID_KEY,
 
693
                               toplevel_id);
 
694
        g_settings_set_enum (settings_object,
 
695
                             PANEL_OBJECT_PACK_TYPE_KEY,
 
696
                             pack_type);
 
697
        g_settings_set_int (settings_object,
 
698
                            PANEL_OBJECT_PACK_INDEX_KEY,
 
699
                            pack_index);
 
700
 
 
701
        g_free (iid);
 
702
 
 
703
        if (settings)
 
704
                *settings = settings_object;
 
705
        else
 
706
                g_object_unref (settings_object);
 
707
 
 
708
        return unique_id;
 
709
}
 
710
 
 
711
void
 
712
panel_layout_object_create_finish (const char *object_id)
 
713
{
 
714
        panel_gsettings_append_strv (layout_settings,
 
715
                                     PANEL_LAYOUT_OBJECT_ID_LIST_KEY,
 
716
                                     object_id);
 
717
}
 
718
 
 
719
 
 
720
/*******************\
 
721
 * Changing layout *
 
722
\*******************/
 
723
 
 
724
 
 
725
gboolean
 
726
panel_layout_is_writable (void)
 
727
{
 
728
        return (g_settings_is_writable (layout_settings,
 
729
                                        PANEL_LAYOUT_TOPLEVEL_ID_LIST_KEY) &&
 
730
                g_settings_is_writable (layout_settings,
 
731
                                        PANEL_LAYOUT_OBJECT_ID_LIST_KEY));
 
732
}
 
733
 
 
734
void
 
735
panel_layout_delete_toplevel (const char *toplevel_id)
 
736
{
 
737
        char  *path;
 
738
        char  *id_copy;
 
739
        char **objects;
 
740
        int    i;
 
741
 
 
742
        if (PANEL_GLIB_STR_EMPTY (toplevel_id))
 
743
                return;
 
744
 
 
745
        /* The original will be freed if removal succeeds */
 
746
        id_copy = g_strdup (toplevel_id);
 
747
 
 
748
        if (!panel_gsettings_remove_all_from_strv (layout_settings,
 
749
                                                   PANEL_LAYOUT_TOPLEVEL_ID_LIST_KEY,
 
750
                                                   id_copy)) {
 
751
                g_free (id_copy);
 
752
                return;
 
753
        }
 
754
 
 
755
        path = g_strdup_printf ("%s%s/",
 
756
                                PANEL_LAYOUT_TOPLEVEL_PATH, id_copy);
 
757
        panel_dconf_recursive_reset (path, NULL);
 
758
 
 
759
        /* remove all applets that were on this toplevel */
 
760
 
 
761
        objects = g_settings_get_strv (layout_settings,
 
762
                                       PANEL_LAYOUT_OBJECT_ID_LIST_KEY);
 
763
 
 
764
        for (i = 0; objects[i] != NULL; i++) {
 
765
                GSettings *settings;
 
766
                char       *object_toplevel_id;
 
767
 
 
768
                path = g_strdup_printf ("%s%s/",
 
769
                                        PANEL_LAYOUT_OBJECT_PATH, objects[i]);
 
770
 
 
771
                settings = g_settings_new_with_path (PANEL_OBJECT_SCHEMA, path);
 
772
                object_toplevel_id = g_settings_get_string (settings,
 
773
                                                            PANEL_OBJECT_TOPLEVEL_ID_KEY);
 
774
 
 
775
                g_object_unref (settings);
 
776
                g_free (path);
 
777
 
 
778
                if (g_strcmp0 (id_copy, object_toplevel_id) == 0)
 
779
                        panel_layout_delete_object (objects[i]);
 
780
 
 
781
                g_free (object_toplevel_id);
 
782
        }
 
783
 
 
784
        g_strfreev (objects);
 
785
 
 
786
        g_free (id_copy);
 
787
}
 
788
 
 
789
void
 
790
panel_layout_delete_object (const char *object_id)
 
791
{
 
792
        char *path;
 
793
        char *id_copy;
 
794
 
 
795
        if (PANEL_GLIB_STR_EMPTY (object_id))
 
796
                return;
 
797
 
 
798
        /* The original will be freed if removal succeeds */
 
799
        id_copy = g_strdup (object_id);
 
800
 
 
801
        if (!panel_gsettings_remove_all_from_strv (layout_settings,
 
802
                                                   PANEL_LAYOUT_OBJECT_ID_LIST_KEY,
 
803
                                                   id_copy)) {
 
804
                g_free (id_copy);
 
805
                return;
 
806
        }
 
807
 
 
808
        path = g_strdup_printf ("%s%s/",
 
809
                                PANEL_LAYOUT_OBJECT_PATH, id_copy);
 
810
        panel_dconf_recursive_reset (path, NULL);
 
811
        g_free (path);
 
812
 
 
813
        path = panel_layout_object_get_gconf_path (id_copy);
 
814
        panel_gconf_recursive_unset (path, NULL);
 
815
        g_free (path);
 
816
 
 
817
        g_free (id_copy);
 
818
}
 
819
 
 
820
static void
 
821
panel_layout_changed_toplevel (void)
 
822
{
 
823
        char       **ids;
 
824
        GSList      *to_remove;
 
825
        gboolean     loading;
 
826
        gboolean     found;
 
827
        const char  *id;
 
828
        GSList      *l;
 
829
        int          i;
 
830
 
 
831
        ids = g_settings_get_strv (layout_settings,
 
832
                                   PANEL_LAYOUT_TOPLEVEL_ID_LIST_KEY);
 
833
 
 
834
        /* Remove what is not in the layout anymore */
 
835
 
 
836
        to_remove = NULL;
 
837
 
 
838
        for (l = panel_toplevel_list_toplevels (); l != NULL; l = l->next) {
 
839
                id = panel_toplevel_get_id (l->data);
 
840
                found = FALSE;
 
841
 
 
842
                for (i = 0; ids[i] != NULL; i++) {
 
843
                        if (g_strcmp0 (ids[i], id) == 0) {
 
844
                                found = TRUE;
 
845
                                break;
 
846
                        }
 
847
                }
 
848
 
 
849
                if (!found)
 
850
                        to_remove = g_slist_prepend (to_remove, l->data);
 
851
        }
 
852
 
 
853
        for (l = to_remove; l != NULL; l = l->next)
 
854
                gtk_widget_destroy (GTK_WIDGET (l->data));
 
855
 
 
856
        g_slist_free (to_remove);
 
857
 
 
858
        /* Add what appeared in the layout */
 
859
 
 
860
        loading = FALSE;
 
861
 
 
862
        for (i = 0; ids[i] != NULL; i++) {
 
863
                found = FALSE;
 
864
 
 
865
                for (l = panel_toplevel_list_toplevels (); l != NULL; l = l->next) {
 
866
                        id = panel_toplevel_get_id (l->data);
 
867
                        if (g_strcmp0 (ids[i], id) == 0) {
 
868
                                found = TRUE;
 
869
                                break;
 
870
                        }
 
871
                }
 
872
 
 
873
                if (!found) {
 
874
                        panel_layout_load_toplevel (ids[i]);
 
875
                        loading = TRUE;
 
876
                }
 
877
        }
 
878
 
 
879
        g_strfreev (ids);
 
880
 
 
881
        /* Reload list of objects to get those that might be on the new
 
882
         * toplevels */
 
883
        if (loading)
 
884
                panel_layout_changed_object ();
 
885
}
 
886
 
 
887
static void
 
888
panel_layout_changed_object (void)
 
889
{
 
890
        char       **ids;
 
891
        GSList      *to_remove;
 
892
        gboolean     loading;
 
893
        gboolean     found;
 
894
        const char  *id;
 
895
        GSList      *l;
 
896
        int          i;
 
897
 
 
898
        ids = g_settings_get_strv (layout_settings,
 
899
                                   PANEL_LAYOUT_OBJECT_ID_LIST_KEY);
 
900
 
 
901
        /* Remove what is not in the layout anymore */
 
902
 
 
903
        to_remove = NULL;
 
904
 
 
905
        for (l = panel_applet_list_applets (); l != NULL; l = l->next) {
 
906
                id = panel_applet_get_id (l->data);
 
907
                found = FALSE;
 
908
 
 
909
                for (i = 0; ids[i] != NULL; i++) {
 
910
                        if (g_strcmp0 (ids[i], id) == 0) {
 
911
                                found = TRUE;
 
912
                                break;
 
913
                        }
 
914
                }
 
915
 
 
916
                if (!found)
 
917
                        to_remove = g_slist_prepend (to_remove, l->data);
 
918
        }
 
919
 
 
920
        for (l = to_remove; l != NULL; l = l->next)
 
921
                panel_applet_clean (l->data);
 
922
 
 
923
        g_slist_free (to_remove);
 
924
 
 
925
        /* Add what appeared in the layout */
 
926
 
 
927
        loading = FALSE;
 
928
 
 
929
        for (i = 0; ids[i] != NULL; i++) {
 
930
                found = FALSE;
 
931
 
 
932
                if (panel_object_loader_is_queued (ids[i]))
 
933
                        continue;
 
934
 
 
935
                for (l = panel_applet_list_applets (); l != NULL; l = l->next) {
 
936
                        id = panel_applet_get_id (l->data);
 
937
                        if (g_strcmp0 (ids[i], id) == 0) {
 
938
                                found = TRUE;
 
939
                                break;
 
940
                        }
 
941
                }
 
942
 
 
943
                if (!found) {
 
944
                        panel_layout_load_object (ids[i]);
 
945
                        loading = TRUE;
 
946
                }
 
947
        }
 
948
 
 
949
        g_strfreev (ids);
 
950
 
 
951
        /* Always do this, even if loading is FALSE: if a panel has been
 
952
         * created, we want a do_load() to unhide it, even if there is no
 
953
         * object to load */
 
954
        panel_object_loader_do_load (FALSE);
 
955
}
 
956
 
 
957
static void
 
958
panel_layout_changed (GSettings *settings,
 
959
                      char      *key,
 
960
                      gpointer   user_data)
 
961
{
 
962
        if (g_strcmp0 (key, PANEL_LAYOUT_TOPLEVEL_ID_LIST_KEY) == 0)
 
963
                panel_layout_changed_toplevel ();
 
964
        else if (g_strcmp0 (key, PANEL_LAYOUT_OBJECT_ID_LIST_KEY) == 0)
 
965
                panel_layout_changed_object ();
 
966
}
 
967
 
 
968
/******************\
 
969
 * Loading layout *
 
970
\******************/
 
971
 
 
972
 
 
973
static void
 
974
panel_layout_load_toplevel (const char *toplevel_id)
 
975
{
 
976
        PanelToplevel *toplevel;
 
977
        char          *path;
 
978
        GSettings     *settings;
 
979
        int            screen;
 
980
 
 
981
        if (PANEL_GLIB_STR_EMPTY (toplevel_id))
 
982
                return;
 
983
 
 
984
        path = g_strdup_printf ("%s%s/",
 
985
                                PANEL_LAYOUT_TOPLEVEL_PATH, toplevel_id);
 
986
 
 
987
        /* Check that the screen is valid */
 
988
        settings = g_settings_new_with_path (PANEL_TOPLEVEL_SCHEMA, path);
 
989
        screen = g_settings_get_int (settings, PANEL_TOPLEVEL_SCREEN_KEY);
 
990
        g_object_unref (settings);
 
991
 
 
992
        if (screen < 0 || screen >= panel_multiscreen_screens ()) {
 
993
                g_free (path);
 
994
                return;
 
995
        }
 
996
 
 
997
        toplevel = g_object_new (PANEL_TYPE_TOPLEVEL,
 
998
                                 "toplevel-id", toplevel_id,
 
999
                                 "settings-path", path,
 
1000
                                 NULL);
 
1001
 
 
1002
        g_free (path);
 
1003
 
 
1004
        /* FIXME: we shouldn't have to do this manually */
 
1005
        panel_setup (toplevel);
 
1006
 
 
1007
        gtk_widget_show (GTK_WIDGET (toplevel));
 
1008
}
 
1009
 
 
1010
static void
 
1011
panel_layout_load_object (const char *object_id)
 
1012
{
 
1013
        char *path;
 
1014
 
 
1015
        if (PANEL_GLIB_STR_EMPTY (object_id))
 
1016
                return;
 
1017
 
 
1018
        path = g_strdup_printf ("%s%s/",
 
1019
                                PANEL_LAYOUT_OBJECT_PATH, object_id);
 
1020
 
 
1021
        panel_object_loader_queue (object_id, path);
 
1022
 
 
1023
        g_free (path);
 
1024
}
 
1025
 
 
1026
static char *
 
1027
panel_layout_get_default_layout_file (void)
 
1028
{
 
1029
        return g_build_filename (PANELDATADIR,
 
1030
                                 "panel-default-layout.layout",
 
1031
                                 NULL);
 
1032
}
 
1033
 
 
1034
static void
 
1035
panel_layout_ensure_toplevel_per_screen (void)
 
1036
{
 
1037
        GSList     *toplevels;
 
1038
        GSList     *empty_screens = NULL;
 
1039
        GSList     *l;
 
1040
        GdkDisplay *display;
 
1041
        int         n_screens, i;
 
1042
        char       *default_layout_file;
 
1043
 
 
1044
        toplevels = panel_toplevel_list_toplevels ();
 
1045
 
 
1046
        display = gdk_display_get_default ();
 
1047
 
 
1048
        n_screens = gdk_display_get_n_screens (display);
 
1049
        for (i = 0; i < n_screens; i++) {
 
1050
                GdkScreen *screen;
 
1051
 
 
1052
                screen = gdk_display_get_screen (display, i);
 
1053
 
 
1054
                for (l = toplevels; l; l = l->next)
 
1055
                        if (gtk_window_get_screen (l->data) == screen)
 
1056
                                break;
 
1057
 
 
1058
                if (!l)
 
1059
                        empty_screens = g_slist_prepend (empty_screens, screen);
 
1060
        }
 
1061
 
 
1062
        if (empty_screens == NULL)
 
1063
                return;
 
1064
 
 
1065
        default_layout_file = panel_layout_get_default_layout_file ();
 
1066
 
 
1067
        for (l = empty_screens; l; l = l->next)
 
1068
                panel_layout_append_from_file_for_screen (default_layout_file,
 
1069
                                                          l->data);
 
1070
 
 
1071
        g_free (default_layout_file);
 
1072
 
 
1073
        g_slist_free (empty_screens);
 
1074
}
 
1075
 
 
1076
gboolean
 
1077
panel_layout_load (void)
 
1078
{
 
1079
        char **toplevels;
 
1080
        char **objects;
 
1081
        int    i;
 
1082
 
 
1083
        panel_layout_init ();
 
1084
 
 
1085
        toplevels = g_settings_get_strv (layout_settings,
 
1086
                                         PANEL_LAYOUT_TOPLEVEL_ID_LIST_KEY);
 
1087
 
 
1088
        if (!toplevels[0]) {
 
1089
                char *default_layout_file;
 
1090
 
 
1091
                g_strfreev (toplevels);
 
1092
 
 
1093
                if (!g_settings_is_writable (layout_settings,
 
1094
                                             PANEL_LAYOUT_TOPLEVEL_ID_LIST_KEY) ||
 
1095
                    !g_settings_is_writable (layout_settings,
 
1096
                                             PANEL_LAYOUT_OBJECT_ID_LIST_KEY)) {
 
1097
                        g_printerr (_("Cannot create initial panel layout.\n"));
 
1098
 
 
1099
                        return FALSE;
 
1100
                }
 
1101
 
 
1102
                default_layout_file = panel_layout_get_default_layout_file ();
 
1103
                panel_layout_append_from_file (default_layout_file, TRUE);
 
1104
                g_free (default_layout_file);
 
1105
 
 
1106
                toplevels = g_settings_get_strv (layout_settings,
 
1107
                                                 PANEL_LAYOUT_TOPLEVEL_ID_LIST_KEY);
 
1108
 
 
1109
                if (!toplevels[0]) {
 
1110
                        g_strfreev (toplevels);
 
1111
                        g_printerr (_("Cannot create initial panel layout.\n"));
 
1112
 
 
1113
                        return FALSE;
 
1114
                }
 
1115
        }
 
1116
 
 
1117
        for (i = 0; toplevels[i] != NULL; i++)
 
1118
                panel_layout_load_toplevel (toplevels[i]);
 
1119
 
 
1120
        g_strfreev (toplevels);
 
1121
 
 
1122
        objects = g_settings_get_strv (layout_settings,
 
1123
                                       PANEL_LAYOUT_OBJECT_ID_LIST_KEY);
 
1124
 
 
1125
        for (i = 0; objects[i] != NULL; i++)
 
1126
                panel_layout_load_object (objects[i]);
 
1127
 
 
1128
        g_strfreev (objects);
 
1129
 
 
1130
        g_signal_connect (layout_settings, "changed",
 
1131
                          G_CALLBACK (panel_layout_changed), NULL);
 
1132
 
 
1133
        /* This needs to happen after we've loaded the current toplevels (to
 
1134
         * know if we have toplevels on all screens), and after we've connected
 
1135
         * to the settings changed notifications (to automatically load created
 
1136
         * toplevels) */
 
1137
        panel_layout_ensure_toplevel_per_screen ();
 
1138
 
 
1139
        panel_object_loader_do_load (TRUE);
 
1140
 
 
1141
        return TRUE;
 
1142
}