5 = keys that return objects =
6 - E_Client: the client associated with the object (E_Client*)
7 - comp_smart_obj: cw->smart_obj (Evas_Object*)
8 - comp_obj: cw (E_Comp_Object*)
10 = keys that are bool flags =
11 - client_restack: client needs a protocol-level restack
12 - comp_override: object is triggering a nocomp override to force compositing
13 - comp_ref: object has a ref from visibility animations
14 - comp_showing: object is currently running its show animation
15 - comp_hiding: object is currently running its hiding animation
16 - comp_object: object is a compositor-created object
17 - comp_object_skip: object has a name which prohibits theme shadows
18 - comp_object-to_del: list of objects which will be deleted when this object is deleted
19 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
20 - effect_running: object is animating by external module
23 #define UPDATE_MAX 512 // same as evas
24 #define FAILURE_MAX 2 // seems reasonable
25 #define SMART_NAME "e_comp_object"
26 #define INPUT_OBJ_SMART_NAME "input_object"
28 /* for non-util functions */
29 #define API_ENTRY E_Comp_Object *cw; \
30 cw = evas_object_smart_data_get(obj); \
31 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
33 /* for util functions (obj may or may not be E_Comp_Object */
34 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
37 CRI("YOU PASSED NULL! ARGH!"); \
40 cw = evas_object_smart_data_get(obj); \
41 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
43 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
45 /* enable for lots of client size info in console output */
47 # define e_util_size_debug_set(x, y)
50 /* enable along with display-specific damage INF calls to enable render tracing
54 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
56 #define RENDER_DEBUG(...)
59 typedef struct _E_Comp_Object
63 int x, y, w, h; // geometry
67 E_Comp_Object_Frame client_inset;
77 Eina_Stringshare *frame_theme;
78 Eina_Stringshare *frame_name;
79 Eina_Stringshare *visibility_effect; //effect when toggling visibility
81 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
83 Evas_Object *smart_obj; // smart object
84 Evas_Object *clip; // clipper over effect object
85 Evas_Object *input_obj; // input smart object
86 Evas_Object *obj; // composite object
87 Evas_Object *frame_object; // for client frames
88 Evas_Object *shobj; // shadow object
89 Evas_Object *effect_obj; // effects object
90 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
95 Evas_Object *transform_tranp_obj;// transform transp rect obj
96 Evas_Object *default_input_obj; // default input object
97 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
98 Eina_List *obj_mirror; // extra mirror objects
99 Eina_Tiler *updates; //render update regions
100 Eina_Tiler *pending_updates; //render update regions which are about to render
102 Evas_Native_Surface *ns; //for custom gl rendering
104 struct wl_listener buffer_destroy_listener;
106 unsigned int update_count; // how many updates have happened to this obj
108 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
110 unsigned int animating; // it's busy animating
111 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
112 unsigned int force_visible; //number of visible obj_mirror objects
113 Eina_Bool delete_pending : 1; // delete pending
114 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
115 Eina_Bool showing : 1; // object is currently in "show" animation
116 Eina_Bool hiding : 1; // object is currently in "hide" animation
117 Eina_Bool visible : 1; // is visible
119 Eina_Bool shaped : 1; // is shaped
120 Eina_Bool update : 1; // has updates to fetch
121 Eina_Bool redirected : 1; // has updates to fetch
122 Eina_Bool native : 1; // native
124 Eina_Bool nocomp : 1; // nocomp applied
125 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
126 Eina_Bool real_hid : 1; // last hide was a real window unmap
128 Eina_Bool effect_set : 1; //effect_obj has a valid group
129 Eina_Bool effect_running : 1; //effect_obj is playing an animation
130 Eina_Bool effect_clip : 1; //effect_obj is clipped
131 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
133 Eina_Bool updates_exist : 1;
134 Eina_Bool updates_full : 1; // entire object will be updated
136 Eina_Bool force_move : 1;
137 Eina_Bool frame_extends : 1; //frame may extend beyond object size
138 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
139 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
140 Eina_Bool user_alpha_set : 1;
141 Eina_Bool user_alpha : 1;
145 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
146 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
153 } indicator; //indicator object for internal client
157 Evas_Object *mask_obj;
160 int mask_x, mask_y, mask_w, mask_h;
163 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
165 tbm_surface_h tbm_surface;
166 E_Comp_Image_Filter image_filter;
167 Eina_Bool set_mouse_callbacks;
172 E_Comp_Wl_Buffer_Ref buffer_ref;
173 Eina_Bool pending_move_set;
174 int pending_move_x, pending_move_y;
175 Eina_Bool pending_resize_set;
176 int pending_resize_w, pending_resize_h;
177 } render_update_lock;
190 struct wl_signal lower;
191 struct wl_signal show;
192 struct wl_signal hide;
196 typedef struct _E_Input_Rect_Data
202 typedef struct _E_Input_Rect_Smart_Data
204 Eina_List *input_rect_data_list;
206 } E_Input_Rect_Smart_Data;
208 struct E_Comp_Object_Mover
211 E_Comp_Object_Mover_Cb func;
217 static Eina_Inlist *_e_comp_object_movers = NULL;
218 static Evas_Smart *_e_comp_smart = NULL;
219 static Evas_Smart *_e_comp_input_obj_smart = NULL;
221 static int _e_comp_object_hooks_delete = 0;
222 static int _e_comp_object_hooks_walking = 0;
224 static Eina_Inlist *_e_comp_object_hooks[] =
226 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
227 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
228 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
229 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
230 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
231 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
232 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
233 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
236 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
237 static int _e_comp_object_intercept_hooks_delete = 0;
238 static int _e_comp_object_intercept_hooks_walking = 0;
240 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
242 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
243 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
247 static Eina_Bool _damage_trace = EINA_FALSE;
248 static Eina_List *_damage_trace_objs = NULL;
249 static Eina_List *_damage_trace_post_objs = NULL;
251 /* sekrit functionzzz */
252 EINTERN void e_client_focused_set(E_Client *ec);
254 /* emitted every time a new noteworthy comp object is added */
255 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
257 /* ecore event define */
258 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
259 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
260 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
262 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
263 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
264 static void _e_comp_object_dim_update(E_Comp_Object *cw);
265 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
266 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
268 static E_Client *dim_client = NULL;
271 _e_comp_object_hooks_clean(void)
274 E_Comp_Object_Hook *ch;
277 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
278 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
280 if (!ch->delete_me) continue;
281 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
287 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
289 E_Comp_Object_Hook *ch;
290 Eina_Bool ret = EINA_TRUE;
292 if (e_object_is_del(E_OBJECT(ec)))
294 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
295 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
296 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
297 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
298 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
299 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
300 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
301 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
307 e_object_ref(E_OBJECT(ec));
308 _e_comp_object_hooks_walking++;
309 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
311 if (ch->delete_me) continue;
312 if (!(ch->func(ch->data, ec)))
318 _e_comp_object_hooks_walking--;
319 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
320 _e_comp_object_hooks_clean();
322 e_object_unref(E_OBJECT(ec));
327 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
329 _e_comp_object_intercept_hooks_clean(void)
332 E_Comp_Object_Intercept_Hook *ch;
335 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
336 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
338 if (!ch->delete_me) continue;
339 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
345 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
347 E_Comp_Object_Intercept_Hook *ch;
348 Eina_Bool ret = EINA_TRUE;
350 if (e_object_is_del(E_OBJECT(ec))) return ret;
351 e_object_ref(E_OBJECT(ec));
352 _e_comp_object_intercept_hooks_walking++;
353 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
355 if (ch->delete_me) continue;
356 if (!(ch->func(ch->data, ec)))
362 _e_comp_object_intercept_hooks_walking--;
363 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
364 _e_comp_object_intercept_hooks_clean();
366 e_object_unref(E_OBJECT(ec));
373 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
375 E_Event_Comp_Object *ev = event;
378 ec = evas_object_data_get(ev->comp_object, "E_Client");
382 e_object_unref(E_OBJECT(ec));
384 evas_object_unref(ev->comp_object);
389 _e_comp_object_event_add(Evas_Object *obj)
391 E_Event_Comp_Object *ev;
394 if (stopping) return;
395 ev = E_NEW(E_Event_Comp_Object, 1);
396 EINA_SAFETY_ON_NULL_RETURN(ev);
398 evas_object_ref(obj);
399 ev->comp_object = obj;
400 ec = evas_object_data_get(ev->comp_object, "E_Client");
404 e_object_ref(E_OBJECT(ec));
406 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
410 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
412 E_Event_Comp_Object *ev = event;
415 ec = evas_object_data_get(ev->comp_object, "E_Client");
419 e_object_unref(E_OBJECT(ec));
421 evas_object_unref(ev->comp_object);
426 _e_comp_object_event_simple(Evas_Object *obj, int type)
428 E_Event_Comp_Object *ev;
431 ev = E_NEW(E_Event_Comp_Object, 1);
434 evas_object_ref(obj);
435 ev->comp_object = obj;
436 ec = evas_object_data_get(ev->comp_object, "E_Client");
440 e_object_ref(E_OBJECT(ec));
442 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
444 /////////////////////////////////////
447 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
449 E_Comp_Object *cw = data;
451 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
455 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
457 E_Comp_Object *cw = data;
459 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
460 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
463 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
464 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
468 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
470 E_Comp_Object *cw = data;
473 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
474 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
477 /////////////////////////////////////
480 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
484 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
485 if (cw->ec->input_only) return;
487 layer = evas_object_layer_get(obj);
489 if (cw->transform_bg_obj)
491 if (layer != evas_object_layer_get(cw->transform_bg_obj))
493 evas_object_layer_set(cw->transform_bg_obj, layer);
496 evas_object_stack_below(cw->transform_bg_obj, obj);
499 if (cw->transform_tranp_obj)
501 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
503 evas_object_layer_set(cw->transform_tranp_obj, layer);
506 evas_object_stack_below(cw->transform_tranp_obj, obj);
511 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
518 if (!map) return NULL;
520 e_map_util_points_populate_from_object_full(map, obj, 0);
521 e_map_util_points_color_set(map, 255, 255, 255, 255);
523 for (i = 0 ; i < 4 ; ++i)
528 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
529 e_map_point_coord_set(map, i, x, y, 1.0);
536 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
542 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
545 e_comp_object_map_set(obj, map);
546 e_comp_object_map_enable_set(obj, EINA_TRUE);
553 evas_object_map_enable_set(obj, EINA_FALSE);
558 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
564 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
567 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
569 e_comp_object_map_set(obj, map);
570 e_comp_object_map_enable_set(obj, EINA_TRUE);
577 evas_object_map_enable_set(obj, EINA_FALSE);
580 /////////////////////////////////////
582 static inline Eina_Bool
583 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
585 if (num > 1) return EINA_TRUE;
586 if ((rects[0].x == 0) && (rects[0].y == 0) &&
587 ((int)rects[0].w == w) && ((int)rects[0].h == h))
592 /////////////////////////////////////
594 /* add a client to the layer-client list */
596 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
598 E_Comp_Object *layer_cw = NULL;
600 /* try to get the internal data for the layer;
601 * will return NULL for fake layers (eg. wayland)
603 g_rec_mutex_lock(&e_comp->ec_list_mutex);
604 if (e_comp->layers[cw->layer].obj)
606 if (evas_object_smart_smart_get(e_comp->layers[cw->layer].obj))
607 layer_cw = evas_object_smart_data_get(e_comp->layers[cw->layer].obj);
609 if (layer_cw == cw) layer_cw = NULL;
611 e_comp->layers[above->layer].clients = eina_inlist_append_relative(e_comp->layers[above->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(above->ec));
613 e_comp->layers[below->layer].clients = eina_inlist_prepend_relative(e_comp->layers[below->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(below->ec));
614 if ((!above) && (!below))
617 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
619 e_comp->layers[cw->layer].clients = eina_inlist_prepend_relative(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(layer_cw->ec));
620 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
621 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
623 e_comp->layers[cw->layer].clients_count++;
624 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
625 #ifndef E_RELEASE_BUILD
628 E_Client *below_ec = e_client_below_get(cw->ec);
631 g_rec_mutex_lock(&e_comp->ec_list_mutex);
632 if (e_comp->layers[cw->layer].obj == below_ec->frame)
633 CRI("ACK! ec:%p", cw->ec);
634 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
641 _e_comp_object_layers_remove(E_Comp_Object *cw)
643 g_rec_mutex_lock(&e_comp->ec_list_mutex);
644 if (cw->ec && e_comp->layers[cw->layer].clients)
646 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
647 e_comp->layers[cw->layer].clients_count--;
649 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
651 e_comp->layers[cw->layer].objs = eina_inlist_remove(e_comp->layers[cw->layer].objs, EINA_INLIST_GET(cw));
652 e_comp->layers[cw->layer].objs_count--;
656 /////////////////////////////////////
658 _e_comp_object_alpha_set(E_Comp_Object *cw)
660 Eina_Bool alpha = cw->ec->argb;
662 if ((cw->external_content) &&
663 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
668 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
669 if (cw->user_alpha_set) alpha = cw->user_alpha;
671 evas_object_image_alpha_set(cw->obj, alpha);
675 _e_comp_object_shadow(E_Comp_Object *cw)
677 if (e_client_util_shadow_state_get(cw->ec))
678 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
680 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
681 if (cw->frame_object)
682 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
683 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
686 /* convert from the surface coordinates to the buffer coordinates */
688 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
690 E_Comp_Wl_Buffer_Viewport *vp;
691 E_Comp_Wl_Client_Data *cdata;
695 cdata = e_client_cdata_get(ec);
697 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
704 vp = &cdata->scaler.buffer_viewport;
705 transform = e_comp_wl_output_buffer_transform_get(ec);
707 e_pixmap_size_get(ec->pixmap, &bw, &bh);
709 /* for subsurface, it should be swap 90 and 270 */
710 if (e_comp_wl_subsurface_check(ec))
713 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
714 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
715 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
716 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
722 case WL_OUTPUT_TRANSFORM_NORMAL:
723 default: tx = sx, ty = sy; break;
724 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
725 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
726 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
727 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
728 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
729 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
730 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
733 tx *= vp->buffer.scale;
734 ty *= vp->buffer.scale;
741 _e_comp_object_map_transform_rect(E_Client *ec, int sx, int sy, int sw, int sh, int *dx, int *dy, int *dw, int *dh)
749 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
750 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
757 if (dw) *dw = MAX(x1, x2) - mx;
758 if (dh) *dh = MAX(y1, y2) - my;
762 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
763 int *dx, int *dy, int *dw, int *dh)
765 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
766 E_Util_Transform_Rect_Vertex sv, dv;
770 e_pixmap_size_get(ec->pixmap, &bw, &bh);
772 sv = e_util_transform_rect_to_vertices(&rect);
774 for (i = 0; i < 4; i++)
776 double x = 0.0, y = 0.0;
778 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
780 /* if evas decide coordinate is outside of map, it returns (0, 0)
781 in this case, full damage is added.
783 if ((i != 0) && (x == 0.0) && (y == 0.0))
786 dv.vertices[i].vertex[0] = x;
787 dv.vertices[i].vertex[1] = y;
788 dv.vertices[i].vertex[2] = 1.0;
789 dv.vertices[i].vertex[3] = 1.0;
792 rect = e_util_transform_vertices_to_rect(&dv);
794 if (dx) *dx = rect.x;
795 if (dy) *dy = rect.y;
796 if (dw) *dw = rect.w;
797 if (dh) *dh = rect.h;
811 _e_comp_object_map_damage_transform_get(E_Client *ec)
818 if (!e_client_transform_core_enable_get(ec))
821 m = e_client_map_get(ec);
825 e_pixmap_size_get(ec->pixmap, &bw, &bh);
826 if ((bw == 0) || (bh == 0))
839 e_map_point_coord_set(m2, 0, 0, 0, 0);
840 e_map_point_coord_set(m2, 1, bw, 0, 0);
841 e_map_point_coord_set(m2, 2, bw, bh, 0);
842 e_map_point_coord_set(m2, 3, 0, bh, 0);
844 for (i = 0; i < 4; i++)
848 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
849 e_map_point_image_uv_set(m2, i, map_x, map_y);
856 /////////////////////////////////////
858 /* handle evas mouse-in events on client object */
860 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
862 Evas_Event_Mouse_In *ev = event_info;
863 E_Comp_Object *cw = data;
865 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
868 /* handle evas mouse-out events on client object */
870 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
872 Evas_Event_Mouse_Out *ev = event_info;
873 E_Comp_Object *cw = data;
875 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
878 /* handle evas mouse wheel events on client object */
880 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
882 Evas_Event_Mouse_Wheel *ev = event_info;
883 E_Comp_Object *cw = data;
884 E_Binding_Event_Wheel ev2;
887 if (e_client_action_get()) return;
888 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
889 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
892 /* handle evas mouse down events on client object */
894 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
896 Evas_Event_Mouse_Down *ev = event_info;
897 E_Comp_Object *cw = data;
898 E_Binding_Event_Mouse_Button ev2;
901 if (e_client_action_get()) return;
902 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
903 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
906 /* handle evas mouse up events on client object */
908 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
910 Evas_Event_Mouse_Up *ev = event_info;
911 E_Comp_Object *cw = data;
912 E_Binding_Event_Mouse_Button ev2;
915 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
916 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
917 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
920 /* handle evas mouse movement events on client object */
922 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
924 Evas_Event_Mouse_Move *ev = event_info;
925 E_Comp_Object *cw = data;
928 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
929 e_client_mouse_move(cw->ec, &ev->cur.output);
931 /////////////////////////////////////
933 /* helper function for checking compositor themes based on user-defined matches */
935 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
937 if (((m->title) && (!ec->netwm.name)) ||
938 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
940 #if defined(__cplusplus) || defined(c_plusplus)
941 if (((m->clas) && (!ec->icccm.cpp_class)) ||
942 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
945 if (((m->clas) && (!ec->icccm.class)) ||
946 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
950 if (((m->role) && (!ec->icccm.window_role)) ||
951 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
957 if ((int)ec->netwm.type != m->primary_type)
960 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
963 if (m->borderless != 0)
967 if (e_client_util_borderless(ec))
969 if (!(((m->borderless == -1) && (!borderless)) ||
970 ((m->borderless == 1) && (borderless))))
977 if (((ec->icccm.transient_for != 0) ||
980 if (!(((m->dialog == -1) && (!dialog)) ||
981 ((m->dialog == 1) && (dialog))))
984 if (m->accepts_focus != 0)
986 int accepts_focus = 0;
988 if (ec->icccm.accepts_focus)
990 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
991 ((m->accepts_focus == 1) && (accepts_focus))))
1000 if (!(((m->vkbd == -1) && (!vkbd)) ||
1001 ((m->vkbd == 1) && (vkbd))))
1006 if (!(((m->argb == -1) && (!ec->argb)) ||
1007 ((m->argb == 1) && (ec->argb))))
1010 if (m->fullscreen != 0)
1012 int fullscreen = ec->fullscreen;
1014 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1015 ((m->fullscreen == 1) && (fullscreen))))
1022 if (ec->netwm.state.modal)
1024 if (!(((m->modal == -1) && (!modal)) ||
1025 ((m->modal == 1) && (modal))))
1031 /* function for setting up a client's compositor frame theme (cw->shobj) */
1033 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1037 Eina_List *list = NULL, *l;
1038 E_Input_Rect_Data *input_rect_data;
1039 E_Input_Rect_Smart_Data *input_rect_sd;
1041 Eina_Stringshare *reshadow_group = NULL;
1042 Eina_Bool focus = EINA_FALSE, urgent = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1043 Eina_Stringshare *name, *title;
1044 E_Comp_Config *conf = e_comp_config_get();
1046 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1047 /* match correct client type */
1048 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1049 name = cw->ec->icccm.name;
1050 title = cw->ec->icccm.title;
1051 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1052 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1054 /* skipping here is mostly a hack for systray because I hate it */
1057 EINA_LIST_FOREACH(list, l, m)
1059 if (((m->name) && (!name)) ||
1060 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1062 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1066 no_shadow = m->no_shadow;
1067 if (m->shadow_style)
1069 /* fast effects are just themes with "/fast" appended and shorter effect times */
1072 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1073 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1075 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1077 /* default to non-fast style if fast not available */
1080 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1081 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1083 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1085 if (ok && m->visibility_effect)
1086 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1093 if (skip || (cw->ec->e.state.video))
1095 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1097 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1100 if (conf->shadow_style)
1104 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1105 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1107 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1111 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1112 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1114 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1121 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1123 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1127 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1129 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1134 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1139 if (cw->ec->override)
1141 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1142 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1144 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1145 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1151 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1152 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1155 _e_comp_object_shadow(cw);
1158 if (focus || cw->ec->focused || cw->ec->override)
1159 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1161 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1162 if (urgent || cw->ec->urgent)
1163 e_comp_object_signal_emit(cw->smart_obj, "e,state,urgent", "e");
1165 e_comp_object_signal_emit(cw->smart_obj, "e,state,not_urgent", "e");
1167 e_comp_object_signal_emit(cw->smart_obj, "e,state,shaded", "e");
1169 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1171 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1172 /* visibility must always be enabled for re_manage clients to prevent
1173 * pop-in animations every time the user sees a persistent client again;
1174 * applying visibility for iconic clients prevents the client from getting
1177 if (cw->visible || cw->ec->re_manage)
1178 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1180 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1182 /* breaks animation counter */
1183 if (cw->frame_object)
1185 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1186 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1187 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1188 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1194 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1198 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1201 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1203 if (input_rect_data->obj)
1205 pass_event_flag = EINA_TRUE;
1211 if (cw->indicator.obj)
1213 Evas_Object *indicator;
1214 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1215 if (indicator != cw->indicator.obj)
1217 edje_object_part_unswallow(cw->shobj, indicator);
1218 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1219 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1223 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1224 evas_object_pass_events_set(cw->obj, pass_event_flag);
1229 /////////////////////////////////////////////
1232 _e_comp_object_animating_begin(E_Comp_Object *cw)
1235 if (cw->animating == 1)
1237 e_comp->animating++;
1239 e_object_ref(E_OBJECT(cw->ec));
1244 _e_comp_object_animating_end(E_Comp_Object *cw)
1253 if (cw->ec->launching)
1255 if (!cw->ec->extra_animating)
1257 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1258 cw->ec->launching = EINA_FALSE;
1259 if (cw->ec->first_mapped)
1261 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1262 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1265 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1269 e_comp->animating--;
1270 cw->showing = cw->hiding = 0;
1272 if (e_comp->animating == 0)
1273 e_comp_visibility_calculation_set(EINA_TRUE);
1274 /* remove ref from animation start, account for possibility of deletion from unref */
1275 return !!e_object_unref(E_OBJECT(cw->ec));
1281 /* handle the end of a compositor animation */
1283 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1285 E_Comp_Object *cw = data;
1287 /* visible clients which have never been sized are a bug */
1288 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1289 CRI("ACK! ec:%p", cw->ec);
1290 if (!_e_comp_object_animating_end(cw)) return;
1291 if (cw->animating) return;
1292 /* hide only after animation finishes to guarantee a full run of the animation */
1293 if (!cw->defer_hide) return;
1294 if ((!strcmp(emission, "e,action,hide,done")) ||
1295 (!strcmp(emission, "e,action,done")) ||
1296 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1298 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1299 evas_object_hide(cw->smart_obj);
1303 /* run a visibility compositor effect if available, return false if object is dead */
1305 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1311 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1312 if (!cw->effect_running)
1313 _e_comp_object_animating_begin(cw);
1314 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1315 return _e_comp_object_animating_end(cw);
1316 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1317 return _e_comp_object_animating_end(cw);
1319 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1322 zone = e_comp_zone_find_by_ec(cw->ec);
1324 zw = zone->w, zh = zone->h;
1329 zone = e_comp_object_util_zone_get(cw->smart_obj);
1330 if (!zone) zone = e_zone_current_get();
1337 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1338 cw->w, cw->h, zw, zh, x, y}, 8);
1339 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1340 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1343 /////////////////////////////////////////////
1345 /* create necessary objects for clients that e manages */
1347 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1349 if (cw->set_mouse_callbacks) return;
1350 if (!cw->smart_obj) return;
1352 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1353 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1354 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1355 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1356 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1357 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1359 cw->set_mouse_callbacks = EINA_TRUE;
1363 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1365 if (!cw->set_mouse_callbacks) return;
1366 if (!cw->smart_obj) return;
1368 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1369 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1370 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1371 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1372 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1373 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1375 cw->set_mouse_callbacks = EINA_FALSE;
1379 _e_comp_object_setup(E_Comp_Object *cw)
1381 cw->clip = evas_object_rectangle_add(e_comp->evas);
1382 evas_object_move(cw->clip, -9999, -9999);
1383 evas_object_resize(cw->clip, 999999, 999999);
1384 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1385 cw->effect_obj = edje_object_add(e_comp->evas);
1386 evas_object_move(cw->effect_obj, cw->x, cw->y);
1387 evas_object_clip_set(cw->effect_obj, cw->clip);
1388 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1389 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1390 cw->shobj = edje_object_add(e_comp->evas);
1391 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1392 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1393 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1395 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1396 if (cw->ec->override)
1398 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1399 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1400 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1402 else if (!cw->ec->input_only)
1404 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1405 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1406 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1408 cw->real_hid = !cw->ec->input_only;
1409 if (!cw->ec->input_only)
1411 e_util_size_debug_set(cw->effect_obj, 1);
1412 _e_comp_object_mouse_event_callback_set(cw);
1415 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1416 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1417 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1418 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1419 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1420 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1422 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1425 /////////////////////////////////////////////
1427 /* for fast path evas rendering; only called during render */
1429 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1431 E_Comp_Object *cw = data;
1432 E_Client *ec = cw->ec;
1434 int bx, by, bxx, byy;
1436 if (e_object_is_del(E_OBJECT(ec))) return;
1437 if (cw->external_content) return;
1438 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1439 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1442 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1443 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1445 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1447 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1448 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1452 bx = by = bxx = byy = 0;
1453 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1456 Edje_Message_Int_Set *msg;
1457 Edje_Message_Int msg2;
1458 Eina_Bool id = (bx || by || bxx || byy);
1460 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1466 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1468 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1472 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1473 e_comp_client_post_update_add(cw->ec);
1475 else if (e_comp_object_render(ec->frame))
1477 /* apply shape mask if necessary */
1478 if ((!cw->native) && (ec->shaped || ec->shape_changed))
1479 e_comp_object_shape_apply(ec->frame);
1480 ec->shape_changed = 0;
1482 /* shaped clients get precise mouse events to handle transparent pixels */
1483 evas_object_precise_is_inside_set(cw->obj, ec->shaped || ec->shaped_input);
1485 /* queue another render if client is still dirty; cannot refresh here. */
1486 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1487 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1489 if (cw->render_trace)
1491 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1497 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1499 E_Comp_Object *cw = data;
1500 E_Client *ec = cw->ec;
1502 if (e_object_is_del(E_OBJECT(ec))) return;
1503 if (cw->external_content) return;
1504 if (!e_comp->hwc) return;
1506 e_comp_client_render_list_add(cw->ec);
1508 if (!ec->hwc_window) return;
1510 e_hwc_windows_rendered_window_add(ec->hwc_window);
1513 /////////////////////////////////////////////
1516 _e_comp_object_client_pending_resize_add(E_Client *ec,
1519 unsigned int serial)
1521 E_Client_Pending_Resize *pnd;
1523 pnd = E_NEW(E_Client_Pending_Resize, 1);
1527 pnd->serial = serial;
1528 ec->pending_resize = eina_list_append(ec->pending_resize, pnd);
1532 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1534 E_Comp_Object *cw = data;
1537 if (cw->render_update_lock.lock)
1539 cw->render_update_lock.pending_move_x = x;
1540 cw->render_update_lock.pending_move_y = y;
1541 cw->render_update_lock.pending_move_set = EINA_TRUE;
1545 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1546 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1547 (cw->external_content))
1549 /* delay to move until the external content is unset */
1550 cw->ec->changes.pos = 1;
1555 if (cw->ec->move_after_resize)
1557 if ((x != cw->ec->x) || (y != cw->ec->y))
1559 if (!cw->ec->is_cursor)
1560 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1561 e_client_pos_set(cw->ec, x, y);
1562 cw->ec->changes.pos = 1;
1568 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1569 (cw->ec->manage_resize.resize_obj))
1571 e_client_pos_set(cw->ec, x, y);
1572 cw->ec->client.x = x + cw->client_inset.l;
1573 cw->ec->client.y = y + cw->client_inset.t;
1574 e_policy_visibility_client_defer_move(cw->ec);
1578 /* if frame_object does not exist, client_inset indicates CSD.
1579 * this means that ec->client matches cw->x/y, the opposite
1582 fx = (!cw->frame_object) * cw->client_inset.l;
1583 fy = (!cw->frame_object) * cw->client_inset.t;
1584 if ((cw->x == x + fx) && (cw->y == y + fy))
1586 if ((cw->ec->x != x) || (cw->ec->y != y))
1588 /* handle case where client tries to move to position and back very quickly */
1589 e_client_pos_set(cw->ec, x, y);
1590 cw->ec->client.x = x + cw->client_inset.l;
1591 cw->ec->client.y = y + cw->client_inset.t;
1595 if (!cw->ec->maximize_override)
1597 /* prevent moving in some directions while directionally maximized */
1598 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1600 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1603 ix = x + cw->client_inset.l;
1604 iy = y + cw->client_inset.t;
1605 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1606 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1607 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1609 /* prevent moving at all if move isn't allowed in current maximize state */
1610 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1611 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1612 if ((!cw->ec->shading) && (!cw->ec->shaded))
1615 zone = e_comp_zone_find_by_ec(cw->ec);
1618 cw->ec->changes.need_unmaximize = 1;
1619 cw->ec->saved.x = ix - zone->x;
1620 cw->ec->saved.y = iy - zone->y;
1621 cw->ec->saved.w = cw->ec->client.w;
1622 cw->ec->saved.h = cw->ec->client.h;
1628 /* only update during resize if triggered by resize */
1629 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1630 /* delay to move while surface waits paired commit serial*/
1631 if (e_client_pending_geometry_has(cw->ec))
1633 /* do nothing while waiting paired commit serial*/
1637 e_client_pos_set(cw->ec, x, y);
1638 if (cw->ec->new_client)
1640 /* don't actually do anything until first client idler loop */
1641 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1642 cw->ec->changes.pos = 1;
1647 /* only update xy position of client to avoid invalid
1648 * first damage region if it is not a new_client. */
1649 if (!cw->ec->shading)
1651 cw->ec->client.x = ix;
1652 cw->ec->client.y = iy;
1655 if (!cw->frame_object)
1657 evas_object_move(obj, x, y);
1662 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1664 E_Comp_Object *cw = data;
1665 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1668 if (cw->render_update_lock.lock)
1670 cw->render_update_lock.pending_resize_w = w;
1671 cw->render_update_lock.pending_resize_h = h;
1672 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1676 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1678 e_client_size_set(cw->ec, w, h);
1679 evas_object_resize(obj, w, h);
1683 /* if frame_object does not exist, client_inset indicates CSD.
1684 * this means that ec->client matches cw->w/h, the opposite
1687 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1688 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1689 if ((cw->w == w + fw) && (cw->h == h + fh))
1691 if (cw->ec->shading || cw->ec->shaded) return;
1692 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1693 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1694 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1696 /* handle case where client tries to resize itself and back very quickly */
1697 e_client_size_set(cw->ec, w, h);
1698 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1699 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1700 evas_object_smart_callback_call(obj, "client_resize", NULL);
1704 /* guarantee that fullscreen is fullscreen */
1705 zone = e_comp_zone_find_by_ec(cw->ec);
1707 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1709 if (!e_client_transform_core_enable_get(cw->ec))
1712 /* calculate client size */
1713 iw = w - cw->client_inset.l - cw->client_inset.r;
1714 ih = h - cw->client_inset.t - cw->client_inset.b;
1715 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1717 /* prevent resizing while maximized depending on direction and config */
1718 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1719 if ((!cw->ec->shading) && (!cw->ec->shaded))
1721 Eina_Bool reject = EINA_FALSE;
1722 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1724 if (cw->ec->client.h != ih)
1726 cw->ec->saved.h = ih;
1727 cw->ec->saved.y = cw->ec->client.y - zone->y;
1728 reject = cw->ec->changes.need_unmaximize = 1;
1731 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1733 if (cw->ec->client.w != iw)
1735 cw->ec->saved.w = iw;
1736 cw->ec->saved.x = cw->ec->client.x - zone->x;
1737 reject = cw->ec->changes.need_unmaximize = 1;
1747 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1749 /* do nothing until client idler loops */
1750 if ((cw->ec->w != w) || (cw->ec->h != h))
1752 e_client_size_set(cw->ec, w, h);
1753 cw->ec->changes.size = 1;
1758 if ((!cw->ec->internal) && e_client_util_resizing_get(cw->ec) && cw->ec->netwm.sync.request &&
1759 ((cw->ec->w != w) || (cw->ec->h != h)))
1762 /* netwm sync resizes queue themselves and then trigger later on */
1763 _e_comp_object_client_pending_resize_add(cw->ec, iw, ih, cw->ec->netwm.sync.serial);
1765 if (e_client_pending_geometry_has(cw->ec))
1767 /* do nothing while waiting paired commit serial*/
1771 e_client_size_set(cw->ec, w, h);
1772 if ((!cw->ec->shading) && (!cw->ec->shaded))
1774 /* client geom never changes when shading since the client is never altered */
1775 cw->ec->client.w = iw;
1776 cw->ec->client.h = ih;
1777 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1780 /* The size of non-compositing window can be changed, so there is a
1781 * need to check that cw is H/W composited if cw is not redirected.
1782 * And of course we have to change size of evas object of H/W composited cw,
1783 * otherwise cw can't receive input events even if it is shown on the screen.
1785 Eina_Bool redirected = cw->redirected;
1787 redirected = e_comp_is_on_overlay(cw->ec);
1789 if ((!cw->ec->input_only) && (redirected) &&
1790 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1791 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1792 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1793 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1796 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1797 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1799 prev_w = cw->w, prev_h = cw->h;
1800 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1801 /* check shading and clamp to pixmap size for regular clients */
1802 if ((!cw->ec->shading) && (!cw->ec->shaded) && (!cw->ec->input_only) && (!cw->ec->override) &&
1803 (((w - fw != pw) || (h - fh != ph))))
1805 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1806 evas_object_smart_callback_call(obj, "client_resize", NULL);
1808 if (cw->frame_object || cw->ec->input_only)
1809 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1812 if ((cw->w == w) && (cw->h == h))
1814 /* going to be a noop resize which won't trigger smart resize */
1815 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1816 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1818 evas_object_resize(obj, w, h);
1822 evas_object_smart_callback_call(obj, "client_resize", NULL);
1825 if ((!cw->frame_object) && (!cw->ec->input_only))
1827 /* "just do it" for overrides */
1828 evas_object_resize(obj, w, h);
1830 if (!cw->ec->override)
1832 /* shape probably changed for non-overrides */
1833 cw->ec->need_shape_merge |= cw->ec->shaped || cw->ec->shaped_input;
1834 cw->ec->need_shape_export |= cw->ec->shaped;
1835 if (cw->ec->shaped || cw->ec->shaped_input)
1839 /* this fixes positioning jiggles when using a resize mode
1840 * which also changes the client's position
1843 if (cw->frame_object)
1844 x = cw->x, y = cw->y;
1846 x = cw->ec->x, y = cw->ec->y;
1847 switch (cw->ec->resize_mode)
1849 case E_POINTER_RESIZE_BL:
1850 case E_POINTER_RESIZE_L:
1851 evas_object_move(obj, x + prev_w - cw->w, y);
1853 case E_POINTER_RESIZE_TL:
1854 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1856 case E_POINTER_RESIZE_T:
1857 case E_POINTER_RESIZE_TR:
1858 evas_object_move(obj, x, y + prev_h - cw->h);
1867 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1869 E_Comp_Object *cw = data;
1870 E_Comp_Wl_Client_Data *child_cdata;
1871 unsigned int l = e_comp_canvas_layer_map(layer);
1874 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1876 /* doing a compositor effect, follow directions */
1877 _e_comp_object_layer_set(obj, layer);
1878 if (layer == cw->ec->layer) //trying to put layer back
1882 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1883 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1884 if (cw->layer != l) goto layer_set;
1888 e_comp_render_queue();
1890 ec = e_client_above_get(cw->ec);
1891 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1892 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1893 ec = e_client_above_get(ec);
1894 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1896 ec = e_client_below_get(cw->ec);
1897 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1898 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1899 ec = e_client_below_get(ec);
1900 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1902 evas_object_stack_above(obj, ec->frame);
1907 if (ec && (cw->ec->parent == ec))
1909 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1910 evas_object_stack_above(obj, ec->frame);
1912 evas_object_stack_below(obj, ec->frame);
1915 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1921 if (cw->layer == l) return;
1922 if (e_comp_canvas_client_layer_map(layer) == 9999)
1923 return; //invalid layer for clients not doing comp effects
1924 if (cw->ec->fullscreen)
1926 cw->ec->saved.layer = layer;
1929 oldraise = e_config->transient.raise;
1931 /* clamp to valid client layer */
1932 layer = e_comp_canvas_client_layer_map_nearest(layer);
1933 cw->ec->layer = layer;
1934 if (e_config->transient.layer)
1937 Eina_List *list = eina_list_clone(cw->ec->transients);
1939 /* We need to set raise to one, else the child wont
1940 * follow to the new layer. It should be like this,
1941 * even if the user usually doesn't want to raise
1944 e_config->transient.raise = 1;
1945 EINA_LIST_FREE(list, child)
1947 child_cdata = e_client_cdata_get(child);
1948 if (child_cdata && !child_cdata->mapped)
1950 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1953 e_client_layer_set(child, layer);
1957 e_config->transient.raise = oldraise;
1959 _e_comp_object_layers_remove(cw);
1960 cw->layer = e_comp_canvas_layer_map(layer);
1961 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1962 //if (cw->ec->new_client)
1963 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1964 _e_comp_object_layer_set(obj, layer);
1965 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1966 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1967 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1969 /* can't stack a client above its own layer marker */
1970 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1972 if (!cw->visible) return;
1973 e_comp_render_queue();
1974 _e_comp_object_transform_obj_stack_update(obj);
1977 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1980 _e_comp_object_raise(Evas_Object *obj)
1982 evas_object_raise(obj);
1984 if (evas_object_smart_smart_get(obj))
1986 E_Client *ec = e_comp_object_client_get(obj);
1988 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1993 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1995 evas_object_lower(obj);
1997 if (evas_object_smart_smart_get(obj))
1999 E_Client *ec = e_comp_object_client_get(obj);
2002 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2003 wl_signal_emit_mutable(&cw->events.lower, NULL);
2009 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
2011 evas_object_stack_above(obj, target);
2013 if (evas_object_smart_smart_get(obj))
2015 E_Client *ec = e_comp_object_client_get(obj);
2017 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2022 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2024 evas_object_stack_below(obj, target);
2026 if (evas_object_smart_smart_get(obj))
2028 E_Client *ec = e_comp_object_client_get(obj);
2030 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2035 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2037 evas_object_layer_set(obj, layer);
2039 if (evas_object_smart_smart_get(obj))
2041 E_Client *ec = e_comp_object_client_get(obj);
2043 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2048 _e_comp_object_is_pending(E_Client *ec)
2052 if (!ec) return EINA_FALSE;
2054 topmost = e_comp_wl_topmost_parent_get(ec);
2056 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2060 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2062 E_Comp_Object *cw2 = NULL;
2065 Evas_Object *o = stack;
2066 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2068 /* We should consider topmost's layer_pending for subsurface */
2069 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2071 if (_e_comp_object_is_pending(cw->ec))
2072 e_comp_object_layer_update(cw->smart_obj,
2073 raising? stack : NULL,
2074 raising? NULL : stack);
2076 /* obey compositor effects! */
2077 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2078 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2079 stack_cb(cw->smart_obj, stack);
2080 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2081 evas_object_data_del(cw->smart_obj, "client_restack");
2085 cw2 = evas_object_data_get(o, "comp_obj");
2087 /* assume someone knew what they were doing during client init */
2088 if (cw->ec->new_client)
2089 layer = cw->ec->layer;
2090 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2091 layer = cw2->ec->layer;
2093 layer = evas_object_layer_get(stack);
2094 ecstack = e_client_below_get(cw->ec);
2095 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2097 /* some FOOL is trying to restack a layer marker */
2098 if (cw->smart_obj == e_comp->layers[cw->layer].obj) return;
2099 evas_object_layer_set(cw->smart_obj, layer);
2100 /* we got our layer wrangled, return now! */
2101 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2104 /* check if we're stacking below another client */
2107 /* check for non-client layer object */
2108 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2110 /* find an existing client to use for layering
2111 * by walking up the object stack
2113 * this is guaranteed to be pretty quick since we'll either:
2114 * - run out of client layers
2115 * - find a stacking client
2117 o = evas_object_above_get(o);
2118 if ((!o) || (o == cw->smart_obj)) break;
2119 if (evas_object_layer_get(o) != layer)
2121 /* reached the top client layer somehow
2122 * use top client object
2124 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2127 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2128 * return here since the top client layer window
2133 ec = e_client_top_get();
2138 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2141 if (cw2 && cw->layer != cw2->layer)
2144 /* remove existing layers */
2145 _e_comp_object_layers_remove(cw);
2148 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2149 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2150 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2151 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2152 else //if no stacking objects found, either raise or lower
2153 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2156 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2158 /* find new object for stacking if cw2 is on state of layer_pending */
2159 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2161 E_Client *new_stack = NULL, *current_ec = NULL;
2162 current_ec = cw2->ec;
2165 while ((new_stack = e_client_below_get(current_ec)))
2167 current_ec = new_stack;
2168 if (new_stack == cw->ec) continue;
2169 if (new_stack->layer != cw2->ec->layer) break;
2170 if (!_e_comp_object_is_pending(new_stack)) break;
2172 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2173 stack = new_stack->frame;
2176 /* stack it above layer object */
2178 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2179 stack = e_comp->layers[below_layer].obj;
2184 while ((new_stack = e_client_above_get(current_ec)))
2186 current_ec = new_stack;
2187 if (new_stack == cw->ec) continue;
2188 if (new_stack->layer != cw2->ec->layer) break;
2189 if (!_e_comp_object_is_pending(new_stack)) break;
2191 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2192 stack = new_stack->frame;
2194 stack = e_comp->layers[cw2->layer].obj;
2198 /* set restack if stacking has changed */
2199 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2200 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2201 stack_cb(cw->smart_obj, stack);
2202 if (e_comp->layers[cw->layer].obj)
2203 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2205 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2207 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2208 evas_object_data_del(cw->smart_obj, "client_restack");
2209 if (!cw->visible) return;
2210 e_comp_render_queue();
2214 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2216 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2218 if (evas_object_below_get(obj) == above)
2220 e_comp_object_layer_update(obj, above, NULL);
2224 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2225 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2226 _e_comp_object_transform_obj_stack_update(obj);
2227 _e_comp_object_transform_obj_stack_update(above);
2232 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2234 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2235 if (evas_object_above_get(obj) == below)
2237 e_comp_object_layer_update(obj, NULL, below);
2241 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2242 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2243 if (evas_object_smart_smart_get(obj))
2244 _e_comp_object_transform_obj_stack_update(obj);
2245 if (evas_object_smart_smart_get(below))
2246 _e_comp_object_transform_obj_stack_update(below);
2251 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2253 E_Comp_Object *cw = data;
2256 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2258 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2260 if (cw->ec->layer_pending)
2261 e_comp_object_layer_update(obj, NULL, obj);
2263 _e_comp_object_lower(cw, obj);
2266 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2267 o = evas_object_below_get(obj);
2268 _e_comp_object_layers_remove(cw);
2269 /* prepend to client list since this client should be the first item now */
2270 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2271 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2272 if (obj == e_comp->layers[cw->layer].obj) goto end; //never lower a layer marker!
2273 evas_object_data_set(obj, "client_restack", (void*)1);
2274 _e_comp_object_lower(cw, obj);
2275 evas_object_data_del(obj, "client_restack");
2276 if (!cw->visible) goto end;
2277 e_comp_render_queue();
2278 _e_comp_object_transform_obj_stack_update(obj);
2285 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2287 E_Comp_Object *cw = data;
2290 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2292 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2294 if (cw->ec->layer_pending)
2296 int obj_layer = evas_object_layer_get(obj);
2297 if (cw->ec->layer != obj_layer)
2298 e_comp_object_layer_update(obj, NULL, NULL);
2301 _e_comp_object_raise(obj);
2304 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2305 o = evas_object_above_get(obj);
2307 E_Client *ecabove = e_client_above_get(cw->ec);
2308 if (ecabove && (ecabove->frame == e_comp->layers[cw->layer].obj) &&
2309 (ecabove->frame == o)) goto end; //highest below marker
2311 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2312 if (obj == e_comp->layers[cw->layer].obj) //never raise a non-layer marker!
2313 _e_comp_object_raise(obj);
2318 /* still stack below override below the layer marker */
2319 for (op = o = e_comp->layers[cw->layer].obj;
2320 o && o != e_comp->layers[cw->layer - 1].obj;
2321 op = o, o = evas_object_below_get(o))
2323 if (evas_object_smart_smart_get(o))
2327 ec = e_comp_object_client_get(o);
2328 if (ec && (!ec->override)) break;
2331 _e_comp_object_stack_below(obj, op);
2332 e_client_focus_defer_set(cw->ec);
2334 if (!cw->visible) goto end;
2335 e_comp_render_queue();
2336 _e_comp_object_transform_obj_stack_update(obj);
2343 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2345 E_Comp_Object *cw = data;
2347 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2348 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2350 ELOGF("COMP", "Hide. intercepted", cw->ec);
2355 if (cw->ec->launching == EINA_TRUE)
2357 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2358 cw->ec->launching = EINA_FALSE;
2363 /* hidden flag = just do it */
2364 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2365 evas_object_hide(obj);
2367 wl_signal_emit_mutable(&cw->events.hide, NULL);
2372 if (cw->ec->input_only)
2374 /* input_only = who cares */
2375 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2376 evas_object_hide(obj);
2378 wl_signal_emit_mutable(&cw->events.hide, NULL);
2382 /* already hidden or currently animating */
2383 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2385 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2389 /* don't try hiding during shutdown */
2390 cw->defer_hide |= stopping;
2391 if (!cw->defer_hide)
2393 if ((!cw->ec->iconic) && (!cw->ec->override))
2394 /* unset delete requested so the client doesn't break */
2395 cw->ec->delete_requested = 0;
2396 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2398 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2399 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2402 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2405 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2407 _e_comp_object_animating_begin(cw);
2408 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2410 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2411 cw->defer_hide = !!cw->animating;
2413 e_comp_object_effect_set(obj, NULL);
2416 if (cw->animating) return;
2417 /* if we have no animations running, go ahead and hide */
2419 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2420 evas_object_hide(obj);
2422 wl_signal_emit_mutable(&cw->events.hide, NULL);
2426 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2428 E_Client *ec = cw->ec;
2431 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2433 if (ec->show_pending.count > 0)
2435 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2436 ec->show_pending.running = EINA_TRUE;
2440 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2441 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2443 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2448 ELOGF("COMP", "show_helper. cw(v:%d,a:%d,dh:%d,ct:%d,u:%p,s(%d,%d)), ec(i:%d(%d,%d),o:%d,g:%d,n:%d)", ec,
2449 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2450 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2453 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2456 if (ec->iconic && cw->animating)
2458 /* triggered during iconify animation */
2459 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2462 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2465 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2466 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2468 evas_object_move(cw->smart_obj, ec->x, ec->y);
2469 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2470 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2472 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2473 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2476 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2477 evas_object_show(cw->smart_obj);
2480 e_client_focus_defer_set(ec);
2484 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2488 pw = ec->client.w, ph = ec->client.h;
2490 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2492 ec->changes.visible = !ec->hidden;
2495 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2499 cw->updates = eina_tiler_new(pw, ph);
2502 ec->changes.visible = !ec->hidden;
2505 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2510 eina_tiler_tile_size_set(cw->updates, 1, 1);
2513 /* ignore until client idler first run */
2514 ec->changes.visible = !ec->hidden;
2517 ELOGF("COMP", "show_helper. return. new_client", ec);
2524 evas_object_move(cw->smart_obj, ec->x, ec->y);
2525 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2526 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2527 evas_object_show(cw->smart_obj);
2530 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2532 /* start_drag not received */
2533 ec->changes.visible = 1;
2536 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2539 /* re-set geometry */
2540 evas_object_move(cw->smart_obj, ec->x, ec->y);
2541 /* force resize in case it hasn't happened yet, or just to update size */
2542 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2543 if ((cw->w < 1) || (cw->h < 1))
2545 /* if resize didn't go through, try again */
2546 ec->visible = ec->changes.visible = 1;
2548 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2551 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2552 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2553 e_pixmap_clear(ec->pixmap);
2555 if (cw->real_hid && w && h)
2558 /* force comp theming in case it didn't happen already */
2559 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2560 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2561 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2564 /* only do the show if show is allowed */
2567 if (ec->internal) //internal clients render when they feel like it
2568 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2570 if (!e_client_is_iconified_by_client(ec)||
2571 e_policy_visibility_client_is_uniconic(ec))
2573 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2574 evas_object_show(cw->smart_obj);
2576 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2577 it is rendered in idle callback without native surface and
2578 compositor shows an empty frame if other objects aren't shown
2579 because job callback of e_comp called at the next loop.
2580 it causes a visual defect when windows are switched.
2584 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2585 e_comp_object_dirty(cw->smart_obj);
2586 e_comp_object_render(cw->smart_obj);
2591 wl_signal_emit_mutable(&cw->events.show, NULL);
2595 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2597 E_Comp_Object *cw = data;
2598 E_Client *ec = cw->ec;
2600 E_Input_Rect_Data *input_rect_data;
2601 E_Input_Rect_Smart_Data *input_rect_sd;
2604 if (ec->ignored) return;
2608 //INF("SHOW2 %p", ec);
2609 _e_comp_intercept_show_helper(cw);
2612 //INF("SHOW %p", ec);
2615 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2616 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2617 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2618 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2622 if ((!cw->obj) && (cw->external_content))
2624 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2628 _e_comp_object_setup(cw);
2631 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2632 cw->obj = evas_object_image_filled_add(e_comp->evas);
2633 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2634 e_util_size_debug_set(cw->obj, 1);
2635 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2636 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2637 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2638 evas_object_name_set(cw->obj, "cw->obj");
2639 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2641 _e_comp_object_alpha_set(cw);
2644 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2647 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2648 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2651 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2654 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2656 if (input_rect_data->obj)
2658 evas_object_geometry_set(input_rect_data->obj,
2659 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2660 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2661 input_rect_data->rect.w, input_rect_data->rect.h);
2668 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2670 _e_comp_intercept_show_helper(cw);
2674 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2676 E_Comp_Object *cw = data;
2680 /* note: this is here as it seems there are enough apps that do not even
2681 * expect us to emulate a look of focus but not actually set x input
2682 * focus as we do - so simply abort any focus set on such windows */
2683 /* be strict about accepting focus hint */
2684 /* be strict about accepting focus hint */
2685 if ((!ec->icccm.accepts_focus) &&
2686 (!ec->icccm.take_focus))
2690 if (e_client_focused_get() == ec)
2691 e_client_focused_set(NULL);
2693 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2694 evas_object_focus_set(obj, focus);
2698 if (focus && ec->lock_focus_out) return;
2699 if (e_object_is_del(E_OBJECT(ec)) && focus)
2700 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2702 /* filter focus setting based on current state */
2707 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2708 evas_object_focus_set(obj, focus);
2711 if ((ec->iconic) && (!ec->deskshow))
2713 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2715 /* don't focus an iconified window. that's silly! */
2716 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2717 e_client_uniconify(ec);
2718 e_client_focus_latest_set(ec);
2732 /* not yet visible, wait till the next time... */
2733 ec->want_focus = !ec->hidden;
2738 e_client_focused_set(ec);
2742 if (e_client_focused_get() == ec)
2743 e_client_focused_set(NULL);
2747 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2749 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2751 evas_object_focus_set(obj, focus);
2755 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2757 E_Comp_Object *cw = data;
2759 if (cw->transparent.set)
2761 cw->transparent.user_r = r;
2762 cw->transparent.user_g = g;
2763 cw->transparent.user_b = b;
2764 cw->transparent.user_a = a;
2766 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2768 cw->transparent.user_r,
2769 cw->transparent.user_g,
2770 cw->transparent.user_b,
2771 cw->transparent.user_a);
2775 evas_object_color_set(obj, r, g, b, a);
2778 ////////////////////////////////////////////////////
2781 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2783 int w, h, ox, oy, ow, oh;
2785 Eina_Bool pass_event_flag = EINA_FALSE;
2786 E_Input_Rect_Data *input_rect_data;
2787 E_Input_Rect_Smart_Data *input_rect_sd;
2789 if (cw->frame_object)
2791 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2792 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2793 /* set a fixed size, force edje calc, check size difference */
2794 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2795 edje_object_message_signal_process(cw->frame_object);
2796 edje_object_calc_force(cw->frame_object);
2797 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2798 cw->client_inset.l = ox;
2799 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2800 cw->client_inset.t = oy;
2801 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2802 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2803 evas_object_resize(cw->frame_object, w, h);
2807 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2810 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2812 if (input_rect_data->obj)
2814 pass_event_flag = EINA_TRUE;
2820 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2821 evas_object_pass_events_set(cw->obj, pass_event_flag);
2825 cw->client_inset.l = 0;
2826 cw->client_inset.r = 0;
2827 cw->client_inset.t = 0;
2828 cw->client_inset.b = 0;
2830 cw->client_inset.calc = !!cw->frame_object;
2834 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2836 E_Comp_Object *cw = data;
2840 /* - get current size
2842 * - readjust for new frame size
2845 w = cw->ec->w, h = cw->ec->h;
2846 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2848 _e_comp_object_frame_recalc(cw);
2850 if (!cw->ec->fullscreen)
2851 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2853 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2854 if (cw->ec->shading || cw->ec->shaded) return;
2855 if (cw->ec->fullscreen)
2857 zone = e_comp_zone_find_by_ec(cw->ec);
2859 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2861 else if (cw->ec->new_client)
2863 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2864 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2865 evas_object_resize(cw->ec->frame, w, h);
2867 else if ((w != cw->ec->w) || (h != cw->ec->h))
2868 evas_object_resize(cw->ec->frame, w, h);
2872 _e_comp_smart_cb_shading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2874 E_Comp_Object *cw = data;
2876 if (!cw->ec) return; //NYI
2877 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2879 cw->shade.x = cw->x;
2880 cw->shade.y = cw->y;
2881 e_comp_object_signal_emit(cw->smart_obj, "e,state,shading", "e");
2885 _e_comp_smart_cb_shaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2887 E_Comp_Object *cw = data;
2889 if (!cw->ec) return; //NYI
2890 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2892 e_comp_object_signal_emit(cw->smart_obj, "e,state,shaded", "e");
2896 _e_comp_smart_cb_unshading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2898 E_Comp_Object *cw = data;
2900 if (!cw->ec) return; //NYI
2901 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2903 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshading", "e");
2907 _e_comp_smart_cb_unshaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2909 E_Comp_Object *cw = data;
2911 if (!cw->ec) return; //NYI
2912 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2914 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshaded", "e");
2918 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2920 E_Comp_Object *cw = data;
2922 _e_comp_object_shadow_setup(cw);
2923 if (cw->frame_object)
2925 _e_comp_object_shadow(cw);
2926 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2927 _e_comp_object_frame_recalc(cw);
2928 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2933 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2935 E_Comp_Object *cw = data;
2937 if (_e_comp_object_shadow_setup(cw))
2938 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2939 if (cw->frame_object)
2941 _e_comp_object_shadow(cw);
2942 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2943 _e_comp_object_frame_recalc(cw);
2944 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2949 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2951 E_Comp_Object *cw = data;
2953 if (cw->frame_object)
2955 _e_comp_object_shadow(cw);
2956 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2957 _e_comp_object_frame_recalc(cw);
2958 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2963 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2965 E_Comp_Object *cw = data;
2967 if (_e_comp_object_shadow_setup(cw))
2970 cw->ec->changes.size = 1;
2972 if (cw->frame_object)
2974 _e_comp_object_shadow(cw);
2975 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2976 _e_comp_object_frame_recalc(cw);
2977 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2982 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2984 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2988 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2990 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2994 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2996 E_Comp_Object *cw = data;
2998 if (!cw->ec) return; //NYI
2999 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
3003 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
3005 E_Comp_Object *cw = data;
3007 if (!cw->ec) return; //NYI
3008 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
3012 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3014 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3018 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3020 E_Comp_Object *cw = data;
3022 if (!e_object_is_del(E_OBJECT(cw->ec)))
3023 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3027 _e_comp_input_obj_smart_add(Evas_Object *obj)
3029 E_Input_Rect_Smart_Data *input_rect_sd;
3030 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3032 if (!input_rect_sd) return;
3033 evas_object_smart_data_set(obj, input_rect_sd);
3037 _e_comp_input_obj_smart_del(Evas_Object *obj)
3039 E_Input_Rect_Smart_Data *input_rect_sd;
3040 E_Input_Rect_Data *input_rect_data;
3042 input_rect_sd = evas_object_smart_data_get(obj);
3043 if (!input_rect_sd) return;
3045 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3047 if (input_rect_data->obj)
3049 evas_object_smart_member_del(input_rect_data->obj);
3050 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3052 E_FREE(input_rect_data);
3054 E_FREE(input_rect_sd);
3058 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3060 E_Input_Rect_Smart_Data *input_rect_sd;
3061 E_Input_Rect_Data *input_rect_data;
3065 input_rect_sd = evas_object_smart_data_get(obj);
3066 if (!input_rect_sd) return;
3068 cw = input_rect_sd->cw;
3069 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3071 if (input_rect_data->obj)
3073 evas_object_geometry_set(input_rect_data->obj,
3074 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3075 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3076 input_rect_data->rect.w, input_rect_data->rect.h);
3082 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3084 E_Input_Rect_Smart_Data *input_rect_sd;
3085 E_Input_Rect_Data *input_rect_data;
3089 input_rect_sd = evas_object_smart_data_get(obj);
3090 if (!input_rect_sd) return;
3092 cw = input_rect_sd->cw;
3093 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3095 if (input_rect_data->obj)
3097 evas_object_geometry_set(input_rect_data->obj,
3098 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3099 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3100 input_rect_data->rect.w, input_rect_data->rect.h);
3106 _e_comp_input_obj_smart_show(Evas_Object *obj)
3108 E_Input_Rect_Smart_Data *input_rect_sd;
3109 E_Input_Rect_Data *input_rect_data;
3112 input_rect_sd = evas_object_smart_data_get(obj);
3113 if (!input_rect_sd) return;
3115 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3117 if (input_rect_data->obj)
3119 evas_object_show(input_rect_data->obj);
3125 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3127 E_Input_Rect_Smart_Data *input_rect_sd;
3128 E_Input_Rect_Data *input_rect_data;
3131 input_rect_sd = evas_object_smart_data_get(obj);
3132 if (!input_rect_sd) return;
3134 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3136 if (input_rect_data->obj)
3138 evas_object_hide(input_rect_data->obj);
3144 _e_comp_input_obj_smart_init(void)
3146 if (_e_comp_input_obj_smart) return;
3148 static const Evas_Smart_Class sc =
3150 INPUT_OBJ_SMART_NAME,
3151 EVAS_SMART_CLASS_VERSION,
3152 _e_comp_input_obj_smart_add,
3153 _e_comp_input_obj_smart_del,
3154 _e_comp_input_obj_smart_move,
3155 _e_comp_input_obj_smart_resize,
3156 _e_comp_input_obj_smart_show,
3157 _e_comp_input_obj_smart_hide,
3170 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3176 _e_comp_smart_add(Evas_Object *obj)
3180 cw = E_NEW(E_Comp_Object, 1);
3181 EINA_SAFETY_ON_NULL_RETURN(cw);
3183 wl_signal_init(&cw->events.lower);
3184 wl_signal_init(&cw->events.show);
3185 wl_signal_init(&cw->events.hide);
3187 cw->smart_obj = obj;
3188 cw->x = cw->y = cw->w = cw->h = -1;
3189 evas_object_smart_data_set(obj, cw);
3190 cw->opacity = 255.0;
3191 cw->external_content = 0;
3192 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3193 cw->transform_bg_color.r = 0;
3194 cw->transform_bg_color.g = 0;
3195 cw->transform_bg_color.b = 0;
3196 cw->transform_bg_color.a = 255;
3197 evas_object_data_set(obj, "comp_obj", cw);
3198 evas_object_move(obj, -1, -1);
3199 /* intercept ALL the callbacks! */
3200 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3201 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3202 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3203 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3204 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3205 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3206 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3207 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3208 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3209 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3210 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3212 evas_object_smart_callback_add(obj, "shading", _e_comp_smart_cb_shading, cw);
3213 evas_object_smart_callback_add(obj, "shaded", _e_comp_smart_cb_shaded, cw);
3214 evas_object_smart_callback_add(obj, "unshading", _e_comp_smart_cb_unshading, cw);
3215 evas_object_smart_callback_add(obj, "unshaded", _e_comp_smart_cb_unshaded, cw);
3217 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3218 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3219 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3220 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3222 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3223 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3225 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3226 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3228 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3230 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3231 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3235 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3238 evas_object_color_set(cw->clip, r, g, b, a);
3239 evas_object_smart_callback_call(obj, "color_set", NULL);
3244 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3247 evas_object_clip_set(cw->clip, clip);
3251 _e_comp_smart_clip_unset(Evas_Object *obj)
3254 evas_object_clip_unset(cw->clip);
3258 _e_comp_smart_hide(Evas_Object *obj)
3260 TRACE_DS_BEGIN(COMP:SMART HIDE);
3265 evas_object_hide(cw->clip);
3266 if (cw->input_obj) evas_object_hide(cw->input_obj);
3267 evas_object_hide(cw->effect_obj);
3268 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3269 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3270 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3277 /* unset native surface if current displaying buffer was destroied */
3278 if (!cw->buffer_destroy_listener.notify)
3280 Evas_Native_Surface *ns;
3281 ns = evas_object_image_native_surface_get(cw->obj);
3282 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3283 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3286 if (!cw->ec->input_only)
3288 edje_object_freeze(cw->effect_obj);
3289 edje_object_freeze(cw->shobj);
3290 edje_object_play_set(cw->shobj, 0);
3291 if (cw->frame_object)
3292 edje_object_play_set(cw->frame_object, 0);
3295 e_comp_render_queue(); //force nocomp recheck
3301 _e_comp_smart_show(Evas_Object *obj)
3309 if ((cw->w < 0) || (cw->h < 0))
3310 CRI("ACK! ec:%p", cw->ec);
3312 TRACE_DS_BEGIN(COMP:SMART SHOW);
3314 e_comp_object_map_update(obj);
3316 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3317 evas_object_show(tmp->frame);
3319 evas_object_show(cw->clip);
3320 if (cw->input_obj) evas_object_show(cw->input_obj);
3321 if (!cw->ec->input_only)
3323 edje_object_thaw(cw->effect_obj);
3324 edje_object_thaw(cw->shobj);
3325 edje_object_play_set(cw->shobj, 1);
3326 if (cw->frame_object)
3327 edje_object_play_set(cw->frame_object, 1);
3329 evas_object_show(cw->effect_obj);
3330 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3331 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3332 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3333 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3334 e_comp_render_queue();
3335 if (cw->ec->input_only)
3340 if (cw->ec->iconic && (!cw->ec->new_client))
3342 if (e_client_is_iconified_by_client(cw->ec))
3344 ELOGF("COMP", "Set launching flag..", cw->ec);
3345 cw->ec->launching = EINA_TRUE;
3348 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3350 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3353 ELOGF("COMP", "Set launching flag..", cw->ec);
3354 cw->ec->launching = EINA_TRUE;
3356 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3357 _e_comp_object_animating_begin(cw);
3358 if (!_e_comp_object_effect_visibility_start(cw, 1))
3364 /* ensure some random effect doesn't lock the client offscreen */
3368 e_comp_object_effect_set(obj, NULL);
3371 _e_comp_object_dim_update(cw);
3377 _e_comp_smart_del(Evas_Object *obj)
3383 if (cw->buffer_destroy_listener.notify)
3385 wl_list_remove(&cw->buffer_destroy_listener.link);
3386 cw->buffer_destroy_listener.notify = NULL;
3389 if (cw->tbm_surface)
3391 tbm_surface_internal_unref(cw->tbm_surface);
3392 cw->tbm_surface = NULL;
3395 if (cw->render_update_lock.buffer_ref.buffer)
3397 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3398 cw->ec, cw->render_update_lock.lock);
3399 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3402 e_comp_object_render_update_del(cw->smart_obj);
3403 E_FREE_FUNC(cw->updates, eina_tiler_free);
3404 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3411 EINA_LIST_FREE(cw->obj_mirror, o)
3413 evas_object_image_data_set(o, NULL);
3414 evas_object_freeze_events_set(o, 1);
3415 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3419 _e_comp_object_layers_remove(cw);
3420 l = evas_object_data_get(obj, "comp_object-to_del");
3421 E_FREE_LIST(l, evas_object_del);
3422 _e_comp_object_mouse_event_callback_unset(cw);
3423 evas_object_del(cw->clip);
3424 evas_object_del(cw->effect_obj);
3425 evas_object_del(cw->shobj);
3426 evas_object_del(cw->frame_object);
3427 evas_object_del(cw->input_obj);
3428 evas_object_del(cw->obj);
3429 evas_object_del(cw->mask.obj);
3430 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3431 evas_object_del(cw->transform_bg_obj);
3432 evas_object_del(cw->transform_tranp_obj);
3433 evas_object_del(cw->default_input_obj);
3434 eina_stringshare_del(cw->frame_theme);
3435 eina_stringshare_del(cw->frame_name);
3439 e_comp->animating--;
3441 e_object_unref(E_OBJECT(cw->ec));
3443 cw->ec->frame = NULL;
3448 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3452 cw->x = x, cw->y = y;
3453 evas_object_move(cw->effect_obj, x, y);
3454 evas_object_move(cw->default_input_obj, x, y);
3455 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3457 e_comp_object_map_update(obj);
3461 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3463 Eina_Bool first = EINA_FALSE;
3468 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3470 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3472 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3474 if (cw->w != w || cw->h != h)
3475 e_comp_object_map_update(obj);
3477 first = ((cw->w < 1) || (cw->h < 1));
3478 cw->w = w, cw->h = h;
3479 if ((!cw->ec->shading) && (!cw->ec->shaded))
3483 if (cw->frame_object)
3484 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3487 /* verify pixmap:object size */
3488 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3490 if ((ww != pw) || (hh != ph))
3491 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3493 evas_object_resize(cw->effect_obj, tw, th);
3494 evas_object_resize(cw->default_input_obj, w, h);
3496 evas_object_resize(cw->input_obj, w, h);
3498 evas_object_resize(cw->mask.obj, w, h);
3499 /* resize render update tiler */
3502 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3503 cw->updates_full = 0;
3504 if (cw->updates) eina_tiler_clear(cw->updates);
3508 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3509 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3514 evas_object_resize(cw->effect_obj, tw, th);
3515 evas_object_resize(cw->default_input_obj, w, h);
3522 e_comp_render_queue();
3528 _e_comp_smart_init(void)
3530 if (_e_comp_smart) return;
3532 static const Evas_Smart_Class sc =
3535 EVAS_SMART_CLASS_VERSION,
3539 _e_comp_smart_resize,
3542 _e_comp_smart_color_set,
3543 _e_comp_smart_clip_set,
3544 _e_comp_smart_clip_unset,
3554 _e_comp_smart = evas_smart_class_new(&sc);
3559 e_comp_object_init(void)
3561 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3562 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3563 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3564 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3568 e_comp_object_shutdown(void)
3574 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3576 API_ENTRY EINA_FALSE;
3577 return !!cw->force_visible;
3579 /////////////////////////////////////////////////////////
3582 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3585 Eina_Bool comp_object;
3587 comp_object = !!evas_object_data_get(obj, "comp_object");
3592 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3594 e_comp_render_queue();
3596 l = evas_object_data_get(obj, "comp_object-to_del");
3597 E_FREE_LIST(l, evas_object_del);
3601 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3603 if (e_comp_util_object_is_above_nocomp(obj) &&
3604 (!evas_object_data_get(obj, "comp_override")))
3606 evas_object_data_set(obj, "comp_override", (void*)1);
3607 e_comp_override_add();
3612 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3614 Eina_Bool ref = EINA_TRUE;
3615 if (evas_object_visible_get(obj))
3619 d = evas_object_data_del(obj, "comp_hiding");
3621 /* currently trying to hide */
3624 /* already visible */
3628 evas_object_show(obj);
3631 evas_object_ref(obj);
3632 evas_object_data_set(obj, "comp_ref", (void*)1);
3634 edje_object_signal_emit(obj, "e,state,visible", "e");
3635 evas_object_data_set(obj, "comp_showing", (void*)1);
3636 if (e_comp_util_object_is_above_nocomp(obj))
3638 evas_object_data_set(obj, "comp_override", (void*)1);
3639 e_comp_override_add();
3644 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3646 if (!evas_object_visible_get(obj)) return;
3647 /* already hiding */
3648 if (evas_object_data_get(obj, "comp_hiding")) return;
3649 if (!evas_object_data_del(obj, "comp_showing"))
3651 evas_object_ref(obj);
3652 evas_object_data_set(obj, "comp_ref", (void*)1);
3654 edje_object_signal_emit(obj, "e,state,hidden", "e");
3655 evas_object_data_set(obj, "comp_hiding", (void*)1);
3657 if (evas_object_data_del(obj, "comp_override"))
3658 e_comp_override_timed_pop();
3662 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3664 if (!e_util_strcmp(emission, "e,action,hide,done"))
3666 if (!evas_object_data_del(obj, "comp_hiding")) return;
3667 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3668 evas_object_hide(obj);
3669 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3672 evas_object_data_del(obj, "comp_showing");
3673 if (evas_object_data_del(obj, "comp_ref"))
3674 evas_object_unref(obj);
3678 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3684 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3688 E_API E_Comp_Object_Hook *
3689 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3691 E_Comp_Object_Hook *ch;
3693 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3694 ch = E_NEW(E_Comp_Object_Hook, 1);
3695 if (!ch) return NULL;
3696 ch->hookpoint = hookpoint;
3698 ch->data = (void*)data;
3699 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3704 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3707 if (_e_comp_object_hooks_walking == 0)
3709 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3713 _e_comp_object_hooks_delete++;
3716 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3717 E_API E_Comp_Object_Intercept_Hook *
3718 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3720 E_Comp_Object_Intercept_Hook *ch;
3722 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3723 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3724 if (!ch) return NULL;
3725 ch->hookpoint = hookpoint;
3727 ch->data = (void*)data;
3728 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3733 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3736 if (_e_comp_object_intercept_hooks_walking == 0)
3738 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3742 _e_comp_object_intercept_hooks_delete++;
3747 e_comp_object_util_add(Evas_Object *obj)
3751 E_Comp_Config *conf = e_comp_config_get();
3752 Eina_Bool skip = EINA_FALSE;
3758 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3760 name = evas_object_name_get(obj);
3761 vis = evas_object_visible_get(obj);
3762 o = edje_object_add(e_comp->evas);
3763 evas_object_data_set(o, "comp_object", (void*)1);
3765 skip = (!strncmp(name, "noshadow", 8));
3767 evas_object_data_set(o, "comp_object_skip", (void*)1);
3769 if (conf->shadow_style)
3771 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3772 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3775 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3776 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3777 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3779 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3781 evas_object_geometry_get(obj, &x, &y, &w, &h);
3782 evas_object_geometry_set(o, x, y, w, h);
3783 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3785 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3787 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3788 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3789 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3790 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3791 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3792 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3794 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3796 edje_object_part_swallow(o, "e.swallow.content", obj);
3798 _e_comp_object_event_add(o);
3801 evas_object_show(o);
3806 /* utility functions for deleting objects when their "owner" is deleted */
3808 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3813 EINA_SAFETY_ON_NULL_RETURN(to_del);
3814 l = evas_object_data_get(obj, "comp_object-to_del");
3815 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3816 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3817 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3821 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3826 EINA_SAFETY_ON_NULL_RETURN(to_del);
3827 l = evas_object_data_get(obj, "comp_object-to_del");
3829 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3832 /////////////////////////////////////////////////////////
3834 EINTERN Evas_Object *
3835 e_comp_object_client_add(E_Client *ec)
3840 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3841 if (ec->frame) return NULL;
3842 _e_comp_smart_init();
3843 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3844 cw = evas_object_smart_data_get(o);
3845 if (!cw) return NULL;
3846 evas_object_data_set(o, "E_Client", ec);
3849 evas_object_data_set(o, "comp_object", (void*)1);
3851 _e_comp_object_event_add(o);
3856 /* utility functions for getting client inset */
3858 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3861 if (!cw->client_inset.calc)
3867 if (ax) *ax = x - cw->client_inset.l;
3868 if (ay) *ay = y - cw->client_inset.t;
3872 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3875 if (!cw->client_inset.calc)
3881 if (ax) *ax = x + cw->client_inset.l;
3882 if (ay) *ay = y + cw->client_inset.t;
3886 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3889 if (!cw->client_inset.calc)
3895 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3896 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3900 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3903 if (!cw->client_inset.calc)
3909 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3910 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3914 e_comp_object_client_get(Evas_Object *obj)
3919 /* FIXME: remove this when eo is used */
3920 o = evas_object_data_get(obj, "comp_smart_obj");
3922 return e_comp_object_client_get(o);
3923 return cw ? cw->ec : NULL;
3927 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3930 if (cw->frame_extends)
3931 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3936 if (w) *w = cw->ec->w;
3937 if (h) *h = cw->ec->h;
3942 e_comp_object_util_zone_get(Evas_Object *obj)
3944 E_Zone *zone = NULL;
3948 zone = e_comp_zone_find_by_ec(cw->ec);
3953 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3954 zone = e_comp_zone_xy_get(x, y);
3960 e_comp_object_util_center(Evas_Object *obj)
3962 int x, y, w, h, ow, oh;
3967 zone = e_comp_object_util_zone_get(obj);
3968 EINA_SAFETY_ON_NULL_RETURN(zone);
3969 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3970 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3971 ow = cw->ec->w, oh = cw->ec->h;
3973 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3974 x = x + (w - ow) / 2;
3975 y = y + (h - oh) / 2;
3976 evas_object_move(obj, x, y);
3980 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3982 int x, y, w, h, ow, oh;
3985 EINA_SAFETY_ON_NULL_RETURN(on);
3986 evas_object_geometry_get(on, &x, &y, &w, &h);
3987 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3988 ow = cw->ec->w, oh = cw->ec->h;
3990 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3991 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3995 e_comp_object_util_fullscreen(Evas_Object *obj)
4000 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
4003 evas_object_move(obj, 0, 0);
4004 evas_object_resize(obj, e_comp->w, e_comp->h);
4009 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4017 ow = cw->w, oh = cw->h;
4019 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4020 zone = e_comp_object_util_zone_get(obj);
4021 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4022 if (x) *x = zx + (zw - ow) / 2;
4023 if (y) *y = zy + (zh - oh) / 2;
4027 e_comp_object_input_objs_del(Evas_Object *obj)
4030 E_Input_Rect_Data *input_rect_data;
4031 E_Input_Rect_Smart_Data *input_rect_sd;
4036 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4037 if (!input_rect_sd) return;
4039 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4041 if (input_rect_data->obj)
4043 evas_object_smart_member_del(input_rect_data->obj);
4044 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4046 E_FREE(input_rect_data);
4051 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4054 E_Input_Rect_Data *input_rect_data = NULL;
4055 E_Input_Rect_Smart_Data *input_rect_sd;
4056 int client_w, client_h;
4058 if (cw->ec->client.w)
4059 client_w = cw->ec->client.w;
4061 client_w = cw->ec->w;
4063 if (cw->ec->client.h)
4064 client_h = cw->ec->client.h;
4066 client_h = cw->ec->h;
4068 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4072 _e_comp_input_obj_smart_init();
4073 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4074 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4075 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4078 input_rect_sd->cw = cw;
4081 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4084 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4085 if (input_rect_data)
4087 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4088 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4092 if ((input_rect_data) &&
4093 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4095 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4096 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4097 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4098 evas_object_clip_set(input_rect_data->obj, cw->clip);
4099 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4100 evas_object_geometry_set(input_rect_data->obj,
4101 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4102 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4103 evas_object_pass_events_set(cw->default_input_obj, 1);
4104 evas_object_pass_events_set(cw->obj, 1);
4107 evas_object_show(input_rect_data->obj);
4108 evas_object_show(cw->input_obj);
4113 evas_object_smart_member_del(cw->input_obj);
4114 E_FREE_FUNC(cw->input_obj, evas_object_del);
4115 evas_object_pass_events_set(cw->default_input_obj, 0);
4116 evas_object_pass_events_set(cw->obj, 0);
4121 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4124 E_Input_Rect_Smart_Data *input_rect_sd;
4125 E_Input_Rect_Data *input_rect_data;
4128 if (!cw->input_obj) return;
4130 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4133 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4135 *list = eina_list_append(*list, &input_rect_data->rect);
4141 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4144 if (l) *l = cw->client_inset.l;
4145 if (r) *r = cw->client_inset.r;
4146 if (t) *t = cw->client_inset.t;
4147 if (b) *b = cw->client_inset.b;
4150 /* set geometry for CSD */
4152 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4158 if (cw->frame_object)
4159 CRI("ACK! ec:%p", cw->ec);
4160 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4161 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4162 calc = cw->client_inset.calc;
4163 cw->client_inset.calc = l || r || t || b;
4164 eina_stringshare_replace(&cw->frame_theme, "borderless");
4165 if (cw->client_inset.calc)
4167 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4168 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4169 e_client_size_set(cw->ec, tw, th);
4171 else if (cw->ec->maximized || cw->ec->fullscreen)
4173 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4174 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4176 if (!cw->ec->new_client)
4178 if (calc && cw->client_inset.calc)
4180 tx = cw->ec->x - (l - cw->client_inset.l);
4181 ty = cw->ec->y - (t - cw->client_inset.t);
4182 e_client_pos_set(cw->ec, tx, ty);
4184 cw->ec->changes.pos = cw->ec->changes.size = 1;
4187 cw->client_inset.l = l;
4188 cw->client_inset.r = r;
4189 cw->client_inset.t = t;
4190 cw->client_inset.b = b;
4194 e_comp_object_frame_allowed(Evas_Object *obj)
4196 API_ENTRY EINA_FALSE;
4197 return (!cw->ec->mwm.borderless) && (cw->frame_object || (!cw->client_inset.calc));
4201 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4203 API_ENTRY EINA_FALSE;
4204 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4205 eina_stringshare_replace(&cw->frame_name, name);
4206 if (cw->frame_object)
4207 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4212 e_comp_object_frame_exists(Evas_Object *obj)
4214 API_ENTRY EINA_FALSE;
4215 return !!cw->frame_object;
4219 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4221 Evas_Object *o, *pbg;
4224 Eina_Stringshare *theme;
4226 API_ENTRY EINA_FALSE;
4228 if (!e_util_strcmp(cw->frame_theme, name))
4229 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4230 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4231 return _e_comp_object_shadow_setup(cw);
4232 pbg = cw->frame_object;
4233 theme = eina_stringshare_add(name);
4235 if (cw->frame_object)
4239 w = cw->ec->w, h = cw->ec->h;
4240 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4241 if ((cw->ec->w != w) || (cw->ec->h != h))
4243 cw->ec->changes.size = 1;
4246 E_FREE_FUNC(cw->frame_object, evas_object_del);
4247 if (!name) goto reshadow;
4249 o = edje_object_add(e_comp->evas);
4250 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4251 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4252 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4254 cw->frame_object = NULL;
4256 eina_stringshare_del(cw->frame_theme);
4257 cw->frame_theme = theme;
4262 if (theme != e_config->theme_default_border_style)
4264 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4265 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4269 ok = e_theme_edje_object_set(o, "base/theme/border",
4270 "e/widgets/border/default/border");
4271 if (ok && (theme == e_config->theme_default_border_style))
4273 /* Reset default border style to default */
4274 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4275 e_config_save_queue();
4282 cw->frame_object = o;
4283 eina_stringshare_del(cw->frame_theme);
4284 cw->frame_theme = theme;
4285 evas_object_name_set(o, "cw->frame_object");
4288 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4292 cw->ec->changes.icon = 1;
4298 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4303 _e_comp_object_shadow_setup(cw);
4306 int old_x, old_y, new_x = 0, new_y = 0;
4308 old_x = cw->x, old_y = cw->y;
4310 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4312 new_x = cw->ec->x, new_y = cw->ec->y;
4313 else if (cw->ec->placed || (!cw->ec->new_client))
4315 /* if no previous frame:
4316 * - reapply client_inset
4321 if (cw->ec->changes.size)
4329 zone = e_comp_zone_find_by_ec(cw->ec);
4332 x = cw->ec->client.x, y = cw->ec->client.y;
4333 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4334 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4336 new_x = x, new_y = y;
4339 if (old_x != new_x || old_y != new_y)
4341 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4342 cw->y = cw->x = -99999;
4343 evas_object_move(obj, new_x, new_y);
4347 if (cw->ec->maximized)
4349 cw->ec->changes.need_maximize = 1;
4352 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4353 if (cw->frame_object)
4355 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4358 cw->frame_extends = 0;
4359 evas_object_del(pbg);
4364 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4366 E_Comp_Object_Mover *prov;
4369 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4370 edje_object_signal_emit(cw->shobj, sig, src);
4371 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4372 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4373 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4375 /* start with highest priority callback first */
4376 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4378 if (!e_util_glob_match(sig, prov->sig)) continue;
4379 if (prov->func(prov->data, obj, sig)) break;
4384 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4386 /* FIXME: at some point I guess this should use eo to inherit
4387 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4388 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4391 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4395 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4398 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4402 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4405 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4409 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4412 Eina_Rectangle rect;
4415 if (cw->ec->input_only || (!cw->updates)) return;
4416 if (cw->nocomp) return;
4417 rect.x = x, rect.y = y;
4418 rect.w = w, rect.h = h;
4419 evas_object_smart_callback_call(obj, "damage", &rect);
4421 if (e_comp_is_on_overlay(cw->ec))
4423 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4424 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4425 * E module attempts to block screen update due to the particular policy.
4427 if (e_pixmap_resource_get(cw->ec->pixmap))
4428 cw->hwc_need_update = EINA_TRUE;
4431 /* ignore overdraw */
4432 if (cw->updates_full)
4434 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4435 e_comp_object_render_update_add(obj);
4437 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4438 evas_object_show(cw->smart_obj);
4442 /* clip rect to client surface */
4443 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4444 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4445 /* if rect is the total size of the client after clip, clear the updates
4446 * since this is guaranteed to be the whole region anyway
4448 eina_tiler_area_size_get(cw->updates, &tw, &th);
4449 if ((w > tw) || (h > th))
4451 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4452 eina_tiler_clear(cw->updates);
4453 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4455 tw = cw->ec->client.w, th = cw->ec->client.h;
4457 if ((!x) && (!y) && (w == tw) && (h == th))
4459 eina_tiler_clear(cw->updates);
4460 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4461 cw->updates_full = 1;
4462 cw->update_count = 0;
4465 if (cw->update_count > UPDATE_MAX)
4467 /* this is going to get really dumb, so just update the whole thing */
4468 eina_tiler_clear(cw->updates);
4469 cw->update_count = cw->updates_full = 1;
4470 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4471 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4475 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4476 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4478 cw->updates_exist = 1;
4479 e_comp_object_render_update_add(obj);
4481 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4482 evas_object_show(cw->smart_obj);
4486 e_comp_object_damage_exists(Evas_Object *obj)
4488 API_ENTRY EINA_FALSE;
4489 return cw->updates_exist;
4493 e_comp_object_render_update_add(Evas_Object *obj)
4497 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4498 if (cw->render_update_lock.lock) return;
4499 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4503 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4505 e_comp_render_queue();
4509 e_comp_object_render_update_del(Evas_Object *obj)
4513 if (cw->ec->input_only || (!cw->updates)) return;
4514 if (!cw->update) return;
4516 /* this gets called during comp animating to clear the update flag */
4517 if (e_comp->grabbed) return;
4518 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4519 if (!e_comp->updates)
4521 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4522 if (e_comp->render_animator)
4523 ecore_animator_freeze(e_comp->render_animator);
4528 e_comp_object_shape_apply(Evas_Object *obj)
4532 unsigned int i, *pix, *p;
4536 if (!cw->ec) return; //NYI
4537 if (cw->external_content) return;
4540 if ((cw->ec->shape_rects_num >= 1) &&
4541 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4546 ERR("BUGGER: shape with native surface? cw=%p", cw);
4549 evas_object_image_size_get(cw->obj, &w, &h);
4550 if ((w < 1) || (h < 1)) return;
4553 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4554 _e_comp_object_alpha_set(cw);
4555 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4556 evas_object_image_alpha_set(o, 1);
4558 p = pix = evas_object_image_data_get(cw->obj, 1);
4561 evas_object_image_data_set(cw->obj, pix);
4566 unsigned char *spix, *sp;
4568 spix = calloc(w * h, sizeof(unsigned char));
4570 for (i = 0; i < cw->ec->shape_rects_num; i++)
4574 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4575 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4576 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4577 sp = spix + (w * ry) + rx;
4578 for (py = 0; py < rh; py++)
4580 for (px = 0; px < rw; px++)
4588 for (py = 0; py < h; py++)
4590 for (px = 0; px < w; px++)
4592 unsigned int mask, imask;
4594 mask = ((unsigned int)(*sp)) << 24;
4596 imask |= imask >> 8;
4597 imask |= imask >> 8;
4598 *p = mask | (*p & imask);
4599 //if (*sp) *p = 0xff000000 | *p;
4600 //else *p = 0x00000000;
4609 for (py = 0; py < h; py++)
4611 for (px = 0; px < w; px++)
4615 evas_object_image_data_set(cw->obj, pix);
4616 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4617 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4619 evas_object_image_data_set(o, pix);
4620 evas_object_image_data_update_add(o, 0, 0, w, h);
4622 // don't need to fix alpha chanel as blending
4623 // should be totally off here regardless of
4624 // alpha channel content
4628 _e_comp_object_clear(E_Comp_Object *cw)
4633 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4635 if (cw->render_update_lock.lock) return;
4638 e_pixmap_clear(cw->ec->pixmap);
4640 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4641 evas_object_image_size_set(cw->obj, 1, 1);
4642 evas_object_image_data_set(cw->obj, NULL);
4643 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4645 evas_object_image_size_set(o, 1, 1);
4646 evas_object_image_data_set(o, NULL);
4649 e_comp_object_render_update_del(cw->smart_obj);
4653 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4657 API_ENTRY EINA_FALSE;
4659 if (cw->transparent.set == set)
4664 evas_object_color_get(obj, &r, &g, &b, &a);
4665 evas_object_color_set(obj, 0, 0, 0, 0);
4667 cw->transparent.user_r = r;
4668 cw->transparent.user_g = g;
4669 cw->transparent.user_b = b;
4670 cw->transparent.user_a = a;
4672 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4674 cw->transparent.user_r,
4675 cw->transparent.user_g,
4676 cw->transparent.user_b,
4677 cw->transparent.user_a);
4679 cw->transparent.set = EINA_TRUE;
4683 cw->transparent.set = EINA_FALSE;
4685 evas_object_color_set(obj,
4686 cw->transparent.user_r,
4687 cw->transparent.user_g,
4688 cw->transparent.user_b,
4689 cw->transparent.user_a);
4691 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4693 cw->transparent.user_r,
4694 cw->transparent.user_g,
4695 cw->transparent.user_b,
4696 cw->transparent.user_a);
4702 /* helper function to simplify toggling of redirection for display servers which support it */
4704 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4709 if (cw->redirected == set) return;
4710 cw->redirected = set;
4711 if (cw->external_content) return;
4713 e_comp_object_map_update(obj);
4717 if (cw->updates_exist)
4718 e_comp_object_render_update_add(obj);
4720 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4722 _e_comp_object_transparent_set(obj, EINA_FALSE);
4723 evas_object_smart_callback_call(obj, "redirected", NULL);
4727 _e_comp_object_clear(cw);
4728 _e_comp_object_transparent_set(obj, EINA_TRUE);
4729 evas_object_smart_callback_call(obj, "unredirected", NULL);
4734 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4737 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4739 if (cw->buffer_destroy_listener.notify)
4741 cw->buffer_destroy_listener.notify = NULL;
4742 wl_list_remove(&cw->buffer_destroy_listener.link);
4745 if (e_object_is_del(E_OBJECT(cw->ec)))
4747 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4752 /* if it's current displaying buffer, do not remove its content */
4753 if (!evas_object_visible_get(cw->ec->frame))
4754 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4759 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4764 if (cw->buffer_destroy_listener.notify)
4766 wl_list_remove(&cw->buffer_destroy_listener.link);
4767 cw->buffer_destroy_listener.notify = NULL;
4770 if (cw->tbm_surface)
4772 tbm_surface_internal_unref(cw->tbm_surface);
4773 cw->tbm_surface = NULL;
4778 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4780 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4781 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4783 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4785 tbm_surface_internal_ref(ns->data.tbm.buffer);
4786 cw->tbm_surface = ns->data.tbm.buffer;
4790 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4791 evas_object_image_native_surface_set(cw->obj, ns);
4795 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4797 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4798 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4799 evas_object_image_native_surface_set(o, ns);
4806 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4808 Evas_Native_Surface ns;
4811 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4812 if (cw->ec->input_only) return;
4813 if (cw->external_content) return;
4814 if (cw->render_update_lock.lock) return;
4817 memset(&ns, 0, sizeof(Evas_Native_Surface));
4821 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4822 set = (!cw->ec->shaped);
4824 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4828 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4832 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4835 if (cw->ec->input_only) return;
4838 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4839 _e_comp_object_alpha_set(cw);
4841 e_comp_object_native_surface_set(obj, cw->native);
4842 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4846 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4852 if (cw->blanked == set) return;
4854 _e_comp_object_alpha_set(cw);
4857 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4858 evas_object_image_data_set(cw->obj, NULL);
4862 e_comp_object_native_surface_set(obj, 1);
4863 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4867 _e_comp_object_damage_trace_rect_set(Evas_Object *obj, Eina_Rectangle *origin, int dmg_x, int dmg_y, int dmg_w, int dmg_h)
4872 if (!_damage_trace) return;
4876 if (!evas_object_visible_get(cw->obj)) return;
4878 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4880 o = evas_object_rectangle_add(e_comp->evas);
4881 evas_object_layer_set(o, E_LAYER_MAX);
4882 evas_object_name_set(o, "damage_trace");
4883 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4884 evas_object_resize(o, dmg_w, dmg_h);
4885 evas_object_color_set(o, 0, 128, 0, 128);
4886 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4887 evas_object_pass_events_set(o, EINA_TRUE);
4888 evas_object_show(o);
4890 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4892 dmg_w, dmg_h, dmg_x, dmg_y,
4893 origin->w, origin->h, origin->x, origin->y);
4895 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4898 /* mark an object as dirty and setup damages */
4900 e_comp_object_dirty(Evas_Object *obj)
4903 Eina_Rectangle *rect;
4907 Eina_Bool dirty, visible;
4911 if (cw->external_content) return;
4912 if (!cw->redirected) return;
4913 if (cw->render_update_lock.lock)
4915 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4918 /* only actually dirty if pixmap is available */
4919 if (!e_pixmap_resource_get(cw->ec->pixmap))
4921 // e_pixmap_size_get returns last attached buffer size
4922 // eventhough it is destroyed
4923 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4926 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4927 visible = cw->visible;
4928 if (!dirty) w = h = 1;
4929 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4931 evas_object_image_data_set(cw->obj, NULL);
4932 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4933 evas_object_image_size_set(cw->obj, tw, th);
4934 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4935 if (cw->pending_updates)
4936 eina_tiler_area_size_set(cw->pending_updates, w, h);
4937 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4939 evas_object_image_pixels_dirty_set(o, dirty);
4941 evas_object_image_data_set(o, NULL);
4942 evas_object_image_size_set(o, tw, th);
4943 visible |= evas_object_visible_get(o);
4947 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4951 e_comp_object_native_surface_set(obj, 1);
4953 m = _e_comp_object_map_damage_transform_get(cw->ec);
4954 it = eina_tiler_iterator_new(cw->updates);
4955 EINA_ITERATOR_FOREACH(it, rect)
4957 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4958 * of evas engine and doesn't convert damage according to evas_map.
4959 * so damage of evas_object_image use surface coordinate.
4963 int damage_x, damage_y, damage_w, damage_h;
4965 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4966 &damage_x, &damage_y, &damage_w, &damage_h);
4967 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4968 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4972 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4973 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4976 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4977 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4978 if (cw->pending_updates)
4979 eina_tiler_rect_add(cw->pending_updates, rect);
4981 eina_iterator_free(it);
4982 if (m) e_map_free(m);
4983 if (cw->pending_updates)
4984 eina_tiler_clear(cw->updates);
4987 cw->pending_updates = cw->updates;
4988 cw->updates = eina_tiler_new(w, h);
4989 eina_tiler_tile_size_set(cw->updates, 1, 1);
4991 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4992 evas_object_smart_callback_call(obj, "dirty", NULL);
4993 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4994 /* force render if main object is hidden but mirrors are visible */
4995 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4996 e_comp_object_render(obj);
5000 e_comp_object_render(Evas_Object *obj)
5007 API_ENTRY EINA_FALSE;
5009 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5010 if (cw->ec->input_only) return EINA_TRUE;
5011 if (cw->external_content) return EINA_TRUE;
5012 if (cw->native) return EINA_FALSE;
5013 /* if comp object is not redirected state, comp object should not be set by newly committed data
5014 because image size of comp object is 1x1 and it should not be shown on canvas */
5015 if (!cw->redirected) return EINA_TRUE;
5016 if (cw->render_update_lock.lock)
5018 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5021 e_comp_object_render_update_del(obj);
5022 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5024 if (!cw->pending_updates)
5026 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5027 evas_object_image_data_set(cw->obj, NULL);
5028 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5029 evas_object_image_data_set(o, NULL);
5033 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5035 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5037 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5040 e_pixmap_image_refresh(cw->ec->pixmap);
5041 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5044 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5045 e_pixmap_image_data_ref(cw->ec->pixmap);
5047 /* set pixel data */
5048 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5049 _e_comp_object_alpha_set(cw);
5050 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5052 evas_object_image_data_set(o, pix);
5053 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5054 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5057 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5059 e_comp_client_post_update_add(cw->ec);
5064 /* create a duplicate of an evas object */
5066 e_comp_object_util_mirror_add(Evas_Object *obj)
5070 unsigned int *pix = NULL;
5071 Eina_Bool argb = EINA_FALSE;
5076 cw = evas_object_data_get(obj, "comp_mirror");
5079 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5080 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5081 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5082 evas_object_image_alpha_set(o, 1);
5083 evas_object_image_source_set(o, obj);
5086 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5087 if (cw->external_content)
5089 ERR("%p of client %p is external content.", obj, cw->ec);
5092 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5093 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5094 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5095 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5096 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5097 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5098 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5099 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5100 evas_object_data_set(o, "comp_mirror", cw);
5102 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5103 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5105 evas_object_image_size_set(o, tw, th);
5108 pix = evas_object_image_data_get(cw->obj, 0);
5114 evas_object_image_native_surface_set(o, cw->ns);
5117 Evas_Native_Surface ns;
5118 memset(&ns, 0, sizeof(Evas_Native_Surface));
5119 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5120 evas_object_image_native_surface_set(o, &ns);
5125 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5126 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5128 (e_pixmap_image_exists(cw->ec->pixmap)))
5129 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5131 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5138 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5139 evas_object_image_pixels_dirty_set(o, dirty);
5140 evas_object_image_data_set(o, pix);
5141 evas_object_image_data_set(cw->obj, pix);
5143 evas_object_image_data_update_add(o, 0, 0, tw, th);
5148 //////////////////////////////////////////////////////
5151 e_comp_object_effect_allowed_get(Evas_Object *obj)
5153 API_ENTRY EINA_FALSE;
5155 if (!cw->shobj) return EINA_FALSE;
5156 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5157 return !e_comp_config_get()->match.disable_borders;
5160 /* setup an api effect for a client */
5162 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5165 Eina_Stringshare *grp;
5166 E_Comp_Config *config;
5167 Eina_Bool loaded = EINA_FALSE;
5169 API_ENTRY EINA_FALSE;
5170 if (!cw->shobj) return EINA_FALSE; //input window
5172 if (!effect) effect = "none";
5173 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5175 config = e_comp_config_get();
5176 if ((config) && (config->effect_file))
5178 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5180 cw->effect_set = EINA_TRUE;
5187 edje_object_file_get(cw->effect_obj, NULL, &grp);
5188 cw->effect_set = !eina_streq(effect, "none");
5189 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5190 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5192 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5193 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5194 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5196 if (cw->effect_running)
5198 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5201 cw->effect_set = EINA_FALSE;
5202 return cw->effect_set;
5206 if (cw->effect_running)
5208 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5211 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5212 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5213 if (cw->effect_clip)
5215 evas_object_clip_unset(cw->clip);
5216 cw->effect_clip = 0;
5218 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5220 _e_comp_object_dim_update(cw);
5222 return cw->effect_set;
5225 /* set params for embryo scripts in effect */
5227 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5229 Edje_Message_Int_Set *msg;
5233 EINA_SAFETY_ON_NULL_RETURN(params);
5234 EINA_SAFETY_ON_FALSE_RETURN(count);
5235 if (!cw->effect_set) return;
5237 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5238 msg->count = (int)count;
5239 for (x = 0; x < count; x++)
5240 msg->val[x] = params[x];
5241 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5242 edje_object_message_signal_process(cw->effect_obj);
5246 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5248 Edje_Signal_Cb end_cb;
5250 E_Comp_Object *cw = data;
5252 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5253 cw->effect_running = 0;
5254 if (!_e_comp_object_animating_end(cw)) return;
5256 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5258 evas_object_data_del(cw->smart_obj, "effect_running");
5259 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5260 e_comp_visibility_calculation_set(EINA_TRUE);
5263 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5264 if (!end_cb) return;
5265 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5266 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5267 end_cb(end_data, cw->smart_obj, emission, source);
5270 /* clip effect to client's zone */
5272 e_comp_object_effect_clip(Evas_Object *obj)
5276 zone = e_comp_zone_find_by_ec(cw->ec);
5278 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5279 if (!cw->effect_clip_able) return;
5280 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5281 cw->effect_clip = 1;
5284 /* unclip effect from client's zone */
5286 e_comp_object_effect_unclip(Evas_Object *obj)
5289 if (!cw->effect_clip) return;
5290 evas_object_clip_unset(cw->smart_obj);
5291 cw->effect_clip = 0;
5294 /* start effect, running end_cb after */
5296 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5298 API_ENTRY EINA_FALSE;
5299 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5300 if (!cw->effect_set) return EINA_FALSE;
5302 if (cw->effect_running)
5304 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5307 e_comp_object_effect_clip(obj);
5308 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5310 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5311 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5312 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5313 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5315 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5316 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5318 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5319 _e_comp_object_animating_begin(cw);
5320 cw->effect_running = 1;
5324 /* stop a currently-running effect immediately */
5326 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5329 Edje_Signal_Cb end_cb_before = NULL;
5330 void *end_data_before = NULL;
5331 API_ENTRY EINA_FALSE;
5333 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5334 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5336 if (end_cb_before != end_cb) return EINA_TRUE;
5337 e_comp_object_effect_unclip(obj);
5338 if (cw->effect_clip)
5340 evas_object_clip_unset(cw->effect_obj);
5341 cw->effect_clip = 0;
5343 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5344 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5346 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5348 evas_object_data_del(cw->smart_obj, "effect_running");
5349 e_comp_visibility_calculation_set(EINA_TRUE);
5352 cw->effect_running = 0;
5353 ret = _e_comp_object_animating_end(cw);
5355 if ((ret) && (end_cb_before))
5357 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5358 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5365 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5367 return a->pri - b->pri;
5370 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5371 E_API E_Comp_Object_Mover *
5372 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5374 E_Comp_Object_Mover *prov;
5376 prov = E_NEW(E_Comp_Object_Mover, 1);
5377 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5378 prov->func = provider;
5379 prov->data = (void*)data;
5382 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5383 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5388 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5390 EINA_SAFETY_ON_NULL_RETURN(prov);
5391 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5396 e_comp_object_effect_object_get(Evas_Object *obj)
5400 return cw->effect_obj;
5404 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5406 API_ENTRY EINA_FALSE;
5407 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5408 if (!cw->effect_set) return EINA_FALSE;
5415 ////////////////////////////////////
5418 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5420 if (e_comp->autoclose.obj)
5422 e_comp_ungrab_input(0, 1);
5423 if (e_comp->autoclose.del_cb)
5424 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5425 else if (!already_del)
5427 evas_object_hide(e_comp->autoclose.obj);
5428 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5430 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5432 e_comp->autoclose.obj = NULL;
5433 e_comp->autoclose.data = NULL;
5434 e_comp->autoclose.del_cb = NULL;
5435 e_comp->autoclose.key_cb = NULL;
5436 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5440 _e_comp_object_autoclose_mouse_up_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
5442 _e_comp_object_autoclose_cleanup(0);
5446 _e_comp_object_autoclose_setup(Evas_Object *obj)
5448 if (!e_comp->autoclose.rect)
5450 /* create rect just below autoclose object to catch mouse events */
5451 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5452 evas_object_move(e_comp->autoclose.rect, 0, 0);
5453 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5454 evas_object_show(e_comp->autoclose.rect);
5455 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5456 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5457 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5458 e_comp_grab_input(0, 1);
5460 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5461 evas_object_focus_set(obj, 1);
5465 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5467 _e_comp_object_autoclose_setup(obj);
5468 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5472 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5474 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5475 _e_comp_object_autoclose_cleanup(1);
5476 if (e_client_focused_get()) return;
5478 E_Zone *zone = e_zone_current_get();
5481 e_zone_focus_reset(zone);
5485 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5489 if (e_comp->autoclose.obj)
5491 if (e_comp->autoclose.obj == obj) return;
5492 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5493 e_comp->autoclose.obj = obj;
5494 e_comp->autoclose.del_cb = del_cb;
5495 e_comp->autoclose.key_cb = cb;
5496 e_comp->autoclose.data = (void*)data;
5497 if (evas_object_visible_get(obj))
5498 _e_comp_object_autoclose_setup(obj);
5500 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5501 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5504 e_comp->autoclose.obj = obj;
5505 e_comp->autoclose.del_cb = del_cb;
5506 e_comp->autoclose.key_cb = cb;
5507 e_comp->autoclose.data = (void*)data;
5508 if (evas_object_visible_get(obj))
5509 _e_comp_object_autoclose_setup(obj);
5511 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5512 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5516 e_comp_object_is_animating(Evas_Object *obj)
5520 return cw->animating;
5524 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5528 if ((cw->external_content) &&
5529 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5531 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5532 "But current external content is %d object for %p.",
5533 cw->content_type, cw->ec);
5537 cw->user_alpha_set = EINA_TRUE;
5538 cw->user_alpha = alpha;
5540 if (!cw->obj) return;
5542 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5544 evas_object_image_alpha_set(cw->obj, alpha);
5546 if ((!cw->native) && (!cw->external_content))
5547 evas_object_image_data_set(cw->obj, NULL);
5551 e_comp_object_alpha_get(Evas_Object *obj)
5553 API_ENTRY EINA_FALSE;
5555 return evas_object_image_alpha_get(cw->obj);
5559 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5561 Eina_Bool mask_set = EINA_FALSE;
5565 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5566 if (cw->ec->input_only) return;
5573 o = evas_object_rectangle_add(e_comp->evas);
5574 evas_object_color_set(o, 0, 0, 0, 0);
5575 evas_object_clip_set(o, cw->clip);
5576 evas_object_smart_member_add(o, obj);
5577 evas_object_move(o, 0, 0);
5578 evas_object_resize(o, cw->w, cw->h);
5579 /* save render op value to restore when clear a mask.
5581 * NOTE: DO NOT change the render op on ec->frame while mask object
5582 * is set. it will overwrite the changed op value. */
5583 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5584 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5585 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5586 if (cw->visible) evas_object_show(o);
5589 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5590 ELOGF("COMP", " |mask_obj", cw->ec);
5591 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5598 evas_object_smart_member_del(cw->mask.obj);
5599 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5601 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5602 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5608 e_comp_object_mask_has(Evas_Object *obj)
5610 API_ENTRY EINA_FALSE;
5612 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5616 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5621 if ((cw->external_content) &&
5622 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5624 WRN("Can set up size to ONLY evas \"image\" object. "
5625 "But current external content is %d object for %p.",
5626 cw->content_type, cw->ec);
5630 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5632 evas_object_image_size_set(cw->obj, tw, th);
5636 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5638 Eina_Bool transform_set = EINA_FALSE;
5640 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5641 if (cw->ec->input_only) return;
5643 transform_set = !!set;
5647 if (!cw->transform_bg_obj)
5649 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5650 evas_object_move(o, 0, 0);
5651 evas_object_resize(o, 1, 1);
5652 if (cw->transform_bg_color.a >= 255)
5653 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5655 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5656 evas_object_color_set(o,
5657 cw->transform_bg_color.r,
5658 cw->transform_bg_color.g,
5659 cw->transform_bg_color.b,
5660 cw->transform_bg_color.a);
5661 if (cw->visible) evas_object_show(o);
5663 cw->transform_bg_obj = o;
5664 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5666 _e_comp_object_transform_obj_stack_update(obj);
5670 if (cw->transform_bg_obj)
5672 evas_object_smart_member_del(cw->transform_bg_obj);
5673 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5679 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5683 cw->transform_bg_color.r = r;
5684 cw->transform_bg_color.g = g;
5685 cw->transform_bg_color.b = b;
5686 cw->transform_bg_color.a = a;
5688 if (cw->transform_bg_obj)
5690 evas_object_color_set(cw->transform_bg_obj,
5691 cw->transform_bg_color.r,
5692 cw->transform_bg_color.g,
5693 cw->transform_bg_color.b,
5694 cw->transform_bg_color.a);
5699 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5702 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5703 if (cw->ec->input_only) return;
5704 if (!cw->transform_bg_obj) return;
5706 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5710 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5713 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5714 if (cw->ec->input_only) return;
5715 if (!cw->transform_bg_obj) return;
5717 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5721 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5723 Eina_Bool transform_set = EINA_FALSE;
5725 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5726 if (cw->ec->input_only) return;
5728 transform_set = !!set;
5732 if (!cw->transform_tranp_obj)
5734 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5735 evas_object_move(o, 0, 0);
5736 evas_object_resize(o, 1, 1);
5737 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5738 evas_object_color_set(o, 0, 0, 0, 0);
5739 if (cw->visible) evas_object_show(o);
5741 cw->transform_tranp_obj = o;
5742 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5743 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5744 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5746 _e_comp_object_transform_obj_stack_update(obj);
5750 if (cw->transform_tranp_obj)
5752 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5753 evas_object_smart_member_del(cw->transform_tranp_obj);
5754 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5760 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5763 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5764 if (cw->ec->input_only) return;
5765 if (!cw->transform_tranp_obj) return;
5767 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5771 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5774 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5775 if (cw->ec->input_only) return;
5776 if (!cw->transform_tranp_obj) return;
5778 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5782 e_comp_object_layer_update(Evas_Object *obj,
5783 Evas_Object *above, Evas_Object *below)
5785 E_Comp_Object *cw2 = NULL;
5786 Evas_Object *o = NULL;
5791 if (cw->ec->layer_block) return;
5792 if ((above) && (below))
5794 ERR("Invalid layer update request! cw=%p", cw);
5802 layer = evas_object_layer_get(o);
5803 cw2 = evas_object_data_get(o, "comp_obj");
5806 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5808 o = evas_object_above_get(o);
5809 if ((!o) || (o == cw->smart_obj)) break;
5810 if (evas_object_layer_get(o) != layer)
5812 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5817 ec = e_client_top_get();
5818 if (ec) o = ec->frame;
5821 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5825 _e_comp_object_layers_remove(cw);
5828 if (cw2->layer > cw->layer)
5829 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5830 else if (cw2->layer == cw->layer)
5833 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5835 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5837 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5840 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5843 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5847 e_comp_object_layer_get(Evas_Object *obj)
5854 e_comp_object_content_set(Evas_Object *obj,
5855 Evas_Object *content,
5856 E_Comp_Object_Content_Type type)
5858 API_ENTRY EINA_FALSE;
5860 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5861 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5862 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5866 ERR("Can't set e.swallow.content to requested content. "
5867 "Previous comp object should not be changed at all.");
5871 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5873 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5874 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5876 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5877 type, content, cw->ec, cw->ec->pixmap);
5881 cw->external_content = EINA_TRUE;
5884 cw->content_type = type;
5885 e_util_size_debug_set(cw->obj, 1);
5886 evas_object_name_set(cw->obj, "cw->obj");
5887 _e_comp_object_alpha_set(cw);
5890 _e_comp_object_shadow_setup(cw);
5896 e_comp_object_content_unset(Evas_Object *obj)
5898 API_ENTRY EINA_FALSE;
5900 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5901 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5903 if (!cw->obj && !cw->ec->visible)
5905 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5909 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5911 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5917 if (cw->frame_object)
5918 edje_object_part_unswallow(cw->frame_object, cw->obj);
5920 edje_object_part_unswallow(cw->shobj, cw->obj);
5922 evas_object_del(cw->obj);
5923 evas_object_hide(cw->obj);
5927 cw->external_content = EINA_FALSE;
5928 if (cw->ec->is_cursor)
5931 DBG("%p is cursor surface..", cw->ec);
5932 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5934 evas_object_resize(cw->ec->frame, pw, ph);
5935 evas_object_hide(cw->ec->frame);
5940 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5941 cw->obj = evas_object_image_filled_add(e_comp->evas);
5942 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5943 e_util_size_debug_set(cw->obj, 1);
5944 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5945 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5946 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5947 evas_object_name_set(cw->obj, "cw->obj");
5948 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5949 _e_comp_object_alpha_set(cw);
5952 _e_comp_object_shadow_setup(cw);
5957 _e_comp_intercept_show_helper(cw);
5961 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5962 e_comp_object_dirty(cw->smart_obj);
5963 e_comp_object_render(cw->smart_obj);
5964 e_comp_object_render_update_add(obj);
5969 EINTERN Evas_Object *
5970 e_comp_object_content_get(Evas_Object *obj)
5974 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5976 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5978 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5985 E_API E_Comp_Object_Content_Type
5986 e_comp_object_content_type_get(Evas_Object *obj)
5988 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5990 return cw->content_type;
5994 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5997 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5998 E_Comp_Config *conf = e_comp_config_get();
5999 if (cw->ec->input_only) return;
6000 if (!conf->dim_rect_enable) return;
6002 cw->dim.mask_set = mask_set;
6008 if (!cw->dim.enable) return;
6009 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6013 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6015 Eina_Bool mask_set = EINA_FALSE;
6019 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6020 E_Comp_Config *conf = e_comp_config_get();
6021 if (cw->ec->input_only) return;
6022 if (!conf->dim_rect_enable) return;
6028 if (cw->dim.mask_obj)
6030 evas_object_smart_member_del(cw->dim.mask_obj);
6031 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6034 ELOGF("COMP", "DIM |Mask applied on Dim rect mask_rect[%d %d %d %d]", cw->ec, cw->dim.mask_x, cw->dim.mask_y, cw->dim.mask_w, cw->dim.mask_h);
6035 o = evas_object_rectangle_add(e_comp->evas);
6036 evas_object_color_set(o, 0, 0, 0, 0);
6037 evas_object_smart_member_add(o, obj);
6038 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6039 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6041 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6042 if (cw->visible) evas_object_show(o);
6044 cw->dim.mask_obj = o;
6045 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6047 evas_object_layer_set(cw->dim.mask_obj, 9998);
6051 if (cw->dim.mask_obj)
6053 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6054 evas_object_smart_member_del(cw->dim.mask_obj);
6055 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6061 e_comp_object_dim_client_set(E_Client *ec)
6063 E_Comp_Config *conf = e_comp_config_get();
6065 if (!conf->dim_rect_enable) return ;
6066 if (dim_client == ec) return;
6068 Eina_Bool prev_dim = EINA_FALSE;
6069 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6071 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6072 prev_dim = EINA_TRUE;
6074 if (prev_dim && dim_client->visible && ec)
6076 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6077 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6081 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6082 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6088 e_comp_object_dim_client_get(void)
6090 E_Comp_Config *conf = e_comp_config_get();
6092 if (!conf->dim_rect_enable ) return NULL;
6098 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6101 char emit[32] = "\0";
6102 E_Comp_Config *conf = e_comp_config_get();
6105 if (!conf->dim_rect_enable) return;
6106 if (!cw->effect_obj) return;
6107 if (enable == cw->dim.enable) return;
6109 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6110 if (noeffect || !conf->dim_rect_effect)
6112 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6116 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6119 cw->dim.enable = enable;
6121 if (cw->dim.mask_set && !enable)
6123 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6124 edje_object_signal_emit(cw->effect_obj, emit, "e");
6126 else if (cw->dim.mask_set && enable)
6128 edje_object_signal_emit(cw->effect_obj, emit, "e");
6129 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6133 edje_object_signal_emit(cw->effect_obj, emit, "e");
6138 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6140 API_ENTRY EINA_FALSE;
6141 E_Comp_Config *conf = e_comp_config_get();
6143 if (!ec) return EINA_FALSE;
6144 if (!conf->dim_rect_enable) return EINA_FALSE;
6146 if (cw->dim.enable) return EINA_TRUE;
6152 _e_comp_object_dim_update(E_Comp_Object *cw)
6154 E_Comp_Config *conf = e_comp_config_get();
6157 if (!conf->dim_rect_enable) return;
6158 if (!cw->effect_obj) return;
6161 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6162 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6164 if (cw->dim.mask_set)
6166 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6172 e_comp_object_clear(Evas_Object *obj)
6176 _e_comp_object_clear(cw);
6180 e_comp_object_hwc_update_exists(Evas_Object *obj)
6182 API_ENTRY EINA_FALSE;
6183 return cw->hwc_need_update;
6188 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6191 cw->hwc_need_update = set;
6195 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6197 API_ENTRY EINA_FALSE;
6198 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6202 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6205 if (cw->indicator.obj != indicator)
6206 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6207 cw->indicator.obj = indicator;
6208 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6212 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6215 if (cw->indicator.obj != indicator) return;
6216 cw->indicator.obj = NULL;
6217 edje_object_part_unswallow(cw->shobj, indicator);
6221 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6224 Edje_Message_Int_Set *msg;
6226 if (!cw->indicator.obj) return;
6228 cw->indicator.w = w;
6229 cw->indicator.h = h;
6231 if (!cw->shobj) return;
6233 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6237 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6238 edje_object_message_signal_process(cw->shobj);
6241 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6243 e_comp_object_map_update(Evas_Object *obj)
6246 E_Client *ec = cw->ec;
6247 E_Comp_Wl_Client_Data *cdata;
6249 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6252 int l, remain = sizeof buffer;
6255 if (e_object_is_del(E_OBJECT(ec))) return;
6256 cdata = e_client_cdata_get(ec);
6259 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6260 * when new buffer is attached.
6262 if (!cdata->buffer_ref.buffer) return;
6264 if ((!cw->redirected) ||
6265 (e_client_video_hw_composition_check(ec)) ||
6266 (!e_comp_wl_output_buffer_transform_get(ec) &&
6267 cdata->scaler.buffer_viewport.buffer.scale == 1))
6269 if (evas_object_map_enable_get(cw->effect_obj))
6271 ELOGF("TRANSFORM", "map: disable", cw->ec);
6272 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6273 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6274 evas_object_resize(cw->effect_obj, tw, th);
6281 EINA_SAFETY_ON_NULL_RETURN(map);
6283 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6289 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6291 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6292 e_map_point_image_uv_set(map, 0, x, y);
6293 l = snprintf(p, remain, "%d,%d", x, y);
6294 p += l, remain -= l;
6296 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6297 e_map_point_image_uv_set(map, 1, x, y);
6298 l = snprintf(p, remain, " %d,%d", x, y);
6299 p += l, remain -= l;
6301 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6302 e_map_point_image_uv_set(map, 2, x, y);
6303 l = snprintf(p, remain, " %d,%d", x, y);
6304 p += l, remain -= l;
6306 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6307 e_map_point_image_uv_set(map, 3, x, y);
6308 l = snprintf(p, remain, " %d,%d", x, y);
6309 p += l, remain -= l;
6311 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6313 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6315 e_comp_object_map_set(cw->effect_obj, map);
6316 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6320 /* if there's screen rotation with comp mode, then ec->effect_obj and
6321 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6323 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6324 evas_object_resize(cw->effect_obj, tw, th);
6328 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6330 API_ENTRY EINA_FALSE;
6332 cw->render_trace = set;
6338 e_comp_object_native_usable_get(Evas_Object *obj)
6340 API_ENTRY EINA_FALSE;
6341 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6343 if (cw->ec->input_only) return EINA_FALSE;
6344 if (cw->external_content) return EINA_FALSE;
6345 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6347 /* just return true value, if it is normal case */
6348 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6351 Evas_Native_Surface *ns;
6352 ns = evas_object_image_native_surface_get(cw->obj);
6354 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6357 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6365 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6367 API_ENTRY EINA_FALSE;
6368 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6369 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6370 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6374 case E_COMP_IMAGE_FILTER_BLUR:
6375 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6377 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6378 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6380 case E_COMP_IMAGE_FILTER_INVERSE:
6381 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6383 case E_COMP_IMAGE_FILTER_NONE:
6385 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6389 cw->image_filter = filter;
6394 EINTERN E_Comp_Image_Filter
6395 e_comp_object_image_filter_get(Evas_Object *obj)
6397 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6398 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6399 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6400 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6402 return cw->image_filter;
6406 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6410 if (!_damage_trace) return;
6412 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6413 evas_object_del(obj);
6415 _damage_trace_post_objs = NULL;
6419 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6421 if (!_damage_trace) return;
6423 _damage_trace_post_objs = _damage_trace_objs;
6424 _damage_trace_objs = NULL;
6428 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6430 if (_damage_trace == onoff) return;
6434 evas_event_callback_add(e_comp->evas,
6435 EVAS_CALLBACK_RENDER_PRE,
6436 _e_comp_object_damage_trace_render_pre_cb,
6439 evas_event_callback_add(e_comp->evas,
6440 EVAS_CALLBACK_RENDER_POST,
6441 _e_comp_object_damage_trace_render_post_cb,
6448 EINA_LIST_FREE(_damage_trace_objs, obj)
6449 evas_object_del(obj);
6451 _damage_trace_objs = NULL;
6453 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6454 evas_object_del(obj);
6456 _damage_trace_post_objs = NULL;
6458 evas_event_callback_del(e_comp->evas,
6459 EVAS_CALLBACK_RENDER_PRE,
6460 _e_comp_object_damage_trace_render_pre_cb);
6462 evas_event_callback_del(e_comp->evas,
6463 EVAS_CALLBACK_RENDER_POST,
6464 _e_comp_object_damage_trace_render_post_cb);
6467 _damage_trace = onoff;
6471 e_comp_object_redirected_get(Evas_Object *obj)
6473 API_ENTRY EINA_FALSE;
6474 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6476 return cw->redirected;
6480 e_comp_object_color_visible_get(Evas_Object *obj)
6482 API_ENTRY EINA_FALSE;
6485 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6487 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6491 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6495 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6499 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6507 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6509 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6511 return e_map_set_to_comp_object(em, obj);
6515 e_comp_object_map_get(const Evas_Object *obj)
6517 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6519 return e_map_get_from_comp_object(obj);
6523 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6525 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6527 evas_object_map_enable_set(obj, enable);
6533 e_comp_object_render_update_lock(Evas_Object *obj)
6535 E_Comp_Wl_Buffer *buffer;
6536 struct wayland_tbm_client_queue *cqueue;
6538 API_ENTRY EINA_FALSE;
6540 if (cw->render_update_lock.lock == 0)
6542 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6544 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6545 if ((buffer) && (buffer->resource))
6547 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6549 wayland_tbm_server_client_queue_flush(cqueue);
6552 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6553 e_comp_object_render_update_del(obj);
6555 ELOGF("COMP", "Render update lock enabled", cw->ec);
6558 cw->render_update_lock.lock++;
6564 e_comp_object_render_update_unlock(Evas_Object *obj)
6568 if (cw->render_update_lock.lock == 0)
6571 cw->render_update_lock.lock--;
6573 if (cw->render_update_lock.lock == 0)
6576 if (cw->render_update_lock.pending_move_set)
6578 evas_object_move(obj,
6579 cw->render_update_lock.pending_move_x,
6580 cw->render_update_lock.pending_move_y);
6581 cw->render_update_lock.pending_move_x = 0;
6582 cw->render_update_lock.pending_move_y = 0;
6583 cw->render_update_lock.pending_move_set = EINA_FALSE;
6586 if (cw->render_update_lock.pending_resize_set)
6588 evas_object_resize(obj,
6589 cw->render_update_lock.pending_resize_w,
6590 cw->render_update_lock.pending_resize_h);
6591 cw->render_update_lock.pending_resize_w = 0;
6592 cw->render_update_lock.pending_resize_h = 0;
6593 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6596 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6598 if ((cw->ec->exp_iconify.buffer_flush) &&
6599 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6600 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6601 e_comp_object_clear(obj);
6603 e_comp_object_render_update_add(obj);
6605 ELOGF("COMP", "Render update lock disabled", cw->ec);
6610 e_comp_object_render_update_lock_get(Evas_Object *obj)
6612 API_ENTRY EINA_FALSE;
6614 if (cw->render_update_lock.lock > 0)
6621 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6625 if (cw->transparent.set)
6627 if (r) *r = cw->transparent.user_r;
6628 if (g) *g = cw->transparent.user_g;
6629 if (b) *b = cw->transparent.user_b;
6630 if (a) *a = cw->transparent.user_a;
6634 evas_object_color_get(obj, r, g, b, a);
6639 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6643 evas_object_render_op_set(cw->obj, op);
6646 EINTERN Evas_Render_Op
6647 e_comp_object_render_op_get(Evas_Object *obj)
6649 API_ENTRY EVAS_RENDER_BLEND;
6651 return evas_object_render_op_get(cw->obj);
6655 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6658 wl_signal_add(&cw->events.lower, listener);
6661 EINTERN struct wl_listener *
6662 e_comp_object_lower_listener_get(Evas_Object *obj, wl_notify_func_t notify)
6665 return wl_signal_get(&cw->events.lower, notify);
6669 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6672 wl_signal_add(&cw->events.show, listener);
6675 EINTERN struct wl_listener *
6676 e_comp_object_show_listener_get(Evas_Object *obj, wl_notify_func_t notify)
6679 return wl_signal_get(&cw->events.show, notify);
6683 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6686 wl_signal_add(&cw->events.hide, listener);
6689 EINTERN struct wl_listener *
6690 e_comp_object_hide_listener_get(Evas_Object *obj, wl_notify_func_t notify)
6693 return wl_signal_get(&cw->events.hide, notify);