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

« back to all changes in this revision

Viewing changes to gnome-panel/panel-toplevel.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:
35
35
#include <gdk/gdkkeysyms.h>
36
36
#include <glib/gi18n.h>
37
37
 
38
 
#include "panel-profile.h"
 
38
#include <libpanel-util/panel-glib.h>
 
39
 
39
40
#include "panel-frame.h"
40
41
#include "panel-xutils.h"
41
42
#include "panel-multiscreen.h"
45
46
#include "panel-widget.h"
46
47
#include "panel-bindings.h"
47
48
#include "panel-struts.h"
48
 
#include "panel-config-global.h"
49
49
#include "panel-lockdown.h"
 
50
#include "panel-schemas.h"
50
51
 
51
52
G_DEFINE_TYPE (PanelToplevel, panel_toplevel, GTK_TYPE_WINDOW)
52
53
 
62
63
#define SNAP_TOLERANCE_FACTOR     6
63
64
#define DEFAULT_ARROW_SIZE        20
64
65
#define HANDLE_SIZE               10
65
 
#define N_ATTACH_TOPLEVEL_SIGNALS 5
66
 
#define N_ATTACH_WIDGET_SIGNALS   5
67
66
 
68
67
typedef enum {
69
68
        PANEL_GRAB_OP_NONE,
76
75
} PanelGrabOpType;
77
76
 
78
77
struct _PanelToplevelPrivate {
 
78
        char                   *toplevel_id;
 
79
 
 
80
        char                   *settings_path;
 
81
        GSettings              *settings;
 
82
        GSettings              *delayed_settings;
 
83
        guint                   apply_delayed_id;
 
84
 
79
85
        gboolean                expand;
80
86
        PanelOrientation        orientation;
81
87
        int                     size;
149
155
        GtkWidget              *hide_button_left;
150
156
        GtkWidget              *hide_button_right;
151
157
 
152
 
        PanelToplevel          *attach_toplevel;
153
 
        gulong                  attach_toplevel_signals [N_ATTACH_TOPLEVEL_SIGNALS];
154
 
        GtkWidget              *attach_widget;
155
 
        gulong                  attach_widget_signals [N_ATTACH_WIDGET_SIGNALS];
156
158
        gint                    n_autohide_disablers;
157
159
 
158
160
        guint                   auto_hide : 1;
179
181
         * those. */
180
182
        guint                   position_centered : 1;
181
183
 
182
 
        /* The toplevel is "attached" to another widget */
183
 
        guint                   attached : 1;
184
 
 
185
 
        /* Hidden temporarily because the attach_toplevel was hidden */
186
 
        guint                   attach_hidden : 1;
187
 
 
188
184
        /* More saved grab op state */
189
185
        guint                   orig_x_centered : 1;
190
186
        guint                   orig_y_centered : 1;
211
207
 
212
208
enum {
213
209
        PROP_0,
 
210
        PROP_TOPLEVEL_ID,
 
211
        PROP_SETTINGS_PATH,
214
212
        PROP_NAME,
215
213
        PROP_EXPAND,
216
214
        PROP_ORIENTATION,
237
235
 
238
236
static void panel_toplevel_calculate_animation_end_geometry (PanelToplevel *toplevel);
239
237
 
 
238
static gboolean panel_toplevel_position_is_writable (PanelToplevel *toplevel);
 
239
 
 
240
static void panel_toplevel_bind_gsettings       (PanelToplevel *toplevel);
 
241
static void panel_toplevel_set_toplevel_id      (PanelToplevel *toplevel,
 
242
                                                 const char    *toplevel_id);
 
243
static void panel_toplevel_set_settings_path    (PanelToplevel *toplevel,
 
244
                                                 const char    *settings_path);
 
245
static void panel_toplevel_set_animate          (PanelToplevel *toplevel,
 
246
                                                 gboolean       animate);
 
247
 
240
248
static void panel_toplevel_update_monitor       (PanelToplevel *toplevel);
241
249
static void panel_toplevel_set_monitor_internal (PanelToplevel *toplevel,
242
250
                                                 int            monitor,
249
257
        return toplevel_list;
250
258
}
251
259
 
252
 
/* Is this the last un-attached toplevel? */
 
260
PanelToplevel *
 
261
panel_toplevel_get_by_id (const char *toplevel_id)
 
262
{
 
263
        GSList *l;
 
264
 
 
265
        if (PANEL_GLIB_STR_EMPTY (toplevel_id))
 
266
                return NULL;
 
267
 
 
268
        for (l = toplevel_list; l; l = l->next) {
 
269
                PanelToplevel *toplevel = l->data;
 
270
 
 
271
                if (!g_strcmp0 (toplevel->priv->toplevel_id, toplevel_id))
 
272
                        return toplevel;
 
273
        }
 
274
 
 
275
        return NULL;
 
276
}
 
277
 
253
278
gboolean
254
 
panel_toplevel_is_last_unattached (PanelToplevel *toplevel)
 
279
panel_toplevel_is_last (PanelToplevel *toplevel)
255
280
{
256
281
        GSList *l;
257
282
 
258
 
        if (panel_toplevel_get_is_attached (toplevel))
259
 
                return FALSE;
260
 
 
261
283
        for (l = toplevel_list; l; l = l->next) {
262
 
                PanelToplevel *t = l->data;
263
 
 
264
 
                if (t != toplevel && !panel_toplevel_get_is_attached (t))
 
284
                if (l->data != toplevel)
265
285
                        return FALSE;
266
286
        }
267
287
 
268
288
        return TRUE;
269
289
}
270
290
 
 
291
gboolean
 
292
panel_toplevel_find_empty_spot (GdkScreen        *screen,
 
293
                                PanelOrientation *orientation,
 
294
                                int              *monitor)
 
295
{
 
296
        int      *filled_spots;
 
297
        GSList   *li;
 
298
        int       i;
 
299
        gboolean  found_a_spot = FALSE;
 
300
 
 
301
        *monitor = 0;
 
302
        *orientation = PANEL_ORIENTATION_TOP;
 
303
 
 
304
        filled_spots = g_new0 (int, panel_multiscreen_monitors (screen));
 
305
 
 
306
        for (li = panel_toplevel_list_toplevels (); li != NULL; li = li->next) {
 
307
                PanelToplevel *toplevel = li->data;
 
308
                GdkScreen *toplevel_screen = gtk_window_get_screen (GTK_WINDOW (toplevel));
 
309
                int toplevel_monitor = panel_toplevel_get_monitor (toplevel);
 
310
 
 
311
                if (toplevel_screen != screen ||
 
312
                    toplevel_monitor < 0)
 
313
                        continue;
 
314
 
 
315
                filled_spots[toplevel_monitor] |= panel_toplevel_get_orientation (toplevel);
 
316
        }
 
317
 
 
318
        for (i = 0; i < panel_multiscreen_monitors (screen); i++) {
 
319
                /* These are ordered based on "priority" of the
 
320
                   orientation when picking it */
 
321
                if ( ! (filled_spots[i] & PANEL_ORIENTATION_TOP)) {
 
322
                        *orientation = PANEL_ORIENTATION_TOP;
 
323
                        *monitor = i;
 
324
                        found_a_spot = TRUE;
 
325
                        break;
 
326
                } else if ( ! (filled_spots[i] & PANEL_ORIENTATION_BOTTOM)) {
 
327
                        *orientation = PANEL_ORIENTATION_BOTTOM;
 
328
                        *monitor = i;
 
329
                        found_a_spot = TRUE;
 
330
                        break;
 
331
                } else if ( ! (filled_spots[i] & PANEL_ORIENTATION_RIGHT)) {
 
332
                        *orientation = PANEL_ORIENTATION_RIGHT;
 
333
                        *monitor = i;
 
334
                        found_a_spot = TRUE;
 
335
                        break;
 
336
                } else if ( ! (filled_spots[i] & PANEL_ORIENTATION_LEFT)) {
 
337
                        *orientation = PANEL_ORIENTATION_LEFT;
 
338
                        *monitor = i;
 
339
                        found_a_spot = TRUE;
 
340
                        break;
 
341
                }
 
342
        }
 
343
 
 
344
        g_free (filled_spots);
 
345
 
 
346
        return found_a_spot;
 
347
}
271
348
 
272
349
static GdkScreen *
273
350
panel_toplevel_get_screen_geometry (PanelToplevel *toplevel,
422
499
}
423
500
 
424
501
static void
425
 
panel_toplevel_begin_attached_move (PanelToplevel *toplevel,
426
 
                                    gboolean       is_keyboard,
427
 
                                    guint32        time_)
428
 
{
429
 
        PanelWidget *attached_panel_widget;
430
 
 
431
 
        attached_panel_widget = panel_toplevel_get_panel_widget (toplevel->priv->attach_toplevel);
432
 
 
433
 
        panel_widget_applet_drag_start (attached_panel_widget,
434
 
                                        toplevel->priv->attach_widget,
435
 
                                        is_keyboard ? PW_DRAG_OFF_CENTER : PW_DRAG_OFF_CURSOR,
436
 
                                        time_);
437
 
}
438
 
 
439
 
static void
440
502
panel_toplevel_begin_grab_op (PanelToplevel   *toplevel,
441
503
                              PanelGrabOpType  op_type,
442
504
                              gboolean         grab_keyboard,
446
508
        GdkWindow     *window;
447
509
        GdkCursorType  cursor_type;
448
510
        GdkCursor     *cursor;
 
511
        GdkDisplay    *display;
 
512
        GdkDevice     *pointer;
 
513
        GdkDevice     *keyboard;
 
514
        GdkDeviceManager *device_manager;
449
515
 
450
516
        if (toplevel->priv->state != PANEL_STATE_NORMAL ||
451
517
            toplevel->priv->grab_op != PANEL_GRAB_OP_NONE)
452
518
                return;
453
519
 
454
 
        if (panel_lockdown_get_locked_down ())
 
520
        if (panel_lockdown_get_panels_locked_down_s ())
455
521
                return;
456
522
 
457
523
        /* If any of the position/orientation are not writable,
458
524
           then we can't really move freely */
459
525
        if (op_type == PANEL_GRAB_OP_MOVE &&
460
 
            ! panel_profile_can_be_moved_freely (toplevel))
 
526
            !panel_toplevel_position_is_writable (toplevel))
461
527
                return;
462
528
 
463
529
        /* If size is not writable, then we can't resize */
466
532
             op_type == PANEL_GRAB_OP_RESIZE_DOWN || 
467
533
             op_type == PANEL_GRAB_OP_RESIZE_LEFT || 
468
534
             op_type == PANEL_GRAB_OP_RESIZE_RIGHT) &&
469
 
            ! panel_profile_is_writable_toplevel_size (toplevel))
470
 
                return;
471
 
 
472
 
        if (toplevel->priv->attached && op_type == PANEL_GRAB_OP_MOVE) {
473
 
                panel_toplevel_begin_attached_move (toplevel, grab_keyboard, time_);
474
 
                return;
475
 
        }
 
535
            ! g_settings_is_writable (toplevel->priv->settings,
 
536
                                      PANEL_TOPLEVEL_SIZE_KEY))
 
537
                return;
476
538
 
477
539
        widget = GTK_WIDGET (toplevel);
478
540
        window = gtk_widget_get_window (widget);
499
561
                                toplevel, toplevel->priv->grab_op);
500
562
 
501
563
        cursor = gdk_cursor_new (cursor_type);
502
 
        gdk_pointer_grab (window, FALSE,
503
 
                          GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
504
 
                          NULL, cursor, time_);
505
 
        gdk_cursor_unref (cursor);
 
564
 
 
565
        display = gdk_window_get_display (window);
 
566
        device_manager = gdk_display_get_device_manager (display);
 
567
        pointer = gdk_device_manager_get_client_pointer (device_manager);
 
568
        keyboard = gdk_device_get_associated_device (pointer);
 
569
 
 
570
        gdk_device_grab (pointer, window,
 
571
                         GDK_OWNERSHIP_NONE, FALSE,
 
572
                         GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
 
573
                         cursor, time_);
 
574
 
 
575
        g_object_unref (cursor);
506
576
 
507
577
        if (grab_keyboard)
508
 
                gdk_keyboard_grab (window, FALSE, time_);
 
578
                gdk_device_grab (keyboard, window,
 
579
                                 GDK_OWNERSHIP_NONE, FALSE,
 
580
                                 GDK_KEY_PRESS | GDK_KEY_RELEASE,
 
581
                                 NULL, time_);
509
582
}
510
583
 
511
584
static void
513
586
                            guint32        time_)
514
587
{
515
588
        GtkWidget *widget;
 
589
        GdkDisplay    *display;
 
590
        GdkDevice     *pointer;
 
591
        GdkDevice     *keyboard;
 
592
        GdkDeviceManager *device_manager;
516
593
 
517
594
        g_return_if_fail (toplevel->priv->grab_op != PANEL_GRAB_OP_NONE);
518
595
 
523
600
 
524
601
        gtk_grab_remove (widget);
525
602
 
526
 
        gdk_pointer_ungrab (time_);
527
 
        gdk_keyboard_ungrab (time_);
 
603
        display = gtk_widget_get_display (widget);
 
604
        device_manager = gdk_display_get_device_manager (display);
 
605
        pointer = gdk_device_manager_get_client_pointer (device_manager);
 
606
        keyboard = gdk_device_get_associated_device (pointer);
 
607
 
 
608
        gdk_device_ungrab (pointer, time_);
 
609
        gdk_device_ungrab (keyboard, time_);
528
610
}
529
611
 
