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

« back to all changes in this revision

Viewing changes to gnome-panel/applet.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:
14
14
#include <glib/gi18n.h>
15
15
#include <gdk/gdkx.h>
16
16
 
 
17
#include <libpanel-util/panel-glib.h>
17
18
#include <libpanel-util/panel-show.h>
18
19
 
19
20
#include "button-widget.h"
20
 
#include "drawer.h"
21
21
#include "launcher.h"
 
22
#include "panel.h"
22
23
#include "panel-addto.h"
23
 
#include "panel-gconf.h"
24
 
#include "panel-config-global.h"
 
24
#include "panel-bindings.h"
25
25
#include "panel-applet-frame.h"
26
26
#include "panel-action-button.h"
27
27
#include "panel-menu-bar.h"
28
28
#include "panel-separator.h"
29
 
#include "panel-compatibility.h"
30
29
#include "panel-toplevel.h"
31
30
#include "panel-util.h"
32
 
#include "panel-profile.h"
33
31
#include "panel-menu-button.h"
34
32
#include "panel-globals.h"
35
33
#include "panel-properties-dialog.h"
 
34
#include "panel-layout.h"
36
35
#include "panel-lockdown.h"
37
 
#include "applet-signaler.h"
38
 
 
39
 
#define SMALL_ICON_SIZE 20
 
36
#include "panel-schemas.h"
40
37
 
41
38
static GSList *registered_applets = NULL;
42
39
static GSList *queued_position_saves = NULL;
43
40
static guint   queued_position_source = 0;
44
41
 
 
42
static GtkWidget *panel_applet_get_menu (AppletInfo *info);
 
43
static void applet_menu_show       (GtkWidget *w, AppletInfo *info);
 
44
static void applet_menu_deactivate (GtkWidget *w, AppletInfo *info);
45
45
 
46
46
static inline PanelWidget *
47
47
panel_applet_get_panel_widget (AppletInfo *info)
54
54
                              gboolean    dnd_enabled)
55
55
{
56
56
        switch (info->type) {
57
 
        case PANEL_OBJECT_DRAWER:
58
 
                panel_drawer_set_dnd_enabled (info->data, dnd_enabled);
59
 
                break;
60
57
        case PANEL_OBJECT_MENU:
61
58
                panel_menu_button_set_dnd_enabled (PANEL_MENU_BUTTON (info->widget),
62
59
                                                   dnd_enabled);
66
63
                break;
67
64
        case PANEL_OBJECT_APPLET:
68
65
                break;
69
 
        case PANEL_OBJECT_LOGOUT:
70
 
        case PANEL_OBJECT_LOCK:
71
66
        case PANEL_OBJECT_ACTION:
72
67
                panel_action_button_set_dnd_enabled (PANEL_ACTION_BUTTON (info->widget),
73
68
                                                     dnd_enabled);
74
69
                break;
75
70
        case PANEL_OBJECT_MENU_BAR:
76
71
        case PANEL_OBJECT_SEPARATOR:
 
72
        case PANEL_OBJECT_USER_MENU:
77
73
                break;
78
74
        default:
79
75
                g_assert_not_reached ();
82
78
 
83
79
}
84
80
 
85
 
gboolean
86
 
panel_applet_toggle_locked (AppletInfo *info)
87
 
{
88
 
        PanelWidget *panel_widget;
89
 
        gboolean     locked;
90
 
 
91
 
        panel_widget = panel_applet_get_panel_widget (info);
92
 
        
93
 
        locked = panel_widget_toggle_applet_locked (panel_widget, info->widget);
94
 
 
95
 
        panel_applet_save_position (info, info->id, TRUE);
96
 
        panel_applet_set_dnd_enabled (info, !locked);
97
 
 
98
 
        return locked;
99
 
}
100
 
 
101
 
static void
102
 
panel_applet_lock (GtkCheckMenuItem *menuitem,
103
 
                   AppletInfo       *info)
104
 
{
105
 
        gboolean locked;
106
 
 
107
 
        locked = panel_applet_toggle_locked (info);
108
 
 
109
 
        gtk_check_menu_item_set_active (menuitem, locked);
110
 
 
111
 
        if (info->move_item)
112
 
                gtk_widget_set_sensitive (info->move_item, !locked);
113
 
}
114
 
 
115
81
static void
116
82
move_applet_callback (GtkWidget *widget, AppletInfo *info)
117
83
{
129
95
        panel = PANEL_WIDGET (parent);
130
96
 
131
97
        panel_widget_applet_drag_start (panel, info->widget,
132
 
                                        PW_DRAG_OFF_CENTER,
133
98
                                        GDK_CURRENT_TIME);
134
99
}
135
100
 
153
118
}
154
119
 
155
120
static void
156
 
panel_applet_recreate_menu (AppletInfo  *info)
 
121
panel_applet_recreate_menu (AppletInfo *info)
157
122
{
158
 
        GList *l;
159
 
 
160
 
        if (!info->menu)
161
 
                return;
162
 
 
163
 
        for (l = info->user_menu; l; l = l->next) {
164
 
                AppletUserMenu *menu = l->data;
165
 
 
166
 
                menu->menuitem =NULL;
167
 
                menu->submenu =NULL;
 
123
        if (info->menu) {
 
124
                GList *l;
 
125
 
 
126
                for (l = info->user_menu; l; l = l->next) {
 
127
                        AppletUserMenu *menu = l->data;
 
128
 
 
129
                        menu->menuitem = NULL;
 
130
                        menu->submenu = NULL;
 
131
                }
 
132
 
 
133
                if (gtk_widget_get_visible (info->menu))
 
134
                        gtk_menu_shell_deactivate (GTK_MENU_SHELL (info->menu));
 
135
 
 
136
                g_signal_handlers_disconnect_by_func (info->menu,
 
137
                                                      G_CALLBACK (applet_menu_show), info);
 
138
                g_signal_handlers_disconnect_by_func (info->menu,
 
139
                                                      G_CALLBACK (applet_menu_deactivate), info);
 
140
 
 
141
                g_object_unref (info->menu);
 
142
                info->menu = NULL;
168
143
        }
169
144
 
170
 
        g_object_unref (info->menu);
171
 
        info->menu = panel_applet_create_menu (info);
172
 
}
173
 
 
174
 
static void
175
 
panel_applet_locked_change_notify (GConfClient *client,
176
 
                                   guint        cnxn_id,
177
 
                                   GConfEntry  *entry,
178
 
                                   GtkWidget   *applet)
179
 
{
180
 
        GConfValue  *value;
181
 
        gboolean     locked;
182
 
        gboolean     applet_locked;
183
 
        AppletInfo  *info;
184
 
        PanelWidget *panel_widget;
185
 
 
186
 
        g_assert (applet != NULL);
187
 
 
188
 
        info = (AppletInfo  *) g_object_get_data (G_OBJECT (applet),
189
 
                                                  "applet_info");
190
 
        if (info == NULL)
191
 
                return;
192
 
 
193
 
        value = gconf_entry_get_value (entry);
194
 
        if (value == NULL || value->type != GCONF_VALUE_BOOL)
195
 
                return;
196
 
 
197
 
        locked = gconf_value_get_bool (value);
198
 
 
199
 
        panel_widget = panel_applet_get_panel_widget (info);
200
 
        applet_locked = panel_widget_get_applet_locked (panel_widget,
201
 
                                                        info->widget);
202
 
 
203
 
        if ((locked && applet_locked) || !(locked || applet_locked))
204
 
                return;
205
 
 
206
 
        panel_applet_toggle_locked (info);
207
 
 
208
 
        if (info->type == PANEL_OBJECT_APPLET)
209
 
                panel_applet_frame_sync_menu_state (PANEL_APPLET_FRAME (info->widget));
210
 
        else
211
 
                panel_applet_recreate_menu (info);
 
145
        panel_applet_get_menu (info);
212
146
}
213
147
 
214
148
static void
216
150
                        AppletInfo *info)
