3e6d4c2e19e64771bf83183d41f70c45a11b4eff
[platform/core/uifw/e17-extra-modules.git] / move-tizen / src / e_mod_move_mini_apptray_widget.c
1 #include "e_mod_move_shared_types.h"
2 #include "e_mod_move_debug.h"
3 #include "e_mod_move.h"
4
5 /* local subsystem functions */
6 static Eina_Bool      _e_mod_move_mini_apptray_widget_mini_apptray_move_set(E_Move_Mini_Apptray_Widget *mini_apptray_widget, Eina_Bool state);
7 static Eina_Bool      _e_mod_move_mini_apptray_widget_mini_apptray_move_get(E_Move_Mini_Apptray_Widget *mini_apptray_widget);
8 static Eina_Bool      _e_mod_move_mini_apptray_widget_cb_motion_start_internal_mini_apptray_check(E_Move_Border *mini_apptray_mb);
9 static Eina_Bool      _e_mod_move_mini_apptray_widget_mini_apptray_flick_process(E_Move_Mini_Apptray_Widget *mini_apptray_widget, E_Move_Border *mb2, int angle, Eina_Bool state);
10 static Eina_Bool      _e_mod_move_mini_apptray_widget_cb_motion_start(void *data, void *event_info);
11 static Eina_Bool      _e_mod_move_mini_apptray_widget_cb_motion_move(void *data, void *event_info);
12 static Eina_Bool      _e_mod_move_mini_apptray_widget_cb_motion_end(void *data, void *event_info);
13 static Ecore_X_Window _e_mod_move_mini_apptray_event_win_find(void *event_info);
14 static void           _e_mod_move_mini_apptray_widget_obj_event_setup(E_Move_Mini_Apptray_Widget *mini_apptray_widget, E_Move_Widget_Object *mwo);
15 static Eina_Bool      _e_mod_move_mini_apptray_widget_event_send_policy_check(E_Move_Mini_Apptray_Widget *mini_apptray_widget, Evas_Point pos);
16
17 /* local subsystem functions */
18 static Eina_Bool
19 _e_mod_move_mini_apptray_widget_mini_apptray_move_set(E_Move_Mini_Apptray_Widget *mini_apptray_widget,
20                                                       Eina_Bool                   state)
21 {
22    E_CHECK_RETURN(mini_apptray_widget, EINA_FALSE);
23    mini_apptray_widget->mini_apptray_move = state;
24    return EINA_TRUE;
25 }
26
27 static Eina_Bool
28 _e_mod_move_mini_apptray_widget_mini_apptray_move_get(E_Move_Mini_Apptray_Widget *mini_apptray_widget)
29 {
30    E_CHECK_RETURN(mini_apptray_widget, EINA_FALSE);
31    return mini_apptray_widget->mini_apptray_move;
32 }
33
34 static Eina_Bool
35 _e_mod_move_mini_apptray_widget_cb_motion_start_internal_mini_apptray_check(E_Move_Border *mini_apptray_mb)
36 {
37    E_Move        *m;
38    E_Move_Border *find_mb = NULL;
39    Eina_Bool      found = EINA_FALSE;
40    m = e_mod_move_util_get();
41
42    E_CHECK_RETURN(m, EINA_FALSE);
43    E_CHECK_RETURN(mini_apptray_mb, EINA_FALSE);
44    E_CHECK_RETURN(TYPE_MINI_APPTRAY_CHECK(mini_apptray_mb), EINA_FALSE);
45    E_CHECK_RETURN(mini_apptray_mb->visible, EINA_FALSE);
46    E_CHECK_RETURN(e_mod_move_util_compositor_object_visible_get(mini_apptray_mb),
47                   EINA_FALSE);
48    if (e_mod_move_mini_apptray_objs_animation_state_get(mini_apptray_mb)) return EINA_FALSE;
49
50    // Mini app-tray is under rotation state.
51    // I think there is another exception case.
52    // It's posible that WM doesn't send rotation change request yet.
53    // In this case the value of wait_for_done is zero,
54    // it means quickpanel isn't rotating for now, but going to be rotated.
55    if (mini_apptray_mb->bd)
56      if (mini_apptray_mb->bd->client.e.state.rot.wait_for_done) return EINA_FALSE;
57
58    // check if notification window is on-screen.
59    EINA_INLIST_REVERSE_FOREACH(m->borders, find_mb)
60      {
61         if (TYPE_INDICATOR_CHECK(find_mb)) continue;
62         if ((find_mb->visible) &&
63             (mini_apptray_mb->bd) &&
64             (REGION_INTERSECTS_WITH_ZONE(find_mb, mini_apptray_mb->bd->zone)))
65           {
66               found = EINA_TRUE;
67               break;
68           }
69      }
70
71    if (found
72         && (find_mb->bd->client.netwm.type == ECORE_X_WINDOW_TYPE_NOTIFICATION)
73         && REGION_EQUAL_TO_ZONE(find_mb, find_mb->bd->zone))
74      {
75         return EINA_FALSE;
76      }
77    // check if notification window is on-screen.
78
79    e_mod_move_mini_apptray_dim_show(mini_apptray_mb);
80
81    if (REGION_INSIDE_ZONE(mini_apptray_mb, mini_apptray_mb->bd->zone))
82      e_mod_move_mini_apptray_objs_add_with_pos(mini_apptray_mb, -10000, -10000);
83    else
84      e_mod_move_mini_apptray_objs_add(mini_apptray_mb);
85
86    return EINA_TRUE;
87 }
88
89 static Eina_Bool
90 _e_mod_move_mini_apptray_widget_mini_apptray_flick_process(E_Move_Mini_Apptray_Widget *mini_apptray_widget,
91                                                            E_Move_Border              *mb2, // mb2 : mini_apptray
92                                                            int                         angle,
93                                                            Eina_Bool                   state)
94 {
95    E_Move_Border            *mb = NULL;
96    E_Move_Widget_Object     *mwo = NULL;
97    Eina_List                *l;
98    E_Zone                   *zone = NULL;
99    int x = 0;
100    int y = 0;
101
102    E_CHECK_RETURN(mini_apptray_widget, EINA_FALSE);
103    mb = e_mod_move_border_client_find(mini_apptray_widget->win);
104    E_CHECK_RETURN(mb, EINA_FALSE);
105    E_CHECK_RETURN(mb2, EINA_FALSE);
106    E_CHECK_RETURN(TYPE_MINI_APPTRAY_CHECK(mb2), EINA_FALSE);
107    E_CHECK_RETURN(state, EINA_FALSE);
108
109    zone = mb->bd->zone;
110
111    EINA_LIST_FOREACH(mini_apptray_widget->objs, l, mwo) // widget click unset
112      {
113         if (!mwo) continue;
114         e_mod_move_event_click_set(mwo->event, EINA_FALSE);
115      }
116
117    _e_mod_move_mini_apptray_widget_mini_apptray_move_set(mini_apptray_widget, EINA_FALSE);
118
119    // flick data free
120    if (mb->flick_data) e_mod_move_flick_data_free(mb);
121
122    switch (angle)
123      {
124       case  90:
125          x = zone->w - mb2->w;
126          y = 0;
127          break;
128       case 180:
129          x = 0;
130          y = 0;
131          break;
132       case 270:
133          x = 0;
134          y = 0;
135          break;
136       case   0:
137       default :
138          x = 0;
139          y = zone->h - mb2->h;
140          break;
141      }
142
143    e_mod_move_mini_apptray_e_border_move(mb2, x, y);
144    e_mod_move_mini_apptray_objs_animation_move(mb2, x, y);
145
146    return EINA_TRUE;
147 }
148
149 static Eina_Bool
150 _e_mod_move_mini_apptray_widget_cb_motion_start(void *data,
151                                                 void *event_info)
152 {
153    E_Move *m = NULL;
154    E_Move_Mini_Apptray_Widget *mini_apptray_widget = (E_Move_Mini_Apptray_Widget *)data;
155
156    E_Move_Border *mb = NULL;
157    E_Move_Border *mini_apptray_mb = NULL;
158    E_Move_Event_Motion_Info *info;
159    E_Move_Widget_Object *mwo = NULL;
160    Evas_Event_Mouse_Down *mouse_down_event = NULL;
161    Eina_Bool clicked = EINA_FALSE;
162    Eina_List *l;
163    E_Move_Border *ev_mb = NULL;
164    Ecore_X_Window ev_win = 0;
165
166    info  = (E_Move_Event_Motion_Info *)event_info;
167    m = e_mod_move_util_get();
168
169    E_CHECK_RETURN(mini_apptray_widget, EINA_FALSE);
170
171    // clicked window indicator policy check
172    EINA_LIST_FOREACH(mini_apptray_widget->objs, l, mwo)
173      {
174         if (!mwo) continue;
175         ev_win = e_mod_move_event_win_get(mwo->event);
176      }
177    ev_mb = e_mod_move_border_client_find(ev_win);
178    // Check Mini Apptray State ( property )
179    if ((ev_mb)
180         && (ev_mb->mini_apptray_state == E_MOVE_MINI_APPTRAY_STATE_OFF))
181      return EINA_FALSE;
182
183    mb = e_mod_move_border_client_find(mini_apptray_widget->win);
184    if (!m || !mb || !mini_apptray_widget || !info) return EINA_FALSE;
185
186    mouse_down_event = info->event_info;
187    E_CHECK_RETURN(mouse_down_event, EINA_FALSE);
188    if (mouse_down_event->button != 1)
189      return EINA_FALSE;
190
191    EINA_LIST_FOREACH(mini_apptray_widget->objs, l, mwo)
192      {
193         if (!mwo) continue;
194         clicked = e_mod_move_event_click_get(mwo->event);
195      }
196    if (clicked)
197      return EINA_FALSE;
198
199    SL(LT_EVENT_OBJ,
200       "[MOVE] ev:%15.15s w:0x%08x MINI_APPTRAY_WIDGET_MOTION_START (%4d,%4d)\n",
201       "EVAS_OBJ", mb->bd->win,
202       info->coord.x, info->coord.y);
203
204    _e_mod_move_mini_apptray_widget_mini_apptray_move_set(mini_apptray_widget, EINA_FALSE);
205
206    /* check if apptray exists on the current zone */
207    mini_apptray_mb = e_mod_move_mini_apptray_find();
208    if ((mini_apptray_mb) &&
209        (mini_apptray_mb->visibility == E_MOVE_VISIBILITY_STATE_VISIBLE))
210      {
211         L(LT_EVENT_OBJ,
212           "[MOVE] ev:%15.15s w:0x%08x MINI_APPTRAY_WIDGET_MOTION_START %s\n",
213           "EVAS_OBJ", mb->bd->win,
214           "mini_apptray exists. return.");
215         return EINA_FALSE;
216      }
217
218    if ((mini_apptray_mb) &&
219        (REGION_INSIDE_ZONE(mini_apptray_mb, mb->bd->zone)))
220      {
221         e_mod_move_mini_apptray_e_border_move(mini_apptray_mb, -10000, -10000);
222      }
223
224    EINA_LIST_FOREACH(mini_apptray_widget->objs, l, mwo)
225      {
226         if (!mwo) continue;
227         e_mod_move_event_click_set(mwo->event, EINA_TRUE);
228      }
229
230    E_CHECK_GOTO(e_mod_move_flick_data_new(mb), error_cleanup);
231    e_mod_move_flick_data_init(mb, info->coord.x, info->coord.y);
232
233    if (!_e_mod_move_mini_apptray_widget_cb_motion_start_internal_mini_apptray_check(mini_apptray_mb))
234      {
235         goto error_cleanup;
236      }
237
238    //e_mod_move_mini_apptray_e_border_raise(mini_apptray_mb);
239    _e_mod_move_mini_apptray_widget_mini_apptray_move_set(mini_apptray_widget, EINA_TRUE);
240    e_mod_move_mini_apptray_objs_animation_start_position_set(mini_apptray_mb,
241                                                              mb->angle);
242    // send mini_apptray to "move start message".
243    e_mod_move_mini_apptray_anim_state_send(mini_apptray_mb, EINA_TRUE);
244
245    mini_apptray_widget->pos = info->coord; // save mouse click position
246
247    return EINA_TRUE;
248
249 error_cleanup:
250
251    EINA_LIST_FOREACH(mini_apptray_widget->objs, l, mwo)
252      {
253         if (!mwo) continue;
254         e_mod_move_event_click_set(mwo->event, EINA_FALSE);
255      }
256
257    _e_mod_move_mini_apptray_widget_mini_apptray_move_set(mini_apptray_widget, EINA_FALSE);
258
259    return EINA_FALSE;
260
261 }
262
263 static Eina_Bool
264 _e_mod_move_mini_apptray_widget_cb_motion_move(void *data,
265                                                void *event_info)
266 {
267    E_Move                      *m = NULL;
268    E_Move_Mini_Apptray_Widget  *mini_apptray_widget = (E_Move_Mini_Apptray_Widget *)data;
269    E_Move_Border               *mb = NULL;
270    E_Move_Event_Motion_Info    *info;
271    E_Move_Widget_Object        *mwo = NULL;
272    E_Zone                      *zone = NULL;
273    Eina_List                   *l;
274    Eina_Bool                    click = EINA_FALSE;
275    int                          angle;
276    Eina_Bool                    flick_state = EINA_FALSE;
277    E_Move_Border               *mini_apptray_mb = NULL;
278
279    info  = (E_Move_Event_Motion_Info *)event_info;
280    m = e_mod_move_util_get();
281
282    E_CHECK_RETURN(mini_apptray_widget, EINA_FALSE);
283    mb = e_mod_move_border_client_find(mini_apptray_widget->win);
284
285    if (!m || !mb || !info) return EINA_FALSE;
286
287    SL(LT_EVENT_OBJ,
288       "[MOVE] ev:%15.15s w:0x%08x MINI_APPTRAY_WIDGET_MOTION_MOVE a:%d (%4d,%4d)\n",
289       "EVAS_OBJ", mb->bd->win, mb->angle,
290       info->coord.x, info->coord.y);
291
292    angle = mb->angle;
293    zone = mb->bd->zone;
294
295    EINA_LIST_FOREACH(mini_apptray_widget->objs, l, mwo)
296      {
297         if (!mwo) continue;
298         click = e_mod_move_event_click_get(mwo->event);
299      }
300    E_CHECK_RETURN(click, EINA_FALSE);
301
302    // do not work on moving just work on flick action
303    e_mod_move_flick_data_update(mb, info->coord.x, info->coord.y);
304    flick_state = e_mod_move_flick_state_get2(mb);
305
306    if (_e_mod_move_mini_apptray_widget_mini_apptray_move_get(mini_apptray_widget))
307      {
308         mini_apptray_mb = e_mod_move_mini_apptray_find();
309
310         if (_e_mod_move_mini_apptray_widget_mini_apptray_flick_process(mini_apptray_widget,
311                                                                        mini_apptray_mb,
312                                                                        angle, flick_state))
313           {
314              return EINA_TRUE;
315           }
316      }
317
318 #if 0
319    if (_e_mod_move_mini_apptray_widget_mini_apptray_move_get(mini_apptray_widget))
320      {
321         mini_apptray_mb = e_mod_move_mini_apptray_find();
322         E_CHECK_RETURN(mini_apptray_mb, EINA_FALSE);
323 // change later for flick_up
324 // todo flick up geometry
325         switch (angle)
326           {
327            case   0:
328               if (info->coord.y > (zone->h - mini_apptray_mb->h))
329                 {
330                    y = info->coord.y;
331                    need_move = EINA_TRUE;
332                 }
333               break;
334            case  90:
335               if (info->coord.x > (zone->w - mini_apptray_mb->w))
336                 {
337                    x = info->coord.x;
338                    need_move = EINA_TRUE;
339                 }
340               break;
341            case 180:
342               if (info->coord.y < mini_apptray_mb->h)
343                 {
344                    y = info->coord.y - mini_apptray_mb->h;
345                    need_move = EINA_TRUE;
346                 }
347               break;
348            case 270:
349               if (info->coord.x < mini_apptray_mb->w)
350                 {
351                    x = info->coord.x - mini_apptray_mb->w;
352                    need_move = EINA_TRUE;
353                 }
354               break;
355            default :
356               break;
357           }
358         if (need_move)
359           e_mod_move_mini_apptray_objs_move(mini_apptray_mb, x, y);
360      }
361
362    mini_apptray_widget->pos = info->coord; // save mouse move position
363 #endif
364
365    return EINA_TRUE;
366 }
367
368 static Eina_Bool
369 _e_mod_move_mini_apptray_widget_cb_motion_end(void *data,
370                                               void *event_info)
371 {
372    E_Move                      *m = NULL;
373    E_Move_Mini_Apptray_Widget  *mini_apptray_widget = (E_Move_Mini_Apptray_Widget *)data;
374    E_Move_Border               *mb = NULL;
375    E_Move_Border               *mini_apptray_mb = NULL;
376    E_Move_Event_Motion_Info    *info;
377    E_Move_Widget_Object        *mwo = NULL;
378    Eina_List                   *l;
379    E_Zone                      *zone;
380    Evas_Event_Mouse_Up         *mouse_up_event;
381    Eina_Bool                    click = EINA_FALSE;
382    Eina_Bool                    flick_state = EINA_FALSE;
383    int                          angle = 0;
384    Ecore_X_Window               ev_win = 0;
385
386    info  = (E_Move_Event_Motion_Info *)event_info;
387    m = e_mod_move_util_get();
388
389    E_CHECK_RETURN(mini_apptray_widget, EINA_FALSE);
390    mb = e_mod_move_border_client_find(mini_apptray_widget->win);
391
392    if (!m || !mb || !info) return EINA_FALSE;
393
394    mouse_up_event = info->event_info;
395    E_CHECK_RETURN(mouse_up_event, EINA_FALSE);
396    if (mouse_up_event->button != 1)
397      return EINA_FALSE;
398
399    SL(LT_EVENT_OBJ,
400       "[MOVE] ev:%15.15s w:0x%08x ,angle:%d, (%d,%d)  %s()\n",
401       "EVAS_OBJ", mb->bd->win, mb->angle, info->coord.x, info->coord.y,
402       __func__);
403
404    angle = mb->angle;
405    zone = mb->bd->zone;
406
407    EINA_LIST_FOREACH(mini_apptray_widget->objs, l, mwo)
408      {
409         if (!mwo) continue;
410         click = e_mod_move_event_click_get(mwo->event);
411      }
412    E_CHECK_GOTO(click, error_cleanup);
413
414    e_mod_move_flick_data_update(mb, info->coord.x, info->coord.y);
415    flick_state = e_mod_move_flick_state_get2(mb);
416
417    if (_e_mod_move_mini_apptray_widget_mini_apptray_move_get(mini_apptray_widget))
418      {
419         mini_apptray_mb = e_mod_move_mini_apptray_find();
420
421         if (_e_mod_move_mini_apptray_widget_mini_apptray_flick_process(mini_apptray_widget,
422                                                                        mini_apptray_mb,
423                                                                        angle, flick_state))
424           {
425              return EINA_TRUE;
426           }
427         else
428           {
429              // if mini_apptray animation is not called, must destory datas explicit
430              if (mini_apptray_mb)
431                {
432                   e_border_focus_set(mini_apptray_mb ->bd, 0, 0);
433                   e_mod_move_mini_apptray_dim_hide(mini_apptray_mb );
434                   e_mod_move_mini_apptray_objs_del(mini_apptray_mb );
435                }
436           }
437      }
438 // just work on flick action. so. currently block.
439 #if 0
440    mx = zone->x;
441    my = zone->y;
442    ax = mx;
443    ay = my;
444    switch (angle)
445      {
446       case   0:
447          if (mini_apptray_mb)
448            {
449               check_h = mini_apptray_mb->h;
450               if (check_h) check_h /= 2;
451               if (info->coord.y > (zone->h - check_h))
452                 {
453                    my = zone->h;
454                    ay = my;
455                 }
456                else
457                 {
458                    my = zone->h - mini_apptray_mb->h;
459                    ay = my;
460                 }
461            }
462          break;
463       case  90:
464          if (mini_apptray_mb)
465            {
466               check_w = mini_apptray_mb->w;
467               if (check_w) check_w /= 2;
468               if (info->coord.x > (zone->w - check_w))
469                 {
470                    mx = zone->w;
471                    ax = mx;
472                 }
473                else
474                 {
475                    mx = zone->w - mini_apptray_mb->w;
476                    ax = mx;
477                 }
478            }
479          break;
480       case 180:
481          if (mini_apptray_mb)
482            {
483               check_h = mini_apptray_mb->h;
484               if (check_h) check_h /= 2;
485               if (info->coord.y < check_h)
486                 {
487                    my = mini_apptray_mb->h * -1;
488                    ay = my;
489                 }
490            }
491          break;
492       case 270:
493          if (mini_apptray_mb)
494            {
495               check_w = mini_apptray_mb->w;
496               if (check_w) check_w /= 2;
497               if (info->coord.x < check_w)
498                 {
499                    mx = mini_apptray_mb->w * -1;
500                    ax = mx;
501                 }
502            }
503          break;
504       default :
505          break;
506      }
507
508    if (mini_apptray_mb)
509      {
510         e_mod_move_mini_apptray_e_border_move(mini_apptray_mb, mx, my);
511         e_mod_move_mini_apptray_objs_animation_move(mini_apptray_mb, ax, ay);
512      }
513 #endif
514
515    // if flick check fail then, redirect event
516    EINA_LIST_FOREACH(mini_apptray_widget->objs, l, mwo)
517      {
518         if (!mwo) continue;
519         ev_win = e_mod_move_event_win_get(mwo->event);
520      }
521
522    if (ev_win)
523      {
524         e_mod_move_mouse_event_send(ev_win, E_MOVE_MOUSE_EVENT_MOVE, mini_apptray_widget->pos);
525         e_mod_move_mouse_event_send(ev_win, E_MOVE_MOUSE_EVENT_DOWN, mini_apptray_widget->pos);
526         e_mod_move_mouse_event_send(ev_win, E_MOVE_MOUSE_EVENT_MOVE, info->coord);
527         e_mod_move_mouse_event_send(ev_win, E_MOVE_MOUSE_EVENT_UP, info->coord);
528      }
529
530    mini_apptray_widget->pos = info->coord; // save mouse up position
531
532    EINA_LIST_FOREACH(mini_apptray_widget->objs, l, mwo)
533      {
534         if (!mwo) continue;
535         e_mod_move_event_click_set(mwo->event, EINA_FALSE);
536      }
537
538 error_cleanup:
539    if (mb->flick_data) e_mod_move_flick_data_free(mb);
540    _e_mod_move_mini_apptray_widget_mini_apptray_move_set(mini_apptray_widget, EINA_FALSE);
541
542    return EINA_TRUE;
543 }
544
545 static Ecore_X_Window
546 _e_mod_move_mini_apptray_event_win_find(void *event_info)
547 {
548    E_Move_Event_Motion_Info *info = NULL;
549    E_Border                 *find_bd = NULL;
550    Ecore_X_Window            win = 0;
551    info  = (E_Move_Event_Motion_Info *)event_info;
552
553    E_CHECK_RETURN(info, 0);
554
555    find_bd = e_mod_move_util_border_find_by_pointer(info->coord.x, info->coord.y);
556
557    if (find_bd) win = find_bd->client.win;
558    else win = 0;
559
560    SL(LT_EVENT_OBJ,
561       "[MOVE] ev:%15.15s MINI_APPTRAY_EVENT_WIN_FIND w:0x%08x (%4d,%4d)\n",
562       "EVAS_OBJ", win, info->coord.x, info->coord.y);
563
564    return win;
565 }
566
567 static void
568 _e_mod_move_mini_apptray_widget_obj_event_setup(E_Move_Mini_Apptray_Widget *mini_apptray_widget,
569                                                 E_Move_Widget_Object    *mwo)
570 {
571    E_CHECK(mini_apptray_widget);
572    E_CHECK(mwo);
573
574    mwo->event = e_mod_move_event_new(mini_apptray_widget->win, mwo->obj);
575    E_CHECK(mwo->event);
576
577    // change later ... below function used for just log
578    e_mod_move_event_data_type_set(mwo->event, E_MOVE_EVENT_DATA_TYPE_WIDGET_INDICATOR);
579
580    e_mod_move_event_angle_cb_set(mwo->event,
581                                  e_mod_move_util_win_prop_angle_get);
582    e_mod_move_event_cb_set(mwo->event, E_MOVE_EVENT_TYPE_MOTION_START,
583                            _e_mod_move_mini_apptray_widget_cb_motion_start,
584                            mini_apptray_widget);
585    e_mod_move_event_cb_set(mwo->event, E_MOVE_EVENT_TYPE_MOTION_MOVE,
586                            _e_mod_move_mini_apptray_widget_cb_motion_move,
587                            mini_apptray_widget);
588    e_mod_move_event_cb_set(mwo->event, E_MOVE_EVENT_TYPE_MOTION_END,
589                            _e_mod_move_mini_apptray_widget_cb_motion_end,
590                            mini_apptray_widget);
591    e_mod_move_event_propagate_type_set(mwo->event,
592                                        E_MOVE_EVENT_PROPAGATE_TYPE_NONE);
593    e_mod_move_event_win_find_cb_set(mwo->event,
594                                     _e_mod_move_mini_apptray_event_win_find);
595 }
596
597 static Eina_Bool
598 _e_mod_move_mini_apptray_widget_event_send_policy_check(E_Move_Mini_Apptray_Widget *mini_apptray_widget,
599                                                         Evas_Point                  pos)
600 {
601    int x = 0, y = 0, w = 0, h = 0;
602    Eina_Bool ret = EINA_FALSE;
603
604    E_CHECK_RETURN(mini_apptray_widget, EINA_FALSE);
605
606    e_mod_move_widget_objs_geometry_get(mini_apptray_widget->objs, &x ,&y, &w, &h);
607
608    if (E_INSIDE(pos.x, pos.y, x, y, w, h)) ret = EINA_TRUE;
609
610    return ret;
611 }
612
613 /* externally accessible functions */
614
615 /* set current mini apptray widget */
616 EINTERN void
617 e_mod_move_mini_apptray_widget_set(E_Move_Mini_Apptray_Widget *mini_apptray_widget)
618 {
619    E_Move *m = NULL;
620
621    m = e_mod_move_util_get();
622    E_CHECK(m);
623
624    if (m->mini_apptray_widget)
625      {
626         e_mod_move_mini_apptray_widget_del(m->mini_apptray_widget);
627      }
628
629    m->mini_apptray_widget = mini_apptray_widget;
630 }
631
632 /* get current mini_apptray widget */
633 EINTERN E_Move_Mini_Apptray_Widget *
634 e_mod_move_mini_apptray_widget_get(void)
635 {
636    E_Move *m = NULL;
637    m = e_mod_move_util_get();
638    E_CHECK_RETURN(m, NULL);
639
640    return m->mini_apptray_widget;
641 }
642
643 /* find mini_apptray widget target window */
644 // must update/change this function ( for mini_apptray policy )
645 EINTERN Eina_Bool
646 e_mod_move_mini_apptray_widget_target_window_find(Ecore_X_Window *win)
647 {
648    E_Move        *m = NULL;
649    E_Move_Border *find_mb = NULL;
650    Eina_Bool      found = EINA_FALSE;
651    E_Zone        *zone = NULL;
652    Eina_Bool      ret = EINA_FALSE;
653
654    E_CHECK_RETURN(win, EINA_FALSE);
655    m = e_mod_move_util_get();
656    E_CHECK_RETURN(m, EINA_FALSE);
657
658    // fix later
659    EINA_INLIST_REVERSE_FOREACH(m->borders, find_mb)
660      {
661         if (!find_mb->bd) continue;
662         // the first OnScreen & FullScreen Window
663         zone = find_mb->bd->zone;
664         if (find_mb->visible
665             && REGION_EQUAL_TO_ZONE(find_mb, zone)  // check fullscreen
666             && (zone->id == 0)) // change zone->id comparing to bd's profile property (mobile)
667           {
668              found = EINA_TRUE;
669              break;
670           }
671      }
672
673    if (found
674        && !(TYPE_INDICATOR_CHECK(find_mb))
675        && !(TYPE_APPTRAY_CHECK(find_mb))
676        && !(TYPE_MINI_APPTRAY_CHECK(find_mb))
677        && !(TYPE_QUICKPANEL_CHECK(find_mb))
678        && (find_mb->mini_apptray_state != E_MOVE_MINI_APPTRAY_STATE_OFF))
679      {
680         *win = find_mb->bd->client.win;
681         ret = EINA_TRUE;
682      }
683
684    return ret;
685 }
686
687 /* find mini_apptray widget's target window and apply mini_apptray widget control */
688 EINTERN void
689 e_mod_move_mini_apptray_widget_apply(void)
690 {
691    E_Move                     *m = NULL;
692    E_Move_Mini_Apptray_Widget *mini_apptray_widget = NULL;
693    E_Move_Border              *mini_apptray_mb = NULL;
694    Ecore_X_Window              target_win;
695
696    m = e_mod_move_util_get();
697    E_CHECK(m);
698
699    E_CHECK(m->apptray_launch_by_flickup);
700
701    if (m->screen_reader_state) return;
702    if (m->setup_wizard_state) return;
703
704    mini_apptray_mb = e_mod_move_mini_apptray_find();
705    if (!mini_apptray_mb)
706      {
707         if ((mini_apptray_widget = e_mod_move_mini_apptray_widget_get()))
708           e_mod_move_mini_apptray_widget_del(mini_apptray_widget);
709         return;
710      }
711
712    if (e_mod_move_mini_apptray_widget_target_window_find(&target_win))
713      {
714         // if previous mini_apptray_widget is created
715         if ((mini_apptray_widget = e_mod_move_mini_apptray_widget_get()))
716           {
717              // if current mini_apptray_widget's win is equal to finded win
718              // then just return.
719              if ((mini_apptray_widget->win == target_win)) return;
720              else
721                {
722                   // if current mini_apptray_widget's win is not equal to finded win
723                   // then del previous mini_apptray_widget and add new mini_apptray_widget.
724                   e_mod_move_mini_apptray_widget_del(mini_apptray_widget);
725
726                   e_mod_move_mini_apptray_widget_set(e_mod_move_mini_apptray_widget_add(target_win));
727                }
728           }
729         else
730           {
731              //if previous mini_apptray_widget is not creagted
732              //then add new mini_apptray_widget.
733              e_mod_move_mini_apptray_widget_set(e_mod_move_mini_apptray_widget_add(target_win));
734           }
735      }
736    else
737      {
738         // if current window does not require mini_apptray_widget
739         // and previous mini_apptray_widget is created,
740         // then del previous mini_apptray_widget
741         if ((mini_apptray_widget = e_mod_move_mini_apptray_widget_get()))
742           {
743              e_mod_move_mini_apptray_widget_del(mini_apptray_widget);
744              e_mod_move_mini_apptray_widget_set(NULL);
745           }
746      }
747 }
748
749 /* create E_Move_Border related Mini_Apptray_Widget */
750 EINTERN E_Move_Mini_Apptray_Widget *
751 e_mod_move_mini_apptray_widget_add(Ecore_X_Window win)
752 {
753    E_Move                     *m = NULL;
754    E_Move_Border              *mb = NULL;
755    E_Move_Mini_Apptray_Widget *mini_apptray_widget = NULL;
756    E_Move_Widget_Object       *mwo = NULL;
757    Eina_List                  *l;
758    int                         x;
759    int                         y;
760    int                         w;
761    int                         h;
762
763    m = e_mod_move_util_get();
764    E_CHECK_RETURN(m, EINA_FALSE);
765
766    E_CHECK_RETURN(e_mod_move_mini_apptray_find(), EINA_FALSE);
767
768    mb = e_mod_move_border_client_find(win);
769    E_CHECK_RETURN(mb, NULL);
770
771    mini_apptray_widget = E_NEW(E_Move_Mini_Apptray_Widget, 1);
772    E_CHECK_RETURN(mini_apptray_widget, NULL);
773
774    mini_apptray_widget->win = win;
775    mini_apptray_widget->objs = e_mod_move_widget_objs_add(m);
776    if (mini_apptray_widget->objs)
777      {
778         switch (mb->angle)
779           {
780              case 90:
781                 x = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_90].x;
782                 y = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_90].y;
783                 w = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_90].w;
784                 h = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_90].h;
785                 break;
786              case 180:
787                 x = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_180].x;
788                 y = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_180].y;
789                 w = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_180].w;
790                 h = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_180].h;
791                 break;
792              case 270:
793                 x = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_270].x;
794                 y = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_270].y;
795                 w = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_270].w;
796                 h = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_270].h;
797                 break;
798              case 0:
799              default:
800                 x = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_0].x;
801                 y = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_0].y;
802                 w = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_0].w;
803                 h = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_0].h;
804                 break;
805           }
806         e_mod_move_widget_objs_move(mini_apptray_widget->objs, x, y);
807         e_mod_move_widget_objs_resize(mini_apptray_widget->objs, w, h);
808         e_mod_move_widget_objs_layer_set(mini_apptray_widget->objs, EVAS_LAYER_MAX-2);
809         e_mod_move_widget_objs_color_set(mini_apptray_widget->objs, 0, 0, 0, 0);
810         e_mod_move_widget_objs_show(mini_apptray_widget->objs);
811         e_mod_move_widget_objs_raise(mini_apptray_widget->objs);
812
813         // Set Input Shape Mask
814         // change later
815         if ((mini_apptray_widget->input_region_id = e_manager_comp_input_region_id_new(m->man)))
816           {
817              e_manager_comp_input_region_id_set(m->man,
818                                                 mini_apptray_widget->input_region_id,
819                                                 x, y, w, h);
820           }
821         else
822           {
823              goto error_cleanup;
824           }
825      }
826    else
827      {
828         goto error_cleanup;
829      }
830
831    // Set Event Handler
832    EINA_LIST_FOREACH(mini_apptray_widget->objs, l, mwo)
833      {
834         if (!mwo) continue;
835         _e_mod_move_mini_apptray_widget_obj_event_setup(mini_apptray_widget, mwo);
836      }
837    return mini_apptray_widget;
838
839 error_cleanup:
840    if (mini_apptray_widget->objs) e_mod_move_widget_objs_del(mini_apptray_widget->objs);
841    memset(mini_apptray_widget, 0, sizeof(E_Move_Mini_Apptray_Widget));
842    E_FREE(mini_apptray_widget);
843    return NULL;
844 }
845
846 /* delete mini_apptray_widget */
847 EINTERN void
848 e_mod_move_mini_apptray_widget_del(E_Move_Mini_Apptray_Widget *mini_apptray_widget)
849 {
850    E_Move        *m = NULL;
851    E_Move_Border *mb = NULL;
852    E_Move_Border *mini_apptray_mb = NULL;
853    E_Zone        *zone = NULL;
854    int x = 0; int y = 0;
855
856    E_CHECK(mini_apptray_widget);
857    m = e_mod_move_util_get();
858
859    if ((mb = e_mod_move_border_client_find(mini_apptray_widget->win)))
860      {
861         // compositor's input region free
862         // change later
863         if (mini_apptray_widget->input_region_id)
864           {
865              e_manager_comp_input_region_id_del(m->man,
866                                                 mini_apptray_widget->input_region_id);
867           }
868
869         // if mini_apptray_widget is deleted, then mini_apptray's mirror object hide with animation
870         if (mini_apptray_widget->mini_apptray_move)
871           {
872              mini_apptray_mb = e_mod_move_mini_apptray_find();
873              E_CHECK_GOTO(mini_apptray_mb, error_cleanup);
874              zone = mini_apptray_mb->bd->zone;
875
876              switch (mb->angle)
877                {
878                 case  90:
879                    x = zone->w;
880                    y = 0;
881                    break;
882                 case 180:
883                    x = 0;
884                    y = mini_apptray_mb->h * -1;
885                    break;
886                 case 270:
887                    x = mini_apptray_mb->w * -1;
888                    y = 0;
889                    break;
890                 case   0:
891                 default :
892                    x = 0;
893                    y = zone->h;
894                    break;
895                }
896              if (e_mod_move_mini_apptray_objs_animation_state_get(mini_apptray_mb))
897                {
898                   e_mod_move_mini_apptray_objs_animation_stop(mini_apptray_mb);
899                   e_mod_move_mini_apptray_objs_animation_clear(mini_apptray_mb);
900                }
901              e_mod_move_mini_apptray_objs_add(mini_apptray_mb);
902
903              e_mod_move_mini_apptray_e_border_move(mini_apptray_mb, x, y);
904              e_mod_move_mini_apptray_objs_animation_move(mini_apptray_mb, x, y);
905              L(LT_EVENT_OBJ,
906                "[MOVE] ev:%15.15s Mini_Apptray Widget Deleted: Hide Mini Apptray %s():%d\n",
907                "EVAS_OBJ", __func__, __LINE__);
908           }
909      }
910
911 error_cleanup:
912    if (mini_apptray_widget->objs) e_mod_move_widget_objs_del(mini_apptray_widget->objs);
913    memset(mini_apptray_widget, 0, sizeof(E_Move_Mini_Apptray_Widget));
914    E_FREE(mini_apptray_widget);
915    if (m) m->mini_apptray_widget = NULL;
916 }
917
918 EINTERN Eina_Bool
919 e_mod_move_mini_apptray_widget_angle_change(Ecore_X_Window win)
920 {
921    E_Move                     *m = NULL;
922    E_Move_Mini_Apptray_Widget *mini_apptray_widget = NULL;
923    Eina_Bool                   ret = EINA_FALSE;
924    E_Move_Border              *mb = NULL;
925    int                         x;
926    int                         y;
927    int                         w;
928    int                         h;
929
930    m = e_mod_move_util_get();
931    E_CHECK_RETURN(m, EINA_FALSE);
932
933    mini_apptray_widget = e_mod_move_mini_apptray_widget_get();
934    E_CHECK_RETURN(mini_apptray_widget, EINA_FALSE);
935
936    if ((mini_apptray_widget->win == win))
937      {
938         if ((mb = e_mod_move_border_client_find(win)))
939           {
940              switch (mb->angle)
941                {
942                   case 90:
943                      x = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_90].x;
944                      y = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_90].y;
945                      w = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_90].w;
946                      h = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_90].h;
947                      break;
948                   case 180:
949                      x = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_180].x;
950                      y = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_180].y;
951                      w = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_180].w;
952                      h = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_180].h;
953                      break;
954                   case 270:
955                      x = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_270].x;
956                      y = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_270].y;
957                      w = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_270].w;
958                      h = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_270].h;
959                      break;
960                   case 0:
961                   default:
962                      x = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_0].x;
963                      y = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_0].y;
964                      w = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_0].w;
965                      h = m->mini_apptray_widget_geometry[E_MOVE_ANGLE_0].h;
966                      break;
967                 }
968               e_mod_move_widget_objs_move(mini_apptray_widget->objs, x, y);
969               e_mod_move_widget_objs_resize(mini_apptray_widget->objs, w, h);
970
971               // Set Input Shape Mask
972               // change later
973               if (mini_apptray_widget->input_region_id)
974                 {
975                    e_manager_comp_input_region_id_set(m->man,
976                                                       mini_apptray_widget->input_region_id,
977                                                       x, y, w, h);
978                 }
979
980               ret = EINA_TRUE;
981            }
982      }
983    return ret;
984 }
985
986 EINTERN Eina_Bool
987 e_mod_move_mini_apptray_widget_scrollable_check(void)
988 {
989    E_Move_Border *lockscr_mb = NULL;
990    E_Move_Border *taskmgr_mb = NULL;
991    E_Move_Border *pwlock_mb = NULL;
992
993    // if lockscreen is exist & visible, then do not show  apptray
994    if ((lockscr_mb = e_mod_move_lockscreen_find()))
995      {
996         if (lockscr_mb->visibility == E_MOVE_VISIBILITY_STATE_VISIBLE)
997           {
998              L(LT_EVENT_OBJ,
999                "[MOVE] ev:%15.15s  %s %s()\n",
1000                "EVAS_OBJ","Lockscreen is exist.", __func__);
1001              return EINA_FALSE;
1002           }
1003      }
1004    // if taskmanage is exist & visible, then do not show  apptray
1005    if ((taskmgr_mb = e_mod_move_taskmanager_find()))
1006      {
1007         if (taskmgr_mb->visibility == E_MOVE_VISIBILITY_STATE_VISIBLE)
1008           {
1009              L(LT_EVENT_OBJ,
1010                "[MOVE] ev:%15.15s  %s %s()\n",
1011                "EVAS_OBJ","TaskManager is exist.", __func__);
1012              return EINA_FALSE;
1013           }
1014      }
1015
1016    // if pwlock is exist & visible, then do not show  apptray
1017    if ((pwlock_mb = e_mod_move_pwlock_find()))
1018      {
1019         if (pwlock_mb->visibility == E_MOVE_VISIBILITY_STATE_VISIBLE)
1020           {
1021              L(LT_EVENT_OBJ,
1022                "[MOVE] ev:%15.15s  %s %s()\n",
1023                "EVAS_OBJ","PWLOCK is exist.", __func__);
1024              return EINA_FALSE;
1025           }
1026      }
1027
1028    return EINA_TRUE;
1029 }
1030
1031 EINTERN Eina_Bool
1032 e_mod_move_mini_apptray_widget_click_get(E_Move_Mini_Apptray_Widget* mini_apptray_widget)
1033 {
1034    Eina_Bool             click = EINA_FALSE;
1035    E_Move_Widget_Object *mwo = NULL;
1036    Eina_List             *l;
1037
1038    E_CHECK_RETURN(mini_apptray_widget, EINA_FALSE);
1039    E_CHECK_RETURN(mini_apptray_widget->objs, EINA_FALSE);
1040
1041    EINA_LIST_FOREACH(mini_apptray_widget->objs, l, mwo)
1042      {
1043         if (!mwo) continue;
1044         click = e_mod_move_event_click_get(mwo->event);
1045      }
1046
1047    return click;
1048 }
1049
1050 EINTERN Eina_Bool
1051 e_mod_move_mini_apptray_widget_event_clear(E_Move_Mini_Apptray_Widget* mini_apptray_widget)
1052 {
1053    Eina_Bool             click = EINA_FALSE;
1054    E_Move_Widget_Object *mwo = NULL;
1055    Eina_List             *l;
1056    E_Move_Border         *mb = NULL;
1057
1058    E_CHECK_RETURN(mini_apptray_widget, EINA_FALSE);
1059    E_CHECK_RETURN(mini_apptray_widget->objs, EINA_FALSE);
1060
1061    click = e_mod_move_mini_apptray_widget_click_get(mini_apptray_widget);
1062    E_CHECK_RETURN(click, EINA_FALSE);
1063
1064    EINA_LIST_FOREACH(mini_apptray_widget->objs, l, mwo)
1065      {
1066         if (!mwo) continue;
1067         e_mod_move_event_data_clear(mwo->event);
1068         e_mod_move_event_click_set(mwo->event, EINA_FALSE);
1069      }
1070
1071    _e_mod_move_mini_apptray_widget_mini_apptray_move_set(mini_apptray_widget, EINA_FALSE);
1072
1073    mb = e_mod_move_border_client_find(mini_apptray_widget->win);
1074    if (mb && mb->flick_data) e_mod_move_flick_data_free(mb);
1075    return EINA_TRUE;
1076 }
1077
1078 EINTERN Eina_Bool
1079 e_mod_move_mini_apptray_widget_state_change(Ecore_X_Window win, Eina_Bool state)
1080 {
1081    E_Move_Mini_Apptray_Widget *mini_apptray_widget = NULL;
1082
1083    if ((mini_apptray_widget = e_mod_move_mini_apptray_widget_get()))
1084      {
1085         if ((mini_apptray_widget->win == win)
1086             && (!state))
1087           {
1088              // mini_apptray_state disable -> delete current mini_apptray_widget
1089              e_mod_move_mini_apptray_widget_del(mini_apptray_widget);
1090              e_mod_move_mini_apptray_widget_set(NULL);
1091           }
1092      }
1093    else
1094      {
1095         if (state) e_mod_move_mini_apptray_widget_apply();
1096      }
1097
1098    return EINA_TRUE;
1099 }
1100
1101 EINTERN Eina_Bool
1102 e_mod_move_mini_apptray_widget_angle_change_post_job(void)
1103 {
1104    E_Move_Mini_Apptray_Widget *mini_apptray_widget = NULL;
1105    E_Move_Border              *mb = NULL;
1106    E_Border                   *bd = NULL;
1107    E_Zone                     *zone = NULL;
1108    int                         angle = 0;
1109    int                         x = 0, y = 0;
1110
1111    mini_apptray_widget = e_mod_move_mini_apptray_widget_get();
1112    E_CHECK_RETURN(mini_apptray_widget, EINA_FALSE);
1113
1114    mb = e_mod_move_border_client_find(mini_apptray_widget->win);
1115    E_CHECK_RETURN(mb, EINA_FALSE);
1116
1117    bd = mb->bd;
1118    E_CHECK_RETURN(bd, EINA_FALSE);
1119
1120    zone = bd->zone;
1121    E_CHECK_RETURN(zone, EINA_FALSE);
1122
1123    angle = mb->angle;
1124
1125    if (e_mod_move_mini_apptray_widget_click_get(mini_apptray_widget))
1126      {
1127          switch (angle)
1128            {
1129             case   0:
1130                x = zone->x + zone->w;
1131                y = zone->y + zone->h;
1132                break;
1133             case  90:
1134                x = zone->x + zone->w;
1135                y = zone->y + zone->h;
1136                break;
1137             case 180:
1138                x = zone->x;
1139                y = zone->y;
1140                break;
1141             case 270:
1142                x = zone->x;
1143                y = zone->y;
1144                break;
1145             default :
1146                break;
1147            }
1148      }
1149
1150    if (mb->flick_data)
1151      e_mod_move_flick_data_init(mb, x, y);
1152
1153    return EINA_TRUE;
1154 }