530
612
static void
851
933
        gdk_window_get_pointer (root_window, &new_x, &new_y, NULL);
852
934
 
853
935
        switch (keyval) {
854
 
        case GDK_Up:
855
 
        case GDK_KP_Up:
 
936
        case GDK_KEY_Up:
 
937
        case GDK_KEY_KP_Up:
856
938
                new_y -= increment;
857
939
                break;
858
 
        case GDK_Left:
859
 
        case GDK_KP_Left:
 
940
        case GDK_KEY_Left:
 
941
        case GDK_KEY_KP_Left:
860
942
                new_x -= increment;
861
943
                break;
862
 
        case GDK_Down:
863
 
        case GDK_KP_Down:
 
944
        case GDK_KEY_Down:
 
945
        case GDK_KEY_KP_Down:
864
946
                new_y += increment;
865
947
                break;
866
 
        case GDK_Right:
867
 
        case GDK_KP_Right:
 
948
        case GDK_KEY_Right:
 
949
        case GDK_KEY_KP_Right:
868
950
                new_x += increment;
869
951
                break;
870
952
        default:
903
985
        PanelOrientation new_orientation;
904
986
 
905
987
        switch (event->keyval) {
906
 
        case GDK_Up:
907
 
        case GDK_KP_Up:
 
988
        case GDK_KEY_Up:
 
989
        case GDK_KEY_KP_Up:
908
990
                new_orientation = PANEL_ORIENTATION_TOP;
909
991
                break;
910
 
        case GDK_Left:
911
 
        case GDK_KP_Left:
 
992
        case GDK_KEY_Left:
 
993
        case GDK_KEY_KP_Left:
912
994
                new_orientation = PANEL_ORIENTATION_LEFT;
913
995
                break;
914
 
        case GDK_Down:
915
 
        case GDK_KP_Down:
 
996
        case GDK_KEY_Down:
 
997
        case GDK_KEY_KP_Down:
916
998
                new_orientation = PANEL_ORIENTATION_BOTTOM;
917
999
                break;
918
 
        case GDK_Right:
919
 
        case GDK_KP_Right:
 
1000
        case GDK_KEY_Right:
 
1001
        case GDK_KEY_KP_Right:
920
1002
                new_orientation = PANEL_ORIENTATION_RIGHT;
921
1003
                break;
922
1004
        default:
936
1018
        PanelGrabOpType grab_op;
937
1019
 
938
1020
        switch (event->keyval) {
939
 
        case GDK_Up:
940
 
        case GDK_KP_Up:
 
1021
        case GDK_KEY_Up:
 
1022
        case GDK_KEY_KP_Up:
941
1023
                if (!(toplevel->priv->orientation & PANEL_HORIZONTAL_MASK))
942
1024
                        return FALSE;
943
1025
                grab_op = PANEL_GRAB_OP_RESIZE_UP;
944
1026
                break;
945
 
        case GDK_Left:
946
 
        case GDK_KP_Left:
 
1027
        case GDK_KEY_Left:
 
1028
        case GDK_KEY_KP_Left:
947
1029
                if (!(toplevel->priv->orientation & PANEL_VERTICAL_MASK))
948
1030
                        return FALSE;
949
1031
                grab_op = PANEL_GRAB_OP_RESIZE_LEFT;
950
1032
                break;
951
 
        case GDK_Down:
952
 
        case GDK_KP_Down:
 
1033
        case GDK_KEY_Down:
 
1034
        case GDK_KEY_KP_Down:
953
1035
                if (!(toplevel->priv->orientation & PANEL_HORIZONTAL_MASK))
954
1036
                        return FALSE;
955
1037
                grab_op = PANEL_GRAB_OP_RESIZE_DOWN;
956
1038
                break;
957
 
        case GDK_Right:
958
 
        case GDK_KP_Right:
 
1039
        case GDK_KEY_Right:
 
1040
        case GDK_KEY_KP_Right:
959
1041
                if (!(toplevel->priv->orientation & PANEL_VERTICAL_MASK))
960
1042
                        return FALSE;
961
1043
                grab_op = PANEL_GRAB_OP_RESIZE_RIGHT;
978
1060
        gboolean retval = FALSE;
979
1061
 
980
1062
        switch (event->keyval) {
981
 
        case GDK_Up:
982
 
        case GDK_KP_Up:
983
 
        case GDK_Left:
984
 
        case GDK_KP_Left:
985
 
        case GDK_Down:
986
 
        case GDK_KP_Down:
987
 
        case GDK_Right:
988
 
        case GDK_KP_Right:
 
1063
        case GDK_KEY_Up:
 
1064
        case GDK_KEY_KP_Up:
 
1065
        case GDK_KEY_Left:
 
1066
        case GDK_KEY_KP_Left:
 
1067
        case GDK_KEY_Down:
 
1068
        case GDK_KEY_KP_Down:
 
1069
        case GDK_KEY_Right:
 
1070
        case GDK_KEY_KP_Right:
989
1071
                switch (toplevel->priv->grab_op) {
990
1072
                case PANEL_GRAB_OP_MOVE:
991
1073
                        if (toplevel->priv->expand)
1010
1092
                        break;
1011
1093
                }
1012
1094
                break;
1013
 
        case GDK_Escape: 
 
1095
        case GDK_KEY_Escape:
1014
1096
                panel_toplevel_cancel_grab_op (toplevel, event->time);
1015
 
        case GDK_Return: /* drop through*/
1016
 
        case GDK_KP_Enter:
1017
 
        case GDK_space:
1018
 
        case GDK_KP_Space:
 
1097
        case GDK_KEY_Return: /* drop through*/
 
1098
        case GDK_KEY_KP_Enter:
 
1099
        case GDK_KEY_space:
 
1100
        case GDK_KEY_KP_Space:
1019
1101
                panel_toplevel_end_grab_op (toplevel, event->time);
1020
1102
                retval = TRUE;
1021
1103
        default: /* drop through*/
1256
1338
                gtk_widget_hide (toplevel->priv->hide_button_left);
1257
1339
                gtk_widget_hide (toplevel->priv->hide_button_right);
1258
1340
        }
1259
 
 
1260
 
        if (toplevel->priv->attached) {
1261
 
                switch (panel_toplevel_get_orientation (toplevel->priv->attach_toplevel)) {
1262
 
                case PANEL_ORIENTATION_TOP:
1263
 
                        gtk_widget_hide (toplevel->priv->hide_button_top);
1264
 
                        break;
1265
 
                case PANEL_ORIENTATION_BOTTOM:
1266
 
                        gtk_widget_hide (toplevel->priv->hide_button_bottom);
1267
 
                        break;
1268
 
                case PANEL_ORIENTATION_LEFT:
1269
 
                        gtk_widget_hide (toplevel->priv->hide_button_left);
1270
 
                        break;
1271
 
                case PANEL_ORIENTATION_RIGHT:
1272
 
                        gtk_widget_hide (toplevel->priv->hide_button_right);
1273
 
                        break;
1274
 
                default:
1275
 
                        g_assert_not_reached ();
1276
 
                        break;
1277
 
                }
1278
 
        }
1279
1341
}
1280
1342
 
1281
1343
static void
1341
1403
        GdkDisplay *display;
1342
1404
        GdkScreen  *screen;
1343
1405
        GtkWidget  *widget;
 
1406
        GdkDeviceManager *device_manager;
 
1407
        GdkDevice  *pointer;
1344
1408
        int         x, y;
1345
1409
 
1346
1410
        display = gdk_display_get_default ();
 
1411
        device_manager = gdk_display_get_device_manager (display);
 
1412
        pointer = gdk_device_manager_get_client_pointer (device_manager);
1347
1413
        widget  = GTK_WIDGET (toplevel);
1348
1414
 
1349
1415
        if (!gtk_widget_get_realized (widget))
1351
1417
 
1352
1418
        screen = NULL;
1353
1419
        x = y = -1;
1354
 
        gdk_display_get_pointer (display, &screen, &x, &y, NULL);
 
1420
        gdk_device_get_position (pointer, &screen, &x, &y);
1355
1421
 
1356
1422
        if (screen != gtk_window_get_screen (GTK_WINDOW (toplevel)))
1357
1423
                return FALSE;
1396
1462
        if (!toplevel->priv->updated_geometry_initial)
1397
1463
                return FALSE;
1398
1464
 
1399
 
        if (toplevel->priv->attached) {
1400
 
                panel_struts_unregister_strut (toplevel);
1401
 
                panel_struts_set_window_hint (toplevel);
1402
 
                return FALSE;
1403
 
        }
1404
 
 
1405
1465
        /* In the case of the initial animation, we really want the struts to
1406
1466
         * represent what is at the end of the animation, to avoid desktop
1407
1467
         * icons jumping around. */
1622
1682
                },
1623
1683
        };
1624
1684
 
1625
 
        if (toplevel->priv->attached)
1626
 
                return N_("Drawer");
1627
 
 
1628
1685
        switch (toplevel->priv->orientation) {
1629
1686
        case PANEL_ORIENTATION_TOP:
1630
1687
                orientation = 0;
1684
1741
}
1685
1742
 
1686
1743
static void
1687
 
panel_toplevel_update_attached_position (PanelToplevel *toplevel,
1688
 
                                         gboolean       hidden,
1689
 
                                         int           *x,
1690
 
                                         int           *y,
1691
 
                                         int           *w,
1692
 
                                         int           *h)
1693
 
{
1694
 
        GtkAllocation     attach_allocation;
1695
 
        PanelOrientation  attach_orientation;
1696
 
        GdkRectangle      toplevel_box;
1697
 
        GdkRectangle      parent_box;
1698
 
        GdkRectangle      attach_box;
1699
 
        int               x_origin = 0, y_origin = 0;
1700
 
        int               monitor_x, monitor_y;
1701
 
        int               monitor_width, monitor_height;
1702
 
 
1703
 
        if (!gtk_widget_get_realized (GTK_WIDGET (toplevel->priv->attach_toplevel)) ||
1704
 
            !gtk_widget_get_realized (toplevel->priv->attach_widget))
1705
 
                return;
1706
 
 
1707
 
        gtk_widget_get_allocation (GTK_WIDGET (toplevel->priv->attach_widget), &attach_allocation);
1708
 
 
1709
 
        toplevel_box = toplevel->priv->geometry;
1710
 
        parent_box   = toplevel->priv->attach_toplevel->priv->geometry;
1711
 
        attach_box   = attach_allocation;
1712
 
 
1713
 
        if (attach_box.x != -1) {
1714
 
                gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (toplevel->priv->attach_widget)),
1715
 
                                       &x_origin, &y_origin);
1716
 
 
1717
 
                attach_box.x += x_origin;
1718
 
                attach_box.y += y_origin;
1719
 
        } else {
1720
 
                /* attach_widget isn't allocated. Put the toplevel
1721
 
                 * off screen.
1722
 
                 */
1723
 
                attach_box.x = -toplevel_box.width;
1724
 
                attach_box.y = -toplevel_box.height;
1725
 
        }
1726
 
 
1727
 
        attach_orientation = panel_toplevel_get_orientation (
1728
 
                                        toplevel->priv->attach_toplevel);
1729
 
 
1730
 
        if (attach_orientation & PANEL_HORIZONTAL_MASK)
1731
 
                *x = attach_box.x + attach_box.width / 2  - toplevel_box.width  / 2;
1732
 
        else
1733
 
                *y = attach_box.y + attach_box.height / 2 - toplevel_box.height / 2;
1734
 
 
1735
 
        switch (attach_orientation) {
1736
 
        case PANEL_ORIENTATION_TOP:
1737
 
                *y = parent_box.y;
1738
 
                if (!hidden)
1739
 
                        *y += parent_box.height;
1740
 
                else
1741
 
                        *h = parent_box.height;
1742
 
                break;
1743
 
        case PANEL_ORIENTATION_BOTTOM:
1744
 
                *y = parent_box.y;
1745
 
                if (!hidden)
1746
 
                        *y -= toplevel_box.height;
1747
 
                else
1748
 
                        *h = parent_box.height;
1749
 
                break;
1750
 
        case PANEL_ORIENTATION_LEFT:
1751
 
                *x = parent_box.x;
1752
 
                if (!hidden)
1753
 
                        *x += parent_box.width;
1754
 
                else
1755
 
                        *w = parent_box.width;
1756
 
                break;
1757
 
        case PANEL_ORIENTATION_RIGHT:
1758
 
                *x = parent_box.x;
1759
 
                if (!hidden)
1760
 
                        *x -= toplevel_box.width;
1761
 
                else
1762
 
                        *w = parent_box.width;
1763
 
                break;
1764
 
        default:
1765
 
                g_assert_not_reached ();
1766
 
                break;
1767
 
        }
