~ubuntu-branches/ubuntu/wily/xfce4-panel/wily

« back to all changes in this revision

Viewing changes to panel/panel-window.c

  • Committer: Package Import Robot
  • Author(s): Unit 193
  • Date: 2015-01-04 13:04:39 UTC
  • mfrom: (1.1.39)
  • Revision ID: package-import@ubuntu.com-20150104130439-sndt8o8ojwe6dr7g
Tags: 4.11.2-0ubuntu1
* New upstream development release.
  - Refresh patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Copyright (C) 2009-2010 Nick Schermer <nick@xfce.org>
 
3
 * Copyright (C) 2014 Jannis Pohlmann <jannis@xfce.org>
3
4
 *
4
5
 * This program is free software; you can redistribute it and/or modify
5
6
 * it under the terms of the GNU General Public License as published by
32
33
#include <X11/Xlib.h>
33
34
#endif
34
35
 
 
36
#include <libwnck/libwnck.h>
 
37
 
35
38
#include <exo/exo.h>
 
39
#include <xfconf/xfconf.h>
36
40
#include <common/panel-private.h>
37
41
#include <common/panel-debug.h>
38
42
#include <common/panel-utils.h>
65
69
 
66
70
 
67
71
 
68
 
typedef enum _StrutsEgde    StrutsEgde;
69
 
typedef enum _AutohideState AutohideState;
70
 
typedef enum _SnapPosition  SnapPosition;
71
 
typedef enum _PluginProp    PluginProp;
72
 
 
73
 
 
74
 
 
75
 
static void         panel_window_get_property               (GObject          *object,
76
 
                                                             guint             prop_id,
77
 
                                                             GValue           *value,
78
 
                                                             GParamSpec       *pspec);
79
 
static void         panel_window_set_property               (GObject          *object,
80
 
                                                             guint             prop_id,
81
 
                                                             const GValue     *value,
82
 
                                                             GParamSpec       *pspec);
83
 
static void         panel_window_finalize                   (GObject          *object);
84
 
static gboolean     panel_window_expose_event               (GtkWidget        *widget,
85
 
                                                             GdkEventExpose   *event);
86
 
static gboolean     panel_window_delete_event               (GtkWidget        *widget,
87
 
                                                             GdkEventAny      *event);
88
 
static gboolean     panel_window_enter_notify_event         (GtkWidget        *widget,
89
 
                                                             GdkEventCrossing *event);
90
 
static gboolean     panel_window_leave_notify_event         (GtkWidget        *widget,
91
 
                                                             GdkEventCrossing *event);
92
 
static gboolean     panel_window_drag_motion                (GtkWidget        *widget,
93
 
                                                             GdkDragContext   *context,
94
 
                                                             gint              x,
95
 
                                                             gint              y,
96
 
                                                             guint             drag_time);
97
 
static void         panel_window_drag_leave                 (GtkWidget        *widget,
98
 
                                                             GdkDragContext   *context,
99
 
                                                             guint             drag_time);
100
 
static gboolean     panel_window_motion_notify_event        (GtkWidget        *widget,
101
 
                                                             GdkEventMotion   *event);
102
 
static gboolean     panel_window_button_press_event         (GtkWidget        *widget,
103
 
                                                             GdkEventButton   *event);
104
 
static gboolean     panel_window_button_release_event       (GtkWidget        *widget,
105
 
                                                             GdkEventButton   *event);
106
 
static void         panel_window_grab_notify                (GtkWidget        *widget,
107
 
                                                             gboolean          was_grabbed);
108
 
static void         panel_window_size_request               (GtkWidget        *widget,
109
 
                                                             GtkRequisition   *requisition);
110
 
static void         panel_window_size_allocate              (GtkWidget        *widget,
111
 
                                                             GtkAllocation    *alloc);
112
 
static void         panel_window_size_allocate_set_xy       (PanelWindow      *window,
113
 
                                                             gint              window_width,
114
 
                                                             gint              window_height,
115
 
                                                             gint             *return_x,
116
 
                                                             gint             *return_y);
117
 
static void         panel_window_screen_changed             (GtkWidget        *widget,
118
 
                                                             GdkScreen        *previous_screen);
119
 
static void         panel_window_style_set                  (GtkWidget        *widget,
120
 
                                                             GtkStyle         *previous_style);
121
 
static void         panel_window_realize                    (GtkWidget        *widget);
122
 
static StrutsEgde   panel_window_screen_struts_edge         (PanelWindow      *window);
123
 
