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

« back to all changes in this revision

Viewing changes to gnome-panel/panel-widget.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:
11
11
 
12
12
#include <gdk/gdkkeysyms.h>
13
13
#include <gtk/gtk.h>
 
14
#include <gtk/gtkx.h>
14
15
 
15
16
#include <libpanel-util/panel-list.h>
16
17
 
18
19
#include "panel-widget.h"
19
20
#include "button-widget.h"
20
21
#include "panel.h"
 
22
#include "panel-bindings.h"
21
23
#include "panel-util.h"
22
24
#include "panel-marshal.h"
23
25
#include "panel-typebuiltins.h"
24
26
#include "panel-applet-frame.h"
25
27
#include "panel-globals.h"
26
 
#include "panel-profile.h"
27
28
#include "panel-lockdown.h"
28
29
 
29
 
#define MOVE_INCREMENT 1
30
 
 
31
30
typedef enum {
32
31
        PANEL_SWITCH_MOVE = 0,
33
 
        PANEL_FREE_MOVE,
34
32
        PANEL_PUSH_MOVE
35
33
} PanelMovementType;
36
34
 
44
42
        APPLET_REMOVED_SIGNAL,
45
43
        PUSH_MOVE_SIGNAL,
46
44
        SWITCH_MOVE_SIGNAL,
47
 
        FREE_MOVE_SIGNAL,
48
45
        TAB_MOVE_SIGNAL,
49
46
        END_MOVE_SIGNAL,
50
47
        POPUP_PANEL_MENU_SIGNAL,
59
56
static gboolean panel_applet_in_drag = FALSE;
60
57
static GtkWidget *saved_focus_widget = NULL;
61
58
 
62
 
static void panel_widget_size_request   (GtkWidget        *widget,
63
 
                                         GtkRequisition   *requisition);
64
 
static void panel_widget_size_allocate  (GtkWidget        *widget,
65
 
                                         GtkAllocation    *allocation);
66
 
static void panel_widget_cadd           (GtkContainer     *container,
67
 
                                         GtkWidget        *widget);
68
 
static void panel_widget_cremove        (GtkContainer     *container,
69
 
                                         GtkWidget        *widget);
70
 
static void panel_widget_destroy        (GtkObject        *obj);
71
 
static void panel_widget_finalize       (GObject          *obj);
72
 
static void panel_widget_realize        (GtkWidget        *widget);
73
 
static void panel_widget_unrealize      (GtkWidget        *panel);
74
 
static void panel_widget_state_changed  (GtkWidget        *widget,
75
 
                                         GtkStateType      previous_state);
76
 
static void panel_widget_style_set      (GtkWidget        *widget,
77
 
                                         GtkStyle         *previous_style);
 
59
static void panel_widget_get_preferred_width  (GtkWidget        *widget,
 
60
                                               gint             *minimal_width,
 
61
                                               gint             *natural_width);
 
62
static void panel_widget_get_preferred_height (GtkWidget        *widget,
 
63
                                               gint             *minimal_height,
 
64
                                               gint             *natural_height);
 
65
static void panel_widget_size_allocate        (GtkWidget        *widget,
 
66
                                               GtkAllocation    *allocation);
 
67
static void panel_widget_cadd                 (GtkContainer     *container,
 
68
                                               GtkWidget        *widget);
 
69
static void panel_widget_cremove              (GtkContainer     *container,
 
70
                                               GtkWidget        *widget);
 
71
static void panel_widget_dispose              (GObject          *obj);
 
72
static void panel_widget_finalize             (GObject          *obj);
 
73
static void panel_widget_realize              (GtkWidget        *widget);
 
74
static void panel_widget_unrealize            (GtkWidget        *panel);
 
75
static void panel_widget_state_flags_changed  (GtkWidget        *widget,
 
76
                                               GtkStateFlags     previous_state);
 
77
static void panel_widget_style_updated        (GtkWidget        *widget);
78
78
 
79
79
static void panel_widget_background_changed (PanelBackground *background,
80
80
                                             PanelWidget     *panel);
83
83
                                             GtkDirectionType  dir);
84
84
static void panel_widget_switch_move_applet (PanelWidget      *panel,
85
85
                                             GtkDirectionType  dir);
86
 
static void panel_widget_free_move_applet   (PanelWidget      *panel,
87
 
                                             GtkDirectionType  dir);
88
86
static void panel_widget_tab_move           (PanelWidget      *panel,
89
87
                                             gboolean          next);
90
88
static void panel_widget_end_move           (PanelWidget      *panel);
91
89
static gboolean panel_widget_real_focus     (GtkWidget        *widget,
92
90
                                             GtkDirectionType  direction);
93
91
 
94
 
static gboolean panel_widget_push_applet_right (PanelWidget *panel,
95
 
                                                GList       *list,
96
 
                                                int          push);
97
 
static gboolean panel_widget_push_applet_left  (PanelWidget *panel,
98
 
                                                GList       *list,
99
 
                                                int          push);
 
92
static void panel_widget_update_positions   (PanelWidget      *panel);
100
93
 
101
94
/************************
102
95
 convenience functions
104
97
static int
105
98
applet_data_compare (AppletData *ad1, AppletData *ad2)
106
99
{
107
 
        return ad1->pos - ad2->pos;
 
100
        if (ad1->pack_type != ad2->pack_type)
 
101
                return ad1->pack_type - ad2->pack_type; /* start < center < end */
 
102
        else if (ad1->pack_type != PANEL_OBJECT_PACK_END)
 
103
                return ad1->pack_index - ad2->pack_index;
 
104
        else
 
105
                return ad2->pack_index - ad1->pack_index;
108
106
}
109
107
 
110
108
static void
111
109
emit_applet_moved (PanelWidget *panel_widget,
112
110
                   AppletData  *applet)
113
111
{
 
112
        /* we always want to queue a draw after moving, so do it here instead
 
113
         * of after the signal emission in all callers */
 
114
        gtk_widget_queue_draw (applet->applet);
 
115
 
114
116
        g_signal_emit (panel_widget,
115
117
                       panel_widget_signals [APPLET_MOVE_SIGNAL], 0,
116
118
                       applet->applet);
125
127
                  GdkModifierType   modifiers,
126
128
                  gboolean          next)
127
129
{
128
 
        gtk_binding_entry_add_signal (binding_set, GDK_Tab, modifiers,
 
130
        gtk_binding_entry_add_signal (binding_set, GDK_KEY_Tab, modifiers,
129
131
                                      "tab_move", 1,
130
132
                                      G_TYPE_BOOLEAN, next);
131
 
        gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, modifiers,
 
133
        gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Tab, modifiers,
132
134
                                      "tab_move", 1,
133
135
                                      G_TYPE_BOOLEAN, next);
134
136
}
138
140
                   GdkModifierType   modifiers,
139
141
                   const gchar      *name)