1768
 
 
1769
 
        panel_toplevel_get_monitor_geometry (toplevel,
1770
 
                                             &monitor_x,
1771
 
                                             &monitor_y,
1772
 
                                             &monitor_width,
1773
 
                                             &monitor_height);
1774
 
 
1775
 
        *x -= monitor_x;
1776
 
        *y -= monitor_y;
1777
 
 
1778
 
        if (toplevel->priv->orientation & PANEL_VERTICAL_MASK)
1779
 
                *x = CLAMP (*x, 0, monitor_width  - toplevel->priv->original_width);
1780
 
        else
1781
 
                *y = CLAMP (*y, 0, monitor_height - toplevel->priv->original_height);
1782
 
}
1783
 
 
1784
 
static void
1785
1744
panel_toplevel_update_normal_position (PanelToplevel *toplevel,
1786
1745
                                       int           *x,
1787
1746
                                       int           *y,
1794
1753
 
1795
1754
        g_assert (x != NULL && y != NULL);
1796
1755
 
1797
 
        if (toplevel->priv->attached) {
1798
 
                panel_toplevel_update_attached_position (toplevel, FALSE, x, y, w, h);
1799
 
                return;
1800
 
        }
1801
 
 
1802
1756
        panel_toplevel_get_monitor_geometry (
1803
1757
                        toplevel, NULL, NULL, &monitor_width, &monitor_height);
1804
1758
 
1928
1882
                  toplevel->priv->state == PANEL_STATE_HIDDEN_LEFT ||
1929
1883
                  toplevel->priv->state == PANEL_STATE_HIDDEN_RIGHT);
1930
1884
 
1931
 
        if (toplevel->priv->attached) {
1932
 
                panel_toplevel_update_attached_position (toplevel, TRUE, x, y, w, h);
1933
 
                return;
1934
 
        }
1935
 
 
1936
1885
        panel_toplevel_get_monitor_geometry (
1937
1886
                        toplevel, NULL, NULL, &monitor_width, &monitor_height);
1938
1887
 
2068
2017
                 * have a wrong value in a size request event */
2069
2018
                toplevel->priv->initial_animation_done = TRUE;
2070
2019
 
2071
 
                if (toplevel->priv->attached && panel_toplevel_get_is_hidden (toplevel))
2072
 
                        gtk_widget_unmap (GTK_WIDGET (toplevel));
2073
 
                else
2074
 
                        gtk_widget_queue_resize (GTK_WIDGET (toplevel));
 
2020
                gtk_widget_queue_resize (GTK_WIDGET (toplevel));
2075
2021
 
2076
2022
                if (toplevel->priv->state == PANEL_STATE_NORMAL)
2077
2023
                        g_signal_emit (toplevel, toplevel_signals [UNHIDE_SIGNAL], 0);
2268
2214
        background = &toplevel->priv->panel_widget->background;
2269
2215
        /* There's no bevels with a color/image background */