static void         panel_window_screen_struts_set          (PanelWindow      *window);
124
 
static void         panel_window_screen_update_borders      (PanelWindow      *window);
125
 
static SnapPosition panel_window_snap_position              (PanelWindow      *window);
126
 
static void         panel_window_display_layout_debug       (GtkWidget        *widget);
127
 
static void         panel_window_screen_layout_changed      (GdkScreen        *screen,
128
 
                                                             PanelWindow      *window);
129
 
static void         panel_window_autohide_queue             (PanelWindow      *window,
130
 
                                                             AutohideState     new_state);
131
 
static void         panel_window_set_autohide               (PanelWindow      *window,
132
 
                                                             gboolean          autohide);
133
 
static void         panel_window_menu_popup                 (PanelWindow      *window,
134
 
                                                             guint32           event_time);
135
 
static void         panel_window_plugins_update             (PanelWindow      *window,
136
 
                                                             PluginProp        prop);
137
 
static void         panel_window_plugin_set_mode            (GtkWidget        *widget,
138
 
                                                             gpointer          user_data);
139
 
static void         panel_window_plugin_set_size            (GtkWidget        *widget,
140
 
                                                             gpointer          user_data);
141
 
static void         panel_window_plugin_set_nrows           (GtkWidget        *widget,
142
 
                                                             gpointer          user_data);
143
 
static void         panel_window_plugin_set_screen_position (GtkWidget        *widget,
144
 
                                                             gpointer          user_data);
 
72
typedef enum _StrutsEgde       StrutsEgde;
 
73
typedef enum _AutohideBehavior AutohideBehavior;
 
74
typedef enum _AutohideState    AutohideState;
 
75
typedef enum _SnapPosition     SnapPosition;
 
76
typedef enum _PluginProp       PluginProp;
 
77
 
 
78
 
 
79
 
 
80
static void         panel_window_get_property                   (GObject          *object,
 
81
                                                                 guint             prop_id,
 
82
                                                                 GValue           *value,
 
83
                                                                 GParamSpec       *pspec);
 
84
static void         panel_window_set_property                   (GObject          *object,
 
85
                                                                 guint             prop_id,
 
86
                                                                 const GValue     *value,
 
87
                                                                 GParamSpec       *pspec);
 
88
static void         panel_window_finalize                       (GObject          *object);
 
89
static gboolean     panel_window_expose_event                   (GtkWidget        *widget,
 
90
                                                                 GdkEventExpose   *event);
 
91
static gboolean     panel_window_delete_event                   (GtkWidget        *widget,
 
92
                                                                 GdkEventAny      *event);
 
93
static gboolean     panel_window_enter_notify_event             (GtkWidget        *widget,
 
94
                                                                 GdkEventCrossing *event);
 
95
static gboolean     panel_window_leave_notify_event             (GtkWidget        *widget,
 
96
                                                                 GdkEventCrossing *event);
 
97
static gboolean     panel_window_drag_motion                    (GtkWidget        *widget,
 
98
                                                                 GdkDragContext   *context,
 
99
                                                                 gint              x,
 
100
                                                                 gint              y,
 
101
                                                                 guint             drag_time);
 
102
static void         panel_window_drag_leave                     (GtkWidget        *widget,
 
103
                                                                 GdkDragContext   *context,
 
104
                                                                 guint             drag_time);
 
105
static gboolean     panel_window_motion_notify_event            (GtkWidget        *widget,
 
106
                                                                 GdkEventMotion   *event);
 
107
static gboolean     panel_window_button_press_event             (GtkWidget        *widget,
 
108
                                                                 GdkEventButton   *event);
 
109
static gboolean     panel_window_button_release_event           (GtkWidget        *widget,
 
110
                                                                 GdkEventButton   *event);
 
111
static void         panel_window_grab_notify                    (GtkWidget        *widget,
 
112
                                                                 gboolean          was_grabbed);
 
113
static void         panel_window_size_request                   (GtkWidget        *widget,
 
114
                                                                 GtkRequisition   *requisition);
 
115
static void         panel_window_size_allocate                  (GtkWidget        *widget,
 
116
                                                                 GtkAllocation    *alloc);
 
117
static void         panel_window_size_allocate_set_xy           (PanelWindow      *window,
 
118
                                                                 gint              window_width,
 
119
                                                                 gint              window_height,
 
120
                                                                 gint             *return_x,
 
121
                                                                 gint             *return_y);
 
