68
typedef enum _StrutsEgde StrutsEgde;
69
typedef enum _AutohideState AutohideState;
70
typedef enum _SnapPosition SnapPosition;
71
typedef enum _PluginProp PluginProp;
75
static void panel_window_get_property (GObject *object,
79
static void panel_window_set_property (GObject *object,
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,
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,
97
static void panel_window_drag_leave (GtkWidget *widget,
98
GdkDragContext *context,
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,
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,
133
static void panel_window_menu_popup (PanelWindow *window,
135
static void panel_window_plugins_update (PanelWindow *window,
137
static void panel_window_plugin_set_mode (GtkWidget *widget,
139
static void panel_window_plugin_set_size (GtkWidget *widget,
141
static void panel_window_plugin_set_nrows (GtkWidget *widget,
143
static void panel_window_plugin_set_screen_position (GtkWidget *widget,
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;
80
static void panel_window_get_property (GObject *object,
84
static void panel_window_set_property (GObject *object,
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,
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,
102
static void panel_window_drag_leave (GtkWidget *widget,
103
GdkDragContext *context,
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,
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,
145
WnckWindow *active_window);
146
static void panel_window_menu_popup (PanelWindow *window,
148
static void panel_window_plugins_update (PanelWindow *window,
150
static void panel_window_plugin_set_mode (GtkWidget *widget,
152
static void panel_window_plugin_set_size (GtkWidget *widget,
154
static void panel_window_plugin_set_nrows (GtkWidget *widget,
156
static void panel_window_plugin_set_screen_position (GtkWidget *widget,
2131
panel_window_active_window_changed (WnckScreen *screen,
2132
WnckWindow *previous_window,
2133
PanelWindow *window)
2135
WnckWindow *active_window;
2137
panel_return_if_fail (WNCK_IS_SCREEN (screen));
2138
panel_return_if_fail (PANEL_IS_WINDOW (window));
2140
/* obtain new active window from the screen */
2141
active_window = wnck_screen_get_active_window (screen);
2143
/* update the active window to be used for the autohide feature */
2144
panel_window_update_autohide_window (window, screen, active_window);
2150
panel_window_active_window_geometry_changed (WnckWindow *active_window,
2151
PanelWindow *window)
2153
GdkRectangle panel_area;
2154
GdkRectangle window_area;
2156
panel_return_if_fail (WNCK_IS_WINDOW (active_window));
2157
panel_return_if_fail (PANEL_IS_WINDOW (window));
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))
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)
2168
if (wnck_window_get_window_type (active_window) != WNCK_WINDOW_DESKTOP)
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);
2175
/* obtain position and dimension from the panel */
2176
panel_window_size_allocate_set_xy (window,
2177
window->alloc.width,
2178
window->alloc.height,
2181
gtk_window_get_size (GTK_WINDOW (window),
2183
&panel_area.height);
2185
/* show/hide the panel, depending on whether the active window overlaps
2186
* with its coordinates */
2187
if (window->autohide_state != AUTOHIDE_HIDDEN)
2189
if (gdk_rectangle_intersect (&panel_area, &window_area, NULL))
2190
panel_window_autohide_queue (window, AUTOHIDE_HIDDEN);
2194
if (!gdk_rectangle_intersect (&panel_area, &window_area, NULL))
2195
panel_window_autohide_queue (window, AUTOHIDE_VISIBLE);
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);
2085
2210
static gboolean
2086
2211
panel_window_autohide_timeout (gpointer user_data)
2230
2355
panel_return_if_fail (PANEL_IS_WINDOW (window));
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)
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;
2364
/* create an autohide window only if we are autohiding at all */
2365
if (window->autohide_behavior != AUTOHIDE_BEHAVIOR_NEVER)
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,
2246
"type-hint", GDK_WINDOW_TYPE_HINT_DOCK,
2247
"gravity", GDK_GRAVITY_STATIC,
2248
"name", "XfcePanelWindowHidden",
2251
/* move the window offscreen */
2252
panel_base_window_move_resize (PANEL_BASE_WINDOW (popup),
2253
-9999, -9999, 3, 3);
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]);
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);
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);
2274
/* show the window */
2275
window->autohide_window = popup;
2276
gtk_widget_show (popup);
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)
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,
2378
"type-hint", GDK_WINDOW_TYPE_HINT_DOCK,
2379
"gravity", GDK_GRAVITY_STATIC,
2380
"name", "XfcePanelWindowHidden",
2383
/* move the window offscreen */
2384
panel_base_window_move_resize (PANEL_BASE_WINDOW (popup),
2385
-9999, -9999, 3, 3);
2387
/* bind some properties to sync the two windows */
2388
for (i = 0; i < G_N_ELEMENTS (properties); i++)
2390
exo_binding_new (G_OBJECT (window), properties[i],
2391
G_OBJECT (popup), properties[i]);
2394
/* respond to drag motion */
2395
gtk_drag_dest_set_track_motion (GTK_WIDGET (window), TRUE);
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);
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);
2411
/* show the window */
2412
window->autohide_window = popup;
2413
gtk_widget_show (popup);
2416
if (window->autohide_behavior == AUTOHIDE_BEHAVIOR_ALWAYS)
2418
/* start autohide by hiding the panel straight away */
2419
if (window->autohide_state != AUTOHIDE_HIDDEN)
2421
panel_window_autohide_queue (window,
2422
window->autohide_block == 0 ? AUTOHIDE_POPDOWN_SLOW : AUTOHIDE_BLOCKED);
2425
else if (window->autohide_behavior == AUTOHIDE_BEHAVIOR_INTELLIGENTLY)
2427
/* start intelligent autohide by making the panel visible initially */
2428
if (window->autohide_state != AUTOHIDE_VISIBLE)
2430
panel_window_autohide_queue (window,
2431
window->autohide_block == 0 ? AUTOHIDE_POPUP : AUTOHIDE_BLOCKED);
2282
2435
else if (window->autohide_window != NULL)
2450
panel_window_update_autohide_window (PanelWindow *window,
2452
WnckWindow *active_window)
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));
2458
/* update current screen */
2459
if (screen != window->wnck_screen)
2461
/* disconnect from previous screen */
2462
if (G_LIKELY (window->wnck_screen != NULL))
2464
g_signal_handlers_disconnect_by_func (window->wnck_screen,
2465
panel_window_active_window_changed, window);
2468
/* remember new screen */
2469
window->wnck_screen = screen;
2471
/* connect to the new screen */
2474
g_signal_connect (G_OBJECT (screen), "active-window-changed",
2475
G_CALLBACK (panel_window_active_window_changed), window);
2479
/* update active window */
2480
if (G_LIKELY (active_window != window->wnck_active_window))
2482
/* disconnect from previously active window */
2483
if (G_LIKELY (window->wnck_active_window != NULL))
2485
g_signal_handlers_disconnect_by_func (window->wnck_active_window,
2486
panel_window_active_window_geometry_changed, window);
2489
/* remember the new window */
2490
window->wnck_active_window = active_window;
2492
/* connect to the new window but only if it is not a desktop/root-type window */
2493
if (active_window != NULL)
2495
g_signal_connect (G_OBJECT (active_window), "geometry-changed",
2496
G_CALLBACK (panel_window_active_window_geometry_changed), window);
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);
2297
2508
panel_window_menu_toggle_locked (GtkCheckMenuItem *item,
2298
2509
PanelWindow *window)
2760
2977
gtk_window_present (GTK_WINDOW (window));
2984
panel_window_migrate_autohide_property (PanelWindow *window,
2985
XfconfChannel *xfconf,
2986
const gchar *property_base)
2989
gchar *new_property;
2990
gchar *old_property;
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');
2996
old_property = g_strdup_printf ("%s/autohide", property_base);
2998
/* check if we have an old "autohide" property for this panel */
2999
if (xfconf_channel_has_property (xfconf, old_property))
3001
new_property = g_strdup_printf ("%s/autohide-behavior", property_base);
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))
3007
/* find out whether or not autohide was enabled in the old config */
3008
autohide = xfconf_channel_get_bool (xfconf, old_property, FALSE);
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,
3014
autohide ? AUTOHIDE_BEHAVIOR_ALWAYS
3015
: AUTOHIDE_BEHAVIOR_NEVER))
3017
/* remove the old autohide property */
3018
xfconf_channel_reset_property (xfconf, old_property, FALSE);
3023
/* the new property is already set, simply remove the old property */
3024
xfconf_channel_reset_property (xfconf, old_property, FALSE);