2 #ifdef REFACTOR_DESK_AREA
3 #include "e_comp_object_intern.h"
5 #include "e_bindings_intern.h"
6 #include "e_utils_intern.h"
10 = keys that return objects =
11 - E_Client: the client associated with the object (E_Client*)
12 - comp_smart_obj: cw->smart_obj (Evas_Object*)
13 - comp_obj: cw (E_Comp_Object*)
15 = keys that are bool flags =
16 - client_restack: client needs a protocol-level restack
17 - comp_override: object is triggering a nocomp override to force compositing
18 - comp_ref: object has a ref from visibility animations
19 - comp_showing: object is currently running its show animation
20 - comp_hiding: object is currently running its hiding animation
21 - comp_object: object is a compositor-created object
22 - comp_object_skip: object has a name which prohibits theme shadows
23 - comp_object-to_del: list of objects which will be deleted when this object is deleted
24 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
25 - effect_running: object is animating by external module
28 #define UPDATE_MAX 512 // same as evas
29 #define FAILURE_MAX 2 // seems reasonable
30 #define SMART_NAME "e_comp_object"
31 #define INPUT_OBJ_SMART_NAME "input_object"
33 /* for non-util functions */
34 #define API_ENTRY E_Comp_Object *cw; \
35 cw = evas_object_smart_data_get(obj); \
36 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
38 /* for util functions (obj may or may not be E_Comp_Object */
39 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
42 CRI("YOU PASSED NULL! ARGH!"); \
45 cw = evas_object_smart_data_get(obj); \
46 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
48 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
50 /* enable for lots of client size info in console output */
52 # define e_util_size_debug_set(x, y)
55 /* enable along with display-specific damage INF calls to enable render tracing
59 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
61 #define RENDER_DEBUG(...)
64 #ifdef REFACTOR_DESK_AREA
66 typedef struct _E_Comp_Object
70 int x, y, w, h; // geometry
74 E_Comp_Object_Frame client_inset;
76 Eina_Stringshare *frame_theme;
77 Eina_Stringshare *frame_name;
78 Eina_Stringshare *visibility_effect; //effect when toggling visibility
80 E_Comp_Object_Content_Type content_type; // type of e.swallow.content
82 Evas_Object *smart_obj; // smart object
83 Evas_Object *clip; // clipper over effect object
84 Evas_Object *input_obj; // input smart object
85 Evas_Object *obj; // composite object
86 Evas_Object *frame_object; // for client frames
87 Evas_Object *shobj; // shadow object
88 Evas_Object *effect_obj; // effects object
89 Evas_Object *transform_bg_obj; // transform backgroung with keep_ratio option
94 Evas_Object *transform_tranp_obj;// transform transp rect obj
95 Evas_Object *default_input_obj; // default input object
96 unsigned int layer; //e_comp_canvas_layer_map(cw->ec->layer)
97 Eina_List *obj_mirror; // extra mirror objects
98 Eina_Tiler *updates; //render update regions
99 Eina_Tiler *pending_updates; //render update regions which are about to render
101 Evas_Native_Surface *ns; //for custom gl rendering
103 struct wl_listener buffer_destroy_listener;
105 unsigned int update_count; // how many updates have happened to this obj
107 unsigned int opacity; // opacity set with _NET_WM_WINDOW_OPACITY
109 unsigned int animating; // it's busy animating
110 unsigned int failures; //number of consecutive e_pixmap_image_draw() failures
111 unsigned int force_visible; //number of visible obj_mirror objects
112 Eina_Bool delete_pending : 1; // delete pending
113 Eina_Bool defer_hide : 1; // flag to get hide to work on deferred hide
114 Eina_Bool showing : 1; // object is currently in "show" animation
115 Eina_Bool hiding : 1; // object is currently in "hide" animation
116 Eina_Bool visible : 1; // is visible
118 Eina_Bool shaped : 1; // is shaped
119 Eina_Bool update : 1; // has updates to fetch
120 Eina_Bool redirected : 1; // has updates to fetch
121 Eina_Bool native : 1; // native
123 Eina_Bool nocomp : 1; // nocomp applied
124 Eina_Bool hwc_need_update : 1; // this window updated while on e_plane to do hw composite
125 Eina_Bool real_hid : 1; // last hide was a real window unmap
127 Eina_Bool effect_set : 1; //effect_obj has a valid group
128 Eina_Bool effect_running : 1; //effect_obj is playing an animation
129 Eina_Bool effect_clip : 1; //effect_obj is clipped
130 Eina_Bool effect_clip_able : 1; //effect_obj will be clipped for effects
132 Eina_Bool updates_exist : 1;
133 Eina_Bool updates_full : 1; // entire object will be updated
135 Eina_Bool force_move : 1;
136 Eina_Bool frame_extends : 1; //frame may extend beyond object size
137 Eina_Bool blanked : 1; //window is rendering blank content (externally composited)
138 Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object
139 Eina_Bool user_alpha_set : 1;
140 Eina_Bool user_alpha : 1;
144 Evas_Object *obj; // mask object: transparent parts of this comp object allow to copy the alpha to current H/W plane.
145 Evas_Render_Op saved_render_op; // saved render operation value to restore when clear a mask.
152 } indicator; //indicator object for internal client
156 Evas_Object *mask_obj;
159 int mask_x, mask_y, mask_w, mask_h;
162 Eina_Bool render_trace : 1; // trace co->obj rendering on canvas
164 tbm_surface_h tbm_surface;
165 E_Comp_Image_Filter image_filter;
166 Eina_Bool set_mouse_callbacks;
171 E_Comp_Wl_Buffer_Ref buffer_ref;
172 Eina_Bool pending_move_set;
173 int pending_move_x, pending_move_y;
174 Eina_Bool pending_resize_set;
175 int pending_resize_w, pending_resize_h;
176 } render_update_lock;
189 struct wl_signal lower;
190 //#ifdef REFACTOR_DESK_AREA
191 struct wl_signal raise;
193 struct wl_signal show;
194 struct wl_signal hide;
195 //#ifdef REFACTOR_DESK_AREA
196 struct wl_signal set_layer;
197 struct wl_signal stack_above;
198 struct wl_signal stack_below;
204 typedef struct _E_Input_Rect_Data
210 typedef struct _E_Input_Rect_Smart_Data
212 Eina_List *input_rect_data_list;
214 } E_Input_Rect_Smart_Data;
216 struct E_Comp_Object_Mover
219 E_Comp_Object_Mover_Cb func;
225 static Eina_Inlist *_e_comp_object_movers = NULL;
226 static Evas_Smart *_e_comp_smart = NULL;
227 static Evas_Smart *_e_comp_input_obj_smart = NULL;
229 static int _e_comp_object_hooks_delete = 0;
230 static int _e_comp_object_hooks_walking = 0;
232 static Eina_Inlist *_e_comp_object_hooks[] =
234 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
235 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
236 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
237 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
238 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
239 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
240 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
241 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
244 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
245 static int _e_comp_object_intercept_hooks_delete = 0;
246 static int _e_comp_object_intercept_hooks_walking = 0;
248 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
250 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
251 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
255 static Eina_Bool _damage_trace = EINA_FALSE;
256 static Eina_List *_damage_trace_objs = NULL;
257 static Eina_List *_damage_trace_post_objs = NULL;
259 /* sekrit functionzzz */
260 EINTERN void e_client_focused_set(E_Client *ec);
262 /* emitted every time a new noteworthy comp object is added */
263 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
265 /* ecore event define */
266 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
267 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
268 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
270 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
271 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
272 static void _e_comp_object_dim_update(E_Comp_Object *cw);
273 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
274 #ifdef REFACTOR_DESK_AREA
276 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
279 static E_Client *dim_client = NULL;
282 _e_comp_object_hooks_clean(void)
285 E_Comp_Object_Hook *ch;
288 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
289 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
291 if (!ch->delete_me) continue;
292 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
298 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
300 E_Comp_Object_Hook *ch;
301 Eina_Bool ret = EINA_TRUE;
303 if (e_object_is_del(E_OBJECT(ec)))
305 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
306 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
307 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
308 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
309 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
310 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
311 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
312 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET)
318 e_object_ref(E_OBJECT(ec));
319 _e_comp_object_hooks_walking++;
320 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
322 if (ch->delete_me) continue;
323 if (!(ch->func(ch->data, ec)))
329 _e_comp_object_hooks_walking--;
330 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
331 _e_comp_object_hooks_clean();
333 e_object_unref(E_OBJECT(ec));
338 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
340 _e_comp_object_intercept_hooks_clean(void)
343 E_Comp_Object_Intercept_Hook *ch;
346 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
347 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
349 if (!ch->delete_me) continue;
350 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
356 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
358 E_Comp_Object_Intercept_Hook *ch;
359 Eina_Bool ret = EINA_TRUE;
361 if (e_object_is_del(E_OBJECT(ec))) return ret;
362 e_object_ref(E_OBJECT(ec));
363 _e_comp_object_intercept_hooks_walking++;
364 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
366 if (ch->delete_me) continue;
367 if (!(ch->func(ch->data, ec)))
373 _e_comp_object_intercept_hooks_walking--;
374 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
375 _e_comp_object_intercept_hooks_clean();
377 e_object_unref(E_OBJECT(ec));
384 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
386 E_Event_Comp_Object *ev = event;
389 ec = evas_object_data_get(ev->comp_object, "E_Client");
393 e_object_unref(E_OBJECT(ec));
395 evas_object_unref(ev->comp_object);
400 _e_comp_object_event_add(Evas_Object *obj)
402 E_Event_Comp_Object *ev;
405 if (stopping) return;
406 ev = E_NEW(E_Event_Comp_Object, 1);
407 EINA_SAFETY_ON_NULL_RETURN(ev);
409 evas_object_ref(obj);
410 ev->comp_object = obj;
411 ec = evas_object_data_get(ev->comp_object, "E_Client");
415 e_object_ref(E_OBJECT(ec));
417 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
421 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
423 E_Event_Comp_Object *ev = event;
426 ec = evas_object_data_get(ev->comp_object, "E_Client");
430 e_object_unref(E_OBJECT(ec));
432 evas_object_unref(ev->comp_object);
437 _e_comp_object_event_simple(Evas_Object *obj, int type)
439 E_Event_Comp_Object *ev;
442 ev = E_NEW(E_Event_Comp_Object, 1);
445 evas_object_ref(obj);
446 ev->comp_object = obj;
447 ec = evas_object_data_get(ev->comp_object, "E_Client");
451 e_object_ref(E_OBJECT(ec));
453 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
455 /////////////////////////////////////
458 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
460 E_Comp_Object *cw = data;
462 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
466 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
468 E_Comp_Object *cw = data;
470 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
471 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
474 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
475 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
479 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
481 E_Comp_Object *cw = data;
484 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
485 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
488 /////////////////////////////////////
490 #ifdef REFACTOR_DESK_AREA
492 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
495 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
500 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
501 if (cw->ec->input_only) return;
503 layer = evas_object_layer_get(obj);
505 if (cw->transform_bg_obj)
507 if (layer != evas_object_layer_get(cw->transform_bg_obj))
509 evas_object_layer_set(cw->transform_bg_obj, layer);
512 evas_object_stack_below(cw->transform_bg_obj, obj);
515 if (cw->transform_tranp_obj)
517 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
519 evas_object_layer_set(cw->transform_tranp_obj, layer);
522 evas_object_stack_below(cw->transform_tranp_obj, obj);
527 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
534 if (!map) return NULL;
536 e_map_util_points_populate_from_object_full(map, obj, 0);
537 e_map_util_points_color_set(map, 255, 255, 255, 255);
539 for (i = 0 ; i < 4 ; ++i)
544 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
545 e_map_point_coord_set(map, i, x, y, 1.0);
552 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
558 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
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);
574 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
580 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
583 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
585 e_comp_object_map_set(obj, map);
586 e_comp_object_map_enable_set(obj, EINA_TRUE);
593 evas_object_map_enable_set(obj, EINA_FALSE);
596 /////////////////////////////////////
598 static inline Eina_Bool
599 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
601 if (num > 1) return EINA_TRUE;
602 if ((rects[0].x == 0) && (rects[0].y == 0) &&
603 ((int)rects[0].w == w) && ((int)rects[0].h == h))
608 /////////////////////////////////////
610 /* add a client to the layer-client list */
611 #ifdef REFACTOR_DESK_AREA
614 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
616 g_rec_mutex_lock(&e_comp->ec_list_mutex);
619 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));
621 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));
622 if ((!above) && (!below))
625 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
626 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
627 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
629 e_comp->layers[cw->layer].clients_count++;
631 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
635 _e_comp_object_layers_remove(E_Comp_Object *cw)
637 g_rec_mutex_lock(&e_comp->ec_list_mutex);
639 if (cw->ec && e_comp->layers[cw->layer].clients)
641 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
642 e_comp->layers[cw->layer].clients_count--;
645 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
649 /////////////////////////////////////
651 _e_comp_object_alpha_set(E_Comp_Object *cw)
653 Eina_Bool alpha = cw->ec->argb;
655 if ((cw->external_content) &&
656 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
661 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
662 if (cw->user_alpha_set) alpha = cw->user_alpha;
664 evas_object_image_alpha_set(cw->obj, alpha);
668 _e_comp_object_shadow(E_Comp_Object *cw)
670 if (e_client_util_shadow_state_get(cw->ec))
671 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
673 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
674 if (cw->frame_object)
675 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
676 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
679 /* convert from the surface coordinates to the buffer coordinates */
681 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
683 E_Comp_Wl_Buffer_Viewport *vp;
684 E_Comp_Wl_Client_Data *cdata;
688 cdata = e_client_cdata_get(ec);
690 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
697 vp = &cdata->scaler.buffer_viewport;
698 transform = e_comp_wl_output_buffer_transform_get(ec);
700 e_pixmap_size_get(ec->pixmap, &bw, &bh);
702 /* for subsurface, it should be swap 90 and 270 */
703 if (e_comp_wl_subsurface_check(ec))
706 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
707 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
708 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
709 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
715 case WL_OUTPUT_TRANSFORM_NORMAL:
716 default: tx = sx, ty = sy; break;
717 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
718 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
719 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
720 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
721 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
722 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
723 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
726 tx *= vp->buffer.scale;
727 ty *= vp->buffer.scale;
734 _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)
742 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
743 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
750 if (dw) *dw = MAX(x1, x2) - mx;
751 if (dh) *dh = MAX(y1, y2) - my;
755 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
756 int *dx, int *dy, int *dw, int *dh)
758 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
759 E_Util_Transform_Rect_Vertex sv, dv;
763 e_pixmap_size_get(ec->pixmap, &bw, &bh);
765 sv = e_util_transform_rect_to_vertices(&rect);
767 for (i = 0; i < 4; i++)
769 double x = 0.0, y = 0.0;
771 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
773 /* if evas decide coordinate is outside of map, it returns (0, 0)
774 in this case, full damage is added.
776 if ((i != 0) && (x == 0.0) && (y == 0.0))
779 dv.vertices[i].vertex[0] = x;
780 dv.vertices[i].vertex[1] = y;
781 dv.vertices[i].vertex[2] = 1.0;
782 dv.vertices[i].vertex[3] = 1.0;
785 rect = e_util_transform_vertices_to_rect(&dv);
787 if (dx) *dx = rect.x;
788 if (dy) *dy = rect.y;
789 if (dw) *dw = rect.w;
790 if (dh) *dh = rect.h;
804 _e_comp_object_map_damage_transform_get(E_Client *ec)
811 if (!e_client_transform_core_enable_get(ec))
814 m = e_client_map_get(ec);
818 e_pixmap_size_get(ec->pixmap, &bw, &bh);
819 if ((bw == 0) || (bh == 0))
832 e_map_point_coord_set(m2, 0, 0, 0, 0);
833 e_map_point_coord_set(m2, 1, bw, 0, 0);
834 e_map_point_coord_set(m2, 2, bw, bh, 0);
835 e_map_point_coord_set(m2, 3, 0, bh, 0);
837 for (i = 0; i < 4; i++)
841 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
842 e_map_point_image_uv_set(m2, i, map_x, map_y);
849 /////////////////////////////////////
851 /* handle evas mouse-in events on client object */
853 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
855 Evas_Event_Mouse_In *ev = event_info;
856 E_Comp_Object *cw = data;
858 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
861 /* handle evas mouse-out events on client object */
863 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
865 Evas_Event_Mouse_Out *ev = event_info;
866 E_Comp_Object *cw = data;
868 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
871 /* handle evas mouse wheel events on client object */
873 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
875 Evas_Event_Mouse_Wheel *ev = event_info;
876 E_Comp_Object *cw = data;
877 E_Binding_Event_Wheel ev2;
880 if (e_client_action_get()) return;
881 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
882 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
885 /* handle evas mouse down events on client object */
887 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
889 Evas_Event_Mouse_Down *ev = event_info;
890 E_Comp_Object *cw = data;
891 E_Binding_Event_Mouse_Button ev2;
894 if (e_client_action_get()) return;
895 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
896 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
899 /* handle evas mouse up events on client object */
901 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
903 Evas_Event_Mouse_Up *ev = event_info;
904 E_Comp_Object *cw = data;
905 E_Binding_Event_Mouse_Button ev2;
908 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
909 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
910 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
913 /* handle evas mouse movement events on client object */
915 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
917 Evas_Event_Mouse_Move *ev = event_info;
918 E_Comp_Object *cw = data;
921 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
922 e_client_mouse_move(cw->ec, &ev->cur.output);
924 /////////////////////////////////////
926 /* helper function for checking compositor themes based on user-defined matches */
928 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
930 if (((m->title) && (!ec->netwm.name)) ||
931 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
933 #if defined(__cplusplus) || defined(c_plusplus)
934 if (((m->clas) && (!ec->icccm.cpp_class)) ||
935 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
938 if (((m->clas) && (!ec->icccm.class)) ||
939 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
943 if (((m->role) && (!ec->icccm.window_role)) ||
944 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
950 if ((int)ec->netwm.type != m->primary_type)
953 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
956 if (m->borderless != 0)
960 if (e_client_util_borderless(ec))
962 if (!(((m->borderless == -1) && (!borderless)) ||
963 ((m->borderless == 1) && (borderless))))
970 if (((ec->icccm.transient_for != 0) ||
973 if (!(((m->dialog == -1) && (!dialog)) ||
974 ((m->dialog == 1) && (dialog))))
977 if (m->accepts_focus != 0)
979 int accepts_focus = 0;
981 if (ec->icccm.accepts_focus)
983 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
984 ((m->accepts_focus == 1) && (accepts_focus))))
993 if (!(((m->vkbd == -1) && (!vkbd)) ||
994 ((m->vkbd == 1) && (vkbd))))
999 if (!(((m->argb == -1) && (!ec->argb)) ||
1000 ((m->argb == 1) && (ec->argb))))
1003 if (m->fullscreen != 0)
1005 int fullscreen = ec->fullscreen;
1007 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
1008 ((m->fullscreen == 1) && (fullscreen))))
1013 if (!(m->modal == -1))
1019 /* function for setting up a client's compositor frame theme (cw->shobj) */
1021 _e_comp_object_shadow_setup(E_Comp_Object *cw)
1025 Eina_List *list = NULL, *l;
1026 E_Input_Rect_Data *input_rect_data;
1027 E_Input_Rect_Smart_Data *input_rect_sd;
1029 Eina_Stringshare *reshadow_group = NULL;
1030 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
1031 Eina_Stringshare *name, *title;
1032 E_Comp_Config *conf = e_comp_config_get();
1034 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
1035 /* match correct client type */
1036 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
1037 name = cw->ec->icccm.name;
1038 title = cw->ec->icccm.title;
1039 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
1040 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
1042 /* skipping here is mostly a hack for systray because I hate it */
1045 EINA_LIST_FOREACH(list, l, m)
1047 if (((m->name) && (!name)) ||
1048 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
1050 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
1053 no_shadow = m->no_shadow;
1054 if (m->shadow_style)
1056 /* fast effects are just themes with "/fast" appended and shorter effect times */
1059 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
1060 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1062 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1064 /* default to non-fast style if fast not available */
1067 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
1068 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1070 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1072 if (ok && m->visibility_effect)
1073 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
1080 if (skip || (cw->ec->e.state.video))
1082 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
1084 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
1087 if (conf->shadow_style)
1091 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
1092 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1094 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1098 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
1099 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
1101 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
1108 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
1110 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
1114 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
1116 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1121 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1126 if (cw->ec->override)
1128 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1129 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1131 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1132 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1138 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1139 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1142 _e_comp_object_shadow(cw);
1145 if (focus || cw->ec->focused || cw->ec->override)
1146 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1148 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1150 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1152 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1153 /* visibility must always be enabled for re_manage clients to prevent
1154 * pop-in animations every time the user sees a persistent client again;
1155 * applying visibility for iconic clients prevents the client from getting
1158 if (cw->visible || cw->ec->re_manage)
1159 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1161 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1163 /* breaks animation counter */
1164 if (cw->frame_object)
1166 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1167 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1168 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1169 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1175 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1179 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1182 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1184 if (input_rect_data->obj)
1186 pass_event_flag = EINA_TRUE;
1192 if (cw->indicator.obj)
1194 Evas_Object *indicator;
1195 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1196 if (indicator != cw->indicator.obj)
1198 edje_object_part_unswallow(cw->shobj, indicator);
1199 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1200 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1204 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1205 evas_object_pass_events_set(cw->obj, pass_event_flag);
1210 /////////////////////////////////////////////
1213 _e_comp_object_animating_begin(E_Comp_Object *cw)
1216 if (cw->animating == 1)
1218 e_comp->animating++;
1220 e_object_ref(E_OBJECT(cw->ec));
1225 _e_comp_object_animating_end(E_Comp_Object *cw)
1234 if (cw->ec->launching)
1236 if (!cw->ec->extra_animating)
1238 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1239 cw->ec->launching = EINA_FALSE;
1240 if (cw->ec->first_mapped)
1242 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1243 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1246 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1250 e_comp->animating--;
1251 cw->showing = cw->hiding = 0;
1253 if (e_comp->animating == 0)
1254 e_comp_visibility_calculation_set(EINA_TRUE);
1255 /* remove ref from animation start, account for possibility of deletion from unref */
1256 return !!e_object_unref(E_OBJECT(cw->ec));
1262 /* handle the end of a compositor animation */
1264 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1266 E_Comp_Object *cw = data;
1268 /* visible clients which have never been sized are a bug */
1269 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1270 CRI("ACK! ec:%p", cw->ec);
1271 if (!_e_comp_object_animating_end(cw)) return;
1272 if (cw->animating) return;
1273 /* hide only after animation finishes to guarantee a full run of the animation */
1274 if (!cw->defer_hide) return;
1275 if ((!strcmp(emission, "e,action,hide,done")) ||
1276 (!strcmp(emission, "e,action,done")) ||
1277 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1279 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1280 evas_object_hide(cw->smart_obj);
1284 /* run a visibility compositor effect if available, return false if object is dead */
1286 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1292 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1293 if (!cw->effect_running)
1294 _e_comp_object_animating_begin(cw);
1295 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1296 return _e_comp_object_animating_end(cw);
1297 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1298 return _e_comp_object_animating_end(cw);
1300 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1303 zone = e_comp_zone_find_by_ec(cw->ec);
1305 zw = zone->w, zh = zone->h;
1310 zone = e_comp_object_util_zone_get(cw->smart_obj);
1311 if (!zone) zone = e_zone_current_get();
1318 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1319 cw->w, cw->h, zw, zh, x, y}, 8);
1320 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1321 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1324 /////////////////////////////////////////////
1326 /* create necessary objects for clients that e manages */
1328 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1330 if (cw->set_mouse_callbacks) return;
1331 if (!cw->smart_obj) return;
1333 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1334 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1335 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1336 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1337 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1338 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1340 cw->set_mouse_callbacks = EINA_TRUE;
1344 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1346 if (!cw->set_mouse_callbacks) return;
1347 if (!cw->smart_obj) return;
1349 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1350 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1351 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1352 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1353 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1354 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1356 cw->set_mouse_callbacks = EINA_FALSE;
1360 _e_comp_object_setup(E_Comp_Object *cw)
1362 cw->clip = evas_object_rectangle_add(e_comp->evas);
1363 evas_object_move(cw->clip, -9999, -9999);
1364 evas_object_resize(cw->clip, 999999, 999999);
1365 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1366 cw->effect_obj = edje_object_add(e_comp->evas);
1367 evas_object_move(cw->effect_obj, cw->x, cw->y);
1368 evas_object_clip_set(cw->effect_obj, cw->clip);
1369 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1370 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1371 cw->shobj = edje_object_add(e_comp->evas);
1372 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1373 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1374 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1376 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1377 if (cw->ec->override)
1379 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1380 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1381 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1383 else if (!cw->ec->input_only)
1385 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1386 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1387 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1389 cw->real_hid = !cw->ec->input_only;
1390 if (!cw->ec->input_only)
1392 e_util_size_debug_set(cw->effect_obj, 1);
1393 _e_comp_object_mouse_event_callback_set(cw);
1396 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1397 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1398 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1399 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1400 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1401 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1403 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1406 /////////////////////////////////////////////
1408 /* for fast path evas rendering; only called during render */
1410 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1412 E_Comp_Object *cw = data;
1413 E_Client *ec = cw->ec;
1415 int bx, by, bxx, byy;
1417 if (e_object_is_del(E_OBJECT(ec))) return;
1418 if (cw->external_content) return;
1419 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1420 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1423 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1424 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1426 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1428 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1429 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1433 bx = by = bxx = byy = 0;
1434 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1437 Edje_Message_Int_Set *msg;
1438 Edje_Message_Int msg2;
1439 Eina_Bool id = (bx || by || bxx || byy);
1441 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1447 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1449 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1453 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1454 e_comp_client_post_update_add(cw->ec);
1456 else if (e_comp_object_render(ec->frame))
1458 /* apply shape mask if necessary */
1459 if ((!cw->native) && (ec->shaped))
1460 e_comp_object_shape_apply(ec->frame);
1462 /* shaped clients get precise mouse events to handle transparent pixels */
1463 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1465 /* queue another render if client is still dirty; cannot refresh here. */
1466 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1467 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1469 if (cw->render_trace)
1471 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1477 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1479 E_Comp_Object *cw = data;
1480 E_Client *ec = cw->ec;
1482 if (e_object_is_del(E_OBJECT(ec))) return;
1483 if (cw->external_content) return;
1484 if (!e_comp->hwc) return;
1486 e_comp_client_render_list_add(cw->ec);
1488 if (!ec->hwc_window) return;
1490 e_hwc_windows_rendered_window_add(ec->hwc_window);
1493 /////////////////////////////////////////////
1496 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1498 E_Comp_Object *cw = data;
1501 if (cw->render_update_lock.lock)
1503 cw->render_update_lock.pending_move_x = x;
1504 cw->render_update_lock.pending_move_y = y;
1505 cw->render_update_lock.pending_move_set = EINA_TRUE;
1509 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1510 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1511 (cw->external_content))
1513 /* delay to move until the external content is unset */
1514 cw->ec->changes.pos = 1;
1519 if (cw->ec->move_after_resize)
1521 if ((x != cw->ec->x) || (y != cw->ec->y))
1523 if (!cw->ec->is_cursor)
1524 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1525 e_client_pos_set(cw->ec, x, y);
1526 cw->ec->changes.pos = 1;
1532 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1533 (cw->ec->manage_resize.resize_obj))
1535 e_client_pos_set(cw->ec, x, y);
1536 cw->ec->client.x = x + cw->client_inset.l;
1537 cw->ec->client.y = y + cw->client_inset.t;
1538 e_policy_visibility_client_defer_move(cw->ec);
1542 /* if frame_object does not exist, client_inset indicates CSD.
1543 * this means that ec->client matches cw->x/y, the opposite
1546 fx = (!cw->frame_object) * cw->client_inset.l;
1547 fy = (!cw->frame_object) * cw->client_inset.t;
1548 if ((cw->x == x + fx) && (cw->y == y + fy))
1550 if ((cw->ec->x != x) || (cw->ec->y != y))
1552 /* handle case where client tries to move to position and back very quickly */
1553 e_client_pos_set(cw->ec, x, y);
1554 cw->ec->client.x = x + cw->client_inset.l;
1555 cw->ec->client.y = y + cw->client_inset.t;
1559 if (!cw->ec->maximize_override)
1561 /* prevent moving in some directions while directionally maximized */
1562 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1564 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1567 ix = x + cw->client_inset.l;
1568 iy = y + cw->client_inset.t;
1569 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1570 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1571 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1573 /* prevent moving at all if move isn't allowed in current maximize state */
1574 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1575 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1578 zone = e_comp_zone_find_by_ec(cw->ec);
1581 cw->ec->changes.need_unmaximize = 1;
1582 cw->ec->saved.x = ix - zone->x;
1583 cw->ec->saved.y = iy - zone->y;
1584 cw->ec->saved.w = cw->ec->client.w;
1585 cw->ec->saved.h = cw->ec->client.h;
1589 /* only update during resize if triggered by resize */
1590 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1591 /* delay to move while surface waits paired commit serial*/
1592 if (e_client_pending_geometry_has(cw->ec))
1594 /* do nothing while waiting paired commit serial*/
1598 e_client_pos_set(cw->ec, x, y);
1599 if (cw->ec->new_client)
1601 /* don't actually do anything until first client idler loop */
1602 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1603 cw->ec->changes.pos = 1;
1608 /* only update xy position of client to avoid invalid
1609 * first damage region if it is not a new_client. */
1610 cw->ec->client.x = ix;
1611 cw->ec->client.y = iy;
1614 if (!cw->frame_object)
1616 evas_object_move(obj, x, y);
1621 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1623 E_Comp_Object *cw = data;
1624 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1627 if (cw->render_update_lock.lock)
1629 cw->render_update_lock.pending_resize_w = w;
1630 cw->render_update_lock.pending_resize_h = h;
1631 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1635 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1637 e_client_size_set(cw->ec, w, h);
1638 evas_object_resize(obj, w, h);
1642 /* if frame_object does not exist, client_inset indicates CSD.
1643 * this means that ec->client matches cw->w/h, the opposite
1646 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1647 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1648 if ((cw->w == w + fw) && (cw->h == h + fh))
1650 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1651 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1652 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1654 /* handle case where client tries to resize itself and back very quickly */
1655 e_client_size_set(cw->ec, w, h);
1656 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1657 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1658 evas_object_smart_callback_call(obj, "client_resize", NULL);
1662 /* guarantee that fullscreen is fullscreen */
1663 zone = e_comp_zone_find_by_ec(cw->ec);
1665 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1667 if (!e_client_transform_core_enable_get(cw->ec))
1670 /* calculate client size */
1671 iw = w - cw->client_inset.l - cw->client_inset.r;
1672 ih = h - cw->client_inset.t - cw->client_inset.b;
1673 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1675 /* prevent resizing while maximized depending on direction and config */
1676 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1678 Eina_Bool reject = EINA_FALSE;
1679 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1681 if (cw->ec->client.h != ih)
1683 cw->ec->saved.h = ih;
1684 cw->ec->saved.y = cw->ec->client.y - zone->y;
1685 reject = cw->ec->changes.need_unmaximize = 1;
1688 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1690 if (cw->ec->client.w != iw)
1692 cw->ec->saved.w = iw;
1693 cw->ec->saved.x = cw->ec->client.x - zone->x;
1694 reject = cw->ec->changes.need_unmaximize = 1;
1703 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1705 /* do nothing until client idler loops */
1706 if ((cw->ec->w != w) || (cw->ec->h != h))
1708 e_client_size_set(cw->ec, w, h);
1709 cw->ec->changes.size = 1;
1714 if (e_client_pending_geometry_has(cw->ec))
1716 /* do nothing while waiting paired commit serial*/
1720 e_client_size_set(cw->ec, w, h);
1722 cw->ec->client.w = iw;
1723 cw->ec->client.h = ih;
1724 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1726 /* The size of non-compositing window can be changed, so there is a
1727 * need to check that cw is H/W composited if cw is not redirected.
1728 * And of course we have to change size of evas object of H/W composited cw,
1729 * otherwise cw can't receive input events even if it is shown on the screen.
1731 Eina_Bool redirected = cw->redirected;
1733 redirected = e_comp_is_on_overlay(cw->ec);
1735 if ((!cw->ec->input_only) && (redirected) &&
1736 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1737 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1738 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1739 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1742 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1743 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1745 prev_w = cw->w, prev_h = cw->h;
1746 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1747 /* check shading and clamp to pixmap size for regular clients */
1748 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1749 (((w - fw != pw) || (h - fh != ph))))
1751 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1752 evas_object_smart_callback_call(obj, "client_resize", NULL);
1754 if (cw->frame_object || cw->ec->input_only)
1755 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1758 if ((cw->w == w) && (cw->h == h))
1760 /* going to be a noop resize which won't trigger smart resize */
1761 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1762 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1764 evas_object_resize(obj, w, h);
1768 evas_object_smart_callback_call(obj, "client_resize", NULL);
1771 if ((!cw->frame_object) && (!cw->ec->input_only))
1773 /* "just do it" for overrides */
1774 evas_object_resize(obj, w, h);
1776 if (!cw->ec->override)
1778 /* shape probably changed for non-overrides */
1783 /* this fixes positioning jiggles when using a resize mode
1784 * which also changes the client's position
1787 if (cw->frame_object)
1788 x = cw->x, y = cw->y;
1790 x = cw->ec->x, y = cw->ec->y;
1791 switch (cw->ec->resize_mode)
1793 case E_POINTER_RESIZE_BL:
1794 case E_POINTER_RESIZE_L:
1795 evas_object_move(obj, x + prev_w - cw->w, y);
1797 case E_POINTER_RESIZE_TL:
1798 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1800 case E_POINTER_RESIZE_T:
1801 case E_POINTER_RESIZE_TR:
1802 evas_object_move(obj, x, y + prev_h - cw->h);
1811 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1813 #ifdef REFACTOR_DESK_AREA
1814 E_Comp_Object *cw = data;
1815 E_Comp_Object_Data_Set_Layer layer_set_data;
1817 layer_set_data.cw = cw;
1818 layer_set_data.layer = layer;
1820 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1824 e_comp_render_queue();
1825 _e_comp_object_transform_obj_stack_update(obj);
1829 E_Comp_Object *cw = data;
1830 E_Comp_Wl_Client_Data *child_cdata;
1831 unsigned int l = e_comp_canvas_layer_map(layer);
1834 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1836 /* doing a compositor effect, follow directions */
1837 _e_comp_object_layer_set(obj, layer);
1838 if (layer == cw->ec->layer) //trying to put layer back
1842 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1843 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1844 if (cw->layer != l) goto layer_set;
1848 e_comp_render_queue();
1850 ec = e_client_above_get(cw->ec);
1851 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1852 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1853 ec = e_client_above_get(ec);
1854 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1856 ec = e_client_below_get(cw->ec);
1857 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1858 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1859 ec = e_client_below_get(ec);
1860 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1862 evas_object_stack_above(obj, ec->frame);
1867 if (ec && (cw->ec->parent == ec))
1869 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1870 evas_object_stack_above(obj, ec->frame);
1872 evas_object_stack_below(obj, ec->frame);
1875 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1881 if (cw->layer == l) return;
1882 if (e_comp_canvas_client_layer_map(layer) == 9999)
1883 return; //invalid layer for clients not doing comp effects
1884 if (cw->ec->fullscreen)
1886 cw->ec->saved.layer = layer;
1889 oldraise = e_config->transient.raise;
1891 /* clamp to valid client layer */
1892 layer = e_comp_canvas_client_layer_map_nearest(layer);
1893 cw->ec->layer = layer;
1894 if (e_config->transient.layer)
1897 Eina_List *list = eina_list_clone(cw->ec->transients);
1899 /* We need to set raise to one, else the child wont
1900 * follow to the new layer. It should be like this,
1901 * even if the user usually doesn't want to raise
1904 e_config->transient.raise = 1;
1905 EINA_LIST_FREE(list, child)
1907 child_cdata = e_client_cdata_get(child);
1908 if (child_cdata && !child_cdata->mapped)
1910 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1913 e_client_layer_set(child, layer);
1917 e_config->transient.raise = oldraise;
1919 _e_comp_object_layers_remove(cw);
1920 cw->layer = e_comp_canvas_layer_map(layer);
1921 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1922 //if (cw->ec->new_client)
1923 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1924 _e_comp_object_layer_set(obj, layer);
1925 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1926 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1927 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1929 /* can't stack a client above its own layer marker */
1930 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1932 if (!cw->visible) return;
1933 e_comp_render_queue();
1934 _e_comp_object_transform_obj_stack_update(obj);
1938 #ifdef REFACTOR_DESK_AREA
1940 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1943 #ifdef REFACTOR_DESK_AREA
1945 _e_comp_object_raise(Evas_Object *obj)
1948 _e_comp_object_raise(Evas_Object *obj)
1951 evas_object_raise(obj);
1953 if (evas_object_smart_smart_get(obj))
1955 E_Client *ec = e_comp_object_client_get(obj);
1957 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1961 #ifdef REFACTOR_DESK_AREA
1963 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1966 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1969 evas_object_lower(obj);
1971 if (evas_object_smart_smart_get(obj))
1973 E_Client *ec = e_comp_object_client_get(obj);
1976 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1977 #ifdef REFACTOR_DESK_AREA
1978 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1980 wl_signal_emit_mutable(&cw->events.lower, NULL);
1986 #ifdef REFACTOR_DESK_AREA
1988 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1991 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1994 evas_object_stack_above(obj, target);
1996 if (evas_object_smart_smart_get(obj))
1998 E_Client *ec = e_comp_object_client_get(obj);
2000 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2004 #ifdef REFACTOR_DESK_AREA
2006 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2009 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
2012 evas_object_stack_below(obj, target);
2014 if (evas_object_smart_smart_get(obj))
2016 E_Client *ec = e_comp_object_client_get(obj);
2018 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
2022 #ifdef REFACTOR_DESK_AREA
2024 e_comp_object_layer_set(Evas_Object *obj, short layer)
2027 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2030 evas_object_layer_set(obj, layer);
2032 if (evas_object_smart_smart_get(obj))
2034 E_Client *ec = e_comp_object_client_get(obj);
2036 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2040 #ifdef REFACTOR_DESK_AREA
2043 _e_comp_object_is_pending(E_Client *ec)
2047 if (!ec) return EINA_FALSE;
2049 topmost = e_comp_wl_topmost_parent_get(ec);
2051 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2055 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2057 E_Comp_Object *cw2 = NULL;
2060 Evas_Object *o = stack;
2061 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2063 /* We should consider topmost's layer_pending for subsurface */
2064 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2066 if (_e_comp_object_is_pending(cw->ec))
2067 e_comp_object_layer_update(cw->smart_obj,
2068 raising? stack : NULL,
2069 raising? NULL : stack);
2071 /* obey compositor effects! */
2072 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2073 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2074 stack_cb(cw->smart_obj, stack);
2075 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2076 evas_object_data_del(cw->smart_obj, "client_restack");
2080 cw2 = evas_object_data_get(o, "comp_obj");
2082 /* assume someone knew what they were doing during client init */
2083 if (cw->ec->new_client)
2084 layer = cw->ec->layer;
2085 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2086 layer = cw2->ec->layer;
2088 layer = evas_object_layer_get(stack);
2089 ecstack = e_client_below_get(cw->ec);
2090 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2092 evas_object_layer_set(cw->smart_obj, layer);
2093 /* we got our layer wrangled, return now! */
2094 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2097 /* check if we're stacking below another client */
2100 /* check for non-client layer object */
2101 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2103 /* find an existing client to use for layering
2104 * by walking up the object stack
2106 * this is guaranteed to be pretty quick since we'll either:
2107 * - run out of client layers
2108 * - find a stacking client
2110 o = evas_object_above_get(o);
2111 if ((!o) || (o == cw->smart_obj)) break;
2112 if (evas_object_layer_get(o) != layer)
2114 /* reached the top client layer somehow
2115 * use top client object
2117 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2120 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2121 * return here since the top client layer window
2126 ec = e_client_top_get();
2131 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2134 if (cw2 && cw->layer != cw2->layer)
2137 /* remove existing layers */
2138 _e_comp_object_layers_remove(cw);
2141 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2142 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2143 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2144 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2145 else //if no stacking objects found, either raise or lower
2146 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2149 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2151 /* find new object for stacking if cw2 is on state of layer_pending */
2152 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2154 E_Client *new_stack = NULL, *current_ec = NULL;
2155 current_ec = cw2->ec;
2158 while ((new_stack = e_client_below_get(current_ec)))
2160 current_ec = new_stack;
2161 if (new_stack == cw->ec) continue;
2162 if (new_stack->layer != cw2->ec->layer) break;
2163 if (!_e_comp_object_is_pending(new_stack)) break;
2165 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2166 stack = new_stack->frame;
2169 /* stack it above layer object */
2171 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2172 stack = e_comp->layers[below_layer].obj;
2177 while ((new_stack = e_client_above_get(current_ec)))
2179 current_ec = new_stack;
2180 if (new_stack == cw->ec) continue;
2181 if (new_stack->layer != cw2->ec->layer) break;
2182 if (!_e_comp_object_is_pending(new_stack)) break;
2184 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2185 stack = new_stack->frame;
2187 stack = e_comp->layers[cw2->layer].obj;
2191 /* set restack if stacking has changed */
2192 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2193 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2194 stack_cb(cw->smart_obj, stack);
2195 if (e_comp->layers[cw->layer].obj)
2196 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2198 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2200 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2201 evas_object_data_del(cw->smart_obj, "client_restack");
2202 if (!cw->visible) return;
2203 e_comp_render_queue();
2208 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2210 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2212 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2214 #ifdef REFACTOR_DESK_AREA
2215 E_Comp_Object *cw = data;
2216 E_Comp_Object_Data_Stack_Above stack_above_data;
2218 stack_above_data.cw = cw;
2219 stack_above_data.above_obj = above;
2221 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2223 if (evas_object_below_get(obj) == above)
2225 e_comp_object_layer_update(obj, above, NULL);
2229 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2231 _e_comp_object_transform_obj_stack_update(obj);
2232 _e_comp_object_transform_obj_stack_update(above);
2239 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2241 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2243 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2245 #ifdef REFACTOR_DESK_AREA
2246 E_Comp_Object *cw = data;
2247 E_Comp_Object_Data_Stack_Below stack_below_data;
2249 stack_below_data.cw = cw;
2250 stack_below_data.below_obj = below;
2252 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2255 e_comp_render_queue();
2257 if (evas_object_above_get(obj) == below)
2259 e_comp_object_layer_update(obj, NULL, below);
2263 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2265 if (evas_object_smart_smart_get(obj))
2266 _e_comp_object_transform_obj_stack_update(obj);
2267 if (evas_object_smart_smart_get(below))
2268 _e_comp_object_transform_obj_stack_update(below);
2275 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2277 E_Comp_Object *cw = data;
2279 #ifdef REFACTOR_DESK_AREA
2284 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2286 #ifdef REFACTOR_DESK_AREA
2287 wl_signal_emit_mutable(&cw->events.lower, cw);
2289 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2291 if (cw->ec->layer_pending)
2292 e_comp_object_layer_update(obj, NULL, obj);
2294 _e_comp_object_lower(cw, obj);
2297 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2298 o = evas_object_below_get(obj);
2299 _e_comp_object_layers_remove(cw);
2300 /* prepend to client list since this client should be the first item now */
2301 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2302 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2303 evas_object_data_set(obj, "client_restack", (void*)1);
2304 _e_comp_object_lower(cw, obj);
2305 evas_object_data_del(obj, "client_restack");
2306 if (!cw->visible) goto end;
2307 e_comp_render_queue();
2308 _e_comp_object_transform_obj_stack_update(obj);
2316 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2318 E_Comp_Object *cw = data;
2319 #ifdef REFACTOR_DESK_AREA
2325 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2327 #ifdef REFACTOR_DESK_AREA
2328 wl_signal_emit_mutable(&cw->events.raise, cw);
2330 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2332 if (cw->ec->layer_pending)
2334 int obj_layer = evas_object_layer_get(obj);
2335 if (cw->ec->layer != obj_layer)
2336 e_comp_object_layer_update(obj, NULL, NULL);
2339 _e_comp_object_raise(obj);
2342 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2343 o = evas_object_above_get(obj);
2344 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2346 /* still stack below override below the layer marker */
2347 for (op = o = e_comp->layers[cw->layer].obj;
2348 o && o != e_comp->layers[cw->layer - 1].obj;
2349 op = o, o = evas_object_below_get(o))
2351 if (evas_object_smart_smart_get(o))
2355 ec = e_comp_object_client_get(o);
2356 if (ec && (!ec->override)) break;
2359 _e_comp_object_stack_below(obj, op);
2360 e_client_focus_defer_set(cw->ec);
2362 if (!cw->visible) goto end;
2363 e_comp_render_queue();
2364 _e_comp_object_transform_obj_stack_update(obj);
2372 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2374 E_Comp_Object *cw = data;
2376 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2377 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2379 ELOGF("COMP", "Hide. intercepted", cw->ec);
2384 if (cw->ec->launching == EINA_TRUE)
2386 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2387 cw->ec->launching = EINA_FALSE;
2392 /* hidden flag = just do it */
2393 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2394 evas_object_hide(obj);
2396 wl_signal_emit_mutable(&cw->events.hide, NULL);
2401 if (cw->ec->input_only)
2403 /* input_only = who cares */
2404 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2405 evas_object_hide(obj);
2407 wl_signal_emit_mutable(&cw->events.hide, NULL);
2411 /* already hidden or currently animating */
2412 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2414 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2418 /* don't try hiding during shutdown */
2419 cw->defer_hide |= stopping;
2420 if (!cw->defer_hide)
2422 if ((!cw->ec->iconic) && (!cw->ec->override))
2423 /* unset delete requested so the client doesn't break */
2424 cw->ec->delete_requested = 0;
2425 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2427 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2428 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2431 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2434 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2436 _e_comp_object_animating_begin(cw);
2437 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2439 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2440 cw->defer_hide = !!cw->animating;
2442 e_comp_object_effect_set(obj, NULL);
2445 if (cw->animating) return;
2446 /* if we have no animations running, go ahead and hide */
2448 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2449 evas_object_hide(obj);
2451 wl_signal_emit_mutable(&cw->events.hide, NULL);
2455 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2457 E_Client *ec = cw->ec;
2460 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2462 if (ec->show_pending.count > 0)
2464 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2465 ec->show_pending.running = EINA_TRUE;
2469 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2470 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2472 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2477 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,
2478 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2479 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2482 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2485 if (ec->iconic && cw->animating)
2487 /* triggered during iconify animation */
2488 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2491 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2494 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2495 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2497 evas_object_move(cw->smart_obj, ec->x, ec->y);
2498 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2499 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2501 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2502 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2505 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2506 evas_object_show(cw->smart_obj);
2509 e_client_focus_defer_set(ec);
2513 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2517 pw = ec->client.w, ph = ec->client.h;
2519 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2521 ec->changes.visible = !ec->hidden;
2524 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2528 cw->updates = eina_tiler_new(pw, ph);
2531 ec->changes.visible = !ec->hidden;
2534 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2539 eina_tiler_tile_size_set(cw->updates, 1, 1);
2542 /* ignore until client idler first run */
2543 ec->changes.visible = !ec->hidden;
2546 ELOGF("COMP", "show_helper. return. new_client", ec);
2553 evas_object_move(cw->smart_obj, ec->x, ec->y);
2554 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2555 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2556 evas_object_show(cw->smart_obj);
2559 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2561 /* start_drag not received */
2562 ec->changes.visible = 1;
2565 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2568 /* re-set geometry */
2569 evas_object_move(cw->smart_obj, ec->x, ec->y);
2570 /* force resize in case it hasn't happened yet, or just to update size */
2571 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2572 if ((cw->w < 1) || (cw->h < 1))
2574 /* if resize didn't go through, try again */
2575 ec->visible = ec->changes.visible = 1;
2577 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2580 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2581 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2582 e_pixmap_clear(ec->pixmap);
2584 if (cw->real_hid && w && h)
2587 /* force comp theming in case it didn't happen already */
2588 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2589 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2590 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2593 /* only do the show if show is allowed */
2596 if (ec->internal) //internal clients render when they feel like it
2597 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2599 if (!e_client_is_iconified_by_client(ec)||
2600 e_policy_visibility_client_is_uniconic(ec))
2602 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2603 evas_object_show(cw->smart_obj);
2605 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2606 it is rendered in idle callback without native surface and
2607 compositor shows an empty frame if other objects aren't shown
2608 because job callback of e_comp called at the next loop.
2609 it causes a visual defect when windows are switched.
2613 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2614 e_comp_object_dirty(cw->smart_obj);
2615 e_comp_object_render(cw->smart_obj);
2620 wl_signal_emit_mutable(&cw->events.show, NULL);
2624 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2626 E_Comp_Object *cw = data;
2627 E_Client *ec = cw->ec;
2629 E_Input_Rect_Data *input_rect_data;
2630 E_Input_Rect_Smart_Data *input_rect_sd;
2633 if (ec->ignored) return;
2637 //INF("SHOW2 %p", ec);
2638 _e_comp_intercept_show_helper(cw);
2641 //INF("SHOW %p", ec);
2644 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2645 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2646 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2647 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2651 if ((!cw->obj) && (cw->external_content))
2653 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2657 _e_comp_object_setup(cw);
2660 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2661 cw->obj = evas_object_image_filled_add(e_comp->evas);
2662 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2663 e_util_size_debug_set(cw->obj, 1);
2664 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2665 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2666 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2667 evas_object_name_set(cw->obj, "cw->obj");
2668 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2670 _e_comp_object_alpha_set(cw);
2673 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2676 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2677 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2680 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2683 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2685 if (input_rect_data->obj)
2687 evas_object_geometry_set(input_rect_data->obj,
2688 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2689 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2690 input_rect_data->rect.w, input_rect_data->rect.h);
2697 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2699 _e_comp_intercept_show_helper(cw);
2703 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2705 E_Comp_Object *cw = data;
2709 /* note: this is here as it seems there are enough apps that do not even
2710 * expect us to emulate a look of focus but not actually set x input
2711 * focus as we do - so simply abort any focus set on such windows */
2712 /* be strict about accepting focus hint */
2713 /* be strict about accepting focus hint */
2714 if ((!ec->icccm.accepts_focus) &&
2715 (!ec->icccm.take_focus))
2719 if (e_client_focused_get() == ec)
2720 e_client_focused_set(NULL);
2722 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2723 evas_object_focus_set(obj, focus);
2727 if (focus && ec->lock_focus_out) return;
2728 if (e_object_is_del(E_OBJECT(ec)) && focus)
2729 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2731 /* filter focus setting based on current state */
2736 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2737 evas_object_focus_set(obj, focus);
2740 if ((ec->iconic) && (!ec->deskshow))
2742 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2744 /* don't focus an iconified window. that's silly! */
2745 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2746 e_client_uniconify(ec);
2747 e_client_focus_latest_set(ec);
2761 /* not yet visible, wait till the next time... */
2762 ec->want_focus = !ec->hidden;
2767 e_client_focused_set(ec);
2771 if (e_client_focused_get() == ec)
2772 e_client_focused_set(NULL);
2776 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2778 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2780 evas_object_focus_set(obj, focus);
2784 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2786 E_Comp_Object *cw = data;
2788 if (cw->transparent.set)
2790 cw->transparent.user_r = r;
2791 cw->transparent.user_g = g;
2792 cw->transparent.user_b = b;
2793 cw->transparent.user_a = a;
2795 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2797 cw->transparent.user_r,
2798 cw->transparent.user_g,
2799 cw->transparent.user_b,
2800 cw->transparent.user_a);
2804 evas_object_color_set(obj, r, g, b, a);
2807 ////////////////////////////////////////////////////
2810 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2812 int w, h, ox, oy, ow, oh;
2814 Eina_Bool pass_event_flag = EINA_FALSE;
2815 E_Input_Rect_Data *input_rect_data;
2816 E_Input_Rect_Smart_Data *input_rect_sd;
2818 if (cw->frame_object)
2820 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2821 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2822 /* set a fixed size, force edje calc, check size difference */
2823 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2824 edje_object_message_signal_process(cw->frame_object);
2825 edje_object_calc_force(cw->frame_object);
2826 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2827 cw->client_inset.l = ox;
2828 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2829 cw->client_inset.t = oy;
2830 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2831 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2832 evas_object_resize(cw->frame_object, w, h);
2836 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2839 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2841 if (input_rect_data->obj)
2843 pass_event_flag = EINA_TRUE;
2849 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2850 evas_object_pass_events_set(cw->obj, pass_event_flag);
2854 cw->client_inset.l = 0;
2855 cw->client_inset.r = 0;
2856 cw->client_inset.t = 0;
2857 cw->client_inset.b = 0;
2859 cw->client_inset.calc = !!cw->frame_object;
2863 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2865 E_Comp_Object *cw = data;
2869 /* - get current size
2871 * - readjust for new frame size
2874 w = cw->ec->w, h = cw->ec->h;
2875 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2877 _e_comp_object_frame_recalc(cw);
2879 if (!cw->ec->fullscreen)
2880 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2882 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2883 if (cw->ec->fullscreen)
2885 zone = e_comp_zone_find_by_ec(cw->ec);
2887 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2889 else if (cw->ec->new_client)
2891 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2892 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2893 evas_object_resize(cw->ec->frame, w, h);
2895 else if ((w != cw->ec->w) || (h != cw->ec->h))
2896 evas_object_resize(cw->ec->frame, w, h);
2900 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2902 E_Comp_Object *cw = data;
2904 _e_comp_object_shadow_setup(cw);
2905 if (cw->frame_object)
2907 _e_comp_object_shadow(cw);
2908 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2909 _e_comp_object_frame_recalc(cw);
2910 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2915 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2917 E_Comp_Object *cw = data;
2919 if (_e_comp_object_shadow_setup(cw))
2920 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2921 if (cw->frame_object)
2923 _e_comp_object_shadow(cw);
2924 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2925 _e_comp_object_frame_recalc(cw);
2926 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2931 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2933 E_Comp_Object *cw = data;
2935 if (cw->frame_object)
2937 _e_comp_object_shadow(cw);
2938 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2939 _e_comp_object_frame_recalc(cw);
2940 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2945 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2947 E_Comp_Object *cw = data;
2949 if (_e_comp_object_shadow_setup(cw))
2952 cw->ec->changes.size = 1;
2954 if (cw->frame_object)
2956 _e_comp_object_shadow(cw);
2957 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2958 _e_comp_object_frame_recalc(cw);
2959 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2964 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2966 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2970 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2972 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2976 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2978 E_Comp_Object *cw = data;
2980 if (!cw->ec) return; //NYI
2981 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2985 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2987 E_Comp_Object *cw = data;
2989 if (!cw->ec) return; //NYI
2990 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2994 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2996 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3000 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3002 E_Comp_Object *cw = data;
3004 if (!e_object_is_del(E_OBJECT(cw->ec)))
3005 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3009 _e_comp_input_obj_smart_add(Evas_Object *obj)
3011 E_Input_Rect_Smart_Data *input_rect_sd;
3012 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3014 if (!input_rect_sd) return;
3015 evas_object_smart_data_set(obj, input_rect_sd);
3019 _e_comp_input_obj_smart_del(Evas_Object *obj)
3021 E_Input_Rect_Smart_Data *input_rect_sd;
3022 E_Input_Rect_Data *input_rect_data;
3024 input_rect_sd = evas_object_smart_data_get(obj);
3025 if (!input_rect_sd) return;
3027 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3029 if (input_rect_data->obj)
3031 evas_object_smart_member_del(input_rect_data->obj);
3032 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3034 E_FREE(input_rect_data);
3036 E_FREE(input_rect_sd);
3040 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3042 E_Input_Rect_Smart_Data *input_rect_sd;
3043 E_Input_Rect_Data *input_rect_data;
3047 input_rect_sd = evas_object_smart_data_get(obj);
3048 if (!input_rect_sd) return;
3050 cw = input_rect_sd->cw;
3051 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3053 if (input_rect_data->obj)
3055 evas_object_geometry_set(input_rect_data->obj,
3056 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3057 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3058 input_rect_data->rect.w, input_rect_data->rect.h);
3064 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3066 E_Input_Rect_Smart_Data *input_rect_sd;
3067 E_Input_Rect_Data *input_rect_data;
3071 input_rect_sd = evas_object_smart_data_get(obj);
3072 if (!input_rect_sd) return;
3074 cw = input_rect_sd->cw;
3075 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3077 if (input_rect_data->obj)
3079 evas_object_geometry_set(input_rect_data->obj,
3080 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3081 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3082 input_rect_data->rect.w, input_rect_data->rect.h);
3088 _e_comp_input_obj_smart_show(Evas_Object *obj)
3090 E_Input_Rect_Smart_Data *input_rect_sd;
3091 E_Input_Rect_Data *input_rect_data;
3094 input_rect_sd = evas_object_smart_data_get(obj);
3095 if (!input_rect_sd) return;
3097 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3099 if (input_rect_data->obj)
3101 evas_object_show(input_rect_data->obj);
3107 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3109 E_Input_Rect_Smart_Data *input_rect_sd;
3110 E_Input_Rect_Data *input_rect_data;
3113 input_rect_sd = evas_object_smart_data_get(obj);
3114 if (!input_rect_sd) return;
3116 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3118 if (input_rect_data->obj)
3120 evas_object_hide(input_rect_data->obj);
3126 _e_comp_input_obj_smart_init(void)
3128 if (_e_comp_input_obj_smart) return;
3130 static const Evas_Smart_Class sc =
3132 INPUT_OBJ_SMART_NAME,
3133 EVAS_SMART_CLASS_VERSION,
3134 _e_comp_input_obj_smart_add,
3135 _e_comp_input_obj_smart_del,
3136 _e_comp_input_obj_smart_move,
3137 _e_comp_input_obj_smart_resize,
3138 _e_comp_input_obj_smart_show,
3139 _e_comp_input_obj_smart_hide,
3152 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3158 _e_comp_smart_add(Evas_Object *obj)
3162 cw = E_NEW(E_Comp_Object, 1);
3163 EINA_SAFETY_ON_NULL_RETURN(cw);
3165 wl_signal_init(&cw->events.lower);
3166 #ifdef REFACTOR_DESK_AREA
3167 wl_signal_init(&cw->events.lower_done);
3168 wl_signal_init(&cw->events.raise);
3170 wl_signal_init(&cw->events.show);
3171 wl_signal_init(&cw->events.hide);
3172 #ifdef REFACTOR_DESK_AREA
3173 wl_signal_init(&cw->events.set_layer);
3174 wl_signal_init(&cw->events.stack_above);
3175 wl_signal_init(&cw->events.stack_below);
3178 cw->smart_obj = obj;
3179 cw->x = cw->y = cw->w = cw->h = -1;
3180 evas_object_smart_data_set(obj, cw);
3181 cw->opacity = 255.0;
3182 cw->external_content = 0;
3183 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3184 cw->transform_bg_color.r = 0;
3185 cw->transform_bg_color.g = 0;
3186 cw->transform_bg_color.b = 0;
3187 cw->transform_bg_color.a = 255;
3188 evas_object_data_set(obj, "comp_obj", cw);
3189 evas_object_move(obj, -1, -1);
3190 /* intercept ALL the callbacks! */
3191 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3192 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3193 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3194 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3195 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3196 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3197 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3198 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3199 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3200 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3201 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3203 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3204 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3205 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3206 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3208 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3209 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3211 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3212 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3214 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3216 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3217 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3221 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3224 evas_object_color_set(cw->clip, r, g, b, a);
3225 evas_object_smart_callback_call(obj, "color_set", NULL);
3230 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3233 evas_object_clip_set(cw->clip, clip);
3237 _e_comp_smart_clip_unset(Evas_Object *obj)
3240 evas_object_clip_unset(cw->clip);
3244 _e_comp_smart_hide(Evas_Object *obj)
3246 TRACE_DS_BEGIN(COMP:SMART HIDE);
3251 evas_object_hide(cw->clip);
3252 if (cw->input_obj) evas_object_hide(cw->input_obj);
3253 evas_object_hide(cw->effect_obj);
3254 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3255 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3256 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3263 /* unset native surface if current displaying buffer was destroied */
3264 if (!cw->buffer_destroy_listener.notify)
3266 Evas_Native_Surface *ns;
3267 ns = evas_object_image_native_surface_get(cw->obj);
3268 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3269 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3272 if (!cw->ec->input_only)
3274 edje_object_freeze(cw->effect_obj);
3275 edje_object_freeze(cw->shobj);
3276 edje_object_play_set(cw->shobj, 0);
3277 if (cw->frame_object)
3278 edje_object_play_set(cw->frame_object, 0);
3281 e_comp_render_queue(); //force nocomp recheck
3287 _e_comp_smart_show(Evas_Object *obj)
3295 if ((cw->w < 0) || (cw->h < 0))
3296 CRI("ACK! ec:%p", cw->ec);
3298 TRACE_DS_BEGIN(COMP:SMART SHOW);
3300 e_comp_object_map_update(obj);
3302 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3303 evas_object_show(tmp->frame);
3305 evas_object_show(cw->clip);
3306 if (cw->input_obj) evas_object_show(cw->input_obj);
3307 if (!cw->ec->input_only)
3309 edje_object_thaw(cw->effect_obj);
3310 edje_object_thaw(cw->shobj);
3311 edje_object_play_set(cw->shobj, 1);
3312 if (cw->frame_object)
3313 edje_object_play_set(cw->frame_object, 1);
3315 evas_object_show(cw->effect_obj);
3316 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3317 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3318 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3319 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3320 e_comp_render_queue();
3321 if (cw->ec->input_only)
3326 if (cw->ec->iconic && (!cw->ec->new_client))
3328 if (e_client_is_iconified_by_client(cw->ec))
3330 ELOGF("COMP", "Set launching flag..", cw->ec);
3331 cw->ec->launching = EINA_TRUE;
3334 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3336 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3339 ELOGF("COMP", "Set launching flag..", cw->ec);
3340 cw->ec->launching = EINA_TRUE;
3342 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3343 _e_comp_object_animating_begin(cw);
3344 if (!_e_comp_object_effect_visibility_start(cw, 1))
3350 /* ensure some random effect doesn't lock the client offscreen */
3354 e_comp_object_effect_set(obj, NULL);
3357 _e_comp_object_dim_update(cw);
3363 _e_comp_smart_del(Evas_Object *obj)
3369 if (cw->buffer_destroy_listener.notify)
3371 wl_list_remove(&cw->buffer_destroy_listener.link);
3372 cw->buffer_destroy_listener.notify = NULL;
3375 if (cw->tbm_surface)
3377 tbm_surface_internal_unref(cw->tbm_surface);
3378 cw->tbm_surface = NULL;
3381 if (cw->render_update_lock.buffer_ref.buffer)
3383 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3384 cw->ec, cw->render_update_lock.lock);
3385 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3388 e_comp_object_render_update_del(cw->smart_obj);
3389 E_FREE_FUNC(cw->updates, eina_tiler_free);
3390 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3397 EINA_LIST_FREE(cw->obj_mirror, o)
3399 evas_object_image_data_set(o, NULL);
3400 evas_object_freeze_events_set(o, 1);
3401 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3405 #ifdef REFACTOR_DESK_AREA
3407 _e_comp_object_layers_remove(cw);
3409 l = evas_object_data_get(obj, "comp_object-to_del");
3410 E_FREE_LIST(l, evas_object_del);
3411 _e_comp_object_mouse_event_callback_unset(cw);
3412 evas_object_del(cw->clip);
3413 evas_object_del(cw->obj);
3414 evas_object_del(cw->shobj);
3415 evas_object_del(cw->effect_obj);
3416 evas_object_del(cw->frame_object);
3417 evas_object_del(cw->input_obj);
3418 evas_object_del(cw->mask.obj);
3419 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3420 evas_object_del(cw->transform_bg_obj);
3421 evas_object_del(cw->transform_tranp_obj);
3422 evas_object_del(cw->default_input_obj);
3423 eina_stringshare_del(cw->frame_theme);
3424 eina_stringshare_del(cw->frame_name);
3428 e_comp->animating--;
3430 e_object_unref(E_OBJECT(cw->ec));
3432 cw->ec->frame = NULL;
3437 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3441 cw->x = x, cw->y = y;
3442 evas_object_move(cw->effect_obj, x, y);
3443 evas_object_move(cw->default_input_obj, x, y);
3444 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3446 e_comp_object_map_update(obj);
3450 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3452 Eina_Bool first = EINA_FALSE;
3457 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3459 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3461 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3463 if (cw->w != w || cw->h != h)
3464 e_comp_object_map_update(obj);
3466 first = ((cw->w < 1) || (cw->h < 1));
3467 cw->w = w, cw->h = h;
3471 if (cw->frame_object)
3472 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3475 /* verify pixmap:object size */
3476 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3478 if ((ww != pw) || (hh != ph))
3479 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3481 evas_object_resize(cw->effect_obj, tw, th);
3482 evas_object_resize(cw->default_input_obj, w, h);
3484 evas_object_resize(cw->input_obj, w, h);
3486 evas_object_resize(cw->mask.obj, w, h);
3487 /* resize render update tiler */
3490 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3491 cw->updates_full = 0;
3492 if (cw->updates) eina_tiler_clear(cw->updates);
3496 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3497 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3505 e_comp_render_queue();
3511 _e_comp_smart_init(void)
3513 if (_e_comp_smart) return;
3515 static const Evas_Smart_Class sc =
3518 EVAS_SMART_CLASS_VERSION,
3522 _e_comp_smart_resize,
3525 _e_comp_smart_color_set,
3526 _e_comp_smart_clip_set,
3527 _e_comp_smart_clip_unset,
3537 _e_comp_smart = evas_smart_class_new(&sc);
3542 e_comp_object_init(void)
3544 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3545 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3546 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3547 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3551 e_comp_object_shutdown(void)
3557 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3559 API_ENTRY EINA_FALSE;
3560 return !!cw->force_visible;
3562 /////////////////////////////////////////////////////////
3565 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3568 Eina_Bool comp_object;
3570 comp_object = !!evas_object_data_get(obj, "comp_object");
3575 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3577 e_comp_render_queue();
3579 l = evas_object_data_get(obj, "comp_object-to_del");
3580 E_FREE_LIST(l, evas_object_del);
3584 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3586 if (e_comp_util_object_is_above_nocomp(obj) &&
3587 (!evas_object_data_get(obj, "comp_override")))
3589 evas_object_data_set(obj, "comp_override", (void*)1);
3590 e_comp_override_add();
3595 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3597 Eina_Bool ref = EINA_TRUE;
3598 if (evas_object_visible_get(obj))
3602 d = evas_object_data_del(obj, "comp_hiding");
3604 /* currently trying to hide */
3607 /* already visible */
3611 evas_object_show(obj);
3614 evas_object_ref(obj);
3615 evas_object_data_set(obj, "comp_ref", (void*)1);
3617 edje_object_signal_emit(obj, "e,state,visible", "e");
3618 evas_object_data_set(obj, "comp_showing", (void*)1);
3619 if (e_comp_util_object_is_above_nocomp(obj))
3621 evas_object_data_set(obj, "comp_override", (void*)1);
3622 e_comp_override_add();
3627 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3629 if (!evas_object_visible_get(obj)) return;
3630 /* already hiding */
3631 if (evas_object_data_get(obj, "comp_hiding")) return;
3632 if (!evas_object_data_del(obj, "comp_showing"))
3634 evas_object_ref(obj);
3635 evas_object_data_set(obj, "comp_ref", (void*)1);
3637 edje_object_signal_emit(obj, "e,state,hidden", "e");
3638 evas_object_data_set(obj, "comp_hiding", (void*)1);
3640 if (evas_object_data_del(obj, "comp_override"))
3641 e_comp_override_timed_pop();
3645 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3647 if (!e_util_strcmp(emission, "e,action,hide,done"))
3649 if (!evas_object_data_del(obj, "comp_hiding")) return;
3650 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3651 evas_object_hide(obj);
3652 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3655 evas_object_data_del(obj, "comp_showing");
3656 if (evas_object_data_del(obj, "comp_ref"))
3657 evas_object_unref(obj);
3661 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3667 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3671 E_API E_Comp_Object_Hook *
3672 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3674 E_Comp_Object_Hook *ch;
3676 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3677 ch = E_NEW(E_Comp_Object_Hook, 1);
3678 if (!ch) return NULL;
3679 ch->hookpoint = hookpoint;
3681 ch->data = (void*)data;
3682 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3687 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3690 if (_e_comp_object_hooks_walking == 0)
3692 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3696 _e_comp_object_hooks_delete++;
3699 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3700 E_API E_Comp_Object_Intercept_Hook *
3701 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3703 E_Comp_Object_Intercept_Hook *ch;
3705 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3706 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3707 if (!ch) return NULL;
3708 ch->hookpoint = hookpoint;
3710 ch->data = (void*)data;
3711 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3716 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3719 if (_e_comp_object_intercept_hooks_walking == 0)
3721 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3725 _e_comp_object_intercept_hooks_delete++;
3730 e_comp_object_util_add(Evas_Object *obj)
3734 E_Comp_Config *conf = e_comp_config_get();
3735 Eina_Bool skip = EINA_FALSE;
3741 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3743 name = evas_object_name_get(obj);
3744 vis = evas_object_visible_get(obj);
3745 o = edje_object_add(e_comp->evas);
3746 evas_object_data_set(o, "comp_object", (void*)1);
3748 skip = (!strncmp(name, "noshadow", 8));
3750 evas_object_data_set(o, "comp_object_skip", (void*)1);
3752 if (conf->shadow_style)
3754 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3755 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3758 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3759 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3760 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3762 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3764 evas_object_geometry_get(obj, &x, &y, &w, &h);
3765 evas_object_geometry_set(o, x, y, w, h);
3766 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3768 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3770 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3771 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3772 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3773 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3774 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3775 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3777 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3779 edje_object_part_swallow(o, "e.swallow.content", obj);
3781 _e_comp_object_event_add(o);
3784 evas_object_show(o);
3789 /* utility functions for deleting objects when their "owner" is deleted */
3791 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3796 EINA_SAFETY_ON_NULL_RETURN(to_del);
3797 l = evas_object_data_get(obj, "comp_object-to_del");
3798 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3799 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3800 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3804 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3809 EINA_SAFETY_ON_NULL_RETURN(to_del);
3810 l = evas_object_data_get(obj, "comp_object-to_del");
3812 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3815 /////////////////////////////////////////////////////////
3817 EINTERN Evas_Object *
3818 e_comp_object_client_add(E_Client *ec)
3823 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3824 if (ec->frame) return NULL;
3825 _e_comp_smart_init();
3826 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3827 cw = evas_object_smart_data_get(o);
3828 if (!cw) return NULL;
3829 evas_object_data_set(o, "E_Client", ec);
3832 evas_object_data_set(o, "comp_object", (void*)1);
3834 _e_comp_object_event_add(o);
3839 /* utility functions for getting client inset */
3841 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3844 if (!cw->client_inset.calc)
3850 if (ax) *ax = x - cw->client_inset.l;
3851 if (ay) *ay = y - cw->client_inset.t;
3855 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3858 if (!cw->client_inset.calc)
3864 if (ax) *ax = x + cw->client_inset.l;
3865 if (ay) *ay = y + cw->client_inset.t;
3869 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3872 if (!cw->client_inset.calc)
3878 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3879 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3883 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3886 if (!cw->client_inset.calc)
3892 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3893 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3897 e_comp_object_client_get(Evas_Object *obj)
3902 /* FIXME: remove this when eo is used */
3903 o = evas_object_data_get(obj, "comp_smart_obj");
3905 return e_comp_object_client_get(o);
3906 return cw ? cw->ec : NULL;
3910 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3913 if (cw->frame_extends)
3914 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3919 if (w) *w = cw->ec->w;
3920 if (h) *h = cw->ec->h;
3925 e_comp_object_util_zone_get(Evas_Object *obj)
3927 E_Zone *zone = NULL;
3931 zone = e_comp_zone_find_by_ec(cw->ec);
3936 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3937 zone = e_comp_zone_xy_get(x, y);
3943 e_comp_object_util_center(Evas_Object *obj)
3945 int x, y, w, h, ow, oh;
3950 zone = e_comp_object_util_zone_get(obj);
3951 EINA_SAFETY_ON_NULL_RETURN(zone);
3952 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3953 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3954 ow = cw->ec->w, oh = cw->ec->h;
3956 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3957 x = x + (w - ow) / 2;
3958 y = y + (h - oh) / 2;
3959 evas_object_move(obj, x, y);
3963 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3965 int x, y, w, h, ow, oh;
3968 EINA_SAFETY_ON_NULL_RETURN(on);
3969 evas_object_geometry_get(on, &x, &y, &w, &h);
3970 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3971 ow = cw->ec->w, oh = cw->ec->h;
3973 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3974 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3978 e_comp_object_util_fullscreen(Evas_Object *obj)
3983 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3986 evas_object_move(obj, 0, 0);
3987 evas_object_resize(obj, e_comp->w, e_comp->h);
3992 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4000 ow = cw->w, oh = cw->h;
4002 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4003 zone = e_comp_object_util_zone_get(obj);
4004 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4005 if (x) *x = zx + (zw - ow) / 2;
4006 if (y) *y = zy + (zh - oh) / 2;
4010 e_comp_object_input_objs_del(Evas_Object *obj)
4013 E_Input_Rect_Data *input_rect_data;
4014 E_Input_Rect_Smart_Data *input_rect_sd;
4019 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4020 if (!input_rect_sd) return;
4022 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4024 if (input_rect_data->obj)
4026 evas_object_smart_member_del(input_rect_data->obj);
4027 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4029 E_FREE(input_rect_data);
4034 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4037 E_Input_Rect_Data *input_rect_data = NULL;
4038 E_Input_Rect_Smart_Data *input_rect_sd;
4039 int client_w, client_h;
4041 if (cw->ec->client.w)
4042 client_w = cw->ec->client.w;
4044 client_w = cw->ec->w;
4046 if (cw->ec->client.h)
4047 client_h = cw->ec->client.h;
4049 client_h = cw->ec->h;
4051 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4055 _e_comp_input_obj_smart_init();
4056 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4057 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4058 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4061 input_rect_sd->cw = cw;
4064 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4067 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4068 if (input_rect_data)
4070 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4071 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4075 if ((input_rect_data) &&
4076 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4078 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4079 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4080 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4081 evas_object_clip_set(input_rect_data->obj, cw->clip);
4082 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4083 evas_object_geometry_set(input_rect_data->obj,
4084 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4085 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4086 evas_object_pass_events_set(cw->default_input_obj, 1);
4087 evas_object_pass_events_set(cw->obj, 1);
4090 evas_object_show(input_rect_data->obj);
4091 evas_object_show(cw->input_obj);
4096 evas_object_smart_member_del(cw->input_obj);
4097 E_FREE_FUNC(cw->input_obj, evas_object_del);
4098 evas_object_pass_events_set(cw->default_input_obj, 0);
4099 evas_object_pass_events_set(cw->obj, 0);
4104 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4107 E_Input_Rect_Smart_Data *input_rect_sd;
4108 E_Input_Rect_Data *input_rect_data;
4111 if (!cw->input_obj) return;
4113 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4116 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4118 *list = eina_list_append(*list, &input_rect_data->rect);
4124 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4127 if (l) *l = cw->client_inset.l;
4128 if (r) *r = cw->client_inset.r;
4129 if (t) *t = cw->client_inset.t;
4130 if (b) *b = cw->client_inset.b;
4133 /* set geometry for CSD */
4135 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4141 if (cw->frame_object)
4142 CRI("ACK! ec:%p", cw->ec);
4143 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4144 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4145 calc = cw->client_inset.calc;
4146 cw->client_inset.calc = l || r || t || b;
4147 eina_stringshare_replace(&cw->frame_theme, "borderless");
4148 if (cw->client_inset.calc)
4150 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4151 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4152 e_client_size_set(cw->ec, tw, th);
4154 else if (cw->ec->maximized || cw->ec->fullscreen)
4156 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4157 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4159 if (!cw->ec->new_client)
4161 if (calc && cw->client_inset.calc)
4163 tx = cw->ec->x - (l - cw->client_inset.l);
4164 ty = cw->ec->y - (t - cw->client_inset.t);
4165 e_client_pos_set(cw->ec, tx, ty);
4167 cw->ec->changes.pos = cw->ec->changes.size = 1;
4170 cw->client_inset.l = l;
4171 cw->client_inset.r = r;
4172 cw->client_inset.t = t;
4173 cw->client_inset.b = b;
4177 e_comp_object_frame_allowed(Evas_Object *obj)
4179 API_ENTRY EINA_FALSE;
4180 return (cw->frame_object || (!cw->client_inset.calc));
4184 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4186 API_ENTRY EINA_FALSE;
4187 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4188 eina_stringshare_replace(&cw->frame_name, name);
4189 if (cw->frame_object)
4190 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4195 e_comp_object_frame_exists(Evas_Object *obj)
4197 API_ENTRY EINA_FALSE;
4198 return !!cw->frame_object;
4202 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4204 Evas_Object *o, *pbg;
4207 Eina_Stringshare *theme;
4209 API_ENTRY EINA_FALSE;
4211 if (!e_util_strcmp(cw->frame_theme, name))
4212 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4213 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4214 return _e_comp_object_shadow_setup(cw);
4215 pbg = cw->frame_object;
4216 theme = eina_stringshare_add(name);
4218 if (cw->frame_object)
4222 w = cw->ec->w, h = cw->ec->h;
4223 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4224 if ((cw->ec->w != w) || (cw->ec->h != h))
4226 cw->ec->changes.size = 1;
4229 E_FREE_FUNC(cw->frame_object, evas_object_del);
4230 if (!name) goto reshadow;
4232 o = edje_object_add(e_comp->evas);
4233 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4234 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4235 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4237 cw->frame_object = NULL;
4239 eina_stringshare_del(cw->frame_theme);
4240 cw->frame_theme = theme;
4245 if (theme != e_config->theme_default_border_style)
4247 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4248 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4252 ok = e_theme_edje_object_set(o, "base/theme/border",
4253 "e/widgets/border/default/border");
4254 if (ok && (theme == e_config->theme_default_border_style))
4256 /* Reset default border style to default */
4257 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4258 e_config_save_queue();
4265 cw->frame_object = o;
4266 eina_stringshare_del(cw->frame_theme);
4267 cw->frame_theme = theme;
4268 evas_object_name_set(o, "cw->frame_object");
4271 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4275 cw->ec->changes.icon = 1;
4281 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4286 _e_comp_object_shadow_setup(cw);
4289 int old_x, old_y, new_x = 0, new_y = 0;
4291 old_x = cw->x, old_y = cw->y;
4293 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4295 new_x = cw->ec->x, new_y = cw->ec->y;
4296 else if (cw->ec->placed || (!cw->ec->new_client))
4298 /* if no previous frame:
4299 * - reapply client_inset
4304 if (cw->ec->changes.size)
4312 zone = e_comp_zone_find_by_ec(cw->ec);
4315 x = cw->ec->client.x, y = cw->ec->client.y;
4316 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4317 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4319 new_x = x, new_y = y;
4322 if (old_x != new_x || old_y != new_y)
4324 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4325 cw->y = cw->x = -99999;
4326 evas_object_move(obj, new_x, new_y);
4330 if (cw->ec->maximized)
4332 cw->ec->changes.need_maximize = 1;
4335 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4336 if (cw->frame_object)
4338 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4341 cw->frame_extends = 0;
4342 evas_object_del(pbg);
4347 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4349 E_Comp_Object_Mover *prov;
4352 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4353 edje_object_signal_emit(cw->shobj, sig, src);
4354 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4355 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4356 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4358 /* start with highest priority callback first */
4359 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4361 if (!e_util_glob_match(sig, prov->sig)) continue;
4362 if (prov->func(prov->data, obj, sig)) break;
4367 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4369 /* FIXME: at some point I guess this should use eo to inherit
4370 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4371 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4374 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4378 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4381 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4385 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4388 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4392 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4395 Eina_Rectangle rect;
4398 if (cw->ec->input_only || (!cw->updates)) return;
4399 if (cw->nocomp) return;
4400 rect.x = x, rect.y = y;
4401 rect.w = w, rect.h = h;
4402 evas_object_smart_callback_call(obj, "damage", &rect);
4404 if (e_comp_is_on_overlay(cw->ec))
4406 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4407 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4408 * E module attempts to block screen update due to the particular policy.
4410 if (e_pixmap_resource_get(cw->ec->pixmap))
4411 cw->hwc_need_update = EINA_TRUE;
4414 /* ignore overdraw */
4415 if (cw->updates_full)
4417 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4418 e_comp_object_render_update_add(obj);
4420 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4421 evas_object_show(cw->smart_obj);
4425 /* clip rect to client surface */
4426 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4427 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4428 /* if rect is the total size of the client after clip, clear the updates
4429 * since this is guaranteed to be the whole region anyway
4431 eina_tiler_area_size_get(cw->updates, &tw, &th);
4432 if ((w > tw) || (h > th))
4434 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4435 eina_tiler_clear(cw->updates);
4436 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4438 tw = cw->ec->client.w, th = cw->ec->client.h;
4440 if ((!x) && (!y) && (w == tw) && (h == th))
4442 eina_tiler_clear(cw->updates);
4443 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4444 cw->updates_full = 1;
4445 cw->update_count = 0;
4448 if (cw->update_count > UPDATE_MAX)
4450 /* this is going to get really dumb, so just update the whole thing */
4451 eina_tiler_clear(cw->updates);
4452 cw->update_count = cw->updates_full = 1;
4453 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4454 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4458 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4459 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4461 cw->updates_exist = 1;
4462 e_comp_object_render_update_add(obj);
4464 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4465 evas_object_show(cw->smart_obj);
4469 e_comp_object_damage_exists(Evas_Object *obj)
4471 API_ENTRY EINA_FALSE;
4472 return cw->updates_exist;
4476 e_comp_object_render_update_add(Evas_Object *obj)
4480 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4481 if (cw->render_update_lock.lock) return;
4482 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4486 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4488 e_comp_render_queue();
4492 e_comp_object_render_update_del(Evas_Object *obj)
4496 if (cw->ec->input_only || (!cw->updates)) return;
4497 if (!cw->update) return;
4499 /* this gets called during comp animating to clear the update flag */
4500 if (e_comp->grabbed) return;
4501 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4502 if (!e_comp->updates)
4504 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4505 if (e_comp->render_animator)
4506 ecore_animator_freeze(e_comp->render_animator);
4511 e_comp_object_shape_apply(Evas_Object *obj)
4515 unsigned int i, *pix, *p;
4519 if (!cw->ec) return; //NYI
4520 if (cw->external_content) return;
4523 if ((cw->ec->shape_rects_num >= 1) &&
4524 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4529 ERR("BUGGER: shape with native surface? cw=%p", cw);
4532 evas_object_image_size_get(cw->obj, &w, &h);
4533 if ((w < 1) || (h < 1)) return;
4536 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4537 _e_comp_object_alpha_set(cw);
4538 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4539 evas_object_image_alpha_set(o, 1);
4541 p = pix = evas_object_image_data_get(cw->obj, 1);
4544 evas_object_image_data_set(cw->obj, pix);
4549 unsigned char *spix, *sp;
4551 spix = calloc(w * h, sizeof(unsigned char));
4553 for (i = 0; i < cw->ec->shape_rects_num; i++)
4557 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4558 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4559 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4560 sp = spix + (w * ry) + rx;
4561 for (py = 0; py < rh; py++)
4563 for (px = 0; px < rw; px++)
4571 for (py = 0; py < h; py++)
4573 for (px = 0; px < w; px++)
4575 unsigned int mask, imask;
4577 mask = ((unsigned int)(*sp)) << 24;
4579 imask |= imask >> 8;
4580 imask |= imask >> 8;
4581 *p = mask | (*p & imask);
4582 //if (*sp) *p = 0xff000000 | *p;
4583 //else *p = 0x00000000;
4592 for (py = 0; py < h; py++)
4594 for (px = 0; px < w; px++)
4598 evas_object_image_data_set(cw->obj, pix);
4599 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4600 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4602 evas_object_image_data_set(o, pix);
4603 evas_object_image_data_update_add(o, 0, 0, w, h);
4605 // don't need to fix alpha chanel as blending
4606 // should be totally off here regardless of
4607 // alpha channel content
4611 _e_comp_object_clear(E_Comp_Object *cw)
4616 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4618 if (cw->render_update_lock.lock) return;
4621 e_pixmap_clear(cw->ec->pixmap);
4623 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4624 evas_object_image_size_set(cw->obj, 1, 1);
4625 evas_object_image_data_set(cw->obj, NULL);
4626 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4628 evas_object_image_size_set(o, 1, 1);
4629 evas_object_image_data_set(o, NULL);
4632 e_comp_object_render_update_del(cw->smart_obj);
4636 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4640 API_ENTRY EINA_FALSE;
4642 if (cw->transparent.set == set)
4647 evas_object_color_get(obj, &r, &g, &b, &a);
4648 evas_object_color_set(obj, 0, 0, 0, 0);
4650 cw->transparent.user_r = r;
4651 cw->transparent.user_g = g;
4652 cw->transparent.user_b = b;
4653 cw->transparent.user_a = a;
4655 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4657 cw->transparent.user_r,
4658 cw->transparent.user_g,
4659 cw->transparent.user_b,
4660 cw->transparent.user_a);
4662 cw->transparent.set = EINA_TRUE;
4666 cw->transparent.set = EINA_FALSE;
4668 evas_object_color_set(obj,
4669 cw->transparent.user_r,
4670 cw->transparent.user_g,
4671 cw->transparent.user_b,
4672 cw->transparent.user_a);
4674 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4676 cw->transparent.user_r,
4677 cw->transparent.user_g,
4678 cw->transparent.user_b,
4679 cw->transparent.user_a);
4685 /* helper function to simplify toggling of redirection for display servers which support it */
4687 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4692 if (cw->redirected == set) return;
4693 cw->redirected = set;
4694 if (cw->external_content) return;
4696 e_comp_object_map_update(obj);
4700 if (cw->updates_exist)
4701 e_comp_object_render_update_add(obj);
4703 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4705 _e_comp_object_transparent_set(obj, EINA_FALSE);
4706 evas_object_smart_callback_call(obj, "redirected", NULL);
4710 _e_comp_object_clear(cw);
4711 _e_comp_object_transparent_set(obj, EINA_TRUE);
4712 evas_object_smart_callback_call(obj, "unredirected", NULL);
4717 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4720 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4722 if (cw->buffer_destroy_listener.notify)
4724 cw->buffer_destroy_listener.notify = NULL;
4725 wl_list_remove(&cw->buffer_destroy_listener.link);
4728 if (e_object_is_del(E_OBJECT(cw->ec)))
4730 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4735 /* if it's current displaying buffer, do not remove its content */
4736 if (!evas_object_visible_get(cw->ec->frame))
4737 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4742 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4747 if (cw->buffer_destroy_listener.notify)
4749 wl_list_remove(&cw->buffer_destroy_listener.link);
4750 cw->buffer_destroy_listener.notify = NULL;
4753 if (cw->tbm_surface)
4755 tbm_surface_internal_unref(cw->tbm_surface);
4756 cw->tbm_surface = NULL;
4761 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4763 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4764 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4766 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4768 tbm_surface_internal_ref(ns->data.tbm.buffer);
4769 cw->tbm_surface = ns->data.tbm.buffer;
4773 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4774 evas_object_image_native_surface_set(cw->obj, ns);
4778 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4780 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4781 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4782 evas_object_image_native_surface_set(o, ns);
4789 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4791 Evas_Native_Surface ns;
4794 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4795 if (cw->ec->input_only) return;
4796 if (cw->external_content) return;
4797 if (cw->render_update_lock.lock) return;
4800 memset(&ns, 0, sizeof(Evas_Native_Surface));
4804 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4805 set = (!cw->ec->shaped);
4807 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4811 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4815 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4818 if (cw->ec->input_only) return;
4821 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4822 _e_comp_object_alpha_set(cw);
4824 e_comp_object_native_surface_set(obj, cw->native);
4825 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4829 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4835 if (cw->blanked == set) return;
4837 _e_comp_object_alpha_set(cw);
4840 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4841 evas_object_image_data_set(cw->obj, NULL);
4845 e_comp_object_native_surface_set(obj, 1);
4846 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4850 _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)
4855 if (!_damage_trace) return;
4859 if (!evas_object_visible_get(cw->obj)) return;
4861 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4863 o = evas_object_rectangle_add(e_comp->evas);
4864 evas_object_layer_set(o, E_LAYER_MAX);
4865 evas_object_name_set(o, "damage_trace");
4866 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4867 evas_object_resize(o, dmg_w, dmg_h);
4868 evas_object_color_set(o, 0, 128, 0, 128);
4869 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4870 evas_object_pass_events_set(o, EINA_TRUE);
4871 evas_object_show(o);
4873 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4875 dmg_w, dmg_h, dmg_x, dmg_y,
4876 origin->w, origin->h, origin->x, origin->y);
4878 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4881 /* mark an object as dirty and setup damages */
4883 e_comp_object_dirty(Evas_Object *obj)
4886 Eina_Rectangle *rect;
4890 Eina_Bool dirty, visible;
4894 if (cw->external_content) return;
4895 if (!cw->redirected) return;
4896 if (cw->render_update_lock.lock)
4898 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4901 /* only actually dirty if pixmap is available */
4902 if (!e_pixmap_resource_get(cw->ec->pixmap))
4904 // e_pixmap_size_get returns last attached buffer size
4905 // eventhough it is destroyed
4906 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4909 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4910 visible = cw->visible;
4911 if (!dirty) w = h = 1;
4912 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4914 evas_object_image_data_set(cw->obj, NULL);
4915 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4916 evas_object_image_size_set(cw->obj, tw, th);
4917 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4918 if (cw->pending_updates)
4919 eina_tiler_area_size_set(cw->pending_updates, w, h);
4920 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4922 evas_object_image_pixels_dirty_set(o, dirty);
4924 evas_object_image_data_set(o, NULL);
4925 evas_object_image_size_set(o, tw, th);
4926 visible |= evas_object_visible_get(o);
4930 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4934 e_comp_object_native_surface_set(obj, 1);
4936 m = _e_comp_object_map_damage_transform_get(cw->ec);
4937 it = eina_tiler_iterator_new(cw->updates);
4938 EINA_ITERATOR_FOREACH(it, rect)
4940 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4941 * of evas engine and doesn't convert damage according to evas_map.
4942 * so damage of evas_object_image use surface coordinate.
4946 int damage_x, damage_y, damage_w, damage_h;
4948 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4949 &damage_x, &damage_y, &damage_w, &damage_h);
4950 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4951 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4955 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4956 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4959 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4960 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4961 if (cw->pending_updates)
4962 eina_tiler_rect_add(cw->pending_updates, rect);
4964 eina_iterator_free(it);
4965 if (m) e_map_free(m);
4966 if (cw->pending_updates)
4967 eina_tiler_clear(cw->updates);
4970 cw->pending_updates = cw->updates;
4971 cw->updates = eina_tiler_new(w, h);
4972 eina_tiler_tile_size_set(cw->updates, 1, 1);
4974 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4975 evas_object_smart_callback_call(obj, "dirty", NULL);
4976 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4977 /* force render if main object is hidden but mirrors are visible */
4978 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4979 e_comp_object_render(obj);
4983 e_comp_object_render(Evas_Object *obj)
4990 API_ENTRY EINA_FALSE;
4992 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4993 if (cw->ec->input_only) return EINA_TRUE;
4994 if (cw->external_content) return EINA_TRUE;
4995 if (cw->native) return EINA_FALSE;
4996 /* if comp object is not redirected state, comp object should not be set by newly committed data
4997 because image size of comp object is 1x1 and it should not be shown on canvas */
4998 if (!cw->redirected) return EINA_TRUE;
4999 if (cw->render_update_lock.lock)
5001 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5004 e_comp_object_render_update_del(obj);
5005 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5007 if (!cw->pending_updates)
5009 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5010 evas_object_image_data_set(cw->obj, NULL);
5011 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5012 evas_object_image_data_set(o, NULL);
5016 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5018 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5020 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5023 e_pixmap_image_refresh(cw->ec->pixmap);
5024 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5027 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5028 e_pixmap_image_data_ref(cw->ec->pixmap);
5030 /* set pixel data */
5031 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5032 _e_comp_object_alpha_set(cw);
5033 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5035 evas_object_image_data_set(o, pix);
5036 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5037 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5040 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5042 e_comp_client_post_update_add(cw->ec);
5047 /* create a duplicate of an evas object */
5049 e_comp_object_util_mirror_add(Evas_Object *obj)
5053 unsigned int *pix = NULL;
5054 Eina_Bool argb = EINA_FALSE;
5059 cw = evas_object_data_get(obj, "comp_mirror");
5062 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5063 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5064 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5065 evas_object_image_alpha_set(o, 1);
5066 evas_object_image_source_set(o, obj);
5069 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5070 if (cw->external_content)
5072 ERR("%p of client %p is external content.", obj, cw->ec);
5075 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5076 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5077 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5078 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5079 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5080 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5081 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5082 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5083 evas_object_data_set(o, "comp_mirror", cw);
5085 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5086 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5088 evas_object_image_size_set(o, tw, th);
5091 pix = evas_object_image_data_get(cw->obj, 0);
5097 evas_object_image_native_surface_set(o, cw->ns);
5100 Evas_Native_Surface ns;
5101 memset(&ns, 0, sizeof(Evas_Native_Surface));
5102 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5103 evas_object_image_native_surface_set(o, &ns);
5108 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5109 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5111 (e_pixmap_image_exists(cw->ec->pixmap)))
5112 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5114 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5121 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5122 evas_object_image_pixels_dirty_set(o, dirty);
5123 evas_object_image_data_set(o, pix);
5124 evas_object_image_data_set(cw->obj, pix);
5126 evas_object_image_data_update_add(o, 0, 0, tw, th);
5131 //////////////////////////////////////////////////////
5134 e_comp_object_effect_allowed_get(Evas_Object *obj)
5136 API_ENTRY EINA_FALSE;
5138 if (!cw->shobj) return EINA_FALSE;
5139 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5140 return !e_comp_config_get()->match.disable_borders;
5143 /* setup an api effect for a client */
5145 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5148 Eina_Stringshare *grp;
5149 E_Comp_Config *config;
5150 Eina_Bool loaded = EINA_FALSE;
5152 API_ENTRY EINA_FALSE;
5153 if (!cw->shobj) return EINA_FALSE; //input window
5155 if (!effect) effect = "none";
5156 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5158 config = e_comp_config_get();
5159 if ((config) && (config->effect_file))
5161 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5163 cw->effect_set = EINA_TRUE;
5170 edje_object_file_get(cw->effect_obj, NULL, &grp);
5171 cw->effect_set = !eina_streq(effect, "none");
5172 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5173 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5175 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5176 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5177 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5179 if (cw->effect_running)
5181 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5184 cw->effect_set = EINA_FALSE;
5185 return cw->effect_set;
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 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5195 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5196 if (cw->effect_clip)
5198 evas_object_clip_unset(cw->clip);
5199 cw->effect_clip = 0;
5201 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5203 _e_comp_object_dim_update(cw);
5205 return cw->effect_set;
5208 /* set params for embryo scripts in effect */
5210 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5212 Edje_Message_Int_Set *msg;
5216 EINA_SAFETY_ON_NULL_RETURN(params);
5217 EINA_SAFETY_ON_FALSE_RETURN(count);
5218 if (!cw->effect_set) return;
5220 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5221 msg->count = (int)count;
5222 for (x = 0; x < count; x++)
5223 msg->val[x] = params[x];
5224 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5225 edje_object_message_signal_process(cw->effect_obj);
5229 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5231 Edje_Signal_Cb end_cb;
5233 E_Comp_Object *cw = data;
5235 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5236 cw->effect_running = 0;
5237 if (!_e_comp_object_animating_end(cw)) return;
5239 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5241 evas_object_data_del(cw->smart_obj, "effect_running");
5242 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5243 e_comp_visibility_calculation_set(EINA_TRUE);
5246 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5247 if (!end_cb) return;
5248 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5249 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5250 end_cb(end_data, cw->smart_obj, emission, source);
5253 /* clip effect to client's zone */
5255 e_comp_object_effect_clip(Evas_Object *obj)
5259 zone = e_comp_zone_find_by_ec(cw->ec);
5261 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5262 if (!cw->effect_clip_able) return;
5263 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5264 cw->effect_clip = 1;
5267 /* unclip effect from client's zone */
5269 e_comp_object_effect_unclip(Evas_Object *obj)
5272 if (!cw->effect_clip) return;
5273 evas_object_clip_unset(cw->smart_obj);
5274 cw->effect_clip = 0;
5277 /* start effect, running end_cb after */
5279 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5281 API_ENTRY EINA_FALSE;
5282 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5283 if (!cw->effect_set) return EINA_FALSE;
5285 if (cw->effect_running)
5287 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5290 e_comp_object_effect_clip(obj);
5291 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5293 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5294 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5295 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5296 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5298 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5299 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5301 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5302 _e_comp_object_animating_begin(cw);
5303 cw->effect_running = 1;
5307 /* stop a currently-running effect immediately */
5309 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5312 Edje_Signal_Cb end_cb_before = NULL;
5313 void *end_data_before = NULL;
5314 API_ENTRY EINA_FALSE;
5316 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5317 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5319 if (end_cb_before != end_cb) return EINA_TRUE;
5320 e_comp_object_effect_unclip(obj);
5321 if (cw->effect_clip)
5323 evas_object_clip_unset(cw->effect_obj);
5324 cw->effect_clip = 0;
5326 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5327 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5329 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5331 evas_object_data_del(cw->smart_obj, "effect_running");
5332 e_comp_visibility_calculation_set(EINA_TRUE);
5335 cw->effect_running = 0;
5336 ret = _e_comp_object_animating_end(cw);
5338 if ((ret) && (end_cb_before))
5340 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5341 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5348 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5350 return a->pri - b->pri;
5353 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5354 E_API E_Comp_Object_Mover *
5355 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5357 E_Comp_Object_Mover *prov;
5359 prov = E_NEW(E_Comp_Object_Mover, 1);
5360 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5361 prov->func = provider;
5362 prov->data = (void*)data;
5365 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5366 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5371 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5373 EINA_SAFETY_ON_NULL_RETURN(prov);
5374 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5379 e_comp_object_effect_object_get(Evas_Object *obj)
5383 return cw->effect_obj;
5387 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5389 API_ENTRY EINA_FALSE;
5390 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5391 if (!cw->effect_set) return EINA_FALSE;
5398 ////////////////////////////////////
5401 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5403 if (e_comp->autoclose.obj)
5405 e_comp_ungrab_input(0, 1);
5406 if (e_comp->autoclose.del_cb)
5407 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5408 else if (!already_del)
5410 evas_object_hide(e_comp->autoclose.obj);
5411 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5413 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5415 e_comp->autoclose.obj = NULL;
5416 e_comp->autoclose.data = NULL;
5417 e_comp->autoclose.del_cb = NULL;
5418 e_comp->autoclose.key_cb = NULL;
5419 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5423 _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)
5425 _e_comp_object_autoclose_cleanup(0);
5429 _e_comp_object_autoclose_setup(Evas_Object *obj)
5431 if (!e_comp->autoclose.rect)
5433 /* create rect just below autoclose object to catch mouse events */
5434 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5435 evas_object_move(e_comp->autoclose.rect, 0, 0);
5436 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5437 evas_object_show(e_comp->autoclose.rect);
5438 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5439 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5440 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5441 e_comp_grab_input(0, 1);
5443 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5444 evas_object_focus_set(obj, 1);
5448 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5450 _e_comp_object_autoclose_setup(obj);
5451 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5455 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5457 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5458 _e_comp_object_autoclose_cleanup(1);
5459 if (e_client_focused_get()) return;
5461 E_Zone *zone = e_zone_current_get();
5464 e_zone_focus_reset(zone);
5468 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5472 if (e_comp->autoclose.obj)
5474 if (e_comp->autoclose.obj == obj) return;
5475 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5476 e_comp->autoclose.obj = obj;
5477 e_comp->autoclose.del_cb = del_cb;
5478 e_comp->autoclose.key_cb = cb;
5479 e_comp->autoclose.data = (void*)data;
5480 if (evas_object_visible_get(obj))
5481 _e_comp_object_autoclose_setup(obj);
5483 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5484 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5487 e_comp->autoclose.obj = obj;
5488 e_comp->autoclose.del_cb = del_cb;
5489 e_comp->autoclose.key_cb = cb;
5490 e_comp->autoclose.data = (void*)data;
5491 if (evas_object_visible_get(obj))
5492 _e_comp_object_autoclose_setup(obj);
5494 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5495 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5499 e_comp_object_is_animating(Evas_Object *obj)
5503 return cw->animating;
5507 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5511 if ((cw->external_content) &&
5512 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5514 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5515 "But current external content is %d object for %p.",
5516 cw->content_type, cw->ec);
5520 cw->user_alpha_set = EINA_TRUE;
5521 cw->user_alpha = alpha;
5523 if (!cw->obj) return;
5525 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5527 evas_object_image_alpha_set(cw->obj, alpha);
5529 if ((!cw->native) && (!cw->external_content))
5530 evas_object_image_data_set(cw->obj, NULL);
5534 e_comp_object_alpha_get(Evas_Object *obj)
5536 API_ENTRY EINA_FALSE;
5538 return evas_object_image_alpha_get(cw->obj);
5542 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5544 Eina_Bool mask_set = EINA_FALSE;
5548 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5549 if (cw->ec->input_only) return;
5556 o = evas_object_rectangle_add(e_comp->evas);
5557 evas_object_color_set(o, 0, 0, 0, 0);
5558 evas_object_clip_set(o, cw->clip);
5559 evas_object_smart_member_add(o, obj);
5560 evas_object_move(o, 0, 0);
5561 evas_object_resize(o, cw->w, cw->h);
5562 /* save render op value to restore when clear a mask.
5564 * NOTE: DO NOT change the render op on ec->frame while mask object
5565 * is set. it will overwrite the changed op value. */
5566 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5567 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5568 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5569 if (cw->visible) evas_object_show(o);
5572 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5573 ELOGF("COMP", " |mask_obj", cw->ec);
5574 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5581 evas_object_smart_member_del(cw->mask.obj);
5582 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5584 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5585 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5591 e_comp_object_mask_has(Evas_Object *obj)
5593 API_ENTRY EINA_FALSE;
5595 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5599 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5604 if ((cw->external_content) &&
5605 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5607 WRN("Can set up size to ONLY evas \"image\" object. "
5608 "But current external content is %d object for %p.",
5609 cw->content_type, cw->ec);
5613 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5615 evas_object_image_size_set(cw->obj, tw, th);
5619 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5621 Eina_Bool transform_set = EINA_FALSE;
5623 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5624 if (cw->ec->input_only) return;
5626 transform_set = !!set;
5630 if (!cw->transform_bg_obj)
5632 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5633 evas_object_move(o, 0, 0);
5634 evas_object_resize(o, 1, 1);
5635 if (cw->transform_bg_color.a >= 255)
5636 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5638 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5639 evas_object_color_set(o,
5640 cw->transform_bg_color.r,
5641 cw->transform_bg_color.g,
5642 cw->transform_bg_color.b,
5643 cw->transform_bg_color.a);
5644 if (cw->visible) evas_object_show(o);
5646 cw->transform_bg_obj = o;
5647 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5649 _e_comp_object_transform_obj_stack_update(obj);
5653 if (cw->transform_bg_obj)
5655 evas_object_smart_member_del(cw->transform_bg_obj);
5656 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5662 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5666 cw->transform_bg_color.r = r;
5667 cw->transform_bg_color.g = g;
5668 cw->transform_bg_color.b = b;
5669 cw->transform_bg_color.a = a;
5671 if (cw->transform_bg_obj)
5673 evas_object_color_set(cw->transform_bg_obj,
5674 cw->transform_bg_color.r,
5675 cw->transform_bg_color.g,
5676 cw->transform_bg_color.b,
5677 cw->transform_bg_color.a);
5682 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5685 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5686 if (cw->ec->input_only) return;
5687 if (!cw->transform_bg_obj) return;
5689 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5693 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5696 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5697 if (cw->ec->input_only) return;
5698 if (!cw->transform_bg_obj) return;
5700 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5704 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5706 Eina_Bool transform_set = EINA_FALSE;
5708 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5709 if (cw->ec->input_only) return;
5711 transform_set = !!set;
5715 if (!cw->transform_tranp_obj)
5717 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5718 evas_object_move(o, 0, 0);
5719 evas_object_resize(o, 1, 1);
5720 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5721 evas_object_color_set(o, 0, 0, 0, 0);
5722 if (cw->visible) evas_object_show(o);
5724 cw->transform_tranp_obj = o;
5725 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5726 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5727 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5729 _e_comp_object_transform_obj_stack_update(obj);
5733 if (cw->transform_tranp_obj)
5735 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5736 evas_object_smart_member_del(cw->transform_tranp_obj);
5737 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5743 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5746 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5747 if (cw->ec->input_only) return;
5748 if (!cw->transform_tranp_obj) return;
5750 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5754 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5757 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5758 if (cw->ec->input_only) return;
5759 if (!cw->transform_tranp_obj) return;
5761 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5764 #ifdef REFACTOR_DESK_AREA
5767 e_comp_object_layer_update(Evas_Object *obj,
5768 Evas_Object *above, Evas_Object *below)
5770 E_Comp_Object *cw2 = NULL;
5771 Evas_Object *o = NULL;
5776 if (cw->ec->layer_block) return;
5777 if ((above) && (below))
5779 ERR("Invalid layer update request! cw=%p", cw);
5787 layer = evas_object_layer_get(o);
5788 cw2 = evas_object_data_get(o, "comp_obj");
5791 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5793 o = evas_object_above_get(o);
5794 if ((!o) || (o == cw->smart_obj)) break;
5795 if (evas_object_layer_get(o) != layer)
5797 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5802 ec = e_client_top_get();
5803 if (ec) o = ec->frame;
5806 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5810 _e_comp_object_layers_remove(cw);
5813 if (cw2->layer > cw->layer)
5814 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5815 else if (cw2->layer == cw->layer)
5818 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5820 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5822 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5825 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5828 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5833 e_comp_object_layer_get(Evas_Object *obj)
5840 e_comp_object_content_set(Evas_Object *obj,
5841 Evas_Object *content,
5842 E_Comp_Object_Content_Type type)
5844 API_ENTRY EINA_FALSE;
5846 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5847 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5848 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5852 ERR("Can't set e.swallow.content to requested content. "
5853 "Previous comp object should not be changed at all.");
5857 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5859 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5860 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5862 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5863 type, content, cw->ec, cw->ec->pixmap);
5867 cw->external_content = EINA_TRUE;
5870 cw->content_type = type;
5871 e_util_size_debug_set(cw->obj, 1);
5872 evas_object_name_set(cw->obj, "cw->obj");
5873 _e_comp_object_alpha_set(cw);
5876 _e_comp_object_shadow_setup(cw);
5882 e_comp_object_content_unset(Evas_Object *obj)
5884 API_ENTRY EINA_FALSE;
5886 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5887 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5889 if (!cw->obj && !cw->ec->visible)
5891 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5895 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5897 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5903 if (cw->frame_object)
5904 edje_object_part_unswallow(cw->frame_object, cw->obj);
5906 edje_object_part_unswallow(cw->shobj, cw->obj);
5908 evas_object_del(cw->obj);
5909 evas_object_hide(cw->obj);
5913 cw->external_content = EINA_FALSE;
5914 if (cw->ec->is_cursor)
5917 DBG("%p is cursor surface..", cw->ec);
5918 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5920 evas_object_resize(cw->ec->frame, pw, ph);
5921 evas_object_hide(cw->ec->frame);
5926 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5927 cw->obj = evas_object_image_filled_add(e_comp->evas);
5928 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5929 e_util_size_debug_set(cw->obj, 1);
5930 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5931 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5932 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5933 evas_object_name_set(cw->obj, "cw->obj");
5934 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5935 _e_comp_object_alpha_set(cw);
5938 _e_comp_object_shadow_setup(cw);
5943 _e_comp_intercept_show_helper(cw);
5947 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5948 e_comp_object_dirty(cw->smart_obj);
5949 e_comp_object_render(cw->smart_obj);
5950 e_comp_object_render_update_add(obj);
5955 EINTERN Evas_Object *
5956 e_comp_object_content_get(Evas_Object *obj)
5960 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5962 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5964 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5971 E_API E_Comp_Object_Content_Type
5972 e_comp_object_content_type_get(Evas_Object *obj)
5974 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5976 return cw->content_type;
5980 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5983 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5984 E_Comp_Config *conf = e_comp_config_get();
5985 if (cw->ec->input_only) return;
5986 if (!conf->dim_rect_enable) return;
5988 cw->dim.mask_set = mask_set;
5994 if (!cw->dim.enable) return;
5995 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
5999 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6001 Eina_Bool mask_set = EINA_FALSE;
6005 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6006 E_Comp_Config *conf = e_comp_config_get();
6007 if (cw->ec->input_only) return;
6008 if (!conf->dim_rect_enable) return;
6014 if (cw->dim.mask_obj)
6016 evas_object_smart_member_del(cw->dim.mask_obj);
6017 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6020 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);
6021 o = evas_object_rectangle_add(e_comp->evas);
6022 evas_object_color_set(o, 0, 0, 0, 0);
6023 evas_object_smart_member_add(o, obj);
6024 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6025 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6027 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6028 if (cw->visible) evas_object_show(o);
6030 cw->dim.mask_obj = o;
6031 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6033 evas_object_layer_set(cw->dim.mask_obj, 9998);
6037 if (cw->dim.mask_obj)
6039 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6040 evas_object_smart_member_del(cw->dim.mask_obj);
6041 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6047 e_comp_object_dim_client_set(E_Client *ec)
6049 E_Comp_Config *conf = e_comp_config_get();
6051 if (!conf->dim_rect_enable) return ;
6052 if (dim_client == ec) return;
6054 Eina_Bool prev_dim = EINA_FALSE;
6055 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6057 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6058 prev_dim = EINA_TRUE;
6060 if (prev_dim && dim_client->visible && ec)
6062 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6063 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6067 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6068 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6074 e_comp_object_dim_client_get(void)
6076 E_Comp_Config *conf = e_comp_config_get();
6078 if (!conf->dim_rect_enable ) return NULL;
6084 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6087 char emit[32] = "\0";
6088 E_Comp_Config *conf = e_comp_config_get();
6091 if (!conf->dim_rect_enable) return;
6092 if (!cw->effect_obj) return;
6093 if (enable == cw->dim.enable) return;
6095 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6096 if (noeffect || !conf->dim_rect_effect)
6098 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6102 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6105 cw->dim.enable = enable;
6107 if (cw->dim.mask_set && !enable)
6109 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6110 edje_object_signal_emit(cw->effect_obj, emit, "e");
6112 else if (cw->dim.mask_set && enable)
6114 edje_object_signal_emit(cw->effect_obj, emit, "e");
6115 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6119 edje_object_signal_emit(cw->effect_obj, emit, "e");
6124 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6126 API_ENTRY EINA_FALSE;
6127 E_Comp_Config *conf = e_comp_config_get();
6129 if (!ec) return EINA_FALSE;
6130 if (!conf->dim_rect_enable) return EINA_FALSE;
6132 if (cw->dim.enable) return EINA_TRUE;
6138 _e_comp_object_dim_update(E_Comp_Object *cw)
6140 E_Comp_Config *conf = e_comp_config_get();
6143 if (!conf->dim_rect_enable) return;
6144 if (!cw->effect_obj) return;
6147 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6148 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6150 if (cw->dim.mask_set)
6152 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6158 e_comp_object_clear(Evas_Object *obj)
6162 _e_comp_object_clear(cw);
6166 e_comp_object_hwc_update_exists(Evas_Object *obj)
6168 API_ENTRY EINA_FALSE;
6169 return cw->hwc_need_update;
6174 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6177 cw->hwc_need_update = set;
6181 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6183 API_ENTRY EINA_FALSE;
6184 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6188 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6191 if (cw->indicator.obj != indicator)
6192 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6193 cw->indicator.obj = indicator;
6194 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6198 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6201 if (cw->indicator.obj != indicator) return;
6202 cw->indicator.obj = NULL;
6203 edje_object_part_unswallow(cw->shobj, indicator);
6207 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6210 Edje_Message_Int_Set *msg;
6212 if (!cw->indicator.obj) return;
6214 cw->indicator.w = w;
6215 cw->indicator.h = h;
6217 if (!cw->shobj) return;
6219 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6223 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6224 edje_object_message_signal_process(cw->shobj);
6227 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6229 e_comp_object_map_update(Evas_Object *obj)
6232 E_Client *ec = cw->ec;
6233 E_Comp_Wl_Client_Data *cdata;
6235 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6238 int l, remain = sizeof buffer;
6241 if (e_object_is_del(E_OBJECT(ec))) return;
6242 cdata = e_client_cdata_get(ec);
6245 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6246 * when new buffer is attached.
6248 if (!cdata->buffer_ref.buffer) return;
6250 if ((!cw->redirected) ||
6251 (e_client_video_hw_composition_check(ec)) ||
6252 (!e_comp_wl_output_buffer_transform_get(ec) &&
6253 cdata->scaler.buffer_viewport.buffer.scale == 1))
6255 if (evas_object_map_enable_get(cw->effect_obj))
6257 ELOGF("TRANSFORM", "map: disable", cw->ec);
6258 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6259 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6260 evas_object_resize(cw->effect_obj, tw, th);
6267 EINA_SAFETY_ON_NULL_RETURN(map);
6269 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6275 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6277 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6278 e_map_point_image_uv_set(map, 0, x, y);
6279 l = snprintf(p, remain, "%d,%d", x, y);
6280 p += l, remain -= l;
6282 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6283 e_map_point_image_uv_set(map, 1, x, y);
6284 l = snprintf(p, remain, " %d,%d", x, y);
6285 p += l, remain -= l;
6287 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6288 e_map_point_image_uv_set(map, 2, x, y);
6289 l = snprintf(p, remain, " %d,%d", x, y);
6290 p += l, remain -= l;
6292 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6293 e_map_point_image_uv_set(map, 3, x, y);
6294 l = snprintf(p, remain, " %d,%d", x, y);
6295 p += l, remain -= l;
6297 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6299 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6301 e_comp_object_map_set(cw->effect_obj, map);
6302 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6306 /* if there's screen rotation with comp mode, then ec->effect_obj and
6307 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6309 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6310 evas_object_resize(cw->effect_obj, tw, th);
6314 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6316 API_ENTRY EINA_FALSE;
6318 cw->render_trace = set;
6324 e_comp_object_native_usable_get(Evas_Object *obj)
6326 API_ENTRY EINA_FALSE;
6327 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6329 if (cw->ec->input_only) return EINA_FALSE;
6330 if (cw->external_content) return EINA_FALSE;
6331 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6333 /* just return true value, if it is normal case */
6334 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6337 Evas_Native_Surface *ns;
6338 ns = evas_object_image_native_surface_get(cw->obj);
6340 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6343 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6351 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6353 API_ENTRY EINA_FALSE;
6354 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6355 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6356 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6360 case E_COMP_IMAGE_FILTER_BLUR:
6361 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6363 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6364 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6366 case E_COMP_IMAGE_FILTER_INVERSE:
6367 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6369 case E_COMP_IMAGE_FILTER_NONE:
6371 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6375 cw->image_filter = filter;
6380 EINTERN E_Comp_Image_Filter
6381 e_comp_object_image_filter_get(Evas_Object *obj)
6383 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6384 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6385 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6386 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6388 return cw->image_filter;
6392 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6396 if (!_damage_trace) return;
6398 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6399 evas_object_del(obj);
6401 _damage_trace_post_objs = NULL;
6405 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6407 if (!_damage_trace) return;
6409 _damage_trace_post_objs = _damage_trace_objs;
6410 _damage_trace_objs = NULL;
6414 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6416 if (_damage_trace == onoff) return;
6420 evas_event_callback_add(e_comp->evas,
6421 EVAS_CALLBACK_RENDER_PRE,
6422 _e_comp_object_damage_trace_render_pre_cb,
6425 evas_event_callback_add(e_comp->evas,
6426 EVAS_CALLBACK_RENDER_POST,
6427 _e_comp_object_damage_trace_render_post_cb,
6434 EINA_LIST_FREE(_damage_trace_objs, obj)
6435 evas_object_del(obj);
6437 _damage_trace_objs = NULL;
6439 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6440 evas_object_del(obj);
6442 _damage_trace_post_objs = NULL;
6444 evas_event_callback_del(e_comp->evas,
6445 EVAS_CALLBACK_RENDER_PRE,
6446 _e_comp_object_damage_trace_render_pre_cb);
6448 evas_event_callback_del(e_comp->evas,
6449 EVAS_CALLBACK_RENDER_POST,
6450 _e_comp_object_damage_trace_render_post_cb);
6453 _damage_trace = onoff;
6457 e_comp_object_redirected_get(Evas_Object *obj)
6459 API_ENTRY EINA_FALSE;
6460 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6462 return cw->redirected;
6466 e_comp_object_color_visible_get(Evas_Object *obj)
6468 API_ENTRY EINA_FALSE;
6471 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6473 e_comp_object_color_get(obj, NULL, NULL, NULL, &a);
6477 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
6481 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
6485 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
6493 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6495 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6497 return e_map_set_to_comp_object(em, obj);
6501 e_comp_object_map_get(const Evas_Object *obj)
6503 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6505 return e_map_get_from_comp_object(obj);
6509 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6511 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6513 evas_object_map_enable_set(obj, enable);
6519 e_comp_object_render_update_lock(Evas_Object *obj)
6521 E_Comp_Wl_Buffer *buffer;
6522 struct wayland_tbm_client_queue *cqueue;
6524 API_ENTRY EINA_FALSE;
6526 if (cw->render_update_lock.lock == 0)
6528 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6530 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6531 if ((buffer) && (buffer->resource))
6533 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6535 wayland_tbm_server_client_queue_flush(cqueue);
6538 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6539 e_comp_object_render_update_del(obj);
6541 ELOGF("COMP", "Render update lock enabled", cw->ec);
6544 cw->render_update_lock.lock++;
6550 e_comp_object_render_update_unlock(Evas_Object *obj)
6554 if (cw->render_update_lock.lock == 0)
6557 cw->render_update_lock.lock--;
6559 if (cw->render_update_lock.lock == 0)
6562 if (cw->render_update_lock.pending_move_set)
6564 evas_object_move(obj,
6565 cw->render_update_lock.pending_move_x,
6566 cw->render_update_lock.pending_move_y);
6567 cw->render_update_lock.pending_move_x = 0;
6568 cw->render_update_lock.pending_move_y = 0;
6569 cw->render_update_lock.pending_move_set = EINA_FALSE;
6572 if (cw->render_update_lock.pending_resize_set)
6574 evas_object_resize(obj,
6575 cw->render_update_lock.pending_resize_w,
6576 cw->render_update_lock.pending_resize_h);
6577 cw->render_update_lock.pending_resize_w = 0;
6578 cw->render_update_lock.pending_resize_h = 0;
6579 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6582 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6584 if ((cw->ec->exp_iconify.buffer_flush) &&
6585 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6586 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6587 e_comp_object_clear(obj);
6589 e_comp_object_render_update_add(obj);
6591 ELOGF("COMP", "Render update lock disabled", cw->ec);
6596 e_comp_object_render_update_lock_get(Evas_Object *obj)
6598 API_ENTRY EINA_FALSE;
6600 if (cw->render_update_lock.lock > 0)
6607 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6611 if (cw->transparent.set)
6613 if (r) *r = cw->transparent.user_r;
6614 if (g) *g = cw->transparent.user_g;
6615 if (b) *b = cw->transparent.user_b;
6616 if (a) *a = cw->transparent.user_a;
6620 evas_object_color_get(obj, r, g, b, a);
6625 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6629 evas_object_render_op_set(cw->obj, op);
6632 EINTERN Evas_Render_Op
6633 e_comp_object_render_op_get(Evas_Object *obj)
6635 API_ENTRY EVAS_RENDER_BLEND;
6637 return evas_object_render_op_get(cw->obj);
6641 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6644 wl_signal_add(&cw->events.lower, listener);
6647 #ifdef REFACTOR_DESK_AREA
6649 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6652 wl_signal_add(&cw->events.lower_done, listener);
6656 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6659 wl_signal_add(&cw->events.raise, listener);
6664 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6667 wl_signal_add(&cw->events.show, listener);
6671 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6674 wl_signal_add(&cw->events.hide, listener);
6677 #ifdef REFACTOR_DESK_AREA
6679 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6682 wl_signal_add(&cw->events.set_layer, listener);
6686 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6689 wl_signal_add(&cw->events.stack_above, listener);
6693 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6696 wl_signal_add(&cw->events.stack_below, listener);