140
142
{
141
 
        gtk_binding_entry_add_signal (binding_set, GDK_Up, modifiers,
 
143
        gtk_binding_entry_add_signal (binding_set, GDK_KEY_Up, modifiers,
142
144
                                      name, 1,
143
145
                                      GTK_TYPE_DIRECTION_TYPE, GTK_DIR_UP);
144
 
        gtk_binding_entry_add_signal (binding_set, GDK_Down, modifiers,
 
146
        gtk_binding_entry_add_signal (binding_set, GDK_KEY_Down, modifiers,
145
147
                                      name, 1,
146
148
                                      GTK_TYPE_DIRECTION_TYPE, GTK_DIR_DOWN);
147
 
        gtk_binding_entry_add_signal (binding_set, GDK_Left, modifiers,
 
149
        gtk_binding_entry_add_signal (binding_set, GDK_KEY_Left, modifiers,
148
150
                                      name, 1,
149
151
                                      GTK_TYPE_DIRECTION_TYPE, GTK_DIR_LEFT);
150
 
        gtk_binding_entry_add_signal (binding_set, GDK_Right, modifiers,
 
152
        gtk_binding_entry_add_signal (binding_set, GDK_KEY_Right, modifiers,
151
153
                                      name, 1,
152
154
                                      GTK_TYPE_DIRECTION_TYPE, GTK_DIR_RIGHT);
153
155
}
165
167
 
166
168
        add_move_bindings (binding_set, GDK_SHIFT_MASK, "push_move");
167
169
        add_move_bindings (binding_set, GDK_CONTROL_MASK, "switch_move");
168
 
        add_move_bindings (binding_set, GDK_MOD1_MASK, "free_move");
169
 
        add_move_bindings (binding_set, 0, "free_move");
170
170
 
171
171
        add_tab_bindings (binding_set, 0, TRUE);
172
172
        add_tab_bindings (binding_set, GDK_SHIFT_MASK, FALSE);
173
173
 
174
174
        gtk_binding_entry_add_signal (binding_set,
175
 
                                      GDK_Escape, 0,
176
 
                                      "end_move", 0);
177
 
        gtk_binding_entry_add_signal (binding_set,
178
 
                                      GDK_KP_Enter, 0,
179
 
                                      "end_move", 0);
180
 
        gtk_binding_entry_add_signal (binding_set,
181
 
                                      GDK_Return, 0,
182
 
                                      "end_move", 0);
183
 
        gtk_binding_entry_add_signal (binding_set,
184
 
                                      GDK_KP_Space, 0,
185
 
                                      "end_move", 0);
186
 
        gtk_binding_entry_add_signal (binding_set,
187
 
                                      GDK_space, 0,
 
175
                                      GDK_KEY_Escape, 0,
 
176
                                      "end_move", 0);
 
177
        gtk_binding_entry_add_signal (binding_set,
 
178
                                      GDK_KEY_KP_Enter, 0,
 
179
                                      "end_move", 0);
 
180
        gtk_binding_entry_add_signal (binding_set,
 
181
                                      GDK_KEY_Return, 0,
 
182
                                      "end_move", 0);
 
183
        gtk_binding_entry_add_signal (binding_set,
 
184
                                      GDK_KEY_KP_Space, 0,
 
185
                                      "end_move", 0);
 
186
        gtk_binding_entry_add_signal (binding_set,
 
187
                                      GDK_KEY_space, 0,
188
188
                                      "end_move", 0);
189
189
 
190
190
        focus_widget = gtk_window_get_focus (GTK_WINDOW (panel->toplevel));
231
231
                     GdkModifierType   modifiers,
232
232
                     gboolean          next)
233
233
{
234
 
        gtk_binding_entry_remove (binding_set, GDK_Tab, modifiers);
235
 
        gtk_binding_entry_remove (binding_set, GDK_KP_Tab, modifiers);
 
234
        gtk_binding_entry_remove (binding_set, GDK_KEY_Tab, modifiers);
 
235
        gtk_binding_entry_remove (binding_set, GDK_KEY_KP_Tab, modifiers);
236
236
}
237
237
 
238
238
static void
239
239
remove_move_bindings (GtkBindingSet    *binding_set,
240
240
                      GdkModifierType   modifiers)
241
241
{
242
 
        gtk_binding_entry_remove (binding_set, GDK_Up, modifiers);
243
 
        gtk_binding_entry_remove (binding_set, GDK_Down, modifiers);
244
 
        gtk_binding_entry_remove (binding_set, GDK_Left, modifiers);
245
 
        gtk_binding_entry_remove (binding_set, GDK_Right, modifiers);
 
242
        gtk_binding_entry_remove (binding_set, GDK_KEY_Up, modifiers);
 
243
        gtk_binding_entry_remove (binding_set, GDK_KEY_Down, modifiers);
 
244
        gtk_binding_entry_remove (binding_set, GDK_KEY_Left, modifiers);
 
245
        gtk_binding_entry_remove (binding_set, GDK_KEY_Right, modifiers);
246
246
}
247
247
 
248
248
static void
264
264
        remove_tab_bindings (binding_set, 0, TRUE);
265
265
        remove_tab_bindings (binding_set, GDK_SHIFT_MASK, FALSE);
266
266
 
267
 
        gtk_binding_entry_remove (binding_set, GDK_Escape, 0);
268
 
        gtk_binding_entry_remove (binding_set, GDK_KP_Enter, 0);
269
 
        gtk_binding_entry_remove (binding_set, GDK_Return, 0);
270
 
        gtk_binding_entry_remove (binding_set, GDK_KP_Space, 0);
271
 
        gtk_binding_entry_remove (binding_set, GDK_space, 0);
 
267
        gtk_binding_entry_remove (binding_set, GDK_KEY_Escape, 0);
 
268
        gtk_binding_entry_remove (binding_set, GDK_KEY_KP_Enter, 0);
 
269
        gtk_binding_entry_remove (binding_set, GDK_KEY_Return, 0);
 
270
        gtk_binding_entry_remove (binding_set, GDK_KEY_KP_Space, 0);
 
271
        gtk_binding_entry_remove (binding_set, GDK_KEY_space, 0);
272
272
}
273
273
 
274
274
static void
275
275
panel_widget_class_init (PanelWidgetClass *class)
276
276
{
277
 
        GtkObjectClass *object_class = (GtkObjectClass*) class;
278
 
        GObjectClass *gobject_class = (GObjectClass*) class;
 
277
        GObjectClass *object_class = (GObjectClass*) class;
279
278
        GtkWidgetClass *widget_class = (GtkWidgetClass*) class;
280
279
        GtkContainerClass *container_class = (GtkContainerClass*) class;
281
280
 
361
360
                              1,
362
361
                              GTK_TYPE_DIRECTION_TYPE);
363
362
 
364
 
        panel_widget_signals[FREE_MOVE_SIGNAL] =
365
 
                g_signal_new ("free_move",
366
 
                              G_TYPE_FROM_CLASS (class),
367
 
                              G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
368
 
                              G_STRUCT_OFFSET (PanelWidgetClass, free_move),
369
 
                              NULL,
370
 
                              NULL,
371
 
                              g_cclosure_marshal_VOID__ENUM,
372
 
                              G_TYPE_NONE,
373
 
                              1,
374
 
                              GTK_TYPE_DIRECTION_TYPE);
375
 
 
376
363
        panel_widget_signals[TAB_MOVE_SIGNAL] =
377
364
                g_signal_new ("tab_move",
378
365
                              G_TYPE_FROM_CLASS (class),
403
390
        class->applet_removed = NULL;
404
391
        class->push_move = panel_widget_push_move_applet;
405
392
        class->switch_move = panel_widget_switch_move_applet;
406
 
        class->free_move = panel_widget_free_move_applet;
407
393
        class->tab_move = panel_widget_tab_move;
408
394
        class->end_move = panel_widget_end_move;
409
395
 
410
 
        object_class->destroy = panel_widget_destroy;
411
 
        gobject_class->finalize = panel_widget_finalize;
 
396
        object_class->dispose = panel_widget_dispose;
 
397
        object_class->finalize = panel_widget_finalize;
412
398
        
413
 
        widget_class->size_request = panel_widget_size_request;
 
399
        widget_class->get_preferred_width = panel_widget_get_preferred_width;
 
400
        widget_class->get_preferred_height = panel_widget_get_preferred_height;
414
401
        widget_class->size_allocate = panel_widget_size_allocate;
415
402
        widget_class->realize = panel_widget_realize;
416
403
        widget_class->unrealize = panel_widget_unrealize;
417
404
        widget_class->focus = panel_widget_real_focus;
418
 
        widget_class->state_changed = panel_widget_state_changed;
419
 
        widget_class->style_set = panel_widget_style_set;
 
405
        widget_class->state_flags_changed = panel_widget_state_flags_changed;
 
406
        widget_class->style_updated = panel_widget_style_updated;
420
407
 
421
408
        container_class->add = panel_widget_cadd;
422
409
        container_class->remove = panel_widget_cremove;
423
410
}
424
411
 
425
412
static void
426
 
remove_panel_from_forbidden(PanelWidget *panel, PanelWidget *r)
427
 
{
428
 
        GSList *list;
429
 
        GtkWidget *parent_panel;
430
 
        
431
 
        g_return_if_fail(PANEL_IS_WIDGET(panel));
432
 
        g_return_if_fail(PANEL_IS_WIDGET(r));
433
 
 
434
 
        if(!panel->master_widget)
435
 
                return;
436
 
 
437
 
        list = g_object_get_data (G_OBJECT(panel->master_widget),
438
 
                                  PANEL_APPLET_FORBIDDEN_PANELS);
439
 
        if(list) {
440
 
                list = g_slist_remove(list,r);
441
 
                g_object_set_data (G_OBJECT(panel->master_widget),
442
 
                                   PANEL_APPLET_FORBIDDEN_PANELS,
443
 
                                   list);
444
 
        }
445
 
        parent_panel = gtk_widget_get_parent (panel->master_widget);
446
 
        if (parent_panel)
447
 
                remove_panel_from_forbidden(PANEL_WIDGET(parent_panel), r);
448
 
}
449
 
 
450
 
static void
451
 
add_panel_to_forbidden(PanelWidget *panel, PanelWidget *r)
452
 
{
453
 
        GSList *list;
454
 
        GtkWidget *parent_panel;
455
 
 
456
 
        g_return_if_fail(PANEL_IS_WIDGET(panel));
457
 
        g_return_if_fail(PANEL_IS_WIDGET(r));
458
 
 
459
 
        if(!panel->master_widget)
460
 
                return;
461
 
 
462
 
        list = g_object_get_data (G_OBJECT(panel->master_widget),
463
 
                                  PANEL_APPLET_FORBIDDEN_PANELS);
464
 
        if(g_slist_find(list,r)==NULL) {
465
 
                list = g_slist_prepend(list,r);
466
 
 
467
 
                g_object_set_data (G_OBJECT(panel->master_widget),
468
 
                                   PANEL_APPLET_FORBIDDEN_PANELS,
469
 
                                   list);
470
 
        }
471
 
        parent_panel = gtk_widget_get_parent (panel->master_widget);
472
 
        if (parent_panel)
473
 
                add_panel_to_forbidden(PANEL_WIDGET(parent_panel), r);
474
 
}
475
 
 
476
 
static void
477
 
run_up_forbidden(PanelWidget *panel,
478
 
                 void (*runfunc)(PanelWidget *,PanelWidget *))
479
 
{
480
 
        GList *list;
481
 
 
482
 
        g_return_if_fail(PANEL_IS_WIDGET(panel));
483
 
 
484
 
        for(list = panel->applet_list;list!=NULL;list = g_list_next(list)) {
485
 
                AppletData *ad = list->data;
486
 
                PanelWidget *p =
487
 
                        g_object_get_data (G_OBJECT(ad->applet),
488
 
                                           PANEL_APPLET_ASSOC_PANEL_KEY);
489
 
                if(p)
490
 
                        run_up_forbidden(p,runfunc);
491
 
        }
492
 
        (*runfunc)(panel,panel);
493
 
}
494
 
 
495
 
static void
496
413
panel_widget_reset_focus (GtkContainer *container,
497
414
                          GtkWidget    *widget)
498
415
{
537
454
panel_widget_cadd (GtkContainer *container,
538
455
                   GtkWidget    *widget)
539
456
{
540
 
        PanelWidget *p;
541
 
 
542
457
        g_return_if_fail (PANEL_IS_WIDGET (container));
543
458
        g_return_if_fail (GTK_IS_WIDGET (widget));
544
459
 
545
 
        panel_widget_add (PANEL_WIDGET (container), widget, FALSE, 0, FALSE);
546
 
 
547
 
        p = g_object_get_data (G_OBJECT(widget),
548
 
                               PANEL_APPLET_ASSOC_PANEL_KEY);
549
 
        if (p) {
550
 
                panel_toplevel_attach_to_widget (p->toplevel,
551
 
                                                 PANEL_WIDGET (container)->toplevel,
552
 
                                                 widget);
553
 
                run_up_forbidden (p, add_panel_to_forbidden);
554
 
        }
 
460
        panel_widget_add (PANEL_WIDGET (container), widget,
 
461
                          PANEL_OBJECT_PACK_START, 0, FALSE);
555
462
}
556
463
 
557
464
static void
558
465
panel_widget_cremove (GtkContainer *container, GtkWidget *widget)
559
466
{
560
467
        AppletData *ad;
561
 
        PanelWidget *p;
562
468
        PanelWidget *panel;
563
469
 
564
470
        g_return_if_fail (PANEL_IS_WIDGET (container));
567
473
        panel = PANEL_WIDGET (container);
568
474
        
569
475
        ad = g_object_get_data (G_OBJECT (widget), PANEL_APPLET_DATA);
570
 
        p = g_object_get_data (G_OBJECT (widget),
571
 
                                 PANEL_APPLET_ASSOC_PANEL_KEY);
572
 
 
573
 
        if (p != NULL) {
574
 
                panel_toplevel_detach (p->toplevel);
575
 
                run_up_forbidden (p, remove_panel_from_forbidden);
576
 
        }
577
476
 
578
477
        panel_widget_reset_focus (container, widget);
579
478
 
587
486
        if (ad)
588
487
                panel->applet_list = g_list_remove (panel->applet_list, ad);
589
488
 
 
489
        panel_widget_update_positions (panel);
 
490
 
590
491
        g_signal_emit (G_OBJECT (container),
591
492
                       panel_widget_signals[APPLET_REMOVED_SIGNAL],
592
493
                       0, widget);
594
495
}
595
496
 
596
497
 
597
 
/*get the list item of the data on the position pos*/
 
498
/* data should be freed with g_list_free() */
598
499
static GList *
599
 
get_applet_list_pos (PanelWidget *panel,
600
 
                     int          pos)
 
500
get_applet_list_pack (PanelWidget         *panel,
 
501
                      PanelObjectPackType  pack_type)
601
502
{
 
503
        GList *ret;
602
504
        GList *l;
 
505
        GList *prev;
603
506
 
604
507
        g_return_val_if_fail (PANEL_IS_WIDGET (panel), NULL);
605
 
        
 
508
 
606
509
        for (l = panel->applet_list; l; l = l->next) {
607
510
                AppletData *ad = l->data;
608
511
 
609
 
                if (ad->pos <= pos) {
610
 
                       if (ad->pos + ad->cells > pos)
611
 
                               return l;
612
 
                } else
613
 
                        return NULL;
614
 
        }
615
 
 
616
 
        return NULL;
617
 
}
618
 
 
619
 
/*tells us if an applet is "stuck" on the right side*/
620
 
int
621
 
panel_widget_is_applet_stuck (PanelWidget *panel_widget,
622
 
                              GtkWidget   *widget)
623
 
{
624
 
        AppletData *applet;
625
 
 
626
 
        g_return_val_if_fail (PANEL_IS_WIDGET (panel_widget), FALSE);
627
 
        g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
628
 
 
629
 
        applet = g_object_get_data (G_OBJECT (widget), PANEL_APPLET_DATA);
630
 
        if (applet) {
631
 
                GList *applet_list, *l;
632
 
                int    end_pos = -1;
633
 
        
634
 
                applet_list = g_list_find (panel_widget->applet_list, applet);
635
 
 
636
 
                for (l = applet_list; l; l = l->next) {
637
 
                        applet = l->data;
638
 
 
639
 
                        if (end_pos != -1 && applet->pos != end_pos)
640
 
                                break;
641
 
 
642
 
                        end_pos = applet->pos + applet->cells;
643
 
                        if (end_pos >= panel_widget->size)
644
 
                                return TRUE;
645
 
                }
646
 
        }
647
 
 
648
 
        return FALSE;
 
512
                if (ad->pack_type == pack_type)
 
513
                        break;
 
514
        }
 
515
 
 
516
        if (!l)
 
517
                return NULL;
 
518
 
 
519
        ret = g_list_copy (l);
 
520
        for (l = ret; l; l = l->next) {
 
521
                AppletData *ad = l->data;
 
522
                if (ad->pack_type != pack_type)
 
523
                        break;
 
524
        }
 
525
 
 
526
        if (!l)
 
527
                return ret;
 
528
 
 
529
        prev = l->prev;
 
530
        if (prev)
 
531
                prev->next = NULL;
 
532
        g_list_free (l);
 
533
 
 
534
        return ret;
649
535
}
650
536
 
651
537
static int
670
556
}
671
557
 
672
558
static void
673
 
panel_widget_jump_applet_right (PanelWidget *panel,
674
 
                                GList       *list,
675
 
                                GList       *next,
676
 
                                int          pos)
677
 
{
678
 
        AppletData *ad;
679
 
        AppletData *nad = NULL;
680
 
 
681
 
        ad = list->data;
682
 
        if (next)
683
 
                nad = next->data;
684
 
 
685
 
        if (pos >= panel->size)
686
 
                return;
687
 
 
688
 
        if (!nad || nad->constrained >= pos + ad->min_cells)
689
 
                goto jump_right;
690
 
 
691
 
        if (!panel_widget_push_applet_right (panel, next, pos + ad->min_cells - nad->constrained)) {
692
 
                panel_widget_jump_applet_right (panel,
693
 
                                                list,
694
 
                                                next->next,
695
 
                                                nad->constrained + nad->min_cells);
696
 
                return;
697
 
        }
698
 
 
699
 
 jump_right:
700
 
        ad->pos = ad->constrained = pos;
701
 
        panel->applet_list = g_list_remove_link (panel->applet_list, list);
702
 
        panel->applet_list = panel_g_list_insert_before (panel->applet_list, next, list);
703
 
        gtk_widget_queue_resize (GTK_WIDGET (panel));
704
 
        emit_applet_moved (panel, ad);
705
 
}
706
 
 
707
 
static void
 
559
panel_widget_compress_pack_indexes_list (PanelWidget *panel,
 
560
                                         GList       *list)
 
561
{
 
562
        GList *l;
 
563
        AppletData *ad;
 
564
        int index;
 
565
 
 
566
        for (l = list, index = 0; l; l = l->next, index++) {
 
567
                ad = l->data;
 
568
                if (ad->pack_index != index) {
 
569
                        ad->pack_index = index;
 
570
                        emit_applet_moved (panel, ad);
 
571
                }
 
572
        }
 
573
}
 
574
 
 
575
/* make sure our lists always start at 0 */
 
576
static void
 
577
panel_widget_compress_pack_indexes (PanelWidget *panel)
 
578
{
 
579
        GList *list;
 
580
 
 
581
        list = get_applet_list_pack (panel, PANEL_OBJECT_PACK_START);
 
582
        panel_widget_compress_pack_indexes_list (panel, list);
 
583
        g_list_free (list);
 
584
 
 
585
        list = get_applet_list_pack (panel, PANEL_OBJECT_PACK_CENTER);
 
586
        panel_widget_compress_pack_indexes_list (panel, list);
 
587
        g_list_free (list);
 
588
 
 
589
        list = get_applet_list_pack (panel, PANEL_OBJECT_PACK_END);
 
590
        list = g_list_reverse (list);
 
591
        panel_widget_compress_pack_indexes_list (panel, list);
 
592
        g_list_free (list);
 
593
}
 
594
 
 
595
static void
 
596
panel_widget_update_size_hints_for_toplevel (PanelWidget *panel)
 
597
{
 
598
        GList *list;
 
599
        GList *ad_with_hints = NULL;
 
600
 
 
601
        panel->nb_applets_size_hints = 0;
 
602
        if (panel->applets_hints != NULL)
 
603
                g_free (panel->applets_hints);
 
604
        panel->applets_hints = NULL;
 
605
        if (panel->applets_using_hint != NULL)
 
606
                g_free (panel->applets_using_hint);
 
607
        panel->applets_using_hint = NULL;
 
608
 
 
609
        if (!panel->packed)
 
610
                return;
 
611
 
 
612
        for (list = panel->applet_list; list; list = list->next) {
 
613
                AppletData *ad = list->data;
 
614
                if (ad->expand_major && ad->size_hints)
 
615
                        ad_with_hints = g_list_prepend (ad_with_hints, ad);
 
616
        }
 
617
 
 
618
        /* put the list in the correct order: this is important
 
619
         * since we'll use this order in the size_allocate() */
 
620
        ad_with_hints = g_list_reverse (ad_with_hints);
 
621
 
 
622
        panel->nb_applets_size_hints = g_list_length (ad_with_hints);
 
623
 
 
624
        if (panel->nb_applets_size_hints > 0) {
 
625
                int i;
 
626
                panel->applets_hints = g_new0 (AppletSizeHints,
 
627
                                               panel->nb_applets_size_hints);
 
628
                panel->applets_using_hint = g_new0 (AppletSizeHintsAlloc,
 
629
                                                    panel->nb_applets_size_hints);
 
630
 
 
631
                i = 0;
 
632
                for (list = ad_with_hints;
 
633
                     list != NULL;
 
634
                     list = g_list_next (list)) {
 
635
                        AppletData *ad = list->data;
 
636
 
 
637
                        panel->applets_hints[i].hints = ad->size_hints;
 
638
                        panel->applets_hints[i].len = ad->size_hints_len;
 
639
                        i++;
 
640
                }
 
641
        }
 
642
}
 
643
 
 
644
/* Note: this can only be called at the beginning of size_allocate, which means
 
645
 * that ad->constrained doesn't matter yet (it will be set to the correct
 
646
 * value in size_allocate). */
 
647
static void
 
648
panel_widget_update_positions_packed_start (PanelWidget *panel)
 
649
{
 
650
        GList *list,*l;
 
651
        AppletData *ad;
 
652
        int size_all = 0;
 
653
        int pos_next;
 
654
 
 
655
        if (panel->packed)
 
656
                return;
 
657
 
 
658
        list = get_applet_list_pack (panel, PANEL_OBJECT_PACK_START);
 
659
 
 
660
        /* get size used by the objects */
 
661
        for (l = list; l; l = l->next) {
 
662
                ad = l->data;
 
663
                size_all += ad->cells;
 
664
        }
 
665
 
 
666
        /* update absolute position of all applets based on this information,
 
667
         * starting with the first object */
 
668
        pos_next = 0;
 
669
        l = list;
 
670
 
 
671
        while (l) {
 
672
                ad = l->data;
 
673
                ad->constrained = pos_next;
 
674
                pos_next += ad->cells;
 
675
                l = l->next;
 
676
        }
 
677
 
 
678
        g_list_free (list);
 
679
}
 
680
 
 
681
/* Note: only use this function when you can; see comment above
 
682
 * panel_widget_update_positions_packed_start()
 
683
 * For center specifically, we require ad->cells to be set. Note that we don't
 
684
 * care much about min_cells: if we need it, this means objects will have to be
 
685
 * pushed to accomodate other objects, which will kill centering anyway.
 
686
 * (FIXME: hrm, not that sure about it ;-)) */
 
687
static void
 
688
panel_widget_update_positions_packed_center (PanelWidget *panel)
 
689
{
 
690
        GList *list,*l;
 
691
        AppletData *ad;
 
692
        int size_all = 0;
 
693
        int pos_next;
 
694
 
 
695
        if (panel->packed)
 
696
                return;
 
697
 
 
698
        list = get_applet_list_pack (panel, PANEL_OBJECT_PACK_CENTER);
 
699
 
 
700
        /* get size used by the objects */
 
701
        for (l = list; l; l = l->next) {
 
702
                ad = l->data;
 
703
                size_all += ad->cells;
 
704
        }
 
705
 
 
706
        /* update absolute position of all applets based on this information,
 
707
         * starting with the first centered object */
 
708
        pos_next = (panel->size - size_all) / 2;
 
709
        l = list;
 
710
 
 
711
        while (l) {
 
712
                ad = l->data;
 
713
                ad->constrained = pos_next;
 
714
                pos_next += ad->cells;
 
715
                l = l->next;
 
716
        }
 
717
 
 
718
        g_list_free (list);
 
719
}
 
720
 
 
721
/* Note: only use this function when you can; see comment above
 
722
 * panel_widget_update_positions_packed_start() */
 
723
static void
 
724
panel_widget_update_positions_packed_end (PanelWidget *panel)
 
725
{
 
726
        GList *list,*l;
 
727
        AppletData *ad;
 
728
        int size_all = 0;
 
729
        int pos_next;
 
730
 
 
731
        if (panel->packed)
 
732
                return;
 
733
 
 
734
        list = get_applet_list_pack (panel, PANEL_OBJECT_PACK_END);
 
735
 
 
736
        /* get size used by the objects */
 
737
        for (l = list; l; l = l->next) {
 
738
                ad = l->data;
 
739
                size_all += ad->cells;
 
740
        }
 
741
 
 
742
        /* update absolute position of all applets based on this information,
 
743
         * starting with the first object */
 
744
        pos_next = panel->size - size_all;
 
745
        l = list;
 
746
 
 
747
        while (l) {
 
748
                ad = l->data;
 
749
                ad->constrained = pos_next;
 
750
                pos_next += ad->cells;
 
751
                l = l->next;
 
752
        }
 
753
 
 
754
        g_list_free (list);
 
755
}
 
756
 
 
757
static void
 
758
panel_widget_update_positions (PanelWidget *panel)
 
759
{
 
760
        int i = 0;
 
761
        GList *list;
 
762
        AppletData *ad;
 
763
 
 
764
        i = 0;
 
765
 
 
766
        if (panel->packed) {
 
767
                /* Because of the following, we have to be very careful that
 
768
                 * this code path is called only before a size_request() on the
 
769
                 * toplevel */
 
770
                panel_widget_update_size_hints_for_toplevel (panel);
 
771
 
 
772
                /* keep in sync with code in size_allocate */
 
773
                for (list = panel->applet_list;
 
774
                     list != NULL;
 
775
                     list = g_list_next (list)) {
 
776
                        ad = list->data;
 
777
                        ad->constrained = i;
 
778
                        i += ad->cells;
 
779
                }
 
780
        } else {
 
781
                /* Re-compute the ideal position of objects, based on their size */
 
782
                panel_widget_update_positions_packed_start (panel);
 
783
                panel_widget_update_positions_packed_center (panel);
 
784
                panel_widget_update_positions_packed_end (panel);
 
785
 
 
786
                /* Second pass: try to position from the start, to make sure
 
787
                 * there's enough room. We don't use size hints yet. */
 
788
                for (list = panel->applet_list;
 
789
                     list != NULL;
 
790
                     list = g_list_next (list)) {
 
791
                        ad = list->data;
 
792
                        if (ad->constrained < i)
 
793
                                ad->constrained = i;
 
794
 
 
795
                        i = ad->constrained + ad->cells;
 
796
                }
 
797
 
 
798
                /* Third pass: now expand from the end, and start using size
 
799
                 * hints if we need more room */
 
800
                i = panel->size;
 
801
                for(list = g_list_last(panel->applet_list);
 
802
                    list!=NULL;
 
803
                    list = g_list_previous(list)) {
 
804
                        ad = list->data;
 
805
                        int cells;
 
806
 
 
807
                        if (ad->constrained + ad->min_cells > i)
 
808
                                ad->constrained = MAX (i - ad->min_cells, 0);
 
809
 
 
810
                        if (ad->expand_major) {
 
811
                                cells = (i - ad->constrained) - 1;
 
812
 
 
813
                                if (ad->size_hints)
 
814
                                        cells = get_size_from_hints (ad, cells);
 
815
                                cells = MAX (cells, ad->min_cells);
 
816
                                cells = MIN (cells, panel->size);
 
817
 
 
818
                                ad->cells = cells;
 
819
                        }
 
820
 
 
821
                        i = ad->constrained;
 
822
                }
 
823
 
 
824
                /* EEEEK, there's not enough room, so shift applets even
 
825
                 * at the expense of perhaps running out of room on the
 
826
                 * right if there is no free space in the middle */
 
827
                if(i < 0) {
 
828
                        i = 0;
 
829
                        for(list = panel->applet_list;
 
830
                            list!=NULL;
 
831
                            list = g_list_next(list)) {
 
832
                                ad = list->data;
 
833
 
 
834
                                if (ad->constrained < i)
 
835
                                        ad->constrained = i;
 
836
 
 
837
                                i = ad->constrained + ad->cells;
 
838
                        }
 
839
                }
 
840
        }
 
841
}
 
842
 
 
843
static inline int
 
844
panel_widget_get_moveby (PanelWidget *panel,
 
845
                         AppletData  *ad)
 
846
{
 
847
        /* move relative to the center of the object */
 
848
        return panel_widget_get_cursorloc (panel) - ad->constrained - ad->cells / 2;
 
849
}
 
850
 
 
851
static int
 
852
panel_widget_move_get_pos_pack (PanelWidget *panel,
 
853
                                PanelObjectPackType pack_type)
 
854
{
 
855
        switch (pack_type) {
 
856
        case PANEL_OBJECT_PACK_START:
 
857
                return 0;
 
858
                break;
 
859
        case PANEL_OBJECT_PACK_CENTER:
 
860
                return panel->size / 2;
 
861
                break;
 
862
        case PANEL_OBJECT_PACK_END:
 
863
                return panel->size;
 
864
                break;
 
865
        default:
 
866
                g_assert_not_reached ();
 
867
                break;
 
868
        }
 
869
 
 
870
        return 0;
 
871
}
 
872
 
 
873
static int
 
874
panel_widget_move_get_pos_next_pack (PanelWidget *panel,
 
875
                                     AppletData  *ad,
 
876
                                     AppletData  *nad)
 
877
{
 
878
        if (!nad || nad->pack_type > ad->pack_type + 1)
 
879
                return panel_widget_move_get_pos_pack (panel, ad->pack_type + 1);
 
880
 
 
881
        return nad->constrained;
 
882
}
 
883
 
 
884
static int
 
885
panel_widget_move_get_pos_prev_pack (PanelWidget *panel,
 
886
                                     AppletData  *ad,
 
887
                                     AppletData  *pad)
 
888
{
 
889
        if (!pad || pad->pack_type < ad->pack_type - 1)
 
890
                return panel_widget_move_get_pos_pack (panel, ad->pack_type - 1);
 
891
 
 
892
        return pad->constrained + pad->cells;
 
893
}
 
894
 
 
895
static void
 
896
panel_widget_move_to_pack (PanelWidget         *panel,
 
897
                           AppletData          *ad,
 
898
                           PanelObjectPackType  new_pack_type,
 
899
                           int                  pack_index)
 
900
{
 
901
        GList *l;
 
902
 
 
903
        if (pack_index >= 0) {
 
904
                for (l = panel->applet_list; l; l = l->next) {
 
905
                        AppletData *ad_to_move = l->data;
 
906
                        if (ad_to_move->pack_type == new_pack_type &&
 
907
                            ad_to_move->pack_index >= pack_index) {
 
908
                                ad_to_move->pack_index++;
 
909
                                emit_applet_moved (panel, ad_to_move);
 
910
                        }
 
911
                }
 
912
        } else
 
913
                pack_index = panel_widget_get_new_pack_index (panel, new_pack_type);
 
914
 
 
915
        ad->pack_type = new_pack_type;
 
916
        ad->pack_index = pack_index;
 
917
}
 
918
 
 
919
/*
 
920
 * Switch move
 
921
 */
 
922
 
 
923
/* if force_switch is set, moveby will be ignored */
 
924
static gboolean
708
925
panel_widget_switch_applet_right (PanelWidget *panel,
709
 
                                  GList       *list)
 
926
                                  GList       *list,
 
927
                                  int          moveby,
 
928
                                  gboolean     force_switch)