2270
2216
        if (panel_background_effective_type (background) == PANEL_BACK_NONE) {
2271
 
                GtkStyle     *style;
2272
 
                GdkRectangle *geometry;
2273
 
                int           max_size;
 
2217
                GtkStyleContext *context;
 
2218
                GtkStateFlags    state;
 
2219
                GdkRectangle    *geometry;
 
2220
                GtkBorder        padding;
 
2221
                int              max_size;
2274
2222
 
2275
 
                style = gtk_widget_get_style (GTK_WIDGET (toplevel->priv->inner_frame));
 
2223
                state = gtk_widget_get_state_flags (GTK_WIDGET (toplevel->priv->inner_frame));
 
2224
                context = gtk_widget_get_style_context (GTK_WIDGET (toplevel->priv->inner_frame));
 
2225
                gtk_style_context_get_padding (context, state, &padding);
2276
2226
                geometry = &toplevel->priv->geometry;
2277
2227
 
2278
 
                if (x <= style->xthickness && x > 0 &&
 
2228
                if (x <= padding.left && x > 0 &&
2279
2229
                    !toplevel->priv->x_centered)
2280
2230
                        x = 0;
2281
2231
 
2282
 
                if (y <= style->ythickness && y > 0 &&
 
2232
                if (y <= padding.top && y > 0 &&
2283
2233
                    !toplevel->priv->y_centered)
2284
2234
                        y = 0;
2285
2235
 
2286
 
                max_size = monitor_width - geometry->width - style->xthickness;
2287
 
                if (x + style->xthickness >= max_size && x < max_size &&
 
2236
                max_size = monitor_width - geometry->width - padding.right;
 
2237
                if (x + padding.left >= max_size && x < max_size &&
2288
2238
                    !toplevel->priv->x_centered)
2289
2239
                        x = max_size;
2290
2240
 
2291
 
                max_size = monitor_height - geometry->height - style->ythickness;
2292
 
                if (y + style->ythickness >= max_size && y < max_size &&
 
2241
                max_size = monitor_height - geometry->height - padding.bottom;
 
2242
                if (y + padding.top >= max_size && y < max_size &&
2293
2243
                    !toplevel->priv->y_centered)
2294
2244
                        y = max_size;
2295
2245
        }
2305
2255
calculate_minimum_height (GtkWidget        *widget,
2306
2256
                          PanelOrientation  orientation)
2307
2257
{
2308
 
        GtkStyle         *style;
2309
 
        PangoContext     *context;
 
2258
        GtkStateFlags     state;
 
2259
        GtkStyleContext  *style_context;
 
2260
        const PangoFontDescription *font_desc;
 
2261
        PangoContext     *pango_context;
2310
2262
        PangoFontMetrics *metrics;
 
2263
        GtkBorder         padding;
2311
2264
        int               focus_width = 0;
2312
2265
        int               focus_pad = 0;
2313
2266
        int               ascent;
2314
2267
        int               descent;
2315
2268
        int               thickness;
2316
2269
  
2317
 
        style = gtk_widget_get_style (widget);
2318
 
        context = gtk_widget_get_pango_context (widget);
2319
 
        metrics = pango_context_get_metrics (context,
2320
 
                                             style->font_desc,
2321
 
                                             pango_context_get_language (context));
2322
 
  
 
2270
        state = gtk_widget_get_state_flags (widget);
 
2271
        style_context = gtk_widget_get_style_context (widget);
 
2272
        font_desc = gtk_style_context_get_font (style_context, state);
 
2273
 
 
2274
        pango_context = gtk_widget_get_pango_context (widget);
 
2275
        metrics = pango_context_get_metrics (pango_context,
 
2276
                                             font_desc,
 
2277
                                             pango_context_get_language (pango_context));
2323
2278
        ascent  = pango_font_metrics_get_ascent  (metrics);
2324
2279
        descent = pango_font_metrics_get_descent (metrics);
2325
2280
  
2326
2281
        pango_font_metrics_unref (metrics);
2327
2282
 
 
2283
        gtk_style_context_get_padding (style_context, state, &padding);
2328
2284
        gtk_widget_style_get (widget,
2329
2285
                              "focus-line-width", &focus_width,
2330
2286
                              "focus-padding", &focus_pad,
2331
2287
                              NULL);
2332
2288
 
2333
2289
        thickness = orientation & PANEL_HORIZONTAL_MASK ?
2334
 
                style->ythickness :
2335
 
                style->xthickness;
 
2290
                padding.top + padding.bottom :
 
2291
                padding.left + padding.right;
2336
2292
 
2337
 
        return PANGO_PIXELS (ascent + descent) + 2 * (focus_width + focus_pad + thickness);
 
2293
        return PANGO_PIXELS (ascent + descent) + 2 * (focus_width + focus_pad) + thickness;
2338
2294
}
2339
2295
 
2340
2296
static int
2386
2342
 
2387
2343
                        current_bonus = bonus;
2388
2344
 
2389
 
                        while (using_hint[i].index > 0 && applets_hints[i].hints[using_hint[i].index - 1] < using_hint[i].size + current_bonus) {
 
2345
                        /* first find the (max, min) range in hints that we
 
2346
                         * will use; since we try to allocate as much size as
 
2347
                         * possible, this means we want the (max, min) range
 
2348
                         * where min is the highest possible (ie, the range
 
2349
                         * with the smaller index possible), while still
 
2350
                         * keeping min smaller than the potential new size */
 
2351
                        while (using_hint[i].index > 0 &&
 
2352
                               applets_hints[i].hints[using_hint[i].index - 1] < using_hint[i].size + current_bonus) {
2390
2353
                                new_size = applets_hints[i].hints[using_hint[i].index - 1];
2391
2354
                                current_bonus = using_hint[i].size
2392
2355
                                                + current_bonus - new_size;
2397
2360
                                using_hint[i].size = new_size;
2398
2361
                        }
2399
2362
 
 
2363
                        /* now, give the bonus, while still keeping a size that
 
2364
                         * is lower than max from the (max, min) range we've
 
2365
                         * settled for */
2400
2366
                        new_size = MIN (applets_hints[i].hints[using_hint[i].index],
2401
2367
                                        using_hint[i].size + current_bonus);
2402
2368
                        if (new_size > using_hint[i].size) {
2404
2370
                                using_hint[i].size = new_size;
2405
2371
                        }
2406
2372
 
 
2373
 
 
2374
                        /* if there's some extra bonus to take, try to allocate
 
2375
                         * it too */
2407
2376
                        if (extra_bonus > 0) {
2408
2377
                                new_size = MIN (applets_hints[i].hints[using_hint[i].index],
2409
2378
                                                using_hint[i].size + extra_bonus);
2428
2397
panel_toplevel_update_size (PanelToplevel  *toplevel,
2429
2398
                            GtkRequisition *requisition)
2430
2399
{
2431
 
        GtkWidget *widget;
2432
 
        GtkStyle  *style;
2433
 
        int        monitor_width, monitor_height;
2434
 
        int        width, height;
2435
 
        int        minimum_height;
2436
 
        int        non_panel_widget_size;
 
2400
        GtkWidget       *widget;
 
2401
        GtkStyleContext *context;
 
2402
        GtkStateFlags    state;
 
2403
        GtkBorder        padding;
 
2404
        int              monitor_width, monitor_height;
 
2405
        int              width, height;
 
2406
        int              minimum_height;
 
2407
        int              non_panel_widget_size;
2437
2408
 
2438
2409
        if (toplevel->priv->animating)
2439
2410
                return;
2440
2411
 
2441
2412
        widget = GTK_WIDGET (toplevel);
2442
 
        style = gtk_widget_get_style (widget);
 
2413
        state = gtk_widget_get_state_flags (widget);
 
2414
        context = gtk_widget_get_style_context (widget);
 
2415
        gtk_style_context_get_padding (context, state, &padding);
2443
2416
 
2444
2417
        panel_toplevel_get_monitor_geometry (
2445
2418
                        toplevel, NULL, NULL, &monitor_width, &monitor_height);
2448
2421
        height = requisition->height;
2449
2422
 
2450
2423
        if (!toplevel->priv->expand &&
2451
 
            !toplevel->priv->buttons_enabled && !toplevel->priv->attached)
 
2424
            !toplevel->priv->buttons_enabled)
2452
2425
                non_panel_widget_size = 2 * HANDLE_SIZE;
2453
2426
        else
2454
2427
                non_panel_widget_size = 0;
2464
2437
 
2465
2438
                if (toplevel->priv->expand)
2466
2439
                        width  = monitor_width;
2467
 
                else {
2468
 
                        int max_width;
2469
 
 
2470
 
                        if (!toplevel->priv->attached)
2471
 
                                max_width = monitor_width;
2472
 
                        else {
2473
 
                                if (panel_toplevel_get_orientation (toplevel->priv->attach_toplevel) == PANEL_ORIENTATION_LEFT)
2474
 
                                        max_width = monitor_width
2475
 
                                                    - toplevel->priv->geometry.x;
2476
 
                                else
2477
 
                                        max_width = toplevel->priv->geometry.x +
2478
 
                                                    toplevel->priv->geometry.width;
2479
 
                        }
2480
 
 
 
2440
                else
2481
2441
                        width = panel_toplevel_update_size_from_hints (
2482
2442
                                                        toplevel,
2483
2443
                                                        requisition->width,
2484
 
                                                        max_width,
 
2444
                                                        monitor_width,
2485
2445
                                                        non_panel_widget_size);
2486
 
                }
2487
2446
 
2488
2447
                width  = MAX (MINIMUM_WIDTH, width);
2489
2448
        } else {
2493
2452
 
2494
2453
                if (toplevel->priv->expand)
2495
2454
                        height = monitor_height;
2496
 
                else {
2497
 
                        int max_height;
2498
 
 
2499
 
                        if (!toplevel->priv->attached)
2500
 
                                max_height = monitor_height;
2501
 
                        else {
2502
 
                                if (panel_toplevel_get_orientation (toplevel->priv->attach_toplevel) == PANEL_ORIENTATION_TOP)
2503
 
                                        max_height = monitor_height
2504
 
                                                     - toplevel->priv->geometry.y;
2505
 
                                else
2506
 
                                        max_height = toplevel->priv->geometry.y +
2507
 
                                                     toplevel->priv->geometry.height;
2508
 
                        }
2509
 
 
 
2455
                else
2510
2456
                        height = panel_toplevel_update_size_from_hints (
2511
2457
                                                        toplevel,
2512
2458
                                                        requisition->height,
2513
 
                                                        max_height,
 
2459
                                                        monitor_height,
2514
2460
                                                        non_panel_widget_size);
2515
 
                }
2516
2461
 
2517
2462
                height = MAX (MINIMUM_WIDTH, height);
2518
2463
        }
2519
2464
 
2520
2465
        if (toplevel->priv->edges & PANEL_EDGE_TOP)
2521
 
                height += style->ythickness;
 
2466
                height += padding.top;
2522
2467
        if (toplevel->priv->edges & PANEL_EDGE_BOTTOM)
2523
 
                height += style->ythickness;
 
2468
                height += padding.bottom;
2524
2469
        if (toplevel->priv->edges & PANEL_EDGE_LEFT)
2525
 
                width += style->ythickness;
 
2470
                width += padding.left;
2526
2471
        if (toplevel->priv->edges & PANEL_EDGE_RIGHT)
2527
 
                width += style->ythickness;
 
2472
                width += padding.right;
2528
2473
 
2529
2474
        toplevel->priv->geometry.width  = CLAMP (width,  0, monitor_width);
2530
2475
        toplevel->priv->geometry.height = CLAMP (height, 0, monitor_height);
2560
2505
        panel_toplevel_update_description (toplevel);
2561
2506
}
2562
2507
 
2563
 
static void
2564
 
panel_toplevel_attach_widget_destroyed (PanelToplevel *toplevel)
2565
 
{
2566
 
        panel_toplevel_detach (toplevel);
2567
 
}
2568
 
 
2569
 
static gboolean
2570
 
panel_toplevel_attach_widget_configure (PanelToplevel *toplevel)
2571
 
{
2572
 
        gtk_widget_queue_resize (GTK_WIDGET (toplevel));
2573
 
 
2574
 
        return FALSE;
2575
 
}
2576
 
 
2577
 
static void
2578
 
panel_toplevel_update_attach_orientation (PanelToplevel *toplevel)
2579
 
{
2580
 
        PanelOrientation attach_orientation;
2581
 
        PanelOrientation orientation;
2582
 
 
2583
 
        attach_orientation =
2584
 
                panel_toplevel_get_orientation (toplevel->priv->attach_toplevel);
2585
 
 
2586
 
        orientation = toplevel->priv->orientation;
2587
 
 
2588
 
        switch (attach_orientation) {
2589
 
        case PANEL_ORIENTATION_TOP:
2590
 
                orientation = PANEL_ORIENTATION_LEFT;
2591
 
                break;
2592
 
        case PANEL_ORIENTATION_BOTTOM:
2593
 
                orientation = PANEL_ORIENTATION_RIGHT;
2594
 
                break;
2595
 
        case PANEL_ORIENTATION_LEFT:
2596
 
                orientation = PANEL_ORIENTATION_TOP;
2597
 
                break;
2598
 
        case PANEL_ORIENTATION_RIGHT:
2599
 
                orientation = PANEL_ORIENTATION_BOTTOM;
2600
 
                break;
2601
 
        default:
2602
 
                g_assert_not_reached ();
2603
 
                break;
2604
 
        }
2605
 
 
2606
 
        panel_toplevel_set_orientation (toplevel, orientation);
2607
 
}
2608
 
 
2609
 
static void
2610
 
panel_toplevel_attach_widget_parent_set (PanelToplevel *toplevel,
2611
 
                                         GtkWidget     *previous_parent,
2612
 
                                         GtkWidget     *attach_widget)
2613
 
{
2614
 
        GtkWidget *panel_widget;
2615
 
 
2616
 
        panel_widget = gtk_widget_get_parent (GTK_WIDGET (attach_widget));
2617
 
        if (!panel_widget)
2618
 
                return;
2619
 
 
2620
 
        g_assert (PANEL_IS_WIDGET (panel_widget));
2621
 
 
2622
 
        toplevel->priv->attach_toplevel = PANEL_WIDGET (panel_widget)->toplevel;
2623
 
        panel_toplevel_update_attach_orientation (toplevel);
2624
 
        gtk_widget_queue_resize (GTK_WIDGET (toplevel));
2625
 
}
2626
 
 
2627
 
static void
2628
 
panel_toplevel_attach_toplevel_hiding (PanelToplevel *toplevel)
2629
 
{
2630
 
        if (!panel_toplevel_get_is_hidden (toplevel)) {
2631
 
                panel_toplevel_hide (toplevel, FALSE, -1);
2632
 
 
2633
 
                toplevel->priv->attach_hidden = TRUE;
2634
 
        }
2635
 
}
2636
 
 
2637
 
static void
2638
 
panel_toplevel_attach_toplevel_unhiding (PanelToplevel *toplevel)
2639
 
{
2640
 
        if (!toplevel->priv->attach_hidden)
2641
 
                return;
2642
 
 
2643
 
        toplevel->priv->attach_hidden = FALSE;
2644
 
 
2645
 
        panel_toplevel_unhide (toplevel);
2646
 
}
2647
 
 
2648
 
static void
2649
 
panel_toplevel_reverse_arrow (PanelToplevel *toplevel,
2650
 
                              GtkWidget     *button)
2651
 
{
2652
 
        GtkArrowType arrow_type;
2653
 
 
2654
 
        arrow_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button), "arrow-type"));
2655
 
 
2656
 
        switch (arrow_type) {
2657
 
        case GTK_ARROW_UP:
2658
 
                arrow_type = GTK_ARROW_DOWN;
2659
 
                break;
2660
 
        case GTK_ARROW_DOWN:
2661
 
                arrow_type = GTK_ARROW_UP;
2662
 
                break;
2663
 
        case GTK_ARROW_LEFT:
2664
 
                arrow_type = GTK_ARROW_RIGHT;
2665
 
                break;
2666
 
        case GTK_ARROW_RIGHT:
2667
 
                arrow_type = GTK_ARROW_LEFT;
2668
 
                break;
2669
 
        default:
2670
 
                g_assert_not_reached ();
2671
 
                break;
2672
 
        }
2673
 
 
2674
 
        g_object_set_data (G_OBJECT (button), "arrow-type", GINT_TO_POINTER (arrow_type));
2675
 
 
2676
 
        gtk_arrow_set (GTK_ARROW (gtk_bin_get_child (GTK_BIN (button))), arrow_type, GTK_SHADOW_NONE);
2677
 
}
2678
 
 
2679
 
static void
2680
 
panel_toplevel_reverse_arrows (PanelToplevel *toplevel)
2681
 
{
2682
 
        panel_toplevel_reverse_arrow (toplevel, toplevel->priv->hide_button_top);
2683
 
        panel_toplevel_reverse_arrow (toplevel, toplevel->priv->hide_button_bottom);
2684
 
        panel_toplevel_reverse_arrow (toplevel, toplevel->priv->hide_button_left);
2685
 
        panel_toplevel_reverse_arrow (toplevel, toplevel->priv->hide_button_right);
2686
 
}
2687
 
 
2688
 
static void
2689
 
panel_toplevel_disconnect_attached (PanelToplevel *toplevel)
2690
 
{
2691
 
        int i;
2692
 
 
2693
 
        for (i = 0; i < N_ATTACH_TOPLEVEL_SIGNALS; i++) {
2694
 
                if (!toplevel->priv->attach_toplevel_signals [i])
2695
 
                        continue;
2696
 
 
2697
 
                g_signal_handler_disconnect (
2698
 
                        toplevel->priv->attach_toplevel,
2699
 
                        toplevel->priv->attach_toplevel_signals [i]);
2700
 
                toplevel->priv->attach_toplevel_signals [i] = 0;
2701
 
        }
2702
 
 
2703
 
        for (i = 0; i < N_ATTACH_WIDGET_SIGNALS; i++) {
2704
 
                if (!toplevel->priv->attach_widget_signals [i])
2705
 
                        continue;
2706
 
                
2707
 
                g_signal_handler_disconnect (
2708
 
                        toplevel->priv->attach_widget,
2709
 
                        toplevel->priv->attach_widget_signals [i]);
2710
 
                toplevel->priv->attach_widget_signals [i] = 0;
2711
 
        }
2712
 
}
2713
 
 
2714
 
static void
2715
 
panel_toplevel_connect_attached (PanelToplevel *toplevel)
2716
 
{
2717
 
        gulong *signals;
2718
 
        int     i = 0;
2719
 
 
2720
 
        signals = toplevel->priv->attach_toplevel_signals;
2721
 
 
2722
 
        signals [i++] = g_signal_connect_swapped (
2723
 
                toplevel->priv->attach_toplevel, "destroy",
2724
 
                G_CALLBACK (panel_toplevel_attach_widget_destroyed), toplevel);
2725
 
        signals [i++] = g_signal_connect_swapped (
2726
 
                toplevel->priv->attach_toplevel, "notify::orientation",
2727
 
                G_CALLBACK (panel_toplevel_update_attach_orientation), toplevel);
2728
 
        signals [i++] = g_signal_connect_swapped (
2729
 
                toplevel->priv->attach_toplevel, "configure-event",
2730
 
                G_CALLBACK (panel_toplevel_attach_widget_configure), toplevel);
2731
 
        signals [i++] = g_signal_connect_swapped (
2732
 
                toplevel->priv->attach_toplevel, "hiding",
2733
 
                G_CALLBACK (panel_toplevel_attach_toplevel_hiding), toplevel);
2734
 
        signals [i++] = g_signal_connect_swapped (
2735
 
                toplevel->priv->attach_toplevel, "unhiding",
2736
 
                G_CALLBACK (panel_toplevel_attach_toplevel_unhiding), toplevel);
2737
 
 
2738
 
        g_assert (i == N_ATTACH_TOPLEVEL_SIGNALS);
2739
 
 
2740
 
        signals = toplevel->priv->attach_widget_signals;
2741
 
        i = 0;
2742
 
 
2743
 
        signals [i++] = g_signal_connect_swapped (
2744
 
                toplevel->priv->attach_widget, "destroy",
2745
 
                G_CALLBACK (panel_toplevel_attach_widget_destroyed), toplevel);
2746
 
        signals [i++] = g_signal_connect_swapped (
2747
 
                toplevel->priv->attach_widget, "configure-event",
2748
 
                G_CALLBACK (panel_toplevel_attach_widget_configure), toplevel);
2749
 
        signals [i++] = g_signal_connect_swapped (
2750
 
                toplevel->priv->attach_widget, "parent-set",
2751
 
                G_CALLBACK (panel_toplevel_attach_widget_parent_set), toplevel);
2752
 
        signals [i++] = g_signal_connect_swapped (
2753
 
                toplevel->priv->attach_widget, "show",
2754
 
                G_CALLBACK (gtk_widget_show), toplevel);
2755
 
        signals [i++] = g_signal_connect_swapped (
2756
 
                toplevel->priv->attach_widget, "hide",
2757
 
                G_CALLBACK (gtk_widget_hide), toplevel);
2758
 
 
2759
 
        g_assert (i == N_ATTACH_WIDGET_SIGNALS);
2760
 
2761
 
 
2762
 
void
2763
 
panel_toplevel_attach_to_widget (PanelToplevel *toplevel,
2764
 
                                 PanelToplevel *attach_toplevel,
2765
 
                                 GtkWidget     *attach_widget)
2766
 
{
2767
 
        g_return_if_fail (PANEL_IS_TOPLEVEL (toplevel));
2768
 
        g_return_if_fail (PANEL_IS_TOPLEVEL (attach_toplevel));
2769
 
        g_return_if_fail (GTK_IS_WIDGET (attach_widget));
2770
 
 
2771
 
        if (toplevel->priv->attached)
2772
 
                panel_toplevel_disconnect_attached (toplevel);
2773
 
 
2774
 
        toplevel->priv->attached = TRUE;
2775
 
 
2776
 
        /* Cancelling the initial animation for drawers in
2777
 
         * panel_toplevel_initially_hide() is not enough, since this will
2778
 
         * happen only when the toplevel is realized, which might be too late
2779
 
         * for drawers (since it's realized when the drawer is clicked) */
2780
 
        toplevel->priv->initial_animation_done = TRUE;
2781
 
 
2782
 
        toplevel->priv->attach_toplevel = attach_toplevel;
2783
 
        toplevel->priv->attach_widget   = attach_widget;
2784
 
 
2785
 
        panel_toplevel_connect_attached (toplevel);
2786
 
        
2787
 
        panel_toplevel_reverse_arrows (toplevel);
2788
 
        panel_toplevel_set_expand (toplevel, FALSE);
2789
 
        panel_toplevel_update_attach_orientation (toplevel);
2790
 
        panel_toplevel_update_hide_buttons (toplevel);
2791
 
 
2792
 
        gtk_window_set_screen (GTK_WINDOW (toplevel),
2793
 
                               gtk_widget_get_screen (GTK_WIDGET (attach_toplevel)));
2794
 
        panel_toplevel_set_monitor (toplevel,
2795
 
                                    panel_toplevel_get_monitor (attach_toplevel));
2796
 
        if (toplevel->priv->state == PANEL_STATE_NORMAL)
2797
 
                panel_toplevel_push_autohide_disabler (toplevel->priv->attach_toplevel);
2798
 
 
2799
 
        gtk_widget_queue_resize (GTK_WIDGET (toplevel));
2800
 
}
2801
 
 
2802
 
void
2803
 
panel_toplevel_detach (PanelToplevel *toplevel)
2804
 
{
2805
 
        g_return_if_fail (PANEL_IS_TOPLEVEL (toplevel));
2806
 
 
2807
 
        if (!toplevel->priv->attached)
2808
 
                return;
2809
 
 
2810
 
        if (toplevel->priv->state == PANEL_STATE_NORMAL)
2811
 
                panel_toplevel_pop_autohide_disabler (toplevel->priv->attach_toplevel);
2812
 
 
2813
 
        panel_toplevel_disconnect_attached (toplevel);
2814
 
        
2815
 
        panel_toplevel_reverse_arrows (toplevel);
2816
 
 
2817
 
        toplevel->priv->attached = FALSE;
2818
 
 
2819
 
        toplevel->priv->attach_toplevel = NULL;
2820
 
        toplevel->priv->attach_widget   = NULL;
2821
 
 
2822
 
        gtk_widget_queue_resize (GTK_WIDGET (toplevel));
2823
 
}
2824
 
 
2825
 
gboolean
2826
 
panel_toplevel_get_is_attached (PanelToplevel *toplevel)
2827
 
{
2828
 
        g_return_val_if_fail (PANEL_IS_TOPLEVEL (toplevel), FALSE);
2829
 
 
2830
 
        return toplevel->priv->attached;
2831
 
}
2832
 
 
2833
 
PanelToplevel *
2834
 
panel_toplevel_get_attach_toplevel (PanelToplevel *toplevel)
2835
 
{
2836
 
        g_return_val_if_fail (PANEL_IS_TOPLEVEL (toplevel), NULL);
2837
 
 
2838
 
        return toplevel->priv->attach_toplevel;
2839
 
}
2840
 
 
2841
 
GtkWidget *
2842
 
panel_toplevel_get_attach_widget (PanelToplevel *toplevel)
2843
 
{
2844
 
        g_return_val_if_fail (PANEL_IS_TOPLEVEL (toplevel), NULL);
2845
 
 
2846
 
        return toplevel->priv->attach_widget;
2847
 
}
2848
 
 
2849
2508
static gboolean
2850
2509
panel_toplevel_popup_panel_menu (PanelToplevel *toplevel)
2851
2510
{
2945
2604
static void
2946
2605
panel_toplevel_initially_hide (PanelToplevel *toplevel)
2947
2606
{
2948
 
#ifndef DISABLE_INITIAL_ANIMATION
2949
 
        if (!toplevel->priv->attached) {
2950
 
                toplevel->priv->initial_animation_done = FALSE;
 
2607
        toplevel->priv->initial_animation_done = FALSE;
2951
2608
 
2952
 
                /* We start the panel off hidden until all the applets are
2953
 
                 * loaded, and then finally slide it down when it's ready to be
2954
 
                 * used */
2955
 
                toplevel->priv->state = PANEL_STATE_AUTO_HIDDEN;
2956
 
                gtk_widget_queue_resize (GTK_WIDGET (toplevel));
2957
 
        } else
2958
 
#endif /* DISABLE_INITIAL_ANIMATION */
2959
 
                toplevel->priv->initial_animation_done = TRUE;
 
2609
        /* We start the panel off hidden until all the applets are
 
2610
         * loaded, and then finally slide it down when it's ready to be
 
2611
         * used */
 
2612
        toplevel->priv->state = PANEL_STATE_AUTO_HIDDEN;
 
2613
        gtk_widget_queue_resize (GTK_WIDGET (toplevel));
2960
2614
}
2961
2615
 
2962
2616
static void
3010
2664
}
3011
2665
 
3012
2666
static void
3013
 
panel_toplevel_destroy (GtkObject *widget)
 
2667
panel_toplevel_dispose (GObject *widget)
3014
2668
{
3015
2669
        PanelToplevel *toplevel = (PanelToplevel *) widget;
3016
2670
        
3017
 
        if (toplevel->priv->attached) {
3018
 
                panel_toplevel_disconnect_attached (toplevel);
3019
 
                toplevel->priv->attached = FALSE;
3020
 
 
3021
 
                toplevel->priv->attach_toplevel = NULL;
3022
 
                toplevel->priv->attach_widget   = NULL;
3023
 
        }
3024
 
 
3025
2671
        panel_toplevel_disconnect_timeouts (toplevel);
3026
2672
 
3027
 
        if (GTK_OBJECT_CLASS (panel_toplevel_parent_class)->destroy)
3028
 
                GTK_OBJECT_CLASS (panel_toplevel_parent_class)->destroy (widget);
 
2673
        G_OBJECT_CLASS (panel_toplevel_parent_class)->dispose (widget);
3029
2674
}
3030
2675
 
3031
2676
static void
3044
2689
        requisition.width  = -1;
3045
2690
        requisition.height = -1;
3046
2691
 
3047
 
        gtk_widget_size_request (widget, &requisition);
 
2692
        gtk_widget_get_preferred_size (widget, &requisition, NULL);
3048
2693
        gtk_widget_get_allocation (widget, &widget_allocation);
3049
2694
 
3050
2695
        if (widget_allocation.width  != requisition.width ||
3065
2710
        GdkRectangle   old_geometry;
3066
2711
        int            position_changed = FALSE;
3067
2712
        int            size_changed = FALSE;
 
2713
        int            dummy; /* to pass a valid pointer */
3068
2714
 
3069
2715
        toplevel = PANEL_TOPLEVEL (widget);
3070
2716
        bin = GTK_BIN (widget);
3074
2720
        panel_toplevel_update_monitor (toplevel);
3075
2721
 
3076
2722
        child = gtk_bin_get_child (bin);
3077
 
        if (child && gtk_widget_get_visible (child))
3078
 
                gtk_widget_size_request (child, requisition);
 
2723
        if (child && gtk_widget_get_visible (child)) {
 
2724
                gtk_widget_get_preferred_width (child, &dummy, &requisition->width);
 
2725
                gtk_widget_get_preferred_height (child, &dummy, &requisition->height);
 
2726
        }
3079
2727
 
3080
2728
        old_geometry = toplevel->priv->geometry;
3081
2729
 
3099
2747
}
3100
2748
 
3101
2749
static void
 
2750
panel_toplevel_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width)
 
2751
{
 
2752
        GtkRequisition requisition;
 
2753
 
 
2754
        panel_toplevel_size_request (widget, &requisition);
 
2755
 
 
2756
        *minimal_width = *natural_width = requisition.width;
 
2757
}
 
2758
 
 
2759
static void
 
2760
panel_toplevel_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height)
 