122
static void         panel_window_screen_changed                 (GtkWidget        *widget,
 
123
                                                                 GdkScreen        *previous_screen);
 
124
static void         panel_window_style_set                      (GtkWidget        *widget,
 
125
                                                                 GtkStyle         *previous_style);
 
126
static void         panel_window_realize                        (GtkWidget        *widget);
 
127
static StrutsEgde   panel_window_screen_struts_edge             (PanelWindow      *window);
 
128
static void         panel_window_screen_struts_set              (PanelWindow      *window);
 
129
static void         panel_window_screen_update_borders          (PanelWindow      *window);
 
130
static SnapPosition panel_window_snap_position                  (PanelWindow      *window);
 
131
static void         panel_window_display_layout_debug           (GtkWidget        *widget);
 
132
static void         panel_window_screen_layout_changed          (GdkScreen        *screen,
 
133
                                                                 PanelWindow      *window);
 
134
static void         panel_window_active_window_changed          (WnckScreen       *screen,
 
135
                                                                 WnckWindow       *previous_window,
 
136
                                                                 PanelWindow      *window);
 
137
static void         panel_window_active_window_geometry_changed (WnckWindow       *active_window,
 
138
                                                                 PanelWindow      *window);
 
139
static void         panel_window_autohide_queue                 (PanelWindow      *window,
 
140
                                                                 AutohideState     new_state);
 
141
static void         panel_window_set_autohide_behavior          (PanelWindow      *window,
 
142
                                                                 AutohideBehavior  behavior);
 
143
static void         panel_window_update_autohide_window         (PanelWindow      *window,
 
144
                                                                 WnckScreen       *screen,
 
145
                                                                 WnckWindow       *active_window);
 
146
static void         panel_window_menu_popup                     (PanelWindow      *window,
 
147
                                                                 guint32           event_time);
 
148
static void         panel_window_plugins_update                 (PanelWindow      *window,
 
149
                                                                 PluginProp        prop);
 
150
static void         panel_window_plugin_set_mode                (GtkWidget        *widget,
 
151
                                                                 gpointer          user_data);
 
152
static void         panel_window_plugin_set_size                (GtkWidget        *widget,
 
153
                                                                 gpointer          user_data);
 
154
static void         panel_window_plugin_set_nrows               (GtkWidget        *widget,
 
155
                                                                 gpointer          user_data);
 
156
static void         panel_window_plugin_set_screen_position     (GtkWidget        *widget,
 
157
                                                                 gpointer          user_data);
145
158
 
146
159
 
147
160
 
155
168
  PROP_LENGTH,
156
169
  PROP_LENGTH_ADJUST,
157
170
  PROP_POSITION_LOCKED,
158
 
  PROP_AUTOHIDE,
 
171
  PROP_AUTOHIDE_BEHAVIOR,
159
172
  PROP_SPAN_MONITORS,
160
173
  PROP_OUTPUT_NAME,
161
174
  PROP_POSITION,
170
183
  PLUGIN_PROP_SIZE
171
184
};
172
185
 
 
186
enum _AutohideBehavior
 
187
{
 
188
  AUTOHIDE_BEHAVIOR_NEVER = 0,
 
189
  AUTOHIDE_BEHAVIOR_INTELLIGENTLY,
 
190
  AUTOHIDE_BEHAVIOR_ALWAYS,
 
191
};
 
192
 
173
193
enum _AutohideState
174
194
{
175
195
  AUTOHIDE_DISABLED = 0, /* autohide is disabled */
278
298
  GdkRectangle         alloc;
279
299
 
280
300
  /* autohiding */
 
301
  WnckScreen          *wnck_screen;
 
302
  WnckWindow          *wnck_active_window;
281
303
  GtkWidget           *autohide_window;
 
304
  AutohideBehavior     autohide_behavior;
282
305
  AutohideState        autohide_state;
283
306
  guint                autohide_timeout_id;
284
307
  gint                 autohide_block;
393
416
                                                         EXO_PARAM_READWRITE));
394
417
 
395
418
  g_object_class_install_property (gobject_class,
396
 
                                   PROP_AUTOHIDE,
397
 
                                   g_param_spec_boolean ("autohide", NULL, NULL,
398
 
                                                         FALSE,
399
 
                                                         EXO_PARAM_READWRITE));
 
419
                                   PROP_AUTOHIDE_BEHAVIOR,
 