710
929
{
711
930
        AppletData *ad;
712
 
        AppletData *nad = NULL;
713
 
        
714
 
        g_assert (list != NULL);
 
931
        AppletData *nad;
 
932
        int         swap_index;
 
933
        int         next_pos;
715
934
 
716
935
        ad = list->data;
717
 
        if (ad->constrained + ad->min_cells >= panel->size)
718
 
                return;
719
 
 
720
 
        if (list->next)
721
 
                nad = list->next->data;
722
 
 
723
 
        if (!nad || nad->constrained >= ad->constrained + ad->min_cells + MOVE_INCREMENT) {
724
 
                ad->pos = ad->constrained += MOVE_INCREMENT;
 
936
 
 
937
        if (panel->packed && !list->next)
 
938
                return FALSE;
 
939
 
 
940
        if (ad->pack_type == PANEL_OBJECT_PACK_END && !list->next)
 
941
                return FALSE;
 
942
 
 
943
        /* count moveby from end of object => remove distance to go there */
 
944
        moveby -= ad->cells / 2;
 
945
 
 
946
        nad = list->next ? list->next->data : NULL;
 
947
 
 
948
        /* Move inside same pack */
 
949
        if (nad && nad->pack_type == ad->pack_type) {
 
950
                if (force_switch ||
 
951
                    (moveby >= nad->cells / 2)) {
 
952
                        swap_index = ad->pack_index;
 
953
                        ad->pack_index = nad->pack_index;
 
954
                        nad->pack_index = swap_index;
 
955
 
 
956
                        panel->applet_list = panel_g_list_swap_next (panel->applet_list, list);
 
957
 
 
958
                        emit_applet_moved (panel, nad);
 
959
                        emit_applet_moved (panel, ad);
 
960
 
 
961
                        panel_widget_update_positions (panel);
 
962
                        gtk_widget_queue_resize (GTK_WIDGET (panel));
 
963
 
 
964
                        return TRUE;
 
965
                } else
 
966
                        return FALSE;
 
967
        }
 
968
 
 
969
        /* Move to next pack */
 
970
        next_pos = panel_widget_move_get_pos_next_pack (panel, ad, nad);
 
971
        if (force_switch ||
 
972
            (moveby >= (next_pos - (ad->constrained + ad->cells)) / 2)) {
 
973
                if (ad->pack_type + 1 == PANEL_OBJECT_PACK_END)
 
974
                        panel_widget_move_to_pack (panel, ad, ad->pack_type + 1, -1);
 
975
                else
 
976
                        panel_widget_move_to_pack (panel, ad, ad->pack_type + 1, 0);
 
977
 
 
978
                emit_applet_moved (panel, ad);
 
979
 
 
980
                panel_widget_update_positions (panel);
725
981
                gtk_widget_queue_resize (GTK_WIDGET (panel));
726
 
                emit_applet_moved (panel, ad);
727
 
                return;
728
 
        }
729
 
 
730
 
        if (nad->locked) {
731
 
                panel_widget_jump_applet_right (panel,
732
 
                                                list,
733
 
                                                list->next->next,
734
 
                                                nad->constrained + nad->min_cells);
735
 
                return;
736
 
        }
737
 
                                                  
738
 
        nad->constrained = nad->pos = ad->constrained;
739
 
        ad->constrained = ad->pos = ad->constrained + nad->min_cells;
740
 
        panel->applet_list = panel_g_list_swap_next (panel->applet_list, list);
741
 
 
742
 
        gtk_widget_queue_resize (GTK_WIDGET (panel));
743
 
 
744
 
        emit_applet_moved (panel, ad);
745
 
        emit_applet_moved (panel, nad);
746
 
}
747
 
 
748
 
static void
749
 
panel_widget_jump_applet_left (PanelWidget *panel,
750
 
                               GList       *list,
751
 
                               GList       *prev,
752
 
                               int          pos)
753
 
{
754
 
        AppletData *ad;
755
 
        AppletData *pad = NULL;
756
 
 
757
 
        ad = list->data;
758
 
        if (prev)
759
 
                pad = prev->data;
760
 
 
761
 
        if (pos < 0)
762
 
                return;
763
 
 
764
 
        if (!pad || pad->constrained + pad->min_cells <= pos)
765
 
                goto jump_left;
766
 
 
767
 
        if (!panel_widget_push_applet_left (panel, prev, pad->constrained + pad->min_cells - pos)) {
768
 
                panel_widget_jump_applet_left (panel,
769
 
                                               list,
770
 
                                               prev->prev,
771
 
                                               pad->constrained - ad->min_cells);
772
 
                return;
773
 
        }
774
 
 
775
 
 jump_left:
776
 
        ad->pos = ad->constrained = pos;
777
 
        panel->applet_list = g_list_remove_link (panel->applet_list, list);
778
 
        panel->applet_list = panel_g_list_insert_after (panel->applet_list, prev, list);
779
 
        gtk_widget_queue_resize (GTK_WIDGET (panel));
780
 
        emit_applet_moved (panel, ad);
781
 
}
782
 
 
783
 
static void
 
982
 
 
983
                return TRUE;
 
984
        }
 
985
 
 
986
        return FALSE;
 
987
}
 
988
 
 
989
/* if force_switch is set, moveby will be ignored */
 
990
static gboolean
784
991
panel_widget_switch_applet_left (PanelWidget *panel,
785
 
                                 GList       *list)
 
992
                                 GList       *list,
 
993
                                 int          moveby,
 
994
                                 gboolean     force_switch)
