update for beta release
[framework/uifw/e17.git] / src / bin / e_shelf.c
1 #include "e.h"
2
3 static void _e_shelf_free(E_Shelf *es);
4 static void _e_shelf_gadcon_min_size_request(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h);
5 static void _e_shelf_gadcon_size_request(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h);
6 static Evas_Object *_e_shelf_gadcon_frame_request(void *data, E_Gadcon_Client *gcc, const char *style);
7 static void _e_shelf_toggle_border_fix(E_Shelf *es);
8 static void _e_shelf_cb_menu_config(void *data, E_Menu *m, E_Menu_Item *mi);
9 static void _e_shelf_cb_menu_edit(void *data, E_Menu *m, E_Menu_Item *mi);
10 static void _e_shelf_cb_menu_contents(void *data, E_Menu *m, E_Menu_Item *mi);
11 static void _e_shelf_cb_confirm_dialog_yes(void *data);
12 static void _e_shelf_cb_menu_delete(void *data, E_Menu *m, E_Menu_Item *mi);
13 static void _e_shelf_menu_append(E_Shelf *es, E_Menu *mn);
14 static void _e_shelf_cb_menu_items_append(void *data, E_Gadcon_Client *gcc, E_Menu *mn);
15 static void _e_shelf_cb_locked_set(void *data, int lock);
16 static void _e_shelf_cb_urgent_show(void *data);
17 static void _e_shelf_cb_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info);
18 static Eina_Bool _e_shelf_cb_mouse_in(void *data, int type, void *event);
19 static Eina_Bool _e_shelf_cb_mouse_out(void *data, int type, void *event);
20 static int _e_shelf_cb_id_sort(const void *data1, const void *data2);
21 static Eina_Bool _e_shelf_cb_hide_animator(void *data);
22 static Eina_Bool _e_shelf_cb_hide_animator_timer(void *data);
23 static Eina_Bool _e_shelf_cb_hide_urgent_timer(void *data);
24 static Eina_Bool _e_shelf_cb_instant_hide_timer(void *data);
25 static void _e_shelf_menu_pre_cb(void *data, E_Menu *m);
26 static void _e_shelf_gadcon_client_remove(void *data, E_Gadcon_Client *gcc);
27 static int _e_shelf_gadcon_client_add(void *data, const E_Gadcon_Client_Class *cc);
28 static const char * _e_shelf_orient_icon_name_get(E_Shelf *s);
29 static void _e_shelf_bindings_add(E_Shelf *es);
30 static void _e_shelf_bindings_del(E_Shelf *es);
31 static Eina_Bool _e_shelf_on_current_desk(E_Shelf *es, E_Event_Zone_Edge *ev);
32
33 static Eina_List *shelves = NULL;
34 static Eina_Hash *winid_shelves = NULL;
35
36 /* externally accessible functions */
37 EINTERN int
38 e_shelf_init(void)
39 {
40    return 1;
41 }
42
43 EINTERN int
44 e_shelf_shutdown(void)
45 {
46    if (x_fatal) return 1;
47    while (shelves)
48      {
49         E_Shelf *es;
50
51         es = eina_list_data_get(shelves);
52         e_object_del(E_OBJECT(es));
53      }
54
55    return 1;
56 }
57
58 EAPI void
59 e_shelf_config_update(void)
60 {
61    Eina_List *l;
62    E_Config_Shelf *cf_es;
63    int id = 0;
64
65    while (shelves)
66      {
67         E_Shelf *es;
68
69         es = eina_list_data_get(shelves);
70         e_object_del(E_OBJECT(es));
71      }
72
73    EINA_LIST_FOREACH(e_config->shelves, l, cf_es)
74      {
75         E_Zone *zone;
76
77         if (cf_es->id <= 0) cf_es->id = id + 1;
78         zone = e_util_container_zone_id_get(cf_es->container, cf_es->zone);
79         if (zone)
80           e_shelf_config_new(zone, cf_es);
81         id = cf_es->id;
82      }
83 }
84
85 EAPI Eina_List *
86 e_shelf_list(void)
87 {
88    shelves = eina_list_sort(shelves, -1, _e_shelf_cb_id_sort);
89    return shelves;
90 }
91
92 EAPI E_Shelf *
93 e_shelf_zone_new(E_Zone *zone, const char *name, const char *style, int popup, int layer, int id)
94 {
95    E_Shelf *es;
96    const char *option;
97    char buf[1024];
98    const char *locname;
99
100    es = E_OBJECT_ALLOC(E_Shelf, E_SHELF_TYPE, _e_shelf_free);
101    if (!es) return NULL;
102    es->id = id;
103    es->x = 0;
104    es->y = 0;
105    es->w = 32;
106    es->h = 32;
107    es->zone = zone;
108    e_zone_useful_geometry_dirty(zone);
109    if (popup)
110      {
111         es->popup = e_popup_new(zone, es->x, es->y, es->w, es->h);
112         e_popup_name_set(es->popup, "shelf");
113         e_popup_layer_set(es->popup, layer);
114         es->ee = es->popup->ecore_evas;
115         es->evas = es->popup->evas;
116      }
117    else
118      {
119         es->ee = zone->container->bg_ecore_evas;
120         es->evas = zone->container->bg_evas;
121      }
122    es->fit_along = 1;
123    es->layer = layer;
124    es->style = eina_stringshare_add(style);
125
126    es->o_event = evas_object_rectangle_add(es->evas);
127    evas_object_color_set(es->o_event, 0, 0, 0, 0);
128    evas_object_resize(es->o_event, es->w, es->h);
129    evas_object_event_callback_add(es->o_event, EVAS_CALLBACK_MOUSE_DOWN, _e_shelf_cb_mouse_down, es);
130
131    /* TODO: We should have a mouse out on the evas object if we are on the desktop */
132    es->handlers = eina_list_append(es->handlers,
133          ecore_event_handler_add(E_EVENT_ZONE_EDGE_MOVE, _e_shelf_cb_mouse_in, es));
134    es->handlers = eina_list_append(es->handlers,
135          ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_shelf_cb_mouse_in, es));
136    es->handlers = eina_list_append(es->handlers,
137          ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_shelf_cb_mouse_in, es));
138    es->handlers = eina_list_append(es->handlers,
139          ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_shelf_cb_mouse_out, es));
140
141    es->o_base = edje_object_add(es->evas);
142    es->name = eina_stringshare_add(name);
143    snprintf(buf, sizeof(buf), "e/shelf/%s/base", es->style);
144    evas_object_resize(es->o_base, es->w, es->h);
145    if (!e_theme_edje_object_set(es->o_base, "base/theme/shelf", buf))
146      e_theme_edje_object_set(es->o_base, "base/theme/shelf",
147                              "e/shelf/default/base");
148    if (es->popup)
149      {
150         evas_object_show(es->o_event);
151         evas_object_show(es->o_base);
152         e_popup_edje_bg_object_set(es->popup, es->o_base);
153         ecore_x_netwm_window_type_set(es->popup->evas_win, ECORE_X_WINDOW_TYPE_DOCK);
154      }
155    else
156      {
157         evas_object_move(es->o_event, es->zone->x + es->x, es->zone->y + es->y);
158         evas_object_move(es->o_base, es->zone->x + es->x, es->zone->y + es->y);
159         evas_object_layer_set(es->o_event, layer);
160         evas_object_layer_set(es->o_base, layer);
161      }
162
163    es->gadcon = e_gadcon_swallowed_new(es->name, es->id, es->o_base, "e.swallow.content");
164    locname = es->name;
165    if (!name) locname = _("Shelf #");
166    snprintf(buf, sizeof(buf), "%s %i", locname, es->id);
167    es->gadcon->location = e_gadcon_location_new(buf, E_GADCON_SITE_SHELF, _e_shelf_gadcon_client_add, es, _e_shelf_gadcon_client_remove, es);
168    e_gadcon_location_register(es->gadcon->location);
169 // hmm dnd in ibar and ibox kill this. ok. need to look into this more   
170 //   es->gadcon->instant_edit = 1;
171    e_gadcon_min_size_request_callback_set(es->gadcon,
172                                           _e_shelf_gadcon_min_size_request, es);
173
174    e_gadcon_size_request_callback_set(es->gadcon,
175                                       _e_shelf_gadcon_size_request, es);
176    e_gadcon_frame_request_callback_set(es->gadcon,
177                                        _e_shelf_gadcon_frame_request, es);
178    e_gadcon_orient(es->gadcon, E_GADCON_ORIENT_TOP);
179    snprintf(buf, sizeof(buf), "e,state,orientation,%s", 
180             e_shelf_orient_string_get(es));
181    edje_object_signal_emit(es->o_base, buf, "e");
182    edje_object_message_signal_process(es->o_base);
183    e_gadcon_zone_set(es->gadcon, zone);
184    e_gadcon_ecore_evas_set(es->gadcon, es->ee);
185    e_gadcon_shelf_set(es->gadcon, es);
186    if (popup)
187      {
188         if (!winid_shelves) 
189           winid_shelves = eina_hash_string_superfast_new(NULL);
190         eina_hash_add(winid_shelves, 
191                       e_util_winid_str_get(es->popup->evas_win), es);
192         e_drop_xdnd_register_set(es->popup->evas_win, 1);
193         e_gadcon_xdnd_window_set(es->gadcon, es->popup->evas_win);
194         e_gadcon_dnd_window_set(es->gadcon, es->popup->evas_win);
195      }
196    else
197      {
198         e_drop_xdnd_register_set(es->zone->container->bg_win, 1);
199         e_gadcon_xdnd_window_set(es->gadcon, es->zone->container->bg_win);
200         e_gadcon_dnd_window_set(es->gadcon, es->zone->container->event_win);
201      }
202    e_gadcon_util_menu_attach_func_set(es->gadcon,
203                                       _e_shelf_cb_menu_items_append, es);
204
205    e_gadcon_util_lock_func_set(es->gadcon,
206                                _e_shelf_cb_locked_set, es);
207    e_gadcon_util_urgent_show_func_set(es->gadcon,
208                                       _e_shelf_cb_urgent_show, es);
209
210    shelves = eina_list_append(shelves, es);
211
212    es->hidden = 0;
213    es->hide_step = 0;
214    es->locked = 0;
215
216    option = edje_object_data_get(es->o_base, "hidden_state_size");
217    if (option)
218      es->hidden_state_size = atoi(option);
219    else
220      es->hidden_state_size = 4;
221    option = edje_object_data_get(es->o_base, "instant_delay");
222    if (option)
223      es->instant_delay = atof(option);
224    else
225      es->instant_delay = -1.0;
226
227    es->hide_origin = -1;
228
229    return es;
230 }
231
232 EAPI void
233 e_shelf_zone_move_resize_handle(E_Zone *zone)
234 {
235    Eina_List *l;
236    E_Shelf *es;
237    Evas_Coord w, h;
238
239    EINA_LIST_FOREACH(shelves, l, es)
240      {
241         if (es->zone == zone) 
242           {
243              E_Gadcon * gc;
244
245              gc = es->gadcon;
246              if (gc->min_size_request.func)
247                {
248                   /* let gadcon container decrease to any size */
249                   edje_extern_object_min_size_set(gc->o_container, 0, 0);
250                }
251              evas_object_smart_callback_call (gc->o_container, "min_size_request", NULL);
252              e_shelf_position_calc(es);
253              if (gc->min_size_request.func)
254                {
255                   evas_object_geometry_get(gc->o_container, NULL, NULL, &w, &h);
256                   /* fix gadcon container min size to current geometry */
257                   edje_extern_object_min_size_set(gc->o_container, w, h);
258                }
259           }
260      }
261 }
262
263 EAPI void
264 e_shelf_populate(E_Shelf *es)
265 {
266    E_OBJECT_CHECK(es);
267    E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
268    e_gadcon_populate(es->gadcon);
269 }
270
271 EAPI void
272 e_shelf_show(E_Shelf *es)
273 {
274    E_OBJECT_CHECK(es);
275    E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
276    if (es->popup)
277      e_popup_show(es->popup);
278    else
279      {
280         evas_object_show(es->o_event);
281         evas_object_show(es->o_base);
282      }
283 }
284
285 EAPI void
286 e_shelf_hide(E_Shelf *es)
287 {
288    E_OBJECT_CHECK(es);
289    E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
290    if (es->popup)
291      e_popup_hide(es->popup);
292    else
293      {
294         evas_object_hide(es->o_event);
295         evas_object_hide(es->o_base);
296      }
297 }
298
299 EAPI void
300 e_shelf_locked_set(E_Shelf *es, int lock)
301 {
302    if (lock)
303      {
304         e_shelf_toggle(es, 1);
305         es->locked++;
306      }
307    else
308      {
309        if (es->locked > 0)
310          es->locked--;
311        if (!es->locked)
312          e_shelf_toggle(es, es->toggle);
313      }
314 }
315
316 EAPI void
317 e_shelf_toggle(E_Shelf *es, int show)
318 {
319    E_OBJECT_CHECK(es);
320    E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
321
322    es->toggle = show;
323    if (es->locked) return;
324    es->interrupted = -1;
325    es->urgent_show = 0;
326    if ((show) && (es->hidden))
327      {
328         es->hidden = 0;
329         edje_object_signal_emit(es->o_base, "e,state,visible", "e");
330         if (es->instant_delay >= 0.0)
331           {
332              _e_shelf_cb_instant_hide_timer(es);
333              es->hide_timer = 
334                ecore_timer_add(es->cfg->hide_timeout, 
335                                _e_shelf_cb_hide_urgent_timer, es);
336           }
337         else
338           {
339              if (es->hide_timer)
340                {
341                   ecore_timer_del(es->hide_timer);
342                   es->hide_timer = NULL;
343                }
344              if (!es->hide_animator)
345                es->hide_animator = 
346                ecore_animator_add(_e_shelf_cb_hide_animator, es);
347           }
348      }
349    else if ((!show) && (!es->hidden) && (!es->gadcon->editing) && 
350             (es->cfg->autohide))
351      {
352         edje_object_signal_emit(es->o_base, "e,state,hidden", "e");
353         if (es->instant_delay >= 0.0)
354           {
355              if (es->hide_timer)
356                {
357                   ecore_timer_del(es->hide_timer);
358                   es->hide_timer = NULL;
359                }
360              es->hidden = 1; 
361              if (!es->instant_timer)
362                es->instant_timer = 
363                ecore_timer_add(es->instant_delay, 
364                                _e_shelf_cb_instant_hide_timer, es);
365           }
366         else
367           {
368              if (es->hide_animator)
369                {
370                   es->interrupted = show;
371                   return;
372                }
373              es->hidden = 1; 
374              if (es->hide_timer) ecore_timer_del(es->hide_timer);
375              es->hide_timer = 
376                ecore_timer_add(es->cfg->hide_timeout, 
377                                _e_shelf_cb_hide_animator_timer, es);
378           }
379      }
380 }
381
382 EAPI void
383 e_shelf_urgent_show(E_Shelf *es)
384 {
385    e_shelf_toggle(es, 1);
386    es->urgent_show = 1;
387 }
388
389 EAPI void
390 e_shelf_move(E_Shelf *es, int x, int y)
391 {
392    E_OBJECT_CHECK(es);
393    E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
394    es->x = x;
395    es->y = y;
396    if (es->popup)
397      e_popup_move(es->popup, es->x, es->y);
398    else
399      {
400         evas_object_move(es->o_event, es->zone->x + es->x, es->zone->y + es->y);
401         evas_object_move(es->o_base, es->zone->x + es->x, es->zone->y + es->y);
402      }
403 }
404
405 EAPI void
406 e_shelf_resize(E_Shelf *es, int w, int h)
407 {
408    E_OBJECT_CHECK(es);
409    E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
410    es->w = w;
411    es->h = h;
412    if (es->popup) e_popup_resize(es->popup, es->w, es->h);
413    evas_object_resize(es->o_event, es->w, es->h);
414    evas_object_resize(es->o_base, es->w, es->h);
415 }
416
417 EAPI void
418 e_shelf_move_resize(E_Shelf *es, int x, int y, int w, int h)
419 {
420    E_OBJECT_CHECK(es);
421    E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
422    es->x = x;
423    es->y = y;
424    es->w = w;
425    es->h = h;
426    if (es->popup) 
427      e_popup_move_resize(es->popup, es->x, es->y, es->w, es->h); 
428    else
429      {
430         evas_object_move(es->o_event, es->zone->x + es->x, es->zone->y + es->y);
431         evas_object_move(es->o_base, es->zone->x + es->x, es->zone->y + es->y);
432      }
433    evas_object_resize(es->o_event, es->w, es->h);
434    evas_object_resize(es->o_base, es->w, es->h);
435 }
436
437 EAPI void
438 e_shelf_layer_set(E_Shelf *es, int layer)
439 {
440    E_OBJECT_CHECK(es);
441    E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
442
443    es->layer = layer;
444    if (es->popup)
445      e_popup_layer_set(es->popup, es->layer);
446    else
447      {
448         evas_object_layer_set(es->o_event, es->layer);
449         evas_object_layer_set(es->o_base, es->layer);
450      }
451 }
452
453 EAPI void
454 e_shelf_save(E_Shelf *es)
455 {
456    E_OBJECT_CHECK(es);
457    E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
458    if (es->cfg)
459      {
460         es->cfg->orient = es->gadcon->orient;
461         if (es->cfg->style) eina_stringshare_del(es->cfg->style);
462         es->cfg->style = eina_stringshare_add(es->style);
463      }
464    else
465      {
466         E_Config_Shelf *cf_es;
467
468         cf_es = E_NEW(E_Config_Shelf, 1);
469         cf_es->name = eina_stringshare_add(es->name);
470         cf_es->container = es->zone->container->num;
471         cf_es->zone = es->zone->num;
472         if (es->popup) cf_es->popup = 1;
473         cf_es->layer = es->layer;
474         e_config->shelves = eina_list_append(e_config->shelves, cf_es);
475         cf_es->orient = es->gadcon->orient;
476         cf_es->style = eina_stringshare_add(es->style);
477         cf_es->fit_along = es->fit_along;
478         cf_es->fit_size = es->fit_size;
479         cf_es->overlap = 0;
480         cf_es->autohide = 0; 
481         cf_es->hide_timeout = 1.0; 
482         cf_es->hide_duration = 1.0;
483         es->cfg = cf_es;
484      }
485    e_config_save_queue();
486 }
487
488 EAPI void
489 e_shelf_unsave(E_Shelf *es)
490 {
491    E_OBJECT_CHECK(es);
492    E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
493    if (es->cfg)
494      {
495         e_config->shelves = eina_list_remove(e_config->shelves, es->cfg);
496         eina_stringshare_del(es->cfg->name);
497         if (es->cfg->style) eina_stringshare_del(es->cfg->style);
498         free(es->cfg);
499      }
500 }
501
502 EAPI void
503 e_shelf_orient(E_Shelf *es, E_Gadcon_Orient orient)
504 {
505    char buf[PATH_MAX];
506
507    E_OBJECT_CHECK(es);
508    E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
509
510    e_gadcon_orient(es->gadcon, orient);
511    snprintf(buf, sizeof(buf), "e,state,orientation,%s", 
512             e_shelf_orient_string_get(es));
513    edje_object_signal_emit(es->o_base, buf, "e");
514    edje_object_message_signal_process(es->o_base);
515    e_gadcon_location_set_icon_name(es->gadcon->location, _e_shelf_orient_icon_name_get(es));
516    e_zone_useful_geometry_dirty(es->zone);
517 }
518
519 EAPI const char *
520 e_shelf_orient_string_get(E_Shelf *es)
521 {
522    const char *sig = "";
523
524    switch (es->gadcon->orient)
525      {
526       case E_GADCON_ORIENT_FLOAT:
527         sig = "float";
528         break;
529       case E_GADCON_ORIENT_HORIZ:
530         sig = "horizontal";
531         break;
532       case E_GADCON_ORIENT_VERT:
533         sig = "vertical";
534         break;
535       case E_GADCON_ORIENT_LEFT:
536         sig = "left";
537         break;
538       case E_GADCON_ORIENT_RIGHT:
539         sig = "right";
540         break;
541       case E_GADCON_ORIENT_TOP:
542         sig = "top";
543         break;
544       case E_GADCON_ORIENT_BOTTOM:
545         sig = "bottom";
546         break;
547       case E_GADCON_ORIENT_CORNER_TL:
548         sig = "top_left";
549         break;
550       case E_GADCON_ORIENT_CORNER_TR:
551         sig = "top_right";
552         break;
553       case E_GADCON_ORIENT_CORNER_BL:
554         sig = "bottom_left";
555         break;
556       case E_GADCON_ORIENT_CORNER_BR:
557         sig = "bottom_right";
558         break;
559       case E_GADCON_ORIENT_CORNER_LT:
560         sig = "left_top";
561         break;
562       case E_GADCON_ORIENT_CORNER_RT:
563         sig = "right_top";
564         break;
565       case E_GADCON_ORIENT_CORNER_LB:
566         sig = "left_bottom";
567         break;
568       case E_GADCON_ORIENT_CORNER_RB:
569         sig = "right_bottom";
570         break;
571       default:
572         break;
573      }
574    return sig;
575 }
576
577 EAPI void
578 e_shelf_position_calc(E_Shelf *es)
579 {
580    E_Gadcon_Orient orient = E_GADCON_ORIENT_FLOAT;
581    int size = 40;
582
583    if (es->cfg)
584      {
585         orient = es->cfg->orient;
586         size = es->cfg->size * e_scale;
587      }
588    else
589      orient = es->gadcon->orient;
590    switch (orient)
591      {
592       case E_GADCON_ORIENT_FLOAT:
593         if (!es->fit_along) es->w = es->zone->w;
594         if (!es->fit_size) es->h = size;
595         break;
596       case E_GADCON_ORIENT_HORIZ:
597         if (!es->fit_along) es->w = es->zone->w;
598         if (!es->fit_size) es->h = size;
599         es->x = (es->zone->w - es->w) / 2;
600         break;
601       case E_GADCON_ORIENT_VERT:
602         if (!es->fit_along) es->h = es->zone->h;
603         if (!es->fit_size) es->w = size;
604         es->y = (es->zone->h - es->h) / 2;
605         break;
606       case E_GADCON_ORIENT_LEFT:
607         if (!es->fit_along) es->h = es->zone->h;
608         if (!es->fit_size) es->w = size;
609         es->x = 0;
610         es->y = (es->zone->h - es->h) / 2;
611         break;
612       case E_GADCON_ORIENT_RIGHT:
613         if (!es->fit_along) es->h = es->zone->h;
614         if (!es->fit_size) es->w = size;
615         es->x = es->zone->w - es->w;
616         es->y = (es->zone->h - es->h) / 2;
617         break;
618       case E_GADCON_ORIENT_TOP:
619         if (!es->fit_along) es->w = es->zone->w;
620         if (!es->fit_size) es->h = size;
621         es->x = (es->zone->w - es->w) / 2;
622         es->y = 0;
623         break;
624       case E_GADCON_ORIENT_BOTTOM:
625         if (!es->fit_along) es->w = es->zone->w;
626         if (!es->fit_size) es->h = size;
627         es->x = (es->zone->w - es->w) / 2;
628         es->y = es->zone->h - es->h;
629         break;
630       case E_GADCON_ORIENT_CORNER_TL:
631         if (!es->fit_along) es->w = es->zone->w;
632         if (!es->fit_size) es->h = size;
633         es->x = 0;
634         es->y = 0;
635         break;
636       case E_GADCON_ORIENT_CORNER_TR:
637         if (!es->fit_along) es->w = es->zone->w;
638         if (!es->fit_size) es->h = size;
639         es->x = es->zone->w - es->w;
640         es->y = 0;
641         break;
642       case E_GADCON_ORIENT_CORNER_BL:
643         if (!es->fit_along) es->w = es->zone->w;
644         if (!es->fit_size) es->h = size;
645         es->x = 0;
646         es->y = es->zone->h - es->h;
647         break;
648       case E_GADCON_ORIENT_CORNER_BR:
649         if (!es->fit_along) es->w = es->zone->w;
650         if (!es->fit_size) es->h = size;
651         es->x = es->zone->w - es->w;
652         es->y = es->zone->h - es->h;
653         break;
654       case E_GADCON_ORIENT_CORNER_LT:
655         if (!es->fit_along) es->h = es->zone->h;
656         if (!es->fit_size) es->w = size;
657         es->x = 0;
658         es->y = 0;
659         break;
660       case E_GADCON_ORIENT_CORNER_RT:
661         if (!es->fit_along) es->h = es->zone->h;
662         if (!es->fit_size) es->w = size;
663         es->x = es->zone->w - es->w;
664         es->y = 0;
665         break;
666       case E_GADCON_ORIENT_CORNER_LB:
667         if (!es->fit_along) es->h = es->zone->h;
668         if (!es->fit_size) es->w = size;
669         es->x = 0;
670         es->y = es->zone->h - es->h;
671         break;
672       case E_GADCON_ORIENT_CORNER_RB:
673         if (!es->fit_along) es->h = es->zone->h;
674         if (!es->fit_size) es->w = size;
675         es->x = es->zone->w - es->w;
676         es->y = es->zone->h - es->h;
677         break;
678       default:
679         break;
680      }
681    es->hide_step = 0;
682    es->hide_origin = -1;
683
684    e_shelf_move_resize(es, es->x, es->y, es->w, es->h);
685    if (es->hidden)
686      {
687         es->hidden = 0;
688         e_shelf_toggle(es, 0);
689      }
690    e_zone_useful_geometry_dirty(es->zone);
691    _e_shelf_bindings_add(es);
692 }
693
694 EAPI void 
695 e_shelf_style_set(E_Shelf *es, const char *style) 
696 {
697    const char *option;
698    char buf[1024];
699
700    E_OBJECT_CHECK(es);
701    E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
702
703    if (!es->o_base) return;
704    if (es->style) eina_stringshare_del(es->style);
705    es->style = eina_stringshare_add(style);
706
707    if (style)
708      snprintf(buf, sizeof(buf), "e/shelf/%s/base", style);
709    else
710      snprintf(buf, sizeof(buf), "e/shelf/%s/base", "default");
711      
712    if (!e_theme_edje_object_set(es->o_base, "base/theme/shelf", buf))
713      e_theme_edje_object_set(es->o_base, "base/theme/shelf", 
714                              "e/shelf/default/base");
715
716    option =  edje_object_data_get(es->o_base, "hidden_state_size");
717    if (option)
718      es->hidden_state_size = atoi(option);
719    else
720      es->hidden_state_size = 4;
721    option =  edje_object_data_get(es->o_base, "instant_delay");
722    if (option)
723      es->instant_delay = atof(option);
724    else
725      es->instant_delay = -1.0;
726
727    e_gadcon_unpopulate(es->gadcon);
728    e_gadcon_populate(es->gadcon);
729 }
730
731 EAPI void 
732 e_shelf_popup_set(E_Shelf *es, int popup) 
733 {
734    /* FIXME: Needs to recreate the evas objects. */
735    E_OBJECT_CHECK(es);
736    E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
737
738    if (!es->cfg) return;
739    if (((popup) && (es->popup)) || ((!popup) && (!es->popup))) return;
740
741    if (popup) 
742      {
743         es->popup = e_popup_new(es->zone, es->x, es->y, es->w, es->h);
744         e_popup_name_set(es->popup, "shelf");
745         e_popup_layer_set(es->popup, es->cfg->layer);
746
747         es->ee = es->popup->ecore_evas;
748         es->evas = es->popup->evas;
749         evas_object_show(es->o_event);
750         evas_object_show(es->o_base);
751         e_popup_edje_bg_object_set(es->popup, es->o_base);
752         ecore_x_netwm_window_type_set(es->popup->evas_win, ECORE_X_WINDOW_TYPE_DOCK);
753         
754         e_drop_xdnd_register_set(es->popup->evas_win, 1);
755         e_gadcon_xdnd_window_set(es->gadcon, es->popup->evas_win);
756         e_gadcon_dnd_window_set(es->gadcon, es->popup->evas_win);
757      }
758    else 
759      {
760         e_drop_xdnd_register_set(es->popup->evas_win, 0);
761         e_object_del(E_OBJECT(es->popup));
762         es->popup = NULL;
763
764         es->ee = es->zone->container->bg_ecore_evas;
765         es->evas = es->zone->container->bg_evas;
766
767         evas_object_move(es->o_event, es->zone->x + es->x, es->zone->y + es->y);
768         evas_object_move(es->o_base, es->zone->x + es->x, es->zone->y + es->y);
769         evas_object_layer_set(es->o_event, es->cfg->layer);
770         evas_object_layer_set(es->o_base, es->cfg->layer);
771
772         e_drop_xdnd_register_set(es->zone->container->bg_win, 1);
773         e_gadcon_xdnd_window_set(es->gadcon, es->zone->container->bg_win);
774         e_gadcon_dnd_window_set(es->gadcon, es->zone->container->event_win);
775      }
776 }
777
778 EAPI E_Shelf *
779 e_shelf_config_new(E_Zone *zone, E_Config_Shelf *cf_es)
780 {
781    E_Shelf *es;
782
783    es = e_shelf_zone_new(zone, cf_es->name, cf_es->style,
784                          cf_es->popup, cf_es->layer, cf_es->id);
785    if (!es) return NULL;
786
787    if (!cf_es->hide_timeout) cf_es->hide_timeout = 1.0; 
788    if (!cf_es->hide_duration) cf_es->hide_duration = 1.0; 
789    es->cfg = cf_es;
790    es->fit_along = cf_es->fit_along;
791    es->fit_size = cf_es->fit_size;
792
793    e_shelf_orient(es, cf_es->orient);
794    e_shelf_position_calc(es);
795    e_shelf_populate(es);
796
797    if (cf_es->desk_show_mode)
798      {
799         E_Desk *desk;
800         Eina_List *ll;
801         E_Config_Shelf_Desk *sd;
802
803         desk = e_desk_current_get(zone);
804         EINA_LIST_FOREACH(cf_es->desk_list, ll, sd)
805           {
806              if ((desk->x == sd->x) && (desk->y == sd->y))
807                {
808                   e_shelf_show(es);
809                   break;
810                }
811           }
812      }
813    else
814      e_shelf_show(es);
815
816    e_shelf_toggle(es, 0);
817    return es;
818 }
819
820 /* local subsystem functions */
821 static void
822 _e_shelf_free(E_Shelf *es)
823 {
824    _e_shelf_bindings_del(es);
825
826    e_gadcon_location_unregister(es->gadcon->location);
827    e_gadcon_location_free(es->gadcon->location); 
828    e_zone_useful_geometry_dirty(es->zone);
829    E_FREE_LIST(es->handlers, ecore_event_handler_del);
830
831    e_object_del(E_OBJECT(es->gadcon));
832    if (es->hide_timer)
833      {
834         ecore_timer_del(es->hide_timer);
835         es->hide_timer  = NULL;
836      }
837    if (es->hide_animator)
838      {
839         ecore_animator_del(es->hide_animator);
840         es->hide_animator = NULL;
841      }
842    if (es->instant_timer)
843      {
844         ecore_timer_del(es->instant_timer);
845         es->instant_timer = NULL;
846      }
847
848    if (es->menu)
849      {
850         e_menu_post_deactivate_callback_set(es->menu, NULL, NULL);
851         e_object_del(E_OBJECT(es->menu));
852         es->menu = NULL;
853      }
854    if (es->config_dialog) e_object_del(E_OBJECT(es->config_dialog));
855    shelves = eina_list_remove(shelves, es);
856    eina_stringshare_del(es->name);
857    eina_stringshare_del(es->style);
858    evas_object_del(es->o_event);
859    evas_object_del(es->o_base);
860    if (es->popup)
861      {
862         e_drop_xdnd_register_set(es->popup->evas_win, 0);
863         eina_hash_del(winid_shelves, 
864                       e_util_winid_str_get(es->popup->evas_win), es);
865         if (!eina_hash_population(winid_shelves))
866           {
867             eina_hash_free(winid_shelves);
868             winid_shelves = NULL;
869           }
870         e_object_del(E_OBJECT(es->popup));
871      }
872    free(es);
873 }
874
875 static void
876 _e_shelf_gadcon_min_size_request(void *data __UNUSED__, E_Gadcon *gc __UNUSED__, Evas_Coord w __UNUSED__, Evas_Coord h __UNUSED__)
877 {
878    return;
879 }
880
881 static void
882 _e_shelf_gadcon_size_request(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h)
883 {
884    E_Shelf *es;
885    Evas_Coord nx, ny, nw, nh, ww, hh, wantw, wanth;
886
887    es = data;
888    nx = es->x;
889    ny = es->y;
890    nw = es->w;
891    nh = es->h;
892    ww = hh = 0;
893    evas_object_geometry_get(gc->o_container, NULL, NULL, &ww, &hh);
894    switch (gc->orient)
895      {
896       case E_GADCON_ORIENT_FLOAT:
897       case E_GADCON_ORIENT_HORIZ:
898       case E_GADCON_ORIENT_TOP:
899       case E_GADCON_ORIENT_BOTTOM:
900       case E_GADCON_ORIENT_CORNER_TL:
901       case E_GADCON_ORIENT_CORNER_TR:
902       case E_GADCON_ORIENT_CORNER_BL:
903       case E_GADCON_ORIENT_CORNER_BR:
904         if (!es->fit_along) w = ww;
905         if (!es->fit_size) h = hh;
906         break;
907       case E_GADCON_ORIENT_VERT:
908       case E_GADCON_ORIENT_LEFT:
909       case E_GADCON_ORIENT_RIGHT:
910       case E_GADCON_ORIENT_CORNER_LT:
911       case E_GADCON_ORIENT_CORNER_RT:
912       case E_GADCON_ORIENT_CORNER_LB:
913       case E_GADCON_ORIENT_CORNER_RB:
914         if (!es->fit_along) h = hh;
915         if (!es->fit_size) w = ww;
916         break;
917       default:
918         break;
919      }
920    e_gadcon_swallowed_min_size_set(gc, w, h);
921    edje_object_size_min_calc(es->o_base, &nw, &nh);
922    wantw = nw;
923    wanth = nh;
924    switch (gc->orient)
925      {
926       case E_GADCON_ORIENT_FLOAT:
927         if (!es->fit_along) nw = es->w;
928         if (!es->fit_size) nh = es->h;
929         if (nw > es->zone->w) nw = es->zone->w;
930         if (nh > es->zone->h) nh = es->zone->h;
931         if (nw != es->w) nx = es->x + ((es->w - nw) / 2);
932         break;
933       case E_GADCON_ORIENT_HORIZ:
934         if (!es->fit_along) nw = es->w;
935         if (!es->fit_size) nh = es->h;
936         if (nw > es->zone->w) nw = es->zone->w;
937         if (nh > es->zone->h) nh = es->zone->h;
938         if (nw != es->w) nx = es->x + ((es->w - nw) / 2);
939         break;
940       case E_GADCON_ORIENT_VERT:
941         if (!es->fit_along) nh = es->h;
942         if (!es->fit_size) nw = es->w;
943         if (nw > es->zone->w) nw = es->zone->w;
944         if (nh > es->zone->h) nh = es->zone->h;
945         if (nh != es->h) ny = es->y + ((es->h - nh) / 2);
946         break;
947       case E_GADCON_ORIENT_LEFT:
948         if (!es->fit_along) nh = es->h;
949         if (!es->fit_size) nw = es->w;
950         if (nw > es->zone->w) nw = es->zone->w;
951         if (nh > es->zone->h) nh = es->zone->h;
952         if (nh != es->h) ny = (es->zone->h - nh) / 2;
953         // nx = 0;
954         break;
955       case E_GADCON_ORIENT_RIGHT:
956         if (!es->fit_along) nh = es->h;
957         if (!es->fit_size) nw = es->w;
958         if (nw > es->zone->w) nw = es->zone->w;
959         if (nh > es->zone->h) nh = es->zone->h;
960         if (nh != es->h) ny = (es->zone->h - nh) / 2;
961         // nx = es->zone->w - nw;
962         break;
963       case E_GADCON_ORIENT_TOP:
964         if (!es->fit_along) nw = es->w;
965         if (!es->fit_size) nh = es->h;
966         if (nw > es->zone->w) nw = es->zone->w;
967         if (nh > es->zone->h) nh = es->zone->h;
968         if (nw != es->w) nx = (es->zone->w - nw) / 2;
969         // ny = 0;
970         break;
971       case E_GADCON_ORIENT_BOTTOM:
972         if (!es->fit_along) nw = es->w;
973         if (!es->fit_size) nh = es->h;
974         if (nw > es->zone->w) nw = es->zone->w;
975         if (nh > es->zone->h) nh = es->zone->h;
976         if (nw != es->w) nx = (es->zone->w - nw) / 2;
977         //ny = es->zone->h - nh;
978         break;
979       case E_GADCON_ORIENT_CORNER_TL:
980         if (!es->fit_along) nw = es->w;
981         if (!es->fit_size) nh = es->h;
982         if (nw > es->zone->w) nw = es->zone->w;
983         if (nh > es->zone->h) nh = es->zone->h;
984         if (nw != es->w) nx = 0;
985         // ny = 0;
986         break;
987       case E_GADCON_ORIENT_CORNER_TR:
988         if (!es->fit_along) nw = es->w;
989         if (!es->fit_size) nh = es->h;
990         if (nw > es->zone->w) nw = es->zone->w;
991         if (nh > es->zone->h) nh = es->zone->h;
992         nx = es->zone->w - nw;
993         // ny = 0;
994         break;
995       case E_GADCON_ORIENT_CORNER_BL:
996         if (!es->fit_along) nw = es->w;
997         if (!es->fit_size) nh = es->h;
998         if (nw > es->zone->w) nw = es->zone->w;
999         if (nh > es->zone->h) nh = es->zone->h;
1000         if (nw != es->w) nx = 0;
1001         // ny = es->zone->h - nh;
1002         break;
1003       case E_GADCON_ORIENT_CORNER_BR:
1004         if (!es->fit_along) nw = es->w;
1005         if (!es->fit_size) nh = es->h;
1006         if (nw > es->zone->w) nw = es->zone->w;
1007         if (nh > es->zone->h) nh = es->zone->h;
1008         nx = es->zone->w - nw;
1009         //ny = es->zone->h - nh;
1010         break;
1011       case E_GADCON_ORIENT_CORNER_LT:
1012         if (!es->fit_along) nh = es->h;
1013         if (!es->fit_size) nw = es->w;
1014         if (nw > es->zone->w) nw = es->zone->w;
1015         if (nh > es->zone->h) nh = es->zone->h;
1016         if (nh != es->h) ny = 0;
1017         // nx = 0;
1018         break;
1019       case E_GADCON_ORIENT_CORNER_RT:
1020         if (!es->fit_along) nh = es->h;
1021         if (!es->fit_size) nw = es->w;
1022         if (nw > es->zone->w) nw = es->zone->w;
1023         if (nh > es->zone->h) nh = es->zone->h;
1024         if (nh != es->h) ny = 0;
1025         // nx = es->zone->w - nw;
1026         break;
1027       case E_GADCON_ORIENT_CORNER_LB:
1028         if (!es->fit_along) nh = es->h;
1029         if (!es->fit_size) nw = es->w;
1030         if (nw > es->zone->w) nw = es->zone->w;
1031         if (nh > es->zone->h) nh = es->zone->h;
1032         if (nh != es->h) ny = es->zone->h - nh;
1033         // nx = 0;
1034         break;
1035       case E_GADCON_ORIENT_CORNER_RB:
1036         if (!es->fit_along) nh = es->h;
1037         if (!es->fit_size) nw = es->w;
1038         if (nw > es->zone->w) nw = es->zone->w;
1039         if (nh > es->zone->h) nh = es->zone->h;
1040         if (nh != es->h) ny = es->zone->h - nh;
1041         // nx = es->zone->w - nw;
1042         break;
1043       default:
1044         break;
1045      }
1046    w -= (wantw - nw);
1047    h -= (wanth - nh);
1048    e_gadcon_swallowed_min_size_set(gc, w, h);
1049    e_shelf_move_resize(es, nx, ny, nw, nh);
1050    e_zone_useful_geometry_dirty(es->zone);
1051 }
1052
1053 static Evas_Object *
1054 _e_shelf_gadcon_frame_request(void *data, E_Gadcon_Client *gcc, const char *style)
1055 {
1056    E_Shelf *es;
1057    Evas_Object *o;
1058    char buf[PATH_MAX];
1059
1060    es = data;
1061    o = edje_object_add(gcc->gadcon->evas);
1062
1063    snprintf(buf, sizeof(buf), "e/shelf/%s/%s", es->style, style);
1064    if (!e_theme_edje_object_set(o, "base/theme/shelf", buf))
1065      {
1066         /* if an inset style (e.g. plain) isn't implemented for a given
1067          * shelf style, fall back to the default one. no need for every
1068          * theme to implement the plain style */
1069         snprintf(buf, sizeof(buf), "e/shelf/default/%s", style);
1070         if (!e_theme_edje_object_set(o, "base/theme/shelf", buf))
1071           {
1072              evas_object_del(o);
1073              return NULL;
1074           }
1075      }
1076    snprintf(buf, sizeof(buf), "e,state,orientation,%s", 
1077             e_shelf_orient_string_get(es));
1078    edje_object_signal_emit(es->o_base, buf, "e");
1079    edje_object_message_signal_process(o);
1080    return o;
1081 }
1082
1083 static void
1084 _e_shelf_toggle_border_fix(E_Shelf *es)
1085 {
1086    Eina_List *l;
1087    E_Border *bd;
1088
1089    if ((es->cfg->overlap) || (!e_config->border_fix_on_shelf_toggle))
1090      return;
1091
1092    EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1093      {
1094         if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
1095           {
1096              if (bd->lock_client_location) continue;
1097              if (es->hidden)
1098                {
1099                   if (!bd->shelf_fix.modified) continue;
1100                   if (!--bd->shelf_fix.modified)
1101                     {
1102                        e_border_move(bd, bd->shelf_fix.x, bd->shelf_fix.y);
1103                        continue;
1104                     }
1105                }
1106
1107              if (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
1108                                es->x, es->y, es->w, es->h))
1109                continue;
1110
1111              if (!es->hidden)
1112                {
1113                   if (!bd->shelf_fix.modified++)
1114                     bd->shelf_fix.x = bd->x;
1115                     bd->shelf_fix.y = bd->y;
1116                }
1117
1118              switch (es->gadcon->orient)
1119                {
1120                 case E_GADCON_ORIENT_TOP:
1121                 case E_GADCON_ORIENT_CORNER_TL:
1122                 case E_GADCON_ORIENT_CORNER_TR:
1123                   if (!es->hidden)
1124                     e_border_move(bd, bd->x, bd->y + es->h);
1125                   break;
1126                 case E_GADCON_ORIENT_BOTTOM:
1127                 case E_GADCON_ORIENT_CORNER_BL:
1128                 case E_GADCON_ORIENT_CORNER_BR:
1129                   if (!es->hidden)
1130                     e_border_move(bd, bd->x, bd->y - es->h);
1131                   break;
1132                 case E_GADCON_ORIENT_LEFT:
1133                 case E_GADCON_ORIENT_CORNER_LB:
1134                 case E_GADCON_ORIENT_CORNER_LT:
1135                   if (!es->hidden)
1136                     e_border_move(bd, bd->x + es->w, bd->y);
1137                   break; 
1138                 case E_GADCON_ORIENT_RIGHT:
1139                 case E_GADCON_ORIENT_CORNER_RB:
1140                 case E_GADCON_ORIENT_CORNER_RT:
1141                   if (!es->hidden)
1142                     e_border_move(bd, bd->x - es->w, bd->y);
1143                   break; 
1144                 default:
1145                    break;
1146                }
1147           }
1148         else
1149           {
1150              E_Maximize max;
1151
1152              max = bd->maximized;
1153              e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
1154              e_border_maximize(bd, max);
1155           }
1156      }
1157 }
1158
1159 static void
1160 _e_shelf_menu_item_free(void *data)
1161 {
1162    E_Shelf *es;
1163
1164    es = e_object_data_get(data);
1165    e_shelf_locked_set(es, 0);
1166 }
1167
1168 static void
1169 _e_shelf_menu_append(E_Shelf *es, E_Menu *mn)
1170 {
1171    E_Menu_Item *mi;
1172    E_Menu *subm;
1173    const char *name;
1174    char buf[256];
1175
1176    name = e_shelf_orient_string_get (es);
1177    snprintf(buf, sizeof(buf), "Shelf %s", name);
1178
1179    e_shelf_locked_set(es, 1);
1180
1181    subm = e_menu_new();
1182    mi = e_menu_item_new(mn);
1183    e_menu_item_label_set(mi, buf);
1184    e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf");
1185    e_menu_pre_activate_callback_set(subm, _e_shelf_menu_pre_cb, es);
1186    e_object_free_attach_func_set(E_OBJECT(mi), _e_shelf_menu_item_free);
1187    e_object_data_set(E_OBJECT(mi), es);
1188    e_menu_item_submenu_set(mi, subm);
1189 }
1190
1191 static void
1192 _e_shelf_cb_menu_items_append(void *data, E_Gadcon_Client *gcc __UNUSED__, E_Menu *mn)
1193 {
1194    E_Shelf *es;
1195
1196    es = data;
1197    _e_shelf_menu_append(es, mn);
1198 }
1199
1200 static void
1201 _e_shelf_cb_locked_set(void *data, int lock)
1202 {
1203    E_Shelf *es;
1204
1205    es = data;
1206    e_shelf_locked_set(es, lock);
1207 }
1208
1209 static void
1210 _e_shelf_cb_urgent_show(void *data)
1211 {
1212    E_Shelf *es;
1213
1214    es = data;
1215    e_shelf_urgent_show(es);
1216 }
1217
1218 static void
1219 _e_shelf_cb_menu_config(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1220 {
1221    E_Shelf *es;
1222
1223    es = data;
1224    if (!es->config_dialog) e_int_shelf_config(es);
1225 }
1226
1227 static void
1228 _e_shelf_cb_menu_edit(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1229 {
1230    E_Shelf *es;
1231
1232    es = data;
1233    if (es->gadcon->editing)
1234      {
1235         e_gadcon_edit_end(es->gadcon);
1236         e_shelf_toggle(es, 0);
1237      }
1238    else
1239      {
1240         e_shelf_toggle(es, 1);
1241         e_gadcon_edit_begin(es->gadcon);
1242      }
1243 }
1244
1245 static void
1246 _e_shelf_cb_menu_contents(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1247 {
1248    E_Shelf *es;
1249
1250    es = data;
1251    if (!es->gadcon->config_dialog) e_int_gadcon_config_shelf(es->gadcon);
1252 }
1253
1254 static void
1255 _e_shelf_cb_confirm_dialog_destroy(void *data)
1256 {
1257    E_Shelf *es;
1258
1259    es = data;
1260    e_object_unref(E_OBJECT(es));
1261 }
1262
1263 static void
1264 _e_shelf_cb_confirm_dialog_yes(void *data)
1265 {
1266    E_Config_Shelf *cfg;
1267    E_Shelf *es;
1268
1269    es = data;
1270    cfg = es->cfg;
1271    if (e_object_is_del(E_OBJECT(es))) return;
1272    e_object_del(E_OBJECT(es));
1273    e_config->shelves = eina_list_remove(e_config->shelves, cfg);
1274    if (cfg->name) eina_stringshare_del(cfg->name);
1275    if (cfg->style) eina_stringshare_del(cfg->style);
1276    E_FREE(cfg);
1277
1278    e_config_save_queue();
1279 }
1280
1281
1282 static void
1283 _e_shelf_cb_menu_delete(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1284 {
1285    E_Shelf *es;
1286    E_Config_Shelf *cfg;
1287
1288    es = data;
1289    if (e_config->cnfmdlg_disabled) 
1290      {
1291         cfg = es->cfg;
1292         if (e_object_is_del(E_OBJECT(es))) return;
1293         e_object_del(E_OBJECT(es));
1294         e_config->shelves = eina_list_remove(e_config->shelves, cfg);
1295         if (cfg->name) eina_stringshare_del(cfg->name);
1296         if (cfg->style) eina_stringshare_del(cfg->style);
1297         E_FREE(cfg);
1298
1299         e_config_save_queue();
1300         return;
1301      }
1302
1303    e_object_ref(E_OBJECT(es));
1304    e_confirm_dialog_show(_("Are you sure you want to delete this shelf?"), "enlightenment",
1305                          _("You requested to delete this shelf.<br>"
1306                               "<br>"
1307                               "Are you sure you want to delete it?"), NULL, NULL,
1308                          _e_shelf_cb_confirm_dialog_yes, NULL, data, NULL, 
1309                          _e_shelf_cb_confirm_dialog_destroy, data);
1310 }
1311
1312 static void
1313 _e_shelf_cb_menu_post(void *data, E_Menu *m __UNUSED__)
1314 {
1315    E_Shelf *es;
1316
1317    es = data;
1318    if (!es->menu) return;
1319    e_object_del(E_OBJECT(es->menu));
1320    es->menu = NULL;
1321 }
1322
1323 static void
1324 _e_shelf_cb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1325 {
1326    Evas_Event_Mouse_Down *ev;
1327    E_Shelf *es;
1328    E_Menu *mn;
1329    int cx, cy;
1330
1331    es = data;
1332    ev = event_info;
1333    switch (ev->button)
1334      {
1335       case 1:
1336         if (es->cfg->autohide_show_action) e_shelf_toggle(es, 1);
1337         break;
1338       case 3:
1339         mn = e_menu_new();
1340         e_menu_post_deactivate_callback_set(mn, _e_shelf_cb_menu_post, es);
1341         es->menu = mn;
1342
1343         _e_shelf_menu_pre_cb(es, mn);
1344
1345         e_gadcon_canvas_zone_geometry_get(es->gadcon, &cx, &cy, NULL, NULL);
1346         e_menu_activate_mouse(mn,
1347                               e_util_zone_current_get(e_manager_current_get()),
1348                               cx + ev->output.x, 
1349                               cy + ev->output.y, 1, 1,
1350                               E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
1351         break;
1352      }
1353 }
1354
1355 static Eina_Bool
1356 _e_shelf_cb_mouse_in(void *data, int type, void *event)
1357 {
1358    E_Shelf *es;
1359
1360    es = data;
1361    if (es->cfg->autohide_show_action) return ECORE_CALLBACK_PASS_ON;
1362
1363    if (type == E_EVENT_ZONE_EDGE_MOVE)
1364      {
1365         E_Event_Zone_Edge *ev;
1366         int show = 0;
1367
1368         ev = event;
1369         if (es->zone != ev->zone) return ECORE_CALLBACK_PASS_ON;
1370         if (!_e_shelf_on_current_desk(es, ev)) return ECORE_CALLBACK_PASS_ON;
1371
1372         switch (es->gadcon->orient)
1373           {
1374            case E_GADCON_ORIENT_FLOAT:
1375            case E_GADCON_ORIENT_HORIZ:
1376            case E_GADCON_ORIENT_VERT:
1377               /* noop */
1378               break;
1379            case E_GADCON_ORIENT_LEFT:
1380            case E_GADCON_ORIENT_CORNER_LT:
1381            case E_GADCON_ORIENT_CORNER_LB:
1382               if (((ev->edge == E_ZONE_EDGE_LEFT) ||
1383                    (ev->edge == E_ZONE_EDGE_TOP_LEFT) ||
1384                    (ev->edge == E_ZONE_EDGE_BOTTOM_LEFT)) &&
1385                   (ev->y >= es->y) && (ev->y <= (es->y + es->h)))
1386                 show = 1;
1387               break;
1388            case E_GADCON_ORIENT_RIGHT:
1389            case E_GADCON_ORIENT_CORNER_RT:
1390            case E_GADCON_ORIENT_CORNER_RB:
1391               if (((ev->edge == E_ZONE_EDGE_RIGHT) ||
1392                    (ev->edge == E_ZONE_EDGE_TOP_RIGHT) ||
1393                    (ev->edge == E_ZONE_EDGE_BOTTOM_RIGHT)) &&
1394                   (ev->y >= es->y) && (ev->y <= (es->y + es->h)))
1395                 show = 1;
1396               break;
1397            case E_GADCON_ORIENT_TOP:
1398            case E_GADCON_ORIENT_CORNER_TL:
1399            case E_GADCON_ORIENT_CORNER_TR:
1400               if (((ev->edge == E_ZONE_EDGE_TOP) ||
1401                    (ev->edge == E_ZONE_EDGE_TOP_LEFT) ||
1402                    (ev->edge == E_ZONE_EDGE_TOP_RIGHT)) &&
1403                   (ev->x >= es->x) && (ev->x <= (es->x + es->w)))
1404                 show = 1;
1405               break;
1406            case E_GADCON_ORIENT_BOTTOM:
1407            case E_GADCON_ORIENT_CORNER_BL:
1408            case E_GADCON_ORIENT_CORNER_BR:
1409               if (((ev->edge == E_ZONE_EDGE_BOTTOM) ||
1410                    (ev->edge == E_ZONE_EDGE_BOTTOM_LEFT) ||
1411                    (ev->edge == E_ZONE_EDGE_BOTTOM_RIGHT)) &&
1412                   (ev->x >= es->x) && (ev->x <= (es->x + es->w)))
1413                 show = 1;
1414               break;
1415           }
1416
1417         if (show)
1418           {
1419              edje_object_signal_emit(es->o_base, "e,state,focused", "e");
1420              e_shelf_toggle(es, 1);
1421           }
1422         else
1423           e_shelf_toggle(es, 0);
1424      }
1425    else if (type == ECORE_X_EVENT_MOUSE_IN)
1426      {
1427         Ecore_X_Event_Mouse_In *ev;
1428
1429         ev = event;
1430         if (!es->popup) return ECORE_CALLBACK_PASS_ON;
1431         if (ev->win == es->popup->evas_win)
1432           {
1433              edje_object_signal_emit(es->o_base, "e,state,focused", "e");
1434              e_shelf_toggle(es, 1);
1435           }
1436      }
1437    else if (type == ECORE_EVENT_MOUSE_MOVE)
1438      {
1439         Ecore_Event_Mouse_Move *ev;
1440
1441         ev = event;
1442         if (!es->popup) return ECORE_CALLBACK_PASS_ON;
1443         if (ev->event_window == es->popup->evas_win)
1444           {
1445              edje_object_signal_emit(es->o_base, "e,state,focused", "e");
1446              e_shelf_toggle(es, 1);
1447           }
1448      }
1449    return ECORE_CALLBACK_PASS_ON;
1450 }
1451
1452 static Eina_Bool
1453 _e_shelf_cb_mouse_out(void *data, int type, void *event)
1454 {
1455    E_Shelf *es;
1456    Ecore_X_Window win;
1457
1458    es = data;
1459
1460    if (type == ECORE_X_EVENT_MOUSE_OUT)
1461      {
1462         Ecore_X_Event_Mouse_Out *ev;
1463
1464         ev = event;
1465
1466         if (es->popup) win = es->popup->evas_win;
1467         else win = es->zone->container->event_win;
1468         if (ev->win != win) return ECORE_CALLBACK_PASS_ON;
1469
1470         /*
1471          * ECORE_X_EVENT_DETAIL_INFERIOR means focus went to children windows
1472          * so do not hide shelf on this case (ie: systray base window, or
1473          * embedded icons).
1474          *
1475          * Problem: when child window get mouse out, shelf window will
1476          * not get mouse out itself, so it will stay visible and
1477          * autohide will fail.
1478          */
1479         if (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
1480
1481         e_shelf_toggle(es, 0);
1482      }
1483    return ECORE_CALLBACK_PASS_ON;
1484 }
1485
1486 static int
1487 _e_shelf_cb_id_sort(const void *data1, const void *data2)
1488 {
1489    const E_Shelf *es1, *es2;
1490
1491    es1 = data1;
1492    es2 = data2;
1493    if ((es1->id) < (es2->id)) return -1;
1494    else if (es1->id > es2->id) return 1;
1495    return 0;
1496 }
1497
1498 static Eina_Bool
1499 _e_shelf_cb_hide_animator(void *data)
1500 {
1501    E_Shelf *es;
1502    int step, hide_max = 0;
1503
1504    es = data;
1505    switch (es->gadcon->orient)
1506      {
1507       case E_GADCON_ORIENT_TOP:
1508       case E_GADCON_ORIENT_CORNER_TL:
1509       case E_GADCON_ORIENT_CORNER_TR:
1510       case E_GADCON_ORIENT_BOTTOM:
1511       case E_GADCON_ORIENT_CORNER_BL:
1512       case E_GADCON_ORIENT_CORNER_BR:
1513         hide_max = es->h - es->hidden_state_size;
1514         if (es->hide_origin == -1) es->hide_origin = es->y;      
1515         break;
1516       case E_GADCON_ORIENT_LEFT:
1517       case E_GADCON_ORIENT_CORNER_LB:
1518       case E_GADCON_ORIENT_CORNER_LT:
1519       case E_GADCON_ORIENT_RIGHT:
1520       case E_GADCON_ORIENT_CORNER_RB:
1521       case E_GADCON_ORIENT_CORNER_RT:
1522         hide_max = es->w - es->hidden_state_size;
1523         if (es->hide_origin == -1) es->hide_origin = es->x;
1524         break;
1525       case E_GADCON_ORIENT_FLOAT:
1526       case E_GADCON_ORIENT_HORIZ:
1527       case E_GADCON_ORIENT_VERT:
1528         break;
1529      }
1530
1531    step = (hide_max / e_config->framerate) / es->cfg->hide_duration;
1532    if (!step) step = 1;
1533
1534    if (es->hidden)
1535      {
1536         if (es->hide_step < hide_max)
1537           {
1538              if (es->hide_step + step > hide_max)
1539                es->hide_step = hide_max;
1540              else
1541                es->hide_step += step;
1542           }
1543         else goto end;
1544      }
1545    else
1546      {
1547         if (es->hide_step > 0)
1548           {
1549              if (es->hide_step < step)
1550                es->hide_step = 0;
1551              else
1552                es->hide_step -= step;          
1553           }
1554         else goto end;
1555      }
1556
1557    switch (es->gadcon->orient)
1558      {
1559       case E_GADCON_ORIENT_TOP:
1560       case E_GADCON_ORIENT_CORNER_TL:
1561       case E_GADCON_ORIENT_CORNER_TR:
1562         e_shelf_move(es, es->x, es->hide_origin - es->hide_step);
1563         break;
1564       case E_GADCON_ORIENT_BOTTOM:
1565       case E_GADCON_ORIENT_CORNER_BL:
1566       case E_GADCON_ORIENT_CORNER_BR:
1567         e_shelf_move(es, es->x, es->hide_origin + es->hide_step);
1568         break;
1569       case E_GADCON_ORIENT_LEFT:
1570       case E_GADCON_ORIENT_CORNER_LB:
1571       case E_GADCON_ORIENT_CORNER_LT:
1572         e_shelf_move(es, es->hide_origin - es->hide_step, es->y);
1573         break;
1574       case E_GADCON_ORIENT_RIGHT:
1575       case E_GADCON_ORIENT_CORNER_RB:
1576       case E_GADCON_ORIENT_CORNER_RT:
1577         e_shelf_move(es, es->hide_origin + es->hide_step, es->y);
1578         break;
1579       case E_GADCON_ORIENT_FLOAT:
1580       case E_GADCON_ORIENT_HORIZ:
1581       case E_GADCON_ORIENT_VERT:
1582          break;
1583      }
1584
1585    return ECORE_CALLBACK_RENEW;
1586
1587 end:
1588    es->hide_animator = NULL;
1589    if (es->interrupted > -1)
1590      e_shelf_toggle(es, es->interrupted);
1591    else if (es->urgent_show)
1592      e_shelf_toggle(es, 0);
1593    else
1594      _e_shelf_toggle_border_fix(es);
1595    return ECORE_CALLBACK_CANCEL;
1596 }
1597
1598 static Eina_Bool
1599 _e_shelf_cb_hide_animator_timer(void *data)
1600 {
1601    E_Shelf *es;
1602
1603    es = data;
1604    if (!es->hide_animator)
1605      es->hide_animator = ecore_animator_add(_e_shelf_cb_hide_animator, es);
1606    es->hide_timer = NULL;
1607    return ECORE_CALLBACK_CANCEL;
1608 }
1609
1610 static Eina_Bool
1611 _e_shelf_cb_hide_urgent_timer(void *data)
1612 {
1613    E_Shelf *es;
1614
1615    es = data;
1616    es->hide_timer = NULL;
1617    if (es->urgent_show) e_shelf_toggle(es, 0);
1618    return ECORE_CALLBACK_CANCEL;
1619 }
1620
1621 static Eina_Bool
1622 _e_shelf_cb_instant_hide_timer(void *data)
1623 {
1624    E_Shelf *es;
1625
1626    es = data;
1627    switch (es->gadcon->orient)
1628      {
1629       case E_GADCON_ORIENT_TOP:
1630       case E_GADCON_ORIENT_CORNER_TL:
1631       case E_GADCON_ORIENT_CORNER_TR:
1632         if (es->hidden)
1633           e_shelf_move(es, es->x, es->y - es->h + es->hidden_state_size);
1634         else
1635           e_shelf_move(es, es->x, es->y + es->h - es->hidden_state_size);
1636         break;
1637       case E_GADCON_ORIENT_BOTTOM:
1638       case E_GADCON_ORIENT_CORNER_BL:
1639       case E_GADCON_ORIENT_CORNER_BR:
1640         if (es->hidden)
1641           e_shelf_move(es, es->x, es->y + es->h - es->hidden_state_size);
1642         else
1643           e_shelf_move(es, es->x, es->y - es->h + es->hidden_state_size);
1644         break;
1645       case E_GADCON_ORIENT_LEFT:
1646       case E_GADCON_ORIENT_CORNER_LB:
1647       case E_GADCON_ORIENT_CORNER_LT:
1648         if (es->hidden)
1649           e_shelf_move(es, es->x - es->w + es->hidden_state_size, es->y);
1650         else
1651           e_shelf_move(es, es->x + es->w - es->hidden_state_size, es->y);
1652         break; 
1653       case E_GADCON_ORIENT_RIGHT:
1654       case E_GADCON_ORIENT_CORNER_RB:
1655       case E_GADCON_ORIENT_CORNER_RT:
1656         if (es->hidden)
1657           e_shelf_move(es, es->x + es->w - es->hidden_state_size, es->y);
1658         else
1659           e_shelf_move(es, es->x - es->w + es->hidden_state_size, es->y);
1660         break; 
1661       default:
1662          break;
1663      }
1664    es->instant_timer = NULL;
1665    _e_shelf_toggle_border_fix(es);
1666    return ECORE_CALLBACK_CANCEL;
1667 }
1668
1669 static void 
1670 _e_shelf_menu_pre_cb(void *data, E_Menu *m) 
1671 {
1672    E_Shelf *es;
1673    E_Menu_Item *mi;
1674
1675    es = data;
1676    e_menu_pre_activate_callback_set(m, NULL, NULL);
1677
1678    mi = e_menu_item_new(m);
1679    if (es->gadcon->editing)
1680      e_menu_item_label_set(mi, _("Stop Moving/Resizing Gadgets"));
1681    else
1682      e_menu_item_label_set(mi, _("Begin Moving/Resizing Gadgets"));
1683    e_util_menu_item_theme_icon_set(mi, "transform-scale");
1684    e_menu_item_callback_set(mi, _e_shelf_cb_menu_edit, es);
1685
1686    mi = e_menu_item_new(m);
1687    e_menu_item_separator_set(mi, 1);
1688
1689    mi = e_menu_item_new(m);
1690    e_menu_item_label_set(mi, _("Contents"));
1691    e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf");
1692    e_menu_item_callback_set(mi, _e_shelf_cb_menu_contents, es);
1693
1694    mi = e_menu_item_new(m);
1695    e_menu_item_label_set(mi, _("Settings"));
1696    e_util_menu_item_theme_icon_set(mi, "configure");
1697    e_menu_item_callback_set(mi, _e_shelf_cb_menu_config, es);
1698
1699    mi = e_menu_item_new(m);
1700    e_menu_item_separator_set(mi, 1);
1701
1702    mi = e_menu_item_new(m);
1703    e_menu_item_label_set(mi, _("Delete"));
1704    e_util_menu_item_theme_icon_set(mi, "list-remove");
1705    e_menu_item_callback_set(mi, _e_shelf_cb_menu_delete, es);   
1706 }
1707
1708 static void
1709 _e_shelf_gadcon_client_remove(void *data, E_Gadcon_Client *gcc)
1710 {
1711    E_Shelf *s;
1712    E_Gadcon *gc;
1713
1714    s = data;
1715    gc = s->gadcon;
1716    e_gadcon_client_config_del(gc->cf, gcc->cf);
1717    e_gadcon_unpopulate(gc);
1718    e_gadcon_populate(gc);
1719    e_config_save_queue();
1720 }
1721
1722 static int
1723 _e_shelf_gadcon_client_add(void *data, const E_Gadcon_Client_Class *cc)
1724 {
1725    E_Shelf *s;
1726    E_Gadcon *gc;
1727
1728    s = data;
1729    gc = s->gadcon;
1730    if (!e_gadcon_client_config_new(gc, cc->name)) return 0;
1731    e_gadcon_unpopulate(gc);
1732    e_gadcon_populate(gc);
1733    e_config_save_queue();
1734    return 1;
1735 }
1736
1737 static const char *
1738 _e_shelf_orient_icon_name_get(E_Shelf * s)
1739 {
1740    const char * name;
1741
1742    name = NULL;
1743    switch (s->cfg->orient) 
1744      {
1745       case E_GADCON_ORIENT_LEFT:
1746         name = "preferences-position-left";
1747         break;
1748       case E_GADCON_ORIENT_RIGHT:
1749         name = "preferences-position-right";
1750         break;
1751       case E_GADCON_ORIENT_TOP:
1752         name = "preferences-position-top";
1753         break;
1754       case E_GADCON_ORIENT_BOTTOM:
1755         name = "preferences-position-bottom";
1756         break;
1757       case E_GADCON_ORIENT_CORNER_TL:
1758         name = "preferences-position-top-left";
1759         break;
1760       case E_GADCON_ORIENT_CORNER_TR:
1761         name = "preferences-position-top-right";
1762         break;
1763       case E_GADCON_ORIENT_CORNER_BL:
1764         name = "preferences-position-bottom-left";
1765         break;
1766       case E_GADCON_ORIENT_CORNER_BR:
1767         name = "preferences-position-bottom-right";
1768         break;
1769       case E_GADCON_ORIENT_CORNER_LT:
1770         name = "preferences-position-left-top";
1771         break;
1772       case E_GADCON_ORIENT_CORNER_RT:
1773         name = "preferences-position-right-top";
1774         break;
1775       case E_GADCON_ORIENT_CORNER_LB:
1776         name = "preferences-position-left-bottom";
1777         break;
1778       case E_GADCON_ORIENT_CORNER_RB:
1779         name = "preferences-position-right-bottom";
1780         break;
1781       default:
1782         name = "preferences-desktop-shelf";
1783         break;
1784      }
1785    return name;
1786 }
1787
1788 static void
1789 _e_shelf_bindings_add(E_Shelf *es)
1790 {
1791    char buf[1024];
1792
1793    /* TODO: This might delete edge windows, and then add them again further down. Should prevent this. */
1794    _e_shelf_bindings_del(es);
1795
1796    /* Don't need edge binding if we don't hide shelf */
1797    if ((!es->cfg->autohide) && (!es->cfg->autohide_show_action)) return;
1798
1799    snprintf(buf, sizeof(buf), "shelf.%d", es->id);
1800    switch (es->gadcon->orient)
1801      {
1802       case E_GADCON_ORIENT_FLOAT:
1803       case E_GADCON_ORIENT_HORIZ:
1804       case E_GADCON_ORIENT_VERT:
1805          /* noop */
1806          break;
1807       case E_GADCON_ORIENT_LEFT:
1808          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_LEFT, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1809          break;
1810       case E_GADCON_ORIENT_RIGHT:
1811          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_RIGHT, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1812          break;
1813       case E_GADCON_ORIENT_TOP:
1814          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_TOP, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1815          break;
1816       case E_GADCON_ORIENT_BOTTOM:
1817          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_BOTTOM, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1818          break;
1819       case E_GADCON_ORIENT_CORNER_TL:
1820       case E_GADCON_ORIENT_CORNER_LT:
1821          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_TOP, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1822          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_LEFT, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1823          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_TOP_LEFT, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1824          break;
1825       case E_GADCON_ORIENT_CORNER_TR:
1826       case E_GADCON_ORIENT_CORNER_RT:
1827          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_TOP, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1828          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_RIGHT, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1829          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_TOP_RIGHT, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1830          break;
1831       case E_GADCON_ORIENT_CORNER_BL:
1832       case E_GADCON_ORIENT_CORNER_LB:
1833          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_BOTTOM, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1834          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_LEFT, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1835          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_BOTTOM_LEFT, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1836          break;
1837       case E_GADCON_ORIENT_CORNER_BR:
1838       case E_GADCON_ORIENT_CORNER_RB:
1839          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_BOTTOM, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1840          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_RIGHT, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1841          e_bindings_edge_add(E_BINDING_CONTEXT_ZONE, E_ZONE_EDGE_BOTTOM_RIGHT, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1842          break;
1843      }
1844 }
1845
1846 static void
1847 _e_shelf_bindings_del(E_Shelf *es)
1848 {
1849    char buf[1024];
1850    E_Zone_Edge edge;
1851
1852    snprintf(buf, sizeof(buf), "shelf.%d", es->id);
1853    for (edge = E_ZONE_EDGE_LEFT; edge <= E_ZONE_EDGE_BOTTOM_LEFT; edge++)
1854      e_bindings_edge_del(E_BINDING_CONTEXT_ZONE, edge, E_BINDING_MODIFIER_NONE, 1, buf, NULL, 0);
1855 }
1856
1857 static Eina_Bool
1858 _e_shelf_on_current_desk(E_Shelf *es, E_Event_Zone_Edge *ev)
1859 {
1860    E_Config_Shelf_Desk *sd;
1861    Eina_List *ll;
1862    int on_current_desk = 0;
1863    int on_all_desks = 1;
1864
1865    EINA_LIST_FOREACH(es->cfg->desk_list, ll, sd)
1866      {
1867         if (!sd) continue;
1868         on_all_desks = 0;
1869         if ((sd->x == ev->zone->desk_x_current) && (sd->y == ev->zone->desk_y_current))
1870           {
1871              on_current_desk = 1;
1872              break;
1873           }
1874      }
1875    if (!on_all_desks && !on_current_desk)
1876      return EINA_FALSE;
1877
1878
1879    return EINA_TRUE;
1880 }