420
                                   g_param_spec_uint ("autohide-behavior", NULL, NULL,
 
421
                                                      AUTOHIDE_BEHAVIOR_NEVER,
 
422
                                                      AUTOHIDE_BEHAVIOR_ALWAYS,
 
423
                                                      AUTOHIDE_BEHAVIOR_NEVER,
 
424
                                                      EXO_PARAM_READWRITE));
400
425
 
401
426
  g_object_class_install_property (gobject_class,
402
427
                                   PROP_SPAN_MONITORS,
462
487
  window->id = -1;
463
488
  window->locked = TRUE;
464
489
  window->screen = NULL;
 
490
  window->wnck_screen = NULL;
 
491
  window->wnck_active_window = NULL;
465
492
  window->struts_edge = STRUTS_EDGE_NONE;
466
493
  window->struts_disabled = FALSE;
467
494
  window->mode = XFCE_PANEL_PLUGIN_MODE_HORIZONTAL;
473
500
  window->span_monitors = FALSE;
474
501
  window->position_locked = FALSE;
475
502
  window->autohide_state = AUTOHIDE_DISABLED;
 
503
  window->autohide_behavior = AUTOHIDE_BEHAVIOR_NEVER;
476
504
  window->autohide_timeout_id = 0;
477
505
  window->autohide_block = 0;
478
506
  window->autohide_grab_block = 0;
539
567
      g_value_set_boolean (value, window->position_locked);
540
568
      break;
541
569
 
542
 
    case PROP_AUTOHIDE:
543
 
      g_value_set_boolean (value, !!(window->autohide_state != AUTOHIDE_DISABLED));
 
570
    case PROP_AUTOHIDE_BEHAVIOR:
 
571
      g_value_set_uint (value, window->autohide_behavior);
544
572
      break;
545
573
 
546
574
    case PROP_SPAN_MONITORS:
663
691
        }
664
692
      break;
665
693
 
666
 
    case PROP_AUTOHIDE:
667
 
      panel_window_set_autohide (window, g_value_get_boolean (value));
 
694
    case PROP_AUTOHIDE_BEHAVIOR:
 
695
      panel_window_set_autohide_behavior (window, MIN (g_value_get_uint (value),
 
696
                                                       AUTOHIDE_BEHAVIOR_ALWAYS));
668
697
      break;
669
698
 
670
699
    case PROP_SPAN_MONITORS:
730
759
{
731
760
  PanelWindow *window = PANEL_WINDOW (object);
732
761
 
 
762
  /* disconnect from active screen and window */
 
763
  panel_window_update_autohide_window (window, NULL, NULL);
 
764
 
733
765
  /* stop running autohide timeout */
734
766
  if (G_UNLIKELY (window->autohide_timeout_id != 0))
735
767
    g_source_remove (window->autohide_timeout_id);
884
916
   /* queue an autohide timeout if needed */
885
917
  if (event->detail != GDK_NOTIFY_INFERIOR
886
918
      && window->autohide_state != AUTOHIDE_DISABLED
887
 
      && window->autohide_state != AUTOHIDE_BLOCKED)
888
 
    panel_window_autohide_queue (window, AUTOHIDE_POPDOWN);
 
919
      && window->autohide_state != AUTOHIDE_BLOCKED) {
 
920
    /* simulate a geometry change to check for overlapping windows with intelligent hiding */
 
921
    if (window->autohide_behavior == AUTOHIDE_BEHAVIOR_INTELLIGENTLY)
 
922
      panel_window_active_window_geometry_changed (window->wnck_active_window, window);
 
923
    /* otherwise just hide the panel */
 
924
    else
 
925
      panel_window_autohide_queue (window, AUTOHIDE_POPDOWN);
 
926
  }
889
927
 
890
928
  return (*GTK_WIDGET_CLASS (panel_window_parent_class)->leave_notify_event) (widget, event);
891
929
}
1415
1453
                             GdkScreen *previous_screen)
1416
1454
{
1417
1455
  PanelWindow *window = PANEL_WINDOW (widget);
 
1456
  WnckWindow  *wnck_window;
 
1457
  WnckScreen  *wnck_screen;
1418
1458
  GdkScreen   *screen;
1419
1459
 
1420
1460
  if (G_LIKELY (GTK_WIDGET_CLASS (panel_window_parent_class)->screen_changed != NULL))
1448
1488
 
1449
1489
  /* update the screen layout */
1450
1490
  panel_window_screen_layout_changed (screen, window);
 
1491
 
 
1492
  /* update wnck screen to be used for the autohide feature */
 
1493
  wnck_screen = wnck_screen_get (gdk_screen_get_number (screen));
 
1494
  wnck_window = wnck_screen_get_active_window (wnck_screen);
 
1495
  panel_window_update_autohide_window (window, wnck_screen, wnck_window);
1451
1496
}
1452
1497
 
