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