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;
189 typedef struct _E_Input_Rect_Data
195 typedef struct _E_Input_Rect_Smart_Data
197 Eina_List *input_rect_data_list;
199 } E_Input_Rect_Smart_Data;
201 struct E_Comp_Object_Mover
204 E_Comp_Object_Mover_Cb func;
210 static Eina_Inlist *_e_comp_object_movers = NULL;
211 static Evas_Smart *_e_comp_smart = NULL;
212 static Evas_Smart *_e_comp_input_obj_smart = NULL;
214 static int _e_comp_object_hooks_delete = 0;
215 static int _e_comp_object_hooks_walking = 0;
217 static Eina_Inlist *_e_comp_object_hooks[] =
219 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
220 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
221 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
222 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
223 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
224 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
225 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
226 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
229 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
230 static int _e_comp_object_intercept_hooks_delete = 0;
231 static int _e_comp_object_intercept_hooks_walking = 0;
233 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
235 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
236 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
240 static Eina_Bool _damage_trace = EINA_FALSE;
241 static Eina_List *_damage_trace_objs = NULL;
242 static Eina_List *_damage_trace_post_objs = NULL;
244 /* sekrit functionzzz */
245 EINTERN void e_client_focused_set(E_Client *ec);
247 /* emitted every time a new noteworthy comp object is added */
248 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
250 /* ecore event define */
251 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
252 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
253 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
255 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
256 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
257 static void _e_comp_object_dim_update(E_Comp_Object *cw);
258 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
259 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
261 static E_Client *dim_client = NULL;
264 _e_comp_object_hooks_clean(void)
267 E_Comp_Object_Hook *ch;
270 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
271 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
273 if (!ch->delete_me) continue;
274 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
280 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
282 E_Comp_Object_Hook *ch;
283 Eina_Bool ret = EINA_TRUE;
285 if (e_object_is_del(E_OBJECT(ec)))
287 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
288 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
289 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
290 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
291 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
292 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
293 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
294 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET))
299 e_object_ref(E_OBJECT(ec));
300 _e_comp_object_hooks_walking++;
301 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
303 if (ch->delete_me) continue;
304 if (!(ch->func(ch->data, ec)))
310 _e_comp_object_hooks_walking--;
311 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
312 _e_comp_object_hooks_clean();
314 e_object_unref(E_OBJECT(ec));
319 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
321 _e_comp_object_intercept_hooks_clean(void)
324 E_Comp_Object_Intercept_Hook *ch;
327 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
328 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
330 if (!ch->delete_me) continue;
331 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
337 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
339 E_Comp_Object_Intercept_Hook *ch;
340 Eina_Bool ret = EINA_TRUE;
342 if (e_object_is_del(E_OBJECT(ec))) return ret;
343 e_object_ref(E_OBJECT(ec));
344 _e_comp_object_intercept_hooks_walking++;
345 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
347 if (ch->delete_me) continue;
348 if (!(ch->func(ch->data, ec)))
354 _e_comp_object_intercept_hooks_walking--;
355 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
356 _e_comp_object_intercept_hooks_clean();
358 e_object_unref(E_OBJECT(ec));
365 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
367 E_Event_Comp_Object *ev = event;
370 ec = evas_object_data_get(ev->comp_object, "E_Client");
374 e_object_unref(E_OBJECT(ec));
376 evas_object_unref(ev->comp_object);
381 _e_comp_object_event_add(Evas_Object *obj)
383 E_Event_Comp_Object *ev;
386 if (stopping) return;
387 ev = E_NEW(E_Event_Comp_Object, 1);
388 EINA_SAFETY_ON_NULL_RETURN(ev);
390 evas_object_ref(obj);
391 ev->comp_object = obj;
392 ec = evas_object_data_get(ev->comp_object, "E_Client");
396 e_object_ref(E_OBJECT(ec));
398 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
402 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
404 E_Event_Comp_Object *ev = event;
407 ec = evas_object_data_get(ev->comp_object, "E_Client");
411 e_object_unref(E_OBJECT(ec));
413 evas_object_unref(ev->comp_object);
418 _e_comp_object_event_simple(Evas_Object *obj, int type)
420 E_Event_Comp_Object *ev;
423 ev = E_NEW(E_Event_Comp_Object, 1);
426 evas_object_ref(obj);
427 ev->comp_object = obj;
428 ec = evas_object_data_get(ev->comp_object, "E_Client");
432 e_object_ref(E_OBJECT(ec));
434 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
436 /////////////////////////////////////
439 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
441 E_Comp_Object *cw = data;
443 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
447 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
449 E_Comp_Object *cw = data;
451 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
452 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
455 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
456 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
460 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
462 E_Comp_Object *cw = data;
465 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
466 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
469 /////////////////////////////////////
472 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
476 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
477 if (cw->ec->input_only) return;
479 layer = evas_object_layer_get(obj);
481 if (cw->transform_bg_obj)
483 if (layer != evas_object_layer_get(cw->transform_bg_obj))
485 evas_object_layer_set(cw->transform_bg_obj, layer);
488 evas_object_stack_below(cw->transform_bg_obj, obj);
491 if (cw->transform_tranp_obj)
493 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
495 evas_object_layer_set(cw->transform_tranp_obj, layer);
498 evas_object_stack_below(cw->transform_tranp_obj, obj);
503 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
510 if (!map) return NULL;
512 e_map_util_points_populate_from_object_full(map, obj, 0);
513 e_map_util_points_color_set(map, 255, 255, 255, 255);
515 for (i = 0 ; i < 4 ; ++i)
520 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
521 e_map_point_coord_set(map, i, x, y, 1.0);
528 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
534 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
537 e_comp_object_map_set(obj, map);
538 e_comp_object_map_enable_set(obj, EINA_TRUE);
545 evas_object_map_enable_set(obj, EINA_FALSE);
550 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
556 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
559 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
561 e_comp_object_map_set(obj, map);
562 e_comp_object_map_enable_set(obj, EINA_TRUE);
569 evas_object_map_enable_set(obj, EINA_FALSE);
572 /////////////////////////////////////
574 static inline Eina_Bool
575 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
577 if (num > 1) return EINA_TRUE;
578 if ((rects[0].x == 0) && (rects[0].y == 0) &&
579 ((int)rects[0].w == w) && ((int)rects[0].h == h))
584 /////////////////////////////////////
586 /* add a client to the layer-client list */
588 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
590 E_Comp_Object *layer_cw = NULL;
592 /* try to get the internal data for the layer;
593 * will return NULL for fake layers (eg. wayland)
595 if (e_comp->layers[cw->layer].obj)
597 if (evas_object_smart_smart_get(e_comp->layers[cw->layer].obj))
598 layer_cw = evas_object_smart_data_get(e_comp->layers[cw->layer].obj);
600 if (layer_cw == cw) layer_cw = NULL;
602 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));
604 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));
605 if ((!above) && (!below))
608 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
610 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));
611 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
612 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
614 e_comp->layers[cw->layer].clients_count++;
615 #ifndef E_RELEASE_BUILD
618 E_Client *below_ec = e_client_below_get(cw->ec);
621 if (e_comp->layers[cw->layer].obj == below_ec->frame)
622 CRI("ACK! ec:%p", cw->ec);
629 _e_comp_object_layers_remove(E_Comp_Object *cw)
631 if (cw->ec && e_comp->layers[cw->layer].clients)
633 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
634 e_comp->layers[cw->layer].clients_count--;
637 e_comp->layers[cw->layer].objs = eina_inlist_remove(e_comp->layers[cw->layer].objs, EINA_INLIST_GET(cw));
638 e_comp->layers[cw->layer].objs_count--;
642 /////////////////////////////////////
644 _e_comp_object_alpha_set(E_Comp_Object *cw)
646 Eina_Bool alpha = cw->ec->argb;
648 if ((cw->external_content) &&
649 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
654 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
655 if (cw->user_alpha_set) alpha = cw->user_alpha;
657 evas_object_image_alpha_set(cw->obj, alpha);
661 _e_comp_object_shadow(E_Comp_Object *cw)
663 if (e_client_util_shadow_state_get(cw->ec))
664 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
666 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
667 if (cw->frame_object)
668 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
669 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
672 /* convert from the surface coordinates to the buffer coordinates */
674 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
676 E_Comp_Wl_Buffer_Viewport *vp;
677 E_Comp_Wl_Client_Data *cdata;
681 cdata = e_client_cdata_get(ec);
683 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
690 vp = &cdata->scaler.buffer_viewport;
691 transform = e_comp_wl_output_buffer_transform_get(ec);
693 e_pixmap_size_get(ec->pixmap, &bw, &bh);
695 /* for subsurface, it should be swap 90 and 270 */
696 if (e_comp_wl_subsurface_check(ec))
699 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
700 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
701 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
702 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
708 case WL_OUTPUT_TRANSFORM_NORMAL:
709 default: tx = sx, ty = sy; break;
710 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
711 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
712 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
713 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
714 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
715 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
716 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
719 tx *= vp->buffer.scale;
720 ty *= vp->buffer.scale;
727 _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)
735 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
736 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
743 if (dw) *dw = MAX(x1, x2) - mx;
744 if (dh) *dh = MAX(y1, y2) - my;
748 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
749 int *dx, int *dy, int *dw, int *dh)
751 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
752 E_Util_Transform_Rect_Vertex sv, dv;
756 e_pixmap_size_get(ec->pixmap, &bw, &bh);
758 sv = e_util_transform_rect_to_vertices(&rect);
760 for (i = 0; i < 4; i++)
762 double x = 0.0, y = 0.0;
764 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
766 /* if evas decide coordinate is outside of map, it returns (0, 0)
767 in this case, full damage is added.
769 if ((i != 0) && (x == 0.0) && (y == 0.0))
772 dv.vertices[i].vertex[0] = x;
773 dv.vertices[i].vertex[1] = y;
774 dv.vertices[i].vertex[2] = 1.0;
775 dv.vertices[i].vertex[3] = 1.0;
778 rect = e_util_transform_vertices_to_rect(&dv);
780 if (dx) *dx = rect.x;
781 if (dy) *dy = rect.y;
782 if (dw) *dw = rect.w;
783 if (dh) *dh = rect.h;
797 _e_comp_object_map_damage_transform_get(E_Client *ec)
804 if (!evas_object_map_enable_get(ec->frame))
807 m = e_client_map_get(ec);
811 e_pixmap_size_get(ec->pixmap, &bw, &bh);
812 if ((bw == 0) || (bh == 0))
825 e_map_point_coord_set(m2, 0, 0, 0, 0);
826 e_map_point_coord_set(m2, 1, bw, 0, 0);
827 e_map_point_coord_set(m2, 2, bw, bh, 0);
828 e_map_point_coord_set(m2, 3, 0, bh, 0);
830 for (i = 0; i < 4; i++)
834 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
835 e_map_point_image_uv_set(m2, i, map_x, map_y);
842 /////////////////////////////////////
844 /* handle evas mouse-in events on client object */
846 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
848 Evas_Event_Mouse_In *ev = event_info;
849 E_Comp_Object *cw = data;
851 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
854 /* handle evas mouse-out events on client object */
856 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
858 Evas_Event_Mouse_Out *ev = event_info;
859 E_Comp_Object *cw = data;
861 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
864 /* handle evas mouse wheel events on client object */
866 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
868 Evas_Event_Mouse_Wheel *ev = event_info;
869 E_Comp_Object *cw = data;
870 E_Binding_Event_Wheel ev2;
873 if (e_client_action_get()) return;
874 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
875 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
878 /* handle evas mouse down events on client object */
880 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
882 Evas_Event_Mouse_Down *ev = event_info;
883 E_Comp_Object *cw = data;
884 E_Binding_Event_Mouse_Button ev2;
887 if (e_client_action_get()) return;
888 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
889 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
892 /* handle evas mouse up events on client object */
894 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
896 Evas_Event_Mouse_Up *ev = event_info;
897 E_Comp_Object *cw = data;
898 E_Binding_Event_Mouse_Button ev2;
901 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
902 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
903 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
906 /* handle evas mouse movement events on client object */
908 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
910 Evas_Event_Mouse_Move *ev = event_info;
911 E_Comp_Object *cw = data;
914 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
915 e_client_mouse_move(cw->ec, &ev->cur.output);
917 /////////////////////////////////////
919 /* helper function for checking compositor themes based on user-defined matches */
921 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
923 if (((m->title) && (!ec->netwm.name)) ||
924 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
926 #if defined(__cplusplus) || defined(c_plusplus)
927 if (((m->clas) && (!ec->icccm.cpp_class)) ||
928 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
931 if (((m->clas) && (!ec->icccm.class)) ||
932 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
936 if (((m->role) && (!ec->icccm.window_role)) ||
937 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
943 if ((int)ec->netwm.type != m->primary_type)
946 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
949 if (m->borderless != 0)
953 if (e_client_util_borderless(ec))
955 if (!(((m->borderless == -1) && (!borderless)) ||
956 ((m->borderless == 1) && (borderless))))
963 if (((ec->icccm.transient_for != 0) ||
966 if (!(((m->dialog == -1) && (!dialog)) ||
967 ((m->dialog == 1) && (dialog))))
970 if (m->accepts_focus != 0)
972 int accepts_focus = 0;
974 if (ec->icccm.accepts_focus)
976 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
977 ((m->accepts_focus == 1) && (accepts_focus))))
986 if (!(((m->vkbd == -1) && (!vkbd)) ||
987 ((m->vkbd == 1) && (vkbd))))
992 if (!(((m->argb == -1) && (!ec->argb)) ||
993 ((m->argb == 1) && (ec->argb))))
996 if (m->fullscreen != 0)
998 int fullscreen = ec->fullscreen;
1000 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1001 ((m->fullscreen == 1) && (fullscreen))))
1008 if (ec->netwm.state.modal)
1010 if (!(((m->modal == -1) && (!modal)) ||
1011 ((m->modal == 1) && (modal))))
1017 /* function for setting up a client's compositor frame theme (cw->shobj) */
1019 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1023 Eina_List *list = NULL, *l;
1024 E_Input_Rect_Data *input_rect_data;
1025 E_Input_Rect_Smart_Data *input_rect_sd;
1027 Eina_Stringshare *reshadow_group = NULL;
1028 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;
1029 Eina_Stringshare *name, *title;
1030 E_Comp_Config *conf = e_comp_config_get();
1032 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1033 /* match correct client type */
1034 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1035 name = cw->ec->icccm.name;
1036 title = cw->ec->icccm.title;
1037 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1038 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1040 /* skipping here is mostly a hack for systray because I hate it */
1043 EINA_LIST_FOREACH(list, l, m)
1045 if (((m->name) && (!name)) ||
1046 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1048 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1052 no_shadow = m->no_shadow;
1053 if (m->shadow_style)
1055 /* fast effects are just themes with "/fast" appended and shorter effect times */
1058 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1059 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1061 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1063 /* default to non-fast style if fast not available */
1066 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1067 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1069 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1071 if (ok && m->visibility_effect)
1072 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1079 if (skip || (cw->ec->e.state.video))
1081 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1083 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1086 if (conf->shadow_style)
1090 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1091 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1093 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1097 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1098 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1100 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1107 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1109 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1113 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1115 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1120 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1125 if (cw->ec->override)
1127 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1128 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1130 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1131 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1137 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1138 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1141 _e_comp_object_shadow(cw);
1144 if (focus || cw->ec->focused || cw->ec->override)
1145 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1147 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1148 if (urgent || cw->ec->urgent)
1149 e_comp_object_signal_emit(cw->smart_obj, "e,state,urgent", "e");
1151 e_comp_object_signal_emit(cw->smart_obj, "e,state,not_urgent", "e");
1153 e_comp_object_signal_emit(cw->smart_obj, "e,state,shaded", "e");
1155 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1157 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1158 /* visibility must always be enabled for re_manage clients to prevent
1159 * pop-in animations every time the user sees a persistent client again;
1160 * applying visibility for iconic clients prevents the client from getting
1163 if (cw->visible || cw->ec->re_manage)
1164 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1166 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1168 /* breaks animation counter */
1169 if (cw->frame_object)
1171 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1172 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1173 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1174 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1180 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1184 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1187 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1189 if (input_rect_data->obj)
1191 pass_event_flag = EINA_TRUE;
1197 if (cw->indicator.obj)
1199 Evas_Object *indicator;
1200 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1201 if (indicator != cw->indicator.obj)
1203 edje_object_part_unswallow(cw->shobj, indicator);
1204 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1205 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1209 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1210 evas_object_pass_events_set(cw->obj, pass_event_flag);
1215 /////////////////////////////////////////////
1218 _e_comp_object_animating_begin(E_Comp_Object *cw)
1221 if (cw->animating == 1)
1223 e_comp->animating++;
1225 e_object_ref(E_OBJECT(cw->ec));
1230 _e_comp_object_animating_end(E_Comp_Object *cw)
1239 if (cw->ec->launching)
1241 if (!cw->ec->extra_animating)
1243 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1244 cw->ec->launching = EINA_FALSE;
1245 if (cw->ec->first_mapped)
1247 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1248 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1251 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1255 e_comp->animating--;
1256 cw->showing = cw->hiding = 0;
1258 if (e_comp->animating == 0)
1259 e_comp_visibility_calculation_set(EINA_TRUE);
1260 /* remove ref from animation start, account for possibility of deletion from unref */
1261 return !!e_object_unref(E_OBJECT(cw->ec));
1267 /* handle the end of a compositor animation */
1269 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1271 E_Comp_Object *cw = data;
1273 /* visible clients which have never been sized are a bug */
1274 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1275 CRI("ACK! ec:%p", cw->ec);
1276 if (!_e_comp_object_animating_end(cw)) return;
1277 if (cw->animating) return;
1278 /* hide only after animation finishes to guarantee a full run of the animation */
1279 if (!cw->defer_hide) return;
1280 if ((!strcmp(emission, "e,action,hide,done")) ||
1281 (!strcmp(emission, "e,action,done")) ||
1282 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1284 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1285 evas_object_hide(cw->smart_obj);
1289 /* run a visibility compositor effect if available, return false if object is dead */
1291 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1297 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1298 if (!cw->effect_running)
1299 _e_comp_object_animating_begin(cw);
1300 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1301 return _e_comp_object_animating_end(cw);
1302 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1303 return _e_comp_object_animating_end(cw);
1305 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1308 zone = e_comp_zone_find_by_ec(cw->ec);
1310 zw = zone->w, zh = zone->h;
1315 zone = e_comp_object_util_zone_get(cw->smart_obj);
1316 if (!zone) zone = e_zone_current_get();
1323 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1324 cw->w, cw->h, zw, zh, x, y}, 8);
1325 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1326 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1329 /////////////////////////////////////////////
1331 /* create necessary objects for clients that e manages */
1333 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1335 if (cw->set_mouse_callbacks) return;
1336 if (!cw->smart_obj) return;
1338 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1339 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1340 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1341 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1342 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1343 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1345 cw->set_mouse_callbacks = EINA_TRUE;
1349 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1351 if (!cw->set_mouse_callbacks) return;
1352 if (!cw->smart_obj) return;
1354 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1355 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1356 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1357 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1358 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1359 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1361 cw->set_mouse_callbacks = EINA_FALSE;
1365 _e_comp_object_setup(E_Comp_Object *cw)
1367 cw->clip = evas_object_rectangle_add(e_comp->evas);
1368 evas_object_move(cw->clip, -9999, -9999);
1369 evas_object_resize(cw->clip, 999999, 999999);
1370 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1371 cw->effect_obj = edje_object_add(e_comp->evas);
1372 evas_object_move(cw->effect_obj, cw->x, cw->y);
1373 evas_object_clip_set(cw->effect_obj, cw->clip);
1374 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1375 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1376 cw->shobj = edje_object_add(e_comp->evas);
1377 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1378 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1379 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1381 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1382 if (cw->ec->override)
1384 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1385 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1386 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1388 else if (!cw->ec->input_only)
1390 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1391 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1392 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1394 cw->real_hid = !cw->ec->input_only;
1395 if (!cw->ec->input_only)
1397 e_util_size_debug_set(cw->effect_obj, 1);
1398 _e_comp_object_mouse_event_callback_set(cw);
1401 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1402 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1403 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1404 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1405 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1406 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1408 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1411 /////////////////////////////////////////////
1413 /* for fast path evas rendering; only called during render */
1415 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1417 E_Comp_Object *cw = data;
1418 E_Client *ec = cw->ec;
1420 int bx, by, bxx, byy;
1422 if (e_object_is_del(E_OBJECT(ec))) return;
1423 if (cw->external_content) return;
1424 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1425 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1428 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1429 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1431 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1433 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1434 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1438 bx = by = bxx = byy = 0;
1439 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1442 Edje_Message_Int_Set *msg;
1443 Edje_Message_Int msg2;
1444 Eina_Bool id = (bx || by || bxx || byy);
1446 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1452 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1454 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1458 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1459 e_comp_client_post_update_add(cw->ec);
1461 else if (e_comp_object_render(ec->frame))
1463 /* apply shape mask if necessary */
1464 if ((!cw->native) && (ec->shaped || ec->shape_changed))
1465 e_comp_object_shape_apply(ec->frame);
1466 ec->shape_changed = 0;
1468 /* shaped clients get precise mouse events to handle transparent pixels */
1469 evas_object_precise_is_inside_set(cw->obj, ec->shaped || ec->shaped_input);
1471 /* queue another render if client is still dirty; cannot refresh here. */
1472 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1473 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1475 if (cw->render_trace)
1477 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1483 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1485 E_Comp_Object *cw = data;
1486 E_Client *ec = cw->ec;
1488 if (e_object_is_del(E_OBJECT(ec))) return;
1489 if (cw->external_content) return;
1490 if (!e_comp->hwc) return;
1492 e_comp_client_render_list_add(cw->ec);
1494 if (!ec->hwc_window) return;
1496 e_hwc_windows_rendered_window_add(ec->hwc_window);
1499 /////////////////////////////////////////////
1502 _e_comp_object_client_pending_resize_add(E_Client *ec,
1505 unsigned int serial)
1507 E_Client_Pending_Resize *pnd;
1509 pnd = E_NEW(E_Client_Pending_Resize, 1);
1513 pnd->serial = serial;
1514 ec->pending_resize = eina_list_append(ec->pending_resize, pnd);
1518 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1520 E_Comp_Object *cw = data;
1523 if (cw->render_update_lock.lock)
1525 cw->render_update_lock.pending_move_x = x;
1526 cw->render_update_lock.pending_move_y = y;
1527 cw->render_update_lock.pending_move_set = EINA_TRUE;
1531 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1532 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1533 (cw->external_content))
1535 /* delay to move until the external content is unset */
1536 cw->ec->changes.pos = 1;
1541 if (cw->ec->move_after_resize)
1543 if ((x != cw->ec->x) || (y != cw->ec->y))
1545 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1546 e_client_pos_set(cw->ec, x, y);
1547 cw->ec->changes.pos = 1;
1553 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1554 (cw->ec->manage_resize.resize_obj))
1556 e_client_pos_set(cw->ec, x, y);
1557 cw->ec->client.x = x + cw->client_inset.l;
1558 cw->ec->client.y = y + cw->client_inset.t;
1559 e_policy_visibility_client_defer_move(cw->ec);
1563 /* if frame_object does not exist, client_inset indicates CSD.
1564 * this means that ec->client matches cw->x/y, the opposite
1567 fx = (!cw->frame_object) * cw->client_inset.l;
1568 fy = (!cw->frame_object) * cw->client_inset.t;
1569 if ((cw->x == x + fx) && (cw->y == y + fy))
1571 if ((cw->ec->x != x) || (cw->ec->y != y))
1573 /* handle case where client tries to move to position and back very quickly */
1574 e_client_pos_set(cw->ec, x, y);
1575 cw->ec->client.x = x + cw->client_inset.l;
1576 cw->ec->client.y = y + cw->client_inset.t;
1580 if (!cw->ec->maximize_override)
1582 /* prevent moving in some directions while directionally maximized */
1583 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1585 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1588 ix = x + cw->client_inset.l;
1589 iy = y + cw->client_inset.t;
1590 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1591 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1592 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1594 /* prevent moving at all if move isn't allowed in current maximize state */
1595 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1596 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1597 if ((!cw->ec->shading) && (!cw->ec->shaded))
1600 zone = e_comp_zone_find_by_ec(cw->ec);
1603 cw->ec->changes.need_unmaximize = 1;
1604 cw->ec->saved.x = ix - zone->x;
1605 cw->ec->saved.y = iy - zone->y;
1606 cw->ec->saved.w = cw->ec->client.w;
1607 cw->ec->saved.h = cw->ec->client.h;
1613 /* only update during resize if triggered by resize */
1614 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1615 /* delay to move while surface waits paired commit serial*/
1616 if (e_client_pending_geometry_has(cw->ec))
1618 /* do nothing while waiting paired commit serial*/
1622 e_client_pos_set(cw->ec, x, y);
1623 if (cw->ec->new_client)
1625 /* don't actually do anything until first client idler loop */
1626 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1627 cw->ec->changes.pos = 1;
1632 /* only update xy position of client to avoid invalid
1633 * first damage region if it is not a new_client. */
1634 if (!cw->ec->shading)
1636 cw->ec->client.x = ix;
1637 cw->ec->client.y = iy;
1640 if (!cw->frame_object)
1642 evas_object_move(obj, x, y);
1647 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1649 E_Comp_Object *cw = data;
1650 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1653 if (cw->render_update_lock.lock)
1655 cw->render_update_lock.pending_resize_w = w;
1656 cw->render_update_lock.pending_resize_h = h;
1657 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1661 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1663 e_client_size_set(cw->ec, w, h);
1664 evas_object_resize(obj, w, h);
1668 /* if frame_object does not exist, client_inset indicates CSD.
1669 * this means that ec->client matches cw->w/h, the opposite
1672 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1673 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1674 if ((cw->w == w + fw) && (cw->h == h + fh))
1676 if (cw->ec->shading || cw->ec->shaded) return;
1677 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1678 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1679 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1681 /* handle case where client tries to resize itself and back very quickly */
1682 e_client_size_set(cw->ec, w, h);
1683 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1684 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1685 evas_object_smart_callback_call(obj, "client_resize", NULL);
1689 /* guarantee that fullscreen is fullscreen */
1690 zone = e_comp_zone_find_by_ec(cw->ec);
1692 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1694 /* calculate client size */
1695 iw = w - cw->client_inset.l - cw->client_inset.r;
1696 ih = h - cw->client_inset.t - cw->client_inset.b;
1697 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1699 /* prevent resizing while maximized depending on direction and config */
1700 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1701 if ((!cw->ec->shading) && (!cw->ec->shaded))
1703 Eina_Bool reject = EINA_FALSE;
1704 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1706 if (cw->ec->client.h != ih)
1708 cw->ec->saved.h = ih;
1709 cw->ec->saved.y = cw->ec->client.y - zone->y;
1710 reject = cw->ec->changes.need_unmaximize = 1;
1713 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1715 if (cw->ec->client.w != iw)
1717 cw->ec->saved.w = iw;
1718 cw->ec->saved.x = cw->ec->client.x - zone->x;
1719 reject = cw->ec->changes.need_unmaximize = 1;
1729 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1731 /* do nothing until client idler loops */
1732 if ((cw->ec->w != w) || (cw->ec->h != h))
1734 e_client_size_set(cw->ec, w, h);
1735 cw->ec->changes.size = 1;
1740 if ((!cw->ec->internal) && e_client_util_resizing_get(cw->ec) && cw->ec->netwm.sync.request &&
1741 ((cw->ec->w != w) || (cw->ec->h != h)))
1744 /* netwm sync resizes queue themselves and then trigger later on */
1745 _e_comp_object_client_pending_resize_add(cw->ec, iw, ih, cw->ec->netwm.sync.serial);
1747 if (e_client_pending_geometry_has(cw->ec))
1749 /* do nothing while waiting paired commit serial*/
1753 e_client_size_set(cw->ec, w, h);
1754 if ((!cw->ec->shading) && (!cw->ec->shaded))
1756 /* client geom never changes when shading since the client is never altered */
1757 cw->ec->client.w = iw;
1758 cw->ec->client.h = ih;
1759 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1762 /* The size of non-compositing window can be changed, so there is a
1763 * need to check that cw is H/W composited if cw is not redirected.
1764 * And of course we have to change size of evas object of H/W composited cw,
1765 * otherwise cw can't receive input events even if it is shown on the screen.
1767 Eina_Bool redirected = cw->redirected;
1769 redirected = e_comp_is_on_overlay(cw->ec);
1771 if ((!cw->ec->input_only) && (redirected) &&
1772 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1773 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1774 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1775 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1778 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1779 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1781 prev_w = cw->w, prev_h = cw->h;
1782 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1783 /* check shading and clamp to pixmap size for regular clients */
1784 if ((!cw->ec->shading) && (!cw->ec->shaded) && (!cw->ec->input_only) && (!cw->ec->override) &&
1785 (((w - fw != pw) || (h - fh != ph))))
1787 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1788 evas_object_smart_callback_call(obj, "client_resize", NULL);
1790 if (cw->frame_object || cw->ec->input_only)
1791 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1794 if ((cw->w == w) && (cw->h == h))
1796 /* going to be a noop resize which won't trigger smart resize */
1797 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1798 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1800 evas_object_resize(obj, w, h);
1804 evas_object_smart_callback_call(obj, "client_resize", NULL);
1807 if ((!cw->frame_object) && (!cw->ec->input_only))
1809 /* "just do it" for overrides */
1810 evas_object_resize(obj, w, h);
1812 if (!cw->ec->override)
1814 /* shape probably changed for non-overrides */
1815 cw->ec->need_shape_merge |= cw->ec->shaped || cw->ec->shaped_input;
1816 cw->ec->need_shape_export |= cw->ec->shaped;
1817 if (cw->ec->shaped || cw->ec->shaped_input)
1821 /* this fixes positioning jiggles when using a resize mode
1822 * which also changes the client's position
1825 if (cw->frame_object)
1826 x = cw->x, y = cw->y;
1828 x = cw->ec->x, y = cw->ec->y;
1829 switch (cw->ec->resize_mode)
1831 case E_POINTER_RESIZE_BL:
1832 case E_POINTER_RESIZE_L:
1833 evas_object_move(obj, x + prev_w - cw->w, y);
1835 case E_POINTER_RESIZE_TL:
1836 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1838 case E_POINTER_RESIZE_T:
1839 case E_POINTER_RESIZE_TR:
1840 evas_object_move(obj, x, y + prev_h - cw->h);
1849 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1851 E_Comp_Object *cw = data;
1852 E_Comp_Wl_Client_Data *child_cdata;
1853 unsigned int l = e_comp_canvas_layer_map(layer);
1856 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1858 /* doing a compositor effect, follow directions */
1859 _e_comp_object_layer_set(obj, layer);
1860 if (layer == cw->ec->layer) //trying to put layer back
1864 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1865 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1866 if (cw->layer != l) goto layer_set;
1870 e_comp_render_queue();
1872 ec = e_client_above_get(cw->ec);
1873 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1874 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1875 ec = e_client_above_get(ec);
1876 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1878 ec = e_client_below_get(cw->ec);
1879 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1880 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1881 ec = e_client_below_get(ec);
1882 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1884 evas_object_stack_above(obj, ec->frame);
1889 if (ec && (cw->ec->parent == ec))
1891 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1892 evas_object_stack_above(obj, ec->frame);
1894 evas_object_stack_below(obj, ec->frame);
1897 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1903 if (cw->layer == l) return;
1904 if (e_comp_canvas_client_layer_map(layer) == 9999)
1905 return; //invalid layer for clients not doing comp effects
1906 if (cw->ec->fullscreen)
1908 cw->ec->saved.layer = layer;
1911 oldraise = e_config->transient.raise;
1913 /* clamp to valid client layer */
1914 layer = e_comp_canvas_client_layer_map_nearest(layer);
1915 cw->ec->layer = layer;
1916 if (e_config->transient.layer)
1919 Eina_List *list = eina_list_clone(cw->ec->transients);
1921 /* We need to set raise to one, else the child wont
1922 * follow to the new layer. It should be like this,
1923 * even if the user usually doesn't want to raise
1926 e_config->transient.raise = 1;
1927 EINA_LIST_FREE(list, child)
1929 child_cdata = e_client_cdata_get(child);
1930 if (child_cdata && !child_cdata->mapped)
1932 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1935 e_client_layer_set(child, layer);
1939 e_config->transient.raise = oldraise;
1941 _e_comp_object_layers_remove(cw);
1942 cw->layer = e_comp_canvas_layer_map(layer);
1943 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1944 //if (cw->ec->new_client)
1945 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1946 _e_comp_object_layer_set(obj, layer);
1947 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1948 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1949 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1951 /* can't stack a client above its own layer marker */
1952 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1954 if (!cw->visible) return;
1955 e_comp_render_queue();
1956 _e_comp_object_transform_obj_stack_update(obj);
1959 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1962 _e_comp_object_raise(Evas_Object *obj)
1964 evas_object_raise(obj);
1966 if (evas_object_smart_smart_get(obj))
1968 E_Client *ec = e_comp_object_client_get(obj);
1970 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1975 _e_comp_object_lower(Evas_Object *obj)
1977 evas_object_lower(obj);
1979 if (evas_object_smart_smart_get(obj))
1981 E_Client *ec = e_comp_object_client_get(obj);
1983 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1988 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1990 evas_object_stack_above(obj, target);
1992 if (evas_object_smart_smart_get(obj))
1994 E_Client *ec = e_comp_object_client_get(obj);
1996 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2001 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2003 evas_object_stack_below(obj, target);
2005 if (evas_object_smart_smart_get(obj))
2007 E_Client *ec = e_comp_object_client_get(obj);
2009 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2014 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2016 evas_object_layer_set(obj, layer);
2018 if (evas_object_smart_smart_get(obj))
2020 E_Client *ec = e_comp_object_client_get(obj);
2022 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2027 _e_comp_object_is_pending(E_Client *ec)
2031 if (!ec) return EINA_FALSE;
2033 topmost = e_comp_wl_topmost_parent_get(ec);
2035 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2039 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2041 E_Comp_Object *cw2 = NULL;
2044 Evas_Object *o = stack;
2045 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2047 /* We should consider topmost's layer_pending for subsurface */
2048 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2050 if (_e_comp_object_is_pending(cw->ec))
2051 e_comp_object_layer_update(cw->smart_obj,
2052 raising? stack : NULL,
2053 raising? NULL : stack);
2055 /* obey compositor effects! */
2056 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2057 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2058 stack_cb(cw->smart_obj, stack);
2059 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2060 evas_object_data_del(cw->smart_obj, "client_restack");
2064 cw2 = evas_object_data_get(o, "comp_obj");
2066 /* assume someone knew what they were doing during client init */
2067 if (cw->ec->new_client)
2068 layer = cw->ec->layer;
2069 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2070 layer = cw2->ec->layer;
2072 layer = evas_object_layer_get(stack);
2073 ecstack = e_client_below_get(cw->ec);
2074 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2076 /* some FOOL is trying to restack a layer marker */
2077 if (cw->smart_obj == e_comp->layers[cw->layer].obj) return;
2078 evas_object_layer_set(cw->smart_obj, layer);
2079 /* we got our layer wrangled, return now! */
2080 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2083 /* check if we're stacking below another client */
2086 /* check for non-client layer object */
2087 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2089 /* find an existing client to use for layering
2090 * by walking up the object stack
2092 * this is guaranteed to be pretty quick since we'll either:
2093 * - run out of client layers
2094 * - find a stacking client
2096 o = evas_object_above_get(o);
2097 if ((!o) || (o == cw->smart_obj)) break;
2098 if (evas_object_layer_get(o) != layer)
2100 /* reached the top client layer somehow
2101 * use top client object
2103 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2106 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2107 * return here since the top client layer window
2112 ec = e_client_top_get();
2117 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2120 if (cw2 && cw->layer != cw2->layer)
2123 /* remove existing layers */
2124 _e_comp_object_layers_remove(cw);
2127 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2128 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2129 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2130 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2131 else //if no stacking objects found, either raise or lower
2132 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2135 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2137 /* find new object for stacking if cw2 is on state of layer_pending */
2138 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2140 E_Client *new_stack = NULL, *current_ec = NULL;
2141 current_ec = cw2->ec;
2144 while ((new_stack = e_client_below_get(current_ec)))
2146 current_ec = new_stack;
2147 if (new_stack == cw->ec) continue;
2148 if (new_stack->layer != cw2->ec->layer) break;
2149 if (!_e_comp_object_is_pending(new_stack)) break;
2151 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2152 stack = new_stack->frame;
2155 /* stack it above layer object */
2157 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2158 stack = e_comp->layers[below_layer].obj;
2163 while ((new_stack = e_client_above_get(current_ec)))
2165 current_ec = new_stack;
2166 if (new_stack == cw->ec) continue;
2167 if (new_stack->layer != cw2->ec->layer) break;
2168 if (!_e_comp_object_is_pending(new_stack)) break;
2170 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2171 stack = new_stack->frame;
2173 stack = e_comp->layers[cw2->layer].obj;
2177 /* set restack if stacking has changed */
2178 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2179 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2180 stack_cb(cw->smart_obj, stack);
2181 if (e_comp->layers[cw->layer].obj)
2182 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2184 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2186 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2187 evas_object_data_del(cw->smart_obj, "client_restack");
2188 if (!cw->visible) return;
2189 e_comp_render_queue();
2193 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2195 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2197 if (evas_object_below_get(obj) == above)
2199 e_comp_object_layer_update(obj, above, NULL);
2203 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2204 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2205 _e_comp_object_transform_obj_stack_update(obj);
2206 _e_comp_object_transform_obj_stack_update(above);
2211 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2213 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2214 if (evas_object_above_get(obj) == below)
2216 e_comp_object_layer_update(obj, NULL, below);
2220 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2221 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2222 if (evas_object_smart_smart_get(obj))
2223 _e_comp_object_transform_obj_stack_update(obj);
2224 if (evas_object_smart_smart_get(below))
2225 _e_comp_object_transform_obj_stack_update(below);
2230 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2232 E_Comp_Object *cw = data;
2235 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2237 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2239 if (cw->ec->layer_pending)
2240 e_comp_object_layer_update(obj, NULL, obj);
2242 _e_comp_object_lower(obj);
2245 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2246 o = evas_object_below_get(obj);
2247 _e_comp_object_layers_remove(cw);
2248 /* prepend to client list since this client should be the first item now */
2249 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2250 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2251 if (obj == e_comp->layers[cw->layer].obj) goto end; //never lower a layer marker!
2252 evas_object_data_set(obj, "client_restack", (void*)1);
2253 _e_comp_object_lower(obj);
2254 evas_object_data_del(obj, "client_restack");
2255 if (!cw->visible) goto end;
2256 e_comp_render_queue();
2257 _e_comp_object_transform_obj_stack_update(obj);
2260 if (!cw->ec->post_lower)
2261 e_client_focus_stack_lower(cw->ec);
2266 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2268 E_Comp_Object *cw = data;
2271 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2273 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2275 if (cw->ec->layer_pending)
2277 int obj_layer = evas_object_layer_get(obj);
2278 if (cw->ec->layer != obj_layer)
2279 e_comp_object_layer_update(obj, NULL, NULL);
2282 _e_comp_object_raise(obj);
2285 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2286 o = evas_object_above_get(obj);
2288 E_Client *ecabove = e_client_above_get(cw->ec);
2289 if (ecabove && (ecabove->frame == e_comp->layers[cw->layer].obj) &&
2290 (ecabove->frame == o)) goto end; //highest below marker
2292 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2293 if (obj == e_comp->layers[cw->layer].obj) //never raise a non-layer marker!
2294 _e_comp_object_raise(obj);
2299 /* still stack below override below the layer marker */
2300 for (op = o = e_comp->layers[cw->layer].obj;
2301 o && o != e_comp->layers[cw->layer - 1].obj;
2302 op = o, o = evas_object_below_get(o))
2304 if (evas_object_smart_smart_get(o))
2308 ec = e_comp_object_client_get(o);
2309 if (ec && (!ec->override)) break;
2312 _e_comp_object_stack_below(obj, op);
2313 e_client_focus_defer_set(cw->ec);
2315 if (!cw->visible) goto end;
2316 e_comp_render_queue();
2317 _e_comp_object_transform_obj_stack_update(obj);
2324 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2326 E_Comp_Object *cw = data;
2328 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2329 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2331 ELOGF("COMP", "Hide. intercepted", cw->ec);
2336 if (cw->ec->launching == EINA_TRUE)
2338 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2339 cw->ec->launching = EINA_FALSE;
2344 /* hidden flag = just do it */
2345 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2346 evas_object_hide(obj);
2350 if (cw->ec->input_only)
2352 /* input_only = who cares */
2353 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2354 evas_object_hide(obj);
2357 /* already hidden or currently animating */
2358 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2360 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2364 /* don't try hiding during shutdown */
2365 cw->defer_hide |= stopping;
2366 if (!cw->defer_hide)
2368 if ((!cw->ec->iconic) && (!cw->ec->override))
2369 /* unset delete requested so the client doesn't break */
2370 cw->ec->delete_requested = 0;
2371 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2373 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2374 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2377 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2380 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2382 _e_comp_object_animating_begin(cw);
2383 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2385 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2386 cw->defer_hide = !!cw->animating;
2388 e_comp_object_effect_set(obj, NULL);
2391 if (cw->animating) return;
2392 /* if we have no animations running, go ahead and hide */
2394 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2395 evas_object_hide(obj);
2399 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2401 E_Client *ec = cw->ec;
2404 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2406 if (ec->show_pending.count > 0)
2408 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2409 ec->show_pending.running = EINA_TRUE;
2413 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2414 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2416 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2421 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,
2422 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2423 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2426 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2429 if (ec->iconic && cw->animating)
2431 /* triggered during iconify animation */
2432 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2435 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2438 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2439 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2441 evas_object_move(cw->smart_obj, ec->x, ec->y);
2442 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2443 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2445 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2446 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2449 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2450 evas_object_show(cw->smart_obj);
2453 e_client_focus_defer_set(ec);
2457 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2461 pw = ec->client.w, ph = ec->client.h;
2463 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2465 ec->changes.visible = !ec->hidden;
2468 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2472 cw->updates = eina_tiler_new(pw, ph);
2475 ec->changes.visible = !ec->hidden;
2478 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2483 eina_tiler_tile_size_set(cw->updates, 1, 1);
2486 /* ignore until client idler first run */
2487 ec->changes.visible = !ec->hidden;
2490 ELOGF("COMP", "show_helper. return. new_client", ec);
2497 evas_object_move(cw->smart_obj, ec->x, ec->y);
2498 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2499 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2500 evas_object_show(cw->smart_obj);
2503 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2505 /* start_drag not received */
2506 ec->changes.visible = 1;
2509 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2512 /* re-set geometry */
2513 evas_object_move(cw->smart_obj, ec->x, ec->y);
2514 /* force resize in case it hasn't happened yet, or just to update size */
2515 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2516 if ((cw->w < 1) || (cw->h < 1))
2518 /* if resize didn't go through, try again */
2519 ec->visible = ec->changes.visible = 1;
2521 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2524 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2525 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2526 e_pixmap_clear(ec->pixmap);
2528 if (cw->real_hid && w && h)
2531 /* force comp theming in case it didn't happen already */
2532 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2533 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2534 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2537 /* only do the show if show is allowed */
2540 if (ec->internal) //internal clients render when they feel like it
2541 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2543 if (!e_client_is_iconified_by_client(ec)||
2544 e_policy_visibility_client_is_uniconic(ec))
2546 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2547 evas_object_show(cw->smart_obj);
2549 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2550 it is rendered in idle callback without native surface and
2551 compositor shows an empty frame if other objects aren't shown
2552 because job callback of e_comp called at the next loop.
2553 it causes a visual defect when windows are switched.
2557 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2558 e_comp_object_dirty(cw->smart_obj);
2559 e_comp_object_render(cw->smart_obj);
2563 e_policy_visibility_client_is_uniconic(ec))
2565 if (ec->exp_iconify.not_raise &&
2566 e_client_check_above_focused(ec))
2567 e_client_focus_stack_append_current_focused(ec);
2569 e_client_focus_defer_set(ec);
2576 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2578 E_Comp_Object *cw = data;
2579 E_Client *ec = cw->ec;
2581 E_Input_Rect_Data *input_rect_data;
2582 E_Input_Rect_Smart_Data *input_rect_sd;
2585 if (ec->ignored) return;
2589 //INF("SHOW2 %p", ec);
2590 _e_comp_intercept_show_helper(cw);
2593 //INF("SHOW %p", ec);
2596 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2597 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2598 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2599 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2603 if ((!cw->obj) && (cw->external_content))
2605 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2609 _e_comp_object_setup(cw);
2612 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2613 cw->obj = evas_object_image_filled_add(e_comp->evas);
2614 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2615 e_util_size_debug_set(cw->obj, 1);
2616 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2617 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2618 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2619 evas_object_name_set(cw->obj, "cw->obj");
2620 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2622 _e_comp_object_alpha_set(cw);
2625 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2628 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2629 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2632 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2635 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2637 if (input_rect_data->obj)
2639 evas_object_geometry_set(input_rect_data->obj,
2640 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2641 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2642 input_rect_data->rect.w, input_rect_data->rect.h);
2649 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2651 _e_comp_intercept_show_helper(cw);
2655 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2657 E_Comp_Object *cw = data;
2661 /* note: this is here as it seems there are enough apps that do not even
2662 * expect us to emulate a look of focus but not actually set x input
2663 * focus as we do - so simply abort any focus set on such windows */
2664 /* be strict about accepting focus hint */
2665 /* be strict about accepting focus hint */
2666 if ((!ec->icccm.accepts_focus) &&
2667 (!ec->icccm.take_focus))
2671 if (e_client_focused_get() == ec)
2672 e_client_focused_set(NULL);
2674 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2675 evas_object_focus_set(obj, focus);
2679 if (focus && ec->lock_focus_out) return;
2680 if (e_object_is_del(E_OBJECT(ec)) && focus)
2681 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2683 /* filter focus setting based on current state */
2688 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2689 evas_object_focus_set(obj, focus);
2692 if ((ec->iconic) && (!ec->deskshow))
2694 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2696 /* don't focus an iconified window. that's silly! */
2697 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2698 e_client_uniconify(ec);
2699 if (e_client_focus_track_enabled())
2700 e_client_focus_latest_set(ec);
2708 if ((!ec->sticky) && (ec->desk) && (!ec->desk->visible))
2710 if (ec->desk->animate_count) return;
2711 e_desk_show(ec->desk);
2712 if (!ec->desk->visible) return;
2720 /* not yet visible, wait till the next time... */
2721 ec->want_focus = !ec->hidden;
2726 e_client_focused_set(ec);
2730 if (e_client_focused_get() == ec)
2731 e_client_focused_set(NULL);
2735 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2737 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2739 evas_object_focus_set(obj, focus);
2743 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2745 E_Comp_Object *cw = data;
2747 if (cw->transparent.set)
2749 cw->transparent.user_r = r;
2750 cw->transparent.user_g = g;
2751 cw->transparent.user_b = b;
2752 cw->transparent.user_a = a;
2754 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2756 cw->transparent.user_r,
2757 cw->transparent.user_g,
2758 cw->transparent.user_b,
2759 cw->transparent.user_a);
2763 evas_object_color_set(obj, r, g, b, a);
2766 ////////////////////////////////////////////////////
2769 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2771 int w, h, ox, oy, ow, oh;
2773 Eina_Bool pass_event_flag = EINA_FALSE;
2774 E_Input_Rect_Data *input_rect_data;
2775 E_Input_Rect_Smart_Data *input_rect_sd;
2777 if (cw->frame_object)
2779 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2780 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2781 /* set a fixed size, force edje calc, check size difference */
2782 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2783 edje_object_message_signal_process(cw->frame_object);
2784 edje_object_calc_force(cw->frame_object);
2785 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2786 cw->client_inset.l = ox;
2787 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2788 cw->client_inset.t = oy;
2789 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2790 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2791 evas_object_resize(cw->frame_object, w, h);
2795 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2798 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2800 if (input_rect_data->obj)
2802 pass_event_flag = EINA_TRUE;
2808 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2809 evas_object_pass_events_set(cw->obj, pass_event_flag);
2813 cw->client_inset.l = 0;
2814 cw->client_inset.r = 0;
2815 cw->client_inset.t = 0;
2816 cw->client_inset.b = 0;
2818 cw->client_inset.calc = !!cw->frame_object;
2822 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2824 E_Comp_Object *cw = data;
2828 /* - get current size
2830 * - readjust for new frame size
2833 w = cw->ec->w, h = cw->ec->h;
2834 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2836 _e_comp_object_frame_recalc(cw);
2838 if (!cw->ec->fullscreen)
2839 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2841 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2842 if (cw->ec->shading || cw->ec->shaded) return;
2843 if (cw->ec->fullscreen)
2845 zone = e_comp_zone_find_by_ec(cw->ec);
2847 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2849 else if (cw->ec->new_client)
2851 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2852 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2853 evas_object_resize(cw->ec->frame, w, h);
2855 else if ((w != cw->ec->w) || (h != cw->ec->h))
2856 evas_object_resize(cw->ec->frame, w, h);
2860 _e_comp_smart_cb_shading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2862 E_Comp_Object *cw = data;
2864 if (!cw->ec) return; //NYI
2865 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2867 cw->shade.x = cw->x;
2868 cw->shade.y = cw->y;
2869 e_comp_object_signal_emit(cw->smart_obj, "e,state,shading", "e");
2873 _e_comp_smart_cb_shaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2875 E_Comp_Object *cw = data;
2877 if (!cw->ec) return; //NYI
2878 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2880 e_comp_object_signal_emit(cw->smart_obj, "e,state,shaded", "e");
2884 _e_comp_smart_cb_unshading(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2886 E_Comp_Object *cw = data;
2888 if (!cw->ec) return; //NYI
2889 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2891 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshading", "e");
2895 _e_comp_smart_cb_unshaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
2897 E_Comp_Object *cw = data;
2899 if (!cw->ec) return; //NYI
2900 E_FREE_FUNC(cw->shade.anim, ecore_timer_del);
2902 e_comp_object_signal_emit(cw->smart_obj, "e,state,unshaded", "e");
2906 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2908 E_Comp_Object *cw = data;
2910 _e_comp_object_shadow_setup(cw);
2911 if (cw->frame_object)
2913 _e_comp_object_shadow(cw);
2914 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2915 _e_comp_object_frame_recalc(cw);
2916 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2921 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2923 E_Comp_Object *cw = data;
2925 if (_e_comp_object_shadow_setup(cw))
2926 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2927 if (cw->frame_object)
2929 _e_comp_object_shadow(cw);
2930 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2931 _e_comp_object_frame_recalc(cw);
2932 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2937 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2939 E_Comp_Object *cw = data;
2941 if (cw->frame_object)
2943 _e_comp_object_shadow(cw);
2944 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2945 _e_comp_object_frame_recalc(cw);
2946 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2951 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2953 E_Comp_Object *cw = data;
2955 if (_e_comp_object_shadow_setup(cw))
2958 cw->ec->changes.size = 1;
2960 if (cw->frame_object)
2962 _e_comp_object_shadow(cw);
2963 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2964 _e_comp_object_frame_recalc(cw);
2965 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2970 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2972 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2976 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2978 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2982 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2984 E_Comp_Object *cw = data;
2986 if (!cw->ec) return; //NYI
2987 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2991 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2993 E_Comp_Object *cw = data;
2995 if (!cw->ec) return; //NYI
2996 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
3000 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3002 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3006 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3008 E_Comp_Object *cw = data;
3010 if (!e_object_is_del(E_OBJECT(cw->ec)))
3011 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3015 _e_comp_input_obj_smart_add(Evas_Object *obj)
3017 E_Input_Rect_Smart_Data *input_rect_sd;
3018 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3020 if (!input_rect_sd) return;
3021 evas_object_smart_data_set(obj, input_rect_sd);
3025 _e_comp_input_obj_smart_del(Evas_Object *obj)
3027 E_Input_Rect_Smart_Data *input_rect_sd;
3028 E_Input_Rect_Data *input_rect_data;
3030 input_rect_sd = evas_object_smart_data_get(obj);
3031 if (!input_rect_sd) return;
3033 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3035 if (input_rect_data->obj)
3037 evas_object_smart_member_del(input_rect_data->obj);
3038 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3040 E_FREE(input_rect_data);
3042 E_FREE(input_rect_sd);
3046 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3048 E_Input_Rect_Smart_Data *input_rect_sd;
3049 E_Input_Rect_Data *input_rect_data;
3053 input_rect_sd = evas_object_smart_data_get(obj);
3054 if (!input_rect_sd) return;
3056 cw = input_rect_sd->cw;
3057 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3059 if (input_rect_data->obj)
3061 evas_object_geometry_set(input_rect_data->obj,
3062 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3063 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3064 input_rect_data->rect.w, input_rect_data->rect.h);
3070 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3072 E_Input_Rect_Smart_Data *input_rect_sd;
3073 E_Input_Rect_Data *input_rect_data;
3077 input_rect_sd = evas_object_smart_data_get(obj);
3078 if (!input_rect_sd) return;
3080 cw = input_rect_sd->cw;
3081 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3083 if (input_rect_data->obj)
3085 evas_object_geometry_set(input_rect_data->obj,
3086 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3087 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3088 input_rect_data->rect.w, input_rect_data->rect.h);
3094 _e_comp_input_obj_smart_show(Evas_Object *obj)
3096 E_Input_Rect_Smart_Data *input_rect_sd;
3097 E_Input_Rect_Data *input_rect_data;
3100 input_rect_sd = evas_object_smart_data_get(obj);
3101 if (!input_rect_sd) return;
3103 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3105 if (input_rect_data->obj)
3107 evas_object_show(input_rect_data->obj);
3113 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3115 E_Input_Rect_Smart_Data *input_rect_sd;
3116 E_Input_Rect_Data *input_rect_data;
3119 input_rect_sd = evas_object_smart_data_get(obj);
3120 if (!input_rect_sd) return;
3122 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3124 if (input_rect_data->obj)
3126 evas_object_hide(input_rect_data->obj);
3132 _e_comp_input_obj_smart_init(void)
3134 if (_e_comp_input_obj_smart) return;
3136 static const Evas_Smart_Class sc =
3138 INPUT_OBJ_SMART_NAME,
3139 EVAS_SMART_CLASS_VERSION,
3140 _e_comp_input_obj_smart_add,
3141 _e_comp_input_obj_smart_del,
3142 _e_comp_input_obj_smart_move,
3143 _e_comp_input_obj_smart_resize,
3144 _e_comp_input_obj_smart_show,
3145 _e_comp_input_obj_smart_hide,
3158 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3164 _e_comp_smart_add(Evas_Object *obj)
3168 cw = E_NEW(E_Comp_Object, 1);
3169 EINA_SAFETY_ON_NULL_RETURN(cw);
3171 cw->smart_obj = obj;
3172 cw->x = cw->y = cw->w = cw->h = -1;
3173 evas_object_smart_data_set(obj, cw);
3174 cw->opacity = 255.0;
3175 cw->external_content = 0;
3176 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3177 cw->transform_bg_color.r = 0;
3178 cw->transform_bg_color.g = 0;
3179 cw->transform_bg_color.b = 0;
3180 cw->transform_bg_color.a = 255;
3181 evas_object_data_set(obj, "comp_obj", cw);
3182 evas_object_move(obj, -1, -1);
3183 /* intercept ALL the callbacks! */
3184 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3185 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3186 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3187 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3188 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3189 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3190 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3191 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3192 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3193 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3194 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3196 evas_object_smart_callback_add(obj, "shading", _e_comp_smart_cb_shading, cw);
3197 evas_object_smart_callback_add(obj, "shaded", _e_comp_smart_cb_shaded, cw);
3198 evas_object_smart_callback_add(obj, "unshading", _e_comp_smart_cb_unshading, cw);
3199 evas_object_smart_callback_add(obj, "unshaded", _e_comp_smart_cb_unshaded, cw);
3201 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3202 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3203 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3204 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3206 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3207 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3209 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3210 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3212 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3214 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3215 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3219 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3222 evas_object_color_set(cw->clip, r, g, b, a);
3223 evas_object_smart_callback_call(obj, "color_set", NULL);
3228 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3231 evas_object_clip_set(cw->clip, clip);
3235 _e_comp_smart_clip_unset(Evas_Object *obj)
3238 evas_object_clip_unset(cw->clip);
3242 _e_comp_smart_hide(Evas_Object *obj)
3244 TRACE_DS_BEGIN(COMP:SMART HIDE);
3249 evas_object_hide(cw->clip);
3250 if (cw->input_obj) evas_object_hide(cw->input_obj);
3251 evas_object_hide(cw->effect_obj);
3252 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3253 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3254 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3261 /* unset native surface if current displaying buffer was destroied */
3262 if (!cw->buffer_destroy_listener.notify)
3264 Evas_Native_Surface *ns;
3265 ns = evas_object_image_native_surface_get(cw->obj);
3266 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3267 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3270 if (!cw->ec->input_only)
3272 edje_object_freeze(cw->effect_obj);
3273 edje_object_freeze(cw->shobj);
3274 edje_object_play_set(cw->shobj, 0);
3275 if (cw->frame_object)
3276 edje_object_play_set(cw->frame_object, 0);
3278 /* ensure focus-out */
3279 if (cw->ec->focused &&
3280 (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK))
3282 ELOGF("FOCUS", "focus unset | smart_hide", cw->ec);
3283 e_client_frame_focus_set(cw->ec, EINA_FALSE);
3284 e_client_focus_defer_unset(cw->ec);
3286 e_comp_render_queue(); //force nocomp recheck
3292 _e_comp_smart_show(Evas_Object *obj)
3300 if ((cw->w < 0) || (cw->h < 0))
3301 CRI("ACK! ec:%p", cw->ec);
3303 TRACE_DS_BEGIN(COMP:SMART SHOW);
3305 e_comp_object_map_update(obj);
3307 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3308 evas_object_show(tmp->frame);
3310 evas_object_show(cw->clip);
3311 if (cw->input_obj) evas_object_show(cw->input_obj);
3312 if (!cw->ec->input_only)
3314 edje_object_thaw(cw->effect_obj);
3315 edje_object_thaw(cw->shobj);
3316 edje_object_play_set(cw->shobj, 1);
3317 if (cw->frame_object)
3318 edje_object_play_set(cw->frame_object, 1);
3320 evas_object_show(cw->effect_obj);
3321 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3322 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3323 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3324 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3325 e_comp_render_queue();
3326 if (cw->ec->input_only)
3331 if (cw->ec->iconic && (!cw->ec->new_client))
3333 if (e_client_is_iconified_by_client(cw->ec))
3335 ELOGF("COMP", "Set launching flag..", cw->ec);
3336 cw->ec->launching = EINA_TRUE;
3339 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3341 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3344 ELOGF("COMP", "Set launching flag..", cw->ec);
3345 cw->ec->launching = EINA_TRUE;
3347 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3348 _e_comp_object_animating_begin(cw);
3349 if (!_e_comp_object_effect_visibility_start(cw, 1))
3355 /* ensure some random effect doesn't lock the client offscreen */
3359 e_comp_object_effect_set(obj, NULL);
3362 _e_comp_object_dim_update(cw);
3368 _e_comp_smart_del(Evas_Object *obj)
3374 if (cw->buffer_destroy_listener.notify)
3376 wl_list_remove(&cw->buffer_destroy_listener.link);
3377 cw->buffer_destroy_listener.notify = NULL;
3380 if (cw->tbm_surface)
3382 tbm_surface_internal_unref(cw->tbm_surface);
3383 cw->tbm_surface = NULL;
3386 if (cw->render_update_lock.buffer_ref.buffer)
3388 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3389 cw->ec, cw->render_update_lock.lock);
3390 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3393 e_comp_object_render_update_del(cw->smart_obj);
3394 E_FREE_FUNC(cw->updates, eina_tiler_free);
3395 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3402 EINA_LIST_FREE(cw->obj_mirror, o)
3404 evas_object_image_data_set(o, NULL);
3405 evas_object_freeze_events_set(o, 1);
3406 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3410 _e_comp_object_layers_remove(cw);
3411 l = evas_object_data_get(obj, "comp_object-to_del");
3412 E_FREE_LIST(l, evas_object_del);
3413 _e_comp_object_mouse_event_callback_unset(cw);
3414 evas_object_del(cw->clip);
3415 evas_object_del(cw->effect_obj);
3416 evas_object_del(cw->shobj);
3417 evas_object_del(cw->frame_object);
3418 evas_object_del(cw->input_obj);
3419 evas_object_del(cw->obj);
3420 evas_object_del(cw->mask.obj);
3421 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3422 evas_object_del(cw->transform_bg_obj);
3423 evas_object_del(cw->transform_tranp_obj);
3424 evas_object_del(cw->default_input_obj);
3425 eina_stringshare_del(cw->frame_theme);
3426 eina_stringshare_del(cw->frame_name);
3430 e_comp->animating--;
3432 e_object_unref(E_OBJECT(cw->ec));
3434 cw->ec->frame = NULL;
3439 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3443 cw->x = x, cw->y = y;
3444 evas_object_move(cw->effect_obj, x, y);
3445 evas_object_move(cw->default_input_obj, x, y);
3446 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3448 e_comp_object_map_update(obj);
3452 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3454 Eina_Bool first = EINA_FALSE;
3459 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3461 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3463 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3465 if (cw->w != w || cw->h != h)
3466 e_comp_object_map_update(obj);
3468 first = ((cw->w < 1) || (cw->h < 1));
3469 cw->w = w, cw->h = h;
3470 if ((!cw->ec->shading) && (!cw->ec->shaded))
3474 if (cw->frame_object)
3475 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3478 /* verify pixmap:object size */
3479 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3481 if ((ww != pw) || (hh != ph))
3482 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3484 evas_object_resize(cw->effect_obj, tw, th);
3485 evas_object_resize(cw->default_input_obj, w, h);
3487 evas_object_resize(cw->input_obj, w, h);
3489 evas_object_resize(cw->mask.obj, w, h);
3490 /* resize render update tiler */
3493 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3494 cw->updates_full = 0;
3495 if (cw->updates) eina_tiler_clear(cw->updates);
3499 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3500 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3505 evas_object_resize(cw->effect_obj, tw, th);
3506 evas_object_resize(cw->default_input_obj, w, h);
3513 e_comp_render_queue();
3519 _e_comp_smart_init(void)
3521 if (_e_comp_smart) return;
3523 static const Evas_Smart_Class sc =
3526 EVAS_SMART_CLASS_VERSION,
3530 _e_comp_smart_resize,
3533 _e_comp_smart_color_set,
3534 _e_comp_smart_clip_set,
3535 _e_comp_smart_clip_unset,
3545 _e_comp_smart = evas_smart_class_new(&sc);
3550 e_comp_object_init(void)
3552 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3553 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3554 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3555 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3559 e_comp_object_shutdown(void)
3565 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3567 API_ENTRY EINA_FALSE;
3568 return !!cw->force_visible;
3570 /////////////////////////////////////////////////////////
3573 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3576 Eina_Bool comp_object;
3578 comp_object = !!evas_object_data_get(obj, "comp_object");
3583 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3585 e_comp_render_queue();
3587 l = evas_object_data_get(obj, "comp_object-to_del");
3588 E_FREE_LIST(l, evas_object_del);
3592 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3594 if (e_comp_util_object_is_above_nocomp(obj) &&
3595 (!evas_object_data_get(obj, "comp_override")))
3597 evas_object_data_set(obj, "comp_override", (void*)1);
3598 e_comp_override_add();
3603 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3605 Eina_Bool ref = EINA_TRUE;
3606 if (evas_object_visible_get(obj))
3610 d = evas_object_data_del(obj, "comp_hiding");
3612 /* currently trying to hide */
3615 /* already visible */
3619 evas_object_show(obj);
3622 evas_object_ref(obj);
3623 evas_object_data_set(obj, "comp_ref", (void*)1);
3625 edje_object_signal_emit(obj, "e,state,visible", "e");
3626 evas_object_data_set(obj, "comp_showing", (void*)1);
3627 if (e_comp_util_object_is_above_nocomp(obj))
3629 evas_object_data_set(obj, "comp_override", (void*)1);
3630 e_comp_override_add();
3635 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3637 if (!evas_object_visible_get(obj)) return;
3638 /* already hiding */
3639 if (evas_object_data_get(obj, "comp_hiding")) return;
3640 if (!evas_object_data_del(obj, "comp_showing"))
3642 evas_object_ref(obj);
3643 evas_object_data_set(obj, "comp_ref", (void*)1);
3645 edje_object_signal_emit(obj, "e,state,hidden", "e");
3646 evas_object_data_set(obj, "comp_hiding", (void*)1);
3648 if (evas_object_data_del(obj, "comp_override"))
3649 e_comp_override_timed_pop();
3653 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3655 if (!e_util_strcmp(emission, "e,action,hide,done"))
3657 if (!evas_object_data_del(obj, "comp_hiding")) return;
3658 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3659 evas_object_hide(obj);
3660 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3663 evas_object_data_del(obj, "comp_showing");
3664 if (evas_object_data_del(obj, "comp_ref"))
3665 evas_object_unref(obj);
3669 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3675 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3679 E_API E_Comp_Object_Hook *
3680 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3682 E_Comp_Object_Hook *ch;
3684 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3685 ch = E_NEW(E_Comp_Object_Hook, 1);
3686 if (!ch) return NULL;
3687 ch->hookpoint = hookpoint;
3689 ch->data = (void*)data;
3690 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3695 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3698 if (_e_comp_object_hooks_walking == 0)
3700 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3704 _e_comp_object_hooks_delete++;
3707 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3708 E_API E_Comp_Object_Intercept_Hook *
3709 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3711 E_Comp_Object_Intercept_Hook *ch;
3713 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3714 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3715 if (!ch) return NULL;
3716 ch->hookpoint = hookpoint;
3718 ch->data = (void*)data;
3719 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3724 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3727 if (_e_comp_object_intercept_hooks_walking == 0)
3729 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3733 _e_comp_object_intercept_hooks_delete++;
3738 e_comp_object_util_add(Evas_Object *obj)
3742 E_Comp_Config *conf = e_comp_config_get();
3743 Eina_Bool skip = EINA_FALSE;
3749 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3751 name = evas_object_name_get(obj);
3752 vis = evas_object_visible_get(obj);
3753 o = edje_object_add(e_comp->evas);
3754 evas_object_data_set(o, "comp_object", (void*)1);
3756 skip = (!strncmp(name, "noshadow", 8));
3758 evas_object_data_set(o, "comp_object_skip", (void*)1);
3760 if (conf->shadow_style)
3762 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3763 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3766 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3767 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3768 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3770 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3772 evas_object_geometry_get(obj, &x, &y, &w, &h);
3773 evas_object_geometry_set(o, x, y, w, h);
3774 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3776 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3778 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3779 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3780 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3781 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3782 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3783 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3785 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3787 edje_object_part_swallow(o, "e.swallow.content", obj);
3789 _e_comp_object_event_add(o);
3792 evas_object_show(o);
3797 /* utility functions for deleting objects when their "owner" is deleted */
3799 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3804 EINA_SAFETY_ON_NULL_RETURN(to_del);
3805 l = evas_object_data_get(obj, "comp_object-to_del");
3806 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3807 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3808 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3812 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3817 EINA_SAFETY_ON_NULL_RETURN(to_del);
3818 l = evas_object_data_get(obj, "comp_object-to_del");
3820 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3823 /////////////////////////////////////////////////////////
3825 EINTERN Evas_Object *
3826 e_comp_object_client_add(E_Client *ec)
3831 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3832 if (ec->frame) return NULL;
3833 _e_comp_smart_init();
3834 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3835 cw = evas_object_smart_data_get(o);
3836 if (!cw) return NULL;
3837 evas_object_data_set(o, "E_Client", ec);
3840 evas_object_data_set(o, "comp_object", (void*)1);
3842 _e_comp_object_event_add(o);
3847 /* utility functions for getting client inset */
3849 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3852 if (!cw->client_inset.calc)
3858 if (ax) *ax = x - cw->client_inset.l;
3859 if (ay) *ay = y - cw->client_inset.t;
3863 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3866 if (!cw->client_inset.calc)
3872 if (ax) *ax = x + cw->client_inset.l;
3873 if (ay) *ay = y + cw->client_inset.t;
3877 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3880 if (!cw->client_inset.calc)
3886 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3887 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3891 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3894 if (!cw->client_inset.calc)
3900 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3901 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3905 e_comp_object_client_get(Evas_Object *obj)
3910 /* FIXME: remove this when eo is used */
3911 o = evas_object_data_get(obj, "comp_smart_obj");
3913 return e_comp_object_client_get(o);
3914 return cw ? cw->ec : NULL;
3918 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3921 if (cw->frame_extends)
3922 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3927 if (w) *w = cw->ec->w;
3928 if (h) *h = cw->ec->h;
3933 e_comp_object_util_zone_get(Evas_Object *obj)
3935 E_Zone *zone = NULL;
3939 zone = e_comp_zone_find_by_ec(cw->ec);
3944 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3945 zone = e_comp_zone_xy_get(x, y);
3951 e_comp_object_util_center(Evas_Object *obj)
3953 int x, y, w, h, ow, oh;
3958 zone = e_comp_object_util_zone_get(obj);
3959 EINA_SAFETY_ON_NULL_RETURN(zone);
3960 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3961 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3962 ow = cw->ec->w, oh = cw->ec->h;
3964 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3965 x = x + (w - ow) / 2;
3966 y = y + (h - oh) / 2;
3967 evas_object_move(obj, x, y);
3971 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3973 int x, y, w, h, ow, oh;
3976 EINA_SAFETY_ON_NULL_RETURN(on);
3977 evas_object_geometry_get(on, &x, &y, &w, &h);
3978 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3979 ow = cw->ec->w, oh = cw->ec->h;
3981 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3982 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3986 e_comp_object_util_fullscreen(Evas_Object *obj)
3991 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3994 evas_object_move(obj, 0, 0);
3995 evas_object_resize(obj, e_comp->w, e_comp->h);
4000 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4008 ow = cw->w, oh = cw->h;
4010 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4011 zone = e_comp_object_util_zone_get(obj);
4012 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4013 if (x) *x = zx + (zw - ow) / 2;
4014 if (y) *y = zy + (zh - oh) / 2;
4018 e_comp_object_input_objs_del(Evas_Object *obj)
4021 E_Input_Rect_Data *input_rect_data;
4022 E_Input_Rect_Smart_Data *input_rect_sd;
4027 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4028 if (!input_rect_sd) return;
4030 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4032 if (input_rect_data->obj)
4034 evas_object_smart_member_del(input_rect_data->obj);
4035 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4037 E_FREE(input_rect_data);
4042 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4045 E_Input_Rect_Data *input_rect_data = NULL;
4046 E_Input_Rect_Smart_Data *input_rect_sd;
4047 int client_w, client_h;
4049 if (cw->ec->client.w)
4050 client_w = cw->ec->client.w;
4052 client_w = cw->ec->w;
4054 if (cw->ec->client.h)
4055 client_h = cw->ec->client.h;
4057 client_h = cw->ec->h;
4059 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4063 _e_comp_input_obj_smart_init();
4064 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4065 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4066 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4069 input_rect_sd->cw = cw;
4072 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4075 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4076 if (input_rect_data)
4078 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4079 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4083 if ((input_rect_data) &&
4084 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4086 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4087 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4088 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4089 evas_object_clip_set(input_rect_data->obj, cw->clip);
4090 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4091 evas_object_geometry_set(input_rect_data->obj,
4092 MAX(cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l), 0) + x,
4093 MAX(cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t), 0) + y, w, h);
4094 evas_object_pass_events_set(cw->default_input_obj, 1);
4095 evas_object_pass_events_set(cw->obj, 1);
4098 evas_object_show(input_rect_data->obj);
4099 evas_object_show(cw->input_obj);
4104 evas_object_smart_member_del(cw->input_obj);
4105 E_FREE_FUNC(cw->input_obj, evas_object_del);
4106 evas_object_pass_events_set(cw->default_input_obj, 0);
4107 evas_object_pass_events_set(cw->obj, 0);
4112 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4115 E_Input_Rect_Smart_Data *input_rect_sd;
4116 E_Input_Rect_Data *input_rect_data;
4119 if (!cw->input_obj) return;
4121 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4124 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4126 *list = eina_list_append(*list, &input_rect_data->rect);
4132 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4135 if (l) *l = cw->client_inset.l;
4136 if (r) *r = cw->client_inset.r;
4137 if (t) *t = cw->client_inset.t;
4138 if (b) *b = cw->client_inset.b;
4141 /* set geometry for CSD */
4143 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4149 if (cw->frame_object)
4150 CRI("ACK! ec:%p", cw->ec);
4151 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4152 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4153 calc = cw->client_inset.calc;
4154 cw->client_inset.calc = l || r || t || b;
4155 eina_stringshare_replace(&cw->frame_theme, "borderless");
4156 if (cw->client_inset.calc)
4158 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4159 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4160 e_client_size_set(cw->ec, tw, th);
4162 else if (cw->ec->maximized || cw->ec->fullscreen)
4164 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4165 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4167 if (!cw->ec->new_client)
4169 if (calc && cw->client_inset.calc)
4171 tx = cw->ec->x - (l - cw->client_inset.l);
4172 ty = cw->ec->y - (t - cw->client_inset.t);
4173 e_client_pos_set(cw->ec, tx, ty);
4175 cw->ec->changes.pos = cw->ec->changes.size = 1;
4178 cw->client_inset.l = l;
4179 cw->client_inset.r = r;
4180 cw->client_inset.t = t;
4181 cw->client_inset.b = b;
4185 e_comp_object_frame_allowed(Evas_Object *obj)
4187 API_ENTRY EINA_FALSE;
4188 return (!cw->ec->mwm.borderless) && (cw->frame_object || (!cw->client_inset.calc));
4192 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4194 API_ENTRY EINA_FALSE;
4195 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4196 eina_stringshare_replace(&cw->frame_name, name);
4197 if (cw->frame_object)
4198 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4203 e_comp_object_frame_exists(Evas_Object *obj)
4205 API_ENTRY EINA_FALSE;
4206 return !!cw->frame_object;
4210 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4212 Evas_Object *o, *pbg;
4215 Eina_Stringshare *theme;
4217 API_ENTRY EINA_FALSE;
4219 if (!e_util_strcmp(cw->frame_theme, name))
4220 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4221 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4222 return _e_comp_object_shadow_setup(cw);
4223 pbg = cw->frame_object;
4224 theme = eina_stringshare_add(name);
4226 if (cw->frame_object)
4230 w = cw->ec->w, h = cw->ec->h;
4231 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4232 if ((cw->ec->w != w) || (cw->ec->h != h))
4234 cw->ec->changes.size = 1;
4237 E_FREE_FUNC(cw->frame_object, evas_object_del);
4238 if (!name) goto reshadow;
4240 o = edje_object_add(e_comp->evas);
4241 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4242 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4243 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4245 cw->frame_object = NULL;
4247 eina_stringshare_del(cw->frame_theme);
4248 cw->frame_theme = theme;
4253 if (theme != e_config->theme_default_border_style)
4255 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4256 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4260 ok = e_theme_edje_object_set(o, "base/theme/border",
4261 "e/widgets/border/default/border");
4262 if (ok && (theme == e_config->theme_default_border_style))
4264 /* Reset default border style to default */
4265 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4266 e_config_save_queue();
4273 cw->frame_object = o;
4274 eina_stringshare_del(cw->frame_theme);
4275 cw->frame_theme = theme;
4276 evas_object_name_set(o, "cw->frame_object");
4279 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4283 cw->ec->changes.icon = 1;
4289 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4294 _e_comp_object_shadow_setup(cw);
4297 int old_x, old_y, new_x = 0, new_y = 0;
4299 old_x = cw->x, old_y = cw->y;
4301 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4303 new_x = cw->ec->x, new_y = cw->ec->y;
4304 else if (cw->ec->placed || (!cw->ec->new_client))
4306 /* if no previous frame:
4307 * - reapply client_inset
4312 if (cw->ec->changes.size)
4320 zone = e_comp_zone_find_by_ec(cw->ec);
4323 x = cw->ec->client.x, y = cw->ec->client.y;
4324 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4325 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4327 new_x = x, new_y = y;
4330 if (old_x != new_x || old_y != new_y)
4332 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4333 cw->y = cw->x = -99999;
4334 evas_object_move(obj, new_x, new_y);
4338 if (cw->ec->maximized)
4340 cw->ec->changes.need_maximize = 1;
4343 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4344 if (cw->frame_object)
4346 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4349 cw->frame_extends = 0;
4350 evas_object_del(pbg);
4355 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4357 E_Comp_Object_Mover *prov;
4360 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4361 edje_object_signal_emit(cw->shobj, sig, src);
4362 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4363 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4364 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4366 /* start with highest priority callback first */
4367 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4369 if (!e_util_glob_match(sig, prov->sig)) continue;
4370 if (prov->func(prov->data, obj, sig)) break;
4375 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4377 /* FIXME: at some point I guess this should use eo to inherit
4378 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4379 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4382 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4386 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4389 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4393 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4396 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4400 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4403 Eina_Rectangle rect;
4406 if (cw->ec->input_only || (!cw->updates)) return;
4407 if (cw->nocomp) return;
4408 rect.x = x, rect.y = y;
4409 rect.w = w, rect.h = h;
4410 evas_object_smart_callback_call(obj, "damage", &rect);
4412 if (e_comp_is_on_overlay(cw->ec))
4414 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4415 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4416 * E module attempts to block screen update due to the particular policy.
4418 if (e_pixmap_resource_get(cw->ec->pixmap))
4419 cw->hwc_need_update = EINA_TRUE;
4422 /* ignore overdraw */
4423 if (cw->updates_full)
4425 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4426 e_comp_object_render_update_add(obj);
4428 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4429 evas_object_show(cw->smart_obj);
4433 /* clip rect to client surface */
4434 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4435 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4436 /* if rect is the total size of the client after clip, clear the updates
4437 * since this is guaranteed to be the whole region anyway
4439 eina_tiler_area_size_get(cw->updates, &tw, &th);
4440 if ((w > tw) || (h > th))
4442 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4443 eina_tiler_clear(cw->updates);
4444 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4446 tw = cw->ec->client.w, th = cw->ec->client.h;
4448 if ((!x) && (!y) && (w == tw) && (h == th))
4450 eina_tiler_clear(cw->updates);
4451 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4452 cw->updates_full = 1;
4453 cw->update_count = 0;
4456 if (cw->update_count > UPDATE_MAX)
4458 /* this is going to get really dumb, so just update the whole thing */
4459 eina_tiler_clear(cw->updates);
4460 cw->update_count = cw->updates_full = 1;
4461 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4462 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4466 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4467 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4469 cw->updates_exist = 1;
4470 e_comp_object_render_update_add(obj);
4472 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4473 evas_object_show(cw->smart_obj);
4477 e_comp_object_damage_exists(Evas_Object *obj)
4479 API_ENTRY EINA_FALSE;
4480 return cw->updates_exist;
4484 e_comp_object_render_update_add(Evas_Object *obj)
4488 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4489 if (cw->render_update_lock.lock) return;
4490 if (e_object_is_del(E_OBJECT(cw->ec)))
4491 CRI("CAN'T RENDER A DELETED CLIENT!!! ec:%p", cw->ec);
4492 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4496 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4498 e_comp_render_queue();
4502 e_comp_object_render_update_del(Evas_Object *obj)
4506 if (cw->ec->input_only || (!cw->updates)) return;
4507 if (!cw->update) return;
4509 /* this gets called during comp animating to clear the update flag */
4510 if (e_comp->grabbed) return;
4511 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4512 if (!e_comp->updates)
4514 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4515 if (e_comp->render_animator)
4516 ecore_animator_freeze(e_comp->render_animator);
4521 e_comp_object_shape_apply(Evas_Object *obj)
4525 unsigned int i, *pix, *p;
4529 if (!cw->ec) return; //NYI
4530 if (cw->external_content) return;
4533 if ((cw->ec->shape_rects_num >= 1) &&
4534 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4539 ERR("BUGGER: shape with native surface? cw=%p", cw);
4542 evas_object_image_size_get(cw->obj, &w, &h);
4543 if ((w < 1) || (h < 1)) return;
4546 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4547 _e_comp_object_alpha_set(cw);
4548 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4549 evas_object_image_alpha_set(o, 1);
4551 p = pix = evas_object_image_data_get(cw->obj, 1);
4554 evas_object_image_data_set(cw->obj, pix);
4559 unsigned char *spix, *sp;
4561 spix = calloc(w * h, sizeof(unsigned char));
4563 for (i = 0; i < cw->ec->shape_rects_num; i++)
4567 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4568 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4569 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4570 sp = spix + (w * ry) + rx;
4571 for (py = 0; py < rh; py++)
4573 for (px = 0; px < rw; px++)
4581 for (py = 0; py < h; py++)
4583 for (px = 0; px < w; px++)
4585 unsigned int mask, imask;
4587 mask = ((unsigned int)(*sp)) << 24;
4589 imask |= imask >> 8;
4590 imask |= imask >> 8;
4591 *p = mask | (*p & imask);
4592 //if (*sp) *p = 0xff000000 | *p;
4593 //else *p = 0x00000000;
4602 for (py = 0; py < h; py++)
4604 for (px = 0; px < w; px++)
4608 evas_object_image_data_set(cw->obj, pix);
4609 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4610 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4612 evas_object_image_data_set(o, pix);
4613 evas_object_image_data_update_add(o, 0, 0, w, h);
4615 // don't need to fix alpha chanel as blending
4616 // should be totally off here regardless of
4617 // alpha channel content
4621 _e_comp_object_clear(E_Comp_Object *cw)
4626 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4628 if (cw->render_update_lock.lock) return;
4631 e_pixmap_clear(cw->ec->pixmap);
4633 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4634 evas_object_image_size_set(cw->obj, 1, 1);
4635 evas_object_image_data_set(cw->obj, NULL);
4636 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4638 evas_object_image_size_set(o, 1, 1);
4639 evas_object_image_data_set(o, NULL);
4642 e_comp_object_render_update_del(cw->smart_obj);
4646 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4650 API_ENTRY EINA_FALSE;
4652 if (cw->transparent.set == set)
4657 evas_object_color_get(obj, &r, &g, &b, &a);
4658 evas_object_color_set(obj, 0, 0, 0, 0);
4660 cw->transparent.user_r = r;
4661 cw->transparent.user_g = g;
4662 cw->transparent.user_b = b;
4663 cw->transparent.user_a = a;
4665 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4667 cw->transparent.user_r,
4668 cw->transparent.user_g,
4669 cw->transparent.user_b,
4670 cw->transparent.user_a);
4672 cw->transparent.set = EINA_TRUE;
4676 cw->transparent.set = EINA_FALSE;
4678 evas_object_color_set(obj,
4679 cw->transparent.user_r,
4680 cw->transparent.user_g,
4681 cw->transparent.user_b,
4682 cw->transparent.user_a);
4684 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4686 cw->transparent.user_r,
4687 cw->transparent.user_g,
4688 cw->transparent.user_b,
4689 cw->transparent.user_a);
4695 /* helper function to simplify toggling of redirection for display servers which support it */
4697 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4702 if (cw->redirected == set) return;
4703 cw->redirected = set;
4704 if (cw->external_content) return;
4706 e_comp_object_map_update(obj);
4710 if (cw->updates_exist)
4711 e_comp_object_render_update_add(obj);
4713 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4715 _e_comp_object_transparent_set(obj, EINA_FALSE);
4716 evas_object_smart_callback_call(obj, "redirected", NULL);
4720 _e_comp_object_clear(cw);
4721 _e_comp_object_transparent_set(obj, EINA_TRUE);
4722 evas_object_smart_callback_call(obj, "unredirected", NULL);
4727 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4730 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4732 if (cw->buffer_destroy_listener.notify)
4734 cw->buffer_destroy_listener.notify = NULL;
4735 wl_list_remove(&cw->buffer_destroy_listener.link);
4738 if (e_object_is_del(E_OBJECT(cw->ec)))
4740 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4745 /* if it's current displaying buffer, do not remove its content */
4746 if (!evas_object_visible_get(cw->ec->frame))
4747 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4752 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4757 if (cw->buffer_destroy_listener.notify)
4759 wl_list_remove(&cw->buffer_destroy_listener.link);
4760 cw->buffer_destroy_listener.notify = NULL;
4763 if (cw->tbm_surface)
4765 tbm_surface_internal_unref(cw->tbm_surface);
4766 cw->tbm_surface = NULL;
4771 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4773 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4774 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4776 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4778 tbm_surface_internal_ref(ns->data.tbm.buffer);
4779 cw->tbm_surface = ns->data.tbm.buffer;
4783 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4784 evas_object_image_native_surface_set(cw->obj, ns);
4788 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4790 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4791 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4792 evas_object_image_native_surface_set(o, ns);
4799 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4801 Evas_Native_Surface ns;
4804 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4805 if (cw->ec->input_only) return;
4806 if (cw->external_content) return;
4807 if (cw->render_update_lock.lock) return;
4810 memset(&ns, 0, sizeof(Evas_Native_Surface));
4814 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4815 set = (!cw->ec->shaped);
4817 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4821 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4825 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4828 if (cw->ec->input_only) return;
4831 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4832 _e_comp_object_alpha_set(cw);
4834 e_comp_object_native_surface_set(obj, cw->native);
4835 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4839 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4845 if (cw->blanked == set) return;
4847 _e_comp_object_alpha_set(cw);
4850 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4851 evas_object_image_data_set(cw->obj, NULL);
4855 e_comp_object_native_surface_set(obj, 1);
4856 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4860 _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)
4865 if (!_damage_trace) return;
4869 if (!evas_object_visible_get(cw->obj)) return;
4871 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4873 o = evas_object_rectangle_add(e_comp->evas);
4874 evas_object_layer_set(o, E_LAYER_MAX);
4875 evas_object_name_set(o, "damage_trace");
4876 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4877 evas_object_resize(o, dmg_w, dmg_h);
4878 evas_object_color_set(o, 0, 128, 0, 128);
4879 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4880 evas_object_pass_events_set(o, EINA_TRUE);
4881 evas_object_show(o);
4883 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4885 dmg_w, dmg_h, dmg_x, dmg_y,
4886 origin->w, origin->h, origin->x, origin->y);
4888 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4891 /* mark an object as dirty and setup damages */
4893 e_comp_object_dirty(Evas_Object *obj)
4896 Eina_Rectangle *rect;
4900 Eina_Bool dirty, visible;
4904 if (cw->external_content) return;
4905 if (!cw->redirected) return;
4906 if (cw->render_update_lock.lock)
4908 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4911 /* only actually dirty if pixmap is available */
4912 if (!e_pixmap_resource_get(cw->ec->pixmap))
4914 // e_pixmap_size_get returns last attached buffer size
4915 // eventhough it is destroyed
4916 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4919 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4920 visible = cw->visible;
4921 if (!dirty) w = h = 1;
4922 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4924 evas_object_image_data_set(cw->obj, NULL);
4925 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4926 evas_object_image_size_set(cw->obj, tw, th);
4927 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4928 if (cw->pending_updates)
4929 eina_tiler_area_size_set(cw->pending_updates, w, h);
4930 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4932 evas_object_image_pixels_dirty_set(o, dirty);
4934 evas_object_image_data_set(o, NULL);
4935 evas_object_image_size_set(o, tw, th);
4936 visible |= evas_object_visible_get(o);
4940 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4944 e_comp_object_native_surface_set(obj, 1);
4946 m = _e_comp_object_map_damage_transform_get(cw->ec);
4947 it = eina_tiler_iterator_new(cw->updates);
4948 EINA_ITERATOR_FOREACH(it, rect)
4950 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4951 * of evas engine and doesn't convert damage according to evas_map.
4952 * so damage of evas_object_image use surface coordinate.
4956 int damage_x, damage_y, damage_w, damage_h;
4958 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4959 &damage_x, &damage_y, &damage_w, &damage_h);
4960 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4961 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4965 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4966 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4969 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4970 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4971 if (cw->pending_updates)
4972 eina_tiler_rect_add(cw->pending_updates, rect);
4974 eina_iterator_free(it);
4975 if (m) e_map_free(m);
4976 if (cw->pending_updates)
4977 eina_tiler_clear(cw->updates);
4980 cw->pending_updates = cw->updates;
4981 cw->updates = eina_tiler_new(w, h);
4982 eina_tiler_tile_size_set(cw->updates, 1, 1);
4984 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4985 evas_object_smart_callback_call(obj, "dirty", NULL);
4986 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4987 /* force render if main object is hidden but mirrors are visible */
4988 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4989 e_comp_object_render(obj);
4993 e_comp_object_render(Evas_Object *obj)
5000 API_ENTRY EINA_FALSE;
5002 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5003 if (cw->ec->input_only) return EINA_TRUE;
5004 if (cw->external_content) return EINA_TRUE;
5005 if (cw->native) return EINA_FALSE;
5006 /* if comp object is not redirected state, comp object should not be set by newly committed data
5007 because image size of comp object is 1x1 and it should not be shown on canvas */
5008 if (!cw->redirected) return EINA_TRUE;
5009 if (cw->render_update_lock.lock)
5011 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5014 e_comp_object_render_update_del(obj);
5015 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5017 if (!cw->pending_updates)
5019 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5020 evas_object_image_data_set(cw->obj, NULL);
5021 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5022 evas_object_image_data_set(o, NULL);
5026 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5028 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5030 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5033 e_pixmap_image_refresh(cw->ec->pixmap);
5034 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5037 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5038 e_pixmap_image_data_ref(cw->ec->pixmap);
5040 /* set pixel data */
5041 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5042 _e_comp_object_alpha_set(cw);
5043 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5045 evas_object_image_data_set(o, pix);
5046 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5047 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5050 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5052 e_comp_client_post_update_add(cw->ec);
5057 /* create a duplicate of an evas object */
5059 e_comp_object_util_mirror_add(Evas_Object *obj)
5063 unsigned int *pix = NULL;
5064 Eina_Bool argb = EINA_FALSE;
5069 cw = evas_object_data_get(obj, "comp_mirror");
5072 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5073 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5074 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5075 evas_object_image_alpha_set(o, 1);
5076 evas_object_image_source_set(o, obj);
5079 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5080 if (cw->external_content)
5082 ERR("%p of client %p is external content.", obj, cw->ec);
5085 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5086 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5087 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5088 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5089 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5090 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5091 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5092 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5093 evas_object_data_set(o, "comp_mirror", cw);
5095 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5096 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5098 evas_object_image_size_set(o, tw, th);
5101 pix = evas_object_image_data_get(cw->obj, 0);
5107 evas_object_image_native_surface_set(o, cw->ns);
5110 Evas_Native_Surface ns;
5111 memset(&ns, 0, sizeof(Evas_Native_Surface));
5112 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5113 evas_object_image_native_surface_set(o, &ns);
5118 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5119 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5121 (e_pixmap_image_exists(cw->ec->pixmap)))
5122 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5124 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5131 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5132 evas_object_image_pixels_dirty_set(o, dirty);
5133 evas_object_image_data_set(o, pix);
5134 evas_object_image_data_set(cw->obj, pix);
5136 evas_object_image_data_update_add(o, 0, 0, tw, th);
5141 //////////////////////////////////////////////////////
5144 e_comp_object_effect_allowed_get(Evas_Object *obj)
5146 API_ENTRY EINA_FALSE;
5148 if (!cw->shobj) return EINA_FALSE;
5149 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5150 return !e_comp_config_get()->match.disable_borders;
5153 /* setup an api effect for a client */
5155 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5158 Eina_Stringshare *grp;
5159 E_Comp_Config *config;
5160 Eina_Bool loaded = EINA_FALSE;
5162 API_ENTRY EINA_FALSE;
5163 if (!cw->shobj) return EINA_FALSE; //input window
5165 if (!effect) effect = "none";
5166 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5168 config = e_comp_config_get();
5169 if ((config) && (config->effect_file))
5171 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5173 cw->effect_set = EINA_TRUE;
5180 edje_object_file_get(cw->effect_obj, NULL, &grp);
5181 cw->effect_set = !eina_streq(effect, "none");
5182 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5183 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5185 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5186 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5187 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5189 if (cw->effect_running)
5191 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5194 cw->effect_set = EINA_FALSE;
5195 return cw->effect_set;
5199 if (cw->effect_running)
5201 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5204 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5205 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5206 if (cw->effect_clip)
5208 evas_object_clip_unset(cw->clip);
5209 cw->effect_clip = 0;
5211 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5213 _e_comp_object_dim_update(cw);
5215 return cw->effect_set;
5218 /* set params for embryo scripts in effect */
5220 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5222 Edje_Message_Int_Set *msg;
5226 EINA_SAFETY_ON_NULL_RETURN(params);
5227 EINA_SAFETY_ON_FALSE_RETURN(count);
5228 if (!cw->effect_set) return;
5230 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5231 msg->count = (int)count;
5232 for (x = 0; x < count; x++)
5233 msg->val[x] = params[x];
5234 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5235 edje_object_message_signal_process(cw->effect_obj);
5239 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5241 Edje_Signal_Cb end_cb;
5243 E_Comp_Object *cw = data;
5245 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5246 cw->effect_running = 0;
5247 if (!_e_comp_object_animating_end(cw)) return;
5249 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5251 evas_object_data_del(cw->smart_obj, "effect_running");
5252 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5253 e_comp_visibility_calculation_set(EINA_TRUE);
5256 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5257 if (!end_cb) return;
5258 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5259 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5260 end_cb(end_data, cw->smart_obj, emission, source);
5263 /* clip effect to client's zone */
5265 e_comp_object_effect_clip(Evas_Object *obj)
5269 zone = e_comp_zone_find_by_ec(cw->ec);
5271 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5272 if (!cw->effect_clip_able) return;
5273 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5274 cw->effect_clip = 1;
5277 /* unclip effect from client's zone */
5279 e_comp_object_effect_unclip(Evas_Object *obj)
5282 if (!cw->effect_clip) return;
5283 evas_object_clip_unset(cw->smart_obj);
5284 cw->effect_clip = 0;
5287 /* start effect, running end_cb after */
5289 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5291 API_ENTRY EINA_FALSE;
5292 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5293 if (!cw->effect_set) return EINA_FALSE;
5295 if (cw->effect_running)
5297 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5300 e_comp_object_effect_clip(obj);
5301 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5303 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5304 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5305 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5306 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5308 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5309 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5311 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5312 _e_comp_object_animating_begin(cw);
5313 cw->effect_running = 1;
5317 /* stop a currently-running effect immediately */
5319 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5322 Edje_Signal_Cb end_cb_before = NULL;
5323 void *end_data_before = NULL;
5324 API_ENTRY EINA_FALSE;
5326 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5327 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5329 if (end_cb_before != end_cb) return EINA_TRUE;
5330 e_comp_object_effect_unclip(obj);
5331 if (cw->effect_clip)
5333 evas_object_clip_unset(cw->effect_obj);
5334 cw->effect_clip = 0;
5336 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5337 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5339 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5341 evas_object_data_del(cw->smart_obj, "effect_running");
5342 e_comp_visibility_calculation_set(EINA_TRUE);
5345 cw->effect_running = 0;
5346 ret = _e_comp_object_animating_end(cw);
5348 if ((ret) && (end_cb_before))
5350 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5351 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5358 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5360 return a->pri - b->pri;
5363 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5364 E_API E_Comp_Object_Mover *
5365 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5367 E_Comp_Object_Mover *prov;
5369 prov = E_NEW(E_Comp_Object_Mover, 1);
5370 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5371 prov->func = provider;
5372 prov->data = (void*)data;
5375 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5376 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5381 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5383 EINA_SAFETY_ON_NULL_RETURN(prov);
5384 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5389 e_comp_object_effect_object_get(Evas_Object *obj)
5393 return cw->effect_obj;
5397 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5399 API_ENTRY EINA_FALSE;
5400 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5401 if (!cw->effect_set) return EINA_FALSE;
5408 ////////////////////////////////////
5411 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5413 if (e_comp->autoclose.obj)
5415 e_comp_ungrab_input(0, 1);
5416 if (e_comp->autoclose.del_cb)
5417 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5418 else if (!already_del)
5420 evas_object_hide(e_comp->autoclose.obj);
5421 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5423 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5425 e_comp->autoclose.obj = NULL;
5426 e_comp->autoclose.data = NULL;
5427 e_comp->autoclose.del_cb = NULL;
5428 e_comp->autoclose.key_cb = NULL;
5429 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5433 _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)
5435 _e_comp_object_autoclose_cleanup(0);
5439 _e_comp_object_autoclose_setup(Evas_Object *obj)
5441 if (!e_comp->autoclose.rect)
5443 /* create rect just below autoclose object to catch mouse events */
5444 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5445 evas_object_move(e_comp->autoclose.rect, 0, 0);
5446 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5447 evas_object_show(e_comp->autoclose.rect);
5448 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5449 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5450 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5451 e_comp_grab_input(0, 1);
5453 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5454 evas_object_focus_set(obj, 1);
5458 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5460 _e_comp_object_autoclose_setup(obj);
5461 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5465 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5467 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5468 _e_comp_object_autoclose_cleanup(1);
5469 if (e_client_focused_get()) return;
5470 if (e_config->focus_policy != E_FOCUS_MOUSE)
5475 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5479 if (e_comp->autoclose.obj)
5481 if (e_comp->autoclose.obj == obj) return;
5482 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5483 e_comp->autoclose.obj = obj;
5484 e_comp->autoclose.del_cb = del_cb;
5485 e_comp->autoclose.key_cb = cb;
5486 e_comp->autoclose.data = (void*)data;
5487 if (evas_object_visible_get(obj))
5488 _e_comp_object_autoclose_setup(obj);
5490 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5491 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5494 e_comp->autoclose.obj = obj;
5495 e_comp->autoclose.del_cb = del_cb;
5496 e_comp->autoclose.key_cb = cb;
5497 e_comp->autoclose.data = (void*)data;
5498 if (evas_object_visible_get(obj))
5499 _e_comp_object_autoclose_setup(obj);
5501 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5502 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5506 e_comp_object_is_animating(Evas_Object *obj)
5510 return cw->animating;
5514 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5518 if ((cw->external_content) &&
5519 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5521 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5522 "But current external content is %d object for %p.",
5523 cw->content_type, cw->ec);
5527 cw->user_alpha_set = EINA_TRUE;
5528 cw->user_alpha = alpha;
5530 if (!cw->obj) return;
5532 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5534 evas_object_image_alpha_set(cw->obj, alpha);
5536 if ((!cw->native) && (!cw->external_content))
5537 evas_object_image_data_set(cw->obj, NULL);
5541 e_comp_object_alpha_get(Evas_Object *obj)
5543 API_ENTRY EINA_FALSE;
5545 return evas_object_image_alpha_get(cw->obj);
5549 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5551 Eina_Bool mask_set = EINA_FALSE;
5555 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5556 if (cw->ec->input_only) return;
5563 o = evas_object_rectangle_add(e_comp->evas);
5564 evas_object_color_set(o, 0, 0, 0, 0);
5565 evas_object_clip_set(o, cw->clip);
5566 evas_object_smart_member_add(o, obj);
5567 evas_object_move(o, 0, 0);
5568 evas_object_resize(o, cw->w, cw->h);
5569 /* save render op value to restore when clear a mask.
5571 * NOTE: DO NOT change the render op on ec->frame while mask object
5572 * is set. it will overwrite the changed op value. */
5573 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5574 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5575 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5576 if (cw->visible) evas_object_show(o);
5579 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5580 ELOGF("COMP", " |mask_obj", cw->ec);
5581 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5588 evas_object_smart_member_del(cw->mask.obj);
5589 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5591 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5592 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5598 e_comp_object_mask_has(Evas_Object *obj)
5600 API_ENTRY EINA_FALSE;
5602 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5606 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5611 if ((cw->external_content) &&
5612 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5614 WRN("Can set up size to ONLY evas \"image\" object. "
5615 "But current external content is %d object for %p.",
5616 cw->content_type, cw->ec);
5620 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5622 evas_object_image_size_set(cw->obj, tw, th);
5626 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5628 Eina_Bool transform_set = EINA_FALSE;
5630 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5631 if (cw->ec->input_only) return;
5633 transform_set = !!set;
5637 if (!cw->transform_bg_obj)
5639 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5640 evas_object_move(o, 0, 0);
5641 evas_object_resize(o, 1, 1);
5642 if (cw->transform_bg_color.a >= 255)
5643 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5645 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5646 evas_object_color_set(o,
5647 cw->transform_bg_color.r,
5648 cw->transform_bg_color.g,
5649 cw->transform_bg_color.b,
5650 cw->transform_bg_color.a);
5651 if (cw->visible) evas_object_show(o);
5653 cw->transform_bg_obj = o;
5654 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5656 _e_comp_object_transform_obj_stack_update(obj);
5660 if (cw->transform_bg_obj)
5662 evas_object_smart_member_del(cw->transform_bg_obj);
5663 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5669 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5673 cw->transform_bg_color.r = r;
5674 cw->transform_bg_color.g = g;
5675 cw->transform_bg_color.b = b;
5676 cw->transform_bg_color.a = a;
5678 if (cw->transform_bg_obj)
5680 evas_object_color_set(cw->transform_bg_obj,
5681 cw->transform_bg_color.r,
5682 cw->transform_bg_color.g,
5683 cw->transform_bg_color.b,
5684 cw->transform_bg_color.a);
5689 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5692 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5693 if (cw->ec->input_only) return;
5694 if (!cw->transform_bg_obj) return;
5696 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5700 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5703 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5704 if (cw->ec->input_only) return;
5705 if (!cw->transform_bg_obj) return;
5707 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5711 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5713 Eina_Bool transform_set = EINA_FALSE;
5715 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5716 if (cw->ec->input_only) return;
5718 transform_set = !!set;
5722 if (!cw->transform_tranp_obj)
5724 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5725 evas_object_move(o, 0, 0);
5726 evas_object_resize(o, 1, 1);
5727 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5728 evas_object_color_set(o, 0, 0, 0, 0);
5729 if (cw->visible) evas_object_show(o);
5731 cw->transform_tranp_obj = o;
5732 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5734 _e_comp_object_transform_obj_stack_update(obj);
5738 if (cw->transform_tranp_obj)
5740 evas_object_smart_member_del(cw->transform_tranp_obj);
5741 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5747 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5750 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5751 if (cw->ec->input_only) return;
5752 if (!cw->transform_tranp_obj) return;
5754 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5758 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5761 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5762 if (cw->ec->input_only) return;
5763 if (!cw->transform_tranp_obj) return;
5765 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5769 e_comp_object_layer_update(Evas_Object *obj,
5770 Evas_Object *above, Evas_Object *below)
5772 E_Comp_Object *cw2 = NULL;
5773 Evas_Object *o = NULL;
5778 if (cw->ec->layer_block) return;
5779 if ((above) && (below))
5781 ERR("Invalid layer update request! cw=%p", cw);
5789 layer = evas_object_layer_get(o);
5790 cw2 = evas_object_data_get(o, "comp_obj");
5793 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5795 o = evas_object_above_get(o);
5796 if ((!o) || (o == cw->smart_obj)) break;
5797 if (evas_object_layer_get(o) != layer)
5799 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5804 ec = e_client_top_get();
5805 if (ec) o = ec->frame;
5808 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5812 _e_comp_object_layers_remove(cw);
5815 if (cw2->layer > cw->layer)
5816 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5817 else if (cw2->layer == cw->layer)
5820 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5822 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5824 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5827 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5830 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5834 e_comp_object_layer_get(Evas_Object *obj)
5841 e_comp_object_content_set(Evas_Object *obj,
5842 Evas_Object *content,
5843 E_Comp_Object_Content_Type type)
5845 API_ENTRY EINA_FALSE;
5847 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5848 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5849 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5853 ERR("Can't set e.swallow.content to requested content. "
5854 "Previous comp object should not be changed at all.");
5858 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5860 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5861 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5863 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5864 type, content, cw->ec, cw->ec->pixmap);
5868 cw->external_content = EINA_TRUE;
5871 cw->content_type = type;
5872 e_util_size_debug_set(cw->obj, 1);
5873 evas_object_name_set(cw->obj, "cw->obj");
5874 _e_comp_object_alpha_set(cw);
5877 _e_comp_object_shadow_setup(cw);
5883 e_comp_object_content_unset(Evas_Object *obj)
5885 API_ENTRY EINA_FALSE;
5887 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5888 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5890 if (!cw->obj && !cw->ec->visible)
5892 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5896 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5898 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5904 if (cw->frame_object)
5905 edje_object_part_unswallow(cw->frame_object, cw->obj);
5907 edje_object_part_unswallow(cw->shobj, cw->obj);
5909 evas_object_del(cw->obj);
5910 evas_object_hide(cw->obj);
5914 cw->external_content = EINA_FALSE;
5915 if (cw->ec->is_cursor)
5918 DBG("%p is cursor surface..", cw->ec);
5919 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5921 evas_object_resize(cw->ec->frame, pw, ph);
5922 evas_object_hide(cw->ec->frame);
5927 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5928 cw->obj = evas_object_image_filled_add(e_comp->evas);
5929 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5930 e_util_size_debug_set(cw->obj, 1);
5931 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5932 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5933 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5934 evas_object_name_set(cw->obj, "cw->obj");
5935 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5936 _e_comp_object_alpha_set(cw);
5939 _e_comp_object_shadow_setup(cw);
5944 _e_comp_intercept_show_helper(cw);
5948 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5949 e_comp_object_dirty(cw->smart_obj);
5950 e_comp_object_render(cw->smart_obj);
5951 e_comp_object_render_update_add(obj);
5956 EINTERN Evas_Object *
5957 e_comp_object_content_get(Evas_Object *obj)
5961 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5963 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5965 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5972 E_API E_Comp_Object_Content_Type
5973 e_comp_object_content_type_get(Evas_Object *obj)
5975 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5977 return cw->content_type;
5981 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5984 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5985 E_Comp_Config *conf = e_comp_config_get();
5986 if (cw->ec->input_only) return;
5987 if (!conf->dim_rect_enable) return;
5989 cw->dim.mask_set = mask_set;
5995 if (!cw->dim.enable) return;
5996 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6000 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6002 Eina_Bool mask_set = EINA_FALSE;
6006 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6007 E_Comp_Config *conf = e_comp_config_get();
6008 if (cw->ec->input_only) return;
6009 if (!conf->dim_rect_enable) return;
6015 if (cw->dim.mask_obj)
6017 evas_object_smart_member_del(cw->dim.mask_obj);
6018 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6021 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);
6022 o = evas_object_rectangle_add(e_comp->evas);
6023 evas_object_color_set(o, 0, 0, 0, 0);
6024 evas_object_smart_member_add(o, obj);
6025 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6026 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6028 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6029 if (cw->visible) evas_object_show(o);
6031 cw->dim.mask_obj = o;
6032 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6034 evas_object_layer_set(cw->dim.mask_obj, 9998);
6038 if (cw->dim.mask_obj)
6040 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6041 evas_object_smart_member_del(cw->dim.mask_obj);
6042 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6048 e_comp_object_dim_client_set(E_Client *ec)
6050 E_Comp_Config *conf = e_comp_config_get();
6052 if (!conf->dim_rect_enable) return ;
6053 if (dim_client == ec) return;
6055 Eina_Bool prev_dim = EINA_FALSE;
6056 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6058 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6059 prev_dim = EINA_TRUE;
6061 if (prev_dim && dim_client->visible && ec)
6063 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6064 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6068 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6069 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6075 e_comp_object_dim_client_get(void)
6077 E_Comp_Config *conf = e_comp_config_get();
6079 if (!conf->dim_rect_enable ) return NULL;
6085 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6088 char emit[32] = "\0";
6089 E_Comp_Config *conf = e_comp_config_get();
6092 if (!conf->dim_rect_enable) return;
6093 if (!cw->effect_obj) return;
6094 if (enable == cw->dim.enable) return;
6096 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6097 if (noeffect || !conf->dim_rect_effect)
6099 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6103 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6106 cw->dim.enable = enable;
6108 if (cw->dim.mask_set && !enable)
6110 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6111 edje_object_signal_emit(cw->effect_obj, emit, "e");
6113 else if (cw->dim.mask_set && enable)
6115 edje_object_signal_emit(cw->effect_obj, emit, "e");
6116 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6120 edje_object_signal_emit(cw->effect_obj, emit, "e");
6125 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6127 API_ENTRY EINA_FALSE;
6128 E_Comp_Config *conf = e_comp_config_get();
6130 if (!ec) return EINA_FALSE;
6131 if (!conf->dim_rect_enable) return EINA_FALSE;
6133 if (cw->dim.enable) return EINA_TRUE;
6139 _e_comp_object_dim_update(E_Comp_Object *cw)
6141 E_Comp_Config *conf = e_comp_config_get();
6144 if (!conf->dim_rect_enable) return;
6145 if (!cw->effect_obj) return;
6148 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6149 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6151 if (cw->dim.mask_set)
6153 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6159 e_comp_object_clear(Evas_Object *obj)
6163 _e_comp_object_clear(cw);
6167 e_comp_object_hwc_update_exists(Evas_Object *obj)
6169 API_ENTRY EINA_FALSE;
6170 return cw->hwc_need_update;
6175 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6178 cw->hwc_need_update = set;
6182 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6184 API_ENTRY EINA_FALSE;
6185 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6189 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6192 if (cw->indicator.obj != indicator)
6193 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6194 cw->indicator.obj = indicator;
6195 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6199 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6202 if (cw->indicator.obj != indicator) return;
6203 cw->indicator.obj = NULL;
6204 edje_object_part_unswallow(cw->shobj, indicator);
6208 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6211 Edje_Message_Int_Set *msg;
6213 if (!cw->indicator.obj) return;
6215 cw->indicator.w = w;
6216 cw->indicator.h = h;
6218 if (!cw->shobj) return;
6220 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6224 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6225 edje_object_message_signal_process(cw->shobj);
6228 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6230 e_comp_object_map_update(Evas_Object *obj)
6233 E_Client *ec = cw->ec;
6234 E_Comp_Wl_Client_Data *cdata;
6236 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6239 int l, remain = sizeof buffer;
6242 if (e_object_is_del(E_OBJECT(ec))) return;
6243 cdata = e_client_cdata_get(ec);
6246 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6247 * when new buffer is attached.
6249 if (!cdata->buffer_ref.buffer) return;
6251 if ((!cw->redirected) ||
6252 (e_client_video_hw_composition_check(ec)) ||
6253 (!e_comp_wl_output_buffer_transform_get(ec) &&
6254 cdata->scaler.buffer_viewport.buffer.scale == 1))
6256 if (evas_object_map_enable_get(cw->effect_obj))
6258 ELOGF("TRANSFORM", "map: disable", cw->ec);
6259 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6260 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6261 evas_object_resize(cw->effect_obj, tw, th);
6268 EINA_SAFETY_ON_NULL_RETURN(map);
6270 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6276 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6278 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6279 e_map_point_image_uv_set(map, 0, x, y);
6280 l = snprintf(p, remain, "%d,%d", x, y);
6281 p += l, remain -= l;
6283 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6284 e_map_point_image_uv_set(map, 1, x, y);
6285 l = snprintf(p, remain, " %d,%d", x, y);
6286 p += l, remain -= l;
6288 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6289 e_map_point_image_uv_set(map, 2, x, y);
6290 l = snprintf(p, remain, " %d,%d", x, y);
6291 p += l, remain -= l;
6293 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6294 e_map_point_image_uv_set(map, 3, x, y);
6295 l = snprintf(p, remain, " %d,%d", x, y);
6296 p += l, remain -= l;
6298 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6300 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6302 e_comp_object_map_set(cw->effect_obj, map);
6303 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6307 /* if there's screen rotation with comp mode, then ec->effect_obj and
6308 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6310 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6311 evas_object_resize(cw->effect_obj, tw, th);
6315 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6317 API_ENTRY EINA_FALSE;
6319 cw->render_trace = set;
6325 e_comp_object_native_usable_get(Evas_Object *obj)
6327 API_ENTRY EINA_FALSE;
6328 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6330 if (cw->ec->input_only) return EINA_FALSE;
6331 if (cw->external_content) return EINA_FALSE;
6332 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6334 /* just return true value, if it is normal case */
6335 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6338 Evas_Native_Surface *ns;
6339 ns = evas_object_image_native_surface_get(cw->obj);
6341 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6344 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6352 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6354 API_ENTRY EINA_FALSE;
6355 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6356 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6357 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6361 case E_COMP_IMAGE_FILTER_BLUR:
6362 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6364 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6365 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6367 case E_COMP_IMAGE_FILTER_INVERSE:
6368 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6370 case E_COMP_IMAGE_FILTER_NONE:
6372 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6376 cw->image_filter = filter;
6381 EINTERN E_Comp_Image_Filter
6382 e_comp_object_image_filter_get(Evas_Object *obj)
6384 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6385 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6386 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6387 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6389 return cw->image_filter;
6393 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6397 if (!_damage_trace) return;
6399 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6400 evas_object_del(obj);
6402 _damage_trace_post_objs = NULL;
6406 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6408 if (!_damage_trace) return;
6410 _damage_trace_post_objs = _damage_trace_objs;
6411 _damage_trace_objs = NULL;
6415 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6417 if (_damage_trace == onoff) return;
6421 evas_event_callback_add(e_comp->evas,
6422 EVAS_CALLBACK_RENDER_PRE,
6423 _e_comp_object_damage_trace_render_pre_cb,
6426 evas_event_callback_add(e_comp->evas,
6427 EVAS_CALLBACK_RENDER_POST,
6428 _e_comp_object_damage_trace_render_post_cb,
6435 EINA_LIST_FREE(_damage_trace_objs, obj)
6436 evas_object_del(obj);
6438 _damage_trace_objs = NULL;
6440 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6441 evas_object_del(obj);
6443 _damage_trace_post_objs = NULL;
6445 evas_event_callback_del(e_comp->evas,
6446 EVAS_CALLBACK_RENDER_PRE,
6447 _e_comp_object_damage_trace_render_pre_cb);
6449 evas_event_callback_del(e_comp->evas,
6450 EVAS_CALLBACK_RENDER_POST,
6451 _e_comp_object_damage_trace_render_post_cb);
6454 _damage_trace = onoff;
6458 e_comp_object_redirected_get(Evas_Object *obj)
6460 API_ENTRY EINA_FALSE;
6461 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6463 return cw->redirected;
6467 e_comp_object_color_visible_get(Evas_Object *obj)
6469 API_ENTRY EINA_FALSE;
6472 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6474 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6478 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6482 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6486 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6494 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6496 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6498 return e_map_set_to_comp_object(em, obj);
6502 e_comp_object_map_get(const Evas_Object *obj)
6504 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6506 return e_map_get_from_comp_object(obj);
6510 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6512 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6514 evas_object_map_enable_set(obj, enable);
6520 e_comp_object_render_update_lock(Evas_Object *obj)
6522 E_Comp_Wl_Buffer *buffer;
6523 struct wayland_tbm_client_queue *cqueue;
6525 API_ENTRY EINA_FALSE;
6527 if (cw->render_update_lock.lock == 0)
6529 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6531 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6532 if ((buffer) && (buffer->resource))
6534 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6536 wayland_tbm_server_client_queue_flush(cqueue);
6539 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6540 e_comp_object_render_update_del(obj);
6542 ELOGF("COMP", "Render update lock enabled", cw->ec);
6545 cw->render_update_lock.lock++;
6551 e_comp_object_render_update_unlock(Evas_Object *obj)
6555 if (cw->render_update_lock.lock == 0)
6558 cw->render_update_lock.lock--;
6560 if (cw->render_update_lock.lock == 0)
6563 if (cw->render_update_lock.pending_move_set)
6565 evas_object_move(obj,
6566 cw->render_update_lock.pending_move_x,
6567 cw->render_update_lock.pending_move_y);
6568 cw->render_update_lock.pending_move_x = 0;
6569 cw->render_update_lock.pending_move_y = 0;
6570 cw->render_update_lock.pending_move_set = EINA_FALSE;
6573 if (cw->render_update_lock.pending_resize_set)
6575 evas_object_resize(obj,
6576 cw->render_update_lock.pending_resize_w,
6577 cw->render_update_lock.pending_resize_h);
6578 cw->render_update_lock.pending_resize_w = 0;
6579 cw->render_update_lock.pending_resize_h = 0;
6580 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6583 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6585 if ((cw->ec->exp_iconify.buffer_flush) &&
6586 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6587 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6588 e_comp_object_clear(obj);
6590 e_comp_object_render_update_add(obj);
6592 ELOGF("COMP", "Render update lock disabled", cw->ec);
6597 e_comp_object_render_update_lock_get(Evas_Object *obj)
6599 API_ENTRY EINA_FALSE;
6601 if (cw->render_update_lock.lock > 0)
6608 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6612 if (cw->transparent.set)
6614 if (r) *r = cw->transparent.user_r;
6615 if (g) *g = cw->transparent.user_g;
6616 if (b) *b = cw->transparent.user_b;
6617 if (a) *a = cw->transparent.user_a;
6621 evas_object_color_get(obj, r, g, b, a);
6626 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6630 evas_object_render_op_set(cw->obj, op);
6633 EINTERN Evas_Render_Op
6634 e_comp_object_render_op_get(Evas_Object *obj)
6636 API_ENTRY EVAS_RENDER_BLEND;
6638 return evas_object_render_op_get(cw->obj);