1453
1498
 
2082
2127
 
2083
2128
 
2084
2129
 
 
2130
static void
 
2131
panel_window_active_window_changed (WnckScreen  *screen,
 
2132
                                    WnckWindow  *previous_window,
 
2133
                                    PanelWindow *window)
 
2134
{
 
2135
  WnckWindow *active_window;
 
2136
 
 
2137
  panel_return_if_fail (WNCK_IS_SCREEN (screen));
 
2138
  panel_return_if_fail (PANEL_IS_WINDOW (window));
 
2139
 
 
2140
  /* obtain new active window from the screen */
 
2141
  active_window = wnck_screen_get_active_window (screen);
 
2142
 
 
2143
  /* update the active window to be used for the autohide feature */
 
2144
  panel_window_update_autohide_window (window, screen, active_window);
 
2145
}
 
2146
 
 
2147
 
 
2148
 
 
2149
static void
 
2150
panel_window_active_window_geometry_changed (WnckWindow  *active_window,
 
2151
                                             PanelWindow *window)
 
2152
{
 
2153
  GdkRectangle panel_area;
 
2154
  GdkRectangle window_area;
 
2155
 
 
2156
  panel_return_if_fail (WNCK_IS_WINDOW (active_window));
 
2157
  panel_return_if_fail (PANEL_IS_WINDOW (window));
 
2158
 
 
2159
  /* ignore if for some reason the active window does not match the one we know */
 
2160
  if (G_UNLIKELY (window->wnck_active_window != active_window))
 
2161
    return;
 
2162
 
 
2163
  /* only react to active window geometry changes if we are doing
 
2164
   * intelligent autohiding */
 
2165
  if (window->autohide_behavior == AUTOHIDE_BEHAVIOR_INTELLIGENTLY
 
2166
      && window->autohide_block == 0)
 
2167
    {
 
2168
      if (wnck_window_get_window_type (active_window) != WNCK_WINDOW_DESKTOP)
 
2169
        {
 
2170
          /* obtain position and dimensions from the active window */
 
2171
          wnck_window_get_geometry (active_window,
 
2172
                                    &window_area.x, &window_area.y,
 
2173
                                    &window_area.width, &window_area.height);
 
2174
 
 
2175
          /* obtain position and dimension from the panel */
 
2176
          panel_window_size_allocate_set_xy (window,
 
2177
                                             window->alloc.width,
 
2178
                                             window->alloc.height,
 
2179
                                             &panel_area.x,
 
2180
                                             &panel_area.y);
 
2181
          gtk_window_get_size (GTK_WINDOW (window),
 
2182
                               &panel_area.width,
 
2183
                               &panel_area.height);
 
2184
 
 
2185
          /* show/hide the panel, depending on whether the active window overlaps
 
2186
           * with its coordinates */
 
2187
          if (window->autohide_state != AUTOHIDE_HIDDEN)
 
2188
            {
 
2189
              if (gdk_rectangle_intersect (&panel_area,  &window_area, NULL))
 
2190
                panel_window_autohide_queue (window, AUTOHIDE_HIDDEN);
 
2191
            }
 
2192
          else
 
2193
            {
 
2194
              if (!gdk_rectangle_intersect (&panel_area, &window_area, NULL))
 
2195
                panel_window_autohide_queue (window, AUTOHIDE_VISIBLE);
 
2196
            }
 
2197
        }
 
2198
      else
 
2199
        {
 
2200
          /* make the panel visible if it isn't at the moment and the active
 
2201
           * window is the desktop */
 
2202
          if (window->autohide_state != AUTOHIDE_VISIBLE)
 
2203
            panel_window_autohide_queue (window, AUTOHIDE_VISIBLE);
 
2204
        }
 
2205
    }
 
2206
}
 
2207
 
 
2208
 
 
2209
 