786
995
{
787
996
        AppletData *ad;
788
 
        AppletData *pad = NULL;
 
997
        AppletData *pad;
 
998
        int         swap_index;
 
999
        int         prev_pos;
789
1000
 
790
1001
        ad = list->data;
791
 
        if (ad->constrained <= 0)
792
 
                return;
793
 
 
794
 
        if (list->prev)
795
 
                pad = list->prev->data;
796
 
 
797
 
        if (!pad || pad->constrained + pad->min_cells <= ad->constrained - MOVE_INCREMENT) {
798
 
                ad->pos = ad->constrained -= MOVE_INCREMENT;
 
1002
 
 
1003
        if (panel->packed && !list->prev)
 
1004
                return FALSE;
 
1005
 
 
1006
        if (ad->pack_type == PANEL_OBJECT_PACK_START && !list->prev)
 
1007
                return FALSE;
 
1008
 
 
1009
        /* count moveby from start of object => add distance to go there */
 
1010
        moveby += ad->cells / 2;
 
1011
 
 
1012
        pad = list->prev ? list->prev->data : NULL;
 
1013
 
 
1014
        /* Move inside same pack */
 
1015
        if (pad && pad->pack_type == ad->pack_type) {
 
1016
                if (force_switch ||
 
1017
                    (moveby <= - pad->cells / 2)) {
 
1018
                        swap_index = ad->pack_index;
 
1019
                        ad->pack_index = pad->pack_index;
 
1020
                        pad->pack_index = swap_index;
 
1021
 
 
1022
                        panel->applet_list = panel_g_list_swap_prev (panel->applet_list, list);
 
1023
 
 
1024
                        emit_applet_moved (panel, ad);
 
1025
                        emit_applet_moved (panel, pad);
 
1026
 
 
1027
                        panel_widget_update_positions (panel);
 
1028
                        gtk_widget_queue_resize (GTK_WIDGET (panel));
 
1029
 
 
1030
                        return TRUE;
 
1031
                } else
 
1032
                        return FALSE;
 
1033
        }
 
1034
 
 
1035
        /* Move to prev pack */
 
1036
        prev_pos = panel_widget_move_get_pos_prev_pack (panel, ad, pad);
 
1037
        if (force_switch ||
 
1038
            (moveby <=  - ((ad->constrained - prev_pos) / 2))) {
 
1039
                panel_widget_move_to_pack (panel, ad, ad->pack_type - 1, -1);
 
1040
                emit_applet_moved (panel, ad);
 
1041
 
 
1042
                panel_widget_update_positions (panel);
799
1043
                gtk_widget_queue_resize (GTK_WIDGET (panel));
800
 
                emit_applet_moved (panel, ad);
801
 
                return;
802
 
        }
803
 
 
804
 
        if (pad->locked) {
805
 
                panel_widget_jump_applet_left (panel,
806
 
                                               list,
807
 
                                               list->prev->prev,
808
 
                                               pad->constrained - ad->min_cells);
809
 
                return;
810
 
        }
811
 
 
812
 
        ad->constrained = ad->pos = pad->constrained;
813
 
        pad->constrained = pad->pos = ad->constrained + ad->min_cells;
814
 
        panel->applet_list = panel_g_list_swap_prev (panel->applet_list, list);
815
 
 
816
 
        gtk_widget_queue_resize (GTK_WIDGET (panel));
817
 
 
818
 
        emit_applet_moved (panel, ad);
819
 
        emit_applet_moved (panel, pad);
820
 
}
821
 
 
822
 
static gboolean
823
 
panel_widget_try_push_right (PanelWidget *panel,
824
 
                             GList       *list,
825
 
                             int          push)
826
 
{
827
 
        AppletData *ad;
828
 
        AppletData *nad = NULL;
829
 
 
830
 
        g_assert (list != NULL);
831
 
 
832
 
        ad = list->data;
833
 
        if (list->next)
834
 
                nad = list->next->data;
835
 
 
836
 
        if (ad->locked)
837
 
                return FALSE;
838
 
 
839
 
        if (ad->constrained + ad->min_cells + push >= panel->size)
840
 
                return FALSE;
841
 
 
842
 
        if (!nad || nad->constrained >= ad->constrained + ad->min_cells + push)
843
 
                return TRUE;
844
 
 
845
 
        return panel_widget_try_push_right (panel, list->next, push);
846
 
}
847
 
 
848
 
static int
849
 
panel_widget_get_right_jump_pos (PanelWidget *panel,
850
 
                                 AppletData  *ad,
851
 
                                 GList       *next,
852
 
                                 int          pos)
853
 
{
854
 
        AppletData *nad = NULL;
855
 
 
856
 
        if (next)
857
 
                nad = next->data;
858
 
 
859
 
        if (!nad || nad->constrained >= pos + ad->min_cells)
860
 
                return pos;
861
 
 
862
 
        if (panel_widget_try_push_right (panel, next, pos + ad->min_cells - nad->constrained))
863
 
                return pos;
864
 
 
865
 
        return panel_widget_get_right_jump_pos (panel,
866
 
                                                ad,
867
 
                                                next->next,
868
 
                                                nad->constrained + nad->min_cells);
869
 
}
870
 
 
871
 
static int
872
 
panel_widget_get_right_switch_pos (PanelWidget *panel,
873
 
                                   GList       *list)
874
 
{
875
 
        AppletData *ad;
876
 
        AppletData *nad = NULL;
877
 
 
878
 
        g_assert (list != NULL);
879
 
 
880
 
        ad = list->data;
881
 
        if (list->next)
882
 
                nad = list->next->data;
883
 
 
884
 
        if (!nad || nad->constrained >= ad->constrained + ad->min_cells + MOVE_INCREMENT)
885
 
                return ad->constrained + MOVE_INCREMENT;
886
 
 
887
 
        if (nad->locked)
888
 
                return panel_widget_get_right_jump_pos (panel,
889
 
                                                        ad,
890
 
                                                        list->next->next,
891
 
                                                        nad->constrained + nad->min_cells);
892
 
 
893
 
        return nad->constrained + nad->min_cells - ad->cells;
894
 
}
895
 
 
896
 
static gboolean
897
 
panel_widget_try_push_left (PanelWidget *panel,
898
 
                            GList       *list,
899
 
                            int          push)
900
 
{
901
 
        AppletData *ad;
902
 
        AppletData *pad = NULL;
903
 
 
904
 
        g_assert (list != NULL);
905
 
 
906
 
        ad = list->data;
907
 
        if (list->prev)
908
 
                pad = list->prev->data;
909
 
 
910
 
        if (ad->locked)
911
 
                return FALSE;
912
 
 
913
 
        if (ad->constrained - push < 0)
914
 
                return FALSE;
915
 
        
916
 
        if (!pad || pad->constrained + pad->min_cells <= ad->constrained - push)
917
 
                return TRUE;
918
 
 
919
 
        return panel_widget_try_push_left (panel, list->prev, push);
920
 
}
921
 
 
922
 
static int
923
 
panel_widget_get_left_jump_pos (PanelWidget *panel,
924
 
                                AppletData  *ad,
925
 
                                GList       *prev,
926
 
                                int          pos)
927
 
{
928
 
        AppletData *pad = NULL;
929
 
 
930
 
        if (prev)
931
 
                pad = prev->data;
932
 
 
933
 
        if (!pad || pad->constrained + pad->min_cells <= pos)
934
 
                return pos;
935
 
 
936
 
        if (panel_widget_try_push_left (panel, prev, pad->constrained + pad->min_cells - pos))
937
 
                return pos;
938
 
 
939
 
        return panel_widget_get_left_jump_pos (panel,
940
 
                                               ad,
941
 
                                               prev->prev,
942
 
                                               pad->constrained - ad->min_cells);
943
 
}
944
 
 
945
 
static int
946
 
panel_widget_get_left_switch_pos (PanelWidget *panel,
947
 
                                  GList       *list)
948
 
{
949
 
        AppletData *ad;
950
 
        AppletData *pad = NULL;
951
 
 
952
 
        g_assert (list != NULL);
953
 
 
954
 
        ad = list->data;
955
 
        if (list->prev)
956
 
                pad = list->prev->data;
957
 
        
958
 
        if (!pad || pad->constrained + pad->min_cells <= ad->constrained - MOVE_INCREMENT)
959
 
                return ad->constrained - MOVE_INCREMENT;
960
 
 
961
 
        if (pad->locked)
962
 
                return panel_widget_get_left_jump_pos (panel,
963
 
                                                       ad,
964
 
                                                       list->prev->prev,
965
 
                                                       pad->constrained - ad->min_cells);
966
 
        
967
 
        return pad->constrained;
 
1044
 
 
1045
                return TRUE;
 
1046
        }
 
1047
 
 
1048
        return FALSE;
968
1049
}
969
1050
 
970
1051
static void
971
1052
panel_widget_switch_move (PanelWidget *panel,
972
 
                          AppletData  *ad,
973
 
                          int          moveby)
 
1053
                          AppletData  *ad)
