1 #include "services/e_service_quickpanel_intern.h"
2 #include "e_service_gesture_intern.h"
3 #include "services/e_service_region_intern.h"
4 #include "e_pixmap_intern.h"
5 #include "e_policy_intern.h"
6 #include "e_policy_wl_intern.h"
7 #include "e_policy_private_data.h"
8 #include "e_client_intern.h"
9 #include "e_comp_object_intern.h"
10 #include "e_layout_intern.h"
12 #define SMART_NAME "quickpanel_object"
13 #define INTERNAL_ENTRY \
15 md = evas_object_smart_data_get(obj); \
21 if (qp->ec && !qp->ec->visible) \
23 qp->show_block = EINA_FALSE; \
24 qp->ec->visible = EINA_TRUE; \
25 evas_object_show(qp->ec->frame); \
29 ELOGF("QUICKPANEL", "SHOW BG_RECT...", qp->ec); \
30 evas_object_stack_below(qp->bg_rect, qp->ec->frame); \
31 evas_object_show(qp->bg_rect); \
39 if (qp->ec && qp->ec->visible) \
41 qp->show_block = EINA_TRUE; \
42 qp->ec->visible = EINA_FALSE; \
43 evas_object_hide(qp->ec->frame); \
47 ELOGF("QUICKPANEL", "HIDE BG_RECT...", qp->ec); \
48 evas_object_hide(qp->bg_rect); \
53 #define QP_VISIBLE_SET(qp, vis) \
56 if (vis) QP_SHOW(qp); \
60 #define BACKEND_FUNC_CALL(f, ...) \
63 if ((qp_mgr_funcs) && \
66 qp_mgr_funcs->f(__VA_ARGS__); \
71 #define BACKEND_FUNC_CALL_RET(f, ...) \
74 if ((qp_mgr_funcs) && \
77 return qp_mgr_funcs->f(__VA_ARGS__); \
81 typedef struct _E_Policy_Quickpanel E_Policy_Quickpanel;
82 typedef struct _Mover_Data Mover_Data;
84 typedef struct _E_QP_Client E_QP_Client;
86 struct _E_Policy_Quickpanel
90 E_Service_Quickpanel_Type type;
95 Evas_Object *indi_obj;
96 Evas_Object *handler_obj;
99 Eina_List *intercept_hooks;
102 Ecore_Idle_Enterer *idle_enterer;
103 Ecore_Event_Handler *buf_change_hdlr;
108 unsigned int timestamp;
114 Ecore_Animator *animator;
115 E_Service_Quickpanel_Effect_Type type;
118 Eina_Bool final_visible_state;
127 E_Policy_Angle_Map rotation;
128 E_Maximize saved_maximize;
130 Eina_Bool show_block;
131 Eina_Bool need_scroll_update;
132 Eina_Bool scroll_lock;
139 E_Client *gesture_target;
144 E_Policy_Quickpanel *qp;
147 Evas_Object *smart_obj; //smart object
148 Evas_Object *qp_layout_obj; // quickpanel's e_layout_object
149 Evas_Object *handler_mirror_obj; // quickpanel handler mirror object
150 Evas_Object *base_clip; // clipper for quickapnel base object
151 Evas_Object *handler_clip; // clipper for quickpanel handler object
153 Eina_Rectangle handler_rect;
159 E_Quickpanel_Type type;
164 E_Quickpanel_Client_Scroll_State scrollable;
168 static Eina_List *qp_services = NULL; /* list of E_Policy_Quickpanel for quickpanel services */
169 static Evas_Smart *_mover_smart = NULL;
170 static Eina_Bool _changed = EINA_FALSE;
171 static E_QP_Mgr_Funcs *qp_mgr_funcs = NULL;
173 Eina_List *qp_clients = NULL; /* list of E_QP_Client */
175 static void _e_qp_srv_effect_update(E_Policy_Quickpanel *qp, int x, int y);
176 static E_QP_Client * _e_qp_client_ec_get(E_Client *ec, E_Quickpanel_Type type);
177 static Eina_Bool _e_qp_client_scrollable_update(E_Policy_Quickpanel *qp);
178 static Eina_Bool _e_qp_client_scrollable_state_set(E_Client *ec, E_Quickpanel_Type type, E_Quickpanel_Client_Scroll_State state);
179 static E_Quickpanel_Client_Scroll_State _e_qp_client_scrollable_state_get(E_Client *ec, E_Quickpanel_Type type);
181 static void _quickpanel_client_evas_cb_show(void *data, Evas *evas, Evas_Object *obj, void *event);
182 static void _quickpanel_client_evas_cb_hide(void *data, Evas *evas, Evas_Object *obj, void *event);
183 static void _quickpanel_client_evas_cb_move(void *data, Evas *evas, Evas_Object *obj, void *event);
185 static Eina_Bool _quickpanel_check_skip_client(E_Client *ec);
187 inline static Eina_Bool
188 _e_qp_srv_is_effect_finish_job_started(E_Policy_Quickpanel *qp)
190 return !!qp->effect.animator;
193 inline static Eina_Bool
194 _e_qp_srv_effect_final_visible_state_get(E_Policy_Quickpanel *qp)
196 return !!qp->effect.final_visible_state;
199 inline static Eina_Bool
200 _e_qp_srv_is_effect_running(E_Policy_Quickpanel *qp)
202 return !!qp->effect.active;
205 /* look for E_Policy_Quickpanel instance of qp service
206 * which is same as given ec
208 * @param ec window of qp service
209 * @return E_Policy_Quickpanel instance of qp service
211 static E_Policy_Quickpanel *
212 _quickpanel_service_get(E_Client *ec)
214 E_Policy_Quickpanel *qp;
217 EINA_LIST_FOREACH(qp_services, l, qp)
224 /* look for E_Policy_Quickpanel instance of qp service
225 * which has same type as given qp_client
227 * @param qp_client instance of qp client
228 * @return instance of qp service
230 static E_Policy_Quickpanel *
231 _quickpanel_get_with_client_type(E_QP_Client *qp_client)
233 E_Policy_Quickpanel *qp;
236 /* look for a qp service which has same type as given qp client */
237 EINA_LIST_FOREACH(qp_services, l, qp)
238 if (qp->type == (E_Service_Quickpanel_Type)qp_client->type)
245 _mover_intercept_show(void *data, Evas_Object *obj)
253 Evas_Object *effect_obj;
254 E_Policy_Quickpanel *qp;
261 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
262 e_comp_object_dirty(ec->frame);
263 e_comp_object_render(ec->frame);
265 // desk-zoom-set apply map on all e_desk's smart_data(clients)
266 // to properly pack a quickpanel window on the mover's e_layout_object
267 // (to became a member of mover) it shouldn't be in e_desk's clists.
268 // because mover (also smart obj) is a member of e_desk
269 // otherwize, desk-zoom will mutiplied on a ec again.
270 if (e_config->qp_add_on_desk_smart)
272 desk = e_desk_current_get(qp->zone);
273 e_desk_client_del(desk, ec);
276 e_layout_pack(md->qp_layout_obj, ec->frame);
279 e = evas_object_evas_get(obj);
280 md->base_clip = evas_object_rectangle_add(e);
281 e_layout_pack(md->qp_layout_obj, md->base_clip);
282 e_layout_child_move(md->base_clip, 0, 0);
283 e_layout_child_resize(md->base_clip, ec->w, ec->h);
284 evas_object_color_set(md->base_clip, 255, 255, 255, 255);
285 evas_object_show(md->base_clip);
286 evas_object_clip_set(ec->frame, md->base_clip);
288 // create handler_mirror_obj
289 md->handler_mirror_obj = e_comp_object_util_mirror_add(ec->frame);
290 effect_obj = e_comp_object_effect_object_get(ec->frame);
291 if (evas_object_map_enable_get(effect_obj))
293 map = e_comp_object_map_get(effect_obj);
294 map2 = e_map_dup(map);
295 e_comp_object_map_set(md->handler_mirror_obj, map2);
296 e_comp_object_map_enable_set(md->handler_mirror_obj, EINA_TRUE);
301 e_layout_pack(md->qp_layout_obj, md->handler_mirror_obj);
302 e_layout_child_move(md->handler_mirror_obj, 0, 0);
303 e_layout_child_resize(md->handler_mirror_obj, ec->w, ec->h);
304 evas_object_show(md->handler_mirror_obj);
306 // create handler_clip
307 md->handler_clip = evas_object_rectangle_add(e);
308 e_layout_pack(md->qp_layout_obj, md->handler_clip);
309 e_layout_child_move(md->handler_clip, md->handler_rect.x, md->handler_rect.y);
310 e_layout_child_resize(md->handler_clip, md->handler_rect.w, md->handler_rect.h);
311 if (e_config->qp_handler.use_alpha)
312 evas_object_color_set(md->handler_clip, 255, 255, 255, e_config->qp_handler.alpha);
314 evas_object_color_set(md->handler_clip, 255, 255, 255, 255);
315 evas_object_show(md->handler_clip);
316 evas_object_clip_set(md->handler_mirror_obj, md->handler_clip);
318 evas_object_show(obj);
320 if (e_config->qp_add_on_desk_smart)
322 desk = e_desk_current_get(qp->zone);
323 e_desk_smart_member_add(desk, obj);
328 _mover_smart_add(Evas_Object *obj)
332 md = E_NEW(Mover_Data, 1);
333 if (EINA_UNLIKELY(!md))
337 md->qp_layout_obj = e_layout_add(evas_object_evas_get(obj));
338 evas_object_color_set(md->qp_layout_obj, 255, 255, 255, 255);
339 evas_object_smart_member_add(md->qp_layout_obj, md->smart_obj);
341 evas_object_smart_data_set(obj, md);
343 evas_object_move(obj, -1 , -1);
344 evas_object_intercept_show_callback_add(obj, _mover_intercept_show, md);
348 _mover_smart_del(Evas_Object *obj)
352 E_Policy_Quickpanel *qp;
360 evas_object_clip_unset(md->base_clip);
361 e_layout_unpack(md->base_clip);
362 evas_object_del(md->base_clip);
364 if (md->handler_clip)
366 evas_object_clip_unset(md->handler_clip);
367 e_layout_unpack(md->handler_clip);
368 evas_object_del(md->handler_clip);
370 if (md->handler_mirror_obj)
372 e_layout_unpack(md->handler_mirror_obj);
373 evas_object_del(md->handler_mirror_obj);
376 if (md->qp_layout_obj) evas_object_del(md->qp_layout_obj);
378 evas_object_color_set(ec->frame, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
380 e_comp_client_override_del(ec);
383 * we need to force update 'E_Client' here even if update only evas_object,
384 * because our render loop would not be started by chaning evas object,
385 * we need to make a change on the 'E_Client'. */
386 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
387 e_comp_object_dirty(ec->frame);
388 e_comp_object_render(ec->frame);
390 e_layout_unpack(ec->frame);
392 if (e_config->qp_add_on_desk_smart)
394 desk = e_desk_current_get(qp->zone);
395 e_desk_smart_member_add(desk, ec->frame);
402 _mover_smart_show(Evas_Object *obj)
406 evas_object_show(md->qp_layout_obj);
410 _mover_smart_hide(Evas_Object *obj)
414 evas_object_hide(md->qp_layout_obj);
418 _mover_smart_move(Evas_Object *obj, int x, int y)
422 evas_object_move(md->qp_layout_obj, x, y);
426 _mover_smart_resize(Evas_Object *obj, int w, int h)
430 e_layout_virtual_size_set(md->qp_layout_obj, w, h);
431 evas_object_resize(md->qp_layout_obj, w, h);
435 _mover_smart_init(void)
437 if (_mover_smart) return;
439 static const Evas_Smart_Class sc =
442 EVAS_SMART_CLASS_VERSION,
449 NULL, /* color_set */
451 NULL, /* clip_unset */
452 NULL, /* calculate */
453 NULL, /* member_add */
454 NULL, /* member_del */
457 NULL, /* callbacks */
458 NULL, /* interfaces */
461 _mover_smart = evas_smart_class_new(&sc);
466 _e_qp_srv_mover_new(E_Policy_Quickpanel *qp)
474 e_comp_client_override_add(qp->ec);
477 mover = evas_object_smart_add(evas_object_evas_get(qp->ec->frame), _mover_smart);
479 /* Should setup 'md' before call evas_object_show() */
480 md = evas_object_smart_data_get(mover);
481 EINA_SAFETY_ON_NULL_RETURN_VAL(md, NULL);
485 evas_object_layer_set(md->smart_obj, qp->ec->layer);
487 e_service_region_rectangle_get(qp->handler_obj, qp->rotation, &x, &y, &w, &h);
488 EINA_RECTANGLE_SET(&md->handler_rect, x, y, w, h);
492 desk = e_desk_current_get(qp->zone);
499 evas_object_move(mover, tx, ty);
500 evas_object_resize(mover, qp->ec->w, qp->ec->h);
501 evas_object_show(mover);
509 _e_qp_srv_mover_object_relocate(E_Policy_Quickpanel *qp, int x, int y)
516 Evas_Object *effect_obj;
521 md = evas_object_smart_data_get(qp->mover);
522 EINA_SAFETY_ON_NULL_RETURN_VAL(md, EINA_FALSE);
524 effect_obj = e_comp_object_effect_object_get(ec->frame);
525 if (evas_object_map_enable_get(effect_obj))
527 map = e_comp_object_map_get(effect_obj);
528 map2 = e_map_dup(map);
533 e_comp_object_map_set(md->handler_mirror_obj, NULL);
534 e_comp_object_map_enable_set(md->handler_mirror_obj, EINA_FALSE);
537 evas_object_geometry_get(qp->mover, &tx, &ty, &tw, &th);
539 switch (qp->rotation)
541 case E_POLICY_ANGLE_MAP_90:
542 if (x < tx) goto ret_false;
543 if ((x + md->handler_rect.w) > (tx+tw)) goto ret_false;
545 e_layout_child_move(md->base_clip, 0, 0);
546 e_layout_child_resize(md->base_clip, x - tx, ec->h);
548 e_layout_child_move(md->handler_mirror_obj, x - tx - ec->w + md->handler_rect.w, 0);
549 e_layout_child_move(md->handler_clip, x - tx, 0);
553 map_count = e_map_count_get(map2);
554 for (i = 0; i < map_count; i++)
557 e_map_point_coord_get(map2, i, &mx, &my, &mz);
558 e_map_point_coord_set(map2, i, mx + (x - tx - ec->w + md->handler_rect.w), my, mz);
563 case E_POLICY_ANGLE_MAP_180:
564 if (y > (ty+th)) goto ret_false;
565 if ((y - md->handler_rect.h) < ty) goto ret_false;
567 e_layout_child_move(md->base_clip, 0, y - ty);
568 e_layout_child_resize(md->base_clip, ec->w, ty + ec->h - y);
570 e_layout_child_move(md->handler_mirror_obj, 0, y - ty - md->handler_rect.h);
571 e_layout_child_move(md->handler_clip, 0, y - ty - md->handler_rect.h);
575 map_count = e_map_count_get(map2);
576 for (i = 0; i < map_count; i++)
579 e_map_point_coord_get(map2, i, &mx, &my, &mz);
580 e_map_point_coord_set(map2, i, mx, my + (y - ty - md->handler_rect.h), mz);
585 case E_POLICY_ANGLE_MAP_270:
586 if ((x + md->handler_rect.w) > (tx+tw)) goto ret_false;
587 if ((x - md->handler_rect.w) < tx) goto ret_false;
589 e_layout_child_move(md->base_clip, x - tx, 0);
590 e_layout_child_resize(md->base_clip, tx + ec->w - x, ec->h);
592 e_layout_child_move(md->handler_mirror_obj, x - tx - md->handler_rect.w, 0);
593 e_layout_child_move(md->handler_clip, x - tx - md->handler_rect.w, 0);
597 map_count = e_map_count_get(map2);
598 for (i = 0; i < map_count; i++)
601 e_map_point_coord_get(map2, i, &mx, &my, &mz);
602 e_map_point_coord_set(map2, i, mx + (x - tx - md->handler_rect.w), my, mz);
608 if (y < ty) goto ret_false;
609 if ((y + md->handler_rect.h) > (ty+th)) goto ret_false;
611 e_layout_child_move(md->base_clip, 0, 0);
612 e_layout_child_resize(md->base_clip, ec->w, y - ty);
614 e_layout_child_move(md->handler_mirror_obj, 0, y - ty - ec->h + md->handler_rect.h);
615 e_layout_child_move(md->handler_clip, 0, y - ty);
619 map_count = e_map_count_get(map2);
620 for (i = 0; i < map_count; i++)
623 e_map_point_coord_get(map2, i, &mx, &my, &mz);
624 e_map_point_coord_set(map2, i, mx, my + (y - ty - ec->h + md->handler_rect.h), mz);
631 e_comp_object_map_set(md->handler_mirror_obj, map2);
632 e_comp_object_map_enable_set(md->handler_mirror_obj, EINA_TRUE);
639 if (map2) e_map_free(map2);
644 _e_qp_srv_mover_cb_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
646 E_Policy_Quickpanel *qp;
649 QP_VISIBLE_SET(qp, qp->effect.final_visible_state);
650 E_FREE_FUNC(qp->effect.animator, ecore_animator_del);
654 _e_qp_srv_event_free(void *d EINA_UNUSED, E_Event_Client *ev)
656 e_object_unref(E_OBJECT(ev->ec));
661 _e_qp_srv_visible_state_change_event(E_Client *ec, int vis_state)
663 E_Event_Client_Property *ev;
667 ev = E_NEW(E_Event_Client_Property, 1);
671 ev->property = vis_state;
672 e_object_ref(E_OBJECT(ec));
673 ecore_event_add(E_EVENT_POLICY_QUICKPANEL_VISIBLE_STATE_CHANGE, ev, (Ecore_End_Cb)_e_qp_srv_event_free, NULL);
677 _e_qp_srv_effect_finish_job_end(E_Policy_Quickpanel *qp)
679 E_QP_Client *qp_client;
683 EINA_SAFETY_ON_NULL_RETURN(qp->ec);
687 evas_object_event_callback_del(qp->mover, EVAS_CALLBACK_DEL, _e_qp_srv_mover_cb_del);
688 E_FREE_FUNC(qp->mover, evas_object_del);
691 QP_VISIBLE_SET(qp, qp->effect.final_visible_state);
692 qp->effect.active = EINA_FALSE;
694 e_zone_orientation_block_set(qp->zone, "quickpanel-mover", EINA_FALSE);
696 /* send visible event to only client with the same type of quickpanel service */
697 EINA_LIST_FOREACH(qp_clients, l, qp_client)
699 if (qp->type == (E_Service_Quickpanel_Type)qp_client->type)
700 e_tzsh_qp_state_visible_update(qp_client->ec,
701 qp->effect.final_visible_state,
705 focused = e_client_focused_get();
708 if (qp->effect.final_visible_state)
709 e_policy_aux_message_send(focused, "quickpanel_state", "shown", NULL);
711 e_policy_aux_message_send(focused, "quickpanel_state", "hidden", NULL);
715 (qp->below != focused))
717 if (qp->effect.final_visible_state)
718 e_policy_aux_message_send(qp->below, "quickpanel_state", "shown", NULL);
720 e_policy_aux_message_send(qp->below, "quickpanel_state", "hidden", NULL);
723 if (qp->gesture_target)
725 if ((qp->gesture_target != focused) &&
726 (qp->gesture_target != qp->below))
728 if (qp->effect.final_visible_state)
729 e_policy_aux_message_send(qp->gesture_target, "quickpanel_state", "shown", NULL);
732 e_policy_aux_message_send(qp->gesture_target, "quickpanel_state", "hidden", NULL);
733 qp->gesture_target = NULL;
738 _e_qp_srv_visible_state_change_event(qp->ec, qp->effect.final_visible_state);
740 if (qp->effect.final_visible_state)
742 if ((!qp->ec->focused) &&
743 (qp->ec->icccm.accepts_focus || qp->ec->icccm.take_focus) &&
744 (evas_object_visible_get(qp->ec->frame) == EINA_TRUE))
746 ELOGF("QUICKPANEL", "effect finished but not focused. focus set to quickpanel", qp->ec);
747 e_client_focus_latest_set(qp->ec);
755 _e_qp_srv_effect_finish_job_op(void *data, double pos)
757 E_Policy_Quickpanel *qp;
758 int new_x = 0, new_y = 0;
762 progress = ecore_animator_pos_map(pos, ECORE_POS_MAP_DECELERATE, 0, 0);
763 switch (qp->rotation)
765 case E_POLICY_ANGLE_MAP_90:
766 case E_POLICY_ANGLE_MAP_270:
767 new_x = qp->effect.from + (qp->effect.to * progress);
770 case E_POLICY_ANGLE_MAP_180:
771 new_y = qp->effect.from + (qp->effect.to * progress);
774 _e_qp_srv_effect_update(qp, new_x, new_y);
778 E_FREE_FUNC(qp->effect.animator, ecore_animator_del);
780 _e_qp_srv_effect_finish_job_end(qp);
782 return ECORE_CALLBACK_CANCEL;
785 return ECORE_CALLBACK_PASS_ON;
789 _e_qp_srv_effect_finish_job_start(E_Policy_Quickpanel *qp, Eina_Bool visible)
794 const double ref = 0.1;
797 if (qp->effect.type == E_SERVICE_QUICKPANEL_EFFECT_TYPE_MOVE)
808 switch (qp->rotation)
810 case E_POLICY_ANGLE_MAP_90:
812 to = (visible) ? (tw - from) : (-from);
813 duration = ((double)abs(to) / ((double)tw / 2)) * ref;
815 case E_POLICY_ANGLE_MAP_180:
817 to = (visible) ? (-from) : (th - from);
818 duration = ((double)abs(to) / ((double)th / 2)) * ref;
820 case E_POLICY_ANGLE_MAP_270:
822 to = (visible) ? (-from) : (tw - from);
823 duration = ((double)abs(to) / ((double)tw / 2)) * ref;
827 to = (visible) ? (th - from) : (-from);
828 duration = ((double)abs(to) / ((double)th / 2)) * ref;
834 if (visible != qp->effect.final_visible_state)
835 qp->effect.final_visible_state = visible;
837 _e_qp_srv_effect_finish_job_end(qp);
841 /* start move effect */
842 qp->effect.from = from;
844 qp->effect.final_visible_state = visible;
845 qp->effect.animator =
846 ecore_animator_timeline_add(duration, _e_qp_srv_effect_finish_job_op, qp);
849 evas_object_event_callback_add(qp->mover, EVAS_CALLBACK_DEL, _e_qp_srv_mover_cb_del, qp);
853 _e_qp_srv_effect_finish_job_stop(E_Policy_Quickpanel *qp)
856 evas_object_event_callback_del(qp->mover, EVAS_CALLBACK_DEL, _e_qp_srv_mover_cb_del);
857 E_FREE_FUNC(qp->effect.animator, ecore_animator_del);
859 if (qp->effect.final_visible_state)
862 (!qp->ec->focused) &&
863 (qp->ec->icccm.accepts_focus || qp->ec->icccm.take_focus) &&
864 (evas_object_visible_get(qp->ec->frame) == EINA_TRUE))
866 ELOGF("QUICKPANEL", "effect finished but not focused. focus set to quickpanel", qp->ec);
867 e_client_focus_latest_set(qp->ec);
874 _quickpanel_send_gesture_to_indicator(void)
876 if (e_config->qp_ignore_indicator_mode)
880 focused = e_client_focused_get();
883 ELOGF("TZ_IND", "INDICATOR state:%d, opacity:%d, vtype:%d",
884 focused, focused->indicator.state, focused->indicator.opacity_mode, focused->indicator.visible_type);
886 if (focused->indicator.state == 2) // state: on
888 if (focused->indicator.visible_type == 0) // visible: hidden
890 /* cancel touch events sended up to now */
891 e_comp_wl_touch_cancel();
892 e_policy_wl_indicator_flick_send(focused);
896 else // state: off, unknown
906 _e_qp_srv_visibility_eval_by_mouse_info(E_Policy_Quickpanel *qp)
910 const float sensitivity = 1.5; /* hard coded. (arbitary) */
912 if (qp->effect.type == E_SERVICE_QUICKPANEL_EFFECT_TYPE_MOVE)
923 switch (qp->rotation)
925 case E_POLICY_ANGLE_MAP_90:
926 is_half = (qp->mouse_info.x > (tw / 2));
928 case E_POLICY_ANGLE_MAP_180:
929 is_half = (qp->mouse_info.y < (th / 2));
931 case E_POLICY_ANGLE_MAP_270:
932 is_half = (qp->mouse_info.x < (tw / 2));
934 case E_POLICY_ANGLE_MAP_0:
936 is_half = (qp->mouse_info.y > (th / 2));
940 if ((qp->mouse_info.accel > sensitivity) ||
941 ((qp->mouse_info.accel > -sensitivity) && is_half))
948 _e_qp_srv_mouse_info_update(E_Policy_Quickpanel *qp, int x, int y, unsigned int timestamp)
953 /* Calculate the acceleration of movement,
954 * determine the visibility of quickpanel based on the result. */
955 dt = timestamp - qp->mouse_info.timestamp;
958 switch (qp->rotation)
960 case E_POLICY_ANGLE_MAP_90:
961 dp = x - qp->mouse_info.x;
963 case E_POLICY_ANGLE_MAP_180:
964 dp = qp->mouse_info.y - y;
966 case E_POLICY_ANGLE_MAP_270:
967 dp = qp->mouse_info.x - x;
970 dp = y - qp->mouse_info.y;
973 qp->mouse_info.accel = (float)dp / (float)dt;
976 qp->mouse_info.x = x;
977 qp->mouse_info.y = y;
978 qp->mouse_info.timestamp = timestamp;
982 _e_qp_srv_effect_start(E_Policy_Quickpanel *qp)
984 if (qp->effect.disable_ref)
987 /* Pause changing zone orientation during mover object is working. */
988 e_zone_orientation_block_set(qp->zone, "quickpanel-mover", EINA_TRUE);
990 qp->effect.active = EINA_TRUE;
992 if (qp->effect.type == E_SERVICE_QUICKPANEL_EFFECT_TYPE_SWIPE)
993 _e_qp_srv_mover_new(qp);
997 _e_qp_srv_qp_move(E_Policy_Quickpanel *qp, int x, int y)
1005 if (!qp->ec) return;
1012 switch (qp->rotation)
1014 case E_POLICY_ANGLE_MAP_90:
1015 new_x = x - qp->geom.w;
1017 case E_POLICY_ANGLE_MAP_180:
1020 case E_POLICY_ANGLE_MAP_270:
1024 new_y = y - qp->geom.h;
1025 if (new_y > 0) new_y = 0;
1031 weight = y / (double)qp->geom.h;
1032 if (weight > 1) weight = 1;
1033 else if (weight < 0) weight = 0;
1035 dim = (int)(178 * weight);
1036 evas_object_color_set(qp->bg_rect, 0, 0, 0, dim);
1039 e_client_util_move_without_frame(ec, new_x, new_y);
1043 _e_qp_srv_effect_update(E_Policy_Quickpanel *qp, int x, int y)
1047 res = _e_qp_srv_is_effect_running(qp);
1054 switch (qp->effect.type)
1056 case E_SERVICE_QUICKPANEL_EFFECT_TYPE_SWIPE:
1057 _e_qp_srv_mover_object_relocate(qp, x, y);
1059 case E_SERVICE_QUICKPANEL_EFFECT_TYPE_MOVE:
1060 _e_qp_srv_qp_move(qp, x, y);
1062 case E_SERVICE_QUICKPANEL_EFFECT_TYPE_APP_CUSTOM:
1063 ERR("Undefine behavior for APP_CUSTOM type");
1066 ERR("Unknown effect type");
1072 _e_qp_srv_effect_finish(E_Policy_Quickpanel *qp, Eina_Bool final_visible_state)
1077 res = _e_qp_srv_is_effect_running(qp);
1081 res = _e_qp_srv_is_effect_finish_job_started(qp);
1084 vis = _e_qp_srv_effect_final_visible_state_get(qp);
1085 if (vis == final_visible_state)
1088 _e_qp_srv_effect_finish_job_stop(qp);
1090 _e_qp_srv_effect_finish_job_start(qp, final_visible_state);
1094 _e_qp_srv_effect_stop(E_Policy_Quickpanel *qp)
1098 res = _e_qp_srv_is_effect_running(qp);
1102 qp->effect.active = EINA_FALSE;
1104 res = _e_qp_srv_is_effect_finish_job_started(qp);
1106 _e_qp_srv_effect_finish_job_end(qp);
1109 e_zone_orientation_block_set(qp->zone, "quickpanel-mover", EINA_FALSE);
1110 QP_VISIBLE_SET(qp, EINA_FALSE);
1111 E_FREE_FUNC(qp->mover, evas_object_del);
1116 _e_qp_srv_effect_disable_unref(E_Policy_Quickpanel *qp)
1118 if (qp->effect.disable_ref > 0)
1119 qp->effect.disable_ref--;
1123 _e_qp_srv_effect_disable_ref(E_Policy_Quickpanel *qp)
1125 qp->effect.disable_ref++;
1126 if (qp->effect.disable_ref == 1)
1127 _e_qp_srv_effect_stop(qp);
1131 _e_qp_check_scrollable(E_Policy_Quickpanel *qp)
1133 E_Client *ec = NULL;
1134 E_QP_Client *qp_client = NULL;
1135 Eina_Bool scrollable = EINA_TRUE;
1137 int zx = 0, zy = 0, zw = 0, zh = 0;
1139 if (!qp) return EINA_FALSE;
1140 if (!qp->ec) return EINA_FALSE;
1142 e_zone_useful_geometry_get(qp->zone, &zx, &zy, &zw, &zh);
1144 for (ec = e_client_below_get(qp->ec); ec; ec = e_client_below_get(ec))
1146 if (!ec->visible) continue;
1147 if (_quickpanel_check_skip_client(ec)) continue;
1148 e_client_geometry_get(ec, &x, &y, &w, &h);
1149 if (!E_INTERSECTS(x, y, w, h, zx, zy, zw, zh)) continue;
1151 qp_client = _e_qp_client_ec_get(ec, (E_Quickpanel_Type)qp->type);
1152 if (!qp_client) continue;
1153 if (qp_client->hint.scrollable == E_QUICKPANEL_CLIENT_SCROLL_STATE_RETAIN)
1156 if (qp_client->hint.scrollable == E_QUICKPANEL_CLIENT_SCROLL_STATE_SET)
1157 scrollable = EINA_TRUE;
1160 ELOGF("QUICKPANEL", "Scroll locked by owner client (ec:%p, win:%zx)", qp->below, ec, e_client_util_win_get(ec));
1161 scrollable = EINA_FALSE;
1170 _region_obj_cb_gesture_start(void *data, Evas_Object *handler, int nfingers, int x, int y, unsigned int timestamp)
1172 E_Policy_Quickpanel *qp;
1173 E_QP_Client *qp_client;
1175 E_Client *pos_ec = NULL;
1176 E_Desk *desk = NULL;
1177 int indi_x, indi_y, indi_w, indi_h;
1178 const int sensitivity = 50;
1180 Eina_Bool scrollable = EINA_TRUE;
1182 ELOGF("QUICKPANEL", "Start gesture for quickpanel", NULL);
1185 if (EINA_UNLIKELY(!qp))
1188 if (EINA_UNLIKELY(!qp->ec))
1191 if (e_object_is_del(E_OBJECT(qp->ec)))
1194 desk = e_desk_current_get(qp->zone);
1196 pos_ec = e_client_under_position_get(desk, x, y, NULL);
1200 ELOGF("QUICKPANEL", "NO visible client under pos(%d,%d)", NULL, x, y);
1204 if (handler == qp->indi_obj)
1208 e_service_region_rectangle_get(qp->indi_obj, qp->rotation, &indi_x, &indi_y, &indi_w, &indi_h);
1209 switch (qp->rotation)
1211 case E_POLICY_ANGLE_MAP_90:
1214 iw = indi_w + sensitivity;
1217 case E_POLICY_ANGLE_MAP_180:
1219 iy = pos_ec->y + pos_ec->h - (indi_h + sensitivity);
1221 ih = indi_h + sensitivity;
1223 case E_POLICY_ANGLE_MAP_270:
1224 ix = pos_ec->x + pos_ec->w - (indi_w + sensitivity);
1226 iw = indi_w + sensitivity;
1229 case E_POLICY_ANGLE_MAP_0:
1234 ih = indi_h + sensitivity;
1238 if (!E_INSIDE(x, y, ix, iy, iw, ih))
1240 ELOGF("QUICKPANEL", "NOT in indicator area", NULL);
1244 if (_quickpanel_send_gesture_to_indicator())
1246 ELOGF("QUICKPANEL", "SEND to change indicator state", NULL);
1251 // check quickpanel service window's scroll lock state
1252 if (qp->scroll_lock)
1254 ELOGF("QUICKPANEL", "Scroll locked by quickpanel service", NULL);
1258 /* Do not show and scroll the quickpanel window if the qp_client winodw
1259 * which is placed at the below of the quickpanel window doesn't want
1260 * to show and scroll the quickpanel window.
1262 qp_client = _e_qp_client_ec_get(qp->below, (E_Quickpanel_Type)qp->type);
1265 if (qp_client->hint.scrollable == E_QUICKPANEL_CLIENT_SCROLL_STATE_UNSET)
1267 ELOGF("QUICKPANEL", "Scroll locked by current client", qp->below);
1270 else if (qp_client->hint.scrollable == E_QUICKPANEL_CLIENT_SCROLL_STATE_RETAIN)
1272 ELOGF("QUICKPANEL", "Scroll follow by previous client", qp->below);
1273 scrollable = _e_qp_check_scrollable(qp);
1274 if (!scrollable) return;
1278 res = _e_qp_srv_is_effect_running(qp);
1281 INF("Already animated");
1285 focused = e_client_focused_get();
1287 e_policy_aux_message_send(focused, "quickpanel_state", "moving", NULL);
1289 qp->gesture_target = focused;
1292 (qp->below != focused))
1293 e_policy_aux_message_send(qp->below, "quickpanel_state", "moving", NULL);
1295 /* cancel touch events sended up to now */
1296 e_comp_wl_touch_cancel();
1298 _e_qp_srv_mouse_info_update(qp, x, y, timestamp);
1299 _e_qp_srv_effect_start(qp);
1300 _e_qp_srv_effect_update(qp, x, y);
1304 _region_obj_cb_gesture_move(void *data, Evas_Object *handler, int nfingers, int x, int y, unsigned int timestamp)
1306 E_Policy_Quickpanel *qp;
1310 res = _e_qp_srv_is_effect_running(qp);
1314 _e_qp_srv_mouse_info_update(qp, x, y, timestamp);
1315 _e_qp_srv_effect_update(qp, x, y);
1319 _region_obj_cb_gesture_end(void *data EINA_UNUSED, Evas_Object *handler, int nfingers, int x, int y, unsigned int timestamp)
1321 E_Policy_Quickpanel *qp;
1325 res = _e_qp_srv_is_effect_running(qp);
1329 v = _e_qp_srv_visibility_eval_by_mouse_info(qp);
1330 _e_qp_srv_effect_finish(qp, v);
1334 _quickpanel_free(E_Policy_Quickpanel *qp)
1336 ELOGF("QUICKPANEL", "Remove Client | qp %p", qp->ec, qp);
1338 evas_object_event_callback_del(qp->ec->frame, EVAS_CALLBACK_SHOW, _quickpanel_client_evas_cb_show);
1339 evas_object_event_callback_del(qp->ec->frame, EVAS_CALLBACK_HIDE, _quickpanel_client_evas_cb_hide);
1340 evas_object_event_callback_del(qp->ec->frame, EVAS_CALLBACK_MOVE, _quickpanel_client_evas_cb_move);
1343 evas_object_del(qp->bg_rect);
1345 E_FREE_FUNC(qp->mover, evas_object_del);
1346 E_FREE_FUNC(qp->indi_obj, evas_object_del);
1347 E_FREE_FUNC(qp->handler_obj, evas_object_del);
1348 E_FREE_FUNC(qp->effect.animator, ecore_animator_del);
1349 E_FREE_FUNC(qp->idle_enterer, ecore_idle_enterer_del);
1350 E_FREE_LIST(qp->events, ecore_event_handler_del);
1351 E_FREE_LIST(qp->hooks, e_client_hook_del);
1352 E_FREE_LIST(qp->intercept_hooks, e_comp_object_intercept_hook_del);
1354 qp_services = eina_list_remove(qp_services, qp);
1359 _quickpanel_hook_client_del(void *d, E_Client *ec)
1361 E_Policy_Quickpanel *qp;
1364 if (EINA_UNLIKELY(!qp))
1372 e_zone_orientation_force_update_del(qp->zone, ec);
1374 _quickpanel_free(qp);
1378 _quickpanel_client_evas_cb_show(void *data, Evas *evas, Evas_Object *obj, void *event)
1380 E_Policy_Quickpanel *qp;
1384 if (EINA_UNLIKELY(!qp))
1387 evas_object_show(qp->handler_obj);
1388 evas_object_raise(qp->handler_obj);
1389 evas_object_hide(qp->indi_obj);
1393 e_pixmap_buffer_clear_cancel(ec->pixmap);
1395 E_FREE_FUNC(qp->buf_change_hdlr, ecore_event_handler_del);
1399 _quickpanel_cb_buffer_change(void *data, int type, void *event)
1401 E_Policy_Quickpanel *qp;
1405 Eina_Bool vis = EINA_FALSE;
1416 /* skip force render if ec is visible */
1420 /* render forcibly */
1421 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1422 e_comp_object_dirty(ec->frame);
1423 e_comp_object_render(ec->frame);
1425 /* make frame event */
1426 e_pixmap_image_clear(ec->pixmap, EINA_TRUE);
1428 /* use single buffer if qp service's ec is invisible */
1429 evas_object_geometry_get(ec->frame, &x, &y, &w, &h);
1431 if (E_INTERSECTS(x, y, w, h,
1436 vis = evas_object_visible_get(ec->frame);
1439 e_pixmap_buffer_clear(ec->pixmap, EINA_TRUE);
1442 return ECORE_CALLBACK_PASS_ON;
1446 _quickpanel_client_evas_cb_hide(void *data, Evas *evas, Evas_Object *obj, void *event)
1448 E_Policy_Quickpanel *qp;
1451 if (EINA_UNLIKELY(!qp))
1454 evas_object_hide(qp->handler_obj);
1455 evas_object_show(qp->indi_obj);
1457 if (qp->need_scroll_update)
1458 _e_qp_client_scrollable_update(qp);
1460 e_pixmap_buffer_clear(qp->ec->pixmap, EINA_TRUE);
1464 _quickpanel_client_evas_cb_move(void *data, Evas *evas, Evas_Object *obj, void *event)
1466 E_Policy_Quickpanel *qp;
1470 if (EINA_UNLIKELY(!qp))
1473 e_service_region_rectangle_get(qp->handler_obj, qp->rotation, &hx, &hy, NULL, NULL);
1474 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
1475 evas_object_move(qp->handler_obj, x + hx, y + hy);
1479 _quickpanel_handler_obj_region_convert_set(E_Policy_Quickpanel *qp, E_Policy_Angle_Map ridx, int x, int y, int w, int h, int tx, int ty, int tw, int th)
1485 case E_POLICY_ANGLE_MAP_0:
1492 case E_POLICY_ANGLE_MAP_90:
1499 case E_POLICY_ANGLE_MAP_180:
1506 case E_POLICY_ANGLE_MAP_270:
1521 e_service_region_rectangle_set(qp->handler_obj, ridx, nx, ny, nw, nh);
1522 ELOGF("QUICKPANEL", "handler obj:%p, angle:%d, geo(%d,%d,%d,%d)", NULL, qp->handler_obj, ridx, nx, ny, nw, nh);
1526 _quickpanel_handler_rect_add(E_Policy_Quickpanel *qp, E_Policy_Angle_Map ridx, int x, int y, int w, int h, int tx, int ty, int tw, int th)
1533 ELOGF("QUICKPANEL", "Handler Geo Set | x %d, y %d, w %d, h %d",
1536 if (qp->handler_obj)
1539 obj = e_service_region_object_new(ec);
1540 evas_object_name_set(obj, "qp::handler_obj");
1544 e_service_region_gesture_set(obj,
1545 POL_GESTURE_TYPE_NONE,
1547 _region_obj_cb_gesture_start,
1548 _region_obj_cb_gesture_move,
1549 _region_obj_cb_gesture_end, qp);
1551 /* Add handler object to smart member to follow the client's stack */
1552 evas_object_smart_member_add(obj, ec->frame);
1553 evas_object_propagate_events_set(obj, 0);
1554 if (evas_object_visible_get(ec->frame))
1555 evas_object_show(obj);
1557 qp->handler_obj = obj;
1560 _quickpanel_handler_obj_region_convert_set(qp, ridx, x, y, w, h, tx, ty, tw, th);
1563 void _quickpanel_indi_obj_region_convert_set(E_Policy_Quickpanel *qp, int angle, int x, int y, int w, int h, int tx, int ty, int tw, int th)
1567 if ((w <= 0) || (h <= 0)) return;
1571 case E_POLICY_ANGLE_MAP_0:
1578 case E_POLICY_ANGLE_MAP_90:
1585 case E_POLICY_ANGLE_MAP_180:
1592 case E_POLICY_ANGLE_MAP_270:
1607 e_service_region_rectangle_set(qp->indi_obj, angle, nx, ny, nw, nh);
1608 ELOGF("QUICKPANEL", "indicator obj:%p, angle:%d, geo(%d,%d,%d,%d)", NULL, qp->indi_obj, angle, nx, ny, nw, nh);
1612 _quickpanel_handler_region_set(E_Policy_Quickpanel *qp, E_Policy_Angle_Map ridx, Eina_Tiler *tiler)
1616 E_Desk *desk = NULL;
1619 /* FIXME supported single rectangle, not tiler */
1626 desk = e_desk_current_get(qp->zone);
1635 it = eina_tiler_iterator_new(tiler);
1636 EINA_ITERATOR_FOREACH(it, r)
1638 _quickpanel_handler_rect_add(qp, ridx, r->x, r->y, r->w, r->h, tx, ty, tw, th);
1639 _quickpanel_indi_obj_region_convert_set(qp, ridx, r->x, r->y, r->w, r->h, tx, ty, tw, th);
1642 eina_iterator_free(it);
1646 _quickpanel_contents_region_set(E_Policy_Quickpanel *qp, E_Policy_Angle_Map ridx, Eina_Tiler *tiler)
1652 it = eina_tiler_iterator_new(tiler);
1653 EINA_ITERATOR_FOREACH(it, r)
1660 eina_iterator_free(it);
1664 _e_qp_srv_visible_handle(E_Policy_Quickpanel *qp, Eina_Bool vis)
1666 Eina_Bool res = EINA_FALSE;
1668 // If vis is true, show (with effect) the quickpanel service.
1669 // Otherwise, hide (with effect) the quickpanel service.
1671 res = _e_qp_srv_is_effect_running(qp);
1673 _e_qp_srv_effect_finish(qp, vis);
1674 else if ((qp->ec) && ((qp->ec->visible) || (vis)))
1676 _e_qp_srv_effect_start(qp);
1677 _e_qp_srv_effect_update(qp, qp->effect.x, qp->effect.y);
1678 _e_qp_srv_effect_finish(qp, vis);
1683 _e_qp_srv_visible_set(E_Policy_Quickpanel *qp, Eina_Bool vis)
1687 res = _e_qp_client_scrollable_update(qp);
1690 if (qp->effect.disable_ref)
1692 QP_VISIBLE_SET(qp, vis);
1696 _e_qp_srv_visible_handle(qp, vis);
1700 e_qp_control_by_command(E_Client *ec, int operation)
1702 E_Policy_Quickpanel *qp = NULL;
1704 qp = _quickpanel_service_get(ec);
1707 /* look for a first quick panel service */
1708 qp = eina_list_nth(qp_services, 0);
1714 _e_qp_srv_visible_handle(qp, EINA_FALSE);
1715 else if (operation == 1)
1716 _e_qp_srv_visible_handle(qp, EINA_TRUE);
1717 else if (operation == 2)
1718 e_service_quickpanel_scroll_lock_set(qp->ec, EINA_TRUE);
1720 e_service_quickpanel_scroll_lock_set(qp->ec, EINA_FALSE);
1725 _quickpanel_cb_rotation_begin(void *data, int type, void *event)
1727 E_Policy_Quickpanel *qp;
1728 E_Event_Client *ev = event;
1732 if (EINA_UNLIKELY(!qp))
1736 if (EINA_UNLIKELY(!ec))
1742 E_FREE_FUNC(qp->mover, evas_object_del);
1744 _e_qp_srv_effect_disable_ref(qp);
1747 return ECORE_CALLBACK_PASS_ON;
1751 _quickpanel_cb_rotation_cancel(void *data, int type, void *event)
1753 E_Policy_Quickpanel *qp;
1754 E_Event_Client *ev = event;
1758 if (EINA_UNLIKELY(!qp))
1762 if (EINA_UNLIKELY(!ec))
1768 _e_qp_srv_effect_disable_unref(qp);
1771 return ECORE_CALLBACK_PASS_ON;
1775 _quickpanel_cb_rotation_done(void *data, int type, void *event)
1777 E_Policy_Quickpanel *qp;
1778 E_Event_Client *ev = event;
1780 E_QP_Client *qp_client;
1785 if (EINA_UNLIKELY(!qp))
1789 if (EINA_UNLIKELY(!ec))
1795 qp->rotation = e_policy_angle_map(ec->e.state.rot.ang.curr);
1797 vis = evas_object_visible_get(ec->frame);
1798 switch (qp->rotation)
1800 case E_POLICY_ANGLE_MAP_90:
1801 qp->effect.x = vis ? qp->zone->w : 0;
1803 case E_POLICY_ANGLE_MAP_180:
1804 qp->effect.y = vis ? 0 : qp->zone->h;
1806 case E_POLICY_ANGLE_MAP_270:
1807 qp->effect.x = vis ? 0 : qp->zone->w;
1810 qp->effect.y = vis ? qp->zone->h : 0;
1814 _e_qp_srv_effect_disable_unref(qp);
1816 /* send orientation event to only client with the same type of quickpanel service */
1817 EINA_LIST_FOREACH(qp_clients, l, qp_client)
1819 if (qp->type == (E_Service_Quickpanel_Type)qp_client->type)
1820 e_tzsh_qp_state_orientation_update(qp_client->ec,
1826 return ECORE_CALLBACK_PASS_ON;
1830 _quickpanel_check_skip_client(E_Client *ec)
1832 Eina_Bool skip = EINA_FALSE;
1834 if (!ec) return EINA_TRUE;
1836 if (e_policy_client_is_keyboard(ec) ||
1837 e_policy_client_is_keyboard_sub(ec) ||
1838 e_policy_client_is_cursor(ec))
1846 /* NOTE: if the state(show/hide/stack) of windows which are stacked below
1847 * quickpanel is changed, we close the quickpanel.
1848 * the most major senario is that quickpanel should be closed when WiFi popup to
1849 * show the available connection list is shown by click the button on
1850 * the quickpanel to turn on the WiFi.
1851 * @see _quickpanel_cb_client_show(),
1852 * _quickpanel_cb_client_hide()
1853 * _quickpanel_cb_client_move()
1854 * _quickpanel_cb_client_stack()
1855 * _quickpanel_cb_client_remove()
1856 * _quickpanel_idle_enter()
1859 _quickpanel_below_visible_client_get(E_Policy_Quickpanel *qp)
1864 if (!qp->zone) return NULL;
1871 for (ec = e_client_below_get(qp->ec); ec; ec = e_client_below_get(ec))
1873 if (!ec->visible) continue;
1874 if (_quickpanel_check_skip_client(ec)) continue;
1875 if (!E_INTERSECTS(ec->x, ec->y, ec->w, ec->h, zx, zy, zw, zh)) continue;
1883 _quickpanel_below_change_eval(void *data, void *event)
1885 E_Policy_Quickpanel *qp;
1889 if (EINA_UNLIKELY(!qp))
1893 if (EINA_UNLIKELY((!ev) || (!ev->ec)))
1896 if (_quickpanel_check_skip_client(ev->ec))
1899 qp->changes.below = EINA_TRUE;
1900 _changed = EINA_TRUE;
1904 _quickpanel_cb_client_show(void *data, int type, void *event)
1906 _quickpanel_below_change_eval(data, event);
1907 return ECORE_CALLBACK_PASS_ON;
1911 _quickpanel_cb_client_hide(void *data, int type, void *event)
1913 _quickpanel_below_change_eval(data, event);
1914 return ECORE_CALLBACK_PASS_ON;
1918 _quickpanel_cb_client_move(void *data, int type, void *event)
1920 _quickpanel_below_change_eval(data, event);
1921 return ECORE_CALLBACK_PASS_ON;
1925 _quickpanel_cb_client_stack(void *data, int type, void *event)
1927 E_Policy_Quickpanel *qp;
1931 EINA_SAFETY_ON_NULL_GOTO(qp, end);
1934 EINA_SAFETY_ON_NULL_GOTO(ev, end);
1936 qp->stacking = ev->ec;
1938 DBG("Stacking Client '%s'(%p)",
1939 ev->ec->icccm.name ? ev->ec->icccm.name : "", ev->ec);
1941 if (evas_object_visible_get(ev->ec->frame))
1942 _quickpanel_below_change_eval(data, event);
1944 return ECORE_CALLBACK_PASS_ON;
1948 _quickpanel_cb_client_remove(void *data, int type, void *event)
1950 E_Policy_Quickpanel *qp;
1954 EINA_SAFETY_ON_NULL_GOTO(qp, end);
1957 EINA_SAFETY_ON_NULL_GOTO(ev, end);
1959 if (qp->stacking == ev->ec)
1960 qp->stacking = NULL;
1962 if (qp->below == ev->ec)
1965 if (qp->gesture_target == ev->ec)
1966 qp->gesture_target = NULL;
1969 _quickpanel_below_change_eval(data, event);
1971 return ECORE_CALLBACK_PASS_ON;
1975 _quickpanel_cb_client_focus_in(void *data, int type, void *event)
1977 E_Policy_Quickpanel *qp;
1982 EINA_SAFETY_ON_NULL_GOTO(qp, end);
1985 EINA_SAFETY_ON_NULL_GOTO(ev, end);
1988 EINA_SAFETY_ON_NULL_GOTO(ec, end);
1995 DBG("Focus changed to '%s'(%zx), Hide QP",
1996 ec->icccm.name ? ec->icccm.name : "", e_client_util_win_get(ec));
1997 e_service_quickpanel_hide(qp->ec);
2000 return ECORE_CALLBACK_PASS_ON;
2004 _quickpanel_cb_desk_geometry_change(void *data, int type, void *event)
2006 E_Policy_Quickpanel *qp;
2007 E_Event_Desk_Geometry_Change *ev;
2008 E_Desk *desk = NULL;
2013 EINA_SAFETY_ON_NULL_GOTO(qp, end);
2016 EINA_SAFETY_ON_NULL_GOTO(ev, end);
2018 desk = e_desk_current_get(qp->zone);
2019 EINA_SAFETY_ON_NULL_GOTO(desk, end);
2021 for (angle = E_POLICY_ANGLE_MAP_0; angle < E_POLICY_ANGLE_MAP_NUM; angle++)
2023 e_service_region_rectangle_get(qp->indi_obj, angle, &x, &y, &w, &h);
2024 if ((w > 0) && (h > 0))
2025 _quickpanel_indi_obj_region_convert_set(qp, angle, x, y, w, h, ev->desk->geom.x, ev->desk->geom.y, ev->desk->geom.w, ev->desk->geom.h);
2027 e_service_region_rectangle_get(qp->handler_obj, angle, &x, &y, &w, &h);
2028 if ((w > 0) && (h > 0))
2029 _quickpanel_handler_obj_region_convert_set(qp, angle, x, y, w, h, ev->desk->geom.x, ev->desk->geom.y, ev->desk->geom.w, ev->desk->geom.h);
2032 evas_object_move(qp->ec->frame, ev->desk->geom.x, ev->desk->geom.y);
2035 return ECORE_CALLBACK_PASS_ON;
2039 _quickpanel_cb_client_zone_set(void *data, int type EINA_UNUSED, void *event)
2041 E_Policy_Quickpanel *qp;
2042 E_Event_Client_Zone_Set *ev;
2047 if (qp->ec != ev->ec)
2050 if (qp->zone == ev->zone)
2053 ELOGF("QUICKPANEL", "Change Zone | qp %p old(%p) new(%p)", qp->ec, qp, qp->zone, ev->zone);
2055 qp->zone = ev->zone;
2058 return ECORE_CALLBACK_PASS_ON;
2061 static Evas_Object *
2062 _quickpanel_indicator_object_new(E_Policy_Quickpanel *qp)
2064 Evas_Object *indi_obj;
2067 indi_obj = e_service_region_object_new(qp->ec);
2068 evas_object_name_set(indi_obj, "qp::indicator_obj");
2072 evas_object_repeat_events_set(indi_obj, EINA_FALSE);
2073 /* FIXME: make me move to explicit layer something like POL_LAYER */
2074 evas_object_layer_set(indi_obj, EVAS_LAYER_MAX - 1);
2076 e_service_region_gesture_set(indi_obj,
2077 POL_GESTURE_TYPE_LINE,
2079 _region_obj_cb_gesture_start,
2080 _region_obj_cb_gesture_move,
2081 _region_obj_cb_gesture_end, qp);
2083 evas_object_show(indi_obj);
2085 if (e_config->qp_add_on_desk_smart)
2087 desk = e_desk_current_get(qp->zone);
2088 e_desk_smart_member_add(desk, indi_obj);
2095 _quickpanel_idle_enter(void *data)
2097 E_Policy_Quickpanel *qp;
2101 _changed = EINA_FALSE;
2104 if (EINA_UNLIKELY(!qp))
2107 if (qp->changes.below)
2110 E_Client *below_old;
2112 below = _quickpanel_below_visible_client_get(qp);
2113 if (qp->below != below)
2115 DBG("qp->below '%s'(%p) new_below '%s'(%p)\n",
2116 qp->below ? (qp->below->icccm.name ? qp->below->icccm.name : "") : "",
2118 below ? (below->icccm.name ? below->icccm.name : "") : "",
2121 below_old = qp->below;
2125 * hide the quickpanel, if below client is the stacking client.
2126 * it means to find out whether or not it was launched.
2129 (qp->below->icccm.accepts_focus))
2131 if ((qp->stacking == below) &&
2135 e_policy_aux_message_send(below_old, "quickpanel_state", "hidden", NULL);
2137 e_service_quickpanel_hide(qp->ec);
2141 _e_qp_client_scrollable_update(qp);
2144 qp->changes.below = EINA_FALSE;
2148 return ECORE_CALLBACK_RENEW;
2152 _quickpanel_intercept_hook_show(void *data, E_Client *ec)
2154 E_Policy_Quickpanel *qp;
2157 if (EINA_UNLIKELY(!qp))
2165 ec->visible = EINA_FALSE;
2173 static E_QP_Client *
2174 _e_qp_client_ec_get(E_Client *ec, E_Quickpanel_Type type)
2176 E_QP_Client *qp_client = NULL;
2179 EINA_LIST_FOREACH(qp_clients, l, qp_client)
2181 if ((qp_client->ec == ec) && (qp_client->type == type))
2189 * EINA_TRUE : user can scroll the QP.
2190 * EINA_FALSE: user can't scroll QP since below window doesn't want.
2193 _e_qp_client_scrollable_update(E_Policy_Quickpanel *qp)
2195 Eina_Bool res = EINA_TRUE;
2197 EINA_SAFETY_ON_NULL_RETURN_VAL(qp, EINA_FALSE);
2198 EINA_SAFETY_ON_NULL_RETURN_VAL(qp->ec, EINA_FALSE);
2199 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(qp->ec)), EINA_FALSE);
2201 if (qp->ec->visible)
2203 qp->need_scroll_update = EINA_TRUE;
2206 qp->need_scroll_update = EINA_FALSE;
2210 evas_object_pass_events_set(qp->handler_obj, EINA_FALSE);
2211 evas_object_pass_events_set(qp->indi_obj, EINA_FALSE);
2218 EINTERN E_Service_Quickpanel_Type
2219 e_service_quickpanel_type_get(E_Client *ec)
2221 E_Policy_Quickpanel *qp = NULL;
2222 E_Service_Quickpanel_Type type = E_SERVICE_QUICKPANEL_TYPE_UNKNOWN;
2224 BACKEND_FUNC_CALL_RET(quickpanel_type_get, ec);
2226 qp = _quickpanel_service_get(ec);
2227 if (qp) type = qp->type;
2232 /* window for quickpanel service */
2234 e_service_quickpanel_client_add(E_Client *ec, E_Service_Quickpanel_Type type)
2236 E_Policy_Quickpanel *qp = NULL;
2240 BACKEND_FUNC_CALL(quickpanel_client_add, ec, type);
2242 /* check for client being deleted */
2243 if (e_object_is_del(E_OBJECT(ec))) return;
2245 /* check for wayland pixmap */
2246 if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
2248 /* check if ec has been assigned to zone. */
2249 zone = e_comp_zone_find_by_ec(ec);
2250 EINA_SAFETY_ON_NULL_RETURN(zone);
2252 qp = E_NEW(E_Policy_Quickpanel, 1);
2253 EINA_SAFETY_ON_NULL_RETURN(qp);
2255 ELOGF("QUICKPANEL", "Set Client | qp %p", ec, qp);
2259 qp->show_block = EINA_TRUE;
2260 qp->effect.type = E_SERVICE_QUICKPANEL_EFFECT_TYPE_SWIPE; /* default effect type */
2261 qp->below = _quickpanel_below_visible_client_get(qp);
2264 if (type == E_SERVICE_QUICKPANEL_TYPE_SYSTEM_DEFAULT)
2266 qp->indi_obj = _quickpanel_indicator_object_new(qp);
2267 EINA_SAFETY_ON_NULL_GOTO(qp->indi_obj, indi_err);
2269 e_client_window_role_set(ec, "quickpanel_system_default");
2271 else if (type == E_SERVICE_QUICKPANEL_TYPE_CONTEXT_MENU)
2273 /* don't support swipe type of effect for the qp context menu in public
2274 * you have to make your own qp module and provide backend functions
2275 * if you want to change type of effect of qp context menu
2277 qp->effect.type = E_SERVICE_QUICKPANEL_EFFECT_TYPE_MOVE;
2278 e_client_window_role_set(ec, "quickpanel_context_menu");
2280 else if (type == E_SERVICE_QUICKPANEL_TYPE_APPS_MENU)
2282 /* don't support swipe type of effect for the qp apps menu in public
2283 * you have to make your own qp module and provide backend functions
2284 * if you want to change type of effect of qp apps menu
2286 qp->effect.type = E_SERVICE_QUICKPANEL_EFFECT_TYPE_MOVE;
2287 e_client_window_role_set(ec, "quickpanel_apps_menu");
2290 #ifdef REFACTOR_DESK_AREA
2291 // set quickpanel layer
2292 layer = e_client_layer_get(ec);
2294 // set quickpanel layer
2295 layer = e_client_desk_area_original_layer_get(ec);
2298 if (E_POLICY_QUICKPANEL_LAYER != layer)
2299 e_client_layer_set(ec, E_POLICY_QUICKPANEL_LAYER);
2302 ec->exp_iconify.skip_iconify = 1;
2305 e_policy_animatable_lock(ec, E_POLICY_ANIMATABLE_NEVER, EINA_TRUE);
2313 if (e_config->qp_use_bg_rect)
2316 o = evas_object_rectangle_add(e_comp->evas);
2319 evas_object_layer_set(o, E_POLICY_QUICKPANEL_LAYER);
2320 evas_object_name_set(o, "qp::bg_rect");
2321 evas_object_move(o, 0, 0);
2322 evas_object_resize(o, qp->zone->w, qp->zone->h);
2323 evas_object_color_set(o, 0, 0, 0, 0);
2324 evas_object_lower(o);
2329 /* add quickpanel to force update list of zone */
2330 e_zone_orientation_force_update_add(qp->zone, ec);
2334 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW, _quickpanel_client_evas_cb_show, qp);
2335 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_HIDE, _quickpanel_client_evas_cb_hide, qp);
2336 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOVE, _quickpanel_client_evas_cb_move, qp);
2337 E_CLIENT_HOOK_APPEND(qp->hooks, E_CLIENT_HOOK_DEL, _quickpanel_hook_client_del, qp);
2338 E_LIST_HANDLER_APPEND(qp->events, E_EVENT_CLIENT_ROTATION_CHANGE_BEGIN, _quickpanel_cb_rotation_begin, qp);
2339 E_LIST_HANDLER_APPEND(qp->events, E_EVENT_CLIENT_ROTATION_CHANGE_CANCEL, _quickpanel_cb_rotation_cancel, qp);
2340 E_LIST_HANDLER_APPEND(qp->events, E_EVENT_CLIENT_ROTATION_CHANGE_END, _quickpanel_cb_rotation_done, qp);
2341 E_LIST_HANDLER_APPEND(qp->events, E_EVENT_CLIENT_SHOW, _quickpanel_cb_client_show, qp);
2342 E_LIST_HANDLER_APPEND(qp->events, E_EVENT_CLIENT_HIDE, _quickpanel_cb_client_hide, qp);
2343 E_LIST_HANDLER_APPEND(qp->events, E_EVENT_CLIENT_MOVE, _quickpanel_cb_client_move, qp);
2344 E_LIST_HANDLER_APPEND(qp->events, E_EVENT_CLIENT_STACK, _quickpanel_cb_client_stack, qp);
2345 E_LIST_HANDLER_APPEND(qp->events, E_EVENT_CLIENT_REMOVE, _quickpanel_cb_client_remove, qp);
2346 E_LIST_HANDLER_APPEND(qp->events, E_EVENT_CLIENT_BUFFER_CHANGE, _quickpanel_cb_buffer_change, qp);
2347 E_LIST_HANDLER_APPEND(qp->events, E_EVENT_CLIENT_FOCUS_IN, _quickpanel_cb_client_focus_in, qp);
2348 E_LIST_HANDLER_APPEND(qp->events, E_EVENT_CLIENT_ZONE_SET, _quickpanel_cb_client_zone_set, qp);
2349 E_LIST_HANDLER_APPEND(qp->events, E_EVENT_DESK_GEOMETRY_CHANGE, _quickpanel_cb_desk_geometry_change, qp);
2351 E_COMP_OBJECT_INTERCEPT_HOOK_APPEND(qp->intercept_hooks, E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, _quickpanel_intercept_hook_show, qp);
2353 qp->idle_enterer = ecore_idle_enterer_add(_quickpanel_idle_enter, qp);
2355 qp_services = eina_list_append(qp_services, qp);
2364 e_service_quickpanel_client_del(E_Client *ec)
2366 E_Policy_Quickpanel *qp;
2369 BACKEND_FUNC_CALL(quickpanel_client_del, ec);
2371 EINA_LIST_FOREACH_SAFE(qp_services, l, ll, qp)
2375 _quickpanel_free(qp);
2382 e_service_quickpanel_effect_type_set(E_Client *ec, E_Service_Quickpanel_Effect_Type type)
2384 E_Policy_Quickpanel *qp;
2386 BACKEND_FUNC_CALL(quickpanel_effect_type_set, ec, type);
2388 qp = _quickpanel_service_get(ec);
2395 if (qp->effect.type == type)
2398 qp->effect.type = type;
2401 case E_SERVICE_QUICKPANEL_EFFECT_TYPE_SWIPE:
2402 ec->lock_client_location = 1;
2403 e_policy_user_geometry_set(ec, E_POLICY_USERGEOM_SERVICE, EINA_FALSE);
2404 if ((ec->maximized == E_MAXIMIZE_NONE) &&
2405 (qp->saved_maximize != E_MAXIMIZE_NONE))
2406 e_client_maximize(ec, qp->saved_maximize);
2408 case E_SERVICE_QUICKPANEL_EFFECT_TYPE_MOVE:
2409 ec->lock_client_location = 0;
2410 e_policy_user_geometry_set(ec, E_POLICY_USERGEOM_SERVICE, EINA_TRUE);
2411 if (ec->maximized != E_MAXIMIZE_NONE)
2413 qp->saved_maximize = ec->maximized;
2414 e_client_unmaximize(ec, ec->maximized);
2416 e_client_util_move_resize_without_frame(ec, 0, 0, qp->zone->w, qp->zone->h);
2418 case E_SERVICE_QUICKPANEL_EFFECT_TYPE_APP_CUSTOM:
2419 WRN("APP_CUSTOM effect type is not supported yet");
2423 ERR("Unkown effect type");
2429 e_service_quickpanel_scroll_lock_set(E_Client *ec, Eina_Bool lock)
2431 E_Policy_Quickpanel *qp = NULL;
2433 BACKEND_FUNC_CALL(quickpanel_scroll_lock_set, ec, lock);
2435 qp = _quickpanel_service_get(ec);
2438 if (qp->scroll_lock == lock)
2441 ELOGF("QUICKPANEL", "Scroll lock is set to %d", NULL, lock);
2442 qp->scroll_lock = lock;
2446 e_service_quickpanel_region_set(E_Client *ec, int type, int angle, Eina_Tiler *tiler)
2448 E_Policy_Quickpanel *qp;
2449 E_Policy_Angle_Map ridx;
2451 BACKEND_FUNC_CALL_RET(quickpanel_region_set, ec, type, angle, tiler);
2453 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), EINA_FALSE);
2455 qp = _quickpanel_service_get(ec);
2456 EINA_SAFETY_ON_NULL_RETURN_VAL(qp, EINA_FALSE);
2458 ridx = e_policy_angle_map(angle);
2459 if (type == E_QUICKPANEL_REGION_TYPE_HANDLER)
2460 _quickpanel_handler_region_set(qp, ridx, tiler);
2461 else if (type == E_QUICKPANEL_REGION_TYPE_CONTENTS)
2462 _quickpanel_contents_region_set(qp, ridx, tiler);
2468 e_service_quickpanel_show(E_Client *ec)
2470 E_Policy_Quickpanel *qp;
2472 BACKEND_FUNC_CALL(quickpanel_show, ec);
2474 qp = _quickpanel_service_get(ec);
2475 EINA_SAFETY_ON_NULL_RETURN(qp);
2476 EINA_SAFETY_ON_NULL_RETURN(qp->ec);
2477 EINA_SAFETY_ON_TRUE_RETURN(e_object_is_del(E_OBJECT(qp->ec)));
2479 _e_qp_srv_visible_set(qp, EINA_TRUE);
2483 e_service_quickpanel_hide(E_Client *ec)
2485 E_Policy_Quickpanel *qp;
2487 BACKEND_FUNC_CALL(quickpanel_hide, ec);
2489 qp = _quickpanel_service_get(ec);
2490 EINA_SAFETY_ON_NULL_RETURN(qp);
2491 EINA_SAFETY_ON_NULL_RETURN(qp->ec);
2492 EINA_SAFETY_ON_TRUE_RETURN(e_object_is_del(E_OBJECT(qp->ec)));
2494 _e_qp_srv_visible_set(qp, EINA_FALSE);
2497 /* check if at least one quickpanel is visible */
2499 e_qps_visible_get(void)
2501 E_Policy_Quickpanel *qp;
2507 BACKEND_FUNC_CALL_RET(qps_visible_get);
2509 EINA_LIST_FOREACH(qp_services, l, qp)
2513 if (e_object_is_del(E_OBJECT(ec))) continue;
2515 evas_object_geometry_get(ec->frame,
2518 if (E_INTERSECTS(x, y, w, h,
2524 vis = evas_object_visible_get(ec->frame);
2525 if (vis) return EINA_TRUE;
2533 e_qp_visible_get(E_Client *ec, E_Quickpanel_Type type)
2535 E_Policy_Quickpanel *qp;
2536 E_QP_Client *qp_client;
2537 Eina_Bool vis = EINA_FALSE;
2540 BACKEND_FUNC_CALL_RET(qp_visible_get, ec, type);
2542 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
2543 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), EINA_FALSE);
2545 qp_client = _e_qp_client_ec_get(ec, type);
2546 EINA_SAFETY_ON_NULL_RETURN_VAL(qp_client, EINA_FALSE);
2548 qp = _quickpanel_get_with_client_type(qp_client);
2549 EINA_SAFETY_ON_NULL_RETURN_VAL(qp, EINA_FALSE);
2550 EINA_SAFETY_ON_NULL_RETURN_VAL(qp->ec, EINA_FALSE);
2552 evas_object_geometry_get(qp->ec->frame, &x, &y, &w, &h);
2554 if (E_INTERSECTS(x, y, w, h, qp->zone->x, qp->zone->y, qp->zone->w, qp->zone->h))
2555 vis = evas_object_visible_get(qp->ec->frame);
2561 e_qp_orientation_get(E_Client *ec, E_Quickpanel_Type type)
2563 E_Policy_Quickpanel *qp;
2564 E_QP_Client *qp_client;
2566 BACKEND_FUNC_CALL_RET(qp_orientation_get, ec, type);
2568 qp_client = _e_qp_client_ec_get(ec, type);
2569 EINA_SAFETY_ON_NULL_RETURN_VAL(qp_client, EINA_FALSE);
2571 qp = _quickpanel_get_with_client_type(qp_client);
2572 EINA_SAFETY_ON_NULL_RETURN_VAL(qp, E_POLICY_ANGLE_MAP_0);
2573 EINA_SAFETY_ON_NULL_RETURN_VAL(qp->ec, E_POLICY_ANGLE_MAP_0);
2574 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(qp->ec)), E_POLICY_ANGLE_MAP_0);
2576 return qp->rotation;
2580 e_qp_client_add(E_Client *ec, E_Quickpanel_Type type)
2582 E_QP_Client *qp_client;
2584 BACKEND_FUNC_CALL(qp_client_add, ec, type);
2586 EINA_SAFETY_ON_NULL_RETURN(ec);
2587 EINA_SAFETY_ON_TRUE_RETURN(e_object_is_del(E_OBJECT(ec)));
2589 qp_client = _e_qp_client_ec_get(ec, type);
2596 qp_client = E_NEW(E_QP_Client, 1);
2597 EINA_SAFETY_ON_NULL_RETURN(qp_client);
2601 qp_client->hint.vis = EINA_TRUE;
2602 qp_client->hint.scrollable = E_QUICKPANEL_CLIENT_SCROLL_STATE_SET;
2603 qp_client->type = type;
2605 qp_clients = eina_list_append(qp_clients, qp_client);
2609 e_qp_client_del(E_Client *ec, E_Quickpanel_Type type)
2611 E_QP_Client *qp_client;
2613 BACKEND_FUNC_CALL(qp_client_del, ec, type);
2615 EINA_SAFETY_ON_NULL_RETURN(ec);
2617 qp_client = _e_qp_client_ec_get(ec, type);
2618 EINA_SAFETY_ON_NULL_RETURN(qp_client);
2621 if (qp_client->ref != 0) return;
2623 qp_clients = eina_list_remove(qp_clients, qp_client);
2629 _check_scrollable_state(E_QP_Client *qp_client)
2631 if (qp_client->hint.scrollable == E_QUICKPANEL_CLIENT_SCROLL_STATE_SET)
2633 else if (qp_client->hint.scrollable == E_QUICKPANEL_CLIENT_SCROLL_STATE_UNSET)
2637 E_Policy_Quickpanel *qp;
2638 qp = _quickpanel_get_with_client_type(qp_client);
2639 if (!qp) return EINA_FALSE;
2641 return _e_qp_check_scrollable(qp);
2646 e_qp_client_show(E_Client *ec, E_Quickpanel_Type type)
2648 E_Policy_Quickpanel *qp;
2649 E_QP_Client *qp_client;
2651 ELOGF("QUICKPANEL", "Request to Show Quickpanel (type:%d)", ec, type);
2652 BACKEND_FUNC_CALL(qp_client_show, ec, type);
2654 qp_client = _e_qp_client_ec_get(ec, type);
2655 EINA_SAFETY_ON_NULL_RETURN(qp_client);
2657 Eina_Bool scrollable = _check_scrollable_state(qp_client);
2660 ELOGF("QUICKPANEL", "Doesn't Show Quickpanel. scrollable_state:%d", ec, qp_client->hint.scrollable);
2664 qp = _quickpanel_get_with_client_type(qp_client);
2665 EINA_SAFETY_ON_NULL_RETURN(qp);
2666 EINA_SAFETY_ON_NULL_RETURN(qp->ec);
2667 EINA_SAFETY_ON_TRUE_RETURN(e_object_is_del(E_OBJECT(qp->ec)));
2669 _e_qp_srv_visible_set(qp, EINA_TRUE);
2673 e_qp_client_hide(E_Client *ec, E_Quickpanel_Type type)
2675 E_Policy_Quickpanel *qp;
2676 E_QP_Client *qp_client;
2678 ELOGF("QUICKPANEL", "Request to Hide Quickpanel (type:%d)", ec, type);
2679 BACKEND_FUNC_CALL(qp_client_hide, ec, type);
2681 qp_client = _e_qp_client_ec_get(ec, type);
2682 EINA_SAFETY_ON_NULL_RETURN(qp_client);
2684 Eina_Bool scrollable = _check_scrollable_state(qp_client);
2687 ELOGF("QUICKPANEL", "Doesn't Hide Quickpanel. scrollable_state:%d", ec, qp_client->hint.scrollable);
2691 qp = _quickpanel_get_with_client_type(qp_client);
2692 EINA_SAFETY_ON_NULL_RETURN(qp);
2693 EINA_SAFETY_ON_NULL_RETURN(qp->ec);
2694 EINA_SAFETY_ON_TRUE_RETURN(e_object_is_del(E_OBJECT(qp->ec)));
2696 _e_qp_srv_visible_set(qp, EINA_FALSE);
2700 e_qp_client_scrollable_set(E_Client *ec, E_Quickpanel_Type type, Eina_Bool set)
2703 USE e_qp_client_scrollable_state_set() function instead of this function.
2704 This will be DEPRECATED.
2708 ELOGF("QUICKPANEL", "Request to Set scrollable state of Quickpanel (type:%d) to %d", ec, type, set);
2709 BACKEND_FUNC_CALL_RET(qp_client_scrollable_set, ec, type, set);
2712 ret = _e_qp_client_scrollable_state_set(ec, type, E_QUICKPANEL_CLIENT_SCROLL_STATE_SET);
2714 ret = _e_qp_client_scrollable_state_set(ec, type, E_QUICKPANEL_CLIENT_SCROLL_STATE_UNSET);
2720 e_qp_client_scrollable_get(E_Client *ec, E_Quickpanel_Type type)
2723 USE e_qp_client_scrollable_state_get() function instead of this function.
2724 This will be DEPRECATED.
2726 int scrollable_state;
2728 BACKEND_FUNC_CALL_RET(qp_client_scrollable_get, ec, type);
2730 scrollable_state = _e_qp_client_scrollable_state_get(ec, type);
2731 if (scrollable_state == E_QUICKPANEL_CLIENT_SCROLL_STATE_UNSET)
2738 _e_qp_client_scrollable_state_set(E_Client *ec, E_Quickpanel_Type type, E_Quickpanel_Client_Scroll_State state)
2740 E_Policy_Quickpanel *qp;
2741 E_QP_Client *qp_client;
2743 qp_client = _e_qp_client_ec_get(ec, type);
2744 EINA_SAFETY_ON_NULL_RETURN_VAL(qp_client, EINA_FALSE);
2746 if (qp_client->hint.scrollable != state)
2747 qp_client->hint.scrollable = state;
2749 qp = _quickpanel_get_with_client_type(qp_client);
2750 EINA_SAFETY_ON_NULL_RETURN_VAL(qp, EINA_FALSE);
2751 EINA_SAFETY_ON_NULL_RETURN_VAL(qp->ec, EINA_FALSE);
2752 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(qp->ec)), EINA_FALSE);
2754 _e_qp_client_scrollable_update(qp);
2759 static E_Quickpanel_Client_Scroll_State
2760 _e_qp_client_scrollable_state_get(E_Client *ec, E_Quickpanel_Type type)
2762 E_QP_Client *qp_client;
2764 qp_client = _e_qp_client_ec_get(ec, type);
2765 EINA_SAFETY_ON_NULL_RETURN_VAL(qp_client, E_QUICKPANEL_CLIENT_SCROLL_STATE_UNSET);
2767 return qp_client->hint.scrollable;
2771 e_qp_client_scrollable_state_set(E_Client *ec, E_Quickpanel_Type type, E_Quickpanel_Client_Scroll_State state)
2773 ELOGF("QUICKPANEL", "Request to Set scrollable state of Quickpanel(type:%d) to %d", ec, type, state);
2774 BACKEND_FUNC_CALL_RET(qp_client_scrollable_state_set, ec, type, state);
2776 return _e_qp_client_scrollable_state_set(ec, type, state);
2779 EINTERN E_Quickpanel_Client_Scroll_State
2780 e_qp_client_scrollable_state_get(E_Client *ec, E_Quickpanel_Type type)
2782 E_QP_Client *qp_client;
2784 BACKEND_FUNC_CALL_RET(qp_client_scrollable_state_get, ec, type);
2786 qp_client = _e_qp_client_ec_get(ec, type);
2787 EINA_SAFETY_ON_NULL_RETURN_VAL(qp_client, EINA_FALSE);
2789 return qp_client->hint.scrollable;
2793 e_service_quickpanel_module_func_set(E_QP_Mgr_Funcs *fp)
2795 EINA_SAFETY_ON_FALSE_RETURN_VAL(e_config->use_module_srv.qp, EINA_FALSE);
2796 EINA_SAFETY_ON_FALSE_RETURN_VAL((qp_mgr_funcs == NULL), EINA_FALSE);
2797 EINA_SAFETY_ON_NULL_RETURN_VAL(fp, EINA_FALSE);
2799 qp_mgr_funcs = E_NEW(E_QP_Mgr_Funcs, 1);
2800 EINA_SAFETY_ON_NULL_RETURN_VAL(qp_mgr_funcs, EINA_FALSE);
2802 qp_mgr_funcs->quickpanel_client_add = fp->quickpanel_client_add;
2803 qp_mgr_funcs->quickpanel_client_del = fp->quickpanel_client_del;
2804 qp_mgr_funcs->quickpanel_show = fp->quickpanel_show;
2805 qp_mgr_funcs->quickpanel_hide = fp->quickpanel_hide;
2806 qp_mgr_funcs->quickpanel_region_set = fp->quickpanel_region_set;
2807 qp_mgr_funcs->quickpanel_effect_type_set = fp->quickpanel_effect_type_set;
2808 qp_mgr_funcs->quickpanel_scroll_lock_set = fp->quickpanel_scroll_lock_set;
2809 qp_mgr_funcs->quickpanel_type_get = fp->quickpanel_type_get;
2810 qp_mgr_funcs->qps_visible_get = fp->qps_visible_get;
2811 qp_mgr_funcs->qp_visible_get = fp->qp_visible_get;
2812 qp_mgr_funcs->qp_orientation_get = fp->qp_orientation_get;
2813 qp_mgr_funcs->qp_client_add = fp->qp_client_add;
2814 qp_mgr_funcs->qp_client_del = fp->qp_client_del;
2815 qp_mgr_funcs->qp_client_show = fp->qp_client_show;
2816 qp_mgr_funcs->qp_client_hide = fp->qp_client_hide;
2817 qp_mgr_funcs->qp_client_scrollable_set = fp->qp_client_scrollable_set;
2818 qp_mgr_funcs->qp_client_scrollable_get = fp->qp_client_scrollable_get;
2819 qp_mgr_funcs->qp_client_scrollable_state_set = fp->qp_client_scrollable_state_set;
2820 qp_mgr_funcs->qp_client_scrollable_state_get = fp->qp_client_scrollable_state_get;
2825 e_service_quickpanel_module_func_unset(void)
2827 EINA_SAFETY_ON_FALSE_RETURN_VAL(e_config->use_module_srv.qp, EINA_FALSE);
2828 EINA_SAFETY_ON_NULL_RETURN_VAL(qp_mgr_funcs, EINA_FALSE);
2830 E_FREE(qp_mgr_funcs);
2836 e_service_quickpanels_get(void)
2838 Eina_List *l, *list = NULL;
2839 E_Policy_Quickpanel *qp;
2841 EINA_LIST_FOREACH(qp_services, l, qp)
2843 list = eina_list_append(list, qp->ec);