217
151
{
218
152
 
219
 
        if (info->type == PANEL_OBJECT_DRAWER)
220
 
                drawer_query_deletion (info->data);
221
 
        else
222
 
                panel_profile_delete_object (info);
 
153
        panel_layout_delete_object (info->id);
223
154
}
224
155
 
225
156
static inline GdkScreen *
249
180
                else if (!strcmp (menu->name, "properties"))
250
181
                        launcher_properties (menu->info->data);
251
182
                break;
252
 
        case PANEL_OBJECT_DRAWER: 
253
 
                if (strcmp (menu->name, "add") == 0) {
254
 
                        Drawer *drawer = menu->info->data;
255
 
 
256
 
                        panel_addto_present (GTK_MENU_ITEM (widget),
257
 
                                             panel_toplevel_get_panel_widget (drawer->toplevel));
258
 
                } else if (strcmp (menu->name, "properties") == 0) {
259
 
                        Drawer *drawer = menu->info->data;
260
 
 
261
 
                        panel_properties_dialog_present (drawer->toplevel);
262
 
                } else if (strcmp (menu->name, "help") == 0) {
263
 
                        panel_show_help (screen,
264
 
                                         "user-guide", "gospanel-18", NULL);
265
 
                }
266
 
                break;
267
183
        case PANEL_OBJECT_MENU:
268
184
                panel_menu_button_invoke_menu (
269
185
                        PANEL_MENU_BUTTON (menu->info->widget), menu->name);
270
186
                break;
271
187
        case PANEL_OBJECT_ACTION:
272
 
        case PANEL_OBJECT_LOGOUT:
273
 
        case PANEL_OBJECT_LOCK:
274
188
                panel_action_button_invoke_menu (
275
189
                        PANEL_ACTION_BUTTON (menu->info->widget), menu->name);
276
190
                break;
285
199
                 */
286
200
                break;
287
201
        case PANEL_OBJECT_SEPARATOR:
 
202
        case PANEL_OBJECT_USER_MENU:
288
203
                break;
289
204
        default:
290
205
                g_assert_not_reached ();
472
387
        g_free(n);
473
388
}
474
389
 
475
 
GtkWidget *
476
 
panel_applet_create_menu (AppletInfo *info)
 
390
static GtkWidget *
 
391
panel_applet_create_bare_menu (AppletInfo *info)
477
392
{
478
 
        GtkWidget   *menu;
479
 
        GtkWidget   *menuitem;
480
 
        GList       *l;
481
 
        PanelWidget *panel_widget;
482
 
        gboolean     added_anything = FALSE;
483
 
 
484
 
        panel_widget = panel_applet_get_panel_widget (info);
 
393
        GtkWidget *menu;
485
394
 
486
395
        menu = g_object_ref_sink (gtk_menu_new ());
487
396
 
493
402
        g_signal_connect (menu, "deactivate",
494
403
                          G_CALLBACK (applet_menu_deactivate), info);
495
404
 
 
405
        return menu;
 
406
}
 
407
 
 
408
static void
 
409
panel_applet_menu_lockdown_changed (PanelLockdown *lockdown,
 
410
                                    gpointer       user_data)
 
411
{
 
412
        AppletInfo *info = user_data;
 
413
 
 
414
        panel_applet_recreate_menu (info);
 
415
}
 
416
 
 
417
static GtkWidget *
 
418
panel_applet_get_menu (AppletInfo *info)
 
419
{
 
420
        GtkWidget   *menu;
 
421
        GList       *l;
 
422
        gboolean     added_anything = FALSE;
 
423
 
 
424
        if (info->menu)
 
425
                return info->menu;
 
426
 
 
427
        menu = panel_applet_create_bare_menu (info);
 
428
 
496
429
        for (l = info->user_menu; l; l = l->next) {
497
430
                AppletUserMenu *user_menu = l->data;
498
431
 
505
438
                added_anything = TRUE;
506
439
        }
507
440
 
508
 
        if (!panel_lockdown_get_locked_down ()) {
509
 
                GtkWidget *image;
510
 
                gboolean   locked;
511
 
                gboolean   lockable;
512
 
                gboolean   movable;
513
 
                gboolean   removable;
514
 
 
515
 
                lockable = panel_applet_lockable (info);
516
 
                movable = panel_applet_can_freely_move (info);
517
 
                removable = panel_profile_id_lists_are_writable ();
518
 
 
519
 
                locked = panel_widget_get_applet_locked (panel_widget, info->widget);
520
 
 
521
 
                if (added_anything) {
522
 
                        menuitem = gtk_separator_menu_item_new ();
523
 
                        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
524
 
                        gtk_widget_show (menuitem);
525
 
                }
526
 
 
527
 
                menuitem = gtk_image_menu_item_new_with_mnemonic (_("_Remove From Panel"));
528
 
                image = gtk_image_new_from_stock (GTK_STOCK_REMOVE,
529
 
                                                  GTK_ICON_SIZE_MENU);
530
 
                gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
531
 
                                               image);
532
 
                g_signal_connect (menuitem, "activate",
533
 
                                  G_CALLBACK (applet_remove_callback), info);
534
 
                gtk_widget_show (menuitem);
535
 
                gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
536
 
                gtk_widget_set_sensitive (menuitem, (!locked || lockable) && removable);
537
 
                
538
 
                menuitem = gtk_menu_item_new_with_mnemonic (_("_Move"));
539
 
                g_signal_connect (menuitem, "activate",
540
 
                                  G_CALLBACK (move_applet_callback), info);
541
 
                gtk_widget_show (menuitem);
542
 
                gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
543
 
                gtk_widget_set_sensitive (menuitem, !locked && movable);
544
 
 
545
 
                g_assert (info->move_item == NULL);
546
 
 
547
 
                info->move_item = menuitem;
548
 
                g_object_add_weak_pointer (G_OBJECT (menuitem),
549
 
                                           (gpointer *) &info->move_item);
550
 
 
551
 
                menuitem = gtk_separator_menu_item_new ();
552
 
                gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
553
 
                gtk_widget_show (menuitem);
554
 
 
555
 
                menuitem = gtk_check_menu_item_new_with_mnemonic (_("Loc_k To Panel"));
556
 
                gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
557
 
                                                locked);