974
1054
{
975
1055
        GList *list;
976
 
        int    finalpos;
977
 
        int    pos;
 
1056
        gboolean moved;
 
1057
        int      moveby;
978
1058
 
979
1059
        g_return_if_fail (ad != NULL);
980
1060
        g_return_if_fail (PANEL_IS_WIDGET (panel));
981
1061
 
982
 
        if (moveby == 0)
983
 
                return;
984
 
 
985
1062
        list = g_list_find (panel->applet_list, ad);
986
1063
        g_return_if_fail (list != NULL);
987
1064
 
988
 
        finalpos = ad->constrained + moveby;
989
 
 
990
 
        if (ad->constrained < finalpos) {
991
 
                AppletData *pad;
992
 
 
993
 
                if (list->prev) {
994
 
                        pad = list->prev->data;
995
 
                        if (pad->expand_major)
996
 
                                gtk_widget_queue_resize (GTK_WIDGET (panel));
997
 
                }
998
 
 
999
 
                while (ad->constrained < finalpos) {
1000
 
                        pos = panel_widget_get_right_switch_pos (panel, list);
1001
 
 
1002
 
                        if (abs (pos - finalpos) >= abs (ad->constrained - finalpos) ||
1003
 
                            pos + ad->min_cells > panel->size)
1004
 
                                break;
1005
 
 
1006
 
                        panel_widget_switch_applet_right (panel, list);
1007
 
                }
1008
 
 
1009
 
                if (list->prev) {
1010
 
                        pad = list->prev->data;
1011
 
                        if (pad->expand_major)
1012
 
                                gtk_widget_queue_resize (GTK_WIDGET (panel));
 
1065
        moveby = panel_widget_get_moveby (panel, ad);
 
1066
 
 
1067
        if (moveby > ad->cells / 2) {
 
1068
                moved = TRUE;
 
1069
                while (moved && moveby > ad->cells / 2) {
 
1070
                        moved = panel_widget_switch_applet_right (panel, list,
 
1071
                                                                  moveby, FALSE);
 
1072
                        moveby = panel_widget_get_moveby (panel, ad);
1013
1073
                }
1014
1074
        } else {
1015
 
                AppletData *nad;
1016
 
 
1017
 
                if (list->next) {
1018
 
                        nad = list->next->data;
1019
 
                        if (nad->expand_major)
1020
 
                                gtk_widget_queue_resize (GTK_WIDGET (panel));
1021
 
                }
1022
 
 
1023
 
                while (ad->constrained > finalpos) {
1024
 
                        pos = panel_widget_get_left_switch_pos (panel, list);
1025
 
 
1026
 
                        if (abs (pos - finalpos) >= abs (ad->constrained - finalpos) || pos < 0)
1027
 
                                break;
1028
 
 
1029
 
                        panel_widget_switch_applet_left (panel, list);
1030
 
                }
1031
 
                
 
1075
                moved = TRUE;
 
1076
                while (moved && moveby < - ad->cells / 2) {
 
1077
                        moved = panel_widget_switch_applet_left (panel, list,
 
1078
                                                                 moveby, FALSE);
 
1079
                        moveby = panel_widget_get_moveby (panel, ad);
 
1080
                }
1032
1081
        }
1033
1082
}
1034
1083
 
1035
1084
static int
1036
1085
panel_widget_push_applet_right (PanelWidget *panel,
1037
1086
                                GList       *list,
1038
 
                                int          push)
 
1087
                                int          moveby,
 
1088
                                gboolean     force_switch)
1039
1089
{
1040
1090
        AppletData *ad;
1041
 
        AppletData *nad = NULL;
 
1091
        AppletData *nad;
 
1092
        PanelObjectPackType new_pack_type;
 
1093
        GList *l;
 
1094
        GList *last_in_pack;
 
1095
        int next_pos;
1042
1096
 
1043
 
        g_assert (list != NULL);
1044
 
        
1045
1097
        ad = list->data;
1046
 
        if (ad->constrained + ad->min_cells + push >= panel->size)
1047
 
                return FALSE;
1048
 
 
1049
 
        if (ad->locked)
1050
 
                return FALSE;
1051
 
 
1052
 
        if (list->next)
1053
 
                nad = list->next->data;
1054
 
 
1055
 
        if (!nad || nad->constrained >= ad->constrained + ad->min_cells + push) {
1056
 
                ad->pos = ad->constrained += push;
1057
 
                gtk_widget_queue_resize (GTK_WIDGET (panel));
 
1098
 
 
1099
        if (ad->pack_type == PANEL_OBJECT_PACK_END)
 
1100
                return FALSE;
 
1101
 
 
1102
        /* count moveby from end of object => remove distance to go there */
 
1103
        moveby -= ad->cells / 2;
 
1104
 
 
1105
        new_pack_type = ad->pack_type + 1;
 
1106
 
 
1107
        for (l = list; l && l->next; l = l->next) {
 
1108
                nad = l->next->data;
 
1109
                if (nad->pack_type != ad->pack_type)
 
1110
                        break;
 
1111
        }
 
1112
 
 
1113
        last_in_pack = l;
 
1114
 
 
1115
        nad = last_in_pack->next ? last_in_pack->next->data : NULL;
 
1116
        next_pos = panel_widget_move_get_pos_next_pack (panel, ad, nad);
 
1117
 
 
1118
        if (!force_switch &&
 
1119
            (moveby < (next_pos - (ad->constrained + ad->cells)) / 2))
 
1120
                return FALSE;
 
1121
 
 
1122
        for (l = last_in_pack; l; l = l->prev) {
 
1123
                ad = l->data;
 
1124
 
 
1125
                if (new_pack_type == PANEL_OBJECT_PACK_END)
 
1126
                        panel_widget_move_to_pack (panel, ad, new_pack_type, -1);
 
1127
                else
 
1128
                        panel_widget_move_to_pack (panel, ad, new_pack_type, 0);
 
1129
 
1058
1130
                emit_applet_moved (panel, ad);
1059
 
                return TRUE;
 
1131
 
 
1132
                if (l == list)
 
1133
                        break;
1060
1134
        }
1061
1135
 
1062
 
        g_assert (list->next != NULL);
1063
 
 
1064
 
        if (!panel_widget_push_applet_right (panel, list->next, push))
1065
 
                return FALSE;
1066
 
 
1067
 
        ad->pos = ad->constrained += push;;
 
1136
        panel_widget_update_positions (panel);
1068
1137
        gtk_widget_queue_resize (GTK_WIDGET (panel));
1069
 
        emit_applet_moved (panel, ad);
1070
 
        
 
1138
 
1071
1139
        return TRUE;
1072
1140
}
1073
1141
 
1074
1142
static int
1075
1143
panel_widget_push_applet_left (PanelWidget *panel,
1076
1144
                               GList       *list,
1077
 
                               int          push)
 
1145
                               int          moveby,
 
1146
                               gboolean     force_switch)
1078
1147
{
1079
1148
        AppletData *ad;
1080
 
        AppletData *pad = NULL;
1081
 
 
1082
 
        g_assert (list != NULL);
 
1149
        AppletData *pad;
 
1150
        PanelObjectPackType new_pack_type;
 
1151
        GList *l;
 
1152
        GList *first_in_pack;
 
1153
        int prev_pos;
1083
1154
 
1084
1155
        ad = list->data;
1085
 
        if (ad->constrained - push < 0)
1086
 
                return FALSE;
1087
 
 
1088
 
        if (ad->locked)
1089
 
                return FALSE;
1090
 
 
1091
 
        if (list->prev)
1092
 
                pad = list->prev->data;
1093
 
 
1094
 
        if (!pad || pad->constrained + pad->min_cells <= ad->constrained - push) {
1095
 
                ad->pos = ad->constrained -= push;
1096
 
                gtk_widget_queue_resize (GTK_WIDGET (panel));
 
1156
 
 
1157
        if (ad->pack_type == PANEL_OBJECT_PACK_START)
 
1158
                return FALSE;
 
1159
 
 
1160
        /* count moveby from start of object => add distance to go there */
 
1161
        moveby += ad->cells / 2;
 
1162
 
 
1163
        new_pack_type = ad->pack_type - 1;
 
1164
 
 
1165
        for (l = list; l && l->prev; l = l->prev) {
 
1166
                pad = l->prev->data;
 
1167
                if (pad->pack_type != ad->pack_type)
 
1168
                        break;
 
1169
        }
 
1170
 
 
1171
        first_in_pack = l;
 
1172
 
 
1173
        pad = first_in_pack->prev ? first_in_pack->prev->data : NULL;
 
1174
        prev_pos = panel_widget_move_get_pos_prev_pack (panel, ad, pad);
 
1175
 
 
1176
        if (!force_switch &&
 
1177
            (moveby >  - ((ad->constrained - prev_pos) / 2)))
 
1178
                return FALSE;
 
1179
 
 
1180
        for (l = first_in_pack; l; l = l->next) {
 
1181
                ad = l->data;
 
1182
 
 
1183
                panel_widget_move_to_pack (panel, ad, new_pack_type, -1);
1097
1184
                emit_applet_moved (panel, ad);
1098
 
                return TRUE;
 
1185
 
 
1186
                if (l == list)
 
1187
                        break;
1099
1188
        }
1100
1189
 
1101
 
        g_assert (list->prev != NULL);
1102
 
 
1103
 
        if (!panel_widget_push_applet_left (panel, list->prev, push))
1104
 
                return FALSE;
1105
 
 
1106
 
        ad->pos = ad->constrained -= push;
 
1190
        panel_widget_update_positions (panel);
1107
1191
        gtk_widget_queue_resize (GTK_WIDGET (panel));
1108
 
        emit_applet_moved (panel, ad);
1109
 
        
 
1192
 
1110
1193
        return TRUE;
1111
1194
}
1112
1195
 
1113
1196
static void
1114
1197
panel_widget_push_move (PanelWidget *panel,
1115
1198
                        AppletData  *ad,
1116
 
                        int          moveby)
 
1199
                        int          direction)
1117
1200
{
1118
 
        AppletData *pad;
1119
 
        int finalpos;
1120
1201
        GList *list;
 
1202
        gboolean moved;
 
1203
        int      moveby;
 
1204
 
 
1205
        /* direction is only used when we move with keybindings */
1121
1206
 
1122
1207
        g_return_if_fail (ad != NULL);
1123
1208
        g_return_if_fail (PANEL_IS_WIDGET (panel));
1124
1209
 
1125
 
        if (moveby == 0)
1126
 
                return;
1127
 
 
1128
1210
        list = g_list_find (panel->applet_list, ad);
1129
1211
        g_return_if_fail (list != NULL);
1130
1212
 
1131
 
        finalpos = ad->constrained + moveby;
1132
 
 
1133
 
        if (ad->constrained < finalpos) {
1134
 
                while (ad->constrained < finalpos)
1135
 
                        if (!panel_widget_push_applet_right (panel, list, 1))
 
1213
        moveby = panel_widget_get_moveby (panel, ad);
 
1214
 
 
1215
        if (direction > 0 || moveby > ad->cells / 2) {
 
1216
                moved = TRUE;
 
1217
                while (direction > 0 ||
 
1218
                       (moved && moveby > ad->cells / 2)) {
 
1219
                        moved = panel_widget_push_applet_right (panel, list,
 
1220
                                                                moveby,
 
1221
                                                                direction != 0);
 
1222
                        moveby = panel_widget_get_moveby (panel, ad);
 
1223
 
 
1224
                        /* a keybinding pushes only once */
 
1225
                        if (direction != 0)
1136
1226
                                break;
1137
 
 
1138
 
                if (list->prev) {
1139
 
                        pad = list->prev->data;
1140
 
                        if (pad->expand_major)
1141
 
                                gtk_widget_queue_resize (GTK_WIDGET (panel));
1142
1227
                }
1143
1228
        } else {
1144
 
                while (ad->constrained > finalpos)
1145
 
                        if (!panel_widget_push_applet_left (panel, list, 1))
 
1229
                moved = TRUE;
 
1230
                while (direction < 0 ||
 
1231
                       (moved && moveby < ad->cells / 2)) {
 
1232
                        moved = panel_widget_push_applet_left (panel, list,
 
1233
                                                               moveby,
 
1234
                                                               direction != 0);
 
1235
                        moveby = panel_widget_get_moveby (panel, ad);
 
1236
 
 
1237
                        /* a keybinding pushes only once */
 
1238
                        if (direction != 0)
1146
1239
                                break;
 
1240
                }
1147
1241
        }
1148
1242
}
1149
1243
 
1150
 
 
1151
 
/*this is a special function and may fail if called improperly, it works
1152
 
only under special circumstance when we know there is nothing from
1153
 
old_size to panel->size*/
1154
 
static void
1155
 
panel_widget_right_stick(PanelWidget *panel,int old_size)
1156
 
{
1157
 
        int i,pos;
1158
 
        GList *list,*prev;
1159
 
        AppletData *ad;
1160
 
 
1161
 
        g_return_if_fail(PANEL_IS_WIDGET(panel));
1162
 
        g_return_if_fail(old_size>=0);
1163
 
        
1164
 
        if(old_size>=panel->size ||
1165
 
           panel->packed)
1166
 
                return;
1167
 
        
1168
 
        list = get_applet_list_pos(panel,old_size-1);
1169
 
 
1170
 
        if(!list)
1171
 
                return;
1172
 
        
1173
 
        pos = panel->size-1;
1174
 
 
1175
 
        ad = list->data;
1176
 
        do { 
1177
 
                i = ad->pos;
1178
 
                ad->pos = ad->constrained = pos--;
1179
 
                ad->cells = 1;
1180
 
                prev = list;
1181
 
                list = g_list_previous(list);
1182
 
                if(!list)
1183
 
                        break;
1184
 
                ad = list->data;
1185
 
        } while(ad->pos + ad->cells == i);
1186
 
 
1187
 
        for (list = prev; list; list = list->next)
1188
 
                emit_applet_moved (panel, list->data);
1189
 
}
1190
 
 
1191
1244
static void
1192
1245
panel_widget_size_request(GtkWidget *widget, GtkRequisition *requisition)
1193
1246
{
1194
1247
        PanelWidget *panel;
1195
1248
        GList *list;
1196
 
        GList *ad_with_hints;
1197
1249
        gboolean dont_fill;
1198
1250
 
1199
1251
        g_return_if_fail(PANEL_IS_WIDGET(widget));
1209
1261
                requisition->width = panel->sz;
1210
1262
        }
1211
1263
 
1212
 
        ad_with_hints = NULL;
1213
 
 
1214
1264
        for(list = panel->applet_list; list!=NULL; list = g_list_next(list)) {
1215
1265
                AppletData *ad = list->data;
1216
 
                GtkRequisition chreq;
1217
 
                gtk_widget_size_request(ad->applet,&chreq);
 
1266
                GtkRequisition child_req;
 
1267
 
 
1268
                gtk_widget_get_preferred_size (ad->applet, &child_req, NULL);
1218
1269
 
1219
1270
                if (panel->orient == GTK_ORIENTATION_HORIZONTAL) {
1220
 
                        if (requisition->height < chreq.height && !ad->size_constrained)
1221
 
                                requisition->height = chreq.height;
1222
 
 
1223
 
                        if (panel->packed && ad->expand_major && ad->size_hints)
1224
 
                                ad_with_hints = g_list_prepend (ad_with_hints,
1225
 
                                                                ad);
1226
 
 
1227
 
                        else if (panel->packed)
1228
 
                                requisition->width += chreq.width;
 
1271
                        if (requisition->height < child_req.height &&
 
1272
                            !ad->size_constrained)
 
1273
                                requisition->height = child_req.height;
 
1274
 
 
1275
                        if (panel->packed &&
 
1276
                            !(ad->expand_major && ad->size_hints))
 
1277
                                requisition->width += child_req.width;
1229
1278
                } else {
1230
 
                        if (requisition->width < chreq.width && !ad->size_constrained)
1231
 
                                requisition->width = chreq.width;
1232
 
 
1233
 
                        if (panel->packed && ad->expand_major && ad->size_hints)
1234
 
                                ad_with_hints = g_list_prepend (ad_with_hints,
1235
 
                                                                ad);
1236
 
 
1237
 
                        else if (panel->packed)
1238
 
                                requisition->height += chreq.height;
 
1279
                        if (requisition->width < child_req.width &&
 
1280
                            !ad->size_constrained)
 
1281
                                requisition->width = child_req.width;
 
1282
 
 
1283
                        if (panel->packed &&
 
1284
                            !(ad->expand_major && ad->size_hints))
 
1285
                                requisition->height += child_req.height;
1239
1286
                }
1240
1287
        }
1241
1288
 
1242
1289
 
1243
 
        panel->nb_applets_size_hints = 0;
1244
 
        if (panel->applets_hints != NULL)
1245
 
                g_free (panel->applets_hints);
1246
 
        panel->applets_hints = NULL;
1247
 
        if (panel->applets_using_hint != NULL)
1248
 
                g_free (panel->applets_using_hint);
1249
 
        panel->applets_using_hint = NULL;
1250
 
 
1251
 
        if(!panel->packed) {
1252
 
                if(panel->orient == GTK_ORIENTATION_HORIZONTAL) {
 
1290
        if (!panel->packed) {
 
1291
                if (panel->orient == GTK_ORIENTATION_HORIZONTAL)
1253
1292
                        requisition->width = panel->size;
1254
 
                } else {
 
1293
                else
1255
1294
                        requisition->height = panel->size;
1256
 
                }
1257
 
        } else {
1258
 
                /* put the list in the correct order: this is important
1259
 
                 * since we'll use this order in the size_allocate() */
1260
 
                ad_with_hints = g_list_reverse (ad_with_hints);
1261
 
 
1262
 
                panel->nb_applets_size_hints = g_list_length (ad_with_hints);
1263
 
                if (panel->nb_applets_size_hints > 0) {
1264
 
                        int i;
1265
 
                        panel->applets_hints = g_new0 (AppletSizeHints, panel->nb_applets_size_hints);
1266
 
 
1267
 
                        i = 0;
1268
 
                        for (list = ad_with_hints;
1269
 
                             list != NULL;
1270
 
                             list = g_list_next (list)) {
1271
 
                                AppletData *ad = list->data;
1272
 
 
1273
 
                                panel->applets_hints[i].hints = ad->size_hints;
1274
 
                                panel->applets_hints[i].len = ad->size_hints_len;
1275
 
                                i++;
1276
 
                        }
1277
 
 
1278
 
                        panel->applets_using_hint = g_new0 (AppletSizeHintsAlloc, panel->nb_applets_size_hints);
1279
 
                }
1280
1295
        }
1281
 
        
 
1296
 
1282
1297
        dont_fill = panel->packed && panel->nb_applets_size_hints != 0;
1283
1298
 
1284
1299
        if (panel->orient == GTK_ORIENTATION_HORIZONTAL) {
1295
1310
}
1296
1311
 
1297
1312
static void
 
1313
panel_widget_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width)
 
1314
{
 
1315
        GtkRequisition requisition;
 
1316
 
 
1317
        panel_widget_size_request (widget, &requisition);
 
1318
 
 
1319
        *minimal_width = *natural_width = requisition.width;
 
1320
}
 
1321
 
 
1322
static void
 
1323
panel_widget_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height)
 
1324
{
 
1325
        GtkRequisition requisition;
 
1326
 
 
1327
        panel_widget_size_request (widget, &requisition);
 
1328
 
 
1329
        *minimal_height = *natural_height = requisition.height;
 
1330
}
 
1331
 
 
1332
static void
1298
1333
queue_resize_on_all_applets(PanelWidget *panel)
1299
1334
{
1300
1335
        GList *li;
1334
1369
        PanelWidget *panel;
1335
1370
        GList *list;
1336
1371
        int i;
1337
 
        int old_size;
1338
1372
        gboolean ltr;
 
1373
        AppletData *ad;
1339
1374
 
1340
1375
        g_return_if_fail(PANEL_IS_WIDGET(widget));
1341
1376
        g_return_if_fail(allocation!=NULL);
1342
1377
 
1343
1378
        panel = PANEL_WIDGET(widget);
1344
1379
 
1345
 
        old_size = panel->size;
1346
1380
        ltr = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR;
1347
1381
        
1348
1382
        gtk_widget_set_allocation (widget, allocation);
1357
1391
                panel->size = allocation->width;
1358
1392
        else
1359
1393
                panel->size = allocation->height;
1360
 
        if(old_size<panel->size)
1361
 
                panel_widget_right_stick(panel,old_size);
1362
1394
 
1363
1395
        if (panel->packed) {
1364
1396
                /* we're assuming the order is the same as the one that was
1365
1397
                 * in size_request() */
1366
1398
                int applet_using_hint_index = 0;
1367
1399
 
 
1400
                /* keep in sync with code in update_positions */
1368
1401
                i = 0;
1369
1402
                for(list = panel->applet_list;
1370
1403
                    list!=NULL;
1371
1404
                    list = g_list_next(list)) {
1372
 
                        AppletData *ad = list->data;
 
1405
                        ad = list->data;
1373
1406
                        GtkAllocation challoc;
1374
1407
                        GtkRequisition chreq;
1375
 
                        gtk_widget_get_child_requisition(ad->applet,&chreq);
 
1408
                        gtk_widget_get_preferred_size (ad->applet, &chreq, NULL);
1376
1409
 
1377
1410
                        ad->constrained = i;
1378
1411
                        
1415
1448
 
1416
1449
        } else { /*not packed*/
1417
1450
 
1418
 
                /* First make sure there's enough room on the left */
1419
 
                i = 0;
 
1451
                /* First pass: set ad->cells so that we can know the absolute
 
1452
                 * position of objects. */
1420
1453
                for (list = panel->applet_list;
1421
1454
                     list != NULL;
1422
1455
                     list = g_list_next (list)) {
1423
 
                        AppletData *ad = list->data;
 
1456
                        ad = list->data;
1424
1457
                        GtkRequisition chreq;
1425
1458
 
1426
 
                        gtk_widget_get_child_requisition(ad->applet,&chreq);
 
1459
                        gtk_widget_get_preferred_size (ad->applet, &chreq, NULL);
1427
1460
 
1428
1461
                        if (!ad->expand_major || !ad->size_hints) {
1429
1462
                                if(panel->orient == GTK_ORIENTATION_HORIZONTAL)
1433
1466
 
1434
1467
                                ad->min_cells = ad->cells;
1435
1468
                        } else {
1436
 
                                ad->cells = ad->size_hints [ad->size_hints_len - 1];
 
1469
                                ad->cells = ad->size_hints [0];
1437
1470
                                ad->min_cells = ad->size_hints [ad->size_hints_len - 1];
1438
1471
                        }
1439
 
 
1440
 
                        ad->constrained = ad->pos;
1441
 
 
1442
 
                        if (ad->constrained < i)
1443
 
                                ad->constrained = i;
1444
 
 
1445
 
                        i = ad->constrained + ad->cells;
1446
 
                }
1447
 
 
1448
 
                /* Now expand from the right */
1449
 
                i = panel->size;
1450
 
                for(list = g_list_last(panel->applet_list);
1451
 
                    list!=NULL;
1452
 
                    list = g_list_previous(list)) {
1453
 
                        AppletData *ad = list->data;
1454
 
                        int cells;
1455
 
                        
1456
 
                        if (ad->constrained + ad->min_cells > i)
1457
 
                                ad->constrained = MAX (i - ad->min_cells, 0);
1458
 
                        
1459
 
                        if (ad->expand_major) {
1460
 
                                cells = (i - ad->constrained) - 1;
1461
 
 
1462
 
                                if (ad->size_hints) 
1463
 
                                        cells = get_size_from_hints (ad, cells);
1464
 
                                cells = MAX (cells, ad->min_cells);
1465
 
                                cells = MIN (cells, panel->size);
1466
 
 
1467
 
                                ad->cells = cells;
1468
 
                        }
1469
 
 
1470
 
                        i = ad->constrained;
1471
 
                }
1472
 
 
1473
 
                /* EEEEK, there's not enough room, so shift applets even
1474
 
                 * at the expense of perhaps running out of room on the
1475
 
                 * right if there is no free space in the middle */
1476
 
                if(i < 0) {
1477
 
                        i = 0;
1478
 
                        for(list = panel->applet_list;
1479
 
                            list!=NULL;
1480
 
                            list = g_list_next(list)) {
1481
 
                                AppletData *ad = list->data;
1482
 
                                
1483
 
                                if (ad->constrained < i)
1484
 
                                        ad->constrained = i;
1485
 
                                
1486
 
                                i = ad->constrained + ad->cells;
1487
 
                        }
1488
 
                }
1489
 
 
 
1472
                }
 
1473
 
 
1474
                panel_widget_update_positions (panel);
 
1475
 
 
1476
                /* Last pass: actually allocate the size for each object */
1490
1477
                for(list = panel->applet_list;
1491
1478
                    list!=NULL;
1492
1479
                    list = g_list_next(list)) {
1493
 
                        AppletData *ad = list->data;
 
1480
                        ad = list->data;
1494
1481
                        GtkAllocation challoc;
1495
1482
                        GtkRequisition chreq;
1496
 
                        gtk_widget_get_child_requisition(ad->applet,&chreq);
 
1483
                        gtk_widget_get_preferred_size (ad->applet, &chreq, NULL);
1497
1484
                        challoc.width = chreq.width;
1498
1485
                        challoc.height = chreq.height;
1499
1486
                        if(panel->orient == GTK_ORIENTATION_HORIZONTAL) {
1515
1502
                        gtk_widget_size_allocate(ad->applet,&challoc);
1516
1503
                }
1517
1504
        }
 
1505
 
 
1506
 
1518
1507
        if(panel->orient == GTK_ORIENTATION_HORIZONTAL)
1519
1508
                panel->thick = allocation->height;
1520
1509
        else
1555
1544
}
1556
1545
 
1557
1546
static void
1558
 
panel_widget_style_set (GtkWidget *widget,
1559
 
                        GtkStyle  *previous_style)
1560
 
{
1561
 
        GtkStyle     *style;
1562
 
        GtkStateType  state;
1563
 
 
1564
 
        if (gtk_widget_get_realized (widget)) {
1565
 
                style = gtk_widget_get_style (widget);
1566
 
                state = gtk_widget_get_state (widget);
1567
 
 
1568
 
                panel_background_set_default_style (
1569
 
                        &PANEL_WIDGET (widget)->background,
1570
 
                        &style->bg [state],
1571
 
                        style->bg_pixmap [state]);
1572
 
        }
1573
 
}
1574
 
 
1575
 
static void
1576
 
panel_widget_state_changed (GtkWidget    *widget,
1577
 
                            GtkStateType  previous_state)
1578
 
{
1579
 
        GtkStyle     *style;
1580
 
        GtkStateType  state;
1581
 
 
1582
 
        if (gtk_widget_get_realized (widget)) {
1583
 
                style = gtk_widget_get_style (widget);
1584
 
                state = gtk_widget_get_state (widget);
1585
 
 
1586
 
                panel_background_set_default_style (
1587
 
                        &PANEL_WIDGET (widget)->background,
1588
 
                        &style->bg [state],
1589
 
                        style->bg_pixmap [state]);
1590
 
        }
 
1547
panel_widget_set_background_default_style (GtkWidget *widget)
 
1548
{
 
1549
        GtkStyleContext *context;
 
1550
        GtkStateFlags    state;
 
1551
        GdkRGBA          bg_color;
 
1552
        cairo_pattern_t *bg_image;
 
1553
 
 
1554
        if (gtk_widget_get_realized (widget)) {
 
1555
                context = gtk_widget_get_style_context (widget);
 
1556
                state = gtk_widget_get_state_flags (widget);
 
1557
 
 
1558
                gtk_style_context_get_background_color (context, state, &bg_color);
 
1559
                gtk_style_context_get (context, state,
 
1560
                                       "background-image", &bg_image,
 
1561
                                       NULL);
 
1562
 
 
1563
                panel_background_set_default_style (
 
1564
                        &PANEL_WIDGET (widget)->background,
 
1565
                        &bg_color, bg_image);
 
1566
 
 
1567
                if (bg_image)
 
1568
                        cairo_pattern_destroy (bg_image);
 
1569
        }
 
1570
}
 
1571
 
 
1572
static void
 
1573
panel_widget_style_updated (GtkWidget *widget)
 
1574
{
 
1575
        panel_widget_set_background_default_style (widget);
 
1576
        GTK_WIDGET_CLASS (panel_widget_parent_class)->style_updated (widget);
 
1577
}
 
1578
 
 
1579
static void
 
1580
panel_widget_state_flags_changed (GtkWidget    *widget,
 
1581
                                  GtkStateFlags previous_state)
 
1582
{
 
1583
        panel_widget_set_background_default_style (widget);
1591
1584
}
1592
1585
 
1593
1586
static gboolean
1603
1596
static void
1604
1597
panel_widget_realize (GtkWidget *widget)
1605
1598
{
1606
 
        PanelWidget  *panel = (PanelWidget *) widget;
1607
 
        GdkWindow    *window;
1608
 
        GtkStyle     *style;
1609
 
        GtkStateType  state;
 
1599
        PanelWidget     *panel = (PanelWidget *) widget;
 
1600
        GdkWindow       *window;
1610
1601
 
1611
1602
        g_signal_connect (panel->toplevel, "configure-event",
1612
1603
                          G_CALLBACK (toplevel_configure_event), panel);
1614
1605
        GTK_WIDGET_CLASS (panel_widget_parent_class)->realize (widget);
1615
1606
 
1616
1607
        window = gtk_widget_get_window (widget);
1617
 
        style = gtk_widget_get_style (widget);
1618
 
        state = gtk_widget_get_state (widget);
1619
 
 
1620
1608
        /* For auto-hidden panels with a colored background, we need native
1621
1609
         * windows to avoid some uglyness on unhide */
1622
1610
        gdk_window_ensure_native (window);
1623
1611
 
1624
 
        panel_background_set_default_style (
1625
 
                &panel->background,
1626
 
                &style->bg [state],
1627
 
                style->bg_pixmap [state]);
1628
 
 
 
1612
        panel_widget_set_background_default_style (widget);
1629
1613
        panel_background_realized (&panel->background, window);
1630
1614
}
1631
1615
 
1694
1678
}
1695
1679
 
1696
1680
static void
1697
 
panel_widget_destroy (GtkObject *obj)
 
1681
panel_widget_dispose (GObject *obj)
1698
1682
{
1699
 
        PanelWidget *panel;
1700
 
 
1701
 
        g_return_if_fail (PANEL_IS_WIDGET (obj));
1702
 
 
1703
 
        panel = PANEL_WIDGET (obj);
 
1683
        PanelWidget *panel = PANEL_WIDGET (obj);
1704
1684
 
1705
1685
        panels = g_slist_remove (panels, panel);
1706
1686
 
1707
1687
        panel_widget_destroy_open_dialogs (panel);
1708
1688
 
1709
 
        if (panel->master_widget != NULL) {
1710
 
                g_object_set_data (G_OBJECT (panel->master_widget),
1711
 
                                   PANEL_APPLET_ASSOC_PANEL_KEY,
1712
 
                                   NULL);
1713
 
                g_object_remove_weak_pointer (G_OBJECT (panel->master_widget),
1714
 
                                              (gpointer *) &panel->master_widget);
1715
 
                panel->master_widget = NULL;
1716
 
        }
1717
 
 
1718
 
        if (GTK_OBJECT_CLASS (panel_widget_parent_class)->destroy)
1719
 
                GTK_OBJECT_CLASS (panel_widget_parent_class)->destroy (obj);
 
1689
        G_OBJECT_CLASS (panel_widget_parent_class)->dispose (obj);
1720
1690
}
1721
1691
 
1722
1692
static void
1733
1703
        panel->thick         = PANEL_MINIMUM_WIDTH;
1734
1704
        panel->size          = G_MAXINT;
1735
1705
        panel->applet_list   = NULL;
1736
 
        panel->master_widget = NULL;
1737
1706
        panel->drop_widget   = widget;
1738
1707
        panel->open_dialogs  = NULL;
1739
1708
 
1782
1751
 
1783
1752
static gboolean
1784
1753
panel_widget_applet_drag_start_no_grab (PanelWidget *panel,
1785
 
                                        GtkWidget *applet,
1786
 
                                        int drag_off)
 
1754
                                        GtkWidget *applet)
1787
1755
{
1788
1756
        AppletData *ad;
1789
1757
        AppletInfo *info;
1794
1762
        ad = g_object_get_data (G_OBJECT (applet), PANEL_APPLET_DATA);
1795
1763
        g_return_val_if_fail (ad != NULL, FALSE);
1796
1764
 
1797
 
        if (ad->locked)
1798
 
                return FALSE;
1799
 
 
1800
1765
        /* Check if we can actually move this object in the
1801
1766
           configuration */
1802
1767
        info = g_object_get_data (G_OBJECT (applet), "applet_info");
1815
1780
                  g_type_name(G_TYPE_FROM_INSTANCE (applet)), applet);
1816
1781
#endif
1817
1782
        panel->currently_dragged_applet = ad;
1818
 
        if (drag_off == PW_DRAG_OFF_CURSOR)
1819
 
                ad->drag_off = panel_widget_get_cursorloc (panel) - ad->constrained;
1820
 
        else if (drag_off == PW_DRAG_OFF_CENTER)
1821
 
                ad->drag_off = ad->cells / 2;
1822
 
        else
1823
 
                ad->drag_off = drag_off;
1824
1783
 
1825
1784
        add_all_move_bindings (panel);
1826
1785
 
1848
1807
                moving_timeout = 0;
1849
1808
                been_moved = FALSE;
1850
1809
        }
 
1810
 
 
1811
        /* Make sure we keep our indexes in a 0:n range, instead of a x:x+n
 
1812
         * range, with a growing x. Note that this is useful not only because
 
1813
         * of moves, but also because of removal of objects (object 0 could be
 
1814
         * removed, but if there is still object 1, we start growing the
 
1815
         * range). But doing this compress only once in a while, after moving
 
1816
         * objects is good enough, since this is nothing urgent and the user
 
1817
         * will move objects before this becomes a real annoying issue. */
 
1818
        panel_widget_compress_pack_indexes (panel);
1851
1819
}
1852
1820
 