2085
2210
static gboolean
2086
2211
panel_window_autohide_timeout (gpointer user_data)
2087
2212
{
2217
2342
 
2218
2343
 
2219
2344
static void
2220
 
panel_window_set_autohide (PanelWindow *window,
2221
 
                           gboolean     autohide)
 
2345
panel_window_set_autohide_behavior (PanelWindow     *window,
 
2346
                                    AutohideBehavior behavior)
2222
2347
{
2223
2348
  GtkWidget   *popup;
2224
2349
  guint        i;
2229
2354
 
2230
2355
  panel_return_if_fail (PANEL_IS_WINDOW (window));
2231
2356
 
2232
 
  if ((window->autohide_state != AUTOHIDE_DISABLED) == autohide)
 
2357
  /* do nothing if the behavior hasn't changed at all */
 
2358
  if (window->autohide_behavior == behavior)
2233
2359
    return;
2234
2360
 
2235
 
  /* respond to drag motion */
2236
 
  gtk_drag_dest_set_track_motion (GTK_WIDGET (window), autohide);
 
2361
  /* remember the new behavior */
 
2362
  window->autohide_behavior = behavior;
2237
2363
 
2238
 
  if (autohide)
 
2364
  /* create an autohide window only if we are autohiding at all */
 
2365
  if (window->autohide_behavior != AUTOHIDE_BEHAVIOR_NEVER)
2239
2366
    {
2240
 
      /* create the window */
2241
 
      panel_return_if_fail (window->autohide_window == NULL);
2242
 
      popup = g_object_new (PANEL_TYPE_BASE_WINDOW,
2243
 
                            "type", GTK_WINDOW_TOPLEVEL,
2244
 
                            "decorated", FALSE,
2245
 
                            "resizable", TRUE,
2246
 
                            "type-hint", GDK_WINDOW_TYPE_HINT_DOCK,
2247
 
                            "gravity", GDK_GRAVITY_STATIC,
2248
 
                            "name", "XfcePanelWindowHidden",
2249
 
                            NULL);
2250
 
 
2251
 
      /* move the window offscreen */
2252
 
      panel_base_window_move_resize (PANEL_BASE_WINDOW (popup),
2253
 
                                     -9999, -9999, 3, 3);
2254
 
 
2255
 
      /* bind some properties to sync the two windows */
2256
 
      for (i = 0; i < G_N_ELEMENTS (properties); i++)
2257
 
        exo_binding_new (G_OBJECT (window), properties[i],
2258
 
                         G_OBJECT (popup), properties[i]);
2259
 
 
2260
 
      /* signals for pointer enter/leave events */
2261
 
      g_signal_connect (G_OBJECT (popup), "enter-notify-event",
2262
 
          G_CALLBACK (panel_window_autohide_event), window);
2263
 
      g_signal_connect (G_OBJECT (popup), "leave-notify-event",
2264
 
          G_CALLBACK (panel_window_autohide_event), window);
2265
 
 
2266
 
      /* show/hide the panel on drag events */
2267
 
      gtk_drag_dest_set (popup, 0, NULL, 0, 0);
2268
 
      gtk_drag_dest_set_track_motion (popup, TRUE);
2269
 
      g_signal_connect (G_OBJECT (popup), "drag-motion",
2270
 
          G_CALLBACK (panel_window_autohide_drag_motion), window);
2271
 
      g_signal_connect (G_OBJECT (popup), "drag-leave",
2272
 
          G_CALLBACK (panel_window_autohide_drag_leave), window);
2273
 
 
2274
 
      /* show the window */
2275
 
      window->autohide_window = popup;
2276
 
      gtk_widget_show (popup);
2277
 
 
2278
 
      /* start autohide */
2279
 
      panel_window_autohide_queue (window,
2280
 
          window->autohide_block == 0 ? AUTOHIDE_POPDOWN_SLOW : AUTOHIDE_BLOCKED);
 
2367
      /* create an autohide window; doing this only when it doesn't exist
 
2368
       * yet allows us to transition between "always autohide" and "intelligently
 
2369
       * autohide" without recreating the window */
 
2370
      if (window->autohide_window == NULL)
 
2371
        {
 
2372
          /* create the window */
 
2373
          panel_return_if_fail (window->autohide_window == NULL);
 
2374
          popup = g_object_new (PANEL_TYPE_BASE_WINDOW,
 
2375
                                "type", GTK_WINDOW_TOPLEVEL,
 
2376
                                "decorated", FALSE,
 
2377
                                "resizable", TRUE,
 
2378
                                "type-hint", GDK_WINDOW_TYPE_HINT_DOCK,
 
2379
                                "gravity", GDK_GRAVITY_STATIC,
 
2380
                                "name", "XfcePanelWindowHidden",
 
2381
                                NULL);
 
2382
 
 
2383
          /* move the window offscreen */
 
2384
          panel_base_window_move_resize (PANEL_BASE_WINDOW (popup),
 
2385
                                         -9999, -9999, 3, 3);
 
2386
 
 
2387
          /* bind some properties to sync the two windows */
 
2388
          for (i = 0; i < G_N_ELEMENTS (properties); i++)
 
2389
            {
 
2390
              exo_binding_new (G_OBJECT (window), properties[i],
 
2391
                               G_OBJECT (popup), properties[i]);
 
2392
            }
 
2393
 
 
2394
          /* respond to drag motion */
 
2395
          gtk_drag_dest_set_track_motion (GTK_WIDGET (window), TRUE);
 
2396
 
 
2397
          /* signals for pointer enter/leave events */
 
2398
          g_signal_connect (G_OBJECT (popup), "enter-notify-event",
 
2399
              G_CALLBACK (panel_window_autohide_event), window);
 
2400
          g_signal_connect (G_OBJECT (popup), "leave-notify-event",
 
2401
              G_CALLBACK (panel_window_autohide_event), window);
 
2402
 
 
2403
          /* show/hide the panel on drag events */
 
2404
          gtk_drag_dest_set (popup, 0, NULL, 0, 0);
 
2405
          gtk_drag_dest_set_track_motion (popup, TRUE);
 
2406
          g_signal_connect (G_OBJECT (popup), "drag-motion",
 
2407
              G_CALLBACK (panel_window_autohide_drag_motion), window);
 
2408
          g_signal_connect (G_OBJECT (popup), "drag-leave",
 
2409
              G_CALLBACK (panel_window_autohide_drag_leave), window);
 
2410
 
 
2411
          /* show the window */
 
2412
          window->autohide_window = popup;
 
2413
          gtk_widget_show (popup);
 
2414
        }
 
2415
 
 
2416
      if (window->autohide_behavior == AUTOHIDE_BEHAVIOR_ALWAYS)
 
2417
        {
 
2418
          /* start autohide by hiding the panel straight away */
 
2419
          if (window->autohide_state != AUTOHIDE_HIDDEN)
 
2420
            {
 
2421
              panel_window_autohide_queue (window,
 
2422
                  window->autohide_block == 0 ? AUTOHIDE_POPDOWN_SLOW : AUTOHIDE_BLOCKED);
 
2423
            }
 
2424
        }
 
2425
      else if (window->autohide_behavior == AUTOHIDE_BEHAVIOR_INTELLIGENTLY)
 
2426
        {
 
2427
          /* start intelligent autohide by making the panel visible initially */
 
2428
          if (window->autohide_state != AUTOHIDE_VISIBLE)
 
2429
            {
 
2430
              panel_window_autohide_queue (window,
 
2431
                  window->autohide_block == 0 ? AUTOHIDE_POPUP : AUTOHIDE_BLOCKED);
 
2432
            }
 
2433
        }
2281
2434
    }
2282
2435
  else if (window->autohide_window != NULL)
2283
2436
    {
2294
2447
 
2295
2448
 
2296
2449
static void
 
2450
panel_window_update_autohide_window (PanelWindow *window,
 
2451
                                     WnckScreen  *screen,
 
2452
                                     WnckWindow  *active_window)
 
2453
{
 
2454
  panel_return_if_fail (PANEL_IS_WINDOW (window));
 
2455
  panel_return_if_fail (screen == NULL || WNCK_IS_SCREEN (screen));
 
2456
  panel_return_if_fail (active_window == NULL || WNCK_IS_WINDOW (active_window));
 
2457
 
 
2458
  /* update current screen */
 
2459
  if (screen != window->wnck_screen)
 
2460
    {
 
2461
      /* disconnect from previous screen */
 
2462
      if (G_LIKELY (window->wnck_screen != NULL))
 
2463
        {
 
2464
          g_signal_handlers_disconnect_by_func (window->wnck_screen,
 
2465
              panel_window_active_window_changed, window);
 
2466
        }
 
2467
 
 
2468
      /* remember new screen */
 
2469
      window->wnck_screen = screen;
 
2470
 
 
2471
      /* connect to the new screen */
 
2472
      if (screen != NULL)
 
2473
        {
 
2474
          g_signal_connect (G_OBJECT (screen), "active-window-changed",
 
2475
              G_CALLBACK (panel_window_active_window_changed), window);
 
2476
        }
 
2477
    }
 
2478
 
 
2479
  /* update active window */
 
2480
  if (G_LIKELY (active_window != window->wnck_active_window))
 
2481
    {
 
2482
      /* disconnect from previously active window */
 
2483
      if (G_LIKELY (window->wnck_active_window != NULL))
 
2484
        {
 
2485
          g_signal_handlers_disconnect_by_func (window->wnck_active_window,
 
2486
              panel_window_active_window_geometry_changed, window);
 
2487
        }
 
2488
 
 
2489
      /* remember the new window */
 
2490
      window->wnck_active_window = active_window;
 
2491
 
 
2492
      /* connect to the new window but only if it is not a desktop/root-type window */
 
2493
      if (active_window != NULL)
 
2494
        {
 
2495
          g_signal_connect (G_OBJECT (active_window), "geometry-changed",
 
2496
              G_CALLBACK (panel_window_active_window_geometry_changed), window);
 
2497
 
 
2498
          /* simulate a geometry change for immediate hiding when the new active
 
2499
           * window already overlaps the panel */
 
2500
          panel_window_active_window_geometry_changed (active_window, window);
 
2501
        }
 
2502
    }
 
2503
}
 
2504
 
 
2505
 
 
2506
 
 
2507
static void
2297
2508
panel_window_menu_toggle_locked (GtkCheckMenuItem *item,
2298
2509
                                 PanelWindow      *window)
2299
2510
{
2701
2912
  window->autohide_block--;
2702
2913
 
2703
2914
  if (window->autohide_block == 0
2704
 
      && window->autohide_state != AUTOHIDE_DISABLED)
2705
 
    panel_window_autohide_queue (window, AUTOHIDE_POPDOWN);
 
2915
      && window->autohide_state != AUTOHIDE_DISABLED) {
 
2916
    /* simulate a geometry change to check for overlapping windows with intelligent hiding */
 
2917
    if (window->autohide_behavior == AUTOHIDE_BEHAVIOR_INTELLIGENTLY)
 
2918
      panel_window_active_window_geometry_changed (window->wnck_active_window, window);
 
2919
    /* otherwise just hide the panel */
 
2920
    else
 
2921
      panel_window_autohide_queue (window, AUTOHIDE_POPDOWN);
 
2922
  }
2706
2923
}
2707
2924
 
2708
2925
 
2760
2977
  gtk_window_present (GTK_WINDOW (window));
2761
2978
#endif
2762
2979
}
 
2980
 
 
2981
 
 
2982
 
 
2983
void
 
2984
panel_window_migrate_autohide_property (PanelWindow   *window,
 
2985
                                        XfconfChannel *xfconf,
 
2986
                                        const gchar   *property_base)
 
2987
{
 
2988
  gboolean autohide;
 
2989
  gchar   *new_property;
 
2990
  gchar   *old_property;
 
2991
 
 
2992
  panel_return_if_fail (PANEL_IS_WINDOW (window));
 
2993
  panel_return_if_fail (XFCONF_IS_CHANNEL (xfconf));
 
2994
  panel_return_if_fail (property_base != NULL && *property_base != '\0');
 
2995
 
 
2996
  old_property = g_strdup_printf ("%s/autohide", property_base);
 
2997
 
 
2998
  /* check if we have an old "autohide" property for this panel */
 
2999
  if (xfconf_channel_has_property (xfconf, old_property))
 
3000
    {
 
3001
      new_property = g_strdup_printf ("%s/autohide-behavior", property_base);
 
3002
 
 
3003
      /* migrate from old "autohide" to new "autohide-behavior" if the latter
 
3004
       * isn't set already */
 
3005
      if (!xfconf_channel_has_property (xfconf, new_property))
 
3006
        {
 
3007
          /* find out whether or not autohide was enabled in the old config */
 
3008
          autohide = xfconf_channel_get_bool (xfconf, old_property, FALSE);
 
3009
 
 
3010
          /* set autohide behavior to always or never, depending on whether it
 
3011
           * was enabled in the old configuration */
 
3012
          if (xfconf_channel_set_uint (xfconf,
 
3013
                                       new_property,
 
3014
                                       autohide ? AUTOHIDE_BEHAVIOR_ALWAYS
 
3015
                                                : AUTOHIDE_BEHAVIOR_NEVER))
 
3016
            {
 
3017
              /* remove the old autohide property */
 
3018
              xfconf_channel_reset_property (xfconf, old_property, FALSE);
 
3019
            }
 
3020
        }
 
3021
      else
 
3022
        {
 
3023
          /* the new property is already set, simply remove the old property */
 
3024
          xfconf_channel_reset_property (xfconf, old_property, FALSE);
 
3025
        }
 
3026
    }
 
3027
}