558
 
                g_signal_connect (menuitem, "toggled",
559
 
                                  G_CALLBACK (panel_applet_lock), info);
560
 
                gtk_widget_show (menuitem);
561
 
                gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
562
 
                gtk_widget_set_sensitive (menuitem, lockable);
563
 
 
564
 
                added_anything = TRUE;
565
 
        }
566
 
 
567
441
        if ( ! added_anything) {
 
442
                g_signal_handlers_disconnect_by_func (menu,
 
443
                                                      G_CALLBACK (applet_menu_show), info);
 
444
                g_signal_handlers_disconnect_by_func (menu,
 
445
                                                      G_CALLBACK (applet_menu_deactivate), info);
 
446
 
568
447
                g_object_unref (menu);
569
448
                return NULL;
570
449
        }
571
450
 
572
 
        return menu;
573
 
}
 
451
        info->menu = menu;
 
452
 
 
453
        panel_lockdown_on_notify (panel_lockdown_get (),
 
454
                                  NULL,
 
455
                                  G_OBJECT (info->menu),
 
456
                                  panel_applet_menu_lockdown_changed,
 
457
                                  info);
 
458
 
 
459
        return info->menu;
 
460
}
 
461
 
 
462
static void
 
463
panel_applet_edit_menu_lockdown_changed (PanelLockdown *lockdown,
 
464
                                         gpointer       user_data)
 
465
{
 
466
        AppletInfo *info = user_data;
 
467
 
 
468
        if (!panel_lockdown_get_panels_locked_down (lockdown))
 
469
                return;
 
470
 
 
471
        if (info->edit_menu) {
 
472
                if (gtk_widget_get_visible (info->edit_menu))
 
473
                        gtk_menu_shell_deactivate (GTK_MENU_SHELL (info->edit_menu));
 
474
 
 
475
                g_signal_handlers_disconnect_by_func (info->edit_menu,
 
476
                                                      G_CALLBACK (applet_menu_deactivate), info);
 
477
                gtk_widget_destroy (info->edit_menu);
 
478
                info->edit_menu = NULL;
 
479
        }
 
480
}
 
481
 
 
482
static GtkWidget *
 
483
panel_applet_get_edit_menu (AppletInfo *info)
 
484
{
 
485
        GtkWidget   *menu;
 
486
        GtkWidget   *menuitem;
 
487
        PanelWidget *panel_widget;
 
488
        GtkWidget   *image;
 
489
        gboolean     movable;
 
490
        gboolean     removable;
 
491
 
 
492
        if (info->edit_menu)
 
493
                return info->edit_menu;
 
494
 
 
495
        if (panel_lockdown_get_panels_locked_down_s ())
 
496
                return NULL;
 
497
 
 
498
        menu = panel_applet_create_bare_menu (info);
 
499
        panel_widget = panel_applet_get_panel_widget (info);
 
500
 
 
501
        movable = panel_applet_can_freely_move (info);
 
502
        removable = panel_layout_is_writable ();
 
503
 
 
504
        menuitem = gtk_menu_item_new_with_mnemonic (_("_Move"));
 
505
        g_signal_connect (menuitem, "activate",
 
506
                          G_CALLBACK (move_applet_callback), info);
 
507
        gtk_widget_show (menuitem);
 
508
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
 
509
        gtk_widget_set_sensitive (menuitem, movable);
 
510
 
 
511
        menuitem = gtk_image_menu_item_new_with_mnemonic (_("_Remove From Panel"));
 
512
        image = gtk_image_new_from_stock (GTK_STOCK_REMOVE,
 
513
                                          GTK_ICON_SIZE_MENU);
 
514
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
 
515
                                       image);
 
516
        g_signal_connect (menuitem, "activate",
 
517
                          G_CALLBACK (applet_remove_callback), info);
 
518
        gtk_widget_show (menuitem);
 
519
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
 
520
        gtk_widget_set_sensitive (menuitem, removable);
 
521
 
 
522
        info->edit_menu = menu;
 
523
 
 
524
        panel_lockdown_on_notify (panel_lockdown_get (),
 
525
                                  "panels-locked-down",
 
526
                                  G_OBJECT (info->edit_menu),
 
527
                                  panel_applet_edit_menu_lockdown_changed,
 
528
                                  info);
 
529
 
 
530
        return info->edit_menu;
 
531
}
 
532
 
574
533
 
