eb3c558f8d2041c52934d3486055d8f6250469a1
[framework/uifw/e17.git] / src / modules / illume-indicator / e_mod_ind_win.c
1 #include "e.h"
2 #include "e_mod_main.h"
3 #include "e_mod_config.h"
4 #include "e_mod_ind_win.h"
5
6 /* local function prototypes */
7 static void _e_mod_ind_win_cb_free(Ind_Win *iwin);
8 static Eina_Bool _e_mod_ind_win_cb_win_prop(void *data, int type __UNUSED__, void *event);
9 static Eina_Bool _e_mod_ind_win_cb_zone_resize(void *data, int type __UNUSED__, void *event);
10 static void _e_mod_ind_win_cb_resize(E_Win *win);
11 static void _e_mod_ind_win_cb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event);
12 static void _e_mod_ind_win_cb_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event);
13 static void _e_mod_ind_win_cb_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event);
14 static void _e_mod_ind_win_cb_min_size_request(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h);
15 static void _e_mod_ind_win_cb_size_request(void *data __UNUSED__, E_Gadcon *gc __UNUSED__, Evas_Coord w __UNUSED__, Evas_Coord h __UNUSED__);
16 static Evas_Object *_e_mod_ind_win_cb_frame_request(void *data __UNUSED__, E_Gadcon_Client *gcc __UNUSED__, const char *style __UNUSED__);
17 static void _e_mod_ind_win_cb_menu_items_append(void *data, E_Gadcon_Client *gcc __UNUSED__, E_Menu *mn);
18 static void _e_mod_ind_win_cb_menu_append(Ind_Win *iwin, E_Menu *mn);
19 static void _e_mod_ind_win_cb_menu_pre(void *data, E_Menu *mn);
20 static void _e_mod_ind_win_cb_menu_post(void *data, E_Menu *mn __UNUSED__);
21 static void _e_mod_ind_win_cb_menu_contents(void *data, E_Menu *mn __UNUSED__, E_Menu_Item *mi __UNUSED__);
22 static void _e_mod_ind_win_cb_menu_edit(void *data, E_Menu *mn __UNUSED__, E_Menu_Item *mi __UNUSED__);
23 static Eina_Bool _e_mod_ind_win_cb_border_hide(void *data, int type __UNUSED__, void *event);
24 static Eina_Bool _e_mod_ind_win_cb_border_show(void *data, int type __UNUSED__, void *event);
25
26 Ind_Win *
27 e_mod_ind_win_new(E_Zone *zone) 
28 {
29    Ind_Win *iwin;
30    Ecore_X_Window_State states[2];
31    Evas_Coord h = 0;
32
33    /* create our new indicator window object */
34    iwin = E_OBJECT_ALLOC(Ind_Win, IND_WIN_TYPE, _e_mod_ind_win_cb_free);
35    if (!iwin) return NULL;
36
37    h = (il_ind_cfg->height * e_scale);
38    iwin->zone = zone;
39
40    /* create new window */
41    iwin->win = e_win_new(zone->container);
42    iwin->win->data = iwin;
43
44    /* set some properties on the window */
45    e_win_title_set(iwin->win, _("Illume Indicator"));
46    e_win_name_class_set(iwin->win, "Illume-Indicator", "Illume-Indicator");
47    e_win_no_remember_set(iwin->win, EINA_TRUE);
48
49    /* hook into window resize so we can resize our objects */
50    e_win_resize_callback_set(iwin->win, _e_mod_ind_win_cb_resize);
51
52    /* set this window to not show in taskbar or pager */
53    states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
54    states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
55    ecore_x_netwm_window_state_set(iwin->win->evas_win, states, 2);
56
57    /* set this window to not accept or take focus */
58    ecore_x_icccm_hints_set(iwin->win->evas_win, 0, 0, 0, 0, 0, 0, 0);
59
60    /* create the popup */
61    iwin->popup = e_popup_new(zone, 0, 0, zone->w, h);
62    e_popup_name_set(iwin->popup, "indicator");
63    e_popup_layer_set(iwin->popup, 200);
64
65    /* create our event rectangle */
66    iwin->o_event = evas_object_rectangle_add(iwin->win->evas);
67    evas_object_color_set(iwin->o_event, 0, 0, 0, 0);
68    evas_object_event_callback_add(iwin->o_event, EVAS_CALLBACK_MOUSE_DOWN, 
69                                   _e_mod_ind_win_cb_mouse_down, iwin);
70    evas_object_event_callback_add(iwin->o_event, EVAS_CALLBACK_MOUSE_UP, 
71                                   _e_mod_ind_win_cb_mouse_up, iwin);
72    evas_object_event_callback_add(iwin->o_event, EVAS_CALLBACK_MOUSE_MOVE, 
73                                   _e_mod_ind_win_cb_mouse_move, iwin);
74    evas_object_move(iwin->o_event, 0, 0);
75    evas_object_show(iwin->o_event);
76
77    /* create our base object */
78    iwin->o_base = edje_object_add(iwin->win->evas);
79    if (!e_theme_edje_object_set(iwin->o_base, 
80                                 "base/theme/modules/illume-indicator", 
81                                 "modules/illume-indicator/window")) 
82      {
83         char buff[PATH_MAX];
84
85         snprintf(buff, sizeof(buff), 
86                  "%s/e-module-illume-indicator.edj", _ind_mod_dir);
87         edje_object_file_set(iwin->o_base, buff, 
88                              "modules/illume-indicator/window");
89      }
90    evas_object_move(iwin->o_base, 0, 0);
91    evas_object_show(iwin->o_base);
92
93    e_popup_edje_bg_object_set(iwin->popup, iwin->o_base);
94
95    /* create our gadget container */
96    iwin->gadcon = e_gadcon_swallowed_new("illume-indicator", zone->id, 
97                                          iwin->o_base, "e.swallow.content");
98    edje_extern_object_min_size_set(iwin->gadcon->o_container, zone->w, h);
99    e_gadcon_min_size_request_callback_set(iwin->gadcon, 
100                                           _e_mod_ind_win_cb_min_size_request, 
101                                           iwin);
102    e_gadcon_size_request_callback_set(iwin->gadcon, 
103                                       _e_mod_ind_win_cb_size_request, iwin);
104    e_gadcon_frame_request_callback_set(iwin->gadcon, 
105                                        _e_mod_ind_win_cb_frame_request, iwin);
106    e_gadcon_orient(iwin->gadcon, E_GADCON_ORIENT_FLOAT);
107    e_gadcon_zone_set(iwin->gadcon, zone);
108    e_gadcon_ecore_evas_set(iwin->gadcon, iwin->win->ecore_evas);
109
110    e_gadcon_util_menu_attach_func_set(iwin->gadcon, 
111                                       _e_mod_ind_win_cb_menu_items_append, 
112                                       iwin);
113    e_gadcon_populate(iwin->gadcon);
114
115    /* hook into property change so we can adjust w/ e_scale */
116    iwin->hdls = 
117      eina_list_append(iwin->hdls, 
118                       ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, 
119                                               _e_mod_ind_win_cb_win_prop, iwin));
120
121    /* hook into zone resize so we can set minimum window width when zone 
122     * size changes */
123    iwin->hdls = 
124      eina_list_append(iwin->hdls, 
125                       ecore_event_handler_add(E_EVENT_ZONE_MOVE_RESIZE, 
126                                               _e_mod_ind_win_cb_zone_resize, 
127                                               iwin));
128
129    iwin->hdls = 
130      eina_list_append(iwin->hdls, 
131                       ecore_event_handler_add(E_EVENT_BORDER_HIDE, 
132                                               _e_mod_ind_win_cb_border_hide, 
133                                               iwin));
134
135    iwin->hdls = 
136      eina_list_append(iwin->hdls, 
137                       ecore_event_handler_add(E_EVENT_BORDER_SHOW, 
138                                               _e_mod_ind_win_cb_border_show, 
139                                               iwin));
140
141    /* set minimum size of this window & popup */
142    e_win_size_min_set(iwin->win, zone->w, h);
143    ecore_evas_size_min_set(iwin->popup->ecore_evas, zone->w, h);
144
145    /* position and resize this window */
146    e_win_move_resize(iwin->win, zone->x, zone->y, zone->w, h);
147    e_popup_move_resize(iwin->popup, zone->x, zone->y, zone->w, h);
148
149    /* show the window */
150    e_win_show(iwin->win);
151    e_popup_show(iwin->popup);
152
153    /* set this window on proper zone */
154    e_border_zone_set(iwin->win->border, zone);
155    iwin->win->border->user_skip_winlist = 1;
156
157    /* set this window to be a dock window. This needs to be done after show 
158     * as E will sometimes reset the window type */
159    ecore_x_netwm_window_type_set(iwin->win->evas_win, ECORE_X_WINDOW_TYPE_DOCK);
160
161    /* tell conformant apps our position and size */
162    ecore_x_e_illume_indicator_geometry_set(zone->black_win, zone->x, zone->y, 
163                                            zone->w, h);
164
165    return iwin;
166 }
167
168 /* local function prototypes */
169 static void 
170 _e_mod_ind_win_cb_free(Ind_Win *iwin) 
171 {
172    Ecore_Event_Handler *hdl;
173
174    /* delete the handlers */
175    EINA_LIST_FREE(iwin->hdls, hdl)
176      ecore_event_handler_del(hdl);
177
178    /* delete the menu */
179    if (iwin->menu) 
180      {
181         e_menu_post_deactivate_callback_set(iwin->menu, NULL, NULL);
182         e_object_del(E_OBJECT(iwin->menu));
183      }
184    iwin->menu = NULL;
185
186    /* delete the gadget container */
187    if (iwin->gadcon) e_object_del(E_OBJECT(iwin->gadcon));
188    iwin->gadcon = NULL;
189
190    /* delete the objects */
191    if (iwin->o_base) evas_object_del(iwin->o_base);
192    iwin->o_base = NULL;
193    if (iwin->o_event) evas_object_del(iwin->o_event);
194    iwin->o_event = NULL;
195
196    /* tell conformant apps our position and size */
197    ecore_x_e_illume_indicator_geometry_set(iwin->zone->black_win, 0, 0, 0, 0);
198
199    if (iwin->popup) e_object_del(E_OBJECT(iwin->popup));
200    iwin->popup = NULL;
201
202    /* delete the window */
203    if (iwin->win) e_object_del(E_OBJECT(iwin->win));
204    iwin->win = NULL;
205
206    /* free the allocated object */
207    E_FREE(iwin);
208 }
209
210 static Eina_Bool
211 _e_mod_ind_win_cb_win_prop(void *data, int type __UNUSED__, void *event) 
212 {
213    Ind_Win *iwin;
214    Ecore_X_Event_Window_Property *ev;
215    Evas_Coord h = 0;
216
217    ev = event;
218
219    if (!(iwin = data)) return ECORE_CALLBACK_PASS_ON;
220    if (ev->win != iwin->win->container->manager->root) 
221      return ECORE_CALLBACK_PASS_ON;
222    if (ev->atom != ATM_ENLIGHTENMENT_SCALE) return ECORE_CALLBACK_PASS_ON;
223
224    h = (il_ind_cfg->height * e_scale);
225
226    /* set minimum size of this window */
227    e_win_size_min_set(iwin->win, iwin->zone->w, h);
228    ecore_evas_size_min_set(iwin->popup->ecore_evas, iwin->zone->w, h);
229
230    /* NB: Not sure why, but we need to tell this border to fetch icccm 
231     * size position hints now :( (NOTE: This was not needed a few days ago) 
232     * If we do not do this, than indicator does not change w/ scale anymore */
233    iwin->win->border->client.icccm.fetch.size_pos_hints = 1;
234
235    /* resize this window */
236    e_win_resize(iwin->win, iwin->zone->w, h);
237    e_popup_resize(iwin->popup, iwin->zone->w, h);
238
239    /* tell conformant apps our position and size */
240    ecore_x_e_illume_indicator_geometry_set(iwin->zone->black_win, 
241                                            iwin->win->x, iwin->win->y, 
242                                            iwin->win->w, h);
243
244    return ECORE_CALLBACK_PASS_ON;
245 }
246
247 static Eina_Bool
248 _e_mod_ind_win_cb_zone_resize(void *data, int type __UNUSED__, void *event) 
249 {
250    Ind_Win *iwin;
251    E_Event_Zone_Move_Resize *ev;
252    Evas_Coord h = 0;
253
254    ev = event;
255    if (!(iwin = data)) return ECORE_CALLBACK_PASS_ON;
256    if (ev->zone != iwin->zone) return ECORE_CALLBACK_PASS_ON;
257
258    h = (il_ind_cfg->height * e_scale);
259
260    /* set minimum size of this window to match zone size */
261    e_win_size_min_set(iwin->win, ev->zone->w, h);
262    ecore_evas_size_min_set(iwin->popup->ecore_evas, ev->zone->w, h);
263
264    return ECORE_CALLBACK_PASS_ON;
265 }
266
267 static void 
268 _e_mod_ind_win_cb_resize(E_Win *win) 
269 {
270    Ind_Win *iwin;
271
272    if (!(iwin = win->data)) return;
273    if (iwin->popup) e_popup_resize(iwin->popup, win->w, win->h);
274    if (iwin->o_event) evas_object_resize(iwin->o_event, win->w, win->h);
275    if (iwin->o_base) evas_object_resize(iwin->o_base, win->w, win->h);
276    if (iwin->gadcon->o_container)
277      edje_extern_object_min_size_set(iwin->gadcon->o_container, 
278                                      win->w, win->h);
279 }
280
281 static void 
282 _e_mod_ind_win_cb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event) 
283 {
284    Ind_Win *iwin;
285    Evas_Event_Mouse_Down *ev;
286
287    ev = event;
288    if (!(iwin = data)) return;
289    if (ev->button == 1) 
290      {
291         iwin->mouse_down = 1;
292
293         /* make sure we can drag */
294         if (iwin->win->border->client.illume.drag.locked) return;
295
296         iwin->drag.start = 1;
297         iwin->drag.dnd = 0;
298         iwin->drag.y = ev->output.y;
299         iwin->drag.by = iwin->win->border->y;
300      }
301    else if (ev->button == 3) 
302      {
303         int x, y;
304
305         /* create our popup menu */
306         iwin->menu = e_menu_new();
307         e_menu_post_deactivate_callback_set(iwin->menu, 
308                                             _e_mod_ind_win_cb_menu_post, iwin);
309
310         /* append items to our menu */
311         _e_mod_ind_win_cb_menu_append(iwin, iwin->menu);
312
313         /* show menu */
314         e_gadcon_canvas_zone_geometry_get(iwin->gadcon, &x, &y, NULL, NULL);
315         e_menu_activate_mouse(iwin->menu, iwin->zone, x + ev->output.x, 
316                               y + ev->output.y, 1, 1, 
317                               E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
318      }
319 }
320
321 static void 
322 _e_mod_ind_win_cb_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event) 
323 {
324    Ind_Win *iwin;
325    Evas_Event_Mouse_Up *ev;
326
327    ev = event;
328    if (!(iwin = data)) return;
329
330    if (ev->button != 1) return;
331
332    /* if we are not dragging, send message to toggle quickpanel state */
333    if ((!iwin->drag.dnd) && (iwin->mouse_down == 1)) 
334      {
335         Ecore_X_Window xwin;
336
337         xwin = iwin->win->border->zone->black_win;
338         ecore_x_e_illume_quickpanel_state_toggle(xwin);
339      }
340    else if (iwin->drag.dnd) 
341      {
342         E_Border *bd;
343
344         bd = iwin->win->border;
345
346         /* reset mouse pointer */
347         if (bd->pointer) 
348           e_pointer_type_pop(bd->pointer, bd, "move");
349
350         /* tell edj we are done moving */
351         edje_object_signal_emit(iwin->o_base, "e,action,move,stop", "e");
352
353         /* send message that we are done dragging */
354         ecore_x_e_illume_drag_end_send(bd->client.win);
355
356         /* update quickpanel position if needed */
357         if (bd->y != iwin->drag.by) 
358           ecore_x_e_illume_quickpanel_position_update_send(bd->client.win);
359
360         /* tell conformant apps our position and size */
361         ecore_x_e_illume_indicator_geometry_set(iwin->zone->black_win, 
362                                                 bd->x, bd->y, 
363                                                 bd->w, bd->h);
364      }
365    iwin->drag.start = 0;
366    iwin->drag.dnd = 0;
367    iwin->drag.y = 0;
368    iwin->drag.by = 0;
369    iwin->mouse_down = 0;
370 }
371
372 static void 
373 _e_mod_ind_win_cb_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event) 
374 {
375    Ind_Win *iwin;
376    Evas_Event_Mouse_Move *ev;
377    E_Border *bd;
378
379    ev = event;
380    if (!(iwin = data)) return;
381    bd = iwin->win->border;
382    if (iwin->drag.start) 
383      {
384         iwin->drag.dnd = 1;
385         iwin->drag.start = 0;
386
387         /* change mouse pointer to indicate we are dragging */
388         if (iwin->win->border->pointer) 
389           e_pointer_type_push(iwin->win->border->pointer, 
390                               iwin->win->border, "move");
391
392         /* tell edj we are going to start moving */
393         edje_object_signal_emit(iwin->o_base, "e,action,move,start", "e");
394
395         /* tell quickpanel to hide because we are going to drag */
396         ecore_x_e_illume_quickpanel_state_send(bd->zone->black_win, 
397                                               ECORE_X_ILLUME_QUICKPANEL_STATE_OFF);
398
399         /* send message that we are going to start dragging */
400         ecore_x_e_illume_drag_start_send(bd->client.win);
401      }
402
403    /* make sure we are dragging */
404    if (iwin->drag.dnd) 
405      {
406         int dy, py, ny;
407
408         /* get current mouse position */
409         py = ev->cur.output.y;
410
411         /* do moves in 'chunks' of screen size */
412         dy = ((bd->zone->h - bd->h) / 8);
413
414         /* are we moving up or down ? */
415         if (ev->cur.output.y > ev->prev.output.y) 
416           {
417              /* moving down */
418              if ((py - iwin->drag.y) < dy) return;
419           }
420         else if (ev->cur.output.y < ev->prev.output.y) 
421           {
422              /* moving up */
423              if ((iwin->drag.y - py) < dy) return;
424           }
425         else return;
426
427         if (py > iwin->drag.y) 
428           ny = bd->y + dy;
429         else if (py < iwin->drag.y) 
430           ny = bd->y - dy;
431         else return;
432
433         /* make sure we don't drag off the screen */
434         if (ny < iwin->zone->y) 
435           ny = iwin->zone->y;
436         else if ((ny + bd->h) > (iwin->zone->y + iwin->zone->h)) 
437           return;
438
439         /* move the border if we need to */
440         if (bd->y != ny) 
441           {
442              bd->y = ny;
443              bd->changes.pos = 1;
444              bd->changed = 1;
445              e_popup_move(iwin->popup, iwin->popup->x, ny);
446           }
447      }
448 }
449
450 static void 
451 _e_mod_ind_win_cb_min_size_request(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h) 
452 {
453    Ind_Win *iwin;
454
455    if (!(iwin = data)) return;
456    if (gc != iwin->gadcon) return;
457    if (h < iwin->win->h) h = iwin->win->h;
458    edje_extern_object_min_size_set(iwin->gadcon->o_container, w, h);
459 }
460
461 static void 
462 _e_mod_ind_win_cb_size_request(void *data __UNUSED__, E_Gadcon *gc __UNUSED__, Evas_Coord w __UNUSED__, Evas_Coord h __UNUSED__) 
463 {
464    return;
465 }
466
467 static Evas_Object *
468 _e_mod_ind_win_cb_frame_request(void *data __UNUSED__, E_Gadcon_Client *gcc __UNUSED__, const char *style __UNUSED__) 
469 {
470    return NULL;
471 }
472
473 static void 
474 _e_mod_ind_win_cb_menu_items_append(void *data, E_Gadcon_Client *gcc __UNUSED__, E_Menu *mn) 
475 {
476    Ind_Win *iwin;
477
478    if (!(iwin = data)) return;
479    _e_mod_ind_win_cb_menu_append(iwin, mn);
480 }
481
482 static void 
483 _e_mod_ind_win_cb_menu_append(Ind_Win *iwin, E_Menu *mn) 
484 {
485    E_Menu *subm;
486    E_Menu_Item *mi;
487    char buff[PATH_MAX];
488
489    snprintf(buff, sizeof(buff), 
490             "%s/e-module-illume-indicator.edj", _ind_mod_dir);
491
492    subm = e_menu_new();
493    mi = e_menu_item_new(mn);
494    e_menu_item_label_set(mi, _("Illume Indicator"));
495    e_menu_item_icon_edje_set(mi, buff, "icon");
496    e_menu_pre_activate_callback_set(subm, _e_mod_ind_win_cb_menu_pre, iwin);
497    e_menu_item_submenu_set(mi, subm);
498 }
499
500 static void 
501 _e_mod_ind_win_cb_menu_pre(void *data, E_Menu *mn) 
502 {
503    Ind_Win *iwin;
504    E_Menu_Item *mi;
505
506    if (!(iwin = data)) return;
507    e_menu_pre_activate_callback_set(mn, NULL, NULL);
508
509    mi = e_menu_item_new(mn);
510    e_menu_item_label_set(mi, _("Set Contents"));
511    e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf");
512    e_menu_item_callback_set(mi, _e_mod_ind_win_cb_menu_contents, iwin);
513
514    mi = e_menu_item_new(mn);
515    if (iwin->gadcon->editing) 
516      e_menu_item_label_set(mi, _("End Move/Resize Items"));
517    else
518      e_menu_item_label_set(mi, _("Begin Move/Resize Items"));
519
520    e_util_menu_item_theme_icon_set(mi, "transform-scale");
521    e_menu_item_callback_set(mi, _e_mod_ind_win_cb_menu_edit, iwin);
522 }
523
524 static void 
525 _e_mod_ind_win_cb_menu_post(void *data, E_Menu *mn __UNUSED__) 
526 {
527    Ind_Win *iwin;
528
529    if (!(iwin = data)) return;
530    if (!iwin->menu) return;
531    e_object_del(E_OBJECT(iwin->menu));
532    iwin->menu = NULL;
533 }
534
535 static void 
536 _e_mod_ind_win_cb_menu_contents(void *data, E_Menu *mn __UNUSED__, E_Menu_Item *mi __UNUSED__) 
537 {
538    Ind_Win *iwin;
539
540    if (!(iwin = data)) return;
541    if (!iwin->gadcon->config_dialog) 
542      e_int_gadcon_config_shelf(iwin->gadcon);
543    else 
544      {
545         e_win_show(iwin->gadcon->config_dialog->dia->win);
546         e_win_raise(iwin->gadcon->config_dialog->dia->win);
547      }
548 }
549
550 static void 
551 _e_mod_ind_win_cb_menu_edit(void *data, E_Menu *mn __UNUSED__, E_Menu_Item *mi __UNUSED__) 
552 {
553    Ind_Win *iwin;
554
555    if (!(iwin = data)) return;
556    if (iwin->gadcon->editing) 
557      e_gadcon_edit_end(iwin->gadcon);
558    else
559      e_gadcon_edit_begin(iwin->gadcon);
560 }
561
562 static Eina_Bool 
563 _e_mod_ind_win_cb_border_hide(void *data, int type __UNUSED__, void *event) 
564 {
565    Ind_Win *iwin;
566    E_Event_Border_Hide *ev;
567
568    if (!(iwin = data)) return ECORE_CALLBACK_PASS_ON;
569    ev = event;
570    if (ev->border != iwin->win->border) return ECORE_CALLBACK_PASS_ON;
571    e_popup_hide(iwin->popup);
572    return ECORE_CALLBACK_PASS_ON;
573 }
574
575 static Eina_Bool 
576 _e_mod_ind_win_cb_border_show(void *data, int type __UNUSED__, void *event) 
577 {
578    Ind_Win *iwin;
579    E_Event_Border_Show *ev;
580
581    if (!(iwin = data)) return ECORE_CALLBACK_PASS_ON;
582    ev = event;
583    if (ev->border != iwin->win->border) return ECORE_CALLBACK_PASS_ON;
584    e_popup_show(iwin->popup);
585    return ECORE_CALLBACK_PASS_ON;
586 }