1 #include "e_comp_object_intern.h"
2 #include "e_bindings_intern.h"
3 #include "e_utils_intern.h"
4 #include "e_comp_canvas_intern.h"
5 #include "e_comp_cfdata_intern.h"
6 #include "e_comp_wl_subsurface_intern.h"
7 #include "e_comp_wl_tbm_intern.h"
8 #include "e_comp_intern.h"
9 #include "e_pixmap_intern.h"
10 #include "e_map_intern.h"
11 #include "e_hwc_window_intern.h"
12 #include "e_hwc_windows_intern.h"
13 #include "e_policy_visibility_intern.h"
14 #include "e_client_video_intern.h"
15 #include "e_client_intern.h"
16 #include "e_zone_intern.h"
17 #include "e_theme_intern.h"
18 #include "e_config_intern.h"
22 = keys that return objects =
23 - E_Client: the client associated with the object (E_Client*)
24 - comp_smart_obj: cw->smart_obj (Evas_Object*)
25 - comp_obj: cw (E_Comp_Object*)
27 = keys that are bool flags =
28 - client_restack: client needs a protocol-level restack
29 - comp_override: object is triggering a nocomp override to force compositing
30 - comp_ref: object has a ref from visibility animations
31 - comp_showing: object is currently running its show animation
32 - comp_hiding: object is currently running its hiding animation
33 - comp_object: object is a compositor-created object
34 - comp_object_skip: object has a name which prohibits theme shadows
35 - comp_object-to_del: list of objects which will be deleted when this object is deleted
36 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
37 - effect_running: object is animating by external module
40 #define UPDATE_MAX 512 // same as evas
41 #define FAILURE_MAX 2 // seems reasonable
42 #define SMART_NAME "e_comp_object"
43 #define INPUT_OBJ_SMART_NAME "input_object"
45 /* for non-util functions */
46 #define API_ENTRY E_Comp_Object *cw; \
47 cw = evas_object_smart_data_get(obj); \
48 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
50 /* for util functions (obj may or may not be E_Comp_Object */
51 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
54 CRI("YOU PASSED NULL! ARGH!"); \
57 cw = evas_object_smart_data_get(obj); \
58 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
60 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
62 /* enable for lots of client size info in console output */
64 # define e_util_size_debug_set(x, y)
67 /* enable along with display-specific damage INF calls to enable render tracing
71 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
73 #define RENDER_DEBUG(...)
76 typedef struct _E_Input_Rect_Data
82 typedef struct _E_Input_Rect_Smart_Data
84 Eina_List *input_rect_data_list;
86 } E_Input_Rect_Smart_Data;
88 struct E_Comp_Object_Mover
91 E_Comp_Object_Mover_Cb func;
97 static Eina_Inlist *_e_comp_object_movers = NULL;
98 static Evas_Smart *_e_comp_smart = NULL;
99 static Evas_Smart *_e_comp_input_obj_smart = NULL;
101 static int _e_comp_object_hooks_delete = 0;
102 static int _e_comp_object_hooks_walking = 0;
104 static Eina_Inlist *_e_comp_object_hooks[] =
106 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
107 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
108 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
109 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
110 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
111 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
112 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
113 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
114 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET] = NULL,
117 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
118 static int _e_comp_object_intercept_hooks_delete = 0;
119 static int _e_comp_object_intercept_hooks_walking = 0;
121 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
123 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
124 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
128 static Eina_Bool _damage_trace = EINA_FALSE;
129 static Eina_List *_damage_trace_objs = NULL;
130 static Eina_List *_damage_trace_post_objs = NULL;
132 /* sekrit functionzzz */
133 EINTERN void e_client_focused_set(E_Client *ec);
135 /* emitted every time a new noteworthy comp object is added */
136 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
138 /* ecore event define */
139 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
140 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
141 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
143 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
144 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
145 static void _e_comp_object_dim_update(E_Comp_Object *cw);
146 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
147 #ifdef REFACTOR_DESK_AREA
149 static void _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj);
150 static void _e_comp_object_raise(Evas_Object *obj);
151 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
152 static void _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target);
153 static void _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target);
154 static void _e_comp_object_transform_obj_stack_update(Evas_Object *obj);
157 static E_Client *dim_client = NULL;
160 _e_comp_object_hooks_clean(void)
163 E_Comp_Object_Hook *ch;
166 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
167 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
169 if (!ch->delete_me) continue;
170 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
176 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
178 E_Comp_Object_Hook *ch;
179 Eina_Bool ret = EINA_TRUE;
181 if (e_object_is_del(E_OBJECT(ec)))
183 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
184 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
185 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
186 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
187 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
188 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
189 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
190 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET) &&
191 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET)
197 e_object_ref(E_OBJECT(ec));
198 _e_comp_object_hooks_walking++;
199 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
201 if (ch->delete_me) continue;
202 if (!(ch->func(ch->data, ec)))
208 _e_comp_object_hooks_walking--;
209 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
210 _e_comp_object_hooks_clean();
212 e_object_unref(E_OBJECT(ec));
217 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
219 _e_comp_object_intercept_hooks_clean(void)
222 E_Comp_Object_Intercept_Hook *ch;
225 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
226 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
228 if (!ch->delete_me) continue;
229 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
235 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
237 E_Comp_Object_Intercept_Hook *ch;
238 Eina_Bool ret = EINA_TRUE;
240 if (e_object_is_del(E_OBJECT(ec))) return ret;
241 e_object_ref(E_OBJECT(ec));
242 _e_comp_object_intercept_hooks_walking++;
243 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
245 if (ch->delete_me) continue;
246 if (!(ch->func(ch->data, ec)))
252 _e_comp_object_intercept_hooks_walking--;
253 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
254 _e_comp_object_intercept_hooks_clean();
256 e_object_unref(E_OBJECT(ec));
263 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
265 E_Event_Comp_Object *ev = event;
268 ec = evas_object_data_get(ev->comp_object, "E_Client");
272 e_object_unref(E_OBJECT(ec));
274 evas_object_unref(ev->comp_object);
279 _e_comp_object_event_add(Evas_Object *obj)
281 E_Event_Comp_Object *ev;
284 if (stopping) return;
285 ev = E_NEW(E_Event_Comp_Object, 1);
286 EINA_SAFETY_ON_NULL_RETURN(ev);
288 evas_object_ref(obj);
289 ev->comp_object = obj;
290 ec = evas_object_data_get(ev->comp_object, "E_Client");
294 e_object_ref(E_OBJECT(ec));
296 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
300 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
302 E_Event_Comp_Object *ev = event;
305 ec = evas_object_data_get(ev->comp_object, "E_Client");
309 e_object_unref(E_OBJECT(ec));
311 evas_object_unref(ev->comp_object);
316 _e_comp_object_event_simple(Evas_Object *obj, int type)
318 E_Event_Comp_Object *ev;
321 ev = E_NEW(E_Event_Comp_Object, 1);
324 evas_object_ref(obj);
325 ev->comp_object = obj;
326 ec = evas_object_data_get(ev->comp_object, "E_Client");
330 e_object_ref(E_OBJECT(ec));
332 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
334 /////////////////////////////////////
337 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
339 E_Comp_Object *cw = data;
341 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
345 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
347 E_Comp_Object *cw = data;
349 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
350 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
353 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
354 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
358 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
360 E_Comp_Object *cw = data;
363 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
364 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
367 /////////////////////////////////////
369 #ifdef REFACTOR_DESK_AREA
371 e_comp_object_transform_obj_stack_update(Evas_Object *obj)
374 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
379 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
380 if (cw->ec->input_only) return;
382 layer = evas_object_layer_get(obj);
384 if (cw->transform_bg_obj)
386 if (layer != evas_object_layer_get(cw->transform_bg_obj))
388 evas_object_layer_set(cw->transform_bg_obj, layer);
391 evas_object_stack_below(cw->transform_bg_obj, obj);
394 if (cw->transform_tranp_obj)
396 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
398 evas_object_layer_set(cw->transform_tranp_obj, layer);
401 evas_object_stack_below(cw->transform_tranp_obj, obj);
406 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
413 if (!map) return NULL;
415 e_map_util_points_populate_from_object_full(map, obj, 0);
416 e_map_util_points_color_set(map, 255, 255, 255, 255);
418 for (i = 0 ; i < 4 ; ++i)
423 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
424 e_map_point_coord_set(map, i, x, y, 1.0);
431 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
437 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
440 e_comp_object_map_set(obj, map);
441 e_comp_object_map_enable_set(obj, EINA_TRUE);
448 evas_object_map_enable_set(obj, EINA_FALSE);
453 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
459 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
462 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
464 e_comp_object_map_set(obj, map);
465 e_comp_object_map_enable_set(obj, EINA_TRUE);
472 evas_object_map_enable_set(obj, EINA_FALSE);
475 /////////////////////////////////////
477 static inline Eina_Bool
478 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
480 if (num > 1) return EINA_TRUE;
481 if ((rects[0].x == 0) && (rects[0].y == 0) &&
482 ((int)rects[0].w == w) && ((int)rects[0].h == h))
487 /////////////////////////////////////
489 /* add a client to the layer-client list */
490 #ifdef REFACTOR_DESK_AREA
493 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
495 g_rec_mutex_lock(&e_comp->ec_list_mutex);
498 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));
500 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));
501 if ((!above) && (!below))
504 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
505 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
506 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
508 e_comp->layers[cw->layer].clients_count++;
510 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
514 _e_comp_object_layers_remove(E_Comp_Object *cw)
516 g_rec_mutex_lock(&e_comp->ec_list_mutex);
518 if (cw->ec && e_comp->layers[cw->layer].clients)
520 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
521 e_comp->layers[cw->layer].clients_count--;
524 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
528 /////////////////////////////////////
530 _e_comp_object_alpha_set(E_Comp_Object *cw)
532 Eina_Bool alpha = cw->ec->argb;
534 if ((cw->external_content) &&
535 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
540 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
541 if (cw->user_alpha_set) alpha = cw->user_alpha;
543 evas_object_image_alpha_set(cw->obj, alpha);
547 _e_comp_object_shadow(E_Comp_Object *cw)
549 if (e_client_util_shadow_state_get(cw->ec))
550 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
552 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
553 if (cw->frame_object)
554 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
555 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
558 /* convert from the surface coordinates to the buffer coordinates */
560 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
562 E_Comp_Wl_Buffer_Viewport *vp;
563 E_Comp_Wl_Client_Data *cdata;
567 cdata = e_client_cdata_get(ec);
569 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
576 vp = &cdata->scaler.buffer_viewport;
577 transform = e_comp_wl_output_buffer_transform_get(ec);
579 e_pixmap_size_get(ec->pixmap, &bw, &bh);
581 /* for subsurface, it should be swap 90 and 270 */
582 if (e_comp_wl_subsurface_check(ec))
585 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
586 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
587 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
588 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
594 case WL_OUTPUT_TRANSFORM_NORMAL:
595 default: tx = sx, ty = sy; break;
596 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
597 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
598 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
599 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
600 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
601 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
602 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
605 tx *= vp->buffer.scale;
606 ty *= vp->buffer.scale;
613 _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)
621 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
622 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
629 if (dw) *dw = MAX(x1, x2) - mx;
630 if (dh) *dh = MAX(y1, y2) - my;
634 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
635 int *dx, int *dy, int *dw, int *dh)
637 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
638 E_Util_Transform_Rect_Vertex sv, dv;
642 e_pixmap_size_get(ec->pixmap, &bw, &bh);
644 sv = e_util_transform_rect_to_vertices(&rect);
646 for (i = 0; i < 4; i++)
648 double x = 0.0, y = 0.0;
650 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
652 /* if evas decide coordinate is outside of map, it returns (0, 0)
653 in this case, full damage is added.
655 if ((i != 0) && (x == 0.0) && (y == 0.0))
658 dv.vertices[i].vertex[0] = x;
659 dv.vertices[i].vertex[1] = y;
660 dv.vertices[i].vertex[2] = 1.0;
661 dv.vertices[i].vertex[3] = 1.0;
664 rect = e_util_transform_vertices_to_rect(&dv);
666 if (dx) *dx = rect.x;
667 if (dy) *dy = rect.y;
668 if (dw) *dw = rect.w;
669 if (dh) *dh = rect.h;
683 _e_comp_object_map_damage_transform_get(E_Client *ec)
690 if (!e_client_transform_core_enable_get(ec))
693 m = e_client_map_get(ec);
697 e_pixmap_size_get(ec->pixmap, &bw, &bh);
698 if ((bw == 0) || (bh == 0))
711 e_map_point_coord_set(m2, 0, 0, 0, 0);
712 e_map_point_coord_set(m2, 1, bw, 0, 0);
713 e_map_point_coord_set(m2, 2, bw, bh, 0);
714 e_map_point_coord_set(m2, 3, 0, bh, 0);
716 for (i = 0; i < 4; i++)
720 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
721 e_map_point_image_uv_set(m2, i, map_x, map_y);
728 /////////////////////////////////////
730 /* handle evas mouse-in events on client object */
732 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
734 Evas_Event_Mouse_In *ev = event_info;
735 E_Comp_Object *cw = data;
737 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
740 /* handle evas mouse-out events on client object */
742 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
744 Evas_Event_Mouse_Out *ev = event_info;
745 E_Comp_Object *cw = data;
747 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
750 /* handle evas mouse wheel events on client object */
752 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
754 Evas_Event_Mouse_Wheel *ev = event_info;
755 E_Comp_Object *cw = data;
756 E_Binding_Event_Wheel ev2;
759 if (e_client_action_get()) return;
760 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
761 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
764 /* handle evas mouse down events on client object */
766 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
768 Evas_Event_Mouse_Down *ev = event_info;
769 E_Comp_Object *cw = data;
770 E_Binding_Event_Mouse_Button ev2;
773 if (e_client_action_get()) return;
774 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
775 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
778 /* handle evas mouse up events on client object */
780 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
782 Evas_Event_Mouse_Up *ev = event_info;
783 E_Comp_Object *cw = data;
784 E_Binding_Event_Mouse_Button ev2;
787 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
788 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
789 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
792 /* handle evas mouse movement events on client object */
794 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
796 Evas_Event_Mouse_Move *ev = event_info;
797 E_Comp_Object *cw = data;
800 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
801 e_client_mouse_move(cw->ec, &ev->cur.output);
803 /////////////////////////////////////
805 /* helper function for checking compositor themes based on user-defined matches */
807 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
809 if (((m->title) && (!ec->netwm.name)) ||
810 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
812 #if defined(__cplusplus) || defined(c_plusplus)
813 if (((m->clas) && (!ec->icccm.cpp_class)) ||
814 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
817 if (((m->clas) && (!ec->icccm.class)) ||
818 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
822 if (((m->role) && (!ec->icccm.window_role)) ||
823 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
829 if ((int)ec->netwm.type != m->primary_type)
832 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
835 if (m->borderless != 0)
839 if (e_client_util_borderless(ec))
841 if (!(((m->borderless == -1) && (!borderless)) ||
842 ((m->borderless == 1) && (borderless))))
849 if (((ec->icccm.transient_for != 0) ||
852 if (!(((m->dialog == -1) && (!dialog)) ||
853 ((m->dialog == 1) && (dialog))))
856 if (m->accepts_focus != 0)
858 int accepts_focus = 0;
860 if (ec->icccm.accepts_focus)
862 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
863 ((m->accepts_focus == 1) && (accepts_focus))))
872 if (!(((m->vkbd == -1) && (!vkbd)) ||
873 ((m->vkbd == 1) && (vkbd))))
878 if (!(((m->argb == -1) && (!ec->argb)) ||
879 ((m->argb == 1) && (ec->argb))))
882 if (m->fullscreen != 0)
884 int fullscreen = ec->fullscreen;
886 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
887 ((m->fullscreen == 1) && (fullscreen))))
892 if (!(m->modal == -1))
898 /* function for setting up a client's compositor frame theme (cw->shobj) */
900 _e_comp_object_shadow_setup(E_Comp_Object *cw)
904 Eina_List *list = NULL, *l;
905 E_Input_Rect_Data *input_rect_data;
906 E_Input_Rect_Smart_Data *input_rect_sd;
908 Eina_Stringshare *reshadow_group = NULL;
909 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
910 Eina_Stringshare *name, *title;
911 E_Comp_Config *conf = e_comp_config_get();
913 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
914 /* match correct client type */
915 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
916 name = cw->ec->icccm.name;
917 title = cw->ec->icccm.title;
918 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
919 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
921 /* skipping here is mostly a hack for systray because I hate it */
924 EINA_LIST_FOREACH(list, l, m)
926 if (((m->name) && (!name)) ||
927 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
929 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
932 no_shadow = m->no_shadow;
935 /* fast effects are just themes with "/fast" appended and shorter effect times */
938 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
939 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
941 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
943 /* default to non-fast style if fast not available */
946 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
947 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
949 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
951 if (ok && m->visibility_effect)
952 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
959 if (skip || (cw->ec->e.state.video))
961 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
963 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
966 if (conf->shadow_style)
970 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
971 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
973 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
977 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
978 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
980 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
987 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
989 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
993 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
995 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1000 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1005 if (cw->ec->override)
1007 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1008 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1010 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1011 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1017 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1018 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1021 _e_comp_object_shadow(cw);
1024 if (focus || cw->ec->focused || cw->ec->override)
1025 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1027 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1029 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1031 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1032 /* visibility must always be enabled for re_manage clients to prevent
1033 * pop-in animations every time the user sees a persistent client again;
1034 * applying visibility for iconic clients prevents the client from getting
1037 if (cw->visible || cw->ec->re_manage)
1038 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1040 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1042 /* breaks animation counter */
1043 if (cw->frame_object)
1045 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1046 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1047 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1048 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1054 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1058 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1061 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1063 if (input_rect_data->obj)
1065 pass_event_flag = EINA_TRUE;
1071 if (cw->indicator.obj)
1073 Evas_Object *indicator;
1074 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1075 if (indicator != cw->indicator.obj)
1077 edje_object_part_unswallow(cw->shobj, indicator);
1078 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1079 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1083 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1084 evas_object_pass_events_set(cw->obj, pass_event_flag);
1089 /////////////////////////////////////////////
1092 _e_comp_object_animating_begin(E_Comp_Object *cw)
1095 if (cw->animating == 1)
1097 e_comp->animating++;
1099 e_object_ref(E_OBJECT(cw->ec));
1104 _e_comp_object_animating_end(E_Comp_Object *cw)
1113 if (cw->ec->launching)
1115 if (!cw->ec->extra_animating)
1117 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1118 cw->ec->launching = EINA_FALSE;
1119 if (cw->ec->first_mapped)
1121 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1122 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1125 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1129 e_comp->animating--;
1130 cw->showing = cw->hiding = 0;
1132 if (e_comp->animating == 0)
1133 e_comp_visibility_calculation_set(EINA_TRUE);
1134 /* remove ref from animation start, account for possibility of deletion from unref */
1135 return !!e_object_unref(E_OBJECT(cw->ec));
1141 /* handle the end of a compositor animation */
1143 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1145 E_Comp_Object *cw = data;
1147 /* visible clients which have never been sized are a bug */
1148 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1149 CRI("ACK! ec:%p", cw->ec);
1150 if (!_e_comp_object_animating_end(cw)) return;
1151 if (cw->animating) return;
1152 /* hide only after animation finishes to guarantee a full run of the animation */
1153 if (!cw->defer_hide) return;
1154 if ((!strcmp(emission, "e,action,hide,done")) ||
1155 (!strcmp(emission, "e,action,done")) ||
1156 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1158 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1159 evas_object_hide(cw->smart_obj);
1163 /* run a visibility compositor effect if available, return false if object is dead */
1165 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1171 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1172 if (!cw->effect_running)
1173 _e_comp_object_animating_begin(cw);
1174 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1175 return _e_comp_object_animating_end(cw);
1176 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1177 return _e_comp_object_animating_end(cw);
1179 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1182 zone = e_comp_zone_find_by_ec(cw->ec);
1184 zw = zone->w, zh = zone->h;
1189 zone = e_comp_object_util_zone_get(cw->smart_obj);
1190 if (!zone) zone = e_zone_current_get();
1197 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1198 cw->w, cw->h, zw, zh, x, y}, 8);
1199 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1200 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1203 /////////////////////////////////////////////
1205 /* create necessary objects for clients that e manages */
1207 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1209 if (cw->set_mouse_callbacks) return;
1210 if (!cw->smart_obj) return;
1212 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1213 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1214 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1215 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1216 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1217 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1219 cw->set_mouse_callbacks = EINA_TRUE;
1223 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1225 if (!cw->set_mouse_callbacks) return;
1226 if (!cw->smart_obj) return;
1228 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1229 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1230 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1231 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1232 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1233 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1235 cw->set_mouse_callbacks = EINA_FALSE;
1239 _e_comp_object_color_visible_set(E_Comp_Object *cw, Eina_Bool set)
1241 if (cw->color_visible == set) return EINA_TRUE;
1243 cw->color_visible = set;
1245 ELOGF("COMP", "color_visible set:%d", cw->ec, set);
1247 wl_signal_emit(&cw->events.color_visible_set, NULL);
1253 _e_comp_object_color_visible_update(E_Comp_Object *cw)
1257 e_comp_object_color_get(cw->smart_obj, NULL, NULL, NULL, &a);
1260 _e_comp_object_color_visible_set(cw, EINA_FALSE);
1266 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
1269 _e_comp_object_color_visible_set(cw, EINA_FALSE);
1277 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
1280 _e_comp_object_color_visible_set(cw, EINA_FALSE);
1287 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
1290 _e_comp_object_color_visible_set(cw, EINA_FALSE);
1295 _e_comp_object_color_visible_set(cw, EINA_TRUE);
1299 _e_comp_intercept_effect_obj_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
1301 E_Comp_Object *cw = data;
1303 evas_object_color_set(obj, r, g, b, a);
1305 _e_comp_object_color_visible_update(cw);
1309 _e_comp_intercept_shobj_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
1311 E_Comp_Object *cw = data;
1313 evas_object_color_set(obj, r, g, b, a);
1315 _e_comp_object_color_visible_update(cw);
1319 _e_comp_intercept_obj_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
1321 E_Comp_Object *cw = data;
1323 evas_object_color_set(obj, r, g, b, a);
1325 _e_comp_object_color_visible_update(cw);
1329 _e_comp_object_setup(E_Comp_Object *cw)
1331 cw->clip = evas_object_rectangle_add(e_comp->evas);
1332 evas_object_move(cw->clip, -9999, -9999);
1333 evas_object_resize(cw->clip, 999999, 999999);
1334 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1335 cw->effect_obj = edje_object_add(e_comp->evas);
1336 evas_object_move(cw->effect_obj, cw->x, cw->y);
1337 evas_object_clip_set(cw->effect_obj, cw->clip);
1338 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1339 evas_object_intercept_color_set_callback_add(cw->effect_obj, _e_comp_intercept_effect_obj_color_set, cw);
1340 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1341 cw->shobj = edje_object_add(e_comp->evas);
1342 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1343 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1344 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1345 evas_object_intercept_color_set_callback_add(cw->shobj, _e_comp_intercept_shobj_color_set, cw);
1347 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1348 if (cw->ec->override)
1350 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1351 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1352 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1354 else if (!cw->ec->input_only)
1356 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1357 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1358 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1360 cw->real_hid = !cw->ec->input_only;
1361 if (!cw->ec->input_only)
1363 e_util_size_debug_set(cw->effect_obj, 1);
1364 _e_comp_object_mouse_event_callback_set(cw);
1367 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1368 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1369 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1370 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1371 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1372 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1374 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1377 /////////////////////////////////////////////
1379 /* for fast path evas rendering; only called during render */
1381 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1383 E_Comp_Object *cw = data;
1384 E_Client *ec = cw->ec;
1386 int bx, by, bxx, byy;
1388 if (e_object_is_del(E_OBJECT(ec))) return;
1389 if (cw->external_content) return;
1390 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1391 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1394 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1395 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1397 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1399 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1400 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1404 bx = by = bxx = byy = 0;
1405 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1408 Edje_Message_Int_Set *msg;
1409 Edje_Message_Int msg2;
1410 Eina_Bool id = (bx || by || bxx || byy);
1412 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1418 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1420 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1424 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1425 e_comp_client_post_update_add(cw->ec);
1427 else if (e_comp_object_render(ec->frame))
1429 /* apply shape mask if necessary */
1430 if ((!cw->native) && (ec->shaped))
1431 e_comp_object_shape_apply(ec->frame);
1433 /* shaped clients get precise mouse events to handle transparent pixels */
1434 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1436 /* queue another render if client is still dirty; cannot refresh here. */
1437 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1438 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1440 if (cw->render_trace)
1442 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1448 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1450 E_Comp_Object *cw = data;
1451 E_Client *ec = cw->ec;
1453 if (e_object_is_del(E_OBJECT(ec))) return;
1454 if (cw->external_content) return;
1455 if (!e_comp->hwc) return;
1457 e_comp_client_render_list_add(cw->ec);
1459 if (!ec->hwc_window) return;
1461 e_hwc_windows_rendered_window_add(ec->hwc_window);
1464 /////////////////////////////////////////////
1467 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1469 E_Comp_Object *cw = data;
1472 if (cw->render_update_lock.lock)
1474 cw->render_update_lock.pending_move_x = x;
1475 cw->render_update_lock.pending_move_y = y;
1476 cw->render_update_lock.pending_move_set = EINA_TRUE;
1480 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1481 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1482 (cw->external_content))
1484 /* delay to move until the external content is unset */
1485 cw->ec->changes.pos = 1;
1490 if (cw->ec->move_after_resize)
1492 if ((x != cw->ec->x) || (y != cw->ec->y))
1494 if (!cw->ec->is_cursor)
1495 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1496 e_client_pos_set(cw->ec, x, y);
1497 cw->ec->changes.pos = 1;
1503 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1504 (cw->ec->manage_resize.resize_obj))
1506 e_client_pos_set(cw->ec, x, y);
1507 cw->ec->client.x = x + cw->client_inset.l;
1508 cw->ec->client.y = y + cw->client_inset.t;
1509 e_policy_visibility_client_defer_move(cw->ec);
1513 /* if frame_object does not exist, client_inset indicates CSD.
1514 * this means that ec->client matches cw->x/y, the opposite
1517 fx = (!cw->frame_object) * cw->client_inset.l;
1518 fy = (!cw->frame_object) * cw->client_inset.t;
1519 if ((cw->x == x + fx) && (cw->y == y + fy))
1521 if ((cw->ec->x != x) || (cw->ec->y != y))
1523 /* handle case where client tries to move to position and back very quickly */
1524 e_client_pos_set(cw->ec, x, y);
1525 cw->ec->client.x = x + cw->client_inset.l;
1526 cw->ec->client.y = y + cw->client_inset.t;
1530 if (!cw->ec->maximize_override)
1532 /* prevent moving in some directions while directionally maximized */
1533 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1535 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1538 ix = x + cw->client_inset.l;
1539 iy = y + cw->client_inset.t;
1540 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1541 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1542 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1544 /* prevent moving at all if move isn't allowed in current maximize state */
1545 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1546 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1549 zone = e_comp_zone_find_by_ec(cw->ec);
1552 cw->ec->changes.need_unmaximize = 1;
1553 cw->ec->saved.x = ix - zone->x;
1554 cw->ec->saved.y = iy - zone->y;
1555 cw->ec->saved.w = cw->ec->client.w;
1556 cw->ec->saved.h = cw->ec->client.h;
1560 /* only update during resize if triggered by resize */
1561 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1562 /* delay to move while surface waits paired commit serial*/
1563 if (e_client_pending_geometry_has(cw->ec))
1565 /* do nothing while waiting paired commit serial*/
1569 e_client_pos_set(cw->ec, x, y);
1570 if (cw->ec->new_client)
1572 /* don't actually do anything until first client idler loop */
1573 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1574 cw->ec->changes.pos = 1;
1579 /* only update xy position of client to avoid invalid
1580 * first damage region if it is not a new_client. */
1581 cw->ec->client.x = ix;
1582 cw->ec->client.y = iy;
1585 if (!cw->frame_object)
1587 evas_object_move(obj, x, y);
1592 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1594 E_Comp_Object *cw = data;
1595 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1598 if (cw->render_update_lock.lock)
1600 cw->render_update_lock.pending_resize_w = w;
1601 cw->render_update_lock.pending_resize_h = h;
1602 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1606 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1608 e_client_size_set(cw->ec, w, h);
1609 evas_object_resize(obj, w, h);
1613 /* if frame_object does not exist, client_inset indicates CSD.
1614 * this means that ec->client matches cw->w/h, the opposite
1617 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1618 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1619 if ((cw->w == w + fw) && (cw->h == h + fh))
1621 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1622 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1623 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1625 /* handle case where client tries to resize itself and back very quickly */
1626 e_client_size_set(cw->ec, w, h);
1627 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1628 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1629 evas_object_smart_callback_call(obj, "client_resize", NULL);
1633 /* guarantee that fullscreen is fullscreen */
1634 zone = e_comp_zone_find_by_ec(cw->ec);
1636 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1638 if (!e_client_transform_core_enable_get(cw->ec))
1641 /* calculate client size */
1642 iw = w - cw->client_inset.l - cw->client_inset.r;
1643 ih = h - cw->client_inset.t - cw->client_inset.b;
1644 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1646 /* prevent resizing while maximized depending on direction and config */
1647 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1649 Eina_Bool reject = EINA_FALSE;
1650 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1652 if (cw->ec->client.h != ih)
1654 cw->ec->saved.h = ih;
1655 cw->ec->saved.y = cw->ec->client.y - zone->y;
1656 reject = cw->ec->changes.need_unmaximize = 1;
1659 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1661 if (cw->ec->client.w != iw)
1663 cw->ec->saved.w = iw;
1664 cw->ec->saved.x = cw->ec->client.x - zone->x;
1665 reject = cw->ec->changes.need_unmaximize = 1;
1674 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1676 /* do nothing until client idler loops */
1677 if ((cw->ec->w != w) || (cw->ec->h != h))
1679 e_client_size_set(cw->ec, w, h);
1680 cw->ec->changes.size = 1;
1685 if (e_client_pending_geometry_has(cw->ec))
1687 /* do nothing while waiting paired commit serial*/
1691 e_client_size_set(cw->ec, w, h);
1693 cw->ec->client.w = iw;
1694 cw->ec->client.h = ih;
1695 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1697 /* The size of non-compositing window can be changed, so there is a
1698 * need to check that cw is H/W composited if cw is not redirected.
1699 * And of course we have to change size of evas object of H/W composited cw,
1700 * otherwise cw can't receive input events even if it is shown on the screen.
1702 Eina_Bool redirected = cw->redirected;
1704 redirected = e_comp_is_on_overlay(cw->ec);
1706 if ((!cw->ec->input_only) && (redirected) &&
1707 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1708 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1709 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1710 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1713 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1714 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1716 prev_w = cw->w, prev_h = cw->h;
1717 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1718 /* check shading and clamp to pixmap size for regular clients */
1719 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1720 (((w - fw != pw) || (h - fh != ph))))
1722 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1723 evas_object_smart_callback_call(obj, "client_resize", NULL);
1725 if (cw->frame_object || cw->ec->input_only)
1726 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1729 if ((cw->w == w) && (cw->h == h))
1731 /* going to be a noop resize which won't trigger smart resize */
1732 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1733 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1735 evas_object_resize(obj, w, h);
1739 evas_object_smart_callback_call(obj, "client_resize", NULL);
1742 if ((!cw->frame_object) && (!cw->ec->input_only))
1744 /* "just do it" for overrides */
1745 evas_object_resize(obj, w, h);
1747 if (!cw->ec->override)
1749 /* shape probably changed for non-overrides */
1754 /* this fixes positioning jiggles when using a resize mode
1755 * which also changes the client's position
1758 if (cw->frame_object)
1759 x = cw->x, y = cw->y;
1761 x = cw->ec->x, y = cw->ec->y;
1762 switch (cw->ec->resize_mode)
1764 case E_POINTER_RESIZE_BL:
1765 case E_POINTER_RESIZE_L:
1766 evas_object_move(obj, x + prev_w - cw->w, y);
1768 case E_POINTER_RESIZE_TL:
1769 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1771 case E_POINTER_RESIZE_T:
1772 case E_POINTER_RESIZE_TR:
1773 evas_object_move(obj, x, y + prev_h - cw->h);
1782 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1784 #ifdef REFACTOR_DESK_AREA
1785 E_Comp_Object *cw = data;
1786 E_Comp_Object_Data_Set_Layer layer_set_data;
1788 layer_set_data.cw = cw;
1789 layer_set_data.layer = layer;
1791 wl_signal_emit(&cw->events.set_layer, &layer_set_data);
1795 e_comp_render_queue();
1796 e_comp_object_transform_obj_stack_update(obj);
1800 E_Comp_Object *cw = data;
1801 E_Comp_Wl_Client_Data *child_cdata;
1802 unsigned int l = e_comp_canvas_layer_map(layer);
1805 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1807 /* doing a compositor effect, follow directions */
1808 _e_comp_object_layer_set(obj, layer);
1809 if (layer == cw->ec->layer) //trying to put layer back
1813 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1814 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1815 if (cw->layer != l) goto layer_set;
1819 e_comp_render_queue();
1821 ec = e_client_above_get(cw->ec);
1822 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1823 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1824 ec = e_client_above_get(ec);
1825 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1827 ec = e_client_below_get(cw->ec);
1828 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1829 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1830 ec = e_client_below_get(ec);
1831 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1833 evas_object_stack_above(obj, ec->frame);
1838 if (ec && (cw->ec->parent == ec))
1840 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1841 evas_object_stack_above(obj, ec->frame);
1843 evas_object_stack_below(obj, ec->frame);
1846 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1852 if (cw->layer == l) return;
1853 if (e_comp_canvas_client_layer_map(layer) == 9999)
1854 return; //invalid layer for clients not doing comp effects
1855 if (cw->ec->fullscreen)
1857 cw->ec->saved.layer = layer;
1860 oldraise = e_config->transient.raise;
1862 /* clamp to valid client layer */
1863 layer = e_comp_canvas_client_layer_map_nearest(layer);
1864 cw->ec->layer = layer;
1865 if (e_config->transient.layer)
1868 Eina_List *list = eina_list_clone(cw->ec->transients);
1870 /* We need to set raise to one, else the child wont
1871 * follow to the new layer. It should be like this,
1872 * even if the user usually doesn't want to raise
1875 e_config->transient.raise = 1;
1876 EINA_LIST_FREE(list, child)
1878 child_cdata = e_client_cdata_get(child);
1879 if (child_cdata && !child_cdata->mapped)
1881 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1884 e_client_layer_set(child, layer);
1888 e_config->transient.raise = oldraise;
1890 _e_comp_object_layers_remove(cw);
1891 cw->layer = e_comp_canvas_layer_map(layer);
1892 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1893 //if (cw->ec->new_client)
1894 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1895 _e_comp_object_layer_set(obj, layer);
1896 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1897 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1898 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1900 /* can't stack a client above its own layer marker */
1901 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1903 if (!cw->visible) return;
1904 e_comp_render_queue();
1905 _e_comp_object_transform_obj_stack_update(obj);
1909 #ifdef REFACTOR_DESK_AREA
1911 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1914 #ifdef REFACTOR_DESK_AREA
1916 e_comp_object_raise(Evas_Object *obj)
1919 _e_comp_object_raise(Evas_Object *obj)
1922 evas_object_raise(obj);
1924 if (evas_object_smart_smart_get(obj))
1926 E_Client *ec = e_comp_object_client_get(obj);
1928 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1932 #ifdef REFACTOR_DESK_AREA
1934 e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1937 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1940 evas_object_lower(obj);
1942 if (evas_object_smart_smart_get(obj))
1944 E_Client *ec = e_comp_object_client_get(obj);
1947 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1948 #ifdef REFACTOR_DESK_AREA
1949 wl_signal_emit(&cw->events.lower_done, NULL);
1951 wl_signal_emit(&cw->events.lower, NULL);
1957 #ifdef REFACTOR_DESK_AREA
1959 e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1962 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1965 evas_object_stack_above(obj, target);
1967 if (evas_object_smart_smart_get(obj))
1969 E_Client *ec = e_comp_object_client_get(obj);
1971 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1975 #ifdef REFACTOR_DESK_AREA
1977 e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1980 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1983 evas_object_stack_below(obj, target);
1985 if (evas_object_smart_smart_get(obj))
1987 E_Client *ec = e_comp_object_client_get(obj);
1989 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1993 #ifdef REFACTOR_DESK_AREA
1995 e_comp_object_layer_set(Evas_Object *obj, short layer)
1998 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2001 evas_object_layer_set(obj, layer);
2003 if (evas_object_smart_smart_get(obj))
2005 E_Client *ec = e_comp_object_client_get(obj);
2007 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2011 #ifdef REFACTOR_DESK_AREA
2014 _e_comp_object_is_pending(E_Client *ec)
2018 if (!ec) return EINA_FALSE;
2020 topmost = e_comp_wl_topmost_parent_get(ec);
2022 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2026 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2028 E_Comp_Object *cw2 = NULL;
2031 Evas_Object *o = stack;
2032 #ifdef REFACTOR_DESK_AREA
2033 Eina_Bool raising = stack_cb == e_comp_object_stack_above;
2035 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2038 /* We should consider topmost's layer_pending for subsurface */
2039 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2041 if (_e_comp_object_is_pending(cw->ec))
2042 e_comp_object_layer_update(cw->smart_obj,
2043 raising? stack : NULL,
2044 raising? NULL : stack);
2046 /* obey compositor effects! */
2047 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2048 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2049 stack_cb(cw->smart_obj, stack);
2050 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2051 evas_object_data_del(cw->smart_obj, "client_restack");
2055 cw2 = evas_object_data_get(o, "comp_obj");
2057 /* assume someone knew what they were doing during client init */
2058 if (cw->ec->new_client)
2059 layer = cw->ec->layer;
2060 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2061 layer = cw2->ec->layer;
2063 layer = evas_object_layer_get(stack);
2064 ecstack = e_client_below_get(cw->ec);
2065 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2067 evas_object_layer_set(cw->smart_obj, layer);
2068 /* we got our layer wrangled, return now! */
2069 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2072 /* check if we're stacking below another client */
2075 /* check for non-client layer object */
2076 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2078 /* find an existing client to use for layering
2079 * by walking up the object stack
2081 * this is guaranteed to be pretty quick since we'll either:
2082 * - run out of client layers
2083 * - find a stacking client
2085 o = evas_object_above_get(o);
2086 if ((!o) || (o == cw->smart_obj)) break;
2087 if (evas_object_layer_get(o) != layer)
2089 /* reached the top client layer somehow
2090 * use top client object
2092 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2095 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2096 * return here since the top client layer window
2101 ec = e_client_top_get();
2106 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2109 if (cw2 && cw->layer != cw2->layer)
2112 /* remove existing layers */
2113 _e_comp_object_layers_remove(cw);
2116 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2117 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2118 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2119 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2120 else //if no stacking objects found, either raise or lower
2121 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2124 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2126 /* find new object for stacking if cw2 is on state of layer_pending */
2127 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2129 E_Client *new_stack = NULL, *current_ec = NULL;
2130 current_ec = cw2->ec;
2133 while ((new_stack = e_client_below_get(current_ec)))
2135 current_ec = new_stack;
2136 if (new_stack == cw->ec) continue;
2137 if (new_stack->layer != cw2->ec->layer) break;
2138 if (!_e_comp_object_is_pending(new_stack)) break;
2140 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2141 stack = new_stack->frame;
2144 /* stack it above layer object */
2146 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2147 stack = e_comp->layers[below_layer].obj;
2152 while ((new_stack = e_client_above_get(current_ec)))
2154 current_ec = new_stack;
2155 if (new_stack == cw->ec) continue;
2156 if (new_stack->layer != cw2->ec->layer) break;
2157 if (!_e_comp_object_is_pending(new_stack)) break;
2159 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2160 stack = new_stack->frame;
2162 stack = e_comp->layers[cw2->layer].obj;
2166 /* set restack if stacking has changed */
2167 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2168 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2169 stack_cb(cw->smart_obj, stack);
2170 if (e_comp->layers[cw->layer].obj)
2171 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2173 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2175 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2176 evas_object_data_del(cw->smart_obj, "client_restack");
2177 if (!cw->visible) return;
2178 e_comp_render_queue();
2183 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2185 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2187 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2189 #ifdef REFACTOR_DESK_AREA
2190 E_Comp_Object *cw = data;
2191 E_Comp_Object_Data_Stack_Above stack_above_data;
2193 stack_above_data.cw = cw;
2194 stack_above_data.above_obj = above;
2196 wl_signal_emit(&cw->events.stack_above, &stack_above_data);
2198 if (evas_object_below_get(obj) == above)
2200 e_comp_object_layer_update(obj, above, NULL);
2204 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2206 _e_comp_object_transform_obj_stack_update(obj);
2207 _e_comp_object_transform_obj_stack_update(above);
2214 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2216 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2218 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2220 #ifdef REFACTOR_DESK_AREA
2221 E_Comp_Object *cw = data;
2222 E_Comp_Object_Data_Stack_Below stack_below_data;
2224 stack_below_data.cw = cw;
2225 stack_below_data.below_obj = below;
2227 wl_signal_emit(&cw->events.stack_below, &stack_below_data);
2230 e_comp_render_queue();
2232 if (evas_object_above_get(obj) == below)
2234 e_comp_object_layer_update(obj, NULL, below);
2238 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2240 if (evas_object_smart_smart_get(obj))
2241 _e_comp_object_transform_obj_stack_update(obj);
2242 if (evas_object_smart_smart_get(below))
2243 _e_comp_object_transform_obj_stack_update(below);
2250 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2252 E_Comp_Object *cw = data;
2254 #ifdef REFACTOR_DESK_AREA
2259 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2261 #ifdef REFACTOR_DESK_AREA
2262 wl_signal_emit(&cw->events.lower, cw);
2264 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2266 if (cw->ec->layer_pending)
2267 e_comp_object_layer_update(obj, NULL, obj);
2269 #ifdef REFACTOR_DESK_AREA
2270 e_comp_object_lower(cw, obj);
2272 _e_comp_object_lower(cw, obj);
2276 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2277 o = evas_object_below_get(obj);
2278 _e_comp_object_layers_remove(cw);
2279 /* prepend to client list since this client should be the first item now */
2280 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2281 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2282 evas_object_data_set(obj, "client_restack", (void*)1);
2283 #ifdef REFACTOR_DESK_AREA
2284 e_comp_object_lower(cw, obj);
2286 _e_comp_object_lower(cw, obj);
2288 evas_object_data_del(obj, "client_restack");
2289 if (!cw->visible) goto end;
2290 e_comp_render_queue();
2291 #ifdef REFACTOR_DESK_AREA
2292 e_comp_object_transform_obj_stack_update(obj);
2294 _e_comp_object_transform_obj_stack_update(obj);
2303 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2305 E_Comp_Object *cw = data;
2306 #ifdef REFACTOR_DESK_AREA
2312 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2314 #ifdef REFACTOR_DESK_AREA
2315 wl_signal_emit(&cw->events.raise, cw);
2317 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2319 if (cw->ec->layer_pending)
2321 int obj_layer = evas_object_layer_get(obj);
2322 if (cw->ec->layer != obj_layer)
2323 e_comp_object_layer_update(obj, NULL, NULL);
2325 #ifdef REFACTOR_DESK_AREA
2326 e_comp_object_raise(obj);
2328 _e_comp_object_raise(obj);
2332 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2333 o = evas_object_above_get(obj);
2334 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2336 /* still stack below override below the layer marker */
2337 for (op = o = e_comp->layers[cw->layer].obj;
2338 o && o != e_comp->layers[cw->layer - 1].obj;
2339 op = o, o = evas_object_below_get(o))
2341 if (evas_object_smart_smart_get(o))
2345 ec = e_comp_object_client_get(o);
2346 if (ec && (!ec->override)) break;
2349 #ifdef REFACTOR_DESK_AREA
2350 e_comp_object_stack_below(obj, op);
2352 _e_comp_object_stack_below(obj, op);
2354 e_client_focus_defer_set(cw->ec);
2356 if (!cw->visible) goto end;
2357 e_comp_render_queue();
2358 #ifdef REFACTOR_DESK_AREA
2359 e_comp_object_transform_obj_stack_update(obj);
2361 _e_comp_object_transform_obj_stack_update(obj);
2370 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2372 E_Comp_Object *cw = data;
2374 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2375 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2377 ELOGF("COMP", "Hide. intercepted", cw->ec);
2382 if (cw->ec->launching == EINA_TRUE)
2384 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2385 cw->ec->launching = EINA_FALSE;
2386 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,cancel", "e");
2391 /* hidden flag = just do it */
2392 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2393 evas_object_hide(obj);
2395 wl_signal_emit(&cw->events.hide, NULL);
2400 if (cw->ec->input_only)
2402 /* input_only = who cares */
2403 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2404 evas_object_hide(obj);
2406 wl_signal_emit(&cw->events.hide, NULL);
2410 /* already hidden or currently animating */
2411 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2413 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2417 /* don't try hiding during shutdown */
2418 cw->defer_hide |= stopping;
2419 if (!cw->defer_hide)
2421 if ((!cw->ec->iconic) && (!cw->ec->override))
2422 /* unset delete requested so the client doesn't break */
2423 cw->ec->delete_requested = 0;
2424 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2426 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2427 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2430 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2433 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2435 _e_comp_object_animating_begin(cw);
2436 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2438 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2439 cw->defer_hide = !!cw->animating;
2441 e_comp_object_effect_set(obj, NULL);
2444 if (cw->animating) return;
2445 /* if we have no animations running, go ahead and hide */
2447 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2448 evas_object_hide(obj);
2450 wl_signal_emit(&cw->events.hide, NULL);
2454 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2456 E_Client *ec = cw->ec;
2459 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2461 if (ec->show_pending.count > 0)
2463 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2464 ec->show_pending.running = EINA_TRUE;
2468 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2469 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2471 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2476 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,
2477 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2478 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2481 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2484 if (ec->iconic && cw->animating)
2486 /* triggered during iconify animation */
2487 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2490 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2493 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2494 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2496 evas_object_move(cw->smart_obj, ec->x, ec->y);
2497 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2498 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2500 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2501 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2504 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2505 evas_object_show(cw->smart_obj);
2508 e_client_focus_defer_set(ec);
2512 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2516 pw = ec->client.w, ph = ec->client.h;
2518 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2520 ec->changes.visible = !ec->hidden;
2523 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2527 cw->updates = eina_tiler_new(pw, ph);
2530 ec->changes.visible = !ec->hidden;
2533 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2538 eina_tiler_tile_size_set(cw->updates, 1, 1);
2541 /* ignore until client idler first run */
2542 ec->changes.visible = !ec->hidden;
2545 ELOGF("COMP", "show_helper. return. new_client", ec);
2552 evas_object_move(cw->smart_obj, ec->x, ec->y);
2553 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2554 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2555 evas_object_show(cw->smart_obj);
2558 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2560 /* start_drag not received */
2561 ec->changes.visible = 1;
2564 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2567 /* re-set geometry */
2568 evas_object_move(cw->smart_obj, ec->x, ec->y);
2569 /* force resize in case it hasn't happened yet, or just to update size */
2570 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2571 if ((cw->w < 1) || (cw->h < 1))
2573 /* if resize didn't go through, try again */
2574 ec->visible = ec->changes.visible = 1;
2576 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2579 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2580 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2581 e_pixmap_clear(ec->pixmap);
2583 if (cw->real_hid && w && h)
2586 /* force comp theming in case it didn't happen already */
2587 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2588 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2589 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2592 /* only do the show if show is allowed */
2595 if (ec->internal) //internal clients render when they feel like it
2596 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2598 if (!e_client_is_iconified_by_client(ec)||
2599 e_policy_visibility_client_is_uniconic(ec))
2601 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2602 evas_object_show(cw->smart_obj);
2604 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2605 it is rendered in idle callback without native surface and
2606 compositor shows an empty frame if other objects aren't shown
2607 because job callback of e_comp called at the next loop.
2608 it causes a visual defect when windows are switched.
2612 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2613 e_comp_object_dirty(cw->smart_obj);
2614 e_comp_object_render(cw->smart_obj);
2619 wl_signal_emit(&cw->events.show, NULL);
2623 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2625 E_Comp_Object *cw = data;
2626 E_Client *ec = cw->ec;
2628 E_Input_Rect_Data *input_rect_data;
2629 E_Input_Rect_Smart_Data *input_rect_sd;
2632 if (ec->ignored) return;
2636 //INF("SHOW2 %p", ec);
2637 _e_comp_intercept_show_helper(cw);
2640 //INF("SHOW %p", ec);
2643 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2644 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2645 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2646 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2650 if ((!cw->obj) && (cw->external_content))
2652 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2656 _e_comp_object_setup(cw);
2659 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2660 cw->obj = evas_object_image_filled_add(e_comp->evas);
2661 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2662 e_util_size_debug_set(cw->obj, 1);
2663 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2664 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2665 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2666 evas_object_name_set(cw->obj, "cw->obj");
2667 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2668 evas_object_intercept_color_set_callback_add(cw->obj, _e_comp_intercept_obj_color_set, cw);
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 wl_signal_emit(&cw->events.color_set, NULL);
2809 _e_comp_object_color_visible_update(cw);
2812 ////////////////////////////////////////////////////
2815 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2817 int w, h, ox, oy, ow, oh;
2819 Eina_Bool pass_event_flag = EINA_FALSE;
2820 E_Input_Rect_Data *input_rect_data;
2821 E_Input_Rect_Smart_Data *input_rect_sd;
2823 if (cw->frame_object)
2825 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2826 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2827 /* set a fixed size, force edje calc, check size difference */
2828 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2829 edje_object_message_signal_process(cw->frame_object);
2830 edje_object_calc_force(cw->frame_object);
2831 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2832 cw->client_inset.l = ox;
2833 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2834 cw->client_inset.t = oy;
2835 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2836 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2837 evas_object_resize(cw->frame_object, w, h);
2841 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2844 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2846 if (input_rect_data->obj)
2848 pass_event_flag = EINA_TRUE;
2854 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2855 evas_object_pass_events_set(cw->obj, pass_event_flag);
2859 cw->client_inset.l = 0;
2860 cw->client_inset.r = 0;
2861 cw->client_inset.t = 0;
2862 cw->client_inset.b = 0;
2864 cw->client_inset.calc = !!cw->frame_object;
2868 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2870 E_Comp_Object *cw = data;
2874 /* - get current size
2876 * - readjust for new frame size
2879 w = cw->ec->w, h = cw->ec->h;
2880 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2882 _e_comp_object_frame_recalc(cw);
2884 if (!cw->ec->fullscreen)
2885 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2887 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2888 if (cw->ec->fullscreen)
2890 zone = e_comp_zone_find_by_ec(cw->ec);
2892 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2894 else if (cw->ec->new_client)
2896 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2897 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2898 evas_object_resize(cw->ec->frame, w, h);
2900 else if ((w != cw->ec->w) || (h != cw->ec->h))
2901 evas_object_resize(cw->ec->frame, w, h);
2905 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2907 E_Comp_Object *cw = data;
2909 _e_comp_object_shadow_setup(cw);
2910 if (cw->frame_object)
2912 _e_comp_object_shadow(cw);
2913 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2914 _e_comp_object_frame_recalc(cw);
2915 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2920 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2922 E_Comp_Object *cw = data;
2924 if (_e_comp_object_shadow_setup(cw))
2925 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2926 if (cw->frame_object)
2928 _e_comp_object_shadow(cw);
2929 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2930 _e_comp_object_frame_recalc(cw);
2931 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2936 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2938 E_Comp_Object *cw = data;
2940 if (cw->frame_object)
2942 _e_comp_object_shadow(cw);
2943 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2944 _e_comp_object_frame_recalc(cw);
2945 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2950 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2952 E_Comp_Object *cw = data;
2954 if (_e_comp_object_shadow_setup(cw))
2957 cw->ec->changes.size = 1;
2959 if (cw->frame_object)
2961 _e_comp_object_shadow(cw);
2962 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2963 _e_comp_object_frame_recalc(cw);
2964 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2969 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2971 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2975 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2977 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2981 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2983 E_Comp_Object *cw = data;
2985 if (!cw->ec) return; //NYI
2986 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2990 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2992 E_Comp_Object *cw = data;
2994 if (!cw->ec) return; //NYI
2995 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
2999 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3001 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3005 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3007 E_Comp_Object *cw = data;
3009 if (!e_object_is_del(E_OBJECT(cw->ec)))
3010 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3014 _e_comp_input_obj_smart_add(Evas_Object *obj)
3016 E_Input_Rect_Smart_Data *input_rect_sd;
3017 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3019 if (!input_rect_sd) return;
3020 evas_object_smart_data_set(obj, input_rect_sd);
3024 _e_comp_input_obj_smart_del(Evas_Object *obj)
3026 E_Input_Rect_Smart_Data *input_rect_sd;
3027 E_Input_Rect_Data *input_rect_data;
3029 input_rect_sd = evas_object_smart_data_get(obj);
3030 if (!input_rect_sd) return;
3032 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3034 if (input_rect_data->obj)
3036 evas_object_smart_member_del(input_rect_data->obj);
3037 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3039 E_FREE(input_rect_data);
3041 E_FREE(input_rect_sd);
3045 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3047 E_Input_Rect_Smart_Data *input_rect_sd;
3048 E_Input_Rect_Data *input_rect_data;
3052 input_rect_sd = evas_object_smart_data_get(obj);
3053 if (!input_rect_sd) return;
3055 cw = input_rect_sd->cw;
3056 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3058 if (input_rect_data->obj)
3060 evas_object_geometry_set(input_rect_data->obj,
3061 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3062 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3063 input_rect_data->rect.w, input_rect_data->rect.h);
3069 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3071 E_Input_Rect_Smart_Data *input_rect_sd;
3072 E_Input_Rect_Data *input_rect_data;
3076 input_rect_sd = evas_object_smart_data_get(obj);
3077 if (!input_rect_sd) return;
3079 cw = input_rect_sd->cw;
3080 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3082 if (input_rect_data->obj)
3084 evas_object_geometry_set(input_rect_data->obj,
3085 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3086 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3087 input_rect_data->rect.w, input_rect_data->rect.h);
3093 _e_comp_input_obj_smart_show(Evas_Object *obj)
3095 E_Input_Rect_Smart_Data *input_rect_sd;
3096 E_Input_Rect_Data *input_rect_data;
3099 input_rect_sd = evas_object_smart_data_get(obj);
3100 if (!input_rect_sd) return;
3102 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3104 if (input_rect_data->obj)
3106 evas_object_show(input_rect_data->obj);
3112 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3114 E_Input_Rect_Smart_Data *input_rect_sd;
3115 E_Input_Rect_Data *input_rect_data;
3118 input_rect_sd = evas_object_smart_data_get(obj);
3119 if (!input_rect_sd) return;
3121 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3123 if (input_rect_data->obj)
3125 evas_object_hide(input_rect_data->obj);
3131 _e_comp_input_obj_smart_init(void)
3133 if (_e_comp_input_obj_smart) return;
3135 static const Evas_Smart_Class sc =
3137 INPUT_OBJ_SMART_NAME,
3138 EVAS_SMART_CLASS_VERSION,
3139 _e_comp_input_obj_smart_add,
3140 _e_comp_input_obj_smart_del,
3141 _e_comp_input_obj_smart_move,
3142 _e_comp_input_obj_smart_resize,
3143 _e_comp_input_obj_smart_show,
3144 _e_comp_input_obj_smart_hide,
3157 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3163 _e_comp_smart_add(Evas_Object *obj)
3167 cw = E_NEW(E_Comp_Object, 1);
3168 EINA_SAFETY_ON_NULL_RETURN(cw);
3170 wl_signal_init(&cw->events.lower);
3171 #ifdef REFACTOR_DESK_AREA
3172 wl_signal_init(&cw->events.lower_done);
3173 wl_signal_init(&cw->events.raise);
3175 wl_signal_init(&cw->events.show);
3176 wl_signal_init(&cw->events.hide);
3177 #ifdef REFACTOR_DESK_AREA
3178 wl_signal_init(&cw->events.set_layer);
3179 wl_signal_init(&cw->events.stack_above);
3180 wl_signal_init(&cw->events.stack_below);
3182 wl_signal_init(&cw->events.image_filter_set);
3183 wl_signal_init(&cw->events.render_op_set);
3184 wl_signal_init(&cw->events.content_type_set);
3185 wl_signal_init(&cw->events.color_set);
3186 wl_signal_init(&cw->events.color_visible_set);
3188 cw->smart_obj = obj;
3189 cw->x = cw->y = cw->w = cw->h = -1;
3190 evas_object_smart_data_set(obj, cw);
3191 cw->opacity = 255.0;
3192 cw->external_content = 0;
3193 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3194 cw->transform_bg_color.r = 0;
3195 cw->transform_bg_color.g = 0;
3196 cw->transform_bg_color.b = 0;
3197 cw->transform_bg_color.a = 255;
3198 cw->color_visible = EINA_TRUE;
3199 evas_object_data_set(obj, "comp_obj", cw);
3200 evas_object_move(obj, -1, -1);
3201 /* intercept ALL the callbacks! */
3202 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3203 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3204 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3205 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3206 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3207 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3208 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3209 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3210 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3211 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3212 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3214 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3215 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3216 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3217 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3219 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3220 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3222 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3223 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3225 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3227 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3228 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3232 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3235 evas_object_color_set(cw->clip, r, g, b, a);
3236 evas_object_smart_callback_call(obj, "color_set", NULL);
3241 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3244 evas_object_clip_set(cw->clip, clip);
3248 _e_comp_smart_clip_unset(Evas_Object *obj)
3251 evas_object_clip_unset(cw->clip);
3255 _e_comp_smart_hide(Evas_Object *obj)
3257 TRACE_DS_BEGIN(COMP:SMART HIDE);
3262 evas_object_hide(cw->clip);
3263 if (cw->input_obj) evas_object_hide(cw->input_obj);
3264 evas_object_hide(cw->effect_obj);
3265 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3266 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3267 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3274 /* unset native surface if current displaying buffer was destroied */
3275 if (!cw->buffer_destroy_listener.notify)
3277 Evas_Native_Surface *ns;
3278 ns = evas_object_image_native_surface_get(cw->obj);
3279 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3280 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3283 if (!cw->ec->input_only)
3285 edje_object_freeze(cw->effect_obj);
3286 edje_object_freeze(cw->shobj);
3287 edje_object_play_set(cw->shobj, 0);
3288 if (cw->frame_object)
3289 edje_object_play_set(cw->frame_object, 0);
3292 e_comp_render_queue(); //force nocomp recheck
3298 _e_comp_smart_show(Evas_Object *obj)
3306 if ((cw->w < 0) || (cw->h < 0))
3307 CRI("ACK! ec:%p", cw->ec);
3309 TRACE_DS_BEGIN(COMP:SMART SHOW);
3311 e_comp_object_map_update(obj);
3313 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3314 evas_object_show(tmp->frame);
3316 evas_object_show(cw->clip);
3317 if (cw->input_obj) evas_object_show(cw->input_obj);
3318 if (!cw->ec->input_only)
3320 edje_object_thaw(cw->effect_obj);
3321 edje_object_thaw(cw->shobj);
3322 edje_object_play_set(cw->shobj, 1);
3323 if (cw->frame_object)
3324 edje_object_play_set(cw->frame_object, 1);
3326 evas_object_show(cw->effect_obj);
3327 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3328 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3329 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3330 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3331 e_comp_render_queue();
3332 if (cw->ec->input_only)
3337 if (cw->ec->iconic && (!cw->ec->new_client))
3339 if (e_client_is_iconified_by_client(cw->ec))
3341 ELOGF("COMP", "Set launching flag..", cw->ec);
3342 cw->ec->launching = EINA_TRUE;
3345 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3347 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3350 ELOGF("COMP", "Set launching flag..", cw->ec);
3351 cw->ec->launching = EINA_TRUE;
3353 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3354 _e_comp_object_animating_begin(cw);
3355 if (!_e_comp_object_effect_visibility_start(cw, 1))
3361 /* ensure some random effect doesn't lock the client offscreen */
3365 e_comp_object_effect_set(obj, NULL);
3368 _e_comp_object_dim_update(cw);
3374 _e_comp_smart_del(Evas_Object *obj)
3380 if (cw->buffer_destroy_listener.notify)
3382 wl_list_remove(&cw->buffer_destroy_listener.link);
3383 cw->buffer_destroy_listener.notify = NULL;
3386 if (cw->tbm_surface)
3388 tbm_surface_internal_unref(cw->tbm_surface);
3389 cw->tbm_surface = NULL;
3392 if (cw->render_update_lock.buffer_ref.buffer)
3394 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3395 cw->ec, cw->render_update_lock.lock);
3396 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3399 e_comp_object_render_update_del(cw->smart_obj);
3400 E_FREE_FUNC(cw->updates, eina_tiler_free);
3401 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3408 EINA_LIST_FREE(cw->obj_mirror, o)
3410 evas_object_image_data_set(o, NULL);
3411 evas_object_freeze_events_set(o, 1);
3412 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3416 #ifdef REFACTOR_DESK_AREA
3418 _e_comp_object_layers_remove(cw);
3420 l = evas_object_data_get(obj, "comp_object-to_del");
3421 E_FREE_LIST(l, evas_object_del);
3422 _e_comp_object_mouse_event_callback_unset(cw);
3423 evas_object_del(cw->clip);
3424 evas_object_del(cw->obj);
3425 evas_object_del(cw->shobj);
3426 evas_object_del(cw->effect_obj);
3427 evas_object_del(cw->frame_object);
3428 evas_object_del(cw->input_obj);
3429 evas_object_del(cw->mask.obj);
3430 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3431 evas_object_del(cw->transform_bg_obj);
3432 evas_object_del(cw->transform_tranp_obj);
3433 evas_object_del(cw->default_input_obj);
3434 eina_stringshare_del(cw->frame_theme);
3435 eina_stringshare_del(cw->frame_name);
3439 e_comp->animating--;
3441 e_object_unref(E_OBJECT(cw->ec));
3443 cw->ec->frame = NULL;
3448 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3452 cw->x = x, cw->y = y;
3453 evas_object_move(cw->effect_obj, x, y);
3454 evas_object_move(cw->default_input_obj, x, y);
3455 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3457 e_comp_object_map_update(obj);
3461 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3463 Eina_Bool first = EINA_FALSE;
3468 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3470 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3472 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3474 if (cw->w != w || cw->h != h)
3475 e_comp_object_map_update(obj);
3477 first = ((cw->w < 1) || (cw->h < 1));
3478 cw->w = w, cw->h = h;
3482 if (cw->frame_object)
3483 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3486 /* verify pixmap:object size */
3487 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3489 if ((ww != pw) || (hh != ph))
3490 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3492 evas_object_resize(cw->effect_obj, tw, th);
3493 evas_object_resize(cw->default_input_obj, w, h);
3495 evas_object_resize(cw->input_obj, w, h);
3497 evas_object_resize(cw->mask.obj, w, h);
3498 /* resize render update tiler */
3501 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3502 cw->updates_full = 0;
3503 if (cw->updates) eina_tiler_clear(cw->updates);
3507 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3508 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3516 e_comp_render_queue();
3522 _e_comp_smart_init(void)
3524 if (_e_comp_smart) return;
3526 static const Evas_Smart_Class sc =
3529 EVAS_SMART_CLASS_VERSION,
3533 _e_comp_smart_resize,
3536 _e_comp_smart_color_set,
3537 _e_comp_smart_clip_set,
3538 _e_comp_smart_clip_unset,
3548 _e_comp_smart = evas_smart_class_new(&sc);
3553 e_comp_object_init(void)
3555 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3556 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3557 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3558 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3562 e_comp_object_shutdown(void)
3568 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3570 API_ENTRY EINA_FALSE;
3571 return !!cw->force_visible;
3573 /////////////////////////////////////////////////////////
3576 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3579 Eina_Bool comp_object;
3581 comp_object = !!evas_object_data_get(obj, "comp_object");
3586 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3588 e_comp_render_queue();
3590 l = evas_object_data_get(obj, "comp_object-to_del");
3591 E_FREE_LIST(l, evas_object_del);
3595 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3597 if (e_comp_util_object_is_above_nocomp(obj) &&
3598 (!evas_object_data_get(obj, "comp_override")))
3600 evas_object_data_set(obj, "comp_override", (void*)1);
3601 e_comp_override_add();
3606 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3608 Eina_Bool ref = EINA_TRUE;
3609 if (evas_object_visible_get(obj))
3613 d = evas_object_data_del(obj, "comp_hiding");
3615 /* currently trying to hide */
3618 /* already visible */
3622 evas_object_show(obj);
3625 evas_object_ref(obj);
3626 evas_object_data_set(obj, "comp_ref", (void*)1);
3628 edje_object_signal_emit(obj, "e,state,visible", "e");
3629 evas_object_data_set(obj, "comp_showing", (void*)1);
3630 if (e_comp_util_object_is_above_nocomp(obj))
3632 evas_object_data_set(obj, "comp_override", (void*)1);
3633 e_comp_override_add();
3638 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3640 if (!evas_object_visible_get(obj)) return;
3641 /* already hiding */
3642 if (evas_object_data_get(obj, "comp_hiding")) return;
3643 if (!evas_object_data_del(obj, "comp_showing"))
3645 evas_object_ref(obj);
3646 evas_object_data_set(obj, "comp_ref", (void*)1);
3648 edje_object_signal_emit(obj, "e,state,hidden", "e");
3649 evas_object_data_set(obj, "comp_hiding", (void*)1);
3651 if (evas_object_data_del(obj, "comp_override"))
3652 e_comp_override_timed_pop();
3656 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3658 if (!e_util_strcmp(emission, "e,action,hide,done"))
3660 if (!evas_object_data_del(obj, "comp_hiding")) return;
3661 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3662 evas_object_hide(obj);
3663 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3666 evas_object_data_del(obj, "comp_showing");
3667 if (evas_object_data_del(obj, "comp_ref"))
3668 evas_object_unref(obj);
3672 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3678 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3682 E_API E_Comp_Object_Hook *
3683 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3685 E_Comp_Object_Hook *ch;
3687 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3688 ch = E_NEW(E_Comp_Object_Hook, 1);
3689 if (!ch) return NULL;
3690 ch->hookpoint = hookpoint;
3692 ch->data = (void*)data;
3693 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3698 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3701 if (_e_comp_object_hooks_walking == 0)
3703 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3707 _e_comp_object_hooks_delete++;
3710 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3711 E_API E_Comp_Object_Intercept_Hook *
3712 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3714 E_Comp_Object_Intercept_Hook *ch;
3716 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3717 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3718 if (!ch) return NULL;
3719 ch->hookpoint = hookpoint;
3721 ch->data = (void*)data;
3722 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3727 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3730 if (_e_comp_object_intercept_hooks_walking == 0)
3732 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3736 _e_comp_object_intercept_hooks_delete++;
3741 e_comp_object_util_add(Evas_Object *obj)
3745 E_Comp_Config *conf = e_comp_config_get();
3746 Eina_Bool skip = EINA_FALSE;
3752 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3754 name = evas_object_name_get(obj);
3755 vis = evas_object_visible_get(obj);
3756 o = edje_object_add(e_comp->evas);
3757 evas_object_data_set(o, "comp_object", (void*)1);
3759 skip = (!strncmp(name, "noshadow", 8));
3761 evas_object_data_set(o, "comp_object_skip", (void*)1);
3763 if (conf->shadow_style)
3765 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3766 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3769 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3770 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3771 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3773 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3775 evas_object_geometry_get(obj, &x, &y, &w, &h);
3776 evas_object_geometry_set(o, x, y, w, h);
3777 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3779 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3781 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3782 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3783 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3784 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3785 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3786 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3788 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3790 edje_object_part_swallow(o, "e.swallow.content", obj);
3792 _e_comp_object_event_add(o);
3795 evas_object_show(o);
3800 /* utility functions for deleting objects when their "owner" is deleted */
3802 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3807 EINA_SAFETY_ON_NULL_RETURN(to_del);
3808 l = evas_object_data_get(obj, "comp_object-to_del");
3809 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3810 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3811 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3815 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3820 EINA_SAFETY_ON_NULL_RETURN(to_del);
3821 l = evas_object_data_get(obj, "comp_object-to_del");
3823 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3826 /////////////////////////////////////////////////////////
3828 EINTERN Evas_Object *
3829 e_comp_object_client_add(E_Client *ec)
3834 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3835 if (ec->frame) return NULL;
3836 _e_comp_smart_init();
3837 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3838 cw = evas_object_smart_data_get(o);
3839 if (!cw) return NULL;
3840 evas_object_data_set(o, "E_Client", ec);
3843 evas_object_data_set(o, "comp_object", (void*)1);
3845 _e_comp_object_event_add(o);
3850 /* utility functions for getting client inset */
3852 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3855 if (!cw->client_inset.calc)
3861 if (ax) *ax = x - cw->client_inset.l;
3862 if (ay) *ay = y - cw->client_inset.t;
3866 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3869 if (!cw->client_inset.calc)
3875 if (ax) *ax = x + cw->client_inset.l;
3876 if (ay) *ay = y + cw->client_inset.t;
3880 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3883 if (!cw->client_inset.calc)
3889 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3890 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3894 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3897 if (!cw->client_inset.calc)
3903 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3904 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3908 e_comp_object_client_get(Evas_Object *obj)
3913 /* FIXME: remove this when eo is used */
3914 o = evas_object_data_get(obj, "comp_smart_obj");
3916 return e_comp_object_client_get(o);
3917 return cw ? cw->ec : NULL;
3921 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3924 if (cw->frame_extends)
3925 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3930 if (w) *w = cw->ec->w;
3931 if (h) *h = cw->ec->h;
3936 e_comp_object_util_zone_get(Evas_Object *obj)
3938 E_Zone *zone = NULL;
3942 zone = e_comp_zone_find_by_ec(cw->ec);
3947 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3948 zone = e_comp_zone_xy_get(x, y);
3954 e_comp_object_util_center(Evas_Object *obj)
3956 int x, y, w, h, ow, oh;
3961 zone = e_comp_object_util_zone_get(obj);
3962 EINA_SAFETY_ON_NULL_RETURN(zone);
3963 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3964 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3965 ow = cw->ec->w, oh = cw->ec->h;
3967 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3968 x = x + (w - ow) / 2;
3969 y = y + (h - oh) / 2;
3970 evas_object_move(obj, x, y);
3974 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3976 int x, y, w, h, ow, oh;
3979 EINA_SAFETY_ON_NULL_RETURN(on);
3980 evas_object_geometry_get(on, &x, &y, &w, &h);
3981 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3982 ow = cw->ec->w, oh = cw->ec->h;
3984 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3985 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3989 e_comp_object_util_fullscreen(Evas_Object *obj)
3994 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3997 evas_object_move(obj, 0, 0);
3998 evas_object_resize(obj, e_comp->w, e_comp->h);
4003 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4011 ow = cw->w, oh = cw->h;
4013 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4014 zone = e_comp_object_util_zone_get(obj);
4015 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4016 if (x) *x = zx + (zw - ow) / 2;
4017 if (y) *y = zy + (zh - oh) / 2;
4021 e_comp_object_input_objs_del(Evas_Object *obj)
4024 E_Input_Rect_Data *input_rect_data;
4025 E_Input_Rect_Smart_Data *input_rect_sd;
4030 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4031 if (!input_rect_sd) return;
4033 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4035 if (input_rect_data->obj)
4037 evas_object_smart_member_del(input_rect_data->obj);
4038 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4040 E_FREE(input_rect_data);
4045 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4048 E_Input_Rect_Data *input_rect_data = NULL;
4049 E_Input_Rect_Smart_Data *input_rect_sd;
4050 int client_w, client_h;
4052 if (cw->ec->client.w)
4053 client_w = cw->ec->client.w;
4055 client_w = cw->ec->w;
4057 if (cw->ec->client.h)
4058 client_h = cw->ec->client.h;
4060 client_h = cw->ec->h;
4062 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4066 _e_comp_input_obj_smart_init();
4067 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4068 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4069 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4072 input_rect_sd->cw = cw;
4075 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4078 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4079 if (input_rect_data)
4081 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4082 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4086 if ((input_rect_data) &&
4087 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4089 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4090 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4091 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4092 evas_object_clip_set(input_rect_data->obj, cw->clip);
4093 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4094 evas_object_geometry_set(input_rect_data->obj,
4095 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4096 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4097 evas_object_pass_events_set(cw->default_input_obj, 1);
4098 evas_object_pass_events_set(cw->obj, 1);
4101 evas_object_show(input_rect_data->obj);
4102 evas_object_show(cw->input_obj);
4107 evas_object_smart_member_del(cw->input_obj);
4108 E_FREE_FUNC(cw->input_obj, evas_object_del);
4109 evas_object_pass_events_set(cw->default_input_obj, 0);
4110 evas_object_pass_events_set(cw->obj, 0);
4115 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4118 E_Input_Rect_Smart_Data *input_rect_sd;
4119 E_Input_Rect_Data *input_rect_data;
4122 if (!cw->input_obj) return;
4124 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4127 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4129 *list = eina_list_append(*list, &input_rect_data->rect);
4135 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4138 if (l) *l = cw->client_inset.l;
4139 if (r) *r = cw->client_inset.r;
4140 if (t) *t = cw->client_inset.t;
4141 if (b) *b = cw->client_inset.b;
4144 /* set geometry for CSD */
4146 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4152 if (cw->frame_object)
4153 CRI("ACK! ec:%p", cw->ec);
4154 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4155 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4156 calc = cw->client_inset.calc;
4157 cw->client_inset.calc = l || r || t || b;
4158 eina_stringshare_replace(&cw->frame_theme, "borderless");
4159 if (cw->client_inset.calc)
4161 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4162 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4163 e_client_size_set(cw->ec, tw, th);
4165 else if (cw->ec->maximized || cw->ec->fullscreen)
4167 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4168 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4170 if (!cw->ec->new_client)
4172 if (calc && cw->client_inset.calc)
4174 tx = cw->ec->x - (l - cw->client_inset.l);
4175 ty = cw->ec->y - (t - cw->client_inset.t);
4176 e_client_pos_set(cw->ec, tx, ty);
4178 cw->ec->changes.pos = cw->ec->changes.size = 1;
4181 cw->client_inset.l = l;
4182 cw->client_inset.r = r;
4183 cw->client_inset.t = t;
4184 cw->client_inset.b = b;
4188 e_comp_object_frame_allowed(Evas_Object *obj)
4190 API_ENTRY EINA_FALSE;
4191 return (cw->frame_object || (!cw->client_inset.calc));
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);
4649 cw->transparent.user_r = r;
4650 cw->transparent.user_g = g;
4651 cw->transparent.user_b = b;
4652 cw->transparent.user_a = a;
4654 cw->transparent.setting = EINA_TRUE;
4655 evas_object_color_set(obj, 0, 0, 0, 0);
4656 cw->transparent.setting = EINA_FALSE;
4658 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4660 cw->transparent.user_r,
4661 cw->transparent.user_g,
4662 cw->transparent.user_b,
4663 cw->transparent.user_a);
4665 cw->transparent.set = EINA_TRUE;
4669 cw->transparent.set = EINA_FALSE;
4671 evas_object_color_set(obj,
4672 cw->transparent.user_r,
4673 cw->transparent.user_g,
4674 cw->transparent.user_b,
4675 cw->transparent.user_a);
4677 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4679 cw->transparent.user_r,
4680 cw->transparent.user_g,
4681 cw->transparent.user_b,
4682 cw->transparent.user_a);
4688 /* helper function to simplify toggling of redirection for display servers which support it */
4690 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4695 if (cw->redirected == set) return;
4696 cw->redirected = set;
4697 if (cw->external_content) return;
4699 e_comp_object_map_update(obj);
4703 if (cw->updates_exist)
4704 e_comp_object_render_update_add(obj);
4706 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4708 _e_comp_object_transparent_set(obj, EINA_FALSE);
4709 evas_object_smart_callback_call(obj, "redirected", NULL);
4713 _e_comp_object_clear(cw);
4714 _e_comp_object_transparent_set(obj, EINA_TRUE);
4715 evas_object_smart_callback_call(obj, "unredirected", NULL);
4720 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4723 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4725 if (cw->buffer_destroy_listener.notify)
4727 cw->buffer_destroy_listener.notify = NULL;
4728 wl_list_remove(&cw->buffer_destroy_listener.link);
4731 if (e_object_is_del(E_OBJECT(cw->ec)))
4733 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4738 /* if it's current displaying buffer, do not remove its content */
4739 if (!evas_object_visible_get(cw->ec->frame))
4740 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4745 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4750 if (cw->buffer_destroy_listener.notify)
4752 wl_list_remove(&cw->buffer_destroy_listener.link);
4753 cw->buffer_destroy_listener.notify = NULL;
4756 if (cw->tbm_surface)
4758 tbm_surface_internal_unref(cw->tbm_surface);
4759 cw->tbm_surface = NULL;
4764 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4766 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4767 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4769 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4771 tbm_surface_internal_ref(ns->data.tbm.buffer);
4772 cw->tbm_surface = ns->data.tbm.buffer;
4776 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4777 evas_object_image_native_surface_set(cw->obj, ns);
4781 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4783 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4784 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4785 evas_object_image_native_surface_set(o, ns);
4792 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4794 Evas_Native_Surface ns;
4797 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4798 if (cw->ec->input_only) return;
4799 if (cw->external_content) return;
4800 if (cw->render_update_lock.lock) return;
4803 memset(&ns, 0, sizeof(Evas_Native_Surface));
4807 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4808 set = (!cw->ec->shaped);
4810 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4814 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4818 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4821 if (cw->ec->input_only) return;
4824 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4825 _e_comp_object_alpha_set(cw);
4827 e_comp_object_native_surface_set(obj, cw->native);
4828 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4832 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4838 if (cw->blanked == set) return;
4840 _e_comp_object_alpha_set(cw);
4843 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4844 evas_object_image_data_set(cw->obj, NULL);
4848 e_comp_object_native_surface_set(obj, 1);
4849 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4853 _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)
4858 if (!_damage_trace) return;
4862 if (!evas_object_visible_get(cw->obj)) return;
4864 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4866 o = evas_object_rectangle_add(e_comp->evas);
4867 evas_object_layer_set(o, E_LAYER_MAX);
4868 evas_object_name_set(o, "damage_trace");
4869 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4870 evas_object_resize(o, dmg_w, dmg_h);
4871 evas_object_color_set(o, 0, 128, 0, 128);
4872 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4873 evas_object_pass_events_set(o, EINA_TRUE);
4874 evas_object_show(o);
4876 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4878 dmg_w, dmg_h, dmg_x, dmg_y,
4879 origin->w, origin->h, origin->x, origin->y);
4881 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4884 /* mark an object as dirty and setup damages */
4886 e_comp_object_dirty(Evas_Object *obj)
4889 Eina_Rectangle *rect;
4893 Eina_Bool dirty, visible;
4897 if (cw->external_content) return;
4898 if (!cw->redirected) return;
4899 if (cw->render_update_lock.lock)
4901 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4904 /* only actually dirty if pixmap is available */
4905 if (!e_pixmap_resource_get(cw->ec->pixmap))
4907 // e_pixmap_size_get returns last attached buffer size
4908 // eventhough it is destroyed
4909 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4912 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4913 visible = cw->visible;
4914 if (!dirty) w = h = 1;
4915 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4917 evas_object_image_data_set(cw->obj, NULL);
4918 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4919 evas_object_image_size_set(cw->obj, tw, th);
4920 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4921 if (cw->pending_updates)
4922 eina_tiler_area_size_set(cw->pending_updates, w, h);
4923 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4925 evas_object_image_pixels_dirty_set(o, dirty);
4927 evas_object_image_data_set(o, NULL);
4928 evas_object_image_size_set(o, tw, th);
4929 visible |= evas_object_visible_get(o);
4933 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4937 e_comp_object_native_surface_set(obj, 1);
4939 m = _e_comp_object_map_damage_transform_get(cw->ec);
4940 it = eina_tiler_iterator_new(cw->updates);
4941 EINA_ITERATOR_FOREACH(it, rect)
4943 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4944 * of evas engine and doesn't convert damage according to evas_map.
4945 * so damage of evas_object_image use surface coordinate.
4949 int damage_x, damage_y, damage_w, damage_h;
4951 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4952 &damage_x, &damage_y, &damage_w, &damage_h);
4953 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4954 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4958 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4959 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4962 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4963 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4964 if (cw->pending_updates)
4965 eina_tiler_rect_add(cw->pending_updates, rect);
4967 eina_iterator_free(it);
4968 if (m) e_map_free(m);
4969 if (cw->pending_updates)
4970 eina_tiler_clear(cw->updates);
4973 cw->pending_updates = cw->updates;
4974 cw->updates = eina_tiler_new(w, h);
4975 eina_tiler_tile_size_set(cw->updates, 1, 1);
4977 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4978 evas_object_smart_callback_call(obj, "dirty", NULL);
4979 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4980 /* force render if main object is hidden but mirrors are visible */
4981 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4982 e_comp_object_render(obj);
4986 e_comp_object_render(Evas_Object *obj)
4993 API_ENTRY EINA_FALSE;
4995 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
4996 if (cw->ec->input_only) return EINA_TRUE;
4997 if (cw->external_content) return EINA_TRUE;
4998 if (cw->native) return EINA_FALSE;
4999 /* if comp object is not redirected state, comp object should not be set by newly committed data
5000 because image size of comp object is 1x1 and it should not be shown on canvas */
5001 if (!cw->redirected) return EINA_TRUE;
5002 if (cw->render_update_lock.lock)
5004 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5007 e_comp_object_render_update_del(obj);
5008 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5010 if (!cw->pending_updates)
5012 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5013 evas_object_image_data_set(cw->obj, NULL);
5014 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5015 evas_object_image_data_set(o, NULL);
5019 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5021 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5023 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5026 e_pixmap_image_refresh(cw->ec->pixmap);
5027 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5030 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5031 e_pixmap_image_data_ref(cw->ec->pixmap);
5033 /* set pixel data */
5034 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5035 _e_comp_object_alpha_set(cw);
5036 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5038 evas_object_image_data_set(o, pix);
5039 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5040 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5043 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5045 e_comp_client_post_update_add(cw->ec);
5050 /* create a duplicate of an evas object */
5052 e_comp_object_util_mirror_add(Evas_Object *obj)
5056 unsigned int *pix = NULL;
5057 Eina_Bool argb = EINA_FALSE;
5062 cw = evas_object_data_get(obj, "comp_mirror");
5065 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5066 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5067 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5068 evas_object_image_alpha_set(o, 1);
5069 evas_object_image_source_set(o, obj);
5072 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5073 if (cw->external_content)
5075 ERR("%p of client %p is external content.", obj, cw->ec);
5078 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5079 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5080 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5081 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5082 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5083 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5084 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5085 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5086 evas_object_data_set(o, "comp_mirror", cw);
5088 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5089 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5091 evas_object_image_size_set(o, tw, th);
5094 pix = evas_object_image_data_get(cw->obj, 0);
5100 evas_object_image_native_surface_set(o, cw->ns);
5103 Evas_Native_Surface ns;
5104 memset(&ns, 0, sizeof(Evas_Native_Surface));
5105 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5106 evas_object_image_native_surface_set(o, &ns);
5111 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5112 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5114 (e_pixmap_image_exists(cw->ec->pixmap)))
5115 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5117 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5124 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5125 evas_object_image_pixels_dirty_set(o, dirty);
5126 evas_object_image_data_set(o, pix);
5127 evas_object_image_data_set(cw->obj, pix);
5129 evas_object_image_data_update_add(o, 0, 0, tw, th);
5134 //////////////////////////////////////////////////////
5137 e_comp_object_effect_allowed_get(Evas_Object *obj)
5139 API_ENTRY EINA_FALSE;
5141 if (!cw->shobj) return EINA_FALSE;
5142 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5143 return !e_comp_config_get()->match.disable_borders;
5146 /* setup an api effect for a client */
5148 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5151 Eina_Stringshare *grp;
5152 E_Comp_Config *config;
5153 Eina_Bool loaded = EINA_FALSE;
5155 API_ENTRY EINA_FALSE;
5156 if (!cw->shobj) return EINA_FALSE; //input window
5158 if (!effect) effect = "none";
5159 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5161 config = e_comp_config_get();
5162 if ((config) && (config->effect_file))
5164 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5166 cw->effect_set = EINA_TRUE;
5173 edje_object_file_get(cw->effect_obj, NULL, &grp);
5174 cw->effect_set = !eina_streq(effect, "none");
5175 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5176 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5178 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5179 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5180 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5182 if (cw->effect_running)
5184 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5187 cw->effect_set = EINA_FALSE;
5188 return cw->effect_set;
5192 if (cw->effect_running)
5194 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5197 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5198 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5199 if (cw->effect_clip)
5201 evas_object_clip_unset(cw->clip);
5202 cw->effect_clip = 0;
5204 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5206 _e_comp_object_dim_update(cw);
5208 return cw->effect_set;
5211 /* set params for embryo scripts in effect */
5213 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5215 Edje_Message_Int_Set *msg;
5219 EINA_SAFETY_ON_NULL_RETURN(params);
5220 EINA_SAFETY_ON_FALSE_RETURN(count);
5221 if (!cw->effect_set) return;
5223 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5224 msg->count = (int)count;
5225 for (x = 0; x < count; x++)
5226 msg->val[x] = params[x];
5227 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5228 edje_object_message_signal_process(cw->effect_obj);
5232 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5234 Edje_Signal_Cb end_cb;
5236 E_Comp_Object *cw = data;
5238 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5239 cw->effect_running = 0;
5240 if (!_e_comp_object_animating_end(cw)) return;
5242 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5244 evas_object_data_del(cw->smart_obj, "effect_running");
5245 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5246 e_comp_visibility_calculation_set(EINA_TRUE);
5249 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5250 if (!end_cb) return;
5251 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5252 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5253 end_cb(end_data, cw->smart_obj, emission, source);
5256 /* clip effect to client's zone */
5258 e_comp_object_effect_clip(Evas_Object *obj)
5262 zone = e_comp_zone_find_by_ec(cw->ec);
5264 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5265 if (!cw->effect_clip_able) return;
5266 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5267 cw->effect_clip = 1;
5270 /* unclip effect from client's zone */
5272 e_comp_object_effect_unclip(Evas_Object *obj)
5275 if (!cw->effect_clip) return;
5276 evas_object_clip_unset(cw->smart_obj);
5277 cw->effect_clip = 0;
5280 /* start effect, running end_cb after */
5282 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5284 API_ENTRY EINA_FALSE;
5285 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5286 if (!cw->effect_set) return EINA_FALSE;
5288 if (cw->effect_running)
5290 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5293 e_comp_object_effect_clip(obj);
5294 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5296 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5297 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5298 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5299 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5301 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5302 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5304 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5305 _e_comp_object_animating_begin(cw);
5306 cw->effect_running = 1;
5310 /* stop a currently-running effect immediately */
5312 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5315 Edje_Signal_Cb end_cb_before = NULL;
5316 void *end_data_before = NULL;
5317 API_ENTRY EINA_FALSE;
5319 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5320 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5322 if (end_cb_before != end_cb) return EINA_TRUE;
5323 e_comp_object_effect_unclip(obj);
5324 if (cw->effect_clip)
5326 evas_object_clip_unset(cw->effect_obj);
5327 cw->effect_clip = 0;
5329 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5330 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5332 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5334 evas_object_data_del(cw->smart_obj, "effect_running");
5335 e_comp_visibility_calculation_set(EINA_TRUE);
5338 cw->effect_running = 0;
5339 ret = _e_comp_object_animating_end(cw);
5341 if ((ret) && (end_cb_before))
5343 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5344 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5351 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5353 return a->pri - b->pri;
5356 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5357 E_API E_Comp_Object_Mover *
5358 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5360 E_Comp_Object_Mover *prov;
5362 prov = E_NEW(E_Comp_Object_Mover, 1);
5363 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5364 prov->func = provider;
5365 prov->data = (void*)data;
5368 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5369 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5374 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5376 EINA_SAFETY_ON_NULL_RETURN(prov);
5377 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5382 e_comp_object_effect_object_get(Evas_Object *obj)
5386 return cw->effect_obj;
5390 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5392 API_ENTRY EINA_FALSE;
5393 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5394 if (!cw->effect_set) return EINA_FALSE;
5401 ////////////////////////////////////
5404 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5406 if (e_comp->autoclose.obj)
5408 e_comp_ungrab_input(0, 1);
5409 if (e_comp->autoclose.del_cb)
5410 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5411 else if (!already_del)
5413 evas_object_hide(e_comp->autoclose.obj);
5414 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5416 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5418 e_comp->autoclose.obj = NULL;
5419 e_comp->autoclose.data = NULL;
5420 e_comp->autoclose.del_cb = NULL;
5421 e_comp->autoclose.key_cb = NULL;
5422 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5426 _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)
5428 _e_comp_object_autoclose_cleanup(0);
5432 _e_comp_object_autoclose_setup(Evas_Object *obj)
5434 if (!e_comp->autoclose.rect)
5436 /* create rect just below autoclose object to catch mouse events */
5437 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5438 evas_object_move(e_comp->autoclose.rect, 0, 0);
5439 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5440 evas_object_show(e_comp->autoclose.rect);
5441 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5442 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5443 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5444 e_comp_grab_input(0, 1);
5446 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5447 evas_object_focus_set(obj, 1);
5451 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5453 _e_comp_object_autoclose_setup(obj);
5454 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5458 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5460 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5461 _e_comp_object_autoclose_cleanup(1);
5462 if (e_client_focused_get()) return;
5464 E_Zone *zone = e_zone_current_get();
5467 e_zone_focus_reset(zone);
5471 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5475 if (e_comp->autoclose.obj)
5477 if (e_comp->autoclose.obj == obj) return;
5478 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5479 e_comp->autoclose.obj = obj;
5480 e_comp->autoclose.del_cb = del_cb;
5481 e_comp->autoclose.key_cb = cb;
5482 e_comp->autoclose.data = (void*)data;
5483 if (evas_object_visible_get(obj))
5484 _e_comp_object_autoclose_setup(obj);
5486 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5487 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5490 e_comp->autoclose.obj = obj;
5491 e_comp->autoclose.del_cb = del_cb;
5492 e_comp->autoclose.key_cb = cb;
5493 e_comp->autoclose.data = (void*)data;
5494 if (evas_object_visible_get(obj))
5495 _e_comp_object_autoclose_setup(obj);
5497 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5498 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5502 e_comp_object_is_animating(Evas_Object *obj)
5506 return cw->animating;
5510 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5514 if ((cw->external_content) &&
5515 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5517 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5518 "But current external content is %d object for %p.",
5519 cw->content_type, cw->ec);
5523 cw->user_alpha_set = EINA_TRUE;
5524 cw->user_alpha = alpha;
5526 if (!cw->obj) return;
5528 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5530 evas_object_image_alpha_set(cw->obj, alpha);
5532 if ((!cw->native) && (!cw->external_content))
5533 evas_object_image_data_set(cw->obj, NULL);
5537 e_comp_object_alpha_get(Evas_Object *obj)
5539 API_ENTRY EINA_FALSE;
5541 return evas_object_image_alpha_get(cw->obj);
5545 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5547 Eina_Bool mask_set = EINA_FALSE;
5551 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5552 if (cw->ec->input_only) return;
5559 o = evas_object_rectangle_add(e_comp->evas);
5560 evas_object_color_set(o, 0, 0, 0, 0);
5561 evas_object_clip_set(o, cw->clip);
5562 evas_object_smart_member_add(o, obj);
5563 evas_object_move(o, 0, 0);
5564 evas_object_resize(o, cw->w, cw->h);
5565 /* save render op value to restore when clear a mask.
5567 * NOTE: DO NOT change the render op on ec->frame while mask object
5568 * is set. it will overwrite the changed op value. */
5569 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5570 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5571 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5572 if (cw->visible) evas_object_show(o);
5575 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5576 ELOGF("COMP", " |mask_obj", cw->ec);
5577 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5584 evas_object_smart_member_del(cw->mask.obj);
5585 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5587 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5588 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5594 e_comp_object_mask_has(Evas_Object *obj)
5596 API_ENTRY EINA_FALSE;
5598 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5602 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5607 if ((cw->external_content) &&
5608 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5610 WRN("Can set up size to ONLY evas \"image\" object. "
5611 "But current external content is %d object for %p.",
5612 cw->content_type, cw->ec);
5616 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5618 evas_object_image_size_set(cw->obj, tw, th);
5622 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5624 Eina_Bool transform_set = EINA_FALSE;
5626 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5627 if (cw->ec->input_only) return;
5629 transform_set = !!set;
5633 if (!cw->transform_bg_obj)
5635 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5636 evas_object_move(o, 0, 0);
5637 evas_object_resize(o, 1, 1);
5638 if (cw->transform_bg_color.a >= 255)
5639 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5641 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5642 evas_object_color_set(o,
5643 cw->transform_bg_color.r,
5644 cw->transform_bg_color.g,
5645 cw->transform_bg_color.b,
5646 cw->transform_bg_color.a);
5647 if (cw->visible) evas_object_show(o);
5649 cw->transform_bg_obj = o;
5650 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5652 #ifdef REFACTOR_DESK_AREA
5653 e_comp_object_transform_obj_stack_update(obj);
5655 _e_comp_object_transform_obj_stack_update(obj);
5660 if (cw->transform_bg_obj)
5662 evas_object_smart_member_del(cw->transform_bg_obj);
5663 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5669 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5673 cw->transform_bg_color.r = r;
5674 cw->transform_bg_color.g = g;
5675 cw->transform_bg_color.b = b;
5676 cw->transform_bg_color.a = a;
5678 if (cw->transform_bg_obj)
5680 evas_object_color_set(cw->transform_bg_obj,
5681 cw->transform_bg_color.r,
5682 cw->transform_bg_color.g,
5683 cw->transform_bg_color.b,
5684 cw->transform_bg_color.a);
5689 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5692 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5693 if (cw->ec->input_only) return;
5694 if (!cw->transform_bg_obj) return;
5696 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5700 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5703 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5704 if (cw->ec->input_only) return;
5705 if (!cw->transform_bg_obj) return;
5707 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5711 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5713 Eina_Bool transform_set = EINA_FALSE;
5715 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5716 if (cw->ec->input_only) return;
5718 transform_set = !!set;
5722 if (!cw->transform_tranp_obj)
5724 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5725 evas_object_move(o, 0, 0);
5726 evas_object_resize(o, 1, 1);
5727 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5728 evas_object_color_set(o, 0, 0, 0, 0);
5729 if (cw->visible) evas_object_show(o);
5731 cw->transform_tranp_obj = o;
5732 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5733 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5734 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5736 #ifdef REFACTOR_DESK_AREA
5737 e_comp_object_transform_obj_stack_update(obj);
5739 _e_comp_object_transform_obj_stack_update(obj);
5744 if (cw->transform_tranp_obj)
5746 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5747 evas_object_smart_member_del(cw->transform_tranp_obj);
5748 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5754 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
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(cw->transform_tranp_obj, vertices);
5765 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5768 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5769 if (cw->ec->input_only) return;
5770 if (!cw->transform_tranp_obj) return;
5772 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5775 #ifdef REFACTOR_DESK_AREA
5778 e_comp_object_layer_update(Evas_Object *obj,
5779 Evas_Object *above, Evas_Object *below)
5781 E_Comp_Object *cw2 = NULL;
5782 Evas_Object *o = NULL;
5787 if (cw->ec->layer_block) return;
5788 if ((above) && (below))
5790 ERR("Invalid layer update request! cw=%p", cw);
5798 layer = evas_object_layer_get(o);
5799 cw2 = evas_object_data_get(o, "comp_obj");
5802 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5804 o = evas_object_above_get(o);
5805 if ((!o) || (o == cw->smart_obj)) break;
5806 if (evas_object_layer_get(o) != layer)
5808 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5813 ec = e_client_top_get();
5814 if (ec) o = ec->frame;
5817 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5821 _e_comp_object_layers_remove(cw);
5824 if (cw2->layer > cw->layer)
5825 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5826 else if (cw2->layer == cw->layer)
5829 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5831 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5833 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5836 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5839 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5844 e_comp_object_layer_get(Evas_Object *obj)
5851 e_comp_object_content_set(Evas_Object *obj,
5852 Evas_Object *content,
5853 E_Comp_Object_Content_Type type)
5855 API_ENTRY EINA_FALSE;
5857 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5858 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5859 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5863 ERR("Can't set e.swallow.content to requested content. "
5864 "Previous comp object should not be changed at all.");
5868 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5870 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5871 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5873 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5874 type, content, cw->ec, cw->ec->pixmap);
5878 cw->external_content = EINA_TRUE;
5881 cw->content_type = type;
5882 e_util_size_debug_set(cw->obj, 1);
5883 evas_object_name_set(cw->obj, "cw->obj");
5884 _e_comp_object_alpha_set(cw);
5887 _e_comp_object_shadow_setup(cw);
5889 wl_signal_emit(&cw->events.content_type_set, NULL);
5895 e_comp_object_content_unset(Evas_Object *obj)
5897 API_ENTRY EINA_FALSE;
5899 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5900 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5902 if (!cw->obj && !cw->ec->visible)
5904 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5908 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5910 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5916 if (cw->frame_object)
5917 edje_object_part_unswallow(cw->frame_object, cw->obj);
5919 edje_object_part_unswallow(cw->shobj, cw->obj);
5921 evas_object_del(cw->obj);
5922 evas_object_hide(cw->obj);
5926 cw->external_content = EINA_FALSE;
5927 if (cw->ec->is_cursor)
5930 DBG("%p is cursor surface..", cw->ec);
5931 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5933 evas_object_resize(cw->ec->frame, pw, ph);
5934 evas_object_hide(cw->ec->frame);
5939 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5940 cw->obj = evas_object_image_filled_add(e_comp->evas);
5941 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5942 e_util_size_debug_set(cw->obj, 1);
5943 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5944 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5945 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5946 evas_object_name_set(cw->obj, "cw->obj");
5947 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5948 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_obj_color_set, cw);
5949 _e_comp_object_alpha_set(cw);
5952 _e_comp_object_shadow_setup(cw);
5957 _e_comp_intercept_show_helper(cw);
5961 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5962 e_comp_object_dirty(cw->smart_obj);
5963 e_comp_object_render(cw->smart_obj);
5964 e_comp_object_render_update_add(obj);
5966 wl_signal_emit(&cw->events.content_type_set, NULL);
5971 EINTERN Evas_Object *
5972 e_comp_object_content_get(Evas_Object *obj)
5976 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5978 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5980 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
5987 E_API E_Comp_Object_Content_Type
5988 e_comp_object_content_type_get(Evas_Object *obj)
5990 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
5992 return cw->content_type;
5996 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
5999 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6000 E_Comp_Config *conf = e_comp_config_get();
6001 if (cw->ec->input_only) return;
6002 if (!conf->dim_rect_enable) return;
6004 cw->dim.mask_set = mask_set;
6010 if (!cw->dim.enable) return;
6011 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6015 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6017 Eina_Bool mask_set = EINA_FALSE;
6021 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6022 E_Comp_Config *conf = e_comp_config_get();
6023 if (cw->ec->input_only) return;
6024 if (!conf->dim_rect_enable) return;
6030 if (cw->dim.mask_obj)
6032 evas_object_smart_member_del(cw->dim.mask_obj);
6033 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6036 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);
6037 o = evas_object_rectangle_add(e_comp->evas);
6038 evas_object_color_set(o, 0, 0, 0, 0);
6039 evas_object_smart_member_add(o, obj);
6040 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6041 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6043 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6044 if (cw->visible) evas_object_show(o);
6046 cw->dim.mask_obj = o;
6047 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6049 evas_object_layer_set(cw->dim.mask_obj, 9998);
6053 if (cw->dim.mask_obj)
6055 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6056 evas_object_smart_member_del(cw->dim.mask_obj);
6057 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6063 e_comp_object_dim_client_set(E_Client *ec)
6065 E_Comp_Config *conf = e_comp_config_get();
6067 if (!conf->dim_rect_enable) return ;
6068 if (dim_client == ec) return;
6070 Eina_Bool prev_dim = EINA_FALSE;
6071 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6073 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6074 prev_dim = EINA_TRUE;
6076 if (prev_dim && dim_client->visible && ec)
6078 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6079 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6083 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6084 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6090 e_comp_object_dim_client_get(void)
6092 E_Comp_Config *conf = e_comp_config_get();
6094 if (!conf->dim_rect_enable ) return NULL;
6100 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6103 char emit[32] = "\0";
6104 E_Comp_Config *conf = e_comp_config_get();
6107 if (!conf->dim_rect_enable) return;
6108 if (!cw->effect_obj) return;
6109 if (enable == cw->dim.enable) return;
6111 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6112 if (noeffect || !conf->dim_rect_effect)
6114 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6118 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6121 cw->dim.enable = enable;
6123 if (cw->dim.mask_set && !enable)
6125 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6126 edje_object_signal_emit(cw->effect_obj, emit, "e");
6128 else if (cw->dim.mask_set && enable)
6130 edje_object_signal_emit(cw->effect_obj, emit, "e");
6131 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6135 edje_object_signal_emit(cw->effect_obj, emit, "e");
6140 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6142 API_ENTRY EINA_FALSE;
6143 E_Comp_Config *conf = e_comp_config_get();
6145 if (!ec) return EINA_FALSE;
6146 if (!conf->dim_rect_enable) return EINA_FALSE;
6148 if (cw->dim.enable) return EINA_TRUE;
6154 _e_comp_object_dim_update(E_Comp_Object *cw)
6156 E_Comp_Config *conf = e_comp_config_get();
6159 if (!conf->dim_rect_enable) return;
6160 if (!cw->effect_obj) return;
6163 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6164 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6166 if (cw->dim.mask_set)
6168 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6174 e_comp_object_clear(Evas_Object *obj)
6178 _e_comp_object_clear(cw);
6182 e_comp_object_hwc_update_exists(Evas_Object *obj)
6184 API_ENTRY EINA_FALSE;
6185 return cw->hwc_need_update;
6190 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6193 cw->hwc_need_update = set;
6197 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6199 API_ENTRY EINA_FALSE;
6200 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6204 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6207 if (cw->indicator.obj != indicator)
6208 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6209 cw->indicator.obj = indicator;
6210 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6214 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6217 if (cw->indicator.obj != indicator) return;
6218 cw->indicator.obj = NULL;
6219 edje_object_part_unswallow(cw->shobj, indicator);
6223 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6226 Edje_Message_Int_Set *msg;
6228 if (!cw->indicator.obj) return;
6230 cw->indicator.w = w;
6231 cw->indicator.h = h;
6233 if (!cw->shobj) return;
6235 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6239 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6240 edje_object_message_signal_process(cw->shobj);
6243 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6245 e_comp_object_map_update(Evas_Object *obj)
6248 E_Client *ec = cw->ec;
6249 E_Comp_Wl_Client_Data *cdata;
6251 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6254 int l, remain = sizeof buffer;
6257 if (e_object_is_del(E_OBJECT(ec))) return;
6258 cdata = e_client_cdata_get(ec);
6261 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6262 * when new buffer is attached.
6264 if (!cdata->buffer_ref.buffer) return;
6266 if ((!cw->redirected) ||
6267 (e_client_video_hw_composition_check(ec)) ||
6268 (!e_comp_wl_output_buffer_transform_get(ec) &&
6269 cdata->scaler.buffer_viewport.buffer.scale == 1))
6271 if (evas_object_map_enable_get(cw->effect_obj))
6273 ELOGF("TRANSFORM", "map: disable", cw->ec);
6274 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6275 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6276 evas_object_resize(cw->effect_obj, tw, th);
6283 EINA_SAFETY_ON_NULL_RETURN(map);
6285 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6291 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6293 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6294 e_map_point_image_uv_set(map, 0, x, y);
6295 l = snprintf(p, remain, "%d,%d", x, y);
6296 p += l, remain -= l;
6298 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6299 e_map_point_image_uv_set(map, 1, x, y);
6300 l = snprintf(p, remain, " %d,%d", x, y);
6301 p += l, remain -= l;
6303 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6304 e_map_point_image_uv_set(map, 2, x, y);
6305 l = snprintf(p, remain, " %d,%d", x, y);
6306 p += l, remain -= l;
6308 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6309 e_map_point_image_uv_set(map, 3, x, y);
6310 l = snprintf(p, remain, " %d,%d", x, y);
6311 p += l, remain -= l;
6313 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6315 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6317 e_comp_object_map_set(cw->effect_obj, map);
6318 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6322 /* if there's screen rotation with comp mode, then ec->effect_obj and
6323 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6325 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6326 evas_object_resize(cw->effect_obj, tw, th);
6330 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6332 API_ENTRY EINA_FALSE;
6334 cw->render_trace = set;
6340 e_comp_object_native_usable_get(Evas_Object *obj)
6342 API_ENTRY EINA_FALSE;
6343 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6345 if (cw->ec->input_only) return EINA_FALSE;
6346 if (cw->external_content) return EINA_FALSE;
6347 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6349 /* just return true value, if it is normal case */
6350 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6353 Evas_Native_Surface *ns;
6354 ns = evas_object_image_native_surface_get(cw->obj);
6356 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6359 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6367 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6369 API_ENTRY EINA_FALSE;
6370 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6371 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6372 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6374 if (cw->image_filter == filter) return EINA_TRUE;
6378 case E_COMP_IMAGE_FILTER_BLUR:
6379 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6381 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6382 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6384 case E_COMP_IMAGE_FILTER_INVERSE:
6385 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6387 case E_COMP_IMAGE_FILTER_NONE:
6389 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6393 cw->image_filter = filter;
6395 wl_signal_emit(&cw->events.image_filter_set, NULL);
6400 EINTERN E_Comp_Image_Filter
6401 e_comp_object_image_filter_get(Evas_Object *obj)
6403 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6404 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6405 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6406 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6408 return cw->image_filter;
6412 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6416 if (!_damage_trace) return;
6418 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6419 evas_object_del(obj);
6421 _damage_trace_post_objs = NULL;
6425 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6427 if (!_damage_trace) return;
6429 _damage_trace_post_objs = _damage_trace_objs;
6430 _damage_trace_objs = NULL;
6434 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6436 if (_damage_trace == onoff) return;
6440 evas_event_callback_add(e_comp->evas,
6441 EVAS_CALLBACK_RENDER_PRE,
6442 _e_comp_object_damage_trace_render_pre_cb,
6445 evas_event_callback_add(e_comp->evas,
6446 EVAS_CALLBACK_RENDER_POST,
6447 _e_comp_object_damage_trace_render_post_cb,
6454 EINA_LIST_FREE(_damage_trace_objs, obj)
6455 evas_object_del(obj);
6457 _damage_trace_objs = NULL;
6459 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6460 evas_object_del(obj);
6462 _damage_trace_post_objs = NULL;
6464 evas_event_callback_del(e_comp->evas,
6465 EVAS_CALLBACK_RENDER_PRE,
6466 _e_comp_object_damage_trace_render_pre_cb);
6468 evas_event_callback_del(e_comp->evas,
6469 EVAS_CALLBACK_RENDER_POST,
6470 _e_comp_object_damage_trace_render_post_cb);
6473 _damage_trace = onoff;
6477 e_comp_object_redirected_get(Evas_Object *obj)
6479 API_ENTRY EINA_FALSE;
6480 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6482 return cw->redirected;
6486 e_comp_object_color_visible_get(Evas_Object *obj)
6488 API_ENTRY EINA_FALSE;
6490 return cw->color_visible;
6494 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6496 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6498 return e_map_set_to_comp_object(em, obj);
6502 e_comp_object_map_get(const Evas_Object *obj)
6504 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6506 return e_map_get_from_comp_object(obj);
6510 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6512 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6514 evas_object_map_enable_set(obj, enable);
6520 e_comp_object_render_update_lock(Evas_Object *obj)
6522 E_Comp_Wl_Buffer *buffer;
6523 struct wayland_tbm_client_queue *cqueue;
6525 API_ENTRY EINA_FALSE;
6527 if (cw->render_update_lock.lock == 0)
6529 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6531 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6532 if ((buffer) && (buffer->resource))
6534 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6536 wayland_tbm_server_client_queue_flush(cqueue);
6539 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6540 e_comp_object_render_update_del(obj);
6542 ELOGF("COMP", "Render update lock enabled", cw->ec);
6545 cw->render_update_lock.lock++;
6551 e_comp_object_render_update_unlock(Evas_Object *obj)
6555 if (cw->render_update_lock.lock == 0)
6558 cw->render_update_lock.lock--;
6560 if (cw->render_update_lock.lock == 0)
6563 if (cw->render_update_lock.pending_move_set)
6565 evas_object_move(obj,
6566 cw->render_update_lock.pending_move_x,
6567 cw->render_update_lock.pending_move_y);
6568 cw->render_update_lock.pending_move_x = 0;
6569 cw->render_update_lock.pending_move_y = 0;
6570 cw->render_update_lock.pending_move_set = EINA_FALSE;
6573 if (cw->render_update_lock.pending_resize_set)
6575 evas_object_resize(obj,
6576 cw->render_update_lock.pending_resize_w,
6577 cw->render_update_lock.pending_resize_h);
6578 cw->render_update_lock.pending_resize_w = 0;
6579 cw->render_update_lock.pending_resize_h = 0;
6580 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6583 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6585 if ((cw->ec->exp_iconify.buffer_flush) &&
6586 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6587 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6588 e_comp_object_clear(obj);
6590 e_comp_object_render_update_add(obj);
6592 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET, cw->ec);
6594 ELOGF("COMP", "Render update lock disabled", cw->ec);
6599 e_comp_object_render_update_lock_get(Evas_Object *obj)
6601 API_ENTRY EINA_FALSE;
6603 if (cw->render_update_lock.lock > 0)
6610 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6614 if ((cw->transparent.set) || (cw->transparent.setting))
6616 if (r) *r = cw->transparent.user_r;
6617 if (g) *g = cw->transparent.user_g;
6618 if (b) *b = cw->transparent.user_b;
6619 if (a) *a = cw->transparent.user_a;
6623 evas_object_color_get(obj, r, g, b, a);
6628 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6632 evas_object_render_op_set(cw->obj, op);
6634 wl_signal_emit(&cw->events.render_op_set, NULL);
6637 EINTERN Evas_Render_Op
6638 e_comp_object_render_op_get(Evas_Object *obj)
6640 API_ENTRY EVAS_RENDER_BLEND;
6642 return evas_object_render_op_get(cw->obj);
6646 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6649 wl_signal_add(&cw->events.lower, listener);
6652 #ifdef REFACTOR_DESK_AREA
6654 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6657 wl_signal_add(&cw->events.lower_done, listener);
6661 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6664 wl_signal_add(&cw->events.raise, listener);
6669 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6672 wl_signal_add(&cw->events.show, listener);
6676 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6679 wl_signal_add(&cw->events.hide, listener);
6682 #ifdef REFACTOR_DESK_AREA
6684 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6687 wl_signal_add(&cw->events.set_layer, listener);
6691 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6694 wl_signal_add(&cw->events.stack_above, listener);
6698 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6701 wl_signal_add(&cw->events.stack_below, listener);
6706 e_comp_object_image_filter_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6709 wl_signal_add(&cw->events.image_filter_set, listener);
6713 e_comp_object_render_op_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6716 wl_signal_add(&cw->events.render_op_set, listener);
6720 e_comp_object_content_type_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6723 wl_signal_add(&cw->events.content_type_set, listener);
6727 e_comp_object_color_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6730 wl_signal_add(&cw->events.color_set, listener);
6734 e_comp_object_color_visible_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6737 wl_signal_add(&cw->events.color_visible_set, listener);