2761
{
 
2762
        GtkRequisition requisition;
 
2763
 
 
2764
        panel_toplevel_size_request (widget, &requisition);
 
2765
 
 
2766
        *minimal_height = *natural_height = requisition.height;
 
2767
}
 
2768
 
 
2769
static void
3102
2770
panel_toplevel_size_allocate (GtkWidget     *widget,
3103
2771
                              GtkAllocation *allocation)
3104
2772
{
3105
 
        PanelToplevel *toplevel = (PanelToplevel *) widget;
3106
 
        GtkBin        *bin = (GtkBin *) widget;
3107
 
        GtkStyle      *style;
3108
 
        GtkWidget     *child;
3109
 
        GtkAllocation  challoc;
3110
 
        GtkAllocation  child_allocation;
 
2773
        PanelToplevel   *toplevel = (PanelToplevel *) widget;
 
2774
        GtkBin          *bin = (GtkBin *) widget;
 
2775
        GtkStyleContext *context;
 
2776
        GtkStateFlags    state;
 
2777
        GtkBorder        padding;
 
2778
        GtkWidget       *child;
 
2779
        GtkAllocation    challoc;
 
2780
        GtkAllocation    child_allocation;
3111
2781
 
3112
2782
        gtk_widget_set_allocation (widget, allocation);
3113
2783
 
3114
2784
        if (toplevel->priv->expand ||
3115
 
            toplevel->priv->buttons_enabled ||
3116
 
            toplevel->priv->attached)
 
2785
            toplevel->priv->buttons_enabled)
3117
2786
                challoc = *allocation;
3118
2787
        else {
3119
2788
                if (toplevel->priv->orientation & PANEL_HORIZONTAL_MASK) {
3129
2798
                }
3130
2799
        }
3131
2800
 
3132
 
        style = gtk_widget_get_style (widget);
 
2801
        state = gtk_widget_get_state_flags (widget);
 
2802
        context = gtk_widget_get_style_context (widget);
 
2803
        gtk_style_context_get_padding (context, state, &padding);
3133
2804
 
3134
2805
        if (toplevel->priv->edges & PANEL_EDGE_TOP) {
3135
 
                challoc.y += style->ythickness;
3136
 
                challoc.height -= style->ythickness;
 
2806
                challoc.y += padding.top;
 
2807
                challoc.height -= padding.top;
3137
2808
        }
3138
2809
 
3139
2810
        if (toplevel->priv->edges & PANEL_EDGE_LEFT) {
3140
 
                challoc.x += style->xthickness;
3141
 
                challoc.width -= style->xthickness;
 
2811
                challoc.x += padding.left;
 
2812
                challoc.width -= padding.left;
3142
2813
        }
3143
2814
 
3144
2815
        if (toplevel->priv->edges & PANEL_EDGE_BOTTOM)
3145
 
                challoc.height -= style->ythickness;
 
2816
                challoc.height -= padding.bottom;
3146
2817
 
3147
2818
        if (toplevel->priv->edges & PANEL_EDGE_RIGHT)
3148
 
                challoc.width -= style->xthickness;
 
2819
                challoc.width -= padding.right;
3149
2820
 
3150
2821
        challoc.width  = MAX (1, challoc.width);
3151
2822
        challoc.height = MAX (1, challoc.height);
3169
2840
}
3170
2841
 
3171
2842
static gboolean
3172
 
panel_toplevel_expose (GtkWidget      *widget,
3173
 
                       GdkEventExpose *event)
 
2843
panel_toplevel_draw (GtkWidget *widget,
 
2844
                     cairo_t   *cr)
3174
2845
{
3175
 
        PanelToplevel  *toplevel = (PanelToplevel *) widget;
3176
 
        PanelFrameEdge  edges;
3177
 
        gboolean        retval = FALSE;
3178
 
        GdkWindow      *window;
3179
 
        GtkStyle       *style;
3180
 
        GtkStateType    state;
3181
 
        GtkAllocation   allocation;
3182
 
 
3183
 
        if (!gtk_widget_is_drawable (widget))
3184
 
                return retval;
3185
 
 
3186
 
        if (GTK_WIDGET_CLASS (panel_toplevel_parent_class)->expose_event)
3187
 
                retval = GTK_WIDGET_CLASS (panel_toplevel_parent_class)->expose_event (widget, event);
 
2846
        PanelToplevel   *toplevel = (PanelToplevel *) widget;
 
2847
        PanelFrameEdge   edges;
 
2848
        gboolean         retval = FALSE;
 
2849
        GdkWindow       *window;
 
2850
        GtkStyleContext *context;
 
2851
        GtkStateFlags    state;
 
2852
        GtkBorder        padding;
 
2853
        int awidth, aheight;
 
2854
 
 
2855
        if (GTK_WIDGET_CLASS (panel_toplevel_parent_class)->draw)
 
2856
                retval = GTK_WIDGET_CLASS (panel_toplevel_parent_class)->draw (widget, cr);
3188
2857
 
3189
2858
        edges = toplevel->priv->edges;
3190
 
        panel_frame_draw (widget, edges);
 
2859
        /* FIXMEchpe: WTF!? */
 
2860
        panel_frame_draw (widget, cr, edges);
3191
2861
 
3192
2862
        if (toplevel->priv->expand ||
3193
 
            toplevel->priv->buttons_enabled ||
3194
 
            toplevel->priv->attached)
 
2863
            toplevel->priv->buttons_enabled)
3195
2864
                return retval;
3196
2865
 
3197
2866
        window = gtk_widget_get_window (widget);
3198
 
        style = gtk_widget_get_style (widget);
3199
 
        state = gtk_widget_get_state (widget);
3200
 
        gtk_widget_get_allocation (widget, &allocation);
 
2867
        state = gtk_widget_get_state_flags (widget);
 
2868
        awidth = gtk_widget_get_allocated_width (widget);
 
2869
        aheight = gtk_widget_get_allocated_height (widget);
 
2870
 
 
2871
        context = gtk_widget_get_style_context (widget);
 
2872
        gtk_style_context_get_padding (context, state, &padding);
 