575
534
void
576
535
panel_applet_menu_set_recurse (GtkMenu     *menu,
617
576
 
618
577
        screen = gtk_widget_get_screen (applet);
619
578
 
620
 
        gtk_widget_size_request (GTK_WIDGET (menu), &requisition);
 
579
        gtk_widget_get_preferred_size (GTK_WIDGET (menu), &requisition, NULL);
621
580
 
622
581
        gdk_window_get_origin (gtk_widget_get_window (applet), &menu_x, &menu_y);
623
582
        gtk_widget_get_pointer (applet, &pointer_x, &pointer_y);
668
627
 
669
628
static void
670
629
applet_show_menu (AppletInfo     *info,
 
630
                  GtkWidget      *menu,
 
631
                  gboolean        custom_position,
671
632
                  GdkEventButton *event)
672
633
{
673
634
        PanelWidget *panel_widget;
674
635
 
675
636
        g_return_if_fail (info != NULL);
676
637
 
 
638
        if (menu == NULL)
 
639
                return;
 
640
 
677
641
        panel_widget = panel_applet_get_panel_widget (info);
678
642
 
679
 
        if (info->menu == NULL)
680
 
                info->menu = panel_applet_create_menu (info);
681
 
 
682
 
        if (info->menu == NULL)
683
 
                return;
684
 
 
685
 
        panel_applet_menu_set_recurse (GTK_MENU (info->menu),
 
643
        panel_applet_menu_set_recurse (GTK_MENU (menu),
686
644
                                       "menu_panel",
687
645
                                       panel_widget);
688
646
 
689
 
        gtk_menu_set_screen (GTK_MENU (info->menu),
 
647
        gtk_menu_set_screen (GTK_MENU (menu),
690
648
                             gtk_window_get_screen (GTK_WINDOW (panel_widget->toplevel)));
691
649
 
692
 
        if (!gtk_widget_get_realized (info->menu))
693
 
                gtk_widget_show (info->menu);
 
650
        if (!gtk_widget_get_realized (menu))
 
651
                gtk_widget_show (menu);
694
652
 
695
 
        gtk_menu_popup (GTK_MENU (info->menu),
696
 
                        NULL,
697
 
                        NULL,
698
 
                        (GtkMenuPositionFunc) panel_applet_position_menu,
 
653
        gtk_menu_popup (GTK_MENU (menu),
 
654
                        NULL,
 
655
                        NULL,
 
656
                        custom_position ?
 
657
                                (GtkMenuPositionFunc) panel_applet_position_menu : NULL,
699
658
                        info->widget,
700
659
                        event->button,
701
660
                        event->time);
702
661
}
703
662
 
704
663
static gboolean
705
 
applet_do_popup_menu (GtkWidget      *widget,
706
 
                      GdkEventButton *event,
707
 
                      AppletInfo     *info)
 
664
applet_must_skip_menu (AppletInfo *info)
708
665
{
709
666
        if (panel_applet_is_in_drag ())
710
 
                return FALSE;
 
667
                return TRUE;
711
668
 
712
669
        if (info->type == PANEL_OBJECT_APPLET)
713
 
                return FALSE;
714
 
 
715
 
        applet_show_menu (info, event);
716
 
 
717
 
        return TRUE;
718
 
}
719
 
 
720
 
static gboolean
721
 
applet_popup_menu (GtkWidget      *widget,
722
 
                   AppletInfo     *info)
723
 
{
724
 
        GdkEventButton event;
725
 
 
726
 
        event.button = 3;
727
 
        event.time = GDK_CURRENT_TIME;
728
 
 
729
 
        return applet_do_popup_menu (widget, &event, info);
 
670
                return TRUE;
 
671
 
 
672
        return FALSE;
730
673
}
731
674
 
732
675
static gboolean
734
677
                     GdkEventButton *event,
735
678
                     AppletInfo     *info)
736
679
{
737
 
        if (event->button == 3)
738
 
                return applet_do_popup_menu (widget, event, info);
739
 
 
740
 
        return FALSE;
 
680
        guint modifiers;
 
681
 
 
682
        if (event->button != 3)
 
683
                return FALSE;
 
684
 
 
685
        if (applet_must_skip_menu (info))
 
686
                return FALSE;
 
687
 
 
688
        modifiers = event->state & gtk_accelerator_get_default_mod_mask ();
 
689
 
 
690
        if (modifiers == panel_bindings_get_mouse_button_modifier_keymask ())
 
691
                applet_show_menu (info, panel_applet_get_edit_menu (info), FALSE, event);
 
692
        else
 
693
                applet_show_menu (info, panel_applet_get_menu (info), TRUE, event);
 
694
 
 
695
        return TRUE;
 
696
}
 
697
 
 
698
static gboolean
 
699
applet_key_press (GtkWidget   *widget,
 
700
                  GdkEventKey *event,
 
701
                  AppletInfo  *info)
 
702
{
 
703
        GdkEventButton eventbutton;
 
704
        gboolean is_popup = FALSE;
 
705
        gboolean is_edit_popup = FALSE;
 
706
 
 
707
        if (applet_must_skip_menu (info))
 
708
                return FALSE;
 
709
 
 
710
        eventbutton.button = 3;
 
711
        eventbutton.time = event->time;
 
712
 
 
713
        /* We're not connecting to the popup-menu signal since we want to be
 
714
         * able to deal with two cases:
 
715
         *  - exact keybinding of popup-menu => we open the context menu
 
716
         *  - keybinding of popup-menu + modifier from metacity => we open menu
 
717
         *    to "edit"
 
718
         */
 
719
        panel_util_key_event_is_popup (event, &is_popup, &is_edit_popup);
 
720
 
 
721
        if (is_edit_popup)
 
722
                applet_show_menu (info, panel_applet_get_edit_menu (info), FALSE, &eventbutton);
 
723
        else if (is_popup)
 
724
                applet_show_menu (info, panel_applet_get_menu (info), TRUE, &eventbutton);
 
725
 
 
726
        return (is_popup || is_edit_popup);
741
727
}
742
728
 
743
729
static void
751
737
        info->widget = NULL;
752
738
 
753
739
        registered_applets = g_slist_remove (registered_applets, info);
754
 
        panel_applet_signaler_remove_applet(info);
755
740
 
756
741
        queued_position_saves =
757
742
                g_slist_remove (queued_position_saves, info);
758
743
 
759
 
        if (info->type == PANEL_OBJECT_DRAWER) {
760
 
                Drawer *drawer = info->data;
761
 
 
762
 
                if (drawer->toplevel) {
763
 
                        PanelWidget *panel_widget;
764
 
 
765
 
                        panel_widget = panel_toplevel_get_panel_widget (
766
 
                                                        drawer->toplevel);
767
 
                        panel_widget->master_widget = NULL;
768
 
 
769
 
                        gtk_widget_destroy (GTK_WIDGET (drawer->toplevel));
770
 
                        drawer->toplevel = NULL;
771
 
                }
772
 
        }
773
 
 
774
 
        if (info->type != PANEL_OBJECT_APPLET)
775
 
                panel_lockdown_notify_remove (G_CALLBACK (panel_applet_recreate_menu),
776
 
                                              info);
777
 
 
778
 
        if (info->menu)
 
744
        if (info->menu) {
 
745
                if (gtk_widget_get_visible (info->menu))
 
746
                        gtk_menu_shell_deactivate (GTK_MENU_SHELL (info->menu));
 
747
 
 
748
                g_signal_handlers_disconnect_by_func (info->menu,
 
749
                                                      G_CALLBACK (applet_menu_show), info);
 
750
                g_signal_handlers_disconnect_by_func (info->menu,
 
751
                                                      G_CALLBACK (applet_menu_deactivate), info);
779
752
                g_object_unref (info->menu);
 
753
        }
780
754
        info->menu = NULL;
781
755
 
 
756
        if (info->edit_menu) {
 
757
                if (gtk_widget_get_visible (info->edit_menu))
 
758
                        gtk_menu_shell_deactivate (GTK_MENU_SHELL (info->edit_menu));
 
759
 
 
760
                g_signal_handlers_disconnect_by_func (info->edit_menu,
 
761
                                                      G_CALLBACK (applet_menu_show), info);
 
762
                g_signal_handlers_disconnect_by_func (info->edit_menu,
 
763
                                                      G_CALLBACK (applet_menu_deactivate), info);
 
764
                g_object_unref (info->edit_menu);
 
765
        }
 
766
        info->edit_menu = NULL;
 
767
 
782
768
        if (info->data_destroy)
783
769
                info->data_destroy (info->data);
784
770
        info->data = NULL;
796
782
        g_list_free (info->user_menu);
797
783
        info->user_menu = NULL;
798
784
 
 
785
        if (info->settings)
 
786
                g_object_unref (info->settings);
 
787
        info->settings = NULL;
 
788
 
799
789
        g_free (info->id);
800
790
        info->id = NULL;
801
791
 
802
792
        g_free (info);
803
793
}
804
794
 
805
 
typedef struct {
806
 
        char            *id;
807
 
        PanelObjectType  type;
808
 
        char            *toplevel_id;
809
 
        int              position;
810
 
        guint            right_stick : 1;
811
 
        guint            locked : 1;
812
 
} PanelAppletToLoad;
813
 
 
814
 
/* Each time those lists get both empty,
815
 
 * panel_applet_queue_initial_unhide_toplevels() should be called */
816
 
static GSList  *panel_applets_to_load = NULL;
817
 
static GSList  *panel_applets_loading = NULL;
818
 
/* We have a timeout to always unhide toplevels after a delay, in case of some
819
 
 * blocking applet */
820
 
#define         UNHIDE_TOPLEVELS_TIMEOUT_SECONDS 5
821
 
static guint    panel_applet_unhide_toplevels_timeout = 0;
822
 
 
823
 
static gboolean panel_applet_have_load_idle = FALSE;
824
 
 
825
 
static void
826
 
free_applet_to_load (PanelAppletToLoad *applet)
827
 
{
828
 
        g_free (applet->id);
829
 
        applet->id = NULL;
830
 
 
831
 
        g_free (applet->toplevel_id);
832
 
        applet->toplevel_id = NULL;
833
 
 
834
 
        g_free (applet);
835
 
}
836
 
 
837
 
gboolean
838
 
panel_applet_on_load_queue (const char *id)
839
 
{
840
 
        GSList *li;
841
 
        for (li = panel_applets_to_load; li != NULL; li = li->next) {
842
 
                PanelAppletToLoad *applet = li->data;
843
 
                if (strcmp (applet->id, id) == 0)
844
 
                        return TRUE;
845
 
        }
846
 
        for (li = panel_applets_loading; li != NULL; li = li->next) {
847
 
                PanelAppletToLoad *applet = li->data;
848
 
                if (strcmp (applet->id, id) == 0)
849
 
                        return TRUE;
850
 
        }
851
 
        return FALSE;
852
 
}
853
 
 
854
 
/* This doesn't do anything if the initial unhide already happened */
855
 
static gboolean
856
 
panel_applet_queue_initial_unhide_toplevels (gpointer user_data)
857
 
{
858
 
        GSList *l;
859
 
 
860
 
        if (panel_applet_unhide_toplevels_timeout != 0) {
861
 
                g_source_remove (panel_applet_unhide_toplevels_timeout);
862
 
                panel_applet_unhide_toplevels_timeout = 0;
863
 
        }
864
 
 
865
 
        for (l = panel_toplevel_list_toplevels (); l != NULL; l = l->next)
866
 
                panel_toplevel_queue_initial_unhide ((PanelToplevel *) l->data);
867
 
 
868
 
        return FALSE;
869
 
}
870
 
 
871
 
void
872
 
panel_applet_stop_loading (const char *id)
873
 
{
874
 
        PanelAppletToLoad *applet;
875
 
        GSList *l;
876
 
 
877
 
        for (l = panel_applets_loading; l; l = l->next) {
878
 
                applet = l->data;
879
 
 
880
 
                if (strcmp (applet->id, id) == 0)
881
 
                        break;
882
 
        }
883
 
 
884
 
        /* this can happen if we reload an applet after it crashed,
885
 
         * for example */
886
 
        if (l != NULL) {
887
 
                panel_applets_loading = g_slist_delete_link (panel_applets_loading, l);
888
 
                free_applet_to_load (applet);
889
 
        }
890
 
 
891
 
        if (panel_applets_loading == NULL && panel_applets_to_load == NULL)
892
 
                panel_applet_queue_initial_unhide_toplevels (NULL);
893
 
}
894
 
 
895
 
static gboolean
896
 
panel_applet_load_idle_handler (gpointer dummy)
897
 
{
898
 
        PanelObjectType    applet_type;
899
 
        PanelAppletToLoad *applet = NULL;
900
 
        PanelToplevel     *toplevel = NULL;
901
 
        PanelWidget       *panel_widget;
902
 
        GSList            *l;
903
 
 
904
 
        if (!panel_applets_to_load) {
905
 
                panel_applet_have_load_idle = FALSE;
906
 
                return FALSE;
907
 
        }
908
 
 
909
 
        for (l = panel_applets_to_load; l; l = l->next) {
910
 
                applet = l->data;
911
 
 
912
 
                toplevel = panel_profile_get_toplevel_by_id (applet->toplevel_id);
913
 
                if (toplevel)
914
 
                        break;
915
 
        }
916
 
 
917
 
        if (!l) {
918
 
                /* All the remaining applets don't have a panel */
919
 
                for (l = panel_applets_to_load; l; l = l->next)
920
 
                        free_applet_to_load (l->data);
921
 
                g_slist_free (panel_applets_to_load);
922
 
                panel_applets_to_load = NULL;
923
 
                panel_applet_have_load_idle = FALSE;
924
 
 
925
 
                if (panel_applets_loading == NULL) {
926
 
                        /* unhide any potential initially hidden toplevel */
927
 
                        panel_applet_queue_initial_unhide_toplevels (NULL);
928
 
                }
929
 
 
930
 
                return FALSE;
931
 
        }
932
 
 
933
 
        panel_applets_to_load = g_slist_delete_link (panel_applets_to_load, l);
934
 
        panel_applets_loading = g_slist_append (panel_applets_loading, applet);
935
 
 
936
 
        panel_widget = panel_toplevel_get_panel_widget (toplevel);
937
 
 
938
 
        if (applet->right_stick) {
939
 
                if (!panel_widget->packed)
940
 
                        applet->position = panel_widget->size - applet->position;
941
 
                else
942
 
                        applet->position = -1;
943
 
        }
944
 
 
945
 
        /* We load applets asynchronously, so we specifically don't call
946
 
         * panel_applet_stop_loading() for this type. However, in case of
947
 
         * failure during the load, we might call panel_applet_stop_loading()
948
 
         * synchronously, which will make us lose the content of the applet
949
 
         * variable. So we save the type to be sure we always ignore the
950
 
         * applets. */
951
 
        applet_type = applet->type;
952
 
 
953
 
        switch (applet_type) {
954
 
        case PANEL_OBJECT_APPLET:
955
 
                panel_applet_frame_load_from_gconf (
956
 
                                        panel_widget,
957
 
                                        applet->locked,
958
 
                                        applet->position,
959
 
                                        applet->id);
960
 
                break;
961
 
        case PANEL_OBJECT_DRAWER:
962
 
                drawer_load_from_gconf (panel_widget,
963
 
                                        applet->locked,
964
 
                                        applet->position,
965
 
                                        applet->id);
966
 
                break;
967
 
        case PANEL_OBJECT_MENU:
968
 
                panel_menu_button_load_from_gconf (panel_widget,
969
 
                                                   applet->locked,
970
 
                                                   applet->position,
971
 
                                                   TRUE,
972
 
                                                   applet->id);
973
 
                break;
974
 
        case PANEL_OBJECT_LAUNCHER:
975
 
                launcher_load_from_gconf (panel_widget,
976
 
                                          applet->locked,
977
 
                                          applet->position,
978
 
                                          applet->id);
979
 
                break;
980
 
        case PANEL_OBJECT_LOGOUT:
981
 
        case PANEL_OBJECT_LOCK:
982
 
                panel_action_button_load_compatible (
983
 
                                applet->type,
984
 
                                panel_widget,
985
 
                                applet->locked,
986
 
                                applet->position,
987
 
                                TRUE,
988
 
                                applet->id);
989
 
                break;
990
 
        case PANEL_OBJECT_ACTION:
991
 
                panel_action_button_load_from_gconf (
992
 
                                panel_widget,
993
 
                                applet->locked,
994
 
                                applet->position,
995
 
                                TRUE,
996
 
                                applet->id);
997
 
                break;
998
 
        case PANEL_OBJECT_MENU_BAR:
999
 
                panel_menu_bar_load_from_gconf (
1000
 
                                panel_widget,
1001
 
                                applet->locked,
1002
 
                                applet->position,
1003
 
                                TRUE,
1004
 
                                applet->id);
1005
 
                break;
1006
 
        case PANEL_OBJECT_SEPARATOR:
1007
 
                panel_separator_load_from_gconf (panel_widget,
1008
 
                                                 applet->locked,
1009
 
                                                 applet->position,
1010
 
                                                 applet->id);
1011
 
                break;
1012
 
        default:
1013
 
                g_assert_not_reached ();
1014
 
                break;
1015
 
        }
1016
 
 
1017
 
        /* Only the real applets will do a late stop_loading */
1018
 
        if (applet_type != PANEL_OBJECT_APPLET)
1019
 
                panel_applet_stop_loading (applet->id);
1020
 
 
1021
 
        return TRUE;
1022
 
}
1023
 
 
1024
 
void
1025
 
panel_applet_queue_applet_to_load (const char      *id,
1026
 
                                   PanelObjectType  type,
1027
 
                                   const char      *toplevel_id,
1028
 
                                   int              position,
1029
 
                                   gboolean         right_stick,
1030
 
                                   gboolean         locked)
1031
 
{
1032
 
        PanelAppletToLoad *applet;
1033
 
 
1034
 
        if (!toplevel_id) {
1035
 
                g_warning ("No toplevel on which to load object '%s'\n", id);
1036
 
                return;
1037
 
        }
1038
 
 
1039
 
        applet = g_new0 (PanelAppletToLoad, 1);
1040
 
 
1041
 
        applet->id          = g_strdup (id);
1042
 
        applet->type        = type;
1043
 
        applet->toplevel_id = g_strdup (toplevel_id);
1044
 
        applet->position    = position;
1045
 
        applet->right_stick = right_stick != FALSE;
1046
 
        applet->locked      = locked != FALSE;
1047
 
 
1048
 
        panel_applets_to_load = g_slist_prepend (panel_applets_to_load, applet);
1049
 
}
1050
 
 
1051
 
static int
1052
 
panel_applet_compare (const PanelAppletToLoad *a,
1053
 
                      const PanelAppletToLoad *b)
1054
 
{
1055
 
        int c;
1056
 
 
1057
 
        if ((c = strcmp (a->toplevel_id, b->toplevel_id)))
1058
 
                return c;
1059
 
        else if (a->right_stick != b->right_stick)
1060
 
                return b->right_stick ? -1 : 1;
1061
 
        else
1062
 
                return a->position - b->position;
1063
 
}
1064
 
 
1065
 
void
1066
 
panel_applet_load_queued_applets (gboolean initial_load)
1067
 
{
1068
 
        if (!panel_applets_to_load) {
1069
 
                panel_applet_queue_initial_unhide_toplevels (NULL);
1070
 
                return;
1071
 
        }
1072
 
 
1073
 
        if (panel_applets_to_load && panel_applet_unhide_toplevels_timeout == 0) {
1074
 
                /* Install a timeout to make sure we don't block the
1075
 
                 * unhiding because of an applet that doesn't load */
1076
 
                panel_applet_unhide_toplevels_timeout =
1077
 
                        g_timeout_add_seconds (UNHIDE_TOPLEVELS_TIMEOUT_SECONDS,
1078
 
                                               panel_applet_queue_initial_unhide_toplevels,
1079
 
                                               NULL);
1080
 
        }
1081
 
 
1082
 
        panel_applets_to_load = g_slist_sort (panel_applets_to_load,
1083
 
                                              (GCompareFunc) panel_applet_compare);
1084
 
 
1085
 
        if ( ! panel_applet_have_load_idle) {
1086
 
                /* on panel startup, we don't care about redraws of the
1087
 
                 * toplevels since they are hidden, so we give a higher
1088
 
                 * priority to loading of applets */
1089
 
                if (initial_load)
1090
 
                        g_idle_add_full (G_PRIORITY_HIGH_IDLE,
1091
 
                                         panel_applet_load_idle_handler,
1092
 
                                         NULL, NULL);
1093
 
                else
1094
 
                        g_idle_add (panel_applet_load_idle_handler, NULL);
1095
 
 
1096
 
                panel_applet_have_load_idle = TRUE;
1097
 
        }
1098
 
}
1099
 
 
1100
795
static G_CONST_RETURN char *
1101
796
panel_applet_get_toplevel_id (AppletInfo *applet)
1102
797
{
1109
804
        if (!panel_widget)
1110
805
                return NULL;
1111
806
 
1112
 
        return panel_profile_get_toplevel_id (panel_widget->toplevel);
 
807
        return panel_toplevel_get_id (panel_widget->toplevel);
1113
808
}
1114
809
 
1115
810
static gboolean
1136
831
                            const char *id,
1137
832
                            gboolean    immediate)
1138
833
{
1139
 
        PanelGConfKeyType  key_type;
1140
 
        GConfClient       *client;
1141
 
        PanelWidget       *panel_widget;
1142
 
        const char        *key;
1143
 
        const char        *toplevel_id;
1144
 
        char              *old_toplevel_id;
1145
 
        gboolean           right_stick;
1146
 
        gboolean           locked;
1147
 
        int                position;
 
834
        PanelWidget *panel_widget;
 
835
        const char  *toplevel_id;
 
836
        AppletData  *applet_data;
1148
837
 
1149
838
        g_return_if_fail (applet_info != NULL);
 
839
        g_return_if_fail (G_IS_OBJECT (applet_info->widget));
1150
840
 
1151
841
        if (!immediate) {
1152
842
                if (!queued_position_source)
1165
855
        if (!(toplevel_id = panel_applet_get_toplevel_id (applet_info)))
1166
856
                return;
1167
857
 
1168
 
        client  = panel_gconf_get_client ();
1169
 
 
1170
 
        key_type = applet_info->type == PANEL_OBJECT_APPLET ? PANEL_GCONF_APPLETS : PANEL_GCONF_OBJECTS;
1171
 
        
1172
858
        panel_widget = panel_applet_get_panel_widget (applet_info);
1173
859
 
1174
 
        /* FIXME: Instead of getting keys, comparing and setting, there
1175
 
           should be a dirty flag */
1176
 
 
1177
 
        key = panel_gconf_full_key (key_type, id, "toplevel_id");
1178
 
        old_toplevel_id = gconf_client_get_string (client, key, NULL);
1179
 
        if (old_toplevel_id == NULL || strcmp (old_toplevel_id, toplevel_id) != 0)
1180
 
                gconf_client_set_string (client, key, toplevel_id, NULL);
1181
 
        g_free (old_toplevel_id);
1182
 
 
1183
 
        /* Note: changing some properties of the panel that may not be locked down
1184
 
           (e.g. background) can change the state of the "panel_right_stick" and
1185
 
           "position" properties of an applet that may in fact be locked down.
1186
 
           So check if these are writable before attempting to write them */
1187
 
 
1188
 
        right_stick = panel_is_applet_right_stick (applet_info->widget) ? 1 : 0;
1189
 
        key = panel_gconf_full_key (
1190
 
                        key_type, id, "panel_right_stick");
1191
 
        if (gconf_client_key_is_writable (client, key, NULL) &&
1192
 
            (gconf_client_get_bool (client, key, NULL) ? 1 : 0) != right_stick)
1193
 
                gconf_client_set_bool (client, key, right_stick, NULL);
1194
 
 
1195
 
        position = panel_applet_get_position (applet_info);
1196
 
        if (right_stick && !panel_widget->packed)
1197
 
                position = panel_widget->size - position;
1198
 
 
1199
 
        key = panel_gconf_full_key (key_type, id, "position");
1200
 
        if (gconf_client_key_is_writable (client, key, NULL) &&
1201
 
            gconf_client_get_int (client, key, NULL) != position)
1202
 
                gconf_client_set_int (client, key, position, NULL);
1203
 
        
1204
 
        locked = panel_widget_get_applet_locked (panel_widget, applet_info->widget) ? 1 : 0;
1205
 
        key = panel_gconf_full_key (key_type, id, "locked");
1206
 
        if (gconf_client_get_bool (client, key, NULL) ? 1 : 0 != locked)
1207
 
                gconf_client_set_bool (client, key, locked, NULL);
 
860
        applet_data = g_object_get_data (G_OBJECT (applet_info->widget),
 
861
                                         PANEL_APPLET_DATA);
 
862
 
 
863
        g_settings_set_string (applet_info->settings,
 
864
                               PANEL_OBJECT_TOPLEVEL_ID_KEY,
 
865
                               toplevel_id);
 
866
        g_settings_set_enum (applet_info->settings,
 
867
                             PANEL_OBJECT_PACK_TYPE_KEY,
 
868
                             applet_data->pack_type);
 
869
        g_settings_set_int (applet_info->settings,
 
870
                            PANEL_OBJECT_PACK_INDEX_KEY,
 
871
                            applet_data->pack_index);
1208
872
}
1209
873
 
1210
874
const char *
1216
880
        return info->id;
1217
881
}
1218
882
 
1219
 
/** \brief  Get the Bonobo IID of the Applet
1220
 
        \param  info  The AppletInfo struct representing the applet
1221
 
        \return  Either the IID of the applet or NULL if the applet does
1222
 
                 not have an IID.
1223
 
*/
1224
 
const char *
1225
 
panel_applet_get_iid (AppletInfo *info)
1226
 
{
1227
 
        if (!info)
1228
 
                return NULL;
1229
 
        if (info->type != PANEL_OBJECT_APPLET)
1230
 
                return NULL;
1231
 
 
1232
 
        PanelAppletFrame * frame = PANEL_APPLET_FRAME(info->data);
1233
 
        if (frame == NULL)
1234
 
                return NULL;  /* This should never happen, but just in case */
1235
 
 
1236
 
        return panel_applet_frame_get_iid(frame);
1237
 
}
1238
 
 
1239
883
const char *
1240
884
panel_applet_get_id_by_widget (GtkWidget *applet_widget)
1241
885
{
1259
903
{
1260
904
        GSList *l;
1261
905
 
1262
 
        if (id == NULL)
1263
 
                return NULL;
1264
 
 
1265
906
        for (l = registered_applets; l; l = l->next) {
1266
907
                AppletInfo *info = l->data;
1267
908
 
1272
913
        return NULL;
1273
914
}
1274
915
 
1275
 
/** \brief  Will find an applet by looking for it's IID
1276
 
        \param  iid  The IID to look for in an applet
1277
 
        \return Either the AppletInfo structure representing the applet or
1278
 
                NULL if an applet with that IID can not be found.
1279
 
*/
1280
 
AppletInfo *
1281
 
panel_applet_get_by_iid (const char *iid)
1282
 
{
1283
 
        GSList *l;
1284
 
 
1285
 
        if (iid == NULL)
1286
 
                return NULL;
1287
 
 
1288
 
        for (l = registered_applets; l; l = l->next) {
1289
 
                AppletInfo *info = l->data;
1290
 
                const char *applet_iid = panel_applet_get_iid(info);
1291
 
 
1292
 
                if (applet_iid == NULL)
1293
 
                        continue;
1294
 
 
1295
 
                if (!strcmp (applet_iid, iid))
1296
 
                        return info;
1297
 
        }
1298
 
 
1299
 
        return NULL;
1300
 
}
1301
 
 
1302
916
GSList *
1303
917
panel_applet_list_applets (void)
1304
918
{
1327
941
 
1328
942
AppletInfo *
1329
943
panel_applet_register (GtkWidget       *applet,
1330
 
                       gpointer         data,
1331
 
                       GDestroyNotify   data_destroy,
1332
944
                       PanelWidget     *panel,
1333
 
                       gboolean         locked,
1334
 
                       gint             pos,
1335
 
                       gboolean         exactpos,
1336
945
                       PanelObjectType  type,
1337
 
                       const char      *id)
 
946
                       const char      *id,
 
947
                       GSettings       *settings,
 
948
                       gpointer         data,
 
949
                       GDestroyNotify   data_destroy)
1338
950
{
1339
 
        AppletInfo *info;
1340
 
        const char *key;
 
951
        AppletInfo          *info;
 
952
        PanelObjectPackType  pack_type;
 
953
        int                  pack_index;
1341
954
        
1342
955
        g_return_val_if_fail (applet != NULL && panel != NULL, NULL);
1343
956
 
1350
963
        info = g_new0 (AppletInfo, 1);
1351
964
        info->type         = type;
1352
965
        info->widget       = applet;
 
966
        info->settings     = g_object_ref (settings);
1353
967
        info->menu         = NULL;
 
968
        info->edit_menu    = NULL;
1354
969
        info->data         = data;
1355
970
        info->data_destroy = data_destroy;
1356
971
        info->user_menu    = NULL;
1357
 
        info->move_item    = NULL;
1358
972
        info->id           = g_strdup (id);
1359
973
 
1360
974
        g_object_set_data (G_OBJECT (applet), "applet_info", info);
1361
975
 
1362
 
        if (type != PANEL_OBJECT_APPLET)
1363
 
                panel_lockdown_notify_add (G_CALLBACK (panel_applet_recreate_menu),
1364
 
                                           info);
1365
 
 
1366
 
        key = panel_gconf_full_key ((type == PANEL_OBJECT_APPLET) ?
1367
 
                                     PANEL_GCONF_APPLETS : PANEL_GCONF_OBJECTS,
1368
 
                                    id, "locked");
1369
 
        panel_gconf_notify_add_while_alive (key,
1370
 
                                            (GConfClientNotifyFunc) panel_applet_locked_change_notify,
1371
 
                                            G_OBJECT (applet));
1372
 
 
1373
 
        if (type == PANEL_OBJECT_DRAWER) {
1374
 
                Drawer *drawer = data;
1375
 
                PanelWidget *assoc_panel;
1376
 
 
1377
 
                assoc_panel = panel_toplevel_get_panel_widget (drawer->toplevel);
1378
 
 
1379
 
                g_object_set_data (G_OBJECT (applet),
1380
 
                                   PANEL_APPLET_ASSOC_PANEL_KEY, assoc_panel);
1381
 
                assoc_panel->master_widget = applet;
1382
 
                g_object_add_weak_pointer (
1383
 
                        G_OBJECT (applet), (gpointer *) &assoc_panel->master_widget);
1384
 
        }
1385
 
 
1386
 
        g_object_set_data (G_OBJECT (applet),
1387
 
                           PANEL_APPLET_FORBIDDEN_PANELS, NULL);
1388
 
 
1389
976
        registered_applets = g_slist_append (registered_applets, info);
1390
977
 
1391
 
        if (panel_widget_add (panel, applet, locked, pos, exactpos) == -1 &&
1392
 
            panel_widget_add (panel, applet, locked, 0, TRUE) == -1) {
1393
 
                GSList *l;
1394
 
 
1395
 
                for (l = panels; l; l = l->next) {
1396
 
                        panel = PANEL_WIDGET (l->data);
1397
 
 
1398
 
                        if (panel_widget_add (panel, applet, locked, 0, TRUE) != -1)
1399
 
                                break;
1400
 
                }
1401
 
 
1402
 
                if (!l) {
1403
 
                        g_warning (_("Cannot find an empty spot"));
1404
 
                        panel_profile_delete_object (info);
1405
 
                        return NULL;
1406
 
                }
1407
 
        }
 
978
        /* Find where to insert the applet */
 
979
        pack_type = g_settings_get_enum (info->settings, PANEL_OBJECT_PACK_TYPE_KEY);
 
980
        pack_index = g_settings_get_int (info->settings, PANEL_OBJECT_PACK_INDEX_KEY);
 
981
 
 
982
        /* Insert it */
 
983
        panel_widget_add (panel, applet, pack_type, pack_index, TRUE);
1408
984
 
1409
985
        if (BUTTON_IS_WIDGET (applet) ||
1410
986
            gtk_widget_get_has_window (applet)) {
1412
988
                                  G_CALLBACK (applet_button_press),
1413
989
                                  info);
1414
990
 
1415
 
                g_signal_connect (applet, "popup_menu",
1416
 
                                  G_CALLBACK (applet_popup_menu),
 
991
                g_signal_connect (applet, "key_press_event",
 
992
                                  G_CALLBACK (applet_key_press),
1417
993
                                  info);
1418
994
        }
1419
995
 
1421
997
                          G_CALLBACK (panel_applet_destroy),
1422
998
                          info);
1423
999
 
1424
 
        panel_applet_set_dnd_enabled (info, !locked);
 
1000
        panel_applet_set_dnd_enabled (info, TRUE);
1425
1001
 
1426
 
        gtk_widget_show_all (applet);
 
1002
        gtk_widget_show (applet);
1427
1003
 
1428
1004
        orientation_change (info, panel);
1429
1005
        size_change (info, panel);
1434
1010
        else
1435
1011
                gtk_widget_child_focus (applet, GTK_DIR_TAB_FORWARD);
1436
1012
 
1437
 
        panel_applet_signaler_add_applet(info);
1438
1013
        return info;
1439
1014
}
1440
1015
 
1441
 
int
1442
 
panel_applet_get_position (AppletInfo *applet)
 
1016
GSettings *
 
1017
panel_applet_get_settings (AppletInfo *applet)
1443
1018
{
1444
 
        AppletData *applet_data;
1445
 
 
1446
 
        g_return_val_if_fail (applet != NULL, 0);
1447
 
        g_return_val_if_fail (G_IS_OBJECT (applet->widget), 0);
1448
 
 
1449
 
        applet_data = g_object_get_data (G_OBJECT (applet->widget), PANEL_APPLET_DATA);
1450
 
 
1451
 
        return applet_data->pos;
 
1019
        g_return_val_if_fail (applet != NULL, NULL);
 
1020
 
 
1021
        return applet->settings;
1452
1022
}
1453
1023
 
1454
1024
gboolean
1455
1025
panel_applet_can_freely_move (AppletInfo *applet)
1456
1026
{
1457
 
        GConfClient       *client;
1458
 
        PanelGConfKeyType  key_type;
1459
 
        const char        *key;
1460
 
 
1461
 
        if (panel_lockdown_get_locked_down ())
1462
 
                return FALSE;
1463
 
 
1464
 
        client  = panel_gconf_get_client ();
1465
 
        
1466
 
        key_type = (applet->type == PANEL_OBJECT_APPLET) ? PANEL_GCONF_APPLETS : PANEL_GCONF_OBJECTS;
1467
 
       
1468
 
        key = panel_gconf_full_key (key_type, applet->id, "position");
1469
 
        if (!gconf_client_key_is_writable (client, key, NULL))
1470
 
                return FALSE;
1471
 
 
1472
 
        key = panel_gconf_full_key (key_type, applet->id, "toplevel_id");
1473
 
        if (!gconf_client_key_is_writable (client, key, NULL))
1474
 
                return FALSE;
1475
 
 
1476
 
        key = panel_gconf_full_key (key_type, applet->id, "panel_right_stick");
1477
 
        if (!gconf_client_key_is_writable (client, key, NULL))
1478
 
                return FALSE;
1479
 
 
1480
 
        return TRUE;
1481
 
}
1482
 
 
1483
 
gboolean
1484
 
panel_applet_lockable (AppletInfo *applet)
1485
 
{
1486
 
        GConfClient        *client;
1487
 
        PanelGConfKeyType   key_type;
1488
 
        const char         *key;
1489
 
 
1490
 
        if (panel_lockdown_get_locked_down ())
1491
 
                return FALSE;
1492
 
        
1493
 
        client  = panel_gconf_get_client ();
1494
 
        
1495
 
        key_type = (applet->type == PANEL_OBJECT_APPLET) ? PANEL_GCONF_APPLETS : PANEL_GCONF_OBJECTS;
1496
 
 
1497
 
        key = panel_gconf_full_key (key_type, applet->id, "locked");
1498
 
 
1499
 
        return gconf_client_key_is_writable (client, key, NULL);
 
1027
        /* if we check for more lockdown than this, then we'll need to update
 
1028
         * callers that use panel_lockdown_on_notify() */
 
1029
        if (panel_lockdown_get_panels_locked_down_s ())
 
1030
                return FALSE;
 
1031
 
 
1032
        return (g_settings_is_writable (applet->settings,
 
1033
                                        PANEL_OBJECT_TOPLEVEL_ID_KEY) &&
 
1034
                g_settings_is_writable (applet->settings,
 
1035
                                        PANEL_OBJECT_PACK_TYPE_KEY) &&
 
1036
                g_settings_is_writable (applet->settings,
 
1037
                                        PANEL_OBJECT_PACK_INDEX_KEY));
1500
1038
}