1853
1821
void
1854
1822
panel_widget_applet_drag_start (PanelWidget *panel,
1855
1823
                                GtkWidget   *applet,
1856
 
                                int          drag_off,
1857
1824
                                guint32      time_)
1858
1825
{
1859
1826
        GdkWindow *window;
1866
1833
                  g_type_name(G_TYPE_FROM_INSTANCE(applet)), applet);
1867
1834
#endif
1868
1835
 
1869
 
        if (!panel_widget_applet_drag_start_no_grab (panel, applet, drag_off))
 
1836
        if (!panel_widget_applet_drag_start_no_grab (panel, applet))
1870
1837
                return;
1871
1838
 
1872
1839
        panel_toplevel_push_autohide_disabler (panel->toplevel);
1877
1844
        if (window) {
1878
1845
                GdkGrabStatus  status;
1879
1846
                GdkCursor     *fleur_cursor;
 
1847
                GdkDisplay    *display;
 
1848
                GdkDevice     *pointer;
 
1849
                GdkDeviceManager *device_manager;
1880
1850
 
1881
1851
                fleur_cursor = gdk_cursor_new (GDK_FLEUR);
1882
1852
 
1883
 
                status = gdk_pointer_grab (window, FALSE,
1884
 
                                           APPLET_EVENT_MASK, NULL,
1885
 
                                           fleur_cursor, time_);
 
1853
                display = gdk_window_get_display (window);
 
1854
                device_manager = gdk_display_get_device_manager (display);
 
1855
                pointer = gdk_device_manager_get_client_pointer (device_manager);
 
1856
                status = gdk_device_grab (pointer, window,
 
1857
                                          GDK_OWNERSHIP_NONE, FALSE,
 
1858
                                          APPLET_EVENT_MASK,
 
1859
                                          fleur_cursor, time_);
1886
1860
 
1887
 
                gdk_cursor_unref (fleur_cursor);
 
1861
                g_object_unref (fleur_cursor);
1888
1862
                gdk_flush ();
1889
1863
 
1890
1864
                if (status != GDK_GRAB_SUCCESS) {
1898
1872
void
1899
1873
panel_widget_applet_drag_end (PanelWidget *panel)
1900
1874
{
 
1875
        GdkDisplay    *display;
 
1876
        GdkDevice     *pointer;
 
1877
        GdkDeviceManager *device_manager;
 
1878
 
1901
1879
        g_return_if_fail (PANEL_IS_WIDGET (panel));
1902
1880
 
1903
1881
        if (panel->currently_dragged_applet == NULL)
1904
1882
                return;
1905
 
        gdk_pointer_ungrab (GDK_CURRENT_TIME);
 
1883
 
 
1884
        display = gtk_widget_get_display (GTK_WIDGET (panel));
 
1885
        device_manager = gdk_display_get_device_manager (display);
 
1886
        pointer = gdk_device_manager_get_client_pointer (device_manager);
 
1887
 
 
1888
        gdk_device_ungrab (pointer, GDK_CURRENT_TIME);
1906
1889
        gtk_grab_remove (panel->currently_dragged_applet->applet);
1907
1890
        panel_widget_applet_drag_end_no_grab (panel);
1908
1891
        panel_toplevel_pop_autohide_disabler (panel->toplevel);
1927
1910
                return y;
1928
1911
}
1929
1912
 
1930
 
/*calculates the value to move the applet by*/
1931
 
static int
1932
 
panel_widget_get_moveby (PanelWidget *panel, int pos, int offset)
1933
 
{
1934
 
        g_return_val_if_fail (PANEL_IS_WIDGET (panel), -1);
1935
 
 
1936
 
        return panel_widget_get_cursorloc (panel) - offset - pos;
1937
 
}
1938
 
 
1939
 
static GList *
1940
 
walk_up_to (int pos, GList *list)
1941
 
{
1942
 
        AppletData *ad;
1943
 
 
1944
 
        g_return_val_if_fail (list != NULL, NULL);
1945
 
 
1946
 
        ad = list->data;
1947
 
 
1948
 
        if (ad->constrained <= pos &&
1949
 
            ad->constrained + ad->cells > pos)
1950
 
                return list;
1951
 
        while (list->next != NULL &&
1952
 
               ad->constrained + ad->cells <= pos) {
1953
 
                list = list->next;
1954
 
                ad = list->data;
1955
 
        }
1956
 
        while (list->prev != NULL &&
1957
 
               ad->constrained > pos) {
1958
 
                list = list->prev;
1959
 
                ad = list->data;
1960
 
        }
1961
 
        return list;
1962
 
}
1963
 
 
1964
 
static GtkWidget *
1965
 
is_in_applet (int pos, AppletData *ad)
1966
 
{
1967
 
        g_return_val_if_fail (ad != NULL, NULL);
1968
 
 
1969
 
        if (ad->constrained <= pos &&
1970
 
            ad->constrained + ad->min_cells > pos)
1971
 
                return ad->applet;
1972
 
        return NULL;
1973
 
}
1974
 
 
1975
 
static int
1976
 
panel_widget_get_free_spot (PanelWidget *panel,
1977
 
                            AppletData  *ad,
1978
 
                            int          place)
1979
 
{
1980
 
        int i, e;
1981
 
        int start;
1982
 
        int right = -1, left = -1;
1983
 
        GList *list;
1984
 
 
1985
 
        g_return_val_if_fail (PANEL_IS_WIDGET (panel), -1);
1986
 
        g_return_val_if_fail (ad != NULL, -1);
1987
 
 
1988
 
        if (ad->constrained >= panel->size)
1989
 
                return -1;
1990
 
 
1991
 
        if (panel->applet_list == NULL) {
1992
 
                if (place + ad->min_cells > panel->size)
1993
 
                        return panel->size-ad->min_cells;
1994
 
                else
1995
 
                        return place;
1996
 
        }
1997
 
 
1998
 
        list = panel->applet_list;
1999
 
 
2000
 
        start = place - ad->drag_off;
2001
 
        if (start < 0)
2002
 
                start = 0;
2003
 
        for (e = 0, i = start; i < panel->size; i++) {
2004
 
                GtkWidget *applet;
2005
 
                list = walk_up_to (i, list);
2006
 
                applet = is_in_applet (i, list->data);
2007
 
                if (applet == NULL ||
2008
 
                    applet == ad->applet) {
2009
 
                        e++;
2010
 
                        if (e >= ad->min_cells) {
2011
 
                                right = i - e + 1;
2012
 
                                break;
2013
 
                        }
2014
 
                } else {
2015
 
                        e = 0;
2016
 
                }
2017
 
        }
2018
 
 
2019
 
        start = place + ad->drag_off;
2020
 
        if (start >= panel->size)
2021
 
                start = panel->size - 1;
2022
 
        for (e = 0, i = start; i >= 0; i--) {
2023
 
                GtkWidget *applet;
2024
 
                list = walk_up_to (i, list);
2025
 
                applet = is_in_applet (i, list->data);
2026
 
                if (applet == NULL ||
2027
 
                    applet == ad->applet) {
2028
 
                        e++;
2029
 
                        if (e >= ad->min_cells) {
2030
 
                                left = i;
2031
 
                                break;
2032
 
                        }
2033
 
                } else {
2034
 
                        e=0;
2035
 
                }
2036
 
        }
2037
 
 
2038
 
        start = place - ad->drag_off;
2039
 
 
2040
 
        if (left == -1) {
2041
 
                if (right == -1)
2042
 
                        return -1;
2043
 
                else
2044
 
                        return right;
2045
 
        } else {
2046
 
                if (right == -1)
2047
 
                        return left;
2048
 
                else
2049
 
                        return abs (left - start) > abs (right - start) ?
2050
 
                                right : left;
2051
 
        }
2052
 
}
2053
 
 
2054
 
static void
2055
 
panel_widget_nice_move (PanelWidget *panel,
2056
 
                        AppletData  *ad,
2057
 
                        int          pos)
2058
 
{
2059
 
        g_return_if_fail (PANEL_IS_WIDGET (panel));
2060
 
        g_return_if_fail (ad != NULL);
2061
 
 
2062
 
        pos = panel_widget_get_free_spot (panel, ad, pos);
2063
 
        if (pos < 0 || pos == ad->pos)
2064
 
                return;
2065
 
 
2066
 
        ad->pos = ad->constrained = pos;
2067
 
 
2068
 
        panel->applet_list =
2069
 
                panel_g_list_resort_item (panel->applet_list, ad,
2070
 
                                          (GCompareFunc)applet_data_compare);
2071
 
 
2072
 
        gtk_widget_queue_resize (GTK_WIDGET (panel));
2073
 
 
2074
 
        emit_applet_moved (panel, ad);
 
1913
/* get pack type & index for insertion at the cursor location in panel */
 
1914
void
 
1915
panel_widget_get_insert_at_cursor (PanelWidget         *widget,
 
1916
                                   PanelObjectPackType *pack_type,
 
1917
                                   int                 *pack_index)
 
1918
{
 
1919
        int         pos;
 
1920
        GList      *l;
 
1921
        AppletData *ad;
 
1922
 
 
1923
        g_return_if_fail (PANEL_IS_WIDGET (widget));
 
1924
 
 
1925
        pos = panel_widget_get_cursorloc (widget);
 
1926
 
 
1927
        /* check if cursor is in an object; in this case, return the pack type
 
1928
         * of the object */
 
1929
        for (l = widget->applet_list; l; l = l->next) {
 
1930
                ad = l->data;
 
1931
 
 
1932
                if (ad->constrained <= pos) {
 
1933
                        if (ad->constrained + ad->cells > pos) {
 
1934
                                *pack_type = ad->pack_type;
 
1935
                                *pack_index = ad->pack_index;
 
1936
                        }
 
1937
                } else
 
1938
                        break;
 
1939
        }
 
1940
 
 
1941
        if (pos <= widget->size / 2)
 
1942
                *pack_type = PANEL_OBJECT_PACK_START;
 
1943
        else
 
1944
                *pack_type = PANEL_OBJECT_PACK_END;
 
1945
 
 
1946
        *pack_index = panel_widget_get_new_pack_index (widget, *pack_type);
 
1947
}
 
1948
 
 
1949
/* get pack type for insertion at the cursor location in panel */
 
1950
PanelObjectPackType
 
1951
panel_widget_get_insert_pack_type_at_cursor (PanelWidget *panel)
 
1952
{
 
1953
        PanelObjectPackType ret = PANEL_OBJECT_PACK_START;
 
1954
        int                 pack_index = 0;
 
1955
 
 
1956
        panel_widget_get_insert_at_cursor (panel, &ret, &pack_index);
 
1957
 
 
1958
        return ret;
 
1959
}
 
1960
 
 
1961
/* get index for insertion with pack type */
 
1962
int
 
1963
panel_widget_get_new_pack_index (PanelWidget         *panel,
 
1964
                                 PanelObjectPackType  pack_type)
 
1965
{
 
1966
        GList      *l;
 
1967
        AppletData *ad;
 
1968
        int         max_pack_index = -1;
 
1969
 
 
1970
        for (l = panel->applet_list; l; l = l->next) {
 
1971
                ad = l->data;
 
1972
                if (ad->pack_type == pack_type)
 
1973
                        max_pack_index = MAX (max_pack_index, ad->pack_index);
 
1974
        }
 
1975
 
 
1976
        return max_pack_index + 1;
2075
1977
}
2076
1978
 
2077
1979
/* schedule to run the below function */
2081
1983
static void
2082
1984
panel_widget_applet_move_to_cursor (PanelWidget *panel)
2083
1985
{
2084
 
        int moveby;
2085
 
        int pos;
2086
1986
        int movement;
2087
1987
        GtkWidget *applet;
2088
 
        GSList *forb;
2089
 
        GdkModifierType mods;
2090
1988
        AppletData *ad;
2091
1989
 
2092
1990
        g_return_if_fail(PANEL_IS_WIDGET(panel));
2096
1994
 
2097
1995
        ad = panel->currently_dragged_applet;
2098
1996
 
2099
 
        pos = ad->constrained;
2100
 
 
2101
1997
        applet = ad->applet;
2102
1998
        g_assert(GTK_IS_WIDGET(applet));
2103
 
        forb = g_object_get_data (G_OBJECT(applet),
2104
 
                                  PANEL_APPLET_FORBIDDEN_PANELS);
2105
1999
 
2106
 
        if(!panel_widget_is_cursor(panel,10)) {
 
2000
        if(!panel_widget_is_cursor(panel,10) &&
 
2001
           !panel_lockdown_get_panels_locked_down_s ()) {
2107
2002
                GSList *list;
2108
2003
 
2109
2004
                for(list=panels;
2115
2010
                        if (panel != new_panel &&
2116
2011
                            panel_widget_is_cursor (new_panel,10) &&
2117
2012
                            panel_screen_from_panel_widget (panel) ==
2118
 
                            panel_screen_from_panel_widget (new_panel) &&
2119
 
                            !g_slist_find (forb, new_panel) &&
2120
 
                            !panel_lockdown_get_locked_down ()) {
2121
 
                                pos = panel_widget_get_moveby (new_panel, 0, ad->drag_off);
 
2013
                            panel_screen_from_panel_widget (new_panel)) {
 
2014
                                PanelObjectPackType pack_type = PANEL_OBJECT_PACK_START;
 
2015
                                int                 pack_index = 0;
2122
2016
 
2123
 
                                if (pos < 0) pos = 0;
 
2017
                                panel_widget_get_insert_at_cursor (new_panel,
 
2018
                                                                   &pack_type,
 
2019
                                                                   &pack_index);
2124
2020
 
2125
2021
                                panel_widget_applet_drag_end (panel);
2126
2022
 
2127
2023
                                /*disable reentrancy into this function*/
2128
 
                                if (!panel_widget_reparent (panel, new_panel, applet, pos)) {
 
2024
                                if (!panel_widget_reparent (panel, new_panel, applet,
 
2025
                                                            pack_type, pack_index)) {
2129
2026
                                        panel_widget_applet_drag_start (
2130
 
                                                panel, applet, ad->drag_off, GDK_CURRENT_TIME);
 
2027
                                                panel, applet, GDK_CURRENT_TIME);
2131
2028
                                        continue;
2132
2029
                                }
2133
2030
 
2134
2031
                                panel_widget_applet_drag_start (
2135
 
                                        new_panel, applet, ad->drag_off, GDK_CURRENT_TIME);
 
2032
                                        new_panel, applet, GDK_CURRENT_TIME);
2136
2033
                                schedule_try_move (new_panel, TRUE);
2137
2034
 
2138
2035
                                return;
2140
2037
                }
2141
2038
        }
2142
2039
 
2143
 
        gdk_window_get_pointer(gtk_widget_get_window (GTK_WIDGET(panel)),
2144
 
                               NULL,NULL,&mods);
2145
 
 
2146
2040
        movement = PANEL_SWITCH_MOVE;
2147
2041
 
2148
2042
        if (panel->packed) {
2149
2043
                movement = PANEL_SWITCH_MOVE;
2150
2044
        } else {
2151
 
                if (mods & GDK_CONTROL_MASK)
 
2045
                if (panel->dragged_state & GDK_CONTROL_MASK)
2152
2046
                        movement = PANEL_SWITCH_MOVE;
2153
 
                else if (mods & GDK_SHIFT_MASK)
 
2047
                else if (panel->dragged_state & GDK_SHIFT_MASK)
2154
2048
                        movement = PANEL_PUSH_MOVE;
2155
 
                else if (mods & GDK_MOD1_MASK)
2156
 
                        movement = PANEL_FREE_MOVE;
2157
2049
        }
2158
2050
        
2159
2051
        switch (movement) {
2160
2052
        case PANEL_SWITCH_MOVE:
2161
 
                moveby = panel_widget_get_moveby (panel, pos, ad->drag_off);
2162
 
                panel_widget_switch_move (panel, ad, moveby);
2163
 
                break;
2164
 
        case PANEL_FREE_MOVE:
2165
 
                panel_widget_nice_move (panel, ad, panel_widget_get_cursorloc (panel));
 
2053
                panel_widget_switch_move (panel, ad);
2166
2054
                break;
2167
2055
        case PANEL_PUSH_MOVE:
2168
 
                moveby = panel_widget_get_moveby (panel, pos, ad->drag_off);
2169
 
                panel_widget_push_move (panel, ad, moveby);
 
2056
                panel_widget_push_move (panel, ad, 0);
2170
2057
                break;
2171
2058
        }
2172
2059
}
2233
2120
{
2234
2121
        GtkWidget   *parent;
2235
2122
        PanelWidget *panel;
 
2123
        guint        modifiers;
2236
2124
        guint32      event_time;
2237
2125
 
2238
2126
        parent = gtk_widget_get_parent (widget);
2250
2138
                return TRUE;
2251
2139
        }
2252
2140
 
2253
 
        /* Begin drag if the middle mouse button is pressed, unless the panel
2254
 
         * is locked down or a grab is active (meaning a menu is open) */
2255
 
        if (panel_lockdown_get_locked_down () || event->button != 2 ||
 
2141
        modifiers = event->state & gtk_accelerator_get_default_mod_mask ();
 
2142
 
 
2143
        /* Begin drag if the middle mouse button and modifier are pressed,
 
2144
         * unless the panel is locked down or a grab is active (meaning a menu
 
2145
         * is open) */
 
2146
        if (panel_lockdown_get_panels_locked_down_s () ||
 
2147
            event->button != 2 ||
 
2148
            modifiers != panel_bindings_get_mouse_button_modifier_keymask () ||
2256
2149
            gtk_grab_get_current() != NULL)
2257
2150
                return FALSE;
2258
2151
 
2261
2154
        if (event->send_event)
2262
2155
                event_time = GDK_CURRENT_TIME;
2263
2156
 
2264
 
        panel_widget_applet_drag_start (panel, widget, PW_DRAG_OFF_CURSOR, event_time);
 
2157
        panel_widget_applet_drag_start (panel, widget, event_time);
2265
2158
 
2266
2159
        return TRUE;
2267
2160
}
2307
2200
                return FALSE;
2308
2201
 
2309
2202
        panel = PANEL_WIDGET (parent);
 
2203
        panel->dragged_state = ((GdkEventMotion *) event)->state & GDK_MODIFIER_MASK;
2310
2204
        
2311
2205
        schedule_try_move (panel, FALSE);
2312
2206
 
2329
2223
        if (!panel_applet_in_drag)
2330
2224
                return FALSE;
2331
2225
        
2332
 
        return gtk_bindings_activate (GTK_OBJECT (panel),
 
2226
        return gtk_bindings_activate (G_OBJECT (panel),
2333
2227
                                      ((GdkEventKey *)event)->keyval, 
2334
2228
                                      ((GdkEventKey *)event)->state);   
2335
2229
}
2450
2344
                                       bind_applet_events, widget);
2451
2345
}
2452
2346
 
2453
 
static int
2454
 
panel_widget_find_empty_pos(PanelWidget *panel, int pos)
2455
 
{
2456
 
        int i;
2457
 
        int right=-1,left=-1;
2458
 
        GList *list;
2459
 
 
2460
 
        g_return_val_if_fail(PANEL_IS_WIDGET(panel),-1);
2461
 
 
2462
 
        if(pos>=panel->size)
2463
 
                pos = panel->size-1;
2464
 
 
2465
 
        if (pos <= 0)
2466
 
                pos = 0;
2467
 
 
2468
 
        if(!panel->applet_list)
2469
 
                return pos;
2470
 
 
2471
 
        list = panel->applet_list;
2472
 
 
2473
 
        for (i = pos; i < panel->size; i++) {
2474
 
                list = walk_up_to (i, list);
2475
 
                if ( ! is_in_applet (i, list->data)) {
2476
 
                        right = i;
2477
 
                        break;
2478
 
                }
2479
 
        }
2480
 
 
2481
 
        for(i = pos; i >= 0; i--) {
2482
 
                list = walk_up_to (i, list);
2483
 
                if ( ! is_in_applet (i, list->data)) {
2484
 
                        left = i;
2485
 
                        break;
2486
 
                }
2487
 
        }
2488
 
 
2489
 
        if (left == -1) {
2490
 
                if (right == -1)
2491
 
                        return -1;
2492
 
                else
2493
 
                        return right;
2494
 
        } else {
2495
 
                if (right == -1)
2496
 
                        return left;
2497
 
                else
2498
 
                        return abs (left - pos) > abs (right - pos) ?
2499
 
                                right : left;
2500
 
        }
2501
 
}
2502
 
 
2503
2347
void
2504
 
panel_widget_add_forbidden (PanelWidget *panel)
2505
 
{
2506
 
        g_return_if_fail (panel != NULL);
2507
 
        g_return_if_fail (PANEL_IS_WIDGET (panel));
2508
 
 
2509
 
        add_panel_to_forbidden (panel, panel);
2510
 
}
2511
 
 
2512
 
int
2513
 
panel_widget_add (PanelWidget *panel,
2514
 
                  GtkWidget   *applet,
2515
 
                  gboolean     locked,
2516
 
                  int          pos,
2517
 
                  gboolean     insert_at_pos)
 
2348
panel_widget_add (PanelWidget         *panel,
 
2349
                  GtkWidget           *applet,
 
2350
                  PanelObjectPackType  pack_type,
 
2351
                  int                  pack_index,
 
2352
                  gboolean             use_pack_index)
2518
2353
{
2519
2354
        AppletData *ad = NULL;
2520
2355
 
2521
 
        g_return_val_if_fail (PANEL_IS_WIDGET (panel), -1);
2522
 
        g_return_val_if_fail (GTK_IS_WIDGET (applet), -1);
 
2356
        g_return_if_fail (PANEL_IS_WIDGET (panel));
 
2357
        g_return_if_fail (GTK_IS_WIDGET (applet));
2523
2358
 
2524
2359
        ad = g_object_get_data (G_OBJECT (applet), PANEL_APPLET_DATA);
2525
2360
 
2526
 
        if (ad != NULL)
2527
 
                pos = ad->pos;
 
2361
        if (ad != NULL) {
 
2362
                pack_type = ad->pack_type;
 
2363
                pack_index = ad->pack_index;
 
2364
        }
2528
2365
 
2529
 
        if (!insert_at_pos || pos < 0) {
 
2366
        if (!use_pack_index || pack_index < 0) {
2530
2367
                if (panel->packed) {
2531
 
                        if (get_applet_list_pos (panel, pos)) 
2532
 
                                /*this is a slight hack so that this applet
2533
 
                                  is inserted AFTER an applet with this pos
2534
 
                                  number*/
2535
 
                                pos++;
 
2368
                        /* add at the end of packed panels */
 
2369
                        AppletData *ad;
 
2370
                        GList *list,*l;
 
2371
 
 
2372
                        list = get_applet_list_pack (panel, PANEL_OBJECT_PACK_END);
 
2373
                        if (list) {
 
2374
                                for (l = list; l; l = l->next) {
 
2375
                                        ad = l->data;
 
2376
                                        ad->pack_index += 1;
 
2377
                                        emit_applet_moved (panel, ad);
 
2378
                                }
 
2379
                                pack_type = PANEL_OBJECT_PACK_END;
 
2380
                                pack_index = 0;
 
2381
                        } else {
 
2382
                                list = get_applet_list_pack (panel, PANEL_OBJECT_PACK_CENTER);
 
2383
                                if (!list)
 
2384
                                        list = get_applet_list_pack (panel, PANEL_OBJECT_PACK_START);
 
2385
 
 
2386
                                if (!list) {
 
2387
                                        pack_type = PANEL_OBJECT_PACK_START;
 
2388
                                        pack_index = 0;
 
2389
                                } else {
 
2390
                                        l = g_list_last (list);
 
2391
                                        AppletData *ad = l->data;
 
2392
                                        pack_type = ad->pack_type;
 
2393
                                        pack_index = ad->pack_index + 1;
 
2394
                                }
 
2395
                        }
 
2396
 
 
2397
                        g_list_free (list);
2536
2398
                } else {
2537
 
                        int newpos = panel_widget_find_empty_pos (panel, pos);
2538
 
                        if (newpos >= 0)
2539
 
                                pos = newpos;
2540
 
                        else if (get_applet_list_pos (panel, pos)) 
2541
 
                                /*this is a slight hack so that this applet
2542
 
                                  is inserted AFTER an applet with this pos
2543
 
                                  number*/
2544
 
                                pos++;
 
2399
                        GList *list,*l;
 
2400
 
 
2401
                        /* only support adding to start/end packs if no index
 
2402
                         * is provided */
 
2403
                        if (pack_type == PANEL_OBJECT_PACK_CENTER)
 
2404
                                pack_type = PANEL_OBJECT_PACK_START;
 
2405
 
 
2406
                        list = get_applet_list_pack (panel, pack_type);
 
2407
 
 
2408
                        l = NULL;
 
2409
                        if (pack_type == PANEL_OBJECT_PACK_START)
 
2410
                                l = g_list_last (list);
 
2411
                        else if  (pack_type == PANEL_OBJECT_PACK_END)
 
2412
                                l = list;
 
2413
                        else
 
2414
                                g_assert_not_reached ();
 
2415
 
 
2416
                        if (!l)
 
2417
                                pack_index = 0;
 
2418
                        else {
 
2419
                                AppletData *ad = l->data;
 
2420
                                pack_index = ad->pack_index + 1;
 
2421
                        }
 
2422
 
 
2423
                        g_list_free (list);
2545
2424
                }
2546
2425
        }
2547
2426
 
2548
 
        if(pos==-1) return -1;
2549
 
 
2550
2427
        if (ad == NULL) {
2551
2428
                ad = g_new (AppletData, 1);
2552
2429
                ad->applet = applet;
2553
2430
                ad->cells = 1;
2554
2431
                ad->min_cells = 1;
2555
 
                ad->pos = pos;
2556
 
                ad->constrained = pos;
2557
 
                ad->drag_off = 0;
2558
 
                ad->no_die = 0;
 
2432
                ad->pack_type = pack_type;
 
2433
                ad->pack_index = pack_index;
 
2434
                ad->constrained = 0;
2559
2435
                ad->size_constrained = FALSE;
2560
2436
                ad->expand_major = FALSE;
2561
2437
                ad->expand_minor = FALSE;
2562
 
                ad->locked = locked;
2563
2438
                ad->size_hints = NULL;
2564
2439
                g_object_set_data (G_OBJECT (applet),
2565
2440
                                   PANEL_APPLET_DATA, ad);
2572
2447
                g_list_insert_sorted(panel->applet_list,ad,
2573
2448
                                     (GCompareFunc)applet_data_compare);
2574
2449
 
2575
 
        /*this will get done right on size allocate!*/
2576
 
        if(panel->orient == GTK_ORIENTATION_HORIZONTAL)
2577
 
                gtk_fixed_put(GTK_FIXED(panel),applet,
2578
 
                              pos,0);
2579
 
        else
2580
 
                gtk_fixed_put(GTK_FIXED(panel),applet,
2581
 
                              0,pos);
2582
 
 
 
2450
        /* the applet will be positioned on size allocate */
 
2451
        gtk_fixed_put (GTK_FIXED (panel), applet, 0, 0);
2583
2452
 
2584
2453
        gtk_widget_queue_resize(GTK_WIDGET(panel));
2585
2454
 
2586
2455
        g_signal_emit (G_OBJECT(panel),
2587
2456
                       panel_widget_signals[APPLET_ADDED_SIGNAL],
2588
2457
                       0, applet);
2589
 
        
2590
 
        /*NOTE: forbidden list is not updated on addition, use the
2591
 
        function above for the panel*/
2592
 
 
2593
 
        return pos;
2594
2458
}
2595
2459
 
2596
2460
gboolean
2597
 
panel_widget_reparent (PanelWidget *old_panel,
2598
 
                       PanelWidget *new_panel,
2599
 
                       GtkWidget *applet,
2600
 
                       int pos)
 
2461
panel_widget_reparent (PanelWidget         *old_panel,
 
2462
                       PanelWidget         *new_panel,
 
2463
                       GtkWidget           *applet,
 
2464
                       PanelObjectPackType  pack_type,
 
2465
                       int                  pack_index)
2601
2466
{
2602
2467
        AppletData *ad;
2603
2468
        GtkWidget *focus_widget = NULL;
2606
2471
        g_return_val_if_fail(PANEL_IS_WIDGET(old_panel), FALSE);
2607
2472
        g_return_val_if_fail(PANEL_IS_WIDGET(new_panel), FALSE);
2608
2473
        g_return_val_if_fail(GTK_IS_WIDGET(applet), FALSE);
2609
 
        g_return_val_if_fail(pos>=0, FALSE);
 
2474
        g_return_val_if_fail(pack_index>=0, FALSE);
2610
2475
 
2611
2476
        ad = g_object_get_data (G_OBJECT (applet), PANEL_APPLET_DATA);
2612
2477
        g_return_val_if_fail(ad!=NULL, FALSE);
2619
2484
        
2620
2485
        info = g_object_get_data (G_OBJECT (ad->applet), "applet_info");
2621
2486
 
2622
 
        ad->pos = ad->constrained = panel_widget_get_free_spot (new_panel, ad, pos);
2623
 
        if (ad->pos == -1)
2624
 
                ad->pos = ad->constrained = 0;
 
2487
        panel_widget_move_to_pack (new_panel, ad, pack_type, pack_index);
 
2488
 
 
2489
        /* with reparent, we'll call cremove/cadd, which will reinsert ad at
 
2490
         * the right place in the list */
2625
2491
 
2626
2492
        gtk_widget_queue_resize (GTK_WIDGET (new_panel));
2627
2493
        gtk_widget_queue_resize (GTK_WIDGET (old_panel));
2628
2494
 
2629
 
        ad->no_die++;
2630
 
 
2631
2495
        panel_widget_reset_saved_focus (old_panel);
2632
2496
        if (gtk_container_get_focus_child (GTK_CONTAINER (old_panel)) == applet)
2633
2497
                focus_widget = gtk_window_get_focus (GTK_WINDOW (old_panel->toplevel));
2651
2515
 
2652
2516
        gdk_flush();
2653
2517
 
2654
 
        ad->no_die--;
2655
 
 
2656
2518
        emit_applet_moved (new_panel, ad);
2657
2519
 
2658
2520
        return TRUE;
2710
2572
                               GtkDirectionType dir)
2711
2573
{
2712
2574
        AppletData *applet;
2713
 
        int         increment = 0;
 
2575
        int         direction = 0;
2714
2576
 
2715
2577
        applet = panel->currently_dragged_applet;
2716
2578
        g_return_if_fail (applet);
2718
2580
        switch (dir) {
2719
2581
        case GTK_DIR_LEFT:
2720
2582
        case GTK_DIR_UP:
2721
 
                increment = -MOVE_INCREMENT;
 
2583
                direction = -1;
2722
2584
                break;
2723
2585
        case GTK_DIR_RIGHT:
2724
2586
        case GTK_DIR_DOWN:
2725
 
                increment = MOVE_INCREMENT;
 
2587
                direction = 1;
2726
2588
                break;
2727
2589
        default:
2728
2590
                return;
2729
2591
        }
2730
2592
 
2731
 
        panel_widget_push_move (panel, applet, increment);
 
2593
        panel_widget_push_move (panel, applet, direction);
2732
2594
}
2733
2595
 
2734
2596
static void 
2747
2609
        switch (dir) {
2748
2610
        case GTK_DIR_LEFT:
2749
2611
        case GTK_DIR_UP:
2750
 
                panel_widget_switch_applet_left (panel, list);
2751
 
                break;
2752
 
        case GTK_DIR_RIGHT:
2753
 
        case GTK_DIR_DOWN:
2754
 
                panel_widget_switch_applet_right (panel, list);
2755
 
                break;
2756
 
        default:
2757
 
                return;
2758
 
        }
2759
 
}
2760
 
 
2761
 
static void 
2762
 
panel_widget_free_move_applet (PanelWidget      *panel,
2763
 
                               GtkDirectionType  dir)
2764
 
{
2765
 
        AppletData *ad;
2766
 
        gint        increment = MOVE_INCREMENT;
2767
 
 
2768
 
        ad = panel->currently_dragged_applet;
2769
 
 
2770
 
        g_return_if_fail (ad);
2771
 
 
2772
 
        switch (dir) {
2773
 
        case GTK_DIR_LEFT:
2774
 
        case GTK_DIR_UP:
2775
 
                increment = -increment;
2776
 
                break;
2777
 
        case GTK_DIR_RIGHT:
2778
 
        case GTK_DIR_DOWN:
2779
 
                break;
2780
 
        default:
2781
 
                return;
2782
 
        }
2783
 
 
2784
 
        panel_widget_nice_move (panel, ad, increment + ad->constrained + ad->drag_off);
 
2612
                panel_widget_switch_applet_left (panel, list, -1, TRUE);
 
2613
                break;
 
2614
        case GTK_DIR_RIGHT:
 
2615
        case GTK_DIR_DOWN:
 
2616
                panel_widget_switch_applet_right (panel, list, -1, TRUE);
 
2617
                break;
 
2618
        default:
 
2619
                return;
 
2620
        }
2785
2621
}
2786
2622
 
2787
2623
static void
2793
2629
        AppletData  *ad;
2794
2630
        GSList      *l;
2795
2631
 
 
2632
        if (panel_lockdown_get_panels_locked_down_s ())
 
2633
                return;
 
2634
 
2796
2635
        ad = panel->currently_dragged_applet;
2797
2636
 
2798
2637
        if (!ad)
2827
2666
                new_panel = previous_panel;
2828
2667
        
2829
2668
        if (new_panel &&
2830
 
            (new_panel != panel) &&
2831
 
            !panel_lockdown_get_locked_down ())
2832
 
                panel_widget_reparent (panel, new_panel, ad->applet, 0);
 
2669
            (new_panel != panel))
 
2670
                panel_widget_reparent (panel, new_panel, ad->applet,
 
2671
                                       PANEL_OBJECT_PACK_START, 0);
2833
2672
}
2834
2673
 
2835
2674
static void
2851
2690
void 
2852
2691
panel_widget_focus (PanelWidget *panel_widget)
2853
2692
{
2854
 
        if (panel_toplevel_get_is_attached (panel_widget->toplevel))
2855
 
                return;
2856
 
 
2857
2693
        /*
2858
2694
         * Set the focus back on the panel; we unset the focus child so that
2859
2695
         * the next time focus is inside the panel we do not remember the
2942
2778
                ad->size_hints = NULL;
2943
2779
        }
2944
2780
 
 
2781
        panel_widget_update_size_hints_for_toplevel (panel);
2945
2782
        gtk_widget_queue_resize (GTK_WIDGET (panel));
2946
2783
}
2947
2784
 
2948
 
void
2949
 
panel_widget_set_applet_locked (PanelWidget *panel,
2950
 
                                GtkWidget   *applet,
2951
 
                                gboolean     locked)
2952
 
{
2953
 
        AppletData *ad;
2954
 
 
2955
 
        ad = g_object_get_data (G_OBJECT (applet), PANEL_APPLET_DATA);
2956
 
        if (!ad)
2957
 
                return;
2958
 
 
2959
 
        ad->locked = locked;
2960
 
}
2961
 
 
2962
 
gboolean
2963
 
panel_widget_get_applet_locked (PanelWidget *panel,
2964
 
                                GtkWidget   *applet)
2965
 
{
2966
 
        AppletData *ad;
2967
 
 
2968
 
        ad = g_object_get_data (G_OBJECT (applet), PANEL_APPLET_DATA);
2969
 
        if (!ad)
2970
 
                return FALSE;
2971
 
 
2972
 
        return ad->locked;
2973
 
}
2974
 
 
2975
 
gboolean
2976
 
panel_widget_toggle_applet_locked (PanelWidget *panel,
2977
 
                                   GtkWidget   *applet)
2978
 
{
2979
 
        AppletData *ad;
2980
 
 
2981
 
        ad = g_object_get_data (G_OBJECT (applet), PANEL_APPLET_DATA);
2982
 
        if (!ad)
2983
 
                return FALSE;
2984
 
 
2985
 
        return ad->locked = !ad->locked;
2986
 
}
2987
 
 
2988
2785
gboolean
2989
2786
panel_applet_is_in_drag (void)
2990
2787
{