2873
 
 
2874
        gtk_style_context_save (context);
 
2875
        gtk_style_context_set_state (context, state);
3201
2876
 
3202
2877
        if (toplevel->priv->orientation & PANEL_HORIZONTAL_MASK) {
3203
2878
                int x, y, width, height;
3204
 
                int xthickness, ythickness;
3205
2879
 
3206
 
                x      = allocation.x;
3207
 
                y      = allocation.y;
 
2880
                x      = 0;
 
2881
                y      = 0;
3208
2882
                width  = HANDLE_SIZE;
3209
 
                height = allocation.height;
3210
 
 
3211
 
                xthickness = style->xthickness;
3212
 
                ythickness = style->ythickness;
 
2883
                height = aheight;
3213
2884
 
3214
2885
                if (edges & PANEL_EDGE_TOP) {
3215
 
                        y += ythickness;
3216
 
                        height -= ythickness;
 
2886
                        y += padding.top;
 
2887
                        height -= padding.top;
3217
2888
                }
3218
2889
                if (edges & PANEL_EDGE_BOTTOM)
3219
 
                        height -= ythickness;
 
2890
                        height -= padding.bottom;
3220
2891
                if (edges & PANEL_EDGE_LEFT)
3221
 
                        x += xthickness;
3222
 
 
3223
 
                gtk_paint_handle (style, window, state,
3224
 
                                  GTK_SHADOW_OUT,
3225
 
                                  &event->area, widget, "handlebox",
3226
 
                                  x, y, width, height,
3227
 
                                  GTK_ORIENTATION_VERTICAL);
3228
 
 
3229
 
                x = allocation.width - HANDLE_SIZE;
 
2892
                        x += padding.left;
 
2893
 
 
2894
                cairo_save (cr);
 
2895
                gtk_render_handle (context, cr, x, y, width, height);
 
2896
                cairo_restore (cr);
 
2897
 
 
2898
                x = awidth - HANDLE_SIZE;
3230
2899
                if (edges & PANEL_EDGE_RIGHT)
3231
 
                        x -= xthickness;
 
2900
                        x -= padding.right;
3232
2901
 
3233
 
                gtk_paint_handle (style, window, state,
3234
 
                                  GTK_SHADOW_OUT,
3235
 
                                  &event->area, widget, "handlebox",
3236
 
                                  x, y, width, height,
3237
 
                                  GTK_ORIENTATION_VERTICAL);
 
2902
                cairo_save (cr);
 
2903
                gtk_render_handle (context, cr, x, y, width, height);
 
2904
                cairo_restore (cr);
3238
2905
        } else {
3239
2906
                int x, y, width, height;
3240
 
                int xthickness, ythickness;
3241
2907
 
3242
 
                x      = allocation.x;
3243
 
                y      = allocation.y;
3244
 
                width  = allocation.width;
 
2908
                x      = 0;
 
2909
                y      = 0;
 
2910
                width  = awidth;
3245
2911
                height = HANDLE_SIZE;
3246
2912
 
3247
 
                xthickness = style->xthickness;
3248
 
                ythickness = style->ythickness;
3249
 
 
3250
2913
                if (edges & PANEL_EDGE_LEFT) {
3251
 
                        x += xthickness;
3252
 
                        width -= xthickness;
 
2914
                        x += padding.left;
 
2915
                        width -= padding.left;
3253
2916
                }
3254
2917
                if (edges & PANEL_EDGE_RIGHT)
3255
 
                        width -= xthickness;
 
2918
                        width -= padding.right;
3256
2919
                if (edges & PANEL_EDGE_TOP)
3257
 
                        y += ythickness;
3258
 
 
3259
 
                gtk_paint_handle (style, window, state,
3260
 
                                  GTK_SHADOW_OUT,
3261
 
                                  &event->area, widget, "handlebox",
3262
 
                                  x, y, width, height,
3263
 
                                  GTK_ORIENTATION_HORIZONTAL);
3264
 
 
3265
 
                y = allocation.height - HANDLE_SIZE;
 
2920
                        y += padding.top;
 
2921
 
 
2922
                cairo_save (cr);
 
2923
                gtk_render_handle (context, cr, x, y, width, height);
 
2924
                cairo_restore (cr);
 
2925
 
 
2926
                y = aheight - HANDLE_SIZE;
3266
2927
                if (edges & PANEL_EDGE_BOTTOM)
3267
 
                        y -= ythickness;
 
2928
                        y -= padding.bottom;
3268
2929
 
3269
 
                gtk_paint_handle (style, window, state,
3270
 
                                  GTK_SHADOW_OUT,
3271
 
                                  &event->area, widget, "handlebox",
3272
 
                                  x, y, width, height,
3273
 
                                  GTK_ORIENTATION_HORIZONTAL);
 
2930
                cairo_save (cr);
 
2931
                gtk_render_handle (context, cr, x, y, width, height);
 
2932
                cairo_restore (cr);
3274
2933
        }
3275
2934
 
 
2935
        gtk_style_context_restore (context);
 
2936
 
3276
2937
        return retval;
3277
2938
}
3278
2939
 
3281
2942
                                   GdkEventButton *event)
3282
2943
{
3283
2944
        PanelToplevel *toplevel;
 
2945
        guint          modifiers;
3284
2946
        GtkWidget     *event_widget;
3285
2947
 
3286
2948
        g_return_val_if_fail (PANEL_IS_TOPLEVEL (widget), FALSE);
3293
2955
        if (toplevel->priv->animating)
3294
2956
                return FALSE;
3295
2957
 
 
2958
        modifiers = event->state & gtk_accelerator_get_default_mod_mask ();
 
2959
 
3296
2960
        /* Get the mouse-button modifier from metacity so that only intentional
3297
2961
         * moves are considered. We don't this for non-expanded panels since we
3298
2962
         * only have the handles that the user can grab. */
3299
 
        if ((toplevel->priv->expand || toplevel->priv->attached) &&
3300
 
            (event->state & GDK_MODIFIER_MASK) != panel_bindings_get_mouse_button_modifier_keymask ())
 
2963
        if (toplevel->priv->expand &&
 
2964
            modifiers != panel_bindings_get_mouse_button_modifier_keymask ())
3301
2965
                return FALSE;
3302
2966
 
3303
2967
        gdk_window_get_user_data (event->window, (gpointer)&event_widget);
3516
3180
                return;
3517
3181
        }
3518
3182
 
3519
 
        if (toplevel->priv->attached) {
3520
 
                /* Re-map unmapped attached toplevels */
3521
 
                if (!gtk_widget_get_mapped (GTK_WIDGET (toplevel)))
3522
 
                        gtk_widget_map (GTK_WIDGET (toplevel));
3523
 
 
3524
 
                gtk_window_present (GTK_WINDOW (toplevel->priv->attach_toplevel));
3525
 
        }
3526
 
 
3527
3183
        g_get_current_time (&toplevel->priv->animation_start_time);
3528
3184
 
3529
3185
        t = panel_toplevel_get_animation_time (toplevel);
3547
3203
 
3548
3204
        g_signal_emit (toplevel, toplevel_signals [HIDE_SIGNAL], 0);
3549
3205
 
3550
 
        if (toplevel->priv->attach_toplevel)
3551
 
                panel_toplevel_pop_autohide_disabler (toplevel->priv->attach_toplevel);
3552
 
 
3553
3206
        if (auto_hide)
3554
3207
                toplevel->priv->state = PANEL_STATE_AUTO_HIDDEN;
3555
3208
        else {
3587
3240
 
3588
3241
        if (toplevel->priv->animate && gtk_widget_get_realized (GTK_WIDGET (toplevel)))
3589
3242
                panel_toplevel_start_animation (toplevel);
3590
 
        else if (toplevel->priv->attached)
3591
 
                gtk_widget_hide (GTK_WIDGET (toplevel));
3592
3243
 
3593
3244
        gtk_widget_queue_resize (GTK_WIDGET (toplevel));
3594
3245
}
3630
3281
 
3631
3282
        panel_toplevel_update_hide_buttons (toplevel);
3632
3283
 
3633
 
        if (toplevel->priv->attach_toplevel)
3634
 
                panel_toplevel_push_autohide_disabler (toplevel->priv->attach_toplevel);
3635
 
 
3636
3284
        if (toplevel->priv->animate && gtk_widget_get_realized (GTK_WIDGET (toplevel)))
3637
3285
                panel_toplevel_start_animation (toplevel);
3638
 
        else if (toplevel->priv->attached)
3639
 
                gtk_widget_show (GTK_WIDGET (toplevel));
3640
3286
 
3641
3287
        gtk_widget_queue_resize (GTK_WIDGET (toplevel));
3642
3288
 
3826
3472
}
3827
3473
 
3828
3474
static void
3829
 
panel_toplevel_style_set (GtkWidget *widget,
3830
 
                          GtkStyle  *previous_style)
 
3475
panel_toplevel_style_updated (GtkWidget *widget)
3831
3476
{
3832
3477
        panel_toplevel_update_hide_buttons (PANEL_TOPLEVEL (widget));
3833
3478
 
3834
 
        if (GTK_WIDGET_CLASS (panel_toplevel_parent_class)->style_set)
3835
 
                GTK_WIDGET_CLASS (panel_toplevel_parent_class)->style_set (widget, previous_style);
 
3479
        if (GTK_WIDGET_CLASS (panel_toplevel_parent_class)->style_updated)
 
3480
                GTK_WIDGET_CLASS (panel_toplevel_parent_class)->style_updated (widget);
3836
3481
}
3837
3482
 
3838
3483
static void
3850
3495
}
3851
3496
 
3852
3497
static void
 
3498
panel_toplevel_enable_animations_changed (PanelToplevel *toplevel)
 
3499
{
 
3500
        gboolean enable_animations;
 
3501
 
 
3502
        enable_animations = TRUE;
 
3503
        g_object_get (G_OBJECT (toplevel->priv->gtk_settings),
 
3504
                      "gtk-enable-animations", &enable_animations,
 
3505
                      NULL);
 
3506
 
 
3507
        panel_toplevel_set_animate (toplevel, enable_animations);
 
3508
}
 
3509
 
 
3510
static void
 
3511
panel_toplevel_disconnect_gtk_settings (PanelToplevel *toplevel)
 
3512
{
 
3513
        if (!toplevel->priv->gtk_settings)
 
3514
                return;
 
3515
 
 
3516
        g_signal_handlers_disconnect_by_func (toplevel->priv->gtk_settings,
 
3517
                                              G_CALLBACK (panel_toplevel_drag_threshold_changed),
 
3518
                                              toplevel);
 
3519
        g_signal_handlers_disconnect_by_func (toplevel->priv->gtk_settings,
 
3520
                                              G_CALLBACK (panel_toplevel_enable_animations_changed),
 
3521
                                              toplevel);
 
3522
}
 
3523
 
 
3524
static void
3853
3525
panel_toplevel_update_gtk_settings (PanelToplevel *toplevel)
3854
3526
{
3855
 
        if (toplevel->priv->gtk_settings)
3856
 
                g_signal_handlers_disconnect_by_func (toplevel->priv->gtk_settings,
3857
 
                                                      G_CALLBACK (panel_toplevel_drag_threshold_changed),
3858
 
                                                      toplevel);
 
3527
        panel_toplevel_disconnect_gtk_settings (toplevel);
3859
3528
 
3860
3529
        toplevel->priv->gtk_settings = gtk_widget_get_settings (GTK_WIDGET (toplevel->priv->panel_widget));
3861
3530
 
3865
3534
                                  toplevel);
3866
3535
 
3867
3536
        panel_toplevel_drag_threshold_changed (toplevel);
 
3537
 
 
3538
        g_signal_connect_swapped (G_OBJECT (toplevel->priv->gtk_settings),
 
3539
                                  "notify::gtk-enable-animations",
 
3540
                                  G_CALLBACK (panel_toplevel_enable_animations_changed),
 
3541
                                  toplevel);
 
3542
 
 
3543
        panel_toplevel_enable_animations_changed (toplevel);
3868
3544
}
3869
3545
 
3870
3546
static void
3879
3555
        gtk_widget_queue_resize (widget);
3880
3556
}
3881
3557
 
 
3558
static GObject *
 
3559
panel_toplevel_constructor (GType                  type,
 
3560
                            guint                  n_construct_properties,
 
3561
                            GObjectConstructParam *construct_properties)
 
3562
{
 
3563
        GObject       *obj;
 
3564
        PanelToplevel *toplevel;
 
3565
 
 
3566
        obj = G_OBJECT_CLASS (panel_toplevel_parent_class)->constructor (type,
 
3567
                                                                         n_construct_properties,
 
3568
                                                                         construct_properties);
 
3569
 
 
3570
        toplevel = PANEL_TOPLEVEL (obj);
 
3571
 
 
3572
        /* We can't do that in init() as init() will set the properties to
 
3573
         * their default, and this would write to gsettings */
 
3574
        panel_toplevel_bind_gsettings (toplevel);
 
3575
 
 
3576
        return obj;
 
3577
}
 
3578
 
3882
3579
static void
3883
3580
panel_toplevel_set_property (GObject      *object,
3884
3581
                             guint         prop_id,
3892
3589
        toplevel = PANEL_TOPLEVEL (object);
3893
3590
 
3894
3591
        switch (prop_id) {
 
3592
        case PROP_TOPLEVEL_ID:
 
3593
                panel_toplevel_set_toplevel_id (toplevel, g_value_get_string (value));
 
3594
                break;
 
3595
        case PROP_SETTINGS_PATH:
 
3596
                panel_toplevel_set_settings_path (toplevel, g_value_get_string (value));
 
3597
                break;
3895
3598
        case PROP_NAME:
3896
3599
                panel_toplevel_set_name (toplevel, g_value_get_string (value));
3897
3600
                break;
3986
3689
        toplevel = PANEL_TOPLEVEL (object);
3987
3690
 
3988
3691
        switch (prop_id) {
 
3692
        case PROP_TOPLEVEL_ID:
 
3693
                g_value_set_string (value, toplevel->priv->toplevel_id);
 
3694
                break;
 
3695
        case PROP_SETTINGS_PATH:
 
3696
                g_value_set_string (value, toplevel->priv->settings_path);
 
3697
                break;
3989
3698
        case PROP_NAME:
3990
3699
                g_value_set_string (value, panel_toplevel_get_name (toplevel));
3991
3700
                break;
4058
3767
 
4059
3768
        toplevel_list = g_slist_remove (toplevel_list, toplevel);
4060
3769
 
4061
 
        if (toplevel->priv->gtk_settings) {
4062
 
                g_signal_handlers_disconnect_by_func (toplevel->priv->gtk_settings,
4063
 
                                                      G_CALLBACK (panel_toplevel_drag_threshold_changed),
4064
 
                                                      toplevel);
4065
 
                toplevel->priv->gtk_settings = NULL;
4066
 
        }
4067
 
 
4068
 
        if (toplevel->priv->attached) {
4069
 
                panel_toplevel_disconnect_attached (toplevel);
4070
 
 
4071
 
                toplevel->priv->attached = FALSE;
4072
 
 
4073
 
                toplevel->priv->attach_toplevel = NULL;
4074
 
                toplevel->priv->attach_widget   = NULL;
4075
 
        }
 
3770
        panel_toplevel_disconnect_gtk_settings (toplevel);
 
3771
        toplevel->priv->gtk_settings = NULL;
4076
3772
 
4077
3773
        if (toplevel->priv->description)
4078
3774
                g_free (toplevel->priv->description);
4082
3778
                g_free (toplevel->priv->name);
4083
3779
        toplevel->priv->name = NULL;
4084
3780
 
 
3781
        if (toplevel->priv->apply_delayed_id)
 
3782
                g_source_remove (toplevel->priv->apply_delayed_id);
 
3783
        toplevel->priv->apply_delayed_id = 0;
 
3784
 
 
3785
        if (toplevel->priv->delayed_settings) {
 
3786
                g_settings_apply (toplevel->priv->delayed_settings);
 
3787
                g_object_unref (toplevel->priv->delayed_settings);
 
3788
        }
 
3789
        toplevel->priv->delayed_settings= NULL;
 
3790
 
 
3791
        if (toplevel->priv->settings)
 
3792
                g_object_unref (toplevel->priv->settings);
 
3793
        toplevel->priv->settings= NULL;
 
3794
 
 
3795
        if (toplevel->priv->settings_path)
 
3796
                g_free (toplevel->priv->settings_path);
 
3797
        toplevel->priv->settings_path = NULL;
 
3798
 
 
3799
        if (toplevel->priv->toplevel_id)
 
3800
                g_free (toplevel->priv->toplevel_id);
 
3801
        toplevel->priv->toplevel_id = NULL;
 
3802
 
4085
3803
        G_OBJECT_CLASS (panel_toplevel_parent_class)->finalize (object);
4086
3804
}
4087
3805
 
4089
3807
panel_toplevel_class_init (PanelToplevelClass *klass)
4090
3808
{
4091
3809
        GObjectClass      *gobject_class   = (GObjectClass      *) klass;
4092
 
        GtkObjectClass    *gtkobject_class = (GtkObjectClass    *) klass;
4093
3810
        GtkWidgetClass    *widget_class    = (GtkWidgetClass    *) klass;
4094
3811
        GtkContainerClass *container_class = (GtkContainerClass *) klass;
4095
3812
        GtkBindingSet     *binding_set;
4096
3813
 
4097
3814
        binding_set = gtk_binding_set_by_class (klass);
4098
3815
 
 
3816
        gobject_class->constructor  = panel_toplevel_constructor;
4099
3817
        gobject_class->set_property = panel_toplevel_set_property;
4100
3818
        gobject_class->get_property = panel_toplevel_get_property;
 
3819
        gobject_class->dispose      = panel_toplevel_dispose;
4101
3820
        gobject_class->finalize     = panel_toplevel_finalize;
4102
3821
 
4103
 
        gtkobject_class->destroy = panel_toplevel_destroy;
4104
 
 
4105
3822
        widget_class->realize              = panel_toplevel_realize;
4106
3823
        widget_class->unrealize            = panel_toplevel_unrealize;
4107
 
        widget_class->size_request         = panel_toplevel_size_request;
 
3824
        widget_class->get_preferred_width  = panel_toplevel_get_preferred_width;
 
3825
        widget_class->get_preferred_height = panel_toplevel_get_preferred_height;
4108
3826
        widget_class->size_allocate        = panel_toplevel_size_allocate;
4109
 
        widget_class->expose_event         = panel_toplevel_expose;
 
3827
        widget_class->draw                 = panel_toplevel_draw;
4110
3828
        widget_class->button_press_event   = panel_toplevel_button_press_event;
4111
3829
        widget_class->button_release_event = panel_toplevel_button_release_event;
4112
3830
        widget_class->key_press_event      = panel_toplevel_key_press_event;
4116
3834
        widget_class->screen_changed       = panel_toplevel_screen_changed;
4117
3835
        widget_class->focus_in_event       = panel_toplevel_focus_in_event;
4118
3836
        widget_class->focus_out_event      = panel_toplevel_focus_out_event;
4119
 
        widget_class->style_set            = panel_toplevel_style_set;
 
3837
        widget_class->style_updated        = panel_toplevel_style_updated;
4120
3838
 
4121
3839
        container_class->check_resize = panel_toplevel_check_resize;
4122
3840
 
4134
3852
 
4135
3853
        g_object_class_install_property (
4136
3854
                gobject_class,
 
3855
                PROP_TOPLEVEL_ID,
 
3856
                g_param_spec_string (
 
3857
                        "toplevel-id",
 
3858
                        "Panel identifier",
 
3859
                        "Unique identifier of this panel",
 
3860
                        NULL,
 
3861
                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
3862
 
 
3863
        g_object_class_install_property (
 
3864
                gobject_class,
 
3865
                PROP_SETTINGS_PATH,
 
3866
                g_param_spec_string (
 
3867
                        "settings-path",
 
3868
                        "GSettings path",
 
3869
                        "The GSettings path used for this panel",
 
3870
                        NULL,
 
3871
                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
3872
 
 
3873
        g_object_class_install_property (
 
3874
                gobject_class,
4137
3875
                PROP_NAME,
4138
3876
                g_param_spec_string (
4139
3877
                        "name",
4226
3964
                gobject_class,
4227
3965
                PROP_Y_BOTTOM,
4228
3966
                g_param_spec_int (
4229
 
                        "y_bottom",
 
3967
                        "y-bottom",
4230
3968
                        "Y position, from the bottom",
4231
3969
                        "The Y position of the panel, starting from the bottom of the screen",
4232
3970
                        -1,
4310
4048
                        "Animate",
4311
4049
                        "Enable hiding/showing animations",
4312
4050
                        TRUE,
4313
 
                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
4051
                        G_PARAM_READABLE));
4314
4052
 
4315
4053
        g_object_class_install_property (
4316
4054
                gobject_class,
4453
4191
                              G_TYPE_BOOLEAN,
4454
4192
                              0);
4455
4193
 
4456
 
        gtk_binding_entry_add_signal (binding_set, GDK_F10, GDK_CONTROL_MASK,
 
4194
        gtk_binding_entry_add_signal (binding_set, GDK_KEY_F10, GDK_CONTROL_MASK,
4457
4195
                                     "popup_panel_menu", 0);
4458
4196
 
4459
4197
        panel_bindings_set_entries (binding_set);
4517
4255
static void
4518
4256
panel_toplevel_init (PanelToplevel *toplevel)
4519
4257
{
4520
 
        int i;
4521
 
 
4522
4258
        toplevel->priv = PANEL_TOPLEVEL_GET_PRIVATE (toplevel);
4523
4259
 
 
4260
        toplevel->priv->toplevel_id      = NULL;
 
4261
 
 
4262
        toplevel->priv->settings_path    = NULL;
 
4263
        toplevel->priv->settings         = NULL;
 
4264
        toplevel->priv->delayed_settings = NULL;
 
4265
        toplevel->priv->apply_delayed_id = 0;
 
4266
 
4524
4267
        toplevel->priv->expand          = TRUE;
4525
4268
        toplevel->priv->orientation     = PANEL_ORIENTATION_BOTTOM;
4526
4269
        toplevel->priv->size            = DEFAULT_SIZE;
4577
4320
        toplevel->priv->hide_button_left   = NULL;
4578
4321
        toplevel->priv->hide_button_right  = NULL;
4579
4322
 
4580
 
        toplevel->priv->attach_toplevel = NULL;
4581
 
        toplevel->priv->attach_widget   = NULL;
4582
4323
        toplevel->priv->n_autohide_disablers = 0;
4583
4324
 
4584
 
        for (i = 0; i < N_ATTACH_TOPLEVEL_SIGNALS; i++)
4585
 
                toplevel->priv->attach_toplevel_signals [i] = 0;
4586
 
        for (i = 0; i < N_ATTACH_WIDGET_SIGNALS; i++)
4587
 
                toplevel->priv->attach_widget_signals [i] = 0;
4588
 
 
4589
4325
        toplevel->priv->auto_hide         = FALSE;
4590
4326
        toplevel->priv->buttons_enabled   = TRUE;
4591
4327
        toplevel->priv->arrows_enabled    = TRUE;
4594
4330
        toplevel->priv->animating         = FALSE;
4595
4331
        toplevel->priv->grab_is_keyboard  = FALSE;
4596
4332
        toplevel->priv->position_centered = FALSE;
4597
 
        toplevel->priv->attached          = FALSE;
4598
 
        toplevel->priv->attach_hidden     = FALSE;
4599
4333
        toplevel->priv->updated_geometry_initial = FALSE;
4600
4334
        toplevel->priv->initial_animation_done   = FALSE;
4601
4335
 
4612
4346
        
4613
4347
        toplevel_list = g_slist_prepend (toplevel_list, toplevel);
4614
4348
 
4615
 
        gtk_window_set_has_resize_grip (GTK_WINDOW (toplevel), FALSE);
4616
 
 
4617
4349
        /* Prevent the window from being deleted via Alt+F4 by accident.  This
4618
4350
         * happens with "alternative" window managers such as Sawfish or XFWM4.
4619
4351
         */
4621
4353
                          "delete-event",
4622
4354
                          G_CALLBACK (gtk_true),
4623
4355
                          NULL);
 
4356
 
 
4357
        /* We don't want a resize grip on the panel */
 
4358
        gtk_window_set_has_resize_grip (GTK_WINDOW (toplevel), FALSE);
4624
4359
}
4625
4360
 
4626
4361
PanelWidget *
4631
4366
        return toplevel->priv->panel_widget;
4632
4367
}
4633
4368
 
 
4369
static gboolean
 
4370
panel_toplevel_position_is_writable (PanelToplevel *toplevel)
 
4371
{
 
4372
        if (panel_lockdown_get_panels_locked_down_s () ||
 
4373
            !(g_settings_is_writable (toplevel->priv->settings,
 
4374
                                      PANEL_TOPLEVEL_SCREEN_KEY) &&
 
4375
              g_settings_is_writable (toplevel->priv->settings,
 
4376
                                      PANEL_TOPLEVEL_MONITOR_KEY) &&
 
4377
              g_settings_is_writable (toplevel->priv->settings,
 
4378
                                      PANEL_TOPLEVEL_ORIENTATION_KEY)))
 
4379
                return FALSE;
 
4380
 
 
4381
        /* For expanded panels we don't really have to check x and y */
 
4382
        if (panel_toplevel_get_expand (toplevel))
 
4383
                return TRUE;
 
4384
 
 
4385
        return (g_settings_is_writable (toplevel->priv->settings,
 
4386
                                        PANEL_TOPLEVEL_X_KEY) &&
 
4387
                g_settings_is_writable (toplevel->priv->settings,
 
4388
                                        PANEL_TOPLEVEL_Y_KEY) &&
 
4389
                g_settings_is_writable (toplevel->priv->settings,
 
4390
                                        PANEL_TOPLEVEL_X_RIGHT_KEY) &&
 
4391
                g_settings_is_writable (toplevel->priv->settings,
 
4392
                                        PANEL_TOPLEVEL_Y_BOTTOM_KEY) &&
 
4393
                g_settings_is_writable (toplevel->priv->settings,
 
4394
                                        PANEL_TOPLEVEL_X_CENTERED_KEY) &&
 
4395
                g_settings_is_writable (toplevel->priv->settings,
 
4396
                                        PANEL_TOPLEVEL_Y_CENTERED_KEY));
 
4397
}
 
4398
 
 
4399
static gboolean
 
4400
panel_toplevel_apply_delayed_settings (PanelToplevel *toplevel)
 
4401
{
 
4402
        g_settings_apply (toplevel->priv->delayed_settings);
 
4403
 
 
4404
        toplevel->priv->apply_delayed_id = 0;
 
4405
 
 
4406
        return FALSE;
 
4407
}
 
4408
 
 
4409
static void
 
4410
panel_toplevel_apply_delayed_settings_queue (PanelToplevel *toplevel)
 
4411
{
 
4412
        if (toplevel->priv->apply_delayed_id != 0)
 
4413
                return;
 
4414
 
 
4415
        toplevel->priv->apply_delayed_id = g_timeout_add (500,
 
4416
                                                          (GSourceFunc) panel_toplevel_apply_delayed_settings,
 
4417
                                                          toplevel);
 
4418
}
 
4419
 
 
4420
static gboolean
 
4421
panel_toplevel_settings_bind_get_screen (GValue   *value,
 
4422
                                         GVariant *variant,
 
4423
                                         gpointer  user_data)
 
4424
{
 
4425
        PanelToplevel *toplevel = PANEL_TOPLEVEL (user_data);
 
4426
        GdkDisplay    *display;
 
4427
        GdkScreen     *screen;
 
4428
        int            screen_n;
 
4429
 
 
4430
        display = gdk_display_get_default ();
 
4431
        screen_n = g_variant_get_int32 (variant);
 
4432
 
 
4433
        if (screen_n < 0 || screen_n >= gdk_display_get_n_screens (display)) {
 
4434
                /* Trigger an event so that the gsettings key gets updated, to
 
4435
                 * to set the key back to an actual available screen so it will
 
4436
                 * get loaded on next startup. */
 
4437
                g_object_notify (G_OBJECT (toplevel), "screen");
 
4438
                return FALSE;
 
4439
        }
 
4440
 
 
4441
        screen = gdk_display_get_screen (display, screen_n);
 
4442
 
 
4443
        if (screen != NULL)
 
4444
                g_value_set_object (value, screen);
 
4445
 
 
4446
        return (screen != NULL);
 
4447
}
 
4448
 
 
4449
static GVariant *
 
4450
panel_toplevel_settings_bind_set_screen (const GValue       *value,
 
4451
                                         const GVariantType *expected_type,
 
4452
                                         gpointer            user_data)
 
4453
{
 
4454
        GdkScreen *screen = g_value_get_object (value);
 
4455
 
 
4456
        if (!screen || GDK_IS_SCREEN (screen))
 
4457
                screen = gdk_screen_get_default ();
 
4458
 
 
4459
        return g_variant_new ("i", gdk_screen_get_number (screen));
 
4460
}
 
4461
 
 
4462
static void
 
4463
panel_toplevel_bind_gsettings (PanelToplevel *toplevel)
 
4464
{
 
4465
        /* Delayed settings: the ones related to the position */
 
4466
 
 
4467
        g_settings_bind (toplevel->priv->delayed_settings,
 
4468
                         PANEL_TOPLEVEL_MONITOR_KEY,
 
4469
                         toplevel,
 
4470
                         "monitor",
 
4471
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4472
 
 
4473
        g_settings_bind (toplevel->priv->delayed_settings,
 
4474
                         PANEL_TOPLEVEL_SIZE_KEY,
 
4475
                         toplevel,
 
4476
                         "size",
 
4477
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4478
 
 
4479
        g_settings_bind (toplevel->priv->delayed_settings,
 
4480
                         PANEL_TOPLEVEL_ORIENTATION_KEY,
 
4481
                         toplevel,
 
4482
                         "orientation",
 
4483
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4484
 
 
4485
        g_settings_bind (toplevel->priv->delayed_settings,
 
4486
                         PANEL_TOPLEVEL_X_KEY,
 
4487
                         toplevel,
 
4488
                         "x",
 
4489
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4490
 
 
4491
        g_settings_bind (toplevel->priv->delayed_settings,
 
4492
                         PANEL_TOPLEVEL_X_RIGHT_KEY,
 
4493
                         toplevel,
 
4494
                         "x-right",
 
4495
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4496
 
 
4497
        g_settings_bind (toplevel->priv->delayed_settings,
 
4498
                         PANEL_TOPLEVEL_X_CENTERED_KEY,
 
4499
                         toplevel,
 
4500
                         "x-centered",
 
4501
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4502
 
 
4503
        g_settings_bind (toplevel->priv->delayed_settings,
 
4504
                         PANEL_TOPLEVEL_Y_KEY,
 
4505
                         toplevel,
 
4506
                         "y",
 
4507
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4508
 
 
4509
        g_settings_bind (toplevel->priv->delayed_settings,
 
4510
                         PANEL_TOPLEVEL_Y_BOTTOM_KEY,
 
4511
                         toplevel,
 
4512
                         "y-bottom",
 
4513
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4514
 
 
4515
        g_settings_bind (toplevel->priv->delayed_settings,
 
4516
                         PANEL_TOPLEVEL_Y_CENTERED_KEY,
 
4517
                         toplevel,
 
4518
                         "y-centered",
 
4519
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4520
 
 
4521
        /* Normal settings */
 
4522
 
 
4523
        g_settings_bind_with_mapping (toplevel->priv->settings,
 
4524
                                      PANEL_TOPLEVEL_SCREEN_KEY,
 
4525
                                      toplevel,
 
4526
                                      "screen",
 
4527
                                      G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY,
 
4528
                                      panel_toplevel_settings_bind_get_screen,
 
4529
                                      panel_toplevel_settings_bind_set_screen,
 
4530
                                      toplevel, NULL);
 
4531
 
 
4532
        g_settings_bind (toplevel->priv->settings,
 
4533
                         PANEL_TOPLEVEL_NAME_KEY,
 
4534
                         toplevel,
 
4535
                         "name",
 
4536
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4537
 
 
4538
        g_settings_bind (toplevel->priv->settings,
 
4539
                         PANEL_TOPLEVEL_EXPAND_KEY,
 
4540
                         toplevel,
 
4541
                         "expand",
 
4542
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4543
 
 
4544
        g_settings_bind (toplevel->priv->settings,
 
4545
                         PANEL_TOPLEVEL_AUTO_HIDE_KEY,
 
4546
                         toplevel,
 
4547
                         "auto-hide",
 
4548
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4549
 
 
4550
        g_settings_bind (toplevel->priv->settings,
 
4551
                         PANEL_TOPLEVEL_HIDE_DELAY_KEY,
 
4552
                         toplevel,
 
4553
                         "hide-delay",
 
4554
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4555
 
 
4556
        g_settings_bind (toplevel->priv->settings,
 
4557
                         PANEL_TOPLEVEL_UNHIDE_DELAY_KEY,
 
4558
                         toplevel,
 
4559
                         "unhide-delay",
 
4560
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4561
 
 
4562
        g_settings_bind (toplevel->priv->settings,
 
4563
                         PANEL_TOPLEVEL_AUTO_HIDE_SIZE_KEY,
 
4564
                         toplevel,
 
4565
                         "auto-hide-size",
 
4566
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4567
 
 
4568
        g_settings_bind (toplevel->priv->settings,
 
4569
                         PANEL_TOPLEVEL_ANIMATION_SPEED_KEY,
 
4570
                         toplevel,
 
4571
                         "animation-speed",
 
4572
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4573
 
 
4574
        g_settings_bind (toplevel->priv->settings,
 
4575
                         PANEL_TOPLEVEL_ENABLE_BUTTONS_KEY,
 
4576
                         toplevel,
 
4577
                         "buttons-enabled",
 
4578
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4579
 
 
4580
        g_settings_bind (toplevel->priv->settings,
 
4581
                         PANEL_TOPLEVEL_ENABLE_ARROWS_KEY,
 
4582
                         toplevel,
 
4583
                         "arrows-enabled",
 
4584
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_NO_SENSITIVITY);
 
4585
}
 
4586
 
 
4587
static void
 
4588
panel_toplevel_set_toplevel_id (PanelToplevel *toplevel,
 
4589
                                const char    *toplevel_id)
 
4590
{
 
4591
        g_assert (toplevel->priv->toplevel_id == NULL);
 
4592
 
 
4593
        toplevel->priv->toplevel_id = g_strdup (toplevel_id);
 
4594
}
 
4595
 
 
4596
G_CONST_RETURN char *
 
4597
panel_toplevel_get_id (PanelToplevel *toplevel)
 
4598
{
 
4599
        g_return_val_if_fail (PANEL_IS_TOPLEVEL (toplevel), NULL);
 
4600
 
 
4601
        return toplevel->priv->toplevel_id;
 
4602
}
 
4603
 
 
4604
static void
 
4605
panel_toplevel_set_settings_path (PanelToplevel *toplevel,
 
4606
                                  const char    *settings_path)
 
4607
{
 
4608
        GSettings *settings_background;
 
4609
 
 
4610
        g_assert (toplevel->priv->settings_path == NULL);
 
4611
        g_assert (toplevel->priv->settings == NULL);
 
4612
        g_assert (toplevel->priv->delayed_settings == NULL);
 
4613
 
 
4614
        toplevel->priv->settings_path = g_strdup (settings_path);
 
4615
        toplevel->priv->settings = g_settings_new_with_path (PANEL_TOPLEVEL_SCHEMA,
 
4616
                                                             settings_path);
 
4617
        toplevel->priv->delayed_settings = g_settings_new_with_path (PANEL_TOPLEVEL_SCHEMA,
 
4618
                                                                     settings_path);
 
4619
        g_settings_delay (toplevel->priv->delayed_settings);
 
4620
 
 
4621
        settings_background = g_settings_get_child (toplevel->priv->settings,
 
4622
                                                    PANEL_BACKGROUND_SCHEMA_CHILD);
 
4623
        /* FIXME: ideally, move this inside panel-widget.c since we're not
 
4624
         * supposed to know about the backgrounds here */
 
4625
        panel_background_settings_init (&toplevel->priv->panel_widget->background,
 
4626
                                        settings_background);
 
4627
        g_object_unref (settings_background);
 
4628
}
 
4629
 
4634
4630
static void
4635
4631
panel_toplevel_update_name (PanelToplevel *toplevel)
4636
4632
{
4850
4846
 
4851
4847
        gtk_widget_queue_resize (GTK_WIDGET (toplevel));
4852
4848
 
 
4849
        panel_toplevel_apply_delayed_settings_queue (toplevel);
4853
4850
        g_object_notify (G_OBJECT (toplevel), "orientation");
4854
4851
 
4855
4852
        g_object_thaw_notify (G_OBJECT (toplevel));
4879
4876
 
4880
4877
        gtk_widget_queue_resize (GTK_WIDGET (toplevel));
4881
4878
 
 
4879
        panel_toplevel_apply_delayed_settings_queue (toplevel);
4882
4880
        g_object_notify (G_OBJECT (toplevel), "size");
4883
4881
}
4884
4882
 
4954
4952
                g_object_notify (G_OBJECT (toplevel), "x-centered");
4955
4953
        }
4956
4954
 
4957
 
        if (changed)
 
4955
        if (changed) {
 
4956
                panel_toplevel_apply_delayed_settings_queue (toplevel);
4958
4957
                gtk_widget_queue_resize (GTK_WIDGET (toplevel));
 
4958
        }
4959
4959
 
4960
4960
        g_object_thaw_notify (G_OBJECT (toplevel));
4961
4961
}
4992
4992
                g_object_notify (G_OBJECT (toplevel), "y-centered");
4993
4993
        }
4994
4994
 
4995
 
        if (changed)
 
4995
        if (changed) {
 
4996
                panel_toplevel_apply_delayed_settings_queue (toplevel);
4996
4997
                gtk_widget_queue_resize (GTK_WIDGET (toplevel));
 
4998
        }
4997
4999
 
4998
5000
        g_object_thaw_notify (G_OBJECT (toplevel));
4999
5001
}
5115
5117
        if (monitor < panel_multiscreen_monitors (screen))
5116
5118
                panel_toplevel_set_monitor_internal (toplevel, monitor, TRUE);
5117
5119
 
 
5120
        panel_toplevel_apply_delayed_settings_queue (toplevel);
5118
5121
        g_object_notify (G_OBJECT (toplevel), "monitor");
5119
5122
}
5120
5123
 
5202
5205
        return toplevel->priv->unhide_delay;
5203
5206
}
5204
5207
 
5205
 
void
 
5208
static void
5206
5209
panel_toplevel_set_animate (PanelToplevel *toplevel,
5207
5210
                            gboolean       animate)
5208
5211
{