1 #include "e_comp_object_intern.h"
2 #include "e_bindings_intern.h"
3 #include "e_utils_intern.h"
4 #ifdef REFACTOR_DESK_AREA
6 #include "e_comp_canvas_intern.h"
8 #include "e_comp_cfdata_intern.h"
9 #include "e_comp_wl_subsurface_intern.h"
10 #include "e_comp_wl_tbm_intern.h"
11 #include "e_comp_intern.h"
12 #include "e_pixmap_intern.h"
13 #include "e_map_intern.h"
14 #include "e_hwc_window_intern.h"
15 #include "e_hwc_windows_intern.h"
16 #include "e_policy_visibility_intern.h"
17 #include "e_client_video_intern.h"
18 #include "e_client_intern.h"
19 #include "e_zone_intern.h"
20 #include "e_theme_intern.h"
21 #include "e_config_intern.h"
25 = keys that return objects =
26 - E_Client: the client associated with the object (E_Client*)
27 - comp_smart_obj: cw->smart_obj (Evas_Object*)
28 - comp_obj: cw (E_Comp_Object*)
30 = keys that are bool flags =
31 - client_restack: client needs a protocol-level restack
32 - comp_override: object is triggering a nocomp override to force compositing
33 - comp_ref: object has a ref from visibility animations
34 - comp_showing: object is currently running its show animation
35 - comp_hiding: object is currently running its hiding animation
36 - comp_object: object is a compositor-created object
37 - comp_object_skip: object has a name which prohibits theme shadows
38 - comp_object-to_del: list of objects which will be deleted when this object is deleted
39 - comp_mirror: object is the result of e_comp_object_util_mirror_add()
40 - effect_running: object is animating by external module
43 #define UPDATE_MAX 512 // same as evas
44 #define FAILURE_MAX 2 // seems reasonable
45 #define SMART_NAME "e_comp_object"
46 #define INPUT_OBJ_SMART_NAME "input_object"
48 /* for non-util functions */
49 #define API_ENTRY E_Comp_Object *cw; \
50 cw = evas_object_smart_data_get(obj); \
51 if ((!obj) || (!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) return
53 /* for util functions (obj may or may not be E_Comp_Object */
54 #define SOFT_ENTRY(...) E_Comp_Object *cw; \
57 CRI("YOU PASSED NULL! ARGH!"); \
60 cw = evas_object_smart_data_get(obj); \
61 if ((!cw) || (e_util_strcmp(evas_object_type_get(obj), SMART_NAME))) \
63 #define INTERNAL_ENTRY E_Comp_Object *cw; cw = evas_object_smart_data_get(obj); if (!cw) return;
65 /* enable for lots of client size info in console output */
67 # define e_util_size_debug_set(x, y)
70 /* enable along with display-specific damage INF calls to enable render tracing
74 #define RENDER_DEBUG(...) INF(__VA_ARGS__)
76 #define RENDER_DEBUG(...)
79 typedef struct _E_Input_Rect_Data
85 typedef struct _E_Input_Rect_Smart_Data
87 Eina_List *input_rect_data_list;
89 } E_Input_Rect_Smart_Data;
91 struct E_Comp_Object_Mover
94 E_Comp_Object_Mover_Cb func;
100 static Eina_Inlist *_e_comp_object_movers = NULL;
101 static Evas_Smart *_e_comp_smart = NULL;
102 static Evas_Smart *_e_comp_input_obj_smart = NULL;
104 static int _e_comp_object_hooks_delete = 0;
105 static int _e_comp_object_hooks_walking = 0;
107 static Eina_Inlist *_e_comp_object_hooks[] =
109 [E_COMP_OBJECT_HOOK_EFFECT_START] = NULL,
110 [E_COMP_OBJECT_HOOK_EFFECT_END] = NULL,
111 [E_COMP_OBJECT_HOOK_RESTACK] = NULL,
112 [E_COMP_OBJECT_HOOK_OBJECT_SETUP] = NULL,
113 [E_COMP_OBJECT_HOOK_LAYER_SET] = NULL,
114 [E_COMP_OBJECT_HOOK_MASK_OBJECT_SET] = NULL,
115 [E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET] = NULL,
116 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET] = NULL,
117 [E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET] = NULL,
120 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
121 static int _e_comp_object_intercept_hooks_delete = 0;
122 static int _e_comp_object_intercept_hooks_walking = 0;
124 static Eina_Inlist *_e_comp_object_intercept_hooks[] =
126 [E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER] = NULL,
127 [E_COMP_OBJECT_INTERCEPT_HOOK_HIDE] = NULL,
131 static Eina_Bool _damage_trace = EINA_FALSE;
132 static Eina_List *_damage_trace_objs = NULL;
133 static Eina_List *_damage_trace_post_objs = NULL;
135 /* sekrit functionzzz */
136 EINTERN void e_client_focused_set(E_Client *ec);
138 /* emitted every time a new noteworthy comp object is added */
139 EINTERN int E_EVENT_COMP_OBJECT_ADD = -1;
141 /* ecore event define */
142 EINTERN int E_EVENT_COMP_OBJECT_IMG_RENDER = -1;
143 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_START = -1;
144 EINTERN int E_EVENT_COMP_OBJECT_EFFECT_END = -1;
146 static void _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect);
147 static Eina_Bool _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj);
148 static void _e_comp_object_dim_update(E_Comp_Object *cw);
149 static void _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror);
150 #ifdef REFACTOR_DESK_AREA
152 static void _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj);
153 static void _e_comp_object_raise(Evas_Object *obj);
154 static void _e_comp_object_layer_set(Evas_Object *obj, short layer);
155 static void _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target);
156 static void _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target);
157 static void _e_comp_object_transform_obj_stack_update(Evas_Object *obj);
160 static E_Client *dim_client = NULL;
163 _e_comp_object_hooks_clean(void)
166 E_Comp_Object_Hook *ch;
169 for (x = 0; x < E_COMP_OBJECT_HOOK_LAST; x++)
170 EINA_INLIST_FOREACH_SAFE(_e_comp_object_hooks[x], l, ch)
172 if (!ch->delete_me) continue;
173 _e_comp_object_hooks[x] = eina_inlist_remove(_e_comp_object_hooks[x], EINA_INLIST_GET(ch));
179 _e_comp_object_hook_call(E_Comp_Object_Hook_Point hookpoint, E_Client *ec)
181 E_Comp_Object_Hook *ch;
182 Eina_Bool ret = EINA_TRUE;
184 if (e_object_is_del(E_OBJECT(ec)))
186 if ((hookpoint != E_COMP_OBJECT_HOOK_EFFECT_START) &&
187 (hookpoint != E_COMP_OBJECT_HOOK_EFFECT_END) &&
188 (hookpoint != E_COMP_OBJECT_HOOK_OBJECT_SETUP) &&
189 (hookpoint != E_COMP_OBJECT_HOOK_LAYER_SET) &&
190 (hookpoint != E_COMP_OBJECT_HOOK_RESTACK) &&
191 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_SET) &&
192 (hookpoint != E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET) &&
193 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET) &&
194 (hookpoint != E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET)
200 e_object_ref(E_OBJECT(ec));
201 _e_comp_object_hooks_walking++;
202 EINA_INLIST_FOREACH(_e_comp_object_hooks[hookpoint], ch)
204 if (ch->delete_me) continue;
205 if (!(ch->func(ch->data, ec)))
211 _e_comp_object_hooks_walking--;
212 if ((_e_comp_object_hooks_walking == 0) && (_e_comp_object_hooks_delete > 0))
213 _e_comp_object_hooks_clean();
215 e_object_unref(E_OBJECT(ec));
220 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
222 _e_comp_object_intercept_hooks_clean(void)
225 E_Comp_Object_Intercept_Hook *ch;
228 for (x = 0; x < E_COMP_OBJECT_INTERCEPT_HOOK_LAST; x++)
229 EINA_INLIST_FOREACH_SAFE(_e_comp_object_intercept_hooks[x], l, ch)
231 if (!ch->delete_me) continue;
232 _e_comp_object_intercept_hooks[x] = eina_inlist_remove(_e_comp_object_intercept_hooks[x], EINA_INLIST_GET(ch));
238 _e_comp_object_intercept_hook_call(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Client *ec)
240 E_Comp_Object_Intercept_Hook *ch;
241 Eina_Bool ret = EINA_TRUE;
243 if (e_object_is_del(E_OBJECT(ec))) return ret;
244 e_object_ref(E_OBJECT(ec));
245 _e_comp_object_intercept_hooks_walking++;
246 EINA_INLIST_FOREACH(_e_comp_object_intercept_hooks[hookpoint], ch)
248 if (ch->delete_me) continue;
249 if (!(ch->func(ch->data, ec)))
255 _e_comp_object_intercept_hooks_walking--;
256 if ((_e_comp_object_intercept_hooks_walking == 0) && (_e_comp_object_intercept_hooks_delete > 0))
257 _e_comp_object_intercept_hooks_clean();
259 e_object_unref(E_OBJECT(ec));
266 _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
268 E_Event_Comp_Object *ev = event;
271 ec = evas_object_data_get(ev->comp_object, "E_Client");
275 e_object_unref(E_OBJECT(ec));
277 evas_object_unref(ev->comp_object);
282 _e_comp_object_event_add(Evas_Object *obj)
284 E_Event_Comp_Object *ev;
287 if (stopping) return;
288 ev = E_NEW(E_Event_Comp_Object, 1);
289 EINA_SAFETY_ON_NULL_RETURN(ev);
291 evas_object_ref(obj);
292 ev->comp_object = obj;
293 ec = evas_object_data_get(ev->comp_object, "E_Client");
297 e_object_ref(E_OBJECT(ec));
299 ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
303 _e_comp_object_simple_free(void *d EINA_UNUSED, void *event)
305 E_Event_Comp_Object *ev = event;
308 ec = evas_object_data_get(ev->comp_object, "E_Client");
312 e_object_unref(E_OBJECT(ec));
314 evas_object_unref(ev->comp_object);
319 _e_comp_object_event_simple(Evas_Object *obj, int type)
321 E_Event_Comp_Object *ev;
324 ev = E_NEW(E_Event_Comp_Object, 1);
327 evas_object_ref(obj);
328 ev->comp_object = obj;
329 ec = evas_object_data_get(ev->comp_object, "E_Client");
333 e_object_ref(E_OBJECT(ec));
335 ecore_event_add(type, ev, (Ecore_End_Cb)_e_comp_object_simple_free, NULL);
337 /////////////////////////////////////
340 _e_comp_object_cb_mirror_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
342 E_Comp_Object *cw = data;
344 cw->obj_mirror = eina_list_remove(cw->obj_mirror, obj);
348 _e_comp_object_cb_mirror_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
350 E_Comp_Object *cw = data;
352 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
353 evas_object_smart_callback_call(cw->smart_obj, "visibility_force", cw->ec);
356 if (e_comp->hwc && !e_comp_is_on_overlay(cw->ec))
357 e_comp_hwc_client_end(cw->ec, __FUNCTION__);
361 _e_comp_object_cb_mirror_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
363 E_Comp_Object *cw = data;
366 if ((!cw->force_visible) && (!e_object_is_del(E_OBJECT(cw->ec))))
367 evas_object_smart_callback_call(cw->smart_obj, "visibility_normal", cw->ec);
370 /////////////////////////////////////
372 #ifdef REFACTOR_DESK_AREA
374 e_comp_object_transform_obj_stack_update(Evas_Object *obj)
377 _e_comp_object_transform_obj_stack_update(Evas_Object *obj)
382 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
383 if (cw->ec->input_only) return;
385 layer = evas_object_layer_get(obj);
387 if (cw->transform_bg_obj)
389 if (layer != evas_object_layer_get(cw->transform_bg_obj))
391 evas_object_layer_set(cw->transform_bg_obj, layer);
394 evas_object_stack_below(cw->transform_bg_obj, obj);
397 if (cw->transform_tranp_obj)
399 if (layer != evas_object_layer_get(cw->transform_tranp_obj))
401 evas_object_layer_set(cw->transform_tranp_obj, layer);
404 evas_object_stack_below(cw->transform_tranp_obj, obj);
409 _e_comp_object_transform_obj_map_new(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
416 if (!map) return NULL;
418 e_map_util_points_populate_from_object_full(map, obj, 0);
419 e_map_util_points_color_set(map, 255, 255, 255, 255);
421 for (i = 0 ; i < 4 ; ++i)
426 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
427 e_map_point_coord_set(map, i, x, y, 1.0);
434 _e_comp_object_transform_obj_map_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
440 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
443 e_comp_object_map_set(obj, map);
444 e_comp_object_map_enable_set(obj, EINA_TRUE);
451 evas_object_map_enable_set(obj, EINA_FALSE);
456 _e_comp_object_transform_obj_map_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
462 E_Map *map = _e_comp_object_transform_obj_map_new(obj, vertices);
465 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
467 e_comp_object_map_set(obj, map);
468 e_comp_object_map_enable_set(obj, EINA_TRUE);
475 evas_object_map_enable_set(obj, EINA_FALSE);
478 /////////////////////////////////////
480 static inline Eina_Bool
481 _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
483 if (num > 1) return EINA_TRUE;
484 if ((rects[0].x == 0) && (rects[0].y == 0) &&
485 ((int)rects[0].w == w) && ((int)rects[0].h == h))
490 /////////////////////////////////////
492 /* add a client to the layer-client list */
493 #ifdef REFACTOR_DESK_AREA
496 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
498 g_rec_mutex_lock(&e_comp->ec_list_mutex);
501 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));
503 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));
504 if ((!above) && (!below))
507 e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
508 else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
509 e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
511 e_comp->layers[cw->layer].clients_count++;
513 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
517 _e_comp_object_layers_remove(E_Comp_Object *cw)
519 g_rec_mutex_lock(&e_comp->ec_list_mutex);
521 if (cw->ec && e_comp->layers[cw->layer].clients)
523 e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
524 e_comp->layers[cw->layer].clients_count--;
527 g_rec_mutex_unlock(&e_comp->ec_list_mutex);
531 /////////////////////////////////////
533 _e_comp_object_alpha_set(E_Comp_Object *cw)
535 Eina_Bool alpha = cw->ec->argb;
537 if ((cw->external_content) &&
538 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
543 if (cw->blanked || cw->ns || cw->ec->shaped) alpha = EINA_TRUE;
544 if (cw->user_alpha_set) alpha = cw->user_alpha;
546 evas_object_image_alpha_set(cw->obj, alpha);
550 _e_comp_object_shadow(E_Comp_Object *cw)
552 if (e_client_util_shadow_state_get(cw->ec))
553 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,on", "e");
555 edje_object_signal_emit(cw->frame_object ?: cw->shobj, "e,state,shadow,off", "e");
556 if (cw->frame_object)
557 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
558 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
561 /* convert from the surface coordinates to the buffer coordinates */
563 _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
565 E_Comp_Wl_Buffer_Viewport *vp;
566 E_Comp_Wl_Client_Data *cdata;
570 cdata = e_client_cdata_get(ec);
572 if (!ec || !cdata || e_object_is_del(E_OBJECT(ec)))
579 vp = &cdata->scaler.buffer_viewport;
580 transform = e_comp_wl_output_buffer_transform_get(ec);
582 e_pixmap_size_get(ec->pixmap, &bw, &bh);
584 /* for subsurface, it should be swap 90 and 270 */
585 if (e_comp_wl_subsurface_check(ec))
588 case WL_OUTPUT_TRANSFORM_90: transform = WL_OUTPUT_TRANSFORM_270; break;
589 case WL_OUTPUT_TRANSFORM_270: transform = WL_OUTPUT_TRANSFORM_90; break;
590 case WL_OUTPUT_TRANSFORM_FLIPPED_90: transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; break;
591 case WL_OUTPUT_TRANSFORM_FLIPPED_270: transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; break;
597 case WL_OUTPUT_TRANSFORM_NORMAL:
598 default: tx = sx, ty = sy; break;
599 case WL_OUTPUT_TRANSFORM_90: tx = sy, ty = bw - sx; break;
600 case WL_OUTPUT_TRANSFORM_180: tx = bw - sx, ty = bh - sy; break;
601 case WL_OUTPUT_TRANSFORM_270: tx = bh - sy, ty = sx; break;
602 case WL_OUTPUT_TRANSFORM_FLIPPED: tx = bw - sx, ty = sy; break;
603 case WL_OUTPUT_TRANSFORM_FLIPPED_90: tx = sy, ty = sx; break;
604 case WL_OUTPUT_TRANSFORM_FLIPPED_180: tx = sx, ty = bh - sy; break;
605 case WL_OUTPUT_TRANSFORM_FLIPPED_270: tx = bh - sy, ty = bw - sx; break;
608 tx *= vp->buffer.scale;
609 ty *= vp->buffer.scale;
616 _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)
624 _e_comp_object_map_transform_pos(ec, x1, y1, &x1, &y1);
625 _e_comp_object_map_transform_pos(ec, x2, y2, &x2, &y2);
632 if (dw) *dw = MAX(x1, x2) - mx;
633 if (dh) *dh = MAX(y1, y2) - my;
637 _e_comp_object_map_damage_transform_rect(E_Client *ec, E_Map *m, int sx, int sy, int sw, int sh,
638 int *dx, int *dy, int *dw, int *dh)
640 E_Util_Transform_Rect rect = {sx, sy, sw, sh};
641 E_Util_Transform_Rect_Vertex sv, dv;
645 e_pixmap_size_get(ec->pixmap, &bw, &bh);
647 sv = e_util_transform_rect_to_vertices(&rect);
649 for (i = 0; i < 4; i++)
651 double x = 0.0, y = 0.0;
653 e_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
655 /* if evas decide coordinate is outside of map, it returns (0, 0)
656 in this case, full damage is added.
658 if ((i != 0) && (x == 0.0) && (y == 0.0))
661 dv.vertices[i].vertex[0] = x;
662 dv.vertices[i].vertex[1] = y;
663 dv.vertices[i].vertex[2] = 1.0;
664 dv.vertices[i].vertex[3] = 1.0;
667 rect = e_util_transform_vertices_to_rect(&dv);
669 if (dx) *dx = rect.x;
670 if (dy) *dy = rect.y;
671 if (dw) *dw = rect.w;
672 if (dh) *dh = rect.h;
686 _e_comp_object_map_damage_transform_get(E_Client *ec)
693 if (!e_client_transform_core_enable_get(ec))
696 m = e_client_map_get(ec);
700 e_pixmap_size_get(ec->pixmap, &bw, &bh);
701 if ((bw == 0) || (bh == 0))
714 e_map_point_coord_set(m2, 0, 0, 0, 0);
715 e_map_point_coord_set(m2, 1, bw, 0, 0);
716 e_map_point_coord_set(m2, 2, bw, bh, 0);
717 e_map_point_coord_set(m2, 3, 0, bh, 0);
719 for (i = 0; i < 4; i++)
723 e_map_point_coord_get(m, i, &map_x, &map_y, NULL);
724 e_map_point_image_uv_set(m2, i, map_x, map_y);
731 /////////////////////////////////////
733 /* handle evas mouse-in events on client object */
735 _e_comp_object_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
737 Evas_Event_Mouse_In *ev = event_info;
738 E_Comp_Object *cw = data;
740 e_client_mouse_in(cw->ec, ev->output.x, ev->output.y);
743 /* handle evas mouse-out events on client object */
745 _e_comp_object_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
747 Evas_Event_Mouse_Out *ev = event_info;
748 E_Comp_Object *cw = data;
750 e_client_mouse_out(cw->ec, ev->output.x, ev->output.y);
753 /* handle evas mouse wheel events on client object */
755 _e_comp_object_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
757 Evas_Event_Mouse_Wheel *ev = event_info;
758 E_Comp_Object *cw = data;
759 E_Binding_Event_Wheel ev2;
762 if (e_client_action_get()) return;
763 e_bindings_evas_event_mouse_wheel_convert(ev, &ev2);
764 e_client_mouse_wheel(cw->ec, &ev->output, &ev2);
767 /* handle evas mouse down events on client object */
769 _e_comp_object_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
771 Evas_Event_Mouse_Down *ev = event_info;
772 E_Comp_Object *cw = data;
773 E_Binding_Event_Mouse_Button ev2;
776 if (e_client_action_get()) return;
777 e_bindings_evas_event_mouse_down_button_convert(ev, &ev2);
778 e_client_mouse_down(cw->ec, ev->button, &ev->output, &ev2);
781 /* handle evas mouse up events on client object */
783 _e_comp_object_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
785 Evas_Event_Mouse_Up *ev = event_info;
786 E_Comp_Object *cw = data;
787 E_Binding_Event_Mouse_Button ev2;
790 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
791 e_bindings_evas_event_mouse_up_button_convert(ev, &ev2);
792 e_client_mouse_up(cw->ec, ev->button, &ev->output, &ev2);
795 /* handle evas mouse movement events on client object */
797 _e_comp_object_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
799 Evas_Event_Mouse_Move *ev = event_info;
800 E_Comp_Object *cw = data;
803 if (e_client_action_get() && (e_client_action_get() != cw->ec)) return;
804 e_client_mouse_move(cw->ec, &ev->cur.output);
806 /////////////////////////////////////
808 /* helper function for checking compositor themes based on user-defined matches */
810 _e_comp_object_shadow_client_match(const E_Client *ec, E_Comp_Match *m)
812 if (((m->title) && (!ec->netwm.name)) ||
813 ((ec->netwm.name) && (m->title) && (!e_util_glob_match(ec->netwm.name, m->title))))
815 #if defined(__cplusplus) || defined(c_plusplus)
816 if (((m->clas) && (!ec->icccm.cpp_class)) ||
817 ((ec->icccm.cpp_class) && (m->clas) && (!e_util_glob_match(ec->icccm.cpp_class, m->clas))))
820 if (((m->clas) && (!ec->icccm.class)) ||
821 ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
825 if (((m->role) && (!ec->icccm.window_role)) ||
826 ((ec->icccm.window_role) && (m->role) && (!e_util_glob_match(ec->icccm.window_role, m->role))))
832 if ((int)ec->netwm.type != m->primary_type)
835 else if (m->primary_type != E_WINDOW_TYPE_REAL_UNKNOWN)
838 if (m->borderless != 0)
842 if (e_client_util_borderless(ec))
844 if (!(((m->borderless == -1) && (!borderless)) ||
845 ((m->borderless == 1) && (borderless))))
852 if (((ec->icccm.transient_for != 0) ||
855 if (!(((m->dialog == -1) && (!dialog)) ||
856 ((m->dialog == 1) && (dialog))))
859 if (m->accepts_focus != 0)
861 int accepts_focus = 0;
863 if (ec->icccm.accepts_focus)
865 if (!(((m->accepts_focus == -1) && (!accepts_focus)) ||
866 ((m->accepts_focus == 1) && (accepts_focus))))
875 if (!(((m->vkbd == -1) && (!vkbd)) ||
876 ((m->vkbd == 1) && (vkbd))))
881 if (!(((m->argb == -1) && (!ec->argb)) ||
882 ((m->argb == 1) && (ec->argb))))
885 if (m->fullscreen != 0)
887 int fullscreen = ec->fullscreen;
889 if (!(((m->fullscreen == -1) && (!fullscreen)) ||
890 ((m->fullscreen == 1) && (fullscreen))))
895 if (!(m->modal == -1))
901 /* function for setting up a client's compositor frame theme (cw->shobj) */
903 _e_comp_object_shadow_setup(E_Comp_Object *cw)
907 Eina_List *list = NULL, *l;
908 E_Input_Rect_Data *input_rect_data;
909 E_Input_Rect_Smart_Data *input_rect_sd;
911 Eina_Stringshare *reshadow_group = NULL;
912 Eina_Bool focus = EINA_FALSE, skip = EINA_FALSE, fast = EINA_FALSE, reshadow = EINA_FALSE, no_shadow = EINA_FALSE, pass_event_flag = EINA_FALSE;
913 Eina_Stringshare *name, *title;
914 E_Comp_Config *conf = e_comp_config_get();
916 edje_object_file_get(cw->shobj, NULL, &reshadow_group);
917 /* match correct client type */
918 list = cw->ec->override ? conf->match.overrides : conf->match.borders;
919 name = cw->ec->icccm.name;
920 title = cw->ec->icccm.title;
921 skip = (cw->ec->override ? conf->match.disable_overrides : conf->match.disable_borders) || (title && (!strncmp(title, "noshadow", 8)));
922 fast = cw->ec->override ? conf->fast_overrides : conf->fast_borders;
924 /* skipping here is mostly a hack for systray because I hate it */
927 EINA_LIST_FOREACH(list, l, m)
929 if (((m->name) && (!name)) ||
930 ((name) && (m->name) && (!e_util_glob_match(name, m->name))))
932 if (!_e_comp_object_shadow_client_match(cw->ec, m)) continue;
935 no_shadow = m->no_shadow;
938 /* fast effects are just themes with "/fast" appended and shorter effect times */
941 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", m->shadow_style);
942 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
944 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
946 /* default to non-fast style if fast not available */
949 snprintf(buf, sizeof(buf), "e/comp/frame/%s", m->shadow_style);
950 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
952 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
954 if (ok && m->visibility_effect)
955 eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
962 if (skip || (cw->ec->e.state.video))
964 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/none");
966 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/none");
969 if (conf->shadow_style)
973 snprintf(buf, sizeof(buf), "e/comp/frame/%s/fast", conf->shadow_style);
974 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
976 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
980 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
981 reshadow = ok = !e_util_strcmp(reshadow_group, buf);
983 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
990 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default/fast");
992 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default/fast");
996 reshadow = ok = !e_util_strcmp(reshadow_group, "e/comp/frame/default");
998 ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", "e/comp/frame/default");
1003 /* reshadow means this entire function call has been a no-op since we're re-setting the current style */
1008 if (cw->ec->override)
1010 if ((!cw->ec->shaped) && (!no_shadow) && (!cw->ec->argb))
1011 edje_object_signal_emit(cw->shobj, "e,state,shadow,on", "e");
1013 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1014 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1020 edje_object_signal_emit(cw->shobj, "e,state,shadow,off", "e");
1021 evas_object_smart_callback_call(cw->smart_obj, "shadow_change", cw->ec);
1024 _e_comp_object_shadow(cw);
1027 if (focus || cw->ec->focused || cw->ec->override)
1028 e_comp_object_signal_emit(cw->smart_obj, "e,state,focused", "e");
1030 e_comp_object_signal_emit(cw->smart_obj, "e,state,unfocused", "e");
1032 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
1034 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
1035 /* visibility must always be enabled for re_manage clients to prevent
1036 * pop-in animations every time the user sees a persistent client again;
1037 * applying visibility for iconic clients prevents the client from getting
1040 if (cw->visible || cw->ec->re_manage)
1041 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
1043 e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e");
1045 /* breaks animation counter */
1046 if (cw->frame_object)
1048 edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
1049 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1050 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1051 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object);
1057 edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->obj);
1061 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
1064 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
1066 if (input_rect_data->obj)
1068 pass_event_flag = EINA_TRUE;
1074 if (cw->indicator.obj)
1076 Evas_Object *indicator;
1077 indicator = edje_object_part_swallow_get(cw->shobj, "e.swallow.indicator");
1078 if (indicator != cw->indicator.obj)
1080 edje_object_part_unswallow(cw->shobj, indicator);
1081 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", cw->indicator.obj);
1082 e_comp_object_indicator_size_set(cw->smart_obj, cw->indicator.w, cw->indicator.h);
1086 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
1087 evas_object_pass_events_set(cw->obj, pass_event_flag);
1092 /////////////////////////////////////////////
1095 _e_comp_object_animating_begin(E_Comp_Object *cw)
1098 if (cw->animating == 1)
1100 e_comp->animating++;
1102 e_object_ref(E_OBJECT(cw->ec));
1107 _e_comp_object_animating_end(E_Comp_Object *cw)
1116 if (cw->ec->launching)
1118 if (!cw->ec->extra_animating)
1120 ELOGF("COMP", "Un-Set launching flag..", cw->ec);
1121 cw->ec->launching = EINA_FALSE;
1122 if (cw->ec->first_mapped)
1124 ELOGF("LAUNCH", "SHOW real win", cw->ec);
1125 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch_real,done", "e");
1128 e_comp_object_signal_emit(cw->ec->frame, "e,action,launch,done", "e");
1132 e_comp->animating--;
1133 cw->showing = cw->hiding = 0;
1135 if (e_comp->animating == 0)
1136 e_comp_visibility_calculation_set(EINA_TRUE);
1137 /* remove ref from animation start, account for possibility of deletion from unref */
1138 return !!e_object_unref(E_OBJECT(cw->ec));
1144 /* handle the end of a compositor animation */
1146 _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
1148 E_Comp_Object *cw = data;
1150 /* visible clients which have never been sized are a bug */
1151 if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
1152 CRI("ACK! ec:%p", cw->ec);
1153 if (!_e_comp_object_animating_end(cw)) return;
1154 if (cw->animating) return;
1155 /* hide only after animation finishes to guarantee a full run of the animation */
1156 if (!cw->defer_hide) return;
1157 if ((!strcmp(emission, "e,action,hide,done")) ||
1158 (!strcmp(emission, "e,action,done")) ||
1159 ((cw->ec->iconic) && (!strcmp(emission, "e,action,show,done"))))
1161 ELOGF("COMP", "defer hide emission:%s", cw->ec, emission);
1162 evas_object_hide(cw->smart_obj);
1166 /* run a visibility compositor effect if available, return false if object is dead */
1168 _e_comp_object_effect_visibility_start(E_Comp_Object *cw, Eina_Bool state)
1174 if ((!cw->visibility_effect) || (!e_comp_object_effect_allowed_get(cw->smart_obj))) return EINA_TRUE;;
1175 if (!cw->effect_running)
1176 _e_comp_object_animating_begin(cw);
1177 if (!e_comp_object_effect_stop(cw->smart_obj, _e_comp_object_done_defer))
1178 return _e_comp_object_animating_end(cw);
1179 if (!e_comp_object_effect_set(cw->smart_obj, cw->visibility_effect))
1180 return _e_comp_object_animating_end(cw);
1182 evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
1185 zone = e_comp_zone_find_by_ec(cw->ec);
1187 zw = zone->w, zh = zone->h;
1192 zone = e_comp_object_util_zone_get(cw->smart_obj);
1193 if (!zone) zone = e_zone_current_get();
1200 e_comp_object_effect_params_set(cw->smart_obj, 1, (int[]){cw->x, cw->y,
1201 cw->w, cw->h, zw, zh, x, y}, 8);
1202 e_comp_object_effect_params_set(cw->smart_obj, 0, (int[]){state}, 1);
1203 e_comp_object_effect_start(cw->smart_obj, _e_comp_object_done_defer, cw);
1206 /////////////////////////////////////////////
1208 /* create necessary objects for clients that e manages */
1210 _e_comp_object_mouse_event_callback_set(E_Comp_Object *cw)
1212 if (cw->set_mouse_callbacks) return;
1213 if (!cw->smart_obj) return;
1215 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in, cw);
1216 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out, cw);
1217 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down, cw);
1218 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up, cw);
1219 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move, cw);
1220 evas_object_event_callback_add(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel, cw);
1222 cw->set_mouse_callbacks = EINA_TRUE;
1226 _e_comp_object_mouse_event_callback_unset(E_Comp_Object *cw)
1228 if (!cw->set_mouse_callbacks) return;
1229 if (!cw->smart_obj) return;
1231 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_IN, _e_comp_object_cb_mouse_in);
1232 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_OUT, _e_comp_object_cb_mouse_out);
1233 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_comp_object_cb_mouse_down);
1234 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_cb_mouse_up);
1235 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_comp_object_cb_mouse_move);
1236 evas_object_event_callback_del(cw->smart_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_comp_object_cb_mouse_wheel);
1238 cw->set_mouse_callbacks = EINA_FALSE;
1242 _e_comp_object_color_visible_set(E_Comp_Object *cw, Eina_Bool set)
1244 if (cw->color_visible == set) return EINA_TRUE;
1246 cw->color_visible = set;
1248 ELOGF("COMP", "color_visible set:%d", cw->ec, set);
1250 wl_signal_emit_mutable(&cw->events.color_visible_set, NULL);
1256 _e_comp_object_color_visible_update(E_Comp_Object *cw)
1260 e_comp_object_color_get(cw->smart_obj, NULL, NULL, NULL, &a);
1263 _e_comp_object_color_visible_set(cw, EINA_FALSE);
1269 evas_object_color_get(cw->effect_obj, NULL, NULL, NULL, &a);
1272 _e_comp_object_color_visible_set(cw, EINA_FALSE);
1280 evas_object_color_get(cw->shobj, NULL, NULL, NULL, &a);
1283 _e_comp_object_color_visible_set(cw, EINA_FALSE);
1290 evas_object_color_get(cw->obj, NULL, NULL, NULL, &a);
1293 _e_comp_object_color_visible_set(cw, EINA_FALSE);
1298 _e_comp_object_color_visible_set(cw, EINA_TRUE);
1302 _e_comp_intercept_effect_obj_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
1304 E_Comp_Object *cw = data;
1306 evas_object_color_set(obj, r, g, b, a);
1308 _e_comp_object_color_visible_update(cw);
1312 _e_comp_intercept_shobj_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
1314 E_Comp_Object *cw = data;
1316 evas_object_color_set(obj, r, g, b, a);
1318 _e_comp_object_color_visible_update(cw);
1322 _e_comp_intercept_obj_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
1324 E_Comp_Object *cw = data;
1326 evas_object_color_set(obj, r, g, b, a);
1328 _e_comp_object_color_visible_update(cw);
1332 _e_comp_object_setup(E_Comp_Object *cw)
1334 cw->clip = evas_object_rectangle_add(e_comp->evas);
1335 evas_object_move(cw->clip, -9999, -9999);
1336 evas_object_resize(cw->clip, 999999, 999999);
1337 evas_object_smart_member_add(cw->clip, cw->smart_obj);
1338 cw->effect_obj = edje_object_add(e_comp->evas);
1339 evas_object_move(cw->effect_obj, cw->x, cw->y);
1340 evas_object_clip_set(cw->effect_obj, cw->clip);
1341 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
1342 evas_object_intercept_color_set_callback_add(cw->effect_obj, _e_comp_intercept_effect_obj_color_set, cw);
1343 e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none");
1344 cw->shobj = edje_object_add(e_comp->evas);
1345 evas_object_data_set(cw->shobj, "comp_smart_obj", cw->smart_obj);
1346 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
1347 edje_object_signal_callback_add(cw->shobj, "e,action,*,done", "e", _e_comp_object_done_defer, cw);
1348 evas_object_intercept_color_set_callback_add(cw->shobj, _e_comp_intercept_shobj_color_set, cw);
1350 /* name objects appropriately for nicer printing when using e_comp_util_wins_print() */
1351 if (cw->ec->override)
1353 evas_object_name_set(cw->shobj, "cw->shobj::WINDOW");
1354 evas_object_name_set(cw->effect_obj, "cw->effect_obj::WINDOW");
1355 evas_object_name_set(cw->clip, "cw->clip::WINDOW");
1357 else if (!cw->ec->input_only)
1359 evas_object_name_set(cw->shobj, "cw->shobj::CLIENT");
1360 evas_object_name_set(cw->effect_obj, "cw->effect_obj::CLIENT");
1361 evas_object_name_set(cw->clip, "cw->clip::CLIENT");
1363 cw->real_hid = !cw->ec->input_only;
1364 if (!cw->ec->input_only)
1366 e_util_size_debug_set(cw->effect_obj, 1);
1367 _e_comp_object_mouse_event_callback_set(cw);
1370 cw->default_input_obj = evas_object_rectangle_add(e_comp->evas);
1371 evas_object_name_set(cw->default_input_obj, "cw->default_input_obj");
1372 evas_object_move(cw->default_input_obj, cw->x, cw->y);
1373 evas_object_resize(cw->default_input_obj, cw->w, cw->h);
1374 evas_object_color_set(cw->default_input_obj, 0, 0, 0, 0);
1375 evas_object_smart_member_add(cw->default_input_obj, cw->smart_obj);
1377 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_OBJECT_SETUP, cw->ec);
1380 /////////////////////////////////////////////
1382 /* for fast path evas rendering; only called during render */
1384 _e_comp_object_pixels_get(void *data, Evas_Object *obj EINA_UNUSED)
1386 E_Comp_Object *cw = data;
1387 E_Client *ec = cw->ec;
1389 int bx, by, bxx, byy;
1391 if (e_object_is_del(E_OBJECT(ec))) return;
1392 if (cw->external_content) return;
1393 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph)) return;
1394 e_pixmap_image_opaque_get(cw->ec->pixmap, &bx, &by, &bxx, &byy);
1397 bxx = pw - (bx + bxx), byy = ph - (by + byy);
1398 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1400 else if (cw->client_inset.calc && (!cw->frame_object)) //CSD
1402 bx = -cw->client_inset.l + 4, by = -cw->client_inset.t + 4;
1403 bxx = -cw->client_inset.r, byy = -cw->client_inset.b;
1407 bx = by = bxx = byy = 0;
1408 evas_object_image_border_set(cw->obj, bx, bxx, by, byy);
1411 Edje_Message_Int_Set *msg;
1412 Edje_Message_Int msg2;
1413 Eina_Bool id = (bx || by || bxx || byy);
1415 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int) * 3));
1421 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 1, msg);
1423 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT, 0, &msg2);
1427 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
1428 e_comp_client_post_update_add(cw->ec);
1430 else if (e_comp_object_render(ec->frame))
1432 /* apply shape mask if necessary */
1433 if ((!cw->native) && (ec->shaped))
1434 e_comp_object_shape_apply(ec->frame);
1436 /* shaped clients get precise mouse events to handle transparent pixels */
1437 evas_object_precise_is_inside_set(cw->obj, ec->shaped);
1439 /* queue another render if client is still dirty; cannot refresh here. */
1440 if (e_pixmap_dirty_get(ec->pixmap) && e_pixmap_size_get(ec->pixmap, &pw, &ph))
1441 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1443 if (cw->render_trace)
1445 _e_comp_object_event_simple(ec->frame, E_EVENT_COMP_OBJECT_IMG_RENDER);
1451 _e_comp_object_pixels_noti(void *data, Evas_Object *obj EINA_UNUSED)
1453 E_Comp_Object *cw = data;
1454 E_Client *ec = cw->ec;
1456 if (e_object_is_del(E_OBJECT(ec))) return;
1457 if (cw->external_content) return;
1458 if (!e_comp->hwc) return;
1460 e_comp_client_render_list_add(cw->ec);
1462 if (!ec->hwc_window) return;
1464 e_hwc_windows_rendered_window_add(ec->hwc_window);
1467 /////////////////////////////////////////////
1470 _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
1472 E_Comp_Object *cw = data;
1475 if (cw->render_update_lock.lock)
1477 cw->render_update_lock.pending_move_x = x;
1478 cw->render_update_lock.pending_move_y = y;
1479 cw->render_update_lock.pending_move_set = EINA_TRUE;
1483 if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
1484 (e_pixmap_usable_get(cw->ec->pixmap)) &&
1485 (cw->external_content))
1487 /* delay to move until the external content is unset */
1488 cw->ec->changes.pos = 1;
1493 if (cw->ec->move_after_resize)
1495 if ((x != cw->ec->x) || (y != cw->ec->y))
1497 if (!cw->ec->is_cursor)
1498 ELOGF("COMP", "Set Pos to (%d,%d). current ec_pos(%d,%d)", cw->ec, x, y, cw->ec->x, cw->ec->y);
1499 e_client_pos_set(cw->ec, x, y);
1500 cw->ec->changes.pos = 1;
1506 if ((cw->ec->resize_mode == E_POINTER_RESIZE_NONE) &&
1507 (cw->ec->manage_resize.resize_obj))
1509 e_client_pos_set(cw->ec, x, y);
1510 cw->ec->client.x = x + cw->client_inset.l;
1511 cw->ec->client.y = y + cw->client_inset.t;
1512 e_policy_visibility_client_defer_move(cw->ec);
1516 /* if frame_object does not exist, client_inset indicates CSD.
1517 * this means that ec->client matches cw->x/y, the opposite
1520 fx = (!cw->frame_object) * cw->client_inset.l;
1521 fy = (!cw->frame_object) * cw->client_inset.t;
1522 if ((cw->x == x + fx) && (cw->y == y + fy))
1524 if ((cw->ec->x != x) || (cw->ec->y != y))
1526 /* handle case where client tries to move to position and back very quickly */
1527 e_client_pos_set(cw->ec, x, y);
1528 cw->ec->client.x = x + cw->client_inset.l;
1529 cw->ec->client.y = y + cw->client_inset.t;
1533 if (!cw->ec->maximize_override)
1535 /* prevent moving in some directions while directionally maximized */
1536 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1538 if ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1541 ix = x + cw->client_inset.l;
1542 iy = y + cw->client_inset.t;
1543 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->x != x) || (cw->ec->y != y)) &&
1544 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_VERTICAL) &&
1545 ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_HORIZONTAL))
1547 /* prevent moving at all if move isn't allowed in current maximize state */
1548 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1549 /* queue unmaximize if we are allowing move and update unmaximize geometry */
1552 zone = e_comp_zone_find_by_ec(cw->ec);
1555 cw->ec->changes.need_unmaximize = 1;
1556 cw->ec->saved.x = ix - zone->x;
1557 cw->ec->saved.y = iy - zone->y;
1558 cw->ec->saved.w = cw->ec->client.w;
1559 cw->ec->saved.h = cw->ec->client.h;
1563 /* only update during resize if triggered by resize */
1564 if (e_client_util_resizing_get(cw->ec) && (!cw->force_move)) return;
1565 /* delay to move while surface waits paired commit serial*/
1566 if (e_client_pending_geometry_has(cw->ec))
1568 /* do nothing while waiting paired commit serial*/
1572 e_client_pos_set(cw->ec, x, y);
1573 if (cw->ec->new_client)
1575 /* don't actually do anything until first client idler loop */
1576 cw->ec->placed = ((!cw->ec->dialog) && (!cw->ec->parent));
1577 cw->ec->changes.pos = 1;
1582 /* only update xy position of client to avoid invalid
1583 * first damage region if it is not a new_client. */
1584 cw->ec->client.x = ix;
1585 cw->ec->client.y = iy;
1588 if (!cw->frame_object)
1590 evas_object_move(obj, x, y);
1595 _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
1597 E_Comp_Object *cw = data;
1598 int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
1601 if (cw->render_update_lock.lock)
1603 cw->render_update_lock.pending_resize_w = w;
1604 cw->render_update_lock.pending_resize_h = h;
1605 cw->render_update_lock.pending_resize_set = EINA_TRUE;
1609 if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
1611 e_client_size_set(cw->ec, w, h);
1612 evas_object_resize(obj, w, h);
1616 /* if frame_object does not exist, client_inset indicates CSD.
1617 * this means that ec->client matches cw->w/h, the opposite
1620 fw = (!cw->frame_object) * (-cw->client_inset.l - cw->client_inset.r);
1621 fh = (!cw->frame_object) * (-cw->client_inset.t - cw->client_inset.b);
1622 if ((cw->w == w + fw) && (cw->h == h + fh))
1624 if (((cw->ec->w != w) || (cw->ec->h != h)) ||
1625 (cw->ec->client.w != w - cw->client_inset.l - cw->client_inset.r) ||
1626 (cw->ec->client.h != h - cw->client_inset.t - cw->client_inset.b))
1628 /* handle case where client tries to resize itself and back very quickly */
1629 e_client_size_set(cw->ec, w, h);
1630 cw->ec->client.w = w - cw->client_inset.l - cw->client_inset.r;
1631 cw->ec->client.h = h - cw->client_inset.t - cw->client_inset.b;
1632 evas_object_smart_callback_call(obj, "client_resize", NULL);
1636 /* guarantee that fullscreen is fullscreen */
1637 zone = e_comp_zone_find_by_ec(cw->ec);
1639 if (cw->ec->fullscreen && ((w != zone->w) || (h != zone->h)))
1641 if (!e_client_transform_core_enable_get(cw->ec))
1644 /* calculate client size */
1645 iw = w - cw->client_inset.l - cw->client_inset.r;
1646 ih = h - cw->client_inset.t - cw->client_inset.b;
1647 if (cw->ec->maximized && (!cw->ec->maximize_override) && ((cw->ec->w != w) || (cw->ec->h != h)))
1649 /* prevent resizing while maximized depending on direction and config */
1650 if ((!e_config->allow_manip) && ((cw->ec->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
1652 Eina_Bool reject = EINA_FALSE;
1653 if (cw->ec->maximized & E_MAXIMIZE_VERTICAL)
1655 if (cw->ec->client.h != ih)
1657 cw->ec->saved.h = ih;
1658 cw->ec->saved.y = cw->ec->client.y - zone->y;
1659 reject = cw->ec->changes.need_unmaximize = 1;
1662 if (cw->ec->maximized & E_MAXIMIZE_HORIZONTAL)
1664 if (cw->ec->client.w != iw)
1666 cw->ec->saved.w = iw;
1667 cw->ec->saved.x = cw->ec->client.x - zone->x;
1668 reject = cw->ec->changes.need_unmaximize = 1;
1677 if (cw->ec->new_client || (!cw->ec->visible) || (!cw->effect_obj))
1679 /* do nothing until client idler loops */
1680 if ((cw->ec->w != w) || (cw->ec->h != h))
1682 e_client_size_set(cw->ec, w, h);
1683 cw->ec->changes.size = 1;
1688 if (e_client_pending_geometry_has(cw->ec))
1690 /* do nothing while waiting paired commit serial*/
1694 e_client_size_set(cw->ec, w, h);
1696 cw->ec->client.w = iw;
1697 cw->ec->client.h = ih;
1698 if ((cw->ec->client.w < 0) || (cw->ec->client.h < 0)) CRI("WTF. ec:%p", cw->ec);
1700 /* The size of non-compositing window can be changed, so there is a
1701 * need to check that cw is H/W composited if cw is not redirected.
1702 * And of course we have to change size of evas object of H/W composited cw,
1703 * otherwise cw can't receive input events even if it is shown on the screen.
1705 Eina_Bool redirected = cw->redirected;
1707 redirected = e_comp_is_on_overlay(cw->ec);
1709 if ((!cw->ec->input_only) && (redirected) &&
1710 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
1711 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) &&
1712 (e_pixmap_dirty_get(cw->ec->pixmap) ||
1713 (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
1716 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
1717 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
1719 prev_w = cw->w, prev_h = cw->h;
1720 e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
1721 /* check shading and clamp to pixmap size for regular clients */
1722 if ((!cw->ec->input_only) && (!cw->ec->override) &&
1723 (((w - fw != pw) || (h - fh != ph))))
1725 //INF("CALLBACK: REQ(%dx%d) != CUR(%dx%d)", w - fw, h - fh, pw, ph);
1726 evas_object_smart_callback_call(obj, "client_resize", NULL);
1728 if (cw->frame_object || cw->ec->input_only)
1729 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
1732 if ((cw->w == w) && (cw->h == h))
1734 /* going to be a noop resize which won't trigger smart resize */
1735 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
1736 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
1738 evas_object_resize(obj, w, h);
1742 evas_object_smart_callback_call(obj, "client_resize", NULL);
1745 if ((!cw->frame_object) && (!cw->ec->input_only))
1747 /* "just do it" for overrides */
1748 evas_object_resize(obj, w, h);
1750 if (!cw->ec->override)
1752 /* shape probably changed for non-overrides */
1757 /* this fixes positioning jiggles when using a resize mode
1758 * which also changes the client's position
1761 if (cw->frame_object)
1762 x = cw->x, y = cw->y;
1764 x = cw->ec->x, y = cw->ec->y;
1765 switch (cw->ec->resize_mode)
1767 case E_POINTER_RESIZE_BL:
1768 case E_POINTER_RESIZE_L:
1769 evas_object_move(obj, x + prev_w - cw->w, y);
1771 case E_POINTER_RESIZE_TL:
1772 evas_object_move(obj, x + prev_w - cw->w, y + prev_h - cw->h);
1774 case E_POINTER_RESIZE_T:
1775 case E_POINTER_RESIZE_TR:
1776 evas_object_move(obj, x, y + prev_h - cw->h);
1785 _e_comp_intercept_layer_set(void *data, Evas_Object *obj, int layer)
1787 #ifdef REFACTOR_DESK_AREA
1788 E_Comp_Object *cw = data;
1789 E_Comp_Object_Data_Set_Layer layer_set_data;
1791 layer_set_data.cw = cw;
1792 layer_set_data.layer = layer;
1794 wl_signal_emit_mutable(&cw->events.set_layer, &layer_set_data);
1798 e_comp_render_queue();
1799 e_comp_object_transform_obj_stack_update(obj);
1803 E_Comp_Object *cw = data;
1804 E_Comp_Wl_Client_Data *child_cdata;
1805 unsigned int l = e_comp_canvas_layer_map(layer);
1808 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
1810 /* doing a compositor effect, follow directions */
1811 _e_comp_object_layer_set(obj, layer);
1812 if (layer == cw->ec->layer) //trying to put layer back
1816 /* if ec->layer and layer are the same but the client is not belong to the given(l)
1817 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
1818 if (cw->layer != l) goto layer_set;
1822 e_comp_render_queue();
1824 ec = e_client_above_get(cw->ec);
1825 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1826 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1827 ec = e_client_above_get(ec);
1828 if (ec && (evas_object_layer_get(ec->frame) != evas_object_layer_get(obj)))
1830 ec = e_client_below_get(cw->ec);
1831 /* skip subsurface: stacking subsurface is handled by e_comp_wl */
1832 while ((ec) && (e_comp_wl_subsurface_check(ec)))
1833 ec = e_client_below_get(ec);
1834 if (ec && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
1836 evas_object_stack_above(obj, ec->frame);
1841 if (ec && (cw->ec->parent == ec))
1843 if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
1844 evas_object_stack_above(obj, ec->frame);
1846 evas_object_stack_below(obj, ec->frame);
1849 evas_object_stack_below(obj, ec ? ec->frame : e_comp->layers[cw->layer].obj);
1855 if (cw->layer == l) return;
1856 if (e_comp_canvas_client_layer_map(layer) == 9999)
1857 return; //invalid layer for clients not doing comp effects
1858 if (cw->ec->fullscreen)
1860 cw->ec->saved.layer = layer;
1863 oldraise = e_config->transient.raise;
1865 /* clamp to valid client layer */
1866 layer = e_comp_canvas_client_layer_map_nearest(layer);
1867 cw->ec->layer = layer;
1868 if (e_config->transient.layer)
1871 Eina_List *list = eina_list_clone(cw->ec->transients);
1873 /* We need to set raise to one, else the child wont
1874 * follow to the new layer. It should be like this,
1875 * even if the user usually doesn't want to raise
1878 e_config->transient.raise = 1;
1879 EINA_LIST_FREE(list, child)
1881 child_cdata = e_client_cdata_get(child);
1882 if (child_cdata && !child_cdata->mapped)
1884 ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
1887 e_client_layer_set(child, layer);
1891 e_config->transient.raise = oldraise;
1893 _e_comp_object_layers_remove(cw);
1894 cw->layer = e_comp_canvas_layer_map(layer);
1895 _e_comp_object_layers_add(cw, NULL, NULL, 0);
1896 //if (cw->ec->new_client)
1897 //INF("CLIENT STACKED %p: %u", cw->ec, layer);
1898 _e_comp_object_layer_set(obj, layer);
1899 if (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
1900 evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
1901 if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
1903 /* can't stack a client above its own layer marker */
1904 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
1906 if (!cw->visible) return;
1907 e_comp_render_queue();
1908 _e_comp_object_transform_obj_stack_update(obj);
1912 #ifdef REFACTOR_DESK_AREA
1914 typedef void (*E_Comp_Object_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
1917 #ifdef REFACTOR_DESK_AREA
1919 e_comp_object_raise(Evas_Object *obj)
1922 _e_comp_object_raise(Evas_Object *obj)
1925 evas_object_raise(obj);
1927 if (evas_object_smart_smart_get(obj))
1929 E_Client *ec = e_comp_object_client_get(obj);
1931 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1935 #ifdef REFACTOR_DESK_AREA
1937 e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1940 _e_comp_object_lower(E_Comp_Object *cw, Evas_Object *obj)
1943 evas_object_lower(obj);
1945 if (evas_object_smart_smart_get(obj))
1947 E_Client *ec = e_comp_object_client_get(obj);
1950 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1951 #ifdef REFACTOR_DESK_AREA
1952 wl_signal_emit_mutable(&cw->events.lower_done, NULL);
1954 wl_signal_emit_mutable(&cw->events.lower, NULL);
1960 #ifdef REFACTOR_DESK_AREA
1962 e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1965 _e_comp_object_stack_above(Evas_Object *obj, Evas_Object *target)
1968 evas_object_stack_above(obj, target);
1970 if (evas_object_smart_smart_get(obj))
1972 E_Client *ec = e_comp_object_client_get(obj);
1974 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1978 #ifdef REFACTOR_DESK_AREA
1980 e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1983 _e_comp_object_stack_below(Evas_Object *obj, Evas_Object *target)
1986 evas_object_stack_below(obj, target);
1988 if (evas_object_smart_smart_get(obj))
1990 E_Client *ec = e_comp_object_client_get(obj);
1992 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RESTACK, ec);
1996 #ifdef REFACTOR_DESK_AREA
1998 e_comp_object_layer_set(Evas_Object *obj, short layer)
2001 _e_comp_object_layer_set(Evas_Object *obj, short layer)
2004 evas_object_layer_set(obj, layer);
2006 if (evas_object_smart_smart_get(obj))
2008 E_Client *ec = e_comp_object_client_get(obj);
2010 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_LAYER_SET, ec);
2014 #ifdef REFACTOR_DESK_AREA
2017 _e_comp_object_is_pending(E_Client *ec)
2021 if (!ec) return EINA_FALSE;
2023 topmost = e_comp_wl_topmost_parent_get(ec);
2025 return (topmost) ? topmost->layer_pending : EINA_FALSE;
2029 _e_comp_intercept_stack_helper(E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
2031 E_Comp_Object *cw2 = NULL;
2034 Evas_Object *o = stack;
2035 #ifdef REFACTOR_DESK_AREA
2036 Eina_Bool raising = stack_cb == e_comp_object_stack_above;
2038 Eina_Bool raising = stack_cb == _e_comp_object_stack_above;
2041 /* We should consider topmost's layer_pending for subsurface */
2042 if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
2044 if (_e_comp_object_is_pending(cw->ec))
2045 e_comp_object_layer_update(cw->smart_obj,
2046 raising? stack : NULL,
2047 raising? NULL : stack);
2049 /* obey compositor effects! */
2050 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2051 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2052 stack_cb(cw->smart_obj, stack);
2053 if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
2054 evas_object_data_del(cw->smart_obj, "client_restack");
2058 cw2 = evas_object_data_get(o, "comp_obj");
2060 /* assume someone knew what they were doing during client init */
2061 if (cw->ec->new_client)
2062 layer = cw->ec->layer;
2063 else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2064 layer = cw2->ec->layer;
2066 layer = evas_object_layer_get(stack);
2067 ecstack = e_client_below_get(cw->ec);
2068 if (layer != e_comp_canvas_layer_map_to(cw->layer))
2070 evas_object_layer_set(cw->smart_obj, layer);
2071 /* we got our layer wrangled, return now! */
2072 if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
2075 /* check if we're stacking below another client */
2078 /* check for non-client layer object */
2079 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
2081 /* find an existing client to use for layering
2082 * by walking up the object stack
2084 * this is guaranteed to be pretty quick since we'll either:
2085 * - run out of client layers
2086 * - find a stacking client
2088 o = evas_object_above_get(o);
2089 if ((!o) || (o == cw->smart_obj)) break;
2090 if (evas_object_layer_get(o) != layer)
2092 /* reached the top client layer somehow
2093 * use top client object
2095 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
2098 /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
2099 * return here since the top client layer window
2104 ec = e_client_top_get();
2109 if (o) cw2 = evas_object_data_get(o, "comp_obj");
2112 if (cw2 && cw->layer != cw2->layer)
2115 /* remove existing layers */
2116 _e_comp_object_layers_remove(cw);
2119 if (o == stack) //if stacking above, cw2 is above; else cw2 is below
2120 _e_comp_object_layers_add(cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
2121 else if (o == cw->smart_obj) //prepend (lower) if not stacking above
2122 _e_comp_object_layers_add(cw, NULL, NULL, !raising);
2123 else //if no stacking objects found, either raise or lower
2124 _e_comp_object_layers_add(cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
2127 _e_comp_object_layers_add(cw, NULL, NULL, 0);
2129 /* find new object for stacking if cw2 is on state of layer_pending */
2130 if ((cw2) && _e_comp_object_is_pending(cw2->ec))
2132 E_Client *new_stack = NULL, *current_ec = NULL;
2133 current_ec = cw2->ec;
2136 while ((new_stack = e_client_below_get(current_ec)))
2138 current_ec = new_stack;
2139 if (new_stack == cw->ec) continue;
2140 if (new_stack->layer != cw2->ec->layer) break;
2141 if (!_e_comp_object_is_pending(new_stack)) break;
2143 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2144 stack = new_stack->frame;
2147 /* stack it above layer object */
2149 below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
2150 stack = e_comp->layers[below_layer].obj;
2155 while ((new_stack = e_client_above_get(current_ec)))
2157 current_ec = new_stack;
2158 if (new_stack == cw->ec) continue;
2159 if (new_stack->layer != cw2->ec->layer) break;
2160 if (!_e_comp_object_is_pending(new_stack)) break;
2162 if ((new_stack) && (new_stack->layer == cw2->ec->layer))
2163 stack = new_stack->frame;
2165 stack = e_comp->layers[cw2->layer].obj;
2169 /* set restack if stacking has changed */
2170 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2171 evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
2172 stack_cb(cw->smart_obj, stack);
2173 if (e_comp->layers[cw->layer].obj)
2174 if (evas_object_below_get(cw->smart_obj) == e_comp->layers[cw->layer].obj)
2176 CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
2178 if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
2179 evas_object_data_del(cw->smart_obj, "client_restack");
2180 if (!cw->visible) return;
2181 e_comp_render_queue();
2186 _e_comp_intercept_stack_above(void *data, Evas_Object *obj, Evas_Object *above)
2188 EINA_SAFETY_ON_TRUE_RETURN(obj == above);
2190 TRACE_DS_BEGIN(COMP:INTERCEPT STACK ABOVE);
2192 #ifdef REFACTOR_DESK_AREA
2193 E_Comp_Object *cw = data;
2194 E_Comp_Object_Data_Stack_Above stack_above_data;
2196 stack_above_data.cw = cw;
2197 stack_above_data.above_obj = above;
2199 wl_signal_emit_mutable(&cw->events.stack_above, &stack_above_data);
2201 if (evas_object_below_get(obj) == above)
2203 e_comp_object_layer_update(obj, above, NULL);
2207 _e_comp_intercept_stack_helper(data, above, _e_comp_object_stack_above);
2209 _e_comp_object_transform_obj_stack_update(obj);
2210 _e_comp_object_transform_obj_stack_update(above);
2217 _e_comp_intercept_stack_below(void *data, Evas_Object *obj, Evas_Object *below)
2219 EINA_SAFETY_ON_TRUE_RETURN(obj == below);
2221 TRACE_DS_BEGIN(COMP:INTERCEPT STACK BELOW);
2223 #ifdef REFACTOR_DESK_AREA
2224 E_Comp_Object *cw = data;
2225 E_Comp_Object_Data_Stack_Below stack_below_data;
2227 stack_below_data.cw = cw;
2228 stack_below_data.below_obj = below;
2230 wl_signal_emit_mutable(&cw->events.stack_below, &stack_below_data);
2233 e_comp_render_queue();
2235 if (evas_object_above_get(obj) == below)
2237 e_comp_object_layer_update(obj, NULL, below);
2241 _e_comp_intercept_stack_helper(data, below, _e_comp_object_stack_below);
2243 if (evas_object_smart_smart_get(obj))
2244 _e_comp_object_transform_obj_stack_update(obj);
2245 if (evas_object_smart_smart_get(below))
2246 _e_comp_object_transform_obj_stack_update(below);
2253 _e_comp_intercept_lower(void *data, Evas_Object *obj)
2255 E_Comp_Object *cw = data;
2257 #ifdef REFACTOR_DESK_AREA
2262 TRACE_DS_BEGIN(COMP:INTERCEPT LOWER);
2264 #ifdef REFACTOR_DESK_AREA
2265 wl_signal_emit_mutable(&cw->events.lower, cw);
2267 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2269 if (cw->ec->layer_pending)
2270 e_comp_object_layer_update(obj, NULL, obj);
2272 #ifdef REFACTOR_DESK_AREA
2273 e_comp_object_lower(cw, obj);
2275 _e_comp_object_lower(cw, obj);
2279 if (!EINA_INLIST_GET(cw->ec)->prev) goto end; //already lowest on layer
2280 o = evas_object_below_get(obj);
2281 _e_comp_object_layers_remove(cw);
2282 /* prepend to client list since this client should be the first item now */
2283 _e_comp_object_layers_add(cw, NULL, NULL, 1);
2284 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at bottom!
2285 evas_object_data_set(obj, "client_restack", (void*)1);
2286 #ifdef REFACTOR_DESK_AREA
2287 e_comp_object_lower(cw, obj);
2289 _e_comp_object_lower(cw, obj);
2291 evas_object_data_del(obj, "client_restack");
2292 if (!cw->visible) goto end;
2293 e_comp_render_queue();
2294 #ifdef REFACTOR_DESK_AREA
2295 e_comp_object_transform_obj_stack_update(obj);
2297 _e_comp_object_transform_obj_stack_update(obj);
2306 _e_comp_intercept_raise(void *data, Evas_Object *obj)
2308 E_Comp_Object *cw = data;
2309 #ifdef REFACTOR_DESK_AREA
2315 TRACE_DS_BEGIN(COMP:INTERCEPT RAISE);
2317 #ifdef REFACTOR_DESK_AREA
2318 wl_signal_emit_mutable(&cw->events.raise, cw);
2320 if ((cw->ec->layer_block) || (cw->ec->layer_pending))
2322 if (cw->ec->layer_pending)
2324 int obj_layer = evas_object_layer_get(obj);
2325 if (cw->ec->layer != obj_layer)
2326 e_comp_object_layer_update(obj, NULL, NULL);
2328 #ifdef REFACTOR_DESK_AREA
2329 e_comp_object_raise(obj);
2331 _e_comp_object_raise(obj);
2335 if (!EINA_INLIST_GET(cw->ec)->next) goto end;//already highest on layer
2336 o = evas_object_above_get(obj);
2337 if (evas_object_layer_get(o) != evas_object_layer_get(obj)) goto end; //already at top!
2339 /* still stack below override below the layer marker */
2340 for (op = o = e_comp->layers[cw->layer].obj;
2341 o && o != e_comp->layers[cw->layer - 1].obj;
2342 op = o, o = evas_object_below_get(o))
2344 if (evas_object_smart_smart_get(o))
2348 ec = e_comp_object_client_get(o);
2349 if (ec && (!ec->override)) break;
2352 #ifdef REFACTOR_DESK_AREA
2353 e_comp_object_stack_below(obj, op);
2355 _e_comp_object_stack_below(obj, op);
2357 e_client_focus_defer_set(cw->ec);
2359 if (!cw->visible) goto end;
2360 e_comp_render_queue();
2361 #ifdef REFACTOR_DESK_AREA
2362 e_comp_object_transform_obj_stack_update(obj);
2364 _e_comp_object_transform_obj_stack_update(obj);
2373 _e_comp_intercept_hide(void *data, Evas_Object *obj)
2375 E_Comp_Object *cw = data;
2377 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2378 if( !_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_HIDE, cw->ec))
2380 ELOGF("COMP", "Hide. intercepted", cw->ec);
2385 if (cw->ec->launching == EINA_TRUE)
2387 ELOGF("COMP", "Hide. Cancel launching flag", cw->ec);
2388 cw->ec->launching = EINA_FALSE;
2393 /* hidden flag = just do it */
2394 ELOGF("COMP", "Hide hidden evas_object:%p", cw->ec, obj);
2395 evas_object_hide(obj);
2397 wl_signal_emit_mutable(&cw->events.hide, NULL);
2402 if (cw->ec->input_only)
2404 /* input_only = who cares */
2405 ELOGF("COMP", "Hide input_only evas_object:%p", cw->ec, obj);
2406 evas_object_hide(obj);
2408 wl_signal_emit_mutable(&cw->events.hide, NULL);
2412 /* already hidden or currently animating */
2413 if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
2415 ELOGF("COMP", "Hide. but already hidden or currently animating", cw->ec);
2419 /* don't try hiding during shutdown */
2420 cw->defer_hide |= stopping;
2421 if (!cw->defer_hide)
2423 if ((!cw->ec->iconic) && (!cw->ec->override))
2424 /* unset delete requested so the client doesn't break */
2425 cw->ec->delete_requested = 0;
2426 if ((!cw->animating) || (!cw->hiding) || cw->ec->iconic)
2428 ELOGF("COMP", "Hide. but after iconify or hide animation, cw->animating:%d, cw->hiding:%d, iconic:%d",
2429 cw->ec, cw->animating, cw->hiding, cw->ec->iconic);
2432 e_comp_object_signal_emit(obj, "e,action,iconify", "e");
2435 e_comp_object_signal_emit(obj, "e,state,hidden", "e");
2437 _e_comp_object_animating_begin(cw);
2438 if (!_e_comp_object_effect_visibility_start(cw, 0)) return;
2440 evas_object_smart_callback_call(obj, "hiding", cw->ec);
2441 cw->defer_hide = !!cw->animating;
2443 e_comp_object_effect_set(obj, NULL);
2446 if (cw->animating) return;
2447 /* if we have no animations running, go ahead and hide */
2449 ELOGF("COMP", "Hide normal object:%p", cw->ec, obj);
2450 evas_object_hide(obj);
2452 wl_signal_emit_mutable(&cw->events.hide, NULL);
2456 _e_comp_intercept_show_helper(E_Comp_Object *cw)
2458 E_Client *ec = cw->ec;
2461 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
2463 if (ec->show_pending.count > 0)
2465 ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count);
2466 ec->show_pending.running = EINA_TRUE;
2470 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
2471 if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec))
2473 ELOGF("COMP", "show_helper. intercepted", cw->ec);
2478 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,
2479 cw->visible, cw->animating, cw->defer_hide, cw->content_type, cw->updates, cw->w, cw->h,
2480 ec->iconic, ec->exp_iconify.by_client, ec->exp_iconify.type, ec->input_only, ec->ignored, ec->new_client);
2483 e_comp_object_signal_emit(cw->smart_obj, "e,state,sticky", "e");
2486 if (ec->iconic && cw->animating)
2488 /* triggered during iconify animation */
2489 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
2492 ELOGF("COMP", "show_helper. return. already cw->visible", ec);
2495 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
2496 cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
2498 evas_object_move(cw->smart_obj, ec->x, ec->y);
2499 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2500 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2502 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2503 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2506 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2507 evas_object_show(cw->smart_obj);
2510 e_client_focus_defer_set(ec);
2514 if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
2518 pw = ec->client.w, ph = ec->client.h;
2520 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
2522 ec->changes.visible = !ec->hidden;
2525 ELOGF("COMP", "show_helper. return. no pixmap size", ec);
2529 cw->updates = eina_tiler_new(pw, ph);
2532 ec->changes.visible = !ec->hidden;
2535 ELOGF("COMP", "show_helper. return. no cw->updates", ec);
2540 eina_tiler_tile_size_set(cw->updates, 1, 1);
2543 /* ignore until client idler first run */
2544 ec->changes.visible = !ec->hidden;
2547 ELOGF("COMP", "show_helper. return. new_client", ec);
2554 evas_object_move(cw->smart_obj, ec->x, ec->y);
2555 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2556 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2557 evas_object_show(cw->smart_obj);
2560 if (ec->netwm.type == E_WINDOW_TYPE_DND && !e_comp_wl->drag_client)
2562 /* start_drag not received */
2563 ec->changes.visible = 1;
2566 ELOGF("COMP", "show_helper. return. start_drag not received yet", ec);
2569 /* re-set geometry */
2570 evas_object_move(cw->smart_obj, ec->x, ec->y);
2571 /* force resize in case it hasn't happened yet, or just to update size */
2572 evas_object_resize(cw->smart_obj, ec->w, ec->h);
2573 if ((cw->w < 1) || (cw->h < 1))
2575 /* if resize didn't go through, try again */
2576 ec->visible = ec->changes.visible = 1;
2578 ELOGF("COMP", "show_helper. return. cw_size(%d,%d)", ec, cw->w, cw->h);
2581 /* if pixmap not available, clear pixmap since we're going to fetch it again */
2582 if (!e_pixmap_size_get(ec->pixmap, &w, &h))
2583 e_pixmap_clear(ec->pixmap);
2585 if (cw->real_hid && w && h)
2588 /* force comp theming in case it didn't happen already */
2589 e_comp_object_frame_theme_set(cw->smart_obj, E_COMP_OBJECT_FRAME_RESHADOW);
2590 if (e_comp->image_filter != E_COMP_IMAGE_FILTER_NONE)
2591 e_comp_object_image_filter_set(cw->smart_obj, e_comp->image_filter);
2594 /* only do the show if show is allowed */
2597 if (ec->internal) //internal clients render when they feel like it
2598 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2600 if (!e_client_is_iconified_by_client(ec)||
2601 e_policy_visibility_client_is_uniconic(ec))
2603 ELOGF("COMP", "show_helper. evas_object_show!!!", ec);
2604 evas_object_show(cw->smart_obj);
2606 /* if comp object is shown in idle enterer before(E_CLIENT_HOOK_EVAL_FETCH),
2607 it is rendered in idle callback without native surface and
2608 compositor shows an empty frame if other objects aren't shown
2609 because job callback of e_comp called at the next loop.
2610 it causes a visual defect when windows are switched.
2614 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
2615 e_comp_object_dirty(cw->smart_obj);
2616 e_comp_object_render(cw->smart_obj);
2621 wl_signal_emit_mutable(&cw->events.show, NULL);
2625 _e_comp_intercept_show(void *data, Evas_Object *obj EINA_UNUSED)
2627 E_Comp_Object *cw = data;
2628 E_Client *ec = cw->ec;
2630 E_Input_Rect_Data *input_rect_data;
2631 E_Input_Rect_Smart_Data *input_rect_sd;
2634 if (ec->ignored) return;
2638 //INF("SHOW2 %p", ec);
2639 _e_comp_intercept_show_helper(cw);
2642 //INF("SHOW %p", ec);
2645 cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
2646 evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
2647 evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
2648 evas_object_name_set(cw->effect_obj, "cw->effect_obj::input_only");
2652 if ((!cw->obj) && (cw->external_content))
2654 ERR("cw->obj for external content is not created! ec:%p", cw->ec);
2658 _e_comp_object_setup(cw);
2661 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
2662 cw->obj = evas_object_image_filled_add(e_comp->evas);
2663 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
2664 e_util_size_debug_set(cw->obj, 1);
2665 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
2666 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
2667 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
2668 evas_object_name_set(cw->obj, "cw->obj");
2669 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
2670 evas_object_intercept_color_set_callback_add(cw->obj, _e_comp_intercept_obj_color_set, cw);
2672 _e_comp_object_alpha_set(cw);
2675 evas_object_color_set(cw->clip, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity, ec->netwm.opacity);
2678 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
2679 evas_object_geometry_set(cw->effect_obj, cw->x, cw->y, tw, th);
2682 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2685 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2687 if (input_rect_data->obj)
2689 evas_object_geometry_set(input_rect_data->obj,
2690 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
2691 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
2692 input_rect_data->rect.w, input_rect_data->rect.h);
2699 evas_object_resize(cw->mask.obj, cw->w, cw->h);
2701 _e_comp_intercept_show_helper(cw);
2705 _e_comp_intercept_focus(void *data, Evas_Object *obj, Eina_Bool focus)
2707 E_Comp_Object *cw = data;
2711 /* note: this is here as it seems there are enough apps that do not even
2712 * expect us to emulate a look of focus but not actually set x input
2713 * focus as we do - so simply abort any focus set on such windows */
2714 /* be strict about accepting focus hint */
2715 /* be strict about accepting focus hint */
2716 if ((!ec->icccm.accepts_focus) &&
2717 (!ec->icccm.take_focus))
2721 if (e_client_focused_get() == ec)
2722 e_client_focused_set(NULL);
2724 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2725 evas_object_focus_set(obj, focus);
2729 if (focus && ec->lock_focus_out) return;
2730 if (e_object_is_del(E_OBJECT(ec)) && focus)
2731 CRI("CAN'T FOCUS DELETED CLIENT! ec:%p", ec);
2733 /* filter focus setting based on current state */
2738 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2739 evas_object_focus_set(obj, focus);
2742 if ((ec->iconic) && (!ec->deskshow))
2744 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
2746 /* don't focus an iconified window. that's silly! */
2747 ELOGF("FOCUS", "Do uniconify to set focus", ec);
2748 e_client_uniconify(ec);
2749 e_client_focus_latest_set(ec);
2763 /* not yet visible, wait till the next time... */
2764 ec->want_focus = !ec->hidden;
2769 e_client_focused_set(ec);
2773 if (e_client_focused_get() == ec)
2774 e_client_focused_set(NULL);
2778 ELOGF("FOCUS", "FOCUS SET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2780 ELOGF("FOCUS", "FOCUS UNSET | evas_object(%p) (frame:%p)", ec, obj, ec->frame);
2782 evas_object_focus_set(obj, focus);
2786 _e_comp_intercept_color_set(void *data, Evas_Object *obj, int r, int g, int b, int a)
2788 E_Comp_Object *cw = data;
2790 if (cw->transparent.set)
2792 cw->transparent.user_r = r;
2793 cw->transparent.user_g = g;
2794 cw->transparent.user_b = b;
2795 cw->transparent.user_a = a;
2797 ELOGF("COMP", "Transparent user_color(%d,%d,%d,%d)",
2799 cw->transparent.user_r,
2800 cw->transparent.user_g,
2801 cw->transparent.user_b,
2802 cw->transparent.user_a);
2806 evas_object_color_set(obj, r, g, b, a);
2809 wl_signal_emit_mutable(&cw->events.color_set, NULL);
2811 _e_comp_object_color_visible_update(cw);
2814 ////////////////////////////////////////////////////
2817 _e_comp_object_frame_recalc(E_Comp_Object *cw)
2819 int w, h, ox, oy, ow, oh;
2821 Eina_Bool pass_event_flag = EINA_FALSE;
2822 E_Input_Rect_Data *input_rect_data;
2823 E_Input_Rect_Smart_Data *input_rect_sd;
2825 if (cw->frame_object)
2827 if (cw->obj) edje_object_part_unswallow(cw->frame_object, cw->obj);
2828 evas_object_geometry_get(cw->frame_object, NULL, NULL, &w, &h);
2829 /* set a fixed size, force edje calc, check size difference */
2830 evas_object_resize(cw->frame_object, MAX(w, 50), MAX(h, 50));
2831 edje_object_message_signal_process(cw->frame_object);
2832 edje_object_calc_force(cw->frame_object);
2833 edje_object_part_geometry_get(cw->frame_object, "e.swallow.client", &ox, &oy, &ow, &oh);
2834 cw->client_inset.l = ox;
2835 cw->client_inset.r = MAX(w, 50) - (ox + ow);
2836 cw->client_inset.t = oy;
2837 cw->client_inset.b = MAX(h, 50) - (oy + oh);
2838 if (cw->obj) edje_object_part_swallow(cw->frame_object, "e.swallow.client", cw->obj);
2839 evas_object_resize(cw->frame_object, w, h);
2843 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
2846 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
2848 if (input_rect_data->obj)
2850 pass_event_flag = EINA_TRUE;
2856 evas_object_pass_events_set(cw->default_input_obj, pass_event_flag);
2857 evas_object_pass_events_set(cw->obj, pass_event_flag);
2861 cw->client_inset.l = 0;
2862 cw->client_inset.r = 0;
2863 cw->client_inset.t = 0;
2864 cw->client_inset.b = 0;
2866 cw->client_inset.calc = !!cw->frame_object;
2870 _e_comp_smart_cb_frame_recalc(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2872 E_Comp_Object *cw = data;
2876 /* - get current size
2878 * - readjust for new frame size
2881 w = cw->ec->w, h = cw->ec->h;
2882 e_comp_object_frame_wh_unadjust(obj, w, h, &pw, &ph);
2884 _e_comp_object_frame_recalc(cw);
2886 if (!cw->ec->fullscreen)
2887 e_comp_object_frame_wh_adjust(obj, cw->ec->client.w, cw->ec->client.h, &w, &h);
2889 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2890 if (cw->ec->fullscreen)
2892 zone = e_comp_zone_find_by_ec(cw->ec);
2894 evas_object_resize(cw->ec->frame, zone->w, zone->h);
2896 else if (cw->ec->new_client)
2898 if ((cw->ec->w < 1) || (cw->ec->h < 1)) return;
2899 e_comp_object_frame_wh_adjust(obj, pw, ph, &w, &h);
2900 evas_object_resize(cw->ec->frame, w, h);
2902 else if ((w != cw->ec->w) || (h != cw->ec->h))
2903 evas_object_resize(cw->ec->frame, w, h);
2907 _e_comp_smart_cb_maximize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2909 E_Comp_Object *cw = data;
2911 _e_comp_object_shadow_setup(cw);
2912 if (cw->frame_object)
2914 _e_comp_object_shadow(cw);
2915 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize", "e");
2916 _e_comp_object_frame_recalc(cw);
2917 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2922 _e_comp_smart_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2924 E_Comp_Object *cw = data;
2926 if (_e_comp_object_shadow_setup(cw))
2927 e_comp_object_damage(cw->smart_obj, 0, 0, cw->ec->w, cw->ec->h);
2928 if (cw->frame_object)
2930 _e_comp_object_shadow(cw);
2931 e_comp_object_signal_emit(cw->smart_obj, "e,action,maximize,fullscreen", "e");
2932 _e_comp_object_frame_recalc(cw);
2933 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2938 _e_comp_smart_cb_unmaximize(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2940 E_Comp_Object *cw = data;
2942 if (cw->frame_object)
2944 _e_comp_object_shadow(cw);
2945 e_comp_object_signal_emit(obj, "e,action,unmaximize", "e");
2946 _e_comp_object_frame_recalc(cw);
2947 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2952 _e_comp_smart_cb_unfullscreen(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
2954 E_Comp_Object *cw = data;
2956 if (_e_comp_object_shadow_setup(cw))
2959 cw->ec->changes.size = 1;
2961 if (cw->frame_object)
2963 _e_comp_object_shadow(cw);
2964 e_comp_object_signal_emit(obj, "e,action,unmaximize,unfullscreen", "e");
2965 _e_comp_object_frame_recalc(cw);
2966 evas_object_smart_callback_call(cw->smart_obj, "frame_recalc_done", &cw->client_inset);
2971 _e_comp_smart_cb_sticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2973 e_comp_object_signal_emit(obj, "e,state,sticky", "e");
2977 _e_comp_smart_cb_unsticky(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2979 e_comp_object_signal_emit(obj, "e,state,unsticky", "e");
2983 _e_comp_smart_cb_unhung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2985 E_Comp_Object *cw = data;
2987 if (!cw->ec) return; //NYI
2988 e_comp_object_signal_emit(cw->smart_obj, "e,state,unhung", "e");
2992 _e_comp_smart_cb_hung(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2994 E_Comp_Object *cw = data;
2996 if (!cw->ec) return; //NYI
2997 e_comp_object_signal_emit(cw->smart_obj, "e,state,hung", "e");
3001 _e_comp_smart_focus_in(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3003 e_comp_object_signal_emit(obj, "e,state,focused", "e");
3007 _e_comp_smart_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3009 E_Comp_Object *cw = data;
3011 if (!e_object_is_del(E_OBJECT(cw->ec)))
3012 e_comp_object_signal_emit(obj, "e,state,unfocused", "e");
3016 _e_comp_input_obj_smart_add(Evas_Object *obj)
3018 E_Input_Rect_Smart_Data *input_rect_sd;
3019 input_rect_sd = E_NEW(E_Input_Rect_Smart_Data, 1);
3021 if (!input_rect_sd) return;
3022 evas_object_smart_data_set(obj, input_rect_sd);
3026 _e_comp_input_obj_smart_del(Evas_Object *obj)
3028 E_Input_Rect_Smart_Data *input_rect_sd;
3029 E_Input_Rect_Data *input_rect_data;
3031 input_rect_sd = evas_object_smart_data_get(obj);
3032 if (!input_rect_sd) return;
3034 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
3036 if (input_rect_data->obj)
3038 evas_object_smart_member_del(input_rect_data->obj);
3039 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
3041 E_FREE(input_rect_data);
3043 E_FREE(input_rect_sd);
3047 _e_comp_input_obj_smart_move(Evas_Object *obj, int x, int y)
3049 E_Input_Rect_Smart_Data *input_rect_sd;
3050 E_Input_Rect_Data *input_rect_data;
3054 input_rect_sd = evas_object_smart_data_get(obj);
3055 if (!input_rect_sd) return;
3057 cw = input_rect_sd->cw;
3058 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3060 if (input_rect_data->obj)
3062 evas_object_geometry_set(input_rect_data->obj,
3063 x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3064 y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3065 input_rect_data->rect.w, input_rect_data->rect.h);
3071 _e_comp_input_obj_smart_resize(Evas_Object *obj, int w, int h)
3073 E_Input_Rect_Smart_Data *input_rect_sd;
3074 E_Input_Rect_Data *input_rect_data;
3078 input_rect_sd = evas_object_smart_data_get(obj);
3079 if (!input_rect_sd) return;
3081 cw = input_rect_sd->cw;
3082 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3084 if (input_rect_data->obj)
3086 evas_object_geometry_set(input_rect_data->obj,
3087 cw->x + input_rect_data->rect.x + (!!cw->frame_object * cw->client_inset.l),
3088 cw->y + input_rect_data->rect.y + (!!cw->frame_object * cw->client_inset.t),
3089 input_rect_data->rect.w, input_rect_data->rect.h);
3095 _e_comp_input_obj_smart_show(Evas_Object *obj)
3097 E_Input_Rect_Smart_Data *input_rect_sd;
3098 E_Input_Rect_Data *input_rect_data;
3101 input_rect_sd = evas_object_smart_data_get(obj);
3102 if (!input_rect_sd) return;
3104 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3106 if (input_rect_data->obj)
3108 evas_object_show(input_rect_data->obj);
3114 _e_comp_input_obj_smart_hide(Evas_Object *obj)
3116 E_Input_Rect_Smart_Data *input_rect_sd;
3117 E_Input_Rect_Data *input_rect_data;
3120 input_rect_sd = evas_object_smart_data_get(obj);
3121 if (!input_rect_sd) return;
3123 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
3125 if (input_rect_data->obj)
3127 evas_object_hide(input_rect_data->obj);
3133 _e_comp_input_obj_smart_init(void)
3135 if (_e_comp_input_obj_smart) return;
3137 static const Evas_Smart_Class sc =
3139 INPUT_OBJ_SMART_NAME,
3140 EVAS_SMART_CLASS_VERSION,
3141 _e_comp_input_obj_smart_add,
3142 _e_comp_input_obj_smart_del,
3143 _e_comp_input_obj_smart_move,
3144 _e_comp_input_obj_smart_resize,
3145 _e_comp_input_obj_smart_show,
3146 _e_comp_input_obj_smart_hide,
3159 _e_comp_input_obj_smart = evas_smart_class_new(&sc);
3165 _e_comp_smart_add(Evas_Object *obj)
3169 cw = E_NEW(E_Comp_Object, 1);
3170 EINA_SAFETY_ON_NULL_RETURN(cw);
3172 wl_signal_init(&cw->events.lower);
3173 #ifdef REFACTOR_DESK_AREA
3174 wl_signal_init(&cw->events.lower_done);
3175 wl_signal_init(&cw->events.raise);
3177 wl_signal_init(&cw->events.show);
3178 wl_signal_init(&cw->events.hide);
3179 #ifdef REFACTOR_DESK_AREA
3180 wl_signal_init(&cw->events.set_layer);
3181 wl_signal_init(&cw->events.stack_above);
3182 wl_signal_init(&cw->events.stack_below);
3184 wl_signal_init(&cw->events.image_filter_set);
3185 wl_signal_init(&cw->events.render_op_set);
3186 wl_signal_init(&cw->events.content_type_set);
3187 wl_signal_init(&cw->events.color_set);
3188 wl_signal_init(&cw->events.color_visible_set);
3190 cw->smart_obj = obj;
3191 cw->x = cw->y = cw->w = cw->h = -1;
3192 evas_object_smart_data_set(obj, cw);
3193 cw->opacity = 255.0;
3194 cw->external_content = 0;
3195 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_NONE;
3196 cw->transform_bg_color.r = 0;
3197 cw->transform_bg_color.g = 0;
3198 cw->transform_bg_color.b = 0;
3199 cw->transform_bg_color.a = 255;
3200 cw->color_visible = EINA_TRUE;
3201 evas_object_data_set(obj, "comp_obj", cw);
3202 evas_object_move(obj, -1, -1);
3203 /* intercept ALL the callbacks! */
3204 evas_object_intercept_stack_above_callback_add(obj, _e_comp_intercept_stack_above, cw);
3205 evas_object_intercept_stack_below_callback_add(obj, _e_comp_intercept_stack_below, cw);
3206 evas_object_intercept_raise_callback_add(obj, _e_comp_intercept_raise, cw);
3207 evas_object_intercept_lower_callback_add(obj, _e_comp_intercept_lower, cw);
3208 evas_object_intercept_layer_set_callback_add(obj, _e_comp_intercept_layer_set, cw);
3209 evas_object_intercept_move_callback_add(obj, _e_comp_intercept_move, cw);
3210 evas_object_intercept_resize_callback_add(obj, _e_comp_intercept_resize, cw);
3211 evas_object_intercept_show_callback_add(obj, _e_comp_intercept_show, cw);
3212 evas_object_intercept_hide_callback_add(obj, _e_comp_intercept_hide, cw);
3213 evas_object_intercept_focus_set_callback_add(obj, _e_comp_intercept_focus, cw);
3214 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_color_set, cw);
3216 evas_object_smart_callback_add(obj, "maximize", _e_comp_smart_cb_maximize, cw);
3217 evas_object_smart_callback_add(obj, "fullscreen", _e_comp_smart_cb_fullscreen, cw);
3218 evas_object_smart_callback_add(obj, "unmaximize", _e_comp_smart_cb_unmaximize, cw);
3219 evas_object_smart_callback_add(obj, "unfullscreen", _e_comp_smart_cb_unfullscreen, cw);
3221 evas_object_smart_callback_add(obj, "stick", _e_comp_smart_cb_sticky, cw);
3222 evas_object_smart_callback_add(obj, "unstick", _e_comp_smart_cb_unsticky, cw);
3224 evas_object_smart_callback_add(obj, "hung", _e_comp_smart_cb_hung, cw);
3225 evas_object_smart_callback_add(obj, "unhung", _e_comp_smart_cb_unhung, cw);
3227 evas_object_smart_callback_add(obj, "frame_recalc", _e_comp_smart_cb_frame_recalc, cw);
3229 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _e_comp_smart_focus_in, cw);
3230 evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _e_comp_smart_focus_out, cw);
3234 _e_comp_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
3237 evas_object_color_set(cw->clip, r, g, b, a);
3238 evas_object_smart_callback_call(obj, "color_set", NULL);
3243 _e_comp_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
3246 evas_object_clip_set(cw->clip, clip);
3250 _e_comp_smart_clip_unset(Evas_Object *obj)
3253 evas_object_clip_unset(cw->clip);
3257 _e_comp_smart_hide(Evas_Object *obj)
3259 TRACE_DS_BEGIN(COMP:SMART HIDE);
3264 evas_object_hide(cw->clip);
3265 if (cw->input_obj) evas_object_hide(cw->input_obj);
3266 evas_object_hide(cw->effect_obj);
3267 if (cw->default_input_obj) evas_object_hide(cw->default_input_obj);
3268 if (cw->transform_bg_obj) evas_object_hide(cw->transform_bg_obj);
3269 if (cw->transform_tranp_obj) evas_object_hide(cw->transform_tranp_obj);
3276 /* unset native surface if current displaying buffer was destroied */
3277 if (!cw->buffer_destroy_listener.notify)
3279 Evas_Native_Surface *ns;
3280 ns = evas_object_image_native_surface_get(cw->obj);
3281 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
3282 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
3285 if (!cw->ec->input_only)
3287 edje_object_freeze(cw->effect_obj);
3288 edje_object_freeze(cw->shobj);
3289 edje_object_play_set(cw->shobj, 0);
3290 if (cw->frame_object)
3291 edje_object_play_set(cw->frame_object, 0);
3294 e_comp_render_queue(); //force nocomp recheck
3300 _e_comp_smart_show(Evas_Object *obj)
3308 if ((cw->w < 0) || (cw->h < 0))
3309 CRI("ACK! ec:%p", cw->ec);
3311 TRACE_DS_BEGIN(COMP:SMART SHOW);
3313 e_comp_object_map_update(obj);
3315 EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
3316 evas_object_show(tmp->frame);
3318 evas_object_show(cw->clip);
3319 if (cw->input_obj) evas_object_show(cw->input_obj);
3320 if (!cw->ec->input_only)
3322 edje_object_thaw(cw->effect_obj);
3323 edje_object_thaw(cw->shobj);
3324 edje_object_play_set(cw->shobj, 1);
3325 if (cw->frame_object)
3326 edje_object_play_set(cw->frame_object, 1);
3328 evas_object_show(cw->effect_obj);
3329 if (cw->mask.obj) evas_object_show(cw->mask.obj);
3330 if (cw->transform_bg_obj) evas_object_show(cw->transform_bg_obj);
3331 if (cw->transform_tranp_obj) evas_object_show(cw->transform_tranp_obj);
3332 if (cw->default_input_obj) evas_object_show(cw->default_input_obj);
3333 e_comp_render_queue();
3334 if (cw->ec->input_only)
3339 if (cw->ec->iconic && (!cw->ec->new_client))
3341 if (e_client_is_iconified_by_client(cw->ec))
3343 ELOGF("COMP", "Set launching flag..", cw->ec);
3344 cw->ec->launching = EINA_TRUE;
3347 e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e");
3349 else if (!cw->showing) /* if set, client was ec->hidden during show animation */
3352 ELOGF("COMP", "Set launching flag..", cw->ec);
3353 cw->ec->launching = EINA_TRUE;
3355 e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
3356 _e_comp_object_animating_begin(cw);
3357 if (!_e_comp_object_effect_visibility_start(cw, 1))
3363 /* ensure some random effect doesn't lock the client offscreen */
3367 e_comp_object_effect_set(obj, NULL);
3370 _e_comp_object_dim_update(cw);
3376 _e_comp_smart_del(Evas_Object *obj)
3382 if (cw->buffer_destroy_listener.notify)
3384 wl_list_remove(&cw->buffer_destroy_listener.link);
3385 cw->buffer_destroy_listener.notify = NULL;
3388 if (cw->tbm_surface)
3390 tbm_surface_internal_unref(cw->tbm_surface);
3391 cw->tbm_surface = NULL;
3394 if (cw->render_update_lock.buffer_ref.buffer)
3396 ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
3397 cw->ec, cw->render_update_lock.lock);
3398 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
3401 e_comp_object_render_update_del(cw->smart_obj);
3402 E_FREE_FUNC(cw->updates, eina_tiler_free);
3403 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
3410 EINA_LIST_FREE(cw->obj_mirror, o)
3412 evas_object_image_data_set(o, NULL);
3413 evas_object_freeze_events_set(o, 1);
3414 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
3418 #ifdef REFACTOR_DESK_AREA
3420 _e_comp_object_layers_remove(cw);
3422 l = evas_object_data_get(obj, "comp_object-to_del");
3423 E_FREE_LIST(l, evas_object_del);
3424 _e_comp_object_mouse_event_callback_unset(cw);
3425 evas_object_del(cw->clip);
3426 evas_object_del(cw->obj);
3427 evas_object_del(cw->shobj);
3428 evas_object_del(cw->effect_obj);
3429 evas_object_del(cw->frame_object);
3430 evas_object_del(cw->input_obj);
3431 evas_object_del(cw->mask.obj);
3432 if (cw->dim.mask_obj) evas_object_del(cw->dim.mask_obj);
3433 evas_object_del(cw->transform_bg_obj);
3434 evas_object_del(cw->transform_tranp_obj);
3435 evas_object_del(cw->default_input_obj);
3436 eina_stringshare_del(cw->frame_theme);
3437 eina_stringshare_del(cw->frame_name);
3441 e_comp->animating--;
3443 e_object_unref(E_OBJECT(cw->ec));
3445 cw->ec->frame = NULL;
3450 _e_comp_smart_move(Evas_Object *obj, int x, int y)
3454 cw->x = x, cw->y = y;
3455 evas_object_move(cw->effect_obj, x, y);
3456 evas_object_move(cw->default_input_obj, x, y);
3457 if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
3459 e_comp_object_map_update(obj);
3463 _e_comp_smart_resize(Evas_Object *obj, int w, int h)
3465 Eina_Bool first = EINA_FALSE;
3470 if (!cw->effect_obj) CRI("ACK! ec:%p", cw->ec);
3472 TRACE_DS_BEGIN(COMP:SMART RESIZE);
3474 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
3476 if (cw->w != w || cw->h != h)
3477 e_comp_object_map_update(obj);
3479 first = ((cw->w < 1) || (cw->h < 1));
3480 cw->w = w, cw->h = h;
3484 if (cw->frame_object)
3485 e_comp_object_frame_wh_unadjust(obj, w, h, &ww, &hh);
3488 /* verify pixmap:object size */
3489 if (e_pixmap_size_get(cw->ec->pixmap, &pw, &ph) && (!cw->ec->override))
3491 if ((ww != pw) || (hh != ph))
3492 ELOGF("COMP", "CW RSZ: %dx%d || PX: %dx%d.", cw->ec, ww, hh, pw, ph);
3494 evas_object_resize(cw->effect_obj, tw, th);
3495 evas_object_resize(cw->default_input_obj, w, h);
3497 evas_object_resize(cw->input_obj, w, h);
3499 evas_object_resize(cw->mask.obj, w, h);
3500 /* resize render update tiler */
3503 RENDER_DEBUG("DAMAGE UNFULL: %p", cw->ec);
3504 cw->updates_full = 0;
3505 if (cw->updates) eina_tiler_clear(cw->updates);
3509 RENDER_DEBUG("DAMAGE RESIZE(%p): %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
3510 if (cw->updates) eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
3518 e_comp_render_queue();
3524 _e_comp_smart_init(void)
3526 if (_e_comp_smart) return;
3528 static const Evas_Smart_Class sc =
3531 EVAS_SMART_CLASS_VERSION,
3535 _e_comp_smart_resize,
3538 _e_comp_smart_color_set,
3539 _e_comp_smart_clip_set,
3540 _e_comp_smart_clip_unset,
3550 _e_comp_smart = evas_smart_class_new(&sc);
3555 e_comp_object_init(void)
3557 E_EVENT_COMP_OBJECT_ADD = ecore_event_type_new();
3558 E_EVENT_COMP_OBJECT_IMG_RENDER = ecore_event_type_new();
3559 E_EVENT_COMP_OBJECT_EFFECT_START = ecore_event_type_new();
3560 E_EVENT_COMP_OBJECT_EFFECT_END = ecore_event_type_new();
3564 e_comp_object_shutdown(void)
3570 e_comp_object_mirror_visibility_check(Evas_Object *obj)
3572 API_ENTRY EINA_FALSE;
3573 return !!cw->force_visible;
3575 /////////////////////////////////////////////////////////
3578 _e_comp_object_util_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3581 Eina_Bool comp_object;
3583 comp_object = !!evas_object_data_get(obj, "comp_object");
3588 o = edje_object_part_swallow_get(obj, "e.swallow.content");
3590 e_comp_render_queue();
3592 l = evas_object_data_get(obj, "comp_object-to_del");
3593 E_FREE_LIST(l, evas_object_del);
3597 _e_comp_object_util_restack(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3599 if (e_comp_util_object_is_above_nocomp(obj) &&
3600 (!evas_object_data_get(obj, "comp_override")))
3602 evas_object_data_set(obj, "comp_override", (void*)1);
3603 e_comp_override_add();
3608 _e_comp_object_util_show(void *data EINA_UNUSED, Evas_Object *obj)
3610 Eina_Bool ref = EINA_TRUE;
3611 if (evas_object_visible_get(obj))
3615 d = evas_object_data_del(obj, "comp_hiding");
3617 /* currently trying to hide */
3620 /* already visible */
3624 evas_object_show(obj);
3627 evas_object_ref(obj);
3628 evas_object_data_set(obj, "comp_ref", (void*)1);
3630 edje_object_signal_emit(obj, "e,state,visible", "e");
3631 evas_object_data_set(obj, "comp_showing", (void*)1);
3632 if (e_comp_util_object_is_above_nocomp(obj))
3634 evas_object_data_set(obj, "comp_override", (void*)1);
3635 e_comp_override_add();
3640 _e_comp_object_util_hide(void *data EINA_UNUSED, Evas_Object *obj)
3642 if (!evas_object_visible_get(obj)) return;
3643 /* already hiding */
3644 if (evas_object_data_get(obj, "comp_hiding")) return;
3645 if (!evas_object_data_del(obj, "comp_showing"))
3647 evas_object_ref(obj);
3648 evas_object_data_set(obj, "comp_ref", (void*)1);
3650 edje_object_signal_emit(obj, "e,state,hidden", "e");
3651 evas_object_data_set(obj, "comp_hiding", (void*)1);
3653 if (evas_object_data_del(obj, "comp_override"))
3654 e_comp_override_timed_pop();
3658 _e_comp_object_util_done_defer(void *data, Evas_Object *obj, const char *emission, const char *source EINA_UNUSED)
3660 if (!e_util_strcmp(emission, "e,action,hide,done"))
3662 if (!evas_object_data_del(obj, "comp_hiding")) return;
3663 evas_object_intercept_hide_callback_del(obj, _e_comp_object_util_hide);
3664 evas_object_hide(obj);
3665 evas_object_intercept_hide_callback_add(obj, _e_comp_object_util_hide, data);
3668 evas_object_data_del(obj, "comp_showing");
3669 if (evas_object_data_del(obj, "comp_ref"))
3670 evas_object_unref(obj);
3674 _e_comp_object_util_moveresize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
3680 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
3684 E_API E_Comp_Object_Hook *
3685 e_comp_object_hook_add(E_Comp_Object_Hook_Point hookpoint, E_Comp_Object_Hook_Cb func, const void *data)
3687 E_Comp_Object_Hook *ch;
3689 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_HOOK_LAST, NULL);
3690 ch = E_NEW(E_Comp_Object_Hook, 1);
3691 if (!ch) return NULL;
3692 ch->hookpoint = hookpoint;
3694 ch->data = (void*)data;
3695 _e_comp_object_hooks[hookpoint] = eina_inlist_append(_e_comp_object_hooks[hookpoint], EINA_INLIST_GET(ch));
3700 e_comp_object_hook_del(E_Comp_Object_Hook *ch)
3703 if (_e_comp_object_hooks_walking == 0)
3705 _e_comp_object_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3709 _e_comp_object_hooks_delete++;
3712 #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_
3713 E_API E_Comp_Object_Intercept_Hook *
3714 e_comp_object_intercept_hook_add(E_Comp_Object_Intercept_Hook_Point hookpoint, E_Comp_Object_Intercept_Hook_Cb func, const void *data)
3716 E_Comp_Object_Intercept_Hook *ch;
3718 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_COMP_OBJECT_INTERCEPT_HOOK_LAST, NULL);
3719 ch = E_NEW(E_Comp_Object_Intercept_Hook, 1);
3720 if (!ch) return NULL;
3721 ch->hookpoint = hookpoint;
3723 ch->data = (void*)data;
3724 _e_comp_object_intercept_hooks[hookpoint] = eina_inlist_append(_e_comp_object_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
3729 e_comp_object_intercept_hook_del(E_Comp_Object_Intercept_Hook *ch)
3732 if (_e_comp_object_intercept_hooks_walking == 0)
3734 _e_comp_object_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_comp_object_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
3738 _e_comp_object_intercept_hooks_delete++;
3743 e_comp_object_util_add(Evas_Object *obj)
3747 E_Comp_Config *conf = e_comp_config_get();
3748 Eina_Bool skip = EINA_FALSE;
3754 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3756 name = evas_object_name_get(obj);
3757 vis = evas_object_visible_get(obj);
3758 o = edje_object_add(e_comp->evas);
3759 evas_object_data_set(o, "comp_object", (void*)1);
3761 skip = (!strncmp(name, "noshadow", 8));
3763 evas_object_data_set(o, "comp_object_skip", (void*)1);
3765 if (conf->shadow_style)
3767 snprintf(buf, sizeof(buf), "e/comp/frame/%s", conf->shadow_style);
3768 ok = e_theme_edje_object_set(o, "base/theme/comp", buf);
3771 e_theme_edje_object_set(o, "base/theme/comp", "e/comp/frame/default");
3772 if (e_util_strcmp(evas_object_type_get(obj), "edje") || (!edje_object_data_get(obj, "noshadow")))
3773 edje_object_signal_emit(o, "e,state,shadow,on", "e");
3775 edje_object_signal_emit(o, "e,state,shadow,off", "e");
3777 evas_object_geometry_get(obj, &x, &y, &w, &h);
3778 evas_object_geometry_set(o, x, y, w, h);
3779 evas_object_pass_events_set(o, evas_object_pass_events_get(obj));
3781 edje_object_signal_callback_add(o, "e,action,*,done", "e", _e_comp_object_util_done_defer, NULL);
3783 evas_object_intercept_show_callback_add(o, _e_comp_object_util_show, NULL);
3784 evas_object_intercept_hide_callback_add(o, _e_comp_object_util_hide, NULL);
3785 evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_comp_object_util_moveresize, NULL);
3786 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3787 evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _e_comp_object_util_moveresize, NULL);
3788 evas_object_event_callback_add(o, EVAS_CALLBACK_RESTACK, _e_comp_object_util_restack, NULL);
3790 e_comp_object_signal_emit(o, "e,state,hidden", "e");
3792 edje_object_part_swallow(o, "e.swallow.content", obj);
3794 _e_comp_object_event_add(o);
3797 evas_object_show(o);
3802 /* utility functions for deleting objects when their "owner" is deleted */
3804 e_comp_object_util_del_list_append(Evas_Object *obj, Evas_Object *to_del)
3809 EINA_SAFETY_ON_NULL_RETURN(to_del);
3810 l = evas_object_data_get(obj, "comp_object-to_del");
3811 evas_object_data_set(obj, "comp_object-to_del", eina_list_append(l, to_del));
3812 evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del);
3813 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_util_del, NULL);
3817 e_comp_object_util_del_list_remove(Evas_Object *obj, Evas_Object *to_del)
3822 EINA_SAFETY_ON_NULL_RETURN(to_del);
3823 l = evas_object_data_get(obj, "comp_object-to_del");
3825 evas_object_data_set(obj, "comp_object-to_del", eina_list_remove(l, to_del));
3828 /////////////////////////////////////////////////////////
3830 EINTERN Evas_Object *
3831 e_comp_object_client_add(E_Client *ec)
3836 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3837 if (ec->frame) return NULL;
3838 _e_comp_smart_init();
3839 o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
3840 cw = evas_object_smart_data_get(o);
3841 if (!cw) return NULL;
3842 evas_object_data_set(o, "E_Client", ec);
3845 evas_object_data_set(o, "comp_object", (void*)1);
3847 _e_comp_object_event_add(o);
3852 /* utility functions for getting client inset */
3854 e_comp_object_frame_xy_adjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3857 if (!cw->client_inset.calc)
3863 if (ax) *ax = x - cw->client_inset.l;
3864 if (ay) *ay = y - cw->client_inset.t;
3868 e_comp_object_frame_xy_unadjust(Evas_Object *obj, int x, int y, int *ax, int *ay)
3871 if (!cw->client_inset.calc)
3877 if (ax) *ax = x + cw->client_inset.l;
3878 if (ay) *ay = y + cw->client_inset.t;
3882 e_comp_object_frame_wh_adjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3885 if (!cw->client_inset.calc)
3891 if (aw) *aw = w + cw->client_inset.l + cw->client_inset.r;
3892 if (ah) *ah = h + cw->client_inset.t + cw->client_inset.b;
3896 e_comp_object_frame_wh_unadjust(Evas_Object *obj, int w, int h, int *aw, int *ah)
3899 if (!cw->client_inset.calc)
3905 if (aw) *aw = w - cw->client_inset.l - cw->client_inset.r;
3906 if (ah) *ah = h - cw->client_inset.t - cw->client_inset.b;
3910 e_comp_object_client_get(Evas_Object *obj)
3915 /* FIXME: remove this when eo is used */
3916 o = evas_object_data_get(obj, "comp_smart_obj");
3918 return e_comp_object_client_get(o);
3919 return cw ? cw->ec : NULL;
3923 e_comp_object_frame_extends_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
3926 if (cw->frame_extends)
3927 edje_object_parts_extends_calc(cw->frame_object, x, y, w, h);
3932 if (w) *w = cw->ec->w;
3933 if (h) *h = cw->ec->h;
3938 e_comp_object_util_zone_get(Evas_Object *obj)
3940 E_Zone *zone = NULL;
3944 zone = e_comp_zone_find_by_ec(cw->ec);
3949 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
3950 zone = e_comp_zone_xy_get(x, y);
3956 e_comp_object_util_center(Evas_Object *obj)
3958 int x, y, w, h, ow, oh;
3963 zone = e_comp_object_util_zone_get(obj);
3964 EINA_SAFETY_ON_NULL_RETURN(zone);
3965 e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
3966 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3967 ow = cw->ec->w, oh = cw->ec->h;
3969 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3970 x = x + (w - ow) / 2;
3971 y = y + (h - oh) / 2;
3972 evas_object_move(obj, x, y);
3976 e_comp_object_util_center_on(Evas_Object *obj, Evas_Object *on)
3978 int x, y, w, h, ow, oh;
3981 EINA_SAFETY_ON_NULL_RETURN(on);
3982 evas_object_geometry_get(on, &x, &y, &w, &h);
3983 if (cw && (cw->ec->changes.size || cw->ec->new_client))
3984 ow = cw->ec->w, oh = cw->ec->h;
3986 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3987 evas_object_move(obj, x + (w / 2) - (ow / 2), y + (h / 2) - (oh / 2));
3991 e_comp_object_util_fullscreen(Evas_Object *obj)
3996 e_client_fullscreen(cw->ec, E_FULLSCREEN_RESIZE);
3999 evas_object_move(obj, 0, 0);
4000 evas_object_resize(obj, e_comp->w, e_comp->h);
4005 e_comp_object_util_center_pos_get(Evas_Object *obj, int *x, int *y)
4013 ow = cw->w, oh = cw->h;
4015 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
4016 zone = e_comp_object_util_zone_get(obj);
4017 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4018 if (x) *x = zx + (zw - ow) / 2;
4019 if (y) *y = zy + (zh - oh) / 2;
4023 e_comp_object_input_objs_del(Evas_Object *obj)
4026 E_Input_Rect_Data *input_rect_data;
4027 E_Input_Rect_Smart_Data *input_rect_sd;
4032 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4033 if (!input_rect_sd) return;
4035 EINA_LIST_FREE(input_rect_sd->input_rect_data_list, input_rect_data)
4037 if (input_rect_data->obj)
4039 evas_object_smart_member_del(input_rect_data->obj);
4040 E_FREE_FUNC(input_rect_data->obj, evas_object_del);
4042 E_FREE(input_rect_data);
4047 e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h)
4050 E_Input_Rect_Data *input_rect_data = NULL;
4051 E_Input_Rect_Smart_Data *input_rect_sd;
4052 int client_w, client_h;
4054 if (cw->ec->client.w)
4055 client_w = cw->ec->client.w;
4057 client_w = cw->ec->w;
4059 if (cw->ec->client.h)
4060 client_h = cw->ec->client.h;
4062 client_h = cw->ec->h;
4064 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, client_w, client_h);
4068 _e_comp_input_obj_smart_init();
4069 cw->input_obj = evas_object_smart_add(e_comp->evas, _e_comp_input_obj_smart);
4070 evas_object_smart_member_add(cw->input_obj, cw->smart_obj);
4071 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4074 input_rect_sd->cw = cw;
4077 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4080 input_rect_data = E_NEW(E_Input_Rect_Data, 1);
4081 if (input_rect_data)
4083 EINA_RECTANGLE_SET(&input_rect_data->rect, x, y, w, h);
4084 input_rect_sd->input_rect_data_list = eina_list_append(input_rect_sd->input_rect_data_list, input_rect_data);
4088 if ((input_rect_data) &&
4089 (x || y || (w != cw->ec->client.w) || (h != cw->ec->client.h)))
4091 input_rect_data->obj = evas_object_rectangle_add(e_comp->evas);
4092 evas_object_name_set(input_rect_data->obj, "cw->input_obj");
4093 evas_object_color_set(input_rect_data->obj, 0, 0, 0, 0);
4094 evas_object_clip_set(input_rect_data->obj, cw->clip);
4095 evas_object_smart_member_add(input_rect_data->obj, cw->input_obj);
4096 evas_object_geometry_set(input_rect_data->obj,
4097 cw->ec->client.x + (!!cw->frame_object * cw->client_inset.l) + x,
4098 cw->ec->client.y + (!!cw->frame_object * cw->client_inset.t) + y, w, h);
4099 evas_object_pass_events_set(cw->default_input_obj, 1);
4100 evas_object_pass_events_set(cw->obj, 1);
4103 evas_object_show(input_rect_data->obj);
4104 evas_object_show(cw->input_obj);
4109 evas_object_smart_member_del(cw->input_obj);
4110 E_FREE_FUNC(cw->input_obj, evas_object_del);
4111 evas_object_pass_events_set(cw->default_input_obj, 0);
4112 evas_object_pass_events_set(cw->obj, 0);
4117 e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list)
4120 E_Input_Rect_Smart_Data *input_rect_sd;
4121 E_Input_Rect_Data *input_rect_data;
4124 if (!cw->input_obj) return;
4126 input_rect_sd = evas_object_smart_data_get(cw->input_obj);
4129 EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data)
4131 *list = eina_list_append(*list, &input_rect_data->rect);
4137 e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b)
4140 if (l) *l = cw->client_inset.l;
4141 if (r) *r = cw->client_inset.r;
4142 if (t) *t = cw->client_inset.t;
4143 if (b) *b = cw->client_inset.b;
4146 /* set geometry for CSD */
4148 e_comp_object_frame_geometry_set(Evas_Object *obj, int l, int r, int t, int b)
4154 if (cw->frame_object)
4155 CRI("ACK! ec:%p", cw->ec);
4156 if ((cw->client_inset.l == l) && (cw->client_inset.r == r) &&
4157 (cw->client_inset.t == t) && (cw->client_inset.b == b)) return;
4158 calc = cw->client_inset.calc;
4159 cw->client_inset.calc = l || r || t || b;
4160 eina_stringshare_replace(&cw->frame_theme, "borderless");
4161 if (cw->client_inset.calc)
4163 tw = cw->ec->w + ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4164 th = cw->ec->h + ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4165 e_client_size_set(cw->ec, tw, th);
4167 else if (cw->ec->maximized || cw->ec->fullscreen)
4169 cw->ec->saved.w -= ((l + r) - (cw->client_inset.l + cw->client_inset.r));
4170 cw->ec->saved.h -= ((t + b) - (cw->client_inset.t + cw->client_inset.b));
4172 if (!cw->ec->new_client)
4174 if (calc && cw->client_inset.calc)
4176 tx = cw->ec->x - (l - cw->client_inset.l);
4177 ty = cw->ec->y - (t - cw->client_inset.t);
4178 e_client_pos_set(cw->ec, tx, ty);
4180 cw->ec->changes.pos = cw->ec->changes.size = 1;
4183 cw->client_inset.l = l;
4184 cw->client_inset.r = r;
4185 cw->client_inset.t = t;
4186 cw->client_inset.b = b;
4190 e_comp_object_frame_allowed(Evas_Object *obj)
4192 API_ENTRY EINA_FALSE;
4193 return (cw->frame_object || (!cw->client_inset.calc));
4197 e_comp_object_frame_title_set(Evas_Object *obj, const char *name)
4199 API_ENTRY EINA_FALSE;
4200 if (!e_util_strcmp(cw->frame_name, name)) return EINA_FALSE;
4201 eina_stringshare_replace(&cw->frame_name, name);
4202 if (cw->frame_object)
4203 edje_object_part_text_set(cw->frame_object, "e.text.title", cw->frame_name);
4208 e_comp_object_frame_exists(Evas_Object *obj)
4210 API_ENTRY EINA_FALSE;
4211 return !!cw->frame_object;
4215 e_comp_object_frame_theme_set(Evas_Object *obj, const char *name)
4217 Evas_Object *o, *pbg;
4220 Eina_Stringshare *theme;
4222 API_ENTRY EINA_FALSE;
4224 if (!e_util_strcmp(cw->frame_theme, name))
4225 return edje_object_part_swallow(cw->shobj, "e.swallow.content", cw->frame_object ?: cw->obj);
4226 if (!e_util_strcmp(name, "COMP_RESHADOW"))
4227 return _e_comp_object_shadow_setup(cw);
4228 pbg = cw->frame_object;
4229 theme = eina_stringshare_add(name);
4231 if (cw->frame_object)
4235 w = cw->ec->w, h = cw->ec->h;
4236 e_comp_object_frame_wh_unadjust(obj, w, h, &cw->ec->w, &cw->ec->h);
4237 if ((cw->ec->w != w) || (cw->ec->h != h))
4239 cw->ec->changes.size = 1;
4242 E_FREE_FUNC(cw->frame_object, evas_object_del);
4243 if (!name) goto reshadow;
4245 o = edje_object_add(e_comp->evas);
4246 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", name);
4247 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4248 if ((!ok) && (!e_util_strcmp(name, "borderless")))
4250 cw->frame_object = NULL;
4252 eina_stringshare_del(cw->frame_theme);
4253 cw->frame_theme = theme;
4258 if (theme != e_config->theme_default_border_style)
4260 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
4261 ok = e_theme_edje_object_set(o, "base/theme/border", buf);
4265 ok = e_theme_edje_object_set(o, "base/theme/border",
4266 "e/widgets/border/default/border");
4267 if (ok && (theme == e_config->theme_default_border_style))
4269 /* Reset default border style to default */
4270 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
4271 e_config_save_queue();
4278 cw->frame_object = o;
4279 eina_stringshare_del(cw->frame_theme);
4280 cw->frame_theme = theme;
4281 evas_object_name_set(o, "cw->frame_object");
4284 edje_object_part_text_set(o, "e.text.title", cw->frame_name);
4288 cw->ec->changes.icon = 1;
4294 CRI("USER IS USING A SHITTY THEME! ABORT!!!!");
4299 _e_comp_object_shadow_setup(cw);
4302 int old_x, old_y, new_x = 0, new_y = 0;
4304 old_x = cw->x, old_y = cw->y;
4306 _e_comp_smart_cb_frame_recalc(cw, cw->smart_obj, NULL);
4308 new_x = cw->ec->x, new_y = cw->ec->y;
4309 else if (cw->ec->placed || (!cw->ec->new_client))
4311 /* if no previous frame:
4312 * - reapply client_inset
4317 if (cw->ec->changes.size)
4325 zone = e_comp_zone_find_by_ec(cw->ec);
4328 x = cw->ec->client.x, y = cw->ec->client.y;
4329 x = MAX(zone->x, cw->ec->client.x - cw->client_inset.l);
4330 y = MAX(zone->y, cw->ec->client.y - cw->client_inset.t);
4332 new_x = x, new_y = y;
4335 if (old_x != new_x || old_y != new_y)
4337 /* this guarantees that we won't get blocked by the NOP check in the interceptor */
4338 cw->y = cw->x = -99999;
4339 evas_object_move(obj, new_x, new_y);
4343 if (cw->ec->maximized)
4345 cw->ec->changes.need_maximize = 1;
4348 evas_object_smart_callback_call(cw->smart_obj, "frame_changed", NULL);
4349 if (cw->frame_object)
4351 cw->frame_extends = !!edje_object_data_get(cw->frame_object, "frame_extends");
4354 cw->frame_extends = 0;
4355 evas_object_del(pbg);
4360 e_comp_object_signal_emit(Evas_Object *obj, const char *sig, const char *src)
4362 E_Comp_Object_Mover *prov;
4365 //INF("EMIT %p: %s %s", cw->ec, sig, src);
4366 edje_object_signal_emit(cw->shobj, sig, src);
4367 if (cw->frame_object) edje_object_signal_emit(cw->frame_object, sig, src);
4368 if ((cw->ec->override && e_comp_config_get()->match.disable_overrides) ||
4369 ((!cw->ec->override) && e_comp_config_get()->match.disable_borders))
4371 /* start with highest priority callback first */
4372 EINA_INLIST_REVERSE_FOREACH(_e_comp_object_movers, prov)
4374 if (!e_util_glob_match(sig, prov->sig)) continue;
4375 if (prov->func(prov->data, obj, sig)) break;
4380 e_comp_object_signal_callback_add(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4382 /* FIXME: at some point I guess this should use eo to inherit
4383 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_ADD
4384 * -EDJE_OBJ_SUB_ID_SIGNAL_CALLBACK_DEL
4387 edje_object_signal_callback_add(cw->shobj, sig, src, cb, (void*)data);
4391 e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb)
4394 edje_object_signal_callback_del(cw->shobj, sig, src, cb);
4398 e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data)
4401 edje_object_signal_callback_del_full(cw->shobj, sig, src, cb, (void*)data);
4405 e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h)
4408 Eina_Rectangle rect;
4411 if (cw->ec->input_only || (!cw->updates)) return;
4412 if (cw->nocomp) return;
4413 rect.x = x, rect.y = y;
4414 rect.w = w, rect.h = h;
4415 evas_object_smart_callback_call(obj, "damage", &rect);
4417 if (e_comp_is_on_overlay(cw->ec))
4419 /* It will not set hwc_need_update value if E modules already cleanup pixmap
4420 * resource on the E_COMP_WL_HOOK_BUFFER_CHANGE hook function. It means that
4421 * E module attempts to block screen update due to the particular policy.
4423 if (e_pixmap_resource_get(cw->ec->pixmap))
4424 cw->hwc_need_update = EINA_TRUE;
4427 /* ignore overdraw */
4428 if (cw->updates_full)
4430 RENDER_DEBUG("IGNORED %p: %d,%d %dx%d", cw->ec, x, y, w, h);
4431 e_comp_object_render_update_add(obj);
4433 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4434 evas_object_show(cw->smart_obj);
4438 /* clip rect to client surface */
4439 RENDER_DEBUG("DAMAGE(%d,%d %dx%d) CLIP(%dx%d)", x, y, w, h, cw->ec->client.w, cw->ec->client.h);
4440 E_RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, cw->ec->client.w, cw->ec->client.h);
4441 /* if rect is the total size of the client after clip, clear the updates
4442 * since this is guaranteed to be the whole region anyway
4444 eina_tiler_area_size_get(cw->updates, &tw, &th);
4445 if ((w > tw) || (h > th))
4447 RENDER_DEBUG("DAMAGE RESIZE %p: %dx%d", cw->ec, cw->ec->client.w, cw->ec->client.h);
4448 eina_tiler_clear(cw->updates);
4449 eina_tiler_area_size_set(cw->updates, cw->ec->client.w, cw->ec->client.h);
4451 tw = cw->ec->client.w, th = cw->ec->client.h;
4453 if ((!x) && (!y) && (w == tw) && (h == th))
4455 eina_tiler_clear(cw->updates);
4456 RENDER_DEBUG("DAMAGE FULL: %p", cw->ec);
4457 cw->updates_full = 1;
4458 cw->update_count = 0;
4461 if (cw->update_count > UPDATE_MAX)
4463 /* this is going to get really dumb, so just update the whole thing */
4464 eina_tiler_clear(cw->updates);
4465 cw->update_count = cw->updates_full = 1;
4466 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){0, 0, tw, th});
4467 RENDER_DEBUG("DAMAGE MAX: %dx%d", tw, th);
4471 eina_tiler_rect_add(cw->updates, &(Eina_Rectangle){x, y, w, h});
4472 RENDER_DEBUG("DAMAGE: %d,%d %dx%d", x, y, w, h);
4474 cw->updates_exist = 1;
4475 e_comp_object_render_update_add(obj);
4477 if ((cw->ec->visible) && (!evas_object_visible_get(cw->smart_obj)) && (!cw->ec->iconic))
4478 evas_object_show(cw->smart_obj);
4482 e_comp_object_damage_exists(Evas_Object *obj)
4484 API_ENTRY EINA_FALSE;
4485 return cw->updates_exist;
4489 e_comp_object_render_update_add(Evas_Object *obj)
4493 if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
4494 if (cw->render_update_lock.lock) return;
4495 if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
4499 e_comp->updates = eina_list_append(e_comp->updates, cw->ec);
4501 e_comp_render_queue();
4505 e_comp_object_render_update_del(Evas_Object *obj)
4509 if (cw->ec->input_only || (!cw->updates)) return;
4510 if (!cw->update) return;
4512 /* this gets called during comp animating to clear the update flag */
4513 if (e_comp->grabbed) return;
4514 e_comp->updates = eina_list_remove(e_comp->updates, cw->ec);
4515 if (!e_comp->updates)
4517 E_FREE_FUNC(e_comp->update_job, ecore_job_del);
4518 if (e_comp->render_animator)
4519 ecore_animator_freeze(e_comp->render_animator);
4524 e_comp_object_shape_apply(Evas_Object *obj)
4528 unsigned int i, *pix, *p;
4532 if (!cw->ec) return; //NYI
4533 if (cw->external_content) return;
4536 if ((cw->ec->shape_rects_num >= 1) &&
4537 (!_e_comp_shaped_check(cw->ec->client.w, cw->ec->client.h, cw->ec->shape_rects, cw->ec->shape_rects_num)))
4542 ERR("BUGGER: shape with native surface? cw=%p", cw);
4545 evas_object_image_size_get(cw->obj, &w, &h);
4546 if ((w < 1) || (h < 1)) return;
4549 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4550 _e_comp_object_alpha_set(cw);
4551 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4552 evas_object_image_alpha_set(o, 1);
4554 p = pix = evas_object_image_data_get(cw->obj, 1);
4557 evas_object_image_data_set(cw->obj, pix);
4562 unsigned char *spix, *sp;
4564 spix = calloc(w * h, sizeof(unsigned char));
4566 for (i = 0; i < cw->ec->shape_rects_num; i++)
4570 rx = cw->ec->shape_rects[i].x; ry = cw->ec->shape_rects[i].y;
4571 rw = cw->ec->shape_rects[i].w; rh = cw->ec->shape_rects[i].h;
4572 E_RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, w, h);
4573 sp = spix + (w * ry) + rx;
4574 for (py = 0; py < rh; py++)
4576 for (px = 0; px < rw; px++)
4584 for (py = 0; py < h; py++)
4586 for (px = 0; px < w; px++)
4588 unsigned int mask, imask;
4590 mask = ((unsigned int)(*sp)) << 24;
4592 imask |= imask >> 8;
4593 imask |= imask >> 8;
4594 *p = mask | (*p & imask);
4595 //if (*sp) *p = 0xff000000 | *p;
4596 //else *p = 0x00000000;
4605 for (py = 0; py < h; py++)
4607 for (px = 0; px < w; px++)
4611 evas_object_image_data_set(cw->obj, pix);
4612 evas_object_image_data_update_add(cw->obj, 0, 0, w, h);
4613 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4615 evas_object_image_data_set(o, pix);
4616 evas_object_image_data_update_add(o, 0, 0, w, h);
4618 // don't need to fix alpha chanel as blending
4619 // should be totally off here regardless of
4620 // alpha channel content
4624 _e_comp_object_clear(E_Comp_Object *cw)
4629 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4631 if (cw->render_update_lock.lock) return;
4634 e_pixmap_clear(cw->ec->pixmap);
4636 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4637 evas_object_image_size_set(cw->obj, 1, 1);
4638 evas_object_image_data_set(cw->obj, NULL);
4639 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4641 evas_object_image_size_set(o, 1, 1);
4642 evas_object_image_data_set(o, NULL);
4645 e_comp_object_render_update_del(cw->smart_obj);
4649 _e_comp_object_transparent_set(Evas_Object *obj, Eina_Bool set)
4653 API_ENTRY EINA_FALSE;
4655 if (cw->transparent.set == set)
4660 evas_object_color_get(obj, &r, &g, &b, &a);
4662 cw->transparent.user_r = r;
4663 cw->transparent.user_g = g;
4664 cw->transparent.user_b = b;
4665 cw->transparent.user_a = a;
4667 cw->transparent.setting = EINA_TRUE;
4668 evas_object_color_set(obj, 0, 0, 0, 0);
4669 cw->transparent.setting = EINA_FALSE;
4671 ELOGF("COMP", "Transparent enabled user_color(%d,%d,%d,%d)",
4673 cw->transparent.user_r,
4674 cw->transparent.user_g,
4675 cw->transparent.user_b,
4676 cw->transparent.user_a);
4678 cw->transparent.set = EINA_TRUE;
4682 cw->transparent.set = EINA_FALSE;
4684 evas_object_color_set(obj,
4685 cw->transparent.user_r,
4686 cw->transparent.user_g,
4687 cw->transparent.user_b,
4688 cw->transparent.user_a);
4690 ELOGF("COMP", "Transparent disabled user_color(%d,%d,%d,%d)",
4692 cw->transparent.user_r,
4693 cw->transparent.user_g,
4694 cw->transparent.user_b,
4695 cw->transparent.user_a);
4701 /* helper function to simplify toggling of redirection for display servers which support it */
4703 e_comp_object_redirected_set(Evas_Object *obj, Eina_Bool set)
4708 if (cw->redirected == set) return;
4709 cw->redirected = set;
4710 if (cw->external_content) return;
4712 e_comp_object_map_update(obj);
4716 if (cw->updates_exist)
4717 e_comp_object_render_update_add(obj);
4719 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4721 _e_comp_object_transparent_set(obj, EINA_FALSE);
4722 evas_object_smart_callback_call(obj, "redirected", NULL);
4726 _e_comp_object_clear(cw);
4727 _e_comp_object_transparent_set(obj, EINA_TRUE);
4728 evas_object_smart_callback_call(obj, "unredirected", NULL);
4733 _e_comp_object_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
4736 cw = container_of(listener, E_Comp_Object, buffer_destroy_listener);
4738 if (cw->buffer_destroy_listener.notify)
4740 cw->buffer_destroy_listener.notify = NULL;
4741 wl_list_remove(&cw->buffer_destroy_listener.link);
4744 if (e_object_is_del(E_OBJECT(cw->ec)))
4746 if (!e_object_delay_del_ref_get(E_OBJECT(cw->ec)))
4751 /* if it's current displaying buffer, do not remove its content */
4752 if (!evas_object_visible_get(cw->ec->frame))
4753 _e_comp_object_native_surface_set(cw, NULL, EINA_TRUE);
4758 _e_comp_object_native_surface_set(E_Comp_Object *cw, Evas_Native_Surface *ns, Eina_Bool with_mirror)
4763 if (cw->buffer_destroy_listener.notify)
4765 wl_list_remove(&cw->buffer_destroy_listener.link);
4766 cw->buffer_destroy_listener.notify = NULL;
4769 if (cw->tbm_surface)
4771 tbm_surface_internal_unref(cw->tbm_surface);
4772 cw->tbm_surface = NULL;
4777 if ((ns->type == EVAS_NATIVE_SURFACE_WL) && (ns->data.wl.legacy_buffer))
4779 cw->buffer_destroy_listener.notify = _e_comp_object_cb_buffer_destroy;
4780 wl_resource_add_destroy_listener((struct wl_resource *)ns->data.wl.legacy_buffer, &cw->buffer_destroy_listener);
4782 else if ((ns->type == EVAS_NATIVE_SURFACE_TBM) && (ns->data.tbm.buffer))
4784 tbm_surface_internal_ref(ns->data.tbm.buffer);
4785 cw->tbm_surface = ns->data.tbm.buffer;
4789 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4790 evas_object_image_native_surface_set(cw->obj, ns);
4794 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
4796 evas_object_image_alpha_set(o, !!cw->ns ? 1 : cw->ec->argb);
4797 TRACE_DS_BEGIN(NATIVE_SURFACE_SET);
4798 evas_object_image_native_surface_set(o, ns);
4805 e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
4807 Evas_Native_Surface ns;
4810 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
4811 if (cw->ec->input_only) return;
4812 if (cw->external_content) return;
4813 if (cw->render_update_lock.lock) return;
4816 memset(&ns, 0, sizeof(Evas_Native_Surface));
4820 /* native requires gl enabled, texture from pixmap enabled, and a non-shaped client */
4821 set = (!cw->ec->shaped);
4823 set = (!!cw->ns) || e_pixmap_native_surface_init(cw->ec->pixmap, &ns);
4827 _e_comp_object_native_surface_set(cw, set && (!cw->blanked) ? (cw->ns ? cw->ns : &ns) : NULL, EINA_TRUE);
4831 e_comp_object_native_surface_override(Evas_Object *obj, Evas_Native_Surface *ns)
4834 if (cw->ec->input_only) return;
4837 cw->ns = (Evas_Native_Surface*)eina_memdup((unsigned char*)ns, sizeof(Evas_Native_Surface), 0);
4838 _e_comp_object_alpha_set(cw);
4840 e_comp_object_native_surface_set(obj, cw->native);
4841 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4845 e_comp_object_blank(Evas_Object *obj, Eina_Bool set)
4851 if (cw->blanked == set) return;
4853 _e_comp_object_alpha_set(cw);
4856 _e_comp_object_native_surface_set(cw, NULL, EINA_FALSE);
4857 evas_object_image_data_set(cw->obj, NULL);
4861 e_comp_object_native_surface_set(obj, 1);
4862 e_comp_object_damage(obj, 0, 0, cw->w, cw->h);
4866 _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)
4871 if (!_damage_trace) return;
4875 if (!evas_object_visible_get(cw->obj)) return;
4877 evas_object_geometry_get(cw->obj, &obj_x, &obj_y, NULL, NULL);
4879 o = evas_object_rectangle_add(e_comp->evas);
4880 evas_object_layer_set(o, E_LAYER_MAX);
4881 evas_object_name_set(o, "damage_trace");
4882 evas_object_move(o, dmg_x + obj_x, dmg_y + obj_y);
4883 evas_object_resize(o, dmg_w, dmg_h);
4884 evas_object_color_set(o, 0, 128, 0, 128);
4885 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
4886 evas_object_pass_events_set(o, EINA_TRUE);
4887 evas_object_show(o);
4889 ELOGF("COMP", "add damage(%dx%d+%d+%d) origin(%dx%d+%d+%d)",
4891 dmg_w, dmg_h, dmg_x, dmg_y,
4892 origin->w, origin->h, origin->x, origin->y);
4894 _damage_trace_objs = eina_list_append(_damage_trace_objs, o);
4897 /* mark an object as dirty and setup damages */
4899 e_comp_object_dirty(Evas_Object *obj)
4902 Eina_Rectangle *rect;
4906 Eina_Bool dirty, visible;
4910 if (cw->external_content) return;
4911 if (!cw->redirected) return;
4912 if (cw->render_update_lock.lock)
4914 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
4917 /* only actually dirty if pixmap is available */
4918 if (!e_pixmap_resource_get(cw->ec->pixmap))
4920 // e_pixmap_size_get returns last attached buffer size
4921 // eventhough it is destroyed
4922 ERR("ERROR NO PIXMAP FOR ec:%p", cw->ec);
4925 dirty = e_pixmap_size_get(cw->ec->pixmap, &w, &h);
4926 visible = cw->visible;
4927 if (!dirty) w = h = 1;
4928 evas_object_image_pixels_dirty_set(cw->obj, cw->blanked ? 0 : dirty);
4930 evas_object_image_data_set(cw->obj, NULL);
4931 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
4932 evas_object_image_size_set(cw->obj, tw, th);
4933 if (cw->mask.obj) evas_object_resize(cw->mask.obj, w, h);
4934 if (cw->pending_updates)
4935 eina_tiler_area_size_set(cw->pending_updates, w, h);
4936 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4938 evas_object_image_pixels_dirty_set(o, dirty);
4940 evas_object_image_data_set(o, NULL);
4941 evas_object_image_size_set(o, tw, th);
4942 visible |= evas_object_visible_get(o);
4946 ERR("ERROR FETCHING PIXMAP FOR %p", cw->ec);
4950 e_comp_object_native_surface_set(obj, 1);
4952 m = _e_comp_object_map_damage_transform_get(cw->ec);
4953 it = eina_tiler_iterator_new(cw->updates);
4954 EINA_ITERATOR_FOREACH(it, rect)
4956 /* evas converts damage according to rotation of ecore_evas in damage_region_set
4957 * of evas engine and doesn't convert damage according to evas_map.
4958 * so damage of evas_object_image use surface coordinate.
4962 int damage_x, damage_y, damage_w, damage_h;
4964 _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
4965 &damage_x, &damage_y, &damage_w, &damage_h);
4966 evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
4967 _e_comp_object_damage_trace_rect_set(obj, rect, damage_x, damage_y, damage_w, damage_h);
4971 evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
4972 _e_comp_object_damage_trace_rect_set(obj, rect, rect->x, rect->y, rect->w, rect->h);
4975 EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
4976 evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
4977 if (cw->pending_updates)
4978 eina_tiler_rect_add(cw->pending_updates, rect);
4980 eina_iterator_free(it);
4981 if (m) e_map_free(m);
4982 if (cw->pending_updates)
4983 eina_tiler_clear(cw->updates);
4986 cw->pending_updates = cw->updates;
4987 cw->updates = eina_tiler_new(w, h);
4988 eina_tiler_tile_size_set(cw->updates, 1, 1);
4990 cw->update_count = cw->updates_full = cw->updates_exist = 0;
4991 evas_object_smart_callback_call(obj, "dirty", NULL);
4992 if (cw->visible || (!visible) || (!cw->pending_updates) || cw->native) return;
4993 /* force render if main object is hidden but mirrors are visible */
4994 RENDER_DEBUG("FORCING RENDER %p", cw->ec);
4995 e_comp_object_render(obj);
4999 e_comp_object_render(Evas_Object *obj)
5006 API_ENTRY EINA_FALSE;
5008 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5009 if (cw->ec->input_only) return EINA_TRUE;
5010 if (cw->external_content) return EINA_TRUE;
5011 if (cw->native) return EINA_FALSE;
5012 /* if comp object is not redirected state, comp object should not be set by newly committed data
5013 because image size of comp object is 1x1 and it should not be shown on canvas */
5014 if (!cw->redirected) return EINA_TRUE;
5015 if (cw->render_update_lock.lock)
5017 ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
5020 e_comp_object_render_update_del(obj);
5021 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
5023 if (!cw->pending_updates)
5025 WRN("RENDER [%p]: NO RECTS!", cw->ec);
5026 evas_object_image_data_set(cw->obj, NULL);
5027 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5028 evas_object_image_data_set(o, NULL);
5032 evas_object_image_pixels_dirty_set(cw->obj, EINA_FALSE);
5034 RENDER_DEBUG("RENDER SIZE: %dx%d", pw, ph);
5036 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5039 e_pixmap_image_refresh(cw->ec->pixmap);
5040 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5043 if ((pix) && ((!cw->blanked) || (cw->obj_mirror)))
5044 e_pixmap_image_data_ref(cw->ec->pixmap);
5046 /* set pixel data */
5047 evas_object_image_data_set(cw->obj, cw->blanked ? NULL : pix);
5048 _e_comp_object_alpha_set(cw);
5049 EINA_LIST_FOREACH(cw->obj_mirror, l, o)
5051 evas_object_image_data_set(o, pix);
5052 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5053 evas_object_image_pixels_dirty_set(o, EINA_FALSE);
5056 E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
5058 e_comp_client_post_update_add(cw->ec);
5063 /* create a duplicate of an evas object */
5065 e_comp_object_util_mirror_add(Evas_Object *obj)
5069 unsigned int *pix = NULL;
5070 Eina_Bool argb = EINA_FALSE;
5075 cw = evas_object_data_get(obj, "comp_mirror");
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 evas_object_image_alpha_set(o, 1);
5082 evas_object_image_source_set(o, obj);
5085 if ((!cw->ec) || (!e_pixmap_size_get(cw->ec->pixmap, &w, &h))) return NULL;
5086 if (cw->external_content)
5088 ERR("%p of client %p is external content.", obj, cw->ec);
5091 o = evas_object_image_filled_add(evas_object_evas_get(obj));
5092 evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
5093 evas_object_image_smooth_scale_set(o, e_comp_config_get()->smooth_windows);
5094 cw->obj_mirror = eina_list_append(cw->obj_mirror, o);
5095 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_object_cb_mirror_del, cw);
5096 evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, _e_comp_object_cb_mirror_show, cw);
5097 evas_object_event_callback_add(o, EVAS_CALLBACK_HIDE, _e_comp_object_cb_mirror_hide, cw);
5098 evas_object_data_set(o, "E_Client_Mirror", cw->ec);
5099 evas_object_data_set(o, "comp_mirror", cw);
5101 evas_object_image_alpha_set(o, evas_object_image_alpha_get(cw->obj));
5102 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5104 evas_object_image_size_set(o, tw, th);
5107 pix = evas_object_image_data_get(cw->obj, 0);
5113 evas_object_image_native_surface_set(o, cw->ns);
5116 Evas_Native_Surface ns;
5117 memset(&ns, 0, sizeof(Evas_Native_Surface));
5118 if (e_pixmap_native_surface_init(cw->ec->pixmap, &ns))
5119 evas_object_image_native_surface_set(o, &ns);
5124 /* FIXME: legacy code, please refer to commit 5e6831187a1 */
5125 argb = e_pixmap_image_is_argb(cw->ec->pixmap);
5127 (e_pixmap_image_exists(cw->ec->pixmap)))
5128 pix = e_pixmap_image_data_get(cw->ec->pixmap);
5130 pix = evas_object_image_data_get(cw->obj, EINA_FALSE);
5137 dirty = evas_object_image_pixels_dirty_get(cw->obj);
5138 evas_object_image_pixels_dirty_set(o, dirty);
5139 evas_object_image_data_set(o, pix);
5140 evas_object_image_data_set(cw->obj, pix);
5142 evas_object_image_data_update_add(o, 0, 0, tw, th);
5147 //////////////////////////////////////////////////////
5150 e_comp_object_effect_allowed_get(Evas_Object *obj)
5152 API_ENTRY EINA_FALSE;
5154 if (!cw->shobj) return EINA_FALSE;
5155 if (cw->ec->override) return !e_comp_config_get()->match.disable_overrides;
5156 return !e_comp_config_get()->match.disable_borders;
5159 /* setup an api effect for a client */
5161 e_comp_object_effect_set(Evas_Object *obj, const char *effect)
5164 Eina_Stringshare *grp;
5165 E_Comp_Config *config;
5166 Eina_Bool loaded = EINA_FALSE;
5168 API_ENTRY EINA_FALSE;
5169 if (!cw->shobj) return EINA_FALSE; //input window
5171 if (!effect) effect = "none";
5172 snprintf(buf, sizeof(buf), "e/comp/effects/%s", effect);
5174 config = e_comp_config_get();
5175 if ((config) && (config->effect_file))
5177 if (edje_object_file_set(cw->effect_obj, config->effect_file, buf))
5179 cw->effect_set = EINA_TRUE;
5186 edje_object_file_get(cw->effect_obj, NULL, &grp);
5187 cw->effect_set = !eina_streq(effect, "none");
5188 if (!e_util_strcmp(buf, grp)) return cw->effect_set;
5189 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5191 snprintf(buf, sizeof(buf), "e/comp/effects/auto/%s", effect);
5192 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", buf))
5193 if (!e_theme_edje_object_set(cw->effect_obj, "base/theme/comp", "e/comp/effects/none"))
5195 if (cw->effect_running)
5197 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5200 cw->effect_set = EINA_FALSE;
5201 return cw->effect_set;
5205 if (cw->effect_running)
5207 if (!e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb")))
5210 ELOGF("COMP", "EFFECT Set GROUP[%s]", cw->ec, buf);
5211 edje_object_part_swallow(cw->effect_obj, "e.swallow.content", cw->shobj);
5212 if (cw->effect_clip)
5214 evas_object_clip_unset(cw->clip);
5215 cw->effect_clip = 0;
5217 cw->effect_clip_able = !edje_object_data_get(cw->effect_obj, "noclip");
5219 _e_comp_object_dim_update(cw);
5221 return cw->effect_set;
5224 /* set params for embryo scripts in effect */
5226 e_comp_object_effect_params_set(Evas_Object *obj, int id, int *params, unsigned int count)
5228 Edje_Message_Int_Set *msg;
5232 EINA_SAFETY_ON_NULL_RETURN(params);
5233 EINA_SAFETY_ON_FALSE_RETURN(count);
5234 if (!cw->effect_set) return;
5236 msg = alloca(sizeof(Edje_Message_Int_Set) + ((count - 1) * sizeof(int)));
5237 msg->count = (int)count;
5238 for (x = 0; x < count; x++)
5239 msg->val[x] = params[x];
5240 edje_object_message_send(cw->effect_obj, EDJE_MESSAGE_INT_SET, id, msg);
5241 edje_object_message_signal_process(cw->effect_obj);
5245 _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
5247 Edje_Signal_Cb end_cb;
5249 E_Comp_Object *cw = data;
5251 edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
5252 cw->effect_running = 0;
5253 if (!_e_comp_object_animating_end(cw)) return;
5255 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5257 evas_object_data_del(cw->smart_obj, "effect_running");
5258 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_END);
5259 e_comp_visibility_calculation_set(EINA_TRUE);
5262 end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
5263 if (!end_cb) return;
5264 end_data = evas_object_data_get(obj, "_e_comp.end_data");
5265 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5266 end_cb(end_data, cw->smart_obj, emission, source);
5269 /* clip effect to client's zone */
5271 e_comp_object_effect_clip(Evas_Object *obj)
5275 zone = e_comp_zone_find_by_ec(cw->ec);
5277 if (cw->effect_clip) e_comp_object_effect_unclip(cw->smart_obj);
5278 if (!cw->effect_clip_able) return;
5279 evas_object_clip_set(cw->smart_obj, zone->bg_clip_object);
5280 cw->effect_clip = 1;
5283 /* unclip effect from client's zone */
5285 e_comp_object_effect_unclip(Evas_Object *obj)
5288 if (!cw->effect_clip) return;
5289 evas_object_clip_unset(cw->smart_obj);
5290 cw->effect_clip = 0;
5293 /* start effect, running end_cb after */
5295 e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *end_data)
5297 API_ENTRY EINA_FALSE;
5298 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE); //NYI
5299 if (!cw->effect_set) return EINA_FALSE;
5301 if (cw->effect_running)
5303 e_comp_object_effect_stop(obj, evas_object_data_get(cw->effect_obj, "_e_comp.end_cb"));
5306 e_comp_object_effect_clip(obj);
5307 edje_object_signal_callback_del(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb);
5309 edje_object_signal_callback_add(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5310 evas_object_data_set(cw->effect_obj, "_e_comp.end_cb", end_cb);
5311 evas_object_data_set(cw->effect_obj, "_e_comp.end_data", end_data);
5312 evas_object_data_set(cw->smart_obj, "effect_running", (void*)1);
5314 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_START, cw->ec);
5315 _e_comp_object_event_simple(obj, E_EVENT_COMP_OBJECT_EFFECT_START);
5317 edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
5318 _e_comp_object_animating_begin(cw);
5319 cw->effect_running = 1;
5323 /* stop a currently-running effect immediately */
5325 e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
5328 Edje_Signal_Cb end_cb_before = NULL;
5329 void *end_data_before = NULL;
5330 API_ENTRY EINA_FALSE;
5332 end_cb_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_cb");
5333 end_data_before = evas_object_data_get(cw->effect_obj, "_e_comp.end_data");
5335 if (end_cb_before != end_cb) return EINA_TRUE;
5336 e_comp_object_effect_unclip(obj);
5337 if (cw->effect_clip)
5339 evas_object_clip_unset(cw->effect_obj);
5340 cw->effect_clip = 0;
5342 edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
5343 edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
5345 if (evas_object_data_get(cw->smart_obj, "effect_running"))
5347 evas_object_data_del(cw->smart_obj, "effect_running");
5348 e_comp_visibility_calculation_set(EINA_TRUE);
5351 cw->effect_running = 0;
5352 ret = _e_comp_object_animating_end(cw);
5354 if ((ret) && (end_cb_before))
5356 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_EFFECT_END, cw->ec);
5357 end_cb_before(end_data_before, cw->smart_obj, "e,action,done", "e");
5364 _e_comp_object_effect_mover_sort_cb(E_Comp_Object_Mover *a, E_Comp_Object_Mover *b)
5366 return a->pri - b->pri;
5369 /* add a function to trigger based on signal emissions for the purpose of modifying effects */
5370 E_API E_Comp_Object_Mover *
5371 e_comp_object_effect_mover_add(int pri, const char *sig, E_Comp_Object_Mover_Cb provider, const void *data)
5373 E_Comp_Object_Mover *prov;
5375 prov = E_NEW(E_Comp_Object_Mover, 1);
5376 EINA_SAFETY_ON_NULL_RETURN_VAL(prov, NULL);
5377 prov->func = provider;
5378 prov->data = (void*)data;
5381 _e_comp_object_movers = eina_inlist_sorted_insert(_e_comp_object_movers, EINA_INLIST_GET(prov),
5382 (Eina_Compare_Cb)_e_comp_object_effect_mover_sort_cb);
5387 e_comp_object_effect_mover_del(E_Comp_Object_Mover *prov)
5389 EINA_SAFETY_ON_NULL_RETURN(prov);
5390 _e_comp_object_movers = eina_inlist_remove(_e_comp_object_movers, EINA_INLIST_GET(prov));
5395 e_comp_object_effect_object_get(Evas_Object *obj)
5399 return cw->effect_obj;
5403 e_comp_object_effect_hiding_set(Evas_Object *obj, Eina_Bool set)
5405 API_ENTRY EINA_FALSE;
5406 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5407 if (!cw->effect_set) return EINA_FALSE;
5414 ////////////////////////////////////
5417 _e_comp_object_autoclose_cleanup(Eina_Bool already_del)
5419 if (e_comp->autoclose.obj)
5421 e_comp_ungrab_input(0, 1);
5422 if (e_comp->autoclose.del_cb)
5423 e_comp->autoclose.del_cb(e_comp->autoclose.data, e_comp->autoclose.obj);
5424 else if (!already_del)
5426 evas_object_hide(e_comp->autoclose.obj);
5427 E_FREE_FUNC(e_comp->autoclose.obj, evas_object_del);
5429 E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
5431 e_comp->autoclose.obj = NULL;
5432 e_comp->autoclose.data = NULL;
5433 e_comp->autoclose.del_cb = NULL;
5434 e_comp->autoclose.key_cb = NULL;
5435 E_FREE_FUNC(e_comp->autoclose.key_handler, ecore_event_handler_del);
5439 _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)
5441 _e_comp_object_autoclose_cleanup(0);
5445 _e_comp_object_autoclose_setup(Evas_Object *obj)
5447 if (!e_comp->autoclose.rect)
5449 /* create rect just below autoclose object to catch mouse events */
5450 e_comp->autoclose.rect = evas_object_rectangle_add(e_comp->evas);
5451 evas_object_move(e_comp->autoclose.rect, 0, 0);
5452 evas_object_resize(e_comp->autoclose.rect, e_comp->w, e_comp->h);
5453 evas_object_show(e_comp->autoclose.rect);
5454 evas_object_name_set(e_comp->autoclose.rect, "e_comp->autoclose.rect");
5455 evas_object_color_set(e_comp->autoclose.rect, 0, 0, 0, 0);
5456 evas_object_event_callback_add(e_comp->autoclose.rect, EVAS_CALLBACK_MOUSE_UP, _e_comp_object_autoclose_mouse_up_cb, e_comp);
5457 e_comp_grab_input(0, 1);
5459 evas_object_layer_set(e_comp->autoclose.rect, evas_object_layer_get(obj) - 1);
5460 evas_object_focus_set(obj, 1);
5464 _e_comp_object_autoclose_show(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5466 _e_comp_object_autoclose_setup(obj);
5467 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5471 _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
5473 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show);
5474 _e_comp_object_autoclose_cleanup(1);
5475 if (e_client_focused_get()) return;
5477 E_Zone *zone = e_zone_current_get();
5480 e_zone_focus_reset(zone);
5484 e_comp_object_util_autoclose(Evas_Object *obj, E_Comp_Object_Autoclose_Cb del_cb, E_Comp_Object_Key_Cb cb, const void *data)
5488 if (e_comp->autoclose.obj)
5490 if (e_comp->autoclose.obj == obj) return;
5491 evas_object_event_callback_del_full(e_comp->autoclose.obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5492 e_comp->autoclose.obj = obj;
5493 e_comp->autoclose.del_cb = del_cb;
5494 e_comp->autoclose.key_cb = cb;
5495 e_comp->autoclose.data = (void*)data;
5496 if (evas_object_visible_get(obj))
5497 _e_comp_object_autoclose_setup(obj);
5499 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5500 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5503 e_comp->autoclose.obj = obj;
5504 e_comp->autoclose.del_cb = del_cb;
5505 e_comp->autoclose.key_cb = cb;
5506 e_comp->autoclose.data = (void*)data;
5507 if (evas_object_visible_get(obj))
5508 _e_comp_object_autoclose_setup(obj);
5510 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _e_comp_object_autoclose_show, e_comp);
5511 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_comp_object_autoclose_del, e_comp);
5515 e_comp_object_is_animating(Evas_Object *obj)
5519 return cw->animating;
5523 e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
5527 if ((cw->external_content) &&
5528 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5530 WRN("Can set up alpha value to ONLY evas \"image\" object. "
5531 "But current external content is %d object for %p.",
5532 cw->content_type, cw->ec);
5536 cw->user_alpha_set = EINA_TRUE;
5537 cw->user_alpha = alpha;
5539 if (!cw->obj) return;
5541 if (alpha == evas_object_image_alpha_get(cw->obj)) return;
5543 evas_object_image_alpha_set(cw->obj, alpha);
5545 if ((!cw->native) && (!cw->external_content))
5546 evas_object_image_data_set(cw->obj, NULL);
5550 e_comp_object_alpha_get(Evas_Object *obj)
5552 API_ENTRY EINA_FALSE;
5554 return evas_object_image_alpha_get(cw->obj);
5558 e_comp_object_mask_set(Evas_Object *obj, Eina_Bool set)
5560 Eina_Bool mask_set = EINA_FALSE;
5564 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5565 if (cw->ec->input_only) return;
5572 o = evas_object_rectangle_add(e_comp->evas);
5573 evas_object_color_set(o, 0, 0, 0, 0);
5574 evas_object_clip_set(o, cw->clip);
5575 evas_object_smart_member_add(o, obj);
5576 evas_object_move(o, 0, 0);
5577 evas_object_resize(o, cw->w, cw->h);
5578 /* save render op value to restore when clear a mask.
5580 * NOTE: DO NOT change the render op on ec->frame while mask object
5581 * is set. it will overwrite the changed op value. */
5582 cw->mask.saved_render_op = evas_object_render_op_get(obj);
5583 evas_object_render_op_set(obj, EVAS_RENDER_COPY);
5584 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5585 if (cw->visible) evas_object_show(o);
5588 evas_object_name_set(cw->mask.obj, "cw->mask_obj");
5589 ELOGF("COMP", " |mask_obj", cw->ec);
5590 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_SET, cw->ec);
5597 evas_object_smart_member_del(cw->mask.obj);
5598 E_FREE_FUNC(cw->mask.obj, evas_object_del);
5600 evas_object_render_op_set(obj, cw->mask.saved_render_op);
5601 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_MASK_OBJECT_UNSET, cw->ec);
5607 e_comp_object_mask_has(Evas_Object *obj)
5609 API_ENTRY EINA_FALSE;
5611 return (cw->mask.obj) ? EINA_TRUE : EINA_FALSE;
5615 e_comp_object_size_update(Evas_Object *obj, int w, int h)
5620 if ((cw->external_content) &&
5621 (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
5623 WRN("Can set up size to ONLY evas \"image\" object. "
5624 "But current external content is %d object for %p.",
5625 cw->content_type, cw->ec);
5629 _e_comp_object_map_transform_rect(cw->ec, 0, 0, w, h, NULL, NULL, &tw, &th);
5631 evas_object_image_size_set(cw->obj, tw, th);
5635 e_comp_object_transform_bg_set(Evas_Object *obj, Eina_Bool set)
5637 Eina_Bool transform_set = EINA_FALSE;
5639 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5640 if (cw->ec->input_only) return;
5642 transform_set = !!set;
5646 if (!cw->transform_bg_obj)
5648 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5649 evas_object_move(o, 0, 0);
5650 evas_object_resize(o, 1, 1);
5651 if (cw->transform_bg_color.a >= 255)
5652 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5654 evas_object_render_op_set(o, EVAS_RENDER_BLEND);
5655 evas_object_color_set(o,
5656 cw->transform_bg_color.r,
5657 cw->transform_bg_color.g,
5658 cw->transform_bg_color.b,
5659 cw->transform_bg_color.a);
5660 if (cw->visible) evas_object_show(o);
5662 cw->transform_bg_obj = o;
5663 evas_object_name_set(cw->transform_bg_obj, "cw->transform_bg_obj");
5665 #ifdef REFACTOR_DESK_AREA
5666 e_comp_object_transform_obj_stack_update(obj);
5668 _e_comp_object_transform_obj_stack_update(obj);
5673 if (cw->transform_bg_obj)
5675 evas_object_smart_member_del(cw->transform_bg_obj);
5676 E_FREE_FUNC(cw->transform_bg_obj, evas_object_del);
5682 e_comp_object_transform_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
5686 cw->transform_bg_color.r = r;
5687 cw->transform_bg_color.g = g;
5688 cw->transform_bg_color.b = b;
5689 cw->transform_bg_color.a = a;
5691 if (cw->transform_bg_obj)
5693 evas_object_color_set(cw->transform_bg_obj,
5694 cw->transform_bg_color.r,
5695 cw->transform_bg_color.g,
5696 cw->transform_bg_color.b,
5697 cw->transform_bg_color.a);
5702 e_comp_object_transform_bg_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5705 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5706 if (cw->ec->input_only) return;
5707 if (!cw->transform_bg_obj) return;
5709 _e_comp_object_transform_obj_map_set(cw->transform_bg_obj, vertices);
5713 e_comp_object_transform_bg_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5716 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5717 if (cw->ec->input_only) return;
5718 if (!cw->transform_bg_obj) return;
5720 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_bg_obj, vertices, zoom);
5724 e_comp_object_transform_transp_set(Evas_Object *obj, Eina_Bool set)
5726 Eina_Bool transform_set = EINA_FALSE;
5728 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5729 if (cw->ec->input_only) return;
5731 transform_set = !!set;
5735 if (!cw->transform_tranp_obj)
5737 Evas_Object *o = evas_object_rectangle_add(e_comp->evas);
5738 evas_object_move(o, 0, 0);
5739 evas_object_resize(o, 1, 1);
5740 evas_object_render_op_set(o, EVAS_RENDER_COPY);
5741 evas_object_color_set(o, 0, 0, 0, 0);
5742 if (cw->visible) evas_object_show(o);
5744 cw->transform_tranp_obj = o;
5745 evas_object_pass_events_set(cw->transform_tranp_obj, EINA_TRUE);
5746 ELOGF("TRANSFORM","transform set: TRUE", cw->ec);
5747 evas_object_name_set(cw->transform_tranp_obj, "cw->transform_trasp_obj");
5749 #ifdef REFACTOR_DESK_AREA
5750 e_comp_object_transform_obj_stack_update(obj);
5752 _e_comp_object_transform_obj_stack_update(obj);
5757 if (cw->transform_tranp_obj)
5759 ELOGF("TRANSFORM","transform set: FALSE", cw->ec);
5760 evas_object_smart_member_del(cw->transform_tranp_obj);
5761 E_FREE_FUNC(cw->transform_tranp_obj, evas_object_del);
5767 e_comp_object_transform_transp_vertices_set(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices)
5770 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5771 if (cw->ec->input_only) return;
5772 if (!cw->transform_tranp_obj) return;
5774 _e_comp_object_transform_obj_map_set(cw->transform_tranp_obj, vertices);
5778 e_comp_object_transform_transp_vertices_set_with_zoom(Evas_Object *obj, E_Util_Transform_Rect_Vertex *vertices, E_Util_Transform_Zoom zoom)
5781 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
5782 if (cw->ec->input_only) return;
5783 if (!cw->transform_tranp_obj) return;
5785 _e_comp_object_transform_obj_map_set_with_zoom(cw->transform_tranp_obj, vertices, zoom);
5788 #ifdef REFACTOR_DESK_AREA
5791 e_comp_object_layer_update(Evas_Object *obj,
5792 Evas_Object *above, Evas_Object *below)
5794 E_Comp_Object *cw2 = NULL;
5795 Evas_Object *o = NULL;
5800 if (cw->ec->layer_block) return;
5801 if ((above) && (below))
5803 ERR("Invalid layer update request! cw=%p", cw);
5811 layer = evas_object_layer_get(o);
5812 cw2 = evas_object_data_get(o, "comp_obj");
5815 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
5817 o = evas_object_above_get(o);
5818 if ((!o) || (o == cw->smart_obj)) break;
5819 if (evas_object_layer_get(o) != layer)
5821 o = e_comp->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
5826 ec = e_client_top_get();
5827 if (ec) o = ec->frame;
5830 if (o) cw2 = evas_object_data_get(o, "comp_obj");
5834 _e_comp_object_layers_remove(cw);
5837 if (cw2->layer > cw->layer)
5838 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5839 else if (cw2->layer == cw->layer)
5842 _e_comp_object_layers_add(cw, cw2, NULL, 0);
5844 _e_comp_object_layers_add(cw, NULL, NULL, above? 0 : 1);
5846 _e_comp_object_layers_add(cw, NULL, cw2, 0);
5849 _e_comp_object_layers_add(cw, NULL, NULL, 1);
5852 _e_comp_object_layers_add(cw, NULL, NULL, 0);
5857 e_comp_object_layer_get(Evas_Object *obj)
5864 e_comp_object_content_set(Evas_Object *obj,
5865 Evas_Object *content,
5866 E_Comp_Object_Content_Type type)
5868 API_ENTRY EINA_FALSE;
5870 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5871 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5872 EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5876 ERR("Can't set e.swallow.content to requested content. "
5877 "Previous comp object should not be changed at all.");
5881 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_FALSE;
5883 if ((type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE) &&
5884 (type != E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE))
5886 ERR("Content type %d for %p is not supported ec:%p pixmap:%p",
5887 type, content, cw->ec, cw->ec->pixmap);
5891 cw->external_content = EINA_TRUE;
5894 cw->content_type = type;
5895 e_util_size_debug_set(cw->obj, 1);
5896 evas_object_name_set(cw->obj, "cw->obj");
5897 _e_comp_object_alpha_set(cw);
5900 _e_comp_object_shadow_setup(cw);
5902 wl_signal_emit_mutable(&cw->events.content_type_set, NULL);
5908 e_comp_object_content_unset(Evas_Object *obj)
5910 API_ENTRY EINA_FALSE;
5912 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
5913 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec->pixmap, EINA_FALSE);
5915 if (!cw->obj && !cw->ec->visible)
5917 ELOGF("COMP", "is not visible yet. no need to unset", cw->ec);
5921 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5923 ELOGF("COMP", "has been set to internal image object already", cw->ec);
5929 if (cw->frame_object)
5930 edje_object_part_unswallow(cw->frame_object, cw->obj);
5932 edje_object_part_unswallow(cw->shobj, cw->obj);
5934 evas_object_del(cw->obj);
5935 evas_object_hide(cw->obj);
5939 cw->external_content = EINA_FALSE;
5940 if (cw->ec->is_cursor)
5943 DBG("%p is cursor surface..", cw->ec);
5944 if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))
5946 evas_object_resize(cw->ec->frame, pw, ph);
5947 evas_object_hide(cw->ec->frame);
5952 cw->content_type = E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE;
5953 cw->obj = evas_object_image_filled_add(e_comp->evas);
5954 evas_object_image_border_center_fill_set(cw->obj, EVAS_BORDER_FILL_SOLID);
5955 e_util_size_debug_set(cw->obj, 1);
5956 evas_object_image_pixels_get_callback_set(cw->obj, _e_comp_object_pixels_get, cw);
5957 evas_object_image_pixels_noti_callback_set(cw->obj, _e_comp_object_pixels_noti, cw);
5958 evas_object_image_smooth_scale_set(cw->obj, e_comp_config_get()->smooth_windows);
5959 evas_object_name_set(cw->obj, "cw->obj");
5960 evas_object_image_colorspace_set(cw->obj, EVAS_COLORSPACE_ARGB8888);
5961 evas_object_intercept_color_set_callback_add(obj, _e_comp_intercept_obj_color_set, cw);
5962 _e_comp_object_alpha_set(cw);
5965 _e_comp_object_shadow_setup(cw);
5970 _e_comp_intercept_show_helper(cw);
5974 e_comp_object_damage(cw->smart_obj, 0, 0, cw->w, cw->h);
5975 e_comp_object_dirty(cw->smart_obj);
5976 e_comp_object_render(cw->smart_obj);
5977 e_comp_object_render_update_add(obj);
5979 wl_signal_emit_mutable(&cw->events.content_type_set, NULL);
5984 EINTERN Evas_Object *
5985 e_comp_object_content_get(Evas_Object *obj)
5989 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, NULL);
5991 if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
5993 ELOGF("COMP", "has been set to internal image object. couldn't return internal image object", cw->ec);
6000 E_API E_Comp_Object_Content_Type
6001 e_comp_object_content_type_get(Evas_Object *obj)
6003 API_ENTRY E_COMP_OBJECT_CONTENT_TYPE_NONE;
6005 return cw->content_type;
6009 e_comp_object_dim_mask_update(Evas_Object *obj, Eina_Bool mask_set, int x, int y, int w, int h)
6012 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6013 E_Comp_Config *conf = e_comp_config_get();
6014 if (cw->ec->input_only) return;
6015 if (!conf->dim_rect_enable) return;
6017 cw->dim.mask_set = mask_set;
6023 if (!cw->dim.enable) return;
6024 e_comp_object_dim_mask_set(cw->ec->frame, mask_set);
6028 e_comp_object_dim_mask_set(Evas_Object *obj, Eina_Bool set)
6030 Eina_Bool mask_set = EINA_FALSE;
6034 EINA_SAFETY_ON_NULL_RETURN(cw->ec);
6035 E_Comp_Config *conf = e_comp_config_get();
6036 if (cw->ec->input_only) return;
6037 if (!conf->dim_rect_enable) return;
6043 if (cw->dim.mask_obj)
6045 evas_object_smart_member_del(cw->dim.mask_obj);
6046 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6049 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);
6050 o = evas_object_rectangle_add(e_comp->evas);
6051 evas_object_color_set(o, 0, 0, 0, 0);
6052 evas_object_smart_member_add(o, obj);
6053 evas_object_resize(o, cw->dim.mask_w, cw->dim.mask_h);
6054 evas_object_move(o, cw->dim.mask_x, cw->dim.mask_y);
6056 evas_object_render_op_set(o, EVAS_RENDER_COPY);
6057 if (cw->visible) evas_object_show(o);
6059 cw->dim.mask_obj = o;
6060 evas_object_name_set(cw->dim.mask_obj, "cw->dim_mask_obj");
6062 evas_object_layer_set(cw->dim.mask_obj, 9998);
6066 if (cw->dim.mask_obj)
6068 ELOGF("COMP", "DIM |Mask on Dim rect Removed", cw->ec);
6069 evas_object_smart_member_del(cw->dim.mask_obj);
6070 E_FREE_FUNC(cw->dim.mask_obj, evas_object_del);
6076 e_comp_object_dim_client_set(E_Client *ec)
6078 E_Comp_Config *conf = e_comp_config_get();
6080 if (!conf->dim_rect_enable) return ;
6081 if (dim_client == ec) return;
6083 Eina_Bool prev_dim = EINA_FALSE;
6084 ELOGF("COMP", "DIM |Client Set %p -> %p", ec, dim_client, ec);
6086 if (dim_client && _e_comp_object_dim_enable_get(dim_client, dim_client->frame))
6087 prev_dim = EINA_TRUE;
6089 if (prev_dim && dim_client->visible && ec)
6091 _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_TRUE);
6092 _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_TRUE);
6096 if (prev_dim) _e_comp_object_dim_enable_set(dim_client, dim_client->frame, EINA_FALSE, EINA_FALSE);
6097 if (ec) _e_comp_object_dim_enable_set(ec, ec->frame, EINA_TRUE, EINA_FALSE);
6103 e_comp_object_dim_client_get(void)
6105 E_Comp_Config *conf = e_comp_config_get();
6107 if (!conf->dim_rect_enable ) return NULL;
6113 _e_comp_object_dim_enable_set(E_Client *ec, Evas_Object *obj, Eina_Bool enable, Eina_Bool noeffect)
6116 char emit[32] = "\0";
6117 E_Comp_Config *conf = e_comp_config_get();
6120 if (!conf->dim_rect_enable) return;
6121 if (!cw->effect_obj) return;
6122 if (enable == cw->dim.enable) return;
6124 ELOGF("COMP", "DIM |set on Client [%d]", ec, enable);
6125 if (noeffect || !conf->dim_rect_effect)
6127 strncpy(emit, (enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), sizeof(emit) - 1);
6131 strncpy(emit, (enable ? "e,state,dim,on" : "e,state,dim,off"), sizeof(emit) - 1);
6134 cw->dim.enable = enable;
6136 if (cw->dim.mask_set && !enable)
6138 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6139 edje_object_signal_emit(cw->effect_obj, emit, "e");
6141 else if (cw->dim.mask_set && enable)
6143 edje_object_signal_emit(cw->effect_obj, emit, "e");
6144 e_comp_object_dim_mask_set(cw->ec->frame, enable);
6148 edje_object_signal_emit(cw->effect_obj, emit, "e");
6153 _e_comp_object_dim_enable_get(E_Client *ec, Evas_Object *obj)
6155 API_ENTRY EINA_FALSE;
6156 E_Comp_Config *conf = e_comp_config_get();
6158 if (!ec) return EINA_FALSE;
6159 if (!conf->dim_rect_enable) return EINA_FALSE;
6161 if (cw->dim.enable) return EINA_TRUE;
6167 _e_comp_object_dim_update(E_Comp_Object *cw)
6169 E_Comp_Config *conf = e_comp_config_get();
6172 if (!conf->dim_rect_enable) return;
6173 if (!cw->effect_obj) return;
6176 edje_object_signal_emit(cw->effect_obj, (cw->dim.enable ? "e,state,dim,on,noeffect" : "e,state,dim,off,noeffect"), "e");
6177 ELOGF("COMP", "DIM |Applied on Client dim.enable[%d]", cw->ec, cw->dim.enable);
6179 if (cw->dim.mask_set)
6181 e_comp_object_dim_mask_set(cw->ec->frame, cw->dim.mask_set);
6187 e_comp_object_clear(Evas_Object *obj)
6191 _e_comp_object_clear(cw);
6195 e_comp_object_hwc_update_exists(Evas_Object *obj)
6197 API_ENTRY EINA_FALSE;
6198 return cw->hwc_need_update;
6203 e_comp_object_hwc_update_set(Evas_Object *obj, Eina_Bool set)
6206 cw->hwc_need_update = set;
6210 e_comp_object_effect_object_part_swallow(Evas_Object *obj, const char *part_name, Evas_Object *swallow_obj)
6212 API_ENTRY EINA_FALSE;
6213 return edje_object_part_swallow(cw->effect_obj, part_name, swallow_obj);
6217 e_comp_object_indicator_swallow(Evas_Object *obj, Evas_Object *indicator)
6220 if (cw->indicator.obj != indicator)
6221 edje_object_part_unswallow(cw->shobj, cw->indicator.obj);
6222 cw->indicator.obj = indicator;
6223 edje_object_part_swallow(cw->shobj, "e.swallow.indicator", indicator);
6227 e_comp_object_indicator_unswallow(Evas_Object *obj, Evas_Object *indicator)
6230 if (cw->indicator.obj != indicator) return;
6231 cw->indicator.obj = NULL;
6232 edje_object_part_unswallow(cw->shobj, indicator);
6236 e_comp_object_indicator_size_set(Evas_Object *obj, int w, int h)
6239 Edje_Message_Int_Set *msg;
6241 if (!cw->indicator.obj) return;
6243 cw->indicator.w = w;
6244 cw->indicator.h = h;
6246 if (!cw->shobj) return;
6248 msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
6252 edje_object_message_send(cw->shobj, EDJE_MESSAGE_INT_SET, 0, msg);
6253 edje_object_message_signal_process(cw->shobj);
6256 /* buffer transform and scale are applied to e_comp_object and e_pixmap internaly */
6258 e_comp_object_map_update(Evas_Object *obj)
6261 E_Client *ec = cw->ec;
6262 E_Comp_Wl_Client_Data *cdata;
6264 int x1, y1, x2, y2, x, y, bw, bh, tw, th;
6267 int l, remain = sizeof buffer;
6270 if (e_object_is_del(E_OBJECT(ec))) return;
6271 cdata = e_client_cdata_get(ec);
6274 /* if buffer had been flushed, buffer could be NULL. Then map will be applied
6275 * when new buffer is attached.
6277 if (!cdata->buffer_ref.buffer) return;
6279 if ((!cw->redirected) ||
6280 (e_client_video_hw_composition_check(ec)) ||
6281 (!e_comp_wl_output_buffer_transform_get(ec) &&
6282 cdata->scaler.buffer_viewport.buffer.scale == 1))
6284 if (evas_object_map_enable_get(cw->effect_obj))
6286 ELOGF("TRANSFORM", "map: disable", cw->ec);
6287 evas_object_map_enable_set(cw->effect_obj, EINA_FALSE);
6288 _e_comp_object_map_transform_rect(cw->ec, 0, 0, cw->w, cw->h, NULL, NULL, &tw, &th);
6289 evas_object_resize(cw->effect_obj, tw, th);
6296 EINA_SAFETY_ON_NULL_RETURN(map);
6298 e_pixmap_size_get(ec->pixmap, &bw, &bh);
6304 e_map_util_points_populate_from_geometry(map, ec->x, ec->y, bw, bh, 0);
6306 _e_comp_object_map_transform_pos(ec, x1, y1, &x, &y);
6307 e_map_point_image_uv_set(map, 0, x, y);
6308 l = snprintf(p, remain, "%d,%d", x, y);
6309 p += l, remain -= l;
6311 _e_comp_object_map_transform_pos(ec, x2, y1, &x, &y);
6312 e_map_point_image_uv_set(map, 1, x, y);
6313 l = snprintf(p, remain, " %d,%d", x, y);
6314 p += l, remain -= l;
6316 _e_comp_object_map_transform_pos(ec, x2, y2, &x, &y);
6317 e_map_point_image_uv_set(map, 2, x, y);
6318 l = snprintf(p, remain, " %d,%d", x, y);
6319 p += l, remain -= l;
6321 _e_comp_object_map_transform_pos(ec, x1, y2, &x, &y);
6322 e_map_point_image_uv_set(map, 3, x, y);
6323 l = snprintf(p, remain, " %d,%d", x, y);
6324 p += l, remain -= l;
6326 ELOGF("TRANSFORM", "map: point(%d,%d %dx%d) uv(%d,%d %d,%d %d,%d %d,%d=>%s)",
6328 ec->x, ec->y, bw, bh, x1, y1, x2, y1, x2, y2, x1, y2, buffer);
6330 e_comp_object_map_set(cw->effect_obj, map);
6331 e_comp_object_map_enable_set(cw->effect_obj, EINA_TRUE);
6335 /* if there's screen rotation with comp mode, then ec->effect_obj and
6336 * ec->obj should rotate. if not, in evas_map, update region is clipped.
6338 _e_comp_object_map_transform_rect(cw->ec, 0, 0, bw, bh, NULL, NULL, &tw, &th);
6339 evas_object_resize(cw->effect_obj, tw, th);
6343 e_comp_object_render_trace_set(Evas_Object *obj, Eina_Bool set)
6345 API_ENTRY EINA_FALSE;
6347 cw->render_trace = set;
6353 e_comp_object_native_usable_get(Evas_Object *obj)
6355 API_ENTRY EINA_FALSE;
6356 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6358 if (cw->ec->input_only) return EINA_FALSE;
6359 if (cw->external_content) return EINA_FALSE;
6360 if (e_comp_object_content_type_get(cw->ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) return EINA_FALSE;
6362 /* just return true value, if it is normal case */
6363 if (e_pixmap_usable_get(cw->ec->pixmap)) return EINA_TRUE;
6366 Evas_Native_Surface *ns;
6367 ns = evas_object_image_native_surface_get(cw->obj);
6369 /* client pixmap is not usable but cw->obj is drawable due to it holds valid native surface*/
6372 ELOGF("COMP", "Client pixmap is Not usable but still holds valid native surface", cw->ec);
6380 e_comp_object_image_filter_set(Evas_Object *obj, E_Comp_Image_Filter filter)
6382 API_ENTRY EINA_FALSE;
6383 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6384 if (e_object_is_del(E_OBJECT(cw->ec))) return EINA_FALSE;
6385 if (!e_client_cdata_get(cw->ec)) return EINA_FALSE;
6387 if (cw->image_filter == filter) return EINA_TRUE;
6391 case E_COMP_IMAGE_FILTER_BLUR:
6392 efl_gfx_filter_program_set(cw->obj, "blur (20) padding_set (0)", "image_filter");
6394 case E_COMP_IMAGE_FILTER_GRAYSCALE:
6395 efl_gfx_filter_program_set(cw->obj, "grayscale ()", "image_filter");
6397 case E_COMP_IMAGE_FILTER_INVERSE:
6398 efl_gfx_filter_program_set(cw->obj, "inverse_color ()", "image_filter");
6400 case E_COMP_IMAGE_FILTER_NONE:
6402 efl_gfx_filter_program_set(cw->obj, NULL, "image_filter");
6406 cw->image_filter = filter;
6408 wl_signal_emit_mutable(&cw->events.image_filter_set, NULL);
6413 EINTERN E_Comp_Image_Filter
6414 e_comp_object_image_filter_get(Evas_Object *obj)
6416 API_ENTRY E_COMP_IMAGE_FILTER_NONE;
6417 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, E_COMP_IMAGE_FILTER_NONE);
6418 if (e_object_is_del(E_OBJECT(cw->ec))) return E_COMP_IMAGE_FILTER_NONE;
6419 if (!e_client_cdata_get(cw->ec)) return E_COMP_IMAGE_FILTER_NONE;
6421 return cw->image_filter;
6425 _e_comp_object_damage_trace_render_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6429 if (!_damage_trace) return;
6431 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6432 evas_object_del(obj);
6434 _damage_trace_post_objs = NULL;
6438 _e_comp_object_damage_trace_render_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
6440 if (!_damage_trace) return;
6442 _damage_trace_post_objs = _damage_trace_objs;
6443 _damage_trace_objs = NULL;
6447 e_comp_object_damage_trace_debug(Eina_Bool onoff)
6449 if (_damage_trace == onoff) return;
6453 evas_event_callback_add(e_comp->evas,
6454 EVAS_CALLBACK_RENDER_PRE,
6455 _e_comp_object_damage_trace_render_pre_cb,
6458 evas_event_callback_add(e_comp->evas,
6459 EVAS_CALLBACK_RENDER_POST,
6460 _e_comp_object_damage_trace_render_post_cb,
6467 EINA_LIST_FREE(_damage_trace_objs, obj)
6468 evas_object_del(obj);
6470 _damage_trace_objs = NULL;
6472 EINA_LIST_FREE(_damage_trace_post_objs, obj)
6473 evas_object_del(obj);
6475 _damage_trace_post_objs = NULL;
6477 evas_event_callback_del(e_comp->evas,
6478 EVAS_CALLBACK_RENDER_PRE,
6479 _e_comp_object_damage_trace_render_pre_cb);
6481 evas_event_callback_del(e_comp->evas,
6482 EVAS_CALLBACK_RENDER_POST,
6483 _e_comp_object_damage_trace_render_post_cb);
6486 _damage_trace = onoff;
6490 e_comp_object_redirected_get(Evas_Object *obj)
6492 API_ENTRY EINA_FALSE;
6493 EINA_SAFETY_ON_NULL_RETURN_VAL(cw->ec, EINA_FALSE);
6495 return cw->redirected;
6499 e_comp_object_color_visible_get(Evas_Object *obj)
6501 API_ENTRY EINA_FALSE;
6503 return cw->color_visible;
6507 e_comp_object_map_set(Evas_Object *obj, E_Map *em)
6509 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6511 return e_map_set_to_comp_object(em, obj);
6515 e_comp_object_map_get(const Evas_Object *obj)
6517 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
6519 return e_map_get_from_comp_object(obj);
6523 e_comp_object_map_enable_set(Evas_Object *obj, Eina_Bool enable)
6525 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6527 evas_object_map_enable_set(obj, enable);
6533 e_comp_object_render_update_lock(Evas_Object *obj)
6535 E_Comp_Wl_Buffer *buffer;
6536 struct wayland_tbm_client_queue *cqueue;
6538 API_ENTRY EINA_FALSE;
6540 if (cw->render_update_lock.lock == 0)
6542 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
6544 buffer = e_pixmap_resource_get(cw->ec->pixmap);
6545 if ((buffer) && (buffer->resource))
6547 cqueue = e_comp_wl_tbm_client_queue_get(cw->ec);
6549 wayland_tbm_server_client_queue_flush(cqueue);
6552 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, buffer);
6553 e_comp_object_render_update_del(obj);
6555 ELOGF("COMP", "Render update lock enabled", cw->ec);
6558 cw->render_update_lock.lock++;
6564 e_comp_object_render_update_unlock(Evas_Object *obj)
6568 if (cw->render_update_lock.lock == 0)
6571 cw->render_update_lock.lock--;
6573 if (cw->render_update_lock.lock == 0)
6576 if (cw->render_update_lock.pending_move_set)
6578 evas_object_move(obj,
6579 cw->render_update_lock.pending_move_x,
6580 cw->render_update_lock.pending_move_y);
6581 cw->render_update_lock.pending_move_x = 0;
6582 cw->render_update_lock.pending_move_y = 0;
6583 cw->render_update_lock.pending_move_set = EINA_FALSE;
6586 if (cw->render_update_lock.pending_resize_set)
6588 evas_object_resize(obj,
6589 cw->render_update_lock.pending_resize_w,
6590 cw->render_update_lock.pending_resize_h);
6591 cw->render_update_lock.pending_resize_w = 0;
6592 cw->render_update_lock.pending_resize_h = 0;
6593 cw->render_update_lock.pending_resize_set = EINA_FALSE;
6596 e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
6598 if ((cw->ec->exp_iconify.buffer_flush) &&
6599 (e_policy_visibility_client_is_iconic(cw->ec)) &&
6600 (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
6601 e_comp_object_clear(obj);
6603 e_comp_object_render_update_add(obj);
6605 _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_UNSET, cw->ec);
6607 ELOGF("COMP", "Render update lock disabled", cw->ec);
6612 e_comp_object_render_update_lock_get(Evas_Object *obj)
6614 API_ENTRY EINA_FALSE;
6616 if (cw->render_update_lock.lock > 0)
6623 e_comp_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a)
6627 if ((cw->transparent.set) || (cw->transparent.setting))
6629 if (r) *r = cw->transparent.user_r;
6630 if (g) *g = cw->transparent.user_g;
6631 if (b) *b = cw->transparent.user_b;
6632 if (a) *a = cw->transparent.user_a;
6636 evas_object_color_get(obj, r, g, b, a);
6641 e_comp_object_render_op_set(Evas_Object *obj, Evas_Render_Op op)
6645 evas_object_render_op_set(cw->obj, op);
6647 wl_signal_emit_mutable(&cw->events.render_op_set, NULL);
6650 EINTERN Evas_Render_Op
6651 e_comp_object_render_op_get(Evas_Object *obj)
6653 API_ENTRY EVAS_RENDER_BLEND;
6655 return evas_object_render_op_get(cw->obj);
6659 e_comp_object_lower_listener_add(Evas_Object *obj, struct wl_listener *listener)
6662 wl_signal_add(&cw->events.lower, listener);
6665 #ifdef REFACTOR_DESK_AREA
6667 e_comp_object_lower_done_listener_add(Evas_Object *obj, struct wl_listener *listener)
6670 wl_signal_add(&cw->events.lower_done, listener);
6674 e_comp_object_raise_listener_add(Evas_Object *obj, struct wl_listener *listener)
6677 wl_signal_add(&cw->events.raise, listener);
6682 e_comp_object_show_listener_add(Evas_Object *obj, struct wl_listener *listener)
6685 wl_signal_add(&cw->events.show, listener);
6689 e_comp_object_hide_listener_add(Evas_Object *obj, struct wl_listener *listener)
6692 wl_signal_add(&cw->events.hide, listener);
6695 #ifdef REFACTOR_DESK_AREA
6697 e_comp_object_set_layer_listener_add(Evas_Object *obj, struct wl_listener *listener)
6700 wl_signal_add(&cw->events.set_layer, listener);
6704 e_comp_object_stack_above_listener_add(Evas_Object *obj, struct wl_listener *listener)
6707 wl_signal_add(&cw->events.stack_above, listener);
6711 e_comp_object_stack_below_listener_add(Evas_Object *obj, struct wl_listener *listener)
6714 wl_signal_add(&cw->events.stack_below, listener);
6719 e_comp_object_image_filter_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6722 wl_signal_add(&cw->events.image_filter_set, listener);
6726 e_comp_object_render_op_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6729 wl_signal_add(&cw->events.render_op_set, listener);
6733 e_comp_object_content_type_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6736 wl_signal_add(&cw->events.content_type_set, listener);
6740 e_comp_object_color_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6743 wl_signal_add(&cw->events.color_set, listener);
6747 e_comp_object_color_visible_set_listener_add(Evas_Object *obj, struct wl_listener *listener)
6750 wl_signal_add(&cw->events.color_visible_set, listener);