2 #include "e_client_intern.h"
4 #define PRI(ec) ((E_Client_Private *)e_object_data_get(E_OBJECT(ec)))
7 EINA_SAFETY_ON_NULL_RETURN(ec); \
8 E_Client_Private *priv = PRI(ec)
10 #define API_ENTRY_VAL(ret) \
11 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, ret); \
12 E_Client_Private *priv = PRI(ec)
14 typedef struct _E_Client_Private E_Client_Private;
16 struct _E_Client_Private
20 struct wl_signal eval_pre_fetch;
21 struct wl_signal eval_fetch;
22 struct wl_signal eval_pre_post_fetch;
23 struct wl_signal eval_post_fetch;
24 struct wl_signal eval_pre_frame_assign;
25 struct wl_signal eval_post_frame_assign;
26 struct wl_signal eval_pre_new_client;
27 struct wl_signal eval_post_new_client;
28 struct wl_signal eval_visibility;
29 struct wl_signal eval_visibility_end;
30 struct wl_signal eval_end;
32 struct wl_signal move_begin;
33 struct wl_signal move_update;
34 struct wl_signal move_end;
35 struct wl_signal move_resize_begin;
36 struct wl_signal move_resize_update;
37 struct wl_signal move_resize_end;
39 struct wl_signal destroy;
40 struct wl_signal new_client;
41 struct wl_signal new_client_post;
43 struct wl_signal unredirect;
44 struct wl_signal redirect;
46 struct wl_signal aux_hint_change;
47 struct wl_signal window_role_change;
48 struct wl_signal transform_change;
49 struct wl_signal activate_done;
51 struct wl_signal mouse_in;
52 struct wl_signal mouse_out;
53 struct wl_signal mouse_down;
55 struct wl_signal focus_set;
56 struct wl_signal focus_unset;
57 struct wl_signal focus_defer_set;
58 struct wl_signal focus_latest_set;
60 struct wl_signal iconify;
61 struct wl_signal uniconify;
62 struct wl_signal maximize;
63 struct wl_signal unmaximize;
64 struct wl_signal fullscreen_pre;
65 struct wl_signal fullscreen;
66 struct wl_signal unfullscreen;
68 struct wl_signal move;
70 struct wl_signal layer_set;
71 struct wl_signal raise;
72 struct wl_signal lower;
73 struct wl_signal stack_below;
74 struct wl_signal stack_above;
75 struct wl_signal stack_transient_for_done;
77 struct wl_signal stick;
78 struct wl_signal unstick;
82 static int _e_client_hooks_delete = 0;
83 static int _e_client_hooks_walking = 0;
85 static int _e_client_intercept_hooks_delete = 0;
86 static int _e_client_intercept_hooks_walking = 0;
88 E_API int E_EVENT_CLIENT_ADD = -1;
89 E_API int E_EVENT_CLIENT_REMOVE = -1;
90 E_API int E_EVENT_CLIENT_ZONE_SET = -1;
91 E_API int E_EVENT_CLIENT_DESK_SET = -1;
92 E_API int E_EVENT_CLIENT_RESIZE = -1;
93 E_API int E_EVENT_CLIENT_MOVE = -1;
94 E_API int E_EVENT_CLIENT_SHOW = -1;
95 E_API int E_EVENT_CLIENT_HIDE = -1;
96 E_API int E_EVENT_CLIENT_ICONIFY = -1;
97 E_API int E_EVENT_CLIENT_UNICONIFY = -1;
98 E_API int E_EVENT_CLIENT_STACK = -1;
99 E_API int E_EVENT_CLIENT_FOCUS_IN = -1;
100 E_API int E_EVENT_CLIENT_FOCUS_OUT = -1;
101 E_API int E_EVENT_CLIENT_PROPERTY = -1;
102 E_API int E_EVENT_CLIENT_FULLSCREEN = -1;
103 E_API int E_EVENT_CLIENT_UNFULLSCREEN = -1;
104 #ifdef _F_ZONE_WINDOW_ROTATION_
105 E_API int E_EVENT_CLIENT_ROTATION_CHANGE_BEGIN = -1;
106 E_API int E_EVENT_CLIENT_ROTATION_CHANGE_CANCEL = -1;
107 E_API int E_EVENT_CLIENT_ROTATION_CHANGE_END = -1;
108 E_API int E_EVENT_CLIENT_ROTATION_GEOMETRY_SET = -1;
110 E_API int E_EVENT_CLIENT_VISIBILITY_CHANGE = -1;
111 E_API int E_EVENT_CLIENT_BUFFER_CHANGE = -1;
112 E_API int E_EVENT_CLIENT_FOCUS_SKIP_SET = -1;
113 E_API int E_EVENT_CLIENT_FOCUS_SKIP_UNSET = -1;
115 static Eina_Hash *clients_hash[E_PIXMAP_TYPE_MAX] = {NULL}; // pixmap->client
117 #ifdef REFACTOR_FOCUS_POLICY
119 static E_Client *focused = NULL;
121 static E_Client *ecmove = NULL;
122 static E_Client *ecresize = NULL;
123 static E_Client *action_client = NULL;
125 #ifdef REFACTOR_FOCUS_POLICY
127 static Eina_List *focus_stack = NULL;
128 static Eina_List *defer_focus_stack = NULL;
131 static Eina_Bool comp_grabbed = EINA_FALSE;
133 static Eina_List *handlers = NULL;
134 static Eina_List *hooks = NULL;
136 static Ecore_Event_Handler *action_handler_mouse = NULL;
137 static Ecore_Timer *action_timer = NULL;
138 static Eina_Rectangle action_orig = {0, 0, 0, 0};
140 static E_Client_Resize_Object_Create_Cb _e_client_resize_object_create_cb = NULL;
142 #ifdef REFACTOR_FOCUS_POLICY
144 static GMutex focused_ec_mutex;
147 EINTERN void e_client_focused_set(E_Client *ec);
148 static void _e_client_transient_for_group_make(E_Client *ec, Eina_List **list);
149 static Evas_Object *_e_client_resize_object_create(E_Client *ec);
150 static void _e_client_resize_object_del(E_Client *ec);
151 static void _e_client_stay_within_canvas(E_Client *ec, int x, int y, int *new_x, int *new_y);
152 static void _e_client_stay_within_canvas_margin(E_Client *ec, int x, int y, int *new_x, int *new_y);
154 static Eina_Inlist *_e_client_hooks[] =
156 [E_CLIENT_HOOK_EVAL_PRE_FETCH] = NULL,
157 [E_CLIENT_HOOK_EVAL_FETCH] = NULL,
158 [E_CLIENT_HOOK_EVAL_PRE_POST_FETCH] = NULL,
159 [E_CLIENT_HOOK_EVAL_POST_FETCH] = NULL,
160 [E_CLIENT_HOOK_EVAL_PRE_FRAME_ASSIGN] = NULL,
161 [E_CLIENT_HOOK_EVAL_POST_FRAME_ASSIGN] = NULL,
162 [E_CLIENT_HOOK_EVAL_PRE_NEW_CLIENT] = NULL,
163 [E_CLIENT_HOOK_EVAL_POST_NEW_CLIENT] = NULL,
164 [E_CLIENT_HOOK_EVAL_END] = NULL,
165 [E_CLIENT_HOOK_FOCUS_SET] = NULL,
166 [E_CLIENT_HOOK_FOCUS_UNSET] = NULL,
167 [E_CLIENT_HOOK_NEW_CLIENT] = NULL,
168 //#ifdef REFACTOR_ZONE_DESK
170 [E_CLIENT_HOOK_DESK_SET] = NULL,
172 [E_CLIENT_HOOK_MOVE_BEGIN] = NULL,
173 [E_CLIENT_HOOK_MOVE_UPDATE] = NULL,
174 [E_CLIENT_HOOK_MOVE_END] = NULL,
175 [E_CLIENT_HOOK_RESIZE_BEGIN] = NULL,
176 [E_CLIENT_HOOK_RESIZE_UPDATE] = NULL,
177 [E_CLIENT_HOOK_RESIZE_END] = NULL,
178 [E_CLIENT_HOOK_FULLSCREEN_PRE] = NULL,
179 //#ifdef REFACTOR_ZONE_DESK
180 [E_CLIENT_HOOK_FULLSCREEN] = NULL,
181 [E_CLIENT_HOOK_UNFULLSCREEN] = NULL,
183 [E_CLIENT_HOOK_DEL] = NULL,
184 [E_CLIENT_HOOK_UNREDIRECT] = NULL,
185 [E_CLIENT_HOOK_REDIRECT] = NULL,
186 #ifdef _F_E_CLIENT_NEW_CLIENT_POST_HOOK_
187 [E_CLIENT_HOOK_NEW_CLIENT_POST] = NULL,
189 [E_CLIENT_HOOK_EVAL_VISIBILITY] = NULL,
190 [E_CLIENT_HOOK_ICONIFY] = NULL,
191 [E_CLIENT_HOOK_UNICONIFY] = NULL,
192 [E_CLIENT_HOOK_AUX_HINT_CHANGE] = NULL,
193 [E_CLIENT_HOOK_WINDOW_ROLE_CHANGE] = NULL,
194 [E_CLIENT_HOOK_TRANSFORM_CHANGE] = NULL,
195 [E_CLIENT_HOOK_ACTIVATE_DONE] = NULL,
196 [E_CLIENT_HOOK_EVAL_VISIBILITY_END] = NULL,
197 //#ifdef REFACTOR_ZONE_DESK
198 [E_CLIENT_HOOK_STICK] = NULL,
199 [E_CLIENT_HOOK_UNSTICK] = NULL,
200 [E_CLIENT_HOOK_MAXIMIZE] = NULL,
201 [E_CLIENT_HOOK_UNMAXIMIZE] = NULL,
205 static Eina_Inlist *_e_client_intercept_hooks[] =
207 [E_CLIENT_INTERCEPT_HOOK_FOCUS_REVERT] = NULL,
208 [E_CLIENT_INTERCEPT_HOOK_AUTO_PLACEMENT] = NULL,
211 ///////////////////////////////////////////
214 _e_client_hooks_clean(void)
220 for (x = 0; x < E_CLIENT_HOOK_LAST; x++)
221 EINA_INLIST_FOREACH_SAFE(_e_client_hooks[x], l, ch)
223 if (!ch->delete_me) continue;
224 _e_client_hooks[x] = eina_inlist_remove(_e_client_hooks[x], EINA_INLIST_GET(ch));
230 _e_client_hook_call(E_Client_Hook_Point hookpoint, E_Client *ec)
234 e_object_ref(E_OBJECT(ec));
235 _e_client_hooks_walking++;
236 EINA_INLIST_FOREACH(_e_client_hooks[hookpoint], ch)
238 if (ch->delete_me) continue;
239 ch->func(ch->data, ec);
240 if ((hookpoint != E_CLIENT_HOOK_DEL) &&
241 (hookpoint != E_CLIENT_HOOK_MOVE_END) &&
242 (hookpoint != E_CLIENT_HOOK_RESIZE_END) &&
243 (hookpoint != E_CLIENT_HOOK_FOCUS_UNSET) &&
244 e_object_is_del(E_OBJECT(ec)))
247 _e_client_hooks_walking--;
248 if ((_e_client_hooks_walking == 0) && (_e_client_hooks_delete > 0))
249 _e_client_hooks_clean();
250 return !!e_object_unref(E_OBJECT(ec));
253 ///////////////////////////////////////////
256 _e_client_intercept_hooks_clean(void)
259 E_Client_Intercept_Hook *ch;
262 for (x = 0; x < E_CLIENT_INTERCEPT_HOOK_LAST; x++)
263 EINA_INLIST_FOREACH_SAFE(_e_client_intercept_hooks[x], l, ch)
265 if (!ch->delete_me) continue;
266 _e_client_intercept_hooks[x] =
267 eina_inlist_remove(_e_client_intercept_hooks[x], EINA_INLIST_GET(ch));
273 _e_client_intercept_hook_call(E_Client_Intercept_Hook_Point hookpoint, E_Client *ec)
275 E_Client_Intercept_Hook *ch;
276 Eina_Bool ret = EINA_TRUE;
278 if (e_object_is_del(E_OBJECT(ec)))
280 if (hookpoint != E_CLIENT_INTERCEPT_HOOK_FOCUS_REVERT)
286 e_object_ref(E_OBJECT(ec));
287 _e_client_intercept_hooks_walking++;
288 EINA_INLIST_FOREACH(_e_client_intercept_hooks[hookpoint], ch)
290 if (ch->delete_me) continue;
291 if (!(ch->func(ch->data, ec)))
297 _e_client_intercept_hooks_walking--;
298 if ((_e_client_intercept_hooks_walking == 0) &&
299 (_e_client_intercept_hooks_delete > 0))
300 _e_client_intercept_hooks_clean();
302 e_object_unref(E_OBJECT(ec));
307 _e_client_event_simple_free(void *d EINA_UNUSED, E_Event_Client *ev)
310 e_object_unref(E_OBJECT(ev->ec));
315 _e_client_event_simple(E_Client *ec, int type)
319 ev = E_NEW(E_Event_Client, 1);
323 e_object_ref(E_OBJECT(ec));
324 ecore_event_add(type, ev, (Ecore_End_Cb)_e_client_event_simple_free, NULL);
328 _e_client_event_add(E_Client *ec)
333 ec->reg_ev.add = EINA_TRUE;
334 ELOGF("COMP", "SEND E_EVENT_CLIENT_ADD event", ec);
335 _e_client_event_simple(ec, E_EVENT_CLIENT_ADD);
339 _e_client_event_remove(E_Client *ec)
344 ec->reg_ev.add = EINA_FALSE;
345 ELOGF("COMP", "SEND E_EVENT_CLIENT_REMOVE event", ec);
346 _e_client_event_simple(ec, E_EVENT_CLIENT_REMOVE);
350 _e_client_event_show(E_Client *ec)
355 ec->reg_ev.show = EINA_TRUE;
356 _e_client_event_simple(ec, E_EVENT_CLIENT_SHOW);
360 _e_client_event_hide(E_Client *ec)
362 if (!ec->reg_ev.show)
365 ec->reg_ev.show = EINA_FALSE;
366 _e_client_event_simple(ec, E_EVENT_CLIENT_HIDE);
370 _e_client_event_property(E_Client *ec, int prop)
372 E_Event_Client_Property *ev;
374 ev = E_NEW(E_Event_Client_Property, 1);
379 e_object_ref(E_OBJECT(ec));
380 ecore_event_add(E_EVENT_CLIENT_PROPERTY, ev, (Ecore_End_Cb)_e_client_event_simple_free, NULL);
383 #ifdef REFACTOR_ZONE_DESK
386 _e_client_event_desk_set_free(void *d EINA_UNUSED, E_Event_Client_Desk_Set *ev)
389 e_object_unref(E_OBJECT(ev->ec));
390 e_object_unref(E_OBJECT(ev->desk));
395 _e_client_event_zone_set_free(void *d EINA_UNUSED, E_Event_Client_Zone_Set *ev)
398 e_object_unref(E_OBJECT(ev->ec));
399 e_object_unref(E_OBJECT(ev->zone));
403 ////////////////////////////////////////////////
406 _e_client_action_input_win_del(void)
408 if (!comp_grabbed) return 0;
410 e_comp_ungrab_input(1, 1);
416 _e_client_action_finish(void)
419 _e_client_action_input_win_del();
421 E_FREE_FUNC(action_timer, ecore_timer_del);
422 E_FREE_FUNC(action_handler_mouse, ecore_event_handler_del);
425 action_client->keyboard_resizing = 0;
427 action_client = NULL;
431 _e_client_transform_point_transform(int cx, int cy, double angle, int x, int y, int *tx, int *ty)
433 double s = sin(angle * M_PI / 180);
434 double c = cos(angle * M_PI / 180);
441 ry = - x * s + y * c;
451 _e_client_transform_geometry_save(E_Client *ec, E_Map *map)
457 for (i = 0; i < 4; i ++)
459 e_map_point_precise_coord_get(map, i,
460 &ec->transform.saved[i].x,
461 &ec->transform.saved[i].y,
462 &ec->transform.saved[i].z);
467 _e_client_transform_resize(E_Client *ec)
471 double dx = 0, dy = 0;
476 if (!ec->transformed) return;
478 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
484 cx = ec->client.x + pw / 2;
485 cy = ec->client.y + ph / 2;
487 /* step 1: Rotate resized object and get map points */
488 map = e_map_new_with_direct_render(ec->transform_core.direct_render);
489 e_map_util_points_populate_from_geometry(map,
490 ec->client.x, ec->client.y,
493 e_map_util_rotate(map, ec->transform.angle, cx, cy);
494 e_map_util_zoom(map, ec->transform.zoom, ec->transform.zoom, cx, cy);
496 for (i = 0; i < 4; i++)
497 e_map_point_precise_coord_get(map, i, &px[i], &py[i], NULL);
501 /* step 2: get adjusted values to keep up fixed position according
503 switch (ec->resize_mode)
505 case E_POINTER_RESIZE_R:
506 case E_POINTER_RESIZE_BR:
507 dx = ec->transform.saved[0].x - px[0];
508 dy = ec->transform.saved[0].y - py[0];
510 case E_POINTER_RESIZE_BL:
511 case E_POINTER_RESIZE_B:
512 dx = ec->transform.saved[1].x - px[1];
513 dy = ec->transform.saved[1].y - py[1];
515 case E_POINTER_RESIZE_TL:
516 case E_POINTER_RESIZE_L:
517 dx = ec->transform.saved[2].x - px[2];
518 dy = ec->transform.saved[2].y - py[2];
520 case E_POINTER_RESIZE_T:
521 case E_POINTER_RESIZE_TR:
522 dx = ec->transform.saved[3].x - px[3];
523 dy = ec->transform.saved[3].y - py[3];
529 ec->transform.adjusted.x = dx;
530 ec->transform.adjusted.y = dy;
532 /* step 3: set each points of the quadrangle */
533 map = e_map_new_with_direct_render(ec->transform_core.direct_render);
534 e_map_util_points_populate_from_object_full(map, ec->frame, 0);
536 for (i = 0; i < 4; i++)
537 e_map_point_precise_coord_set(map, i, px[i] + dx, py[i] + dy, 0);
539 e_client_map_set(ec, map);
540 e_client_map_enable_set(ec, EINA_TRUE);
545 _e_client_transform_resize_handle(E_Client *ec)
548 int new_x, new_y, new_w, new_h;
552 Evas_Point current, moveinfo;
555 if (e_object_is_del(E_OBJECT(ec))) return;
556 if (e_client_util_ignored_get(ec)) return;
557 if (!ec->transformed) return;
559 zone = e_comp_zone_find_by_ec(ec);
562 button_id = ec->moveinfo.down.button;
564 org_w = ec->mouse.last_down[button_id - 1].w;
565 org_h = ec->mouse.last_down[button_id - 1].h;
567 new_w = ec->client.w;
568 new_h = ec->client.h;
569 new_x = ec->client.x;
570 new_y = ec->client.y;
572 /* step 1: get center coordinate its' based on original object geometry*/
573 cx = ec->client.x + org_w / 2;
574 cy = ec->client.y + org_h / 2;
576 /* step 2: transform coordinates of mouse position
577 * subtract adjusted value from mouse position is needed */
578 current.x = ec->mouse.current.mx - ec->transform.adjusted.x;
579 current.y = ec->mouse.current.my - ec->transform.adjusted.y;
580 moveinfo.x = ec->moveinfo.down.mx - ec->transform.adjusted.x;
581 moveinfo.y = ec->moveinfo.down.my - ec->transform.adjusted.y;
583 _e_client_transform_point_transform(cx, cy, ec->transform.angle,
584 current.x, current.y,
585 ¤t.x, ¤t.y);
586 _e_client_transform_point_transform(cx, cy, ec->transform.angle,
587 moveinfo.x, moveinfo.y,
588 &moveinfo.x, &moveinfo.y);
590 /* step 3: calculate new size */
591 if ((ec->resize_mode == E_POINTER_RESIZE_TR) ||
592 (ec->resize_mode == E_POINTER_RESIZE_R) ||
593 (ec->resize_mode == E_POINTER_RESIZE_BR))
595 if ((button_id >= 1) && (button_id <= 3))
596 new_w = org_w + (current.x - moveinfo.x);
598 new_w = ec->moveinfo.down.w + (current.x - moveinfo.x);
600 else if ((ec->resize_mode == E_POINTER_RESIZE_TL) ||
601 (ec->resize_mode == E_POINTER_RESIZE_L) ||
602 (ec->resize_mode == E_POINTER_RESIZE_BL))
604 if ((button_id >= 1) && (button_id <= 3))
605 new_w = org_w - (current.x - moveinfo.x);
607 new_w = ec->moveinfo.down.w - (current.x - moveinfo.x);
610 if ((ec->resize_mode == E_POINTER_RESIZE_TL) ||
611 (ec->resize_mode == E_POINTER_RESIZE_T) ||
612 (ec->resize_mode == E_POINTER_RESIZE_TR))
614 if ((button_id >= 1) && (button_id <= 3))
615 new_h = org_h - (current.y - moveinfo.y);
617 new_h = ec->moveinfo.down.h - (current.y - moveinfo.y);
619 else if ((ec->resize_mode == E_POINTER_RESIZE_BL) ||
620 (ec->resize_mode == E_POINTER_RESIZE_B) ||
621 (ec->resize_mode == E_POINTER_RESIZE_BR))
623 if ((button_id >= 1) && (button_id <= 3))
624 new_h = org_h + (current.y - moveinfo.y);
626 new_h = ec->moveinfo.down.h + (current.y - moveinfo.y);
629 new_w = MIN(new_w, zone->w);
630 new_h = MIN(new_h, zone->h);
632 /* step 4: move to new position */
633 if ((ec->resize_mode == E_POINTER_RESIZE_TL) ||
634 (ec->resize_mode == E_POINTER_RESIZE_L) ||
635 (ec->resize_mode == E_POINTER_RESIZE_BL))
636 new_x += (new_w - org_w);
637 if ((ec->resize_mode == E_POINTER_RESIZE_TL) ||
638 (ec->resize_mode == E_POINTER_RESIZE_T) ||
639 (ec->resize_mode == E_POINTER_RESIZE_TR))
640 new_y += (new_h - org_h);
642 /* step 5: set geometry to new value */
643 evas_object_geometry_set(ec->frame, new_x, new_y, new_w, new_h);
647 _e_client_transform_resize_begin(E_Client *ec)
650 if (!ec->transformed) return;
652 map = e_client_map_get(ec);
653 _e_client_transform_geometry_save(ec, map);
658 _e_client_transform_resize_end(E_Client *ec)
661 int new_x = 0, new_y = 0;
664 if (!ec->transformed) return;
666 map = e_client_map_get(ec);
669 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
675 cx = ec->client.x + pw / 2 + ec->transform.adjusted.x;
676 cy = ec->client.y + ph / 2 + ec->transform.adjusted.y;
678 if (ec->transform.zoom != 1.0)
682 tmp_map = e_map_dup(map);
683 e_map_util_zoom(tmp_map,
684 1 / ec->transform.zoom,
685 1 / ec->transform.zoom,
688 _e_client_transform_geometry_save(ec, tmp_map);
693 _e_client_transform_geometry_save(ec, map);
696 /* move original object to adjusted position after resizing */
697 _e_client_transform_point_transform(cx, cy,
699 ec->transform.saved[0].x,
700 ec->transform.saved[0].y,
702 e_client_util_move_without_frame(ec, new_x, new_y);
703 e_map_util_object_move_sync_set(map, EINA_TRUE);
708 _e_client_transform_move_end(E_Client *ec)
712 double dx, dy, px, py;
715 if (!ec->transformed) return;
717 map = e_client_map_get(ec);
720 if (ec->transform.zoom != 1.0)
722 e_map_point_precise_coord_get(map, 0, &px, &py, NULL);
724 dx = px - ec->transform.saved[0].x;
725 dy = py - ec->transform.saved[0].y;
727 for (i = 0; i < 4; i++)
729 ec->transform.saved[i].x += dx;
730 ec->transform.saved[i].y += dy;
734 _e_client_transform_geometry_save(ec, map);
739 e_client_intercept_hook_focus_revert_call(E_Client *ec)
741 // no need to call the intercept hook if ec is NULL.
742 if (!ec) return EINA_FALSE;
744 if (!_e_client_intercept_hook_call(E_CLIENT_INTERCEPT_HOOK_FOCUS_REVERT, ec))
746 ELOGF("FOCUS", "E_CLIENT_INTERCEPT_HOOK_FOCUS_REVERT Intercepted.", ec);
754 e_client_check_fully_contain_by_above(E_Client *ec, Eina_Bool check_layer)
756 E_Client *above = NULL;
758 int x = 0, y = 0, w = 0, h = 0;
759 int ax = 0, ay = 0, aw = 0, ah = 0;
761 if (!ec) return NULL;
763 e_client_geometry_get(ec, &x, &y, &w, &h);
765 zone = e_comp_zone_find_by_ec(ec);
767 E_RECTS_CLIP_TO_RECT(x, y, w, h, zone->x, zone->y, zone->w, zone->h);
769 above = e_client_above_get(ec);
773 (above->layer <= ec->layer))
775 above = e_client_above_get(above);
779 if ((!e_object_is_del(E_OBJECT(above))) &&
780 (!e_client_util_ignored_get(above)) &&
782 (!above->iconic || e_policy_visibility_client_is_uniconic(above)) &&
783 (!above->bg_state) &&
785 (!above->visibility.force_obscured) &&
788 e_client_geometry_get(above, &ax, &ay, &aw, &ah);
789 if (E_CONTAINS(ax, ay, aw, ah, x, y, w, h))
792 above = e_client_above_get(above);
799 e_client_check_obscured_by_children_group(E_Client *ec)
801 E_Client *cec = NULL;
802 Eina_List *transients = NULL, *l = NULL;
804 _e_client_transient_for_group_make(ec, &transients);
805 if (!transients) return NULL;
807 EINA_LIST_FOREACH(transients, l, cec)
809 if (E_CONTAINS(cec->x, cec->y, cec->w, cec->h, ec->x, ec->y, ec->w, ec->h))
811 if (!cec->argb) break;
812 if (cec->visibility.opaque > 0) break;
816 eina_list_free(transients);
822 e_client_check_really_iconified(E_Client *ec)
824 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
826 if (!ec->iconic) return EINA_FALSE;
828 return ((!e_policy_visibility_client_is_uniconic(ec) &&
829 !e_policy_visibility_client_is_uniconify_render_running(ec)) ||
830 (e_client_is_iconified_by_client(ec)));
833 #ifdef REFACTOR_FOCUS_POLICY
836 _e_client_focus_can_take_by_vis_obscured(E_Client *ec)
838 switch (ec->visibility.obscured)
840 case E_VISIBILITY_UNKNOWN:
841 if (e_client_check_really_iconified(ec))
844 if (!evas_object_visible_get(ec->frame) &&
845 !eina_list_data_find(defer_focus_stack, ec))
849 case E_VISIBILITY_FULLY_OBSCURED:
850 if (e_client_check_really_iconified(ec))
853 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK)
855 if (!evas_object_visible_get(ec->frame))
857 ELOGF("FOCUS", "client is hidden, skip focus", ec);
863 case E_VISIBILITY_UNOBSCURED:
864 case E_VISIBILITY_PARTIALLY_OBSCURED:
865 case E_VISIBILITY_PRE_UNOBSCURED:
873 _e_client_focus_can_take(E_Client *ec)
876 E_Client *child_ec = NULL;
877 E_Client *above_ec = NULL;
878 int x = 0, y = 0, w = 0, h = 0;
880 if (!ec) return EINA_FALSE;
881 if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
882 if (e_client_util_ignored_get(ec)) return EINA_FALSE;
884 if (!(ec->icccm.accepts_focus || ec->icccm.take_focus)) return EINA_FALSE;
885 if (ec->lock_focus_in || ec->lock_focus_out) return EINA_FALSE;
887 if (!ec->visible) return EINA_FALSE;
888 if (ec->bg_state) return EINA_FALSE;
889 if (ec->visibility.force_obscured) return EINA_FALSE;
890 if (!_e_client_focus_can_take_by_vis_obscured(ec)) return EINA_FALSE;
892 zone = e_comp_zone_find_by_ec(ec);
895 e_client_geometry_get(ec, &x, &y, &w, &h);
896 if (!E_INTERSECTS(zone->x, zone->y, zone->w, zone->h, x, y, w, h))
900 above_ec = e_client_check_fully_contain_by_above(ec, EINA_FALSE);
903 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK)
905 if (!evas_object_visible_get(above_ec->frame))
909 child_ec = e_client_check_obscured_by_children_group(ec);
910 if (!child_ec) return EINA_FALSE;
911 if (above_ec != child_ec) return EINA_FALSE;
913 if (_e_client_focus_can_take(child_ec))
915 else if (e_client_check_fully_contain_by_above(child_ec, EINA_FALSE))
923 e_client_focus_can_take(E_Client *ec)
925 return _e_client_focus_can_take(ec);
929 _e_client_focus_topmost_focusable_get(void)
933 E_CLIENT_REVERSE_FOREACH(ec)
935 if (_e_client_focus_can_take(ec))
942 _e_client_find_next_focus(E_Client *ec)
945 E_Client *temp_ec = NULL;
947 // call the intercept hook of the revert focus
948 if (e_client_intercept_hook_focus_revert_call(ec))
951 EINA_LIST_FOREACH(focus_stack, l, temp_ec)
953 if (_e_client_focus_can_take(temp_ec))
961 _e_client_revert_focus_get(E_Client *ec)
963 E_Client *pec = NULL, *focus_ec = NULL;
967 if (stopping) return NULL;
969 return _e_client_find_next_focus(NULL);
971 zone = e_comp_zone_find_by_ec(ec);
972 if (!zone) return NULL;
973 desk = e_desk_current_get(zone);
974 if (!desk) return NULL;
975 if (!e_comp_client_zone_is_displaying(ec)) return NULL;
977 if (e_config->focus_policy == E_FOCUS_MOUSE)
979 // set mouse over focus
980 pec = e_client_under_pointer_get(desk, ec);
983 /* no autoraise/revert here because it's probably annoying */
986 focus_ec = _e_client_find_next_focus(ec);
993 _e_client_event_focus_skip_set(E_Client *ec, Eina_Bool by_client)
995 E_Event_Client_Focus_Skip_Set *ev;
997 ev = E_NEW(E_Event_Client_Focus_Skip_Set, 1);
1001 ev->by_client = by_client;
1002 e_object_ref(E_OBJECT(ec));
1004 ecore_event_add(E_EVENT_CLIENT_FOCUS_SKIP_SET, ev, (Ecore_End_Cb)_e_client_event_simple_free, NULL);
1008 _e_client_event_focus_skip_unset(E_Client *ec, Eina_Bool by_client)
1010 E_Event_Client_Focus_Skip_Unset *ev;
1012 ev = E_NEW(E_Event_Client_Focus_Skip_Unset, 1);
1016 ev->by_client = by_client;
1017 e_object_ref(E_OBJECT(ec));
1019 ecore_event_add(E_EVENT_CLIENT_FOCUS_SKIP_UNSET, ev, (Ecore_End_Cb)_e_client_event_simple_free, NULL);
1023 e_client_focus_skip_set(E_Client *ec, Eina_Bool skip, Eina_Bool by_client)
1029 if (ec->icccm.accepts_focus)
1031 ELOGF("TZPOL", "FOCUS|SKIP SET (by_client:%d)", ec, by_client);
1032 ec->icccm.accepts_focus = ec->icccm.take_focus = 0;
1033 ec->changes.accepts_focus = 1;
1036 _e_client_event_focus_skip_set(ec, by_client);
1041 if (!ec->icccm.accepts_focus)
1043 ELOGF("TZPOL", "FOCUS|SKIP UNSET (by_client:%d)", ec, by_client);
1044 ec->icccm.accepts_focus = ec->icccm.take_focus = 1;
1045 ec->changes.accepts_focus = 1;
1048 _e_client_event_focus_skip_unset(ec, by_client);
1053 #ifdef REFACTOR_FOCUS_POLICY
1056 e_client_revert_focus(E_Client *ec)
1058 E_Client *focus_ec = NULL;
1060 // check topmost focus policy
1061 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK)
1063 focus_ec = _e_client_focus_topmost_focusable_get();
1064 if (focused == focus_ec) return;
1068 if (!focus_ec->iconic || focus_ec->exp_iconify.buffer_flush)
1070 ELOGF("FOCUS", "focus set | topmost_focus", focus_ec);
1071 if (focused) e_client_frame_focus_set(focused, EINA_FALSE);
1072 e_client_frame_focus_set(focus_ec, EINA_TRUE);
1077 ELOGF("FOCUS", "focus unset | No focusable ec", focused);
1078 e_client_frame_focus_set(focused, EINA_FALSE);
1084 focus_ec = _e_client_revert_focus_get(ec);
1085 if (!focus_ec) return;
1089 e_client_focus_defer_unset(ec);
1090 ELOGF("FOCUS", "focus unset | revert_focus", ec);
1091 e_client_frame_focus_set(ec, EINA_FALSE);
1094 if (!focus_ec->iconic || focus_ec->exp_iconify.buffer_flush)
1096 ELOGF("FOCUS", "focus set | revert_focus", focus_ec);
1097 e_client_frame_focus_set(focus_ec, EINA_TRUE);
1103 e_client_check_above_focused(E_Client *ec)
1105 E_Client *focus = NULL;
1106 E_Client *above = NULL;
1108 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
1110 focus = e_client_focused_get();
1111 if (!focus) return EINA_FALSE;
1113 above = e_client_above_get(ec);
1119 above = e_client_above_get(above);
1126 _e_client_private_init(E_Client *ec)
1128 E_Client_Private *priv;
1130 priv = E_NEW(E_Client_Private, 1);
1134 wl_signal_init(&priv->events.eval_pre_fetch);
1135 wl_signal_init(&priv->events.eval_fetch);
1136 wl_signal_init(&priv->events.eval_pre_post_fetch);
1137 wl_signal_init(&priv->events.eval_post_fetch);
1138 wl_signal_init(&priv->events.eval_pre_frame_assign);
1139 wl_signal_init(&priv->events.eval_post_frame_assign);
1140 wl_signal_init(&priv->events.eval_pre_new_client);
1141 wl_signal_init(&priv->events.eval_post_new_client);
1142 wl_signal_init(&priv->events.eval_visibility);
1143 wl_signal_init(&priv->events.eval_visibility_end);
1144 wl_signal_init(&priv->events.eval_end);
1145 wl_signal_init(&priv->events.move_begin);
1146 wl_signal_init(&priv->events.move_update);
1147 wl_signal_init(&priv->events.move_end);
1148 wl_signal_init(&priv->events.move_resize_begin);
1149 wl_signal_init(&priv->events.move_resize_update);
1150 wl_signal_init(&priv->events.move_resize_end);
1151 wl_signal_init(&priv->events.destroy);
1152 wl_signal_init(&priv->events.new_client);
1153 wl_signal_init(&priv->events.new_client_post);
1154 wl_signal_init(&priv->events.unredirect);
1155 wl_signal_init(&priv->events.redirect);
1156 wl_signal_init(&priv->events.aux_hint_change);
1157 wl_signal_init(&priv->events.window_role_change);
1158 wl_signal_init(&priv->events.transform_change);
1159 wl_signal_init(&priv->events.activate_done);
1160 wl_signal_init(&priv->events.mouse_in);
1161 wl_signal_init(&priv->events.mouse_out);
1162 wl_signal_init(&priv->events.mouse_down);
1163 wl_signal_init(&priv->events.focus_set);
1164 wl_signal_init(&priv->events.focus_unset);
1165 wl_signal_init(&priv->events.focus_defer_set);
1166 wl_signal_init(&priv->events.focus_latest_set);
1167 wl_signal_init(&priv->events.iconify);
1168 wl_signal_init(&priv->events.uniconify);
1169 wl_signal_init(&priv->events.maximize);
1170 wl_signal_init(&priv->events.unmaximize);
1171 wl_signal_init(&priv->events.fullscreen_pre);
1172 wl_signal_init(&priv->events.fullscreen);
1173 wl_signal_init(&priv->events.unfullscreen);
1174 wl_signal_init(&priv->events.move);
1175 wl_signal_init(&priv->events.layer_set);
1176 wl_signal_init(&priv->events.raise);
1177 wl_signal_init(&priv->events.lower);
1178 wl_signal_init(&priv->events.stack_below);
1179 wl_signal_init(&priv->events.stack_above);
1180 wl_signal_init(&priv->events.stack_transient_for_done);
1181 wl_signal_init(&priv->events.stick);
1182 wl_signal_init(&priv->events.unstick);
1184 e_object_data_set(E_OBJECT(ec), priv);
1190 _e_client_private_finish(E_Client *ec)
1192 E_Client_Private *priv;
1195 e_object_data_set(E_OBJECT(ec), NULL);
1201 _e_client_free(E_Client *ec)
1203 e_comp_object_redirected_set(ec->frame, 0);
1204 e_comp_object_render_update_del(ec->frame);
1206 E_OBJECT(ec)->references++;
1207 #ifdef REFACTOR_ZONE_DESK
1211 ec->desk->fullscreen_clients = eina_list_remove(ec->desk->fullscreen_clients, ec);
1212 if (!ec->desk->fullscreen_clients)
1213 e_comp_render_queue();
1217 e_comp->new_clients--;
1219 if (ec->e.state.video_parent && ec->e.state.video_parent_client)
1221 ec->e.state.video_parent_client->e.state.video_child =
1222 eina_list_remove(ec->e.state.video_parent_client->e.state.video_child, ec);
1224 if (ec->e.state.video_child)
1228 EINA_LIST_FREE(ec->e.state.video_child, tmp)
1229 tmp->e.state.video_parent_client = NULL;
1231 E_FREE_FUNC(ec->kill_timer, ecore_timer_del);
1232 E_FREE_LIST(ec->pending_resize, free);
1234 E_FREE_FUNC(ec->map_timer, ecore_timer_del);
1236 ec->transients = eina_list_free(ec->transients);
1237 if (ec->netwm.icons)
1240 for (i = 0; i < ec->netwm.num_icons; i++)
1241 free(ec->netwm.icons[i].data);
1242 E_FREE(ec->netwm.icons);
1244 E_FREE(ec->netwm.extra_types);
1245 eina_stringshare_replace(&ec->border.name, NULL);
1246 eina_stringshare_replace(&ec->bordername, NULL);
1247 eina_stringshare_replace(&ec->icccm.name, NULL);
1248 #if defined(__cplusplus) || defined(c_plusplus)
1249 eina_stringshare_replace(&ec->icccm.cpp_class, NULL);
1251 eina_stringshare_replace(&ec->icccm.class, NULL);
1253 eina_stringshare_replace(&ec->icccm.title, NULL);
1254 eina_stringshare_replace(&ec->icccm.icon_name, NULL);
1255 eina_stringshare_replace(&ec->icccm.machine, NULL);
1256 eina_stringshare_replace(&ec->icccm.window_role, NULL);
1257 if ((ec->icccm.command.argc > 0) && (ec->icccm.command.argv))
1261 for (i = 0; i < ec->icccm.command.argc; i++)
1262 free(ec->icccm.command.argv[i]);
1263 E_FREE(ec->icccm.command.argv);
1265 eina_stringshare_replace(&ec->netwm.name, NULL);
1266 eina_stringshare_replace(&ec->netwm.icon_name, NULL);
1267 eina_stringshare_replace(&ec->internal_icon, NULL);
1268 eina_stringshare_replace(&ec->internal_icon_key, NULL);
1270 #ifdef REFACTOR_FOCUS_POLICY
1271 // This code is executed at E_CLIENT_HOOK_DEL callback at e_focus_policy_history.c
1273 focus_stack = eina_list_remove(focus_stack, ec);
1274 e_client_focus_defer_unset(ec);
1277 E_FREE_FUNC(ec->frame, evas_object_del);
1279 #ifdef REFACTOR_FOCUS_POLICY
1280 // This code is executed at E_CLIENT_HOOK_DEL callback at e_focus_policy_topmost.c and e_focus_policy_history.c
1284 ELOGF("COMP", "CRITICAL. focused is deleted ec.", ec);
1285 ELOGF("FOCUS", "CLIENT FOCUS_SET", NULL);
1286 g_mutex_lock(&focused_ec_mutex);
1288 g_mutex_unlock(&focused_ec_mutex);
1292 E_OBJECT(ec)->references--;
1293 ELOGF("COMP", "CLIENT FREE", ec);
1295 e_uuid_store_entry_del(ec->uuid);
1296 #ifdef REFACTOR_ZONE_DESK
1298 e_desk_client_del(ec->desk, ec);
1301 _e_client_private_finish(ec);
1306 _e_client_del(E_Client *ec)
1313 #ifdef REFACTOR_FOCUS_POLICY
1314 // This code is executed at E_CLIENT_HOOK_DEL callback at e_focus_policy_history.c
1316 focus_stack = eina_list_remove(focus_stack, ec);
1317 e_client_focus_defer_unset(ec);
1319 #ifdef REFACTOR_ZONE_DESK
1321 e_desk_visible_client_iconified_list_remove(ec->desk, ec);
1323 if (ec == e_comp_object_dim_client_get())
1325 INF("[DIM] client deleted\n");
1326 e_comp_object_dim_client_set(NULL);
1329 if (ec->cur_mouse_action)
1331 if (ec->cur_mouse_action->func.end)
1332 ec->cur_mouse_action->func.end(E_OBJECT(ec), "");
1334 if (action_client == ec) _e_client_action_finish();
1338 e_client_comp_hidden_set(ec, 1);
1339 evas_object_pass_events_set(ec->frame, 1);
1341 #ifdef REFACTOR_FOCUS_POLICY
1342 // This code is executed at E_CLIENT_HOOK_DEL callback at e_focus_policy_history.c
1345 e_client_revert_focus(ec);
1348 E_FREE_FUNC(ec->ping_poller, ecore_poller_del);
1350 wl_signal_emit_mutable(&PRI(ec)->events.destroy, NULL);
1352 /* must be called before parent/child clear */
1353 _e_client_hook_call(E_CLIENT_HOOK_DEL, ec);
1355 _e_client_event_remove(ec);
1357 ELOGF("COMP", "CLIENT DEL", ec);
1361 ec->parent->transients = eina_list_remove(ec->parent->transients, ec);
1364 EINA_LIST_FREE(ec->transients, child)
1365 child->parent = NULL;
1367 type = e_pixmap_type_get(ec->pixmap);
1368 if (type < E_PIXMAP_TYPE_MAX)
1369 eina_hash_del_by_key(clients_hash[type], &ec->pixmap);
1370 e_comp->clients = eina_list_remove(e_comp->clients, ec);
1371 e_comp_object_render_update_del(ec->frame);
1372 e_comp_post_update_purge(ec);
1373 if (e_pixmap_free(ec->pixmap))
1374 e_pixmap_client_set(ec->pixmap, NULL);
1377 // base_output_resolution
1378 e_client_transform_core_remove(ec, ec->base_output_resolution.transform);
1379 e_util_transform_del(ec->base_output_resolution.transform);
1380 ec->base_output_resolution.transform = NULL;
1381 E_FREE_FUNC(ec->base_output_resolution.hook_subsurf_create, e_comp_wl_hook_del);
1383 #ifdef REFACTOR_ZONE_DESK
1386 e_client_transform_core_remove(ec, ec->desk_zoom.transform);
1387 e_util_transform_del(ec->desk_zoom.transform);
1388 ec->desk_zoom.transform = NULL;
1389 E_FREE_FUNC(ec->desk_zoom.hook_subsurf_create, e_comp_wl_hook_del);
1392 if (ec->transform_core.transform_list)
1394 E_Util_Transform *transform;
1396 EINA_LIST_FREE(ec->transform_core.transform_list, transform)
1398 e_util_transform_unref(transform);
1402 ec->transform_core.result.enable = EINA_FALSE;
1404 #ifdef REFACTOR_ZONE_DESK
1406 e_client_desk_area_set(ec, NULL);
1407 e_util_transform_del(ec->desk_area.transform);
1408 ec->desk_area.transform = NULL;
1411 _e_client_resize_object_del(ec);
1413 e_comp_visibility_calculation_set(EINA_TRUE);
1416 ///////////////////////////////////////////
1419 _e_client_cb_kill_timer(void *data)
1421 E_Client *ec = data;
1423 // dont wait until it's hung -
1426 if (ec->netwm.pid > 1)
1427 kill(ec->netwm.pid, SIGKILL);
1429 ec->kill_timer = NULL;
1430 return ECORE_CALLBACK_CANCEL;
1434 _e_client_cb_ping_poller(void *data)
1439 if (e_object_is_del(E_OBJECT(ec)))
1441 ec->ping_poller = NULL;
1442 return ECORE_CALLBACK_CANCEL;
1450 evas_object_smart_callback_call(ec->frame, "unhung", NULL);
1451 E_FREE_FUNC(ec->kill_timer, ecore_timer_del);
1456 /* if time between last ping and now is greater
1457 * than half the ping interval... */
1458 if ((ecore_loop_time_get() - ec->ping) >
1459 ((e_config->ping_clients_interval *
1460 ecore_poller_poll_interval_get(ECORE_POLLER_CORE)) / 2.0))
1465 evas_object_smart_callback_call(ec->frame, "hung", NULL);
1466 /* FIXME: if below dialog is up - hide it now */
1468 if (ec->delete_requested)
1470 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
1471 e_client_act_kill_begin(ec);
1475 ec->ping_poller = NULL;
1477 return ECORE_CALLBACK_CANCEL;
1480 ///////////////////////////////////////////
1483 _e_client_action_input_win_new(void)
1487 CRI("DOUBLE COMP GRAB! ACK!!!!");
1490 comp_grabbed = e_comp_grab_input(1, 1);
1491 if (!comp_grabbed) _e_client_action_input_win_del();
1492 return comp_grabbed;
1496 _e_client_action_init(E_Client *ec)
1498 action_orig.x = ec->x;
1499 action_orig.y = ec->y;
1500 action_orig.w = ec->w;
1501 action_orig.h = ec->h;
1505 action_client->keyboard_resizing = 0;
1511 _e_client_move_begin(E_Client *ec)
1513 if ((ec->fullscreen) || (ec->lock_user_location))
1516 if (!_e_client_action_input_win_new()) return 0;
1520 wl_signal_emit_mutable(&PRI(ec)->events.move_begin, NULL);
1521 _e_client_hook_call(E_CLIENT_HOOK_MOVE_BEGIN, ec);
1524 if (ecmove == ec) ecmove = NULL;
1525 _e_client_action_input_win_del();
1528 if (!ec->lock_user_stacking)
1530 if (e_config->border_raise_on_mouse_action)
1535 e_comp_client_override_add(ec);
1541 _e_client_move_end(E_Client *ec)
1544 _e_client_action_input_win_del();
1546 wl_signal_emit_mutable(&PRI(ec)->events.move_end, NULL);
1547 _e_client_hook_call(E_CLIENT_HOOK_MOVE_END, ec);
1549 if (ec->transformed)
1550 _e_client_transform_move_end(ec);
1553 e_comp_client_override_del(ec);
1560 _e_client_action_move_timeout(void *data EINA_UNUSED)
1562 _e_client_move_end(action_client);
1563 _e_client_action_finish();
1564 return ECORE_CALLBACK_CANCEL;
1568 _e_client_action_move_timeout_add(void)
1570 E_FREE_FUNC(action_timer, ecore_timer_del);
1571 if (e_config->border_keyboard.timeout)
1572 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_client_action_move_timeout, NULL);
1576 _e_client_move_mouse_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
1578 if (!comp_grabbed) return ECORE_CALLBACK_RENEW;
1581 ERR("no action_client!");
1583 if (action_client) _e_client_move_end(action_client);
1584 _e_client_action_finish();
1585 return ECORE_CALLBACK_DONE;
1589 _e_client_moveinfo_gather(E_Client *ec, const char *source)
1591 if (e_util_glob_match(source, "mouse,*,1"))
1592 ec->moveinfo.down.button = 1;
1593 else if (e_util_glob_match(source, "mouse,*,2"))
1594 ec->moveinfo.down.button = 2;
1595 else if (e_util_glob_match(source, "mouse,*,3"))
1596 ec->moveinfo.down.button = 3;
1598 ec->moveinfo.down.button = 0;
1599 if ((ec->moveinfo.down.button >= 1) && (ec->moveinfo.down.button <= 3))
1601 ec->moveinfo.down.mx = ec->mouse.last_down[ec->moveinfo.down.button - 1].mx;
1602 ec->moveinfo.down.my = ec->mouse.last_down[ec->moveinfo.down.button - 1].my;
1606 ec->moveinfo.down.mx = ec->mouse.current.mx;
1607 ec->moveinfo.down.my = ec->mouse.current.my;
1612 _e_client_move_handle(E_Client *ec)
1616 if ((ec->moveinfo.down.button >= 1) && (ec->moveinfo.down.button <= 3))
1618 x = ec->mouse.last_down[ec->moveinfo.down.button - 1].x +
1619 (ec->mouse.current.mx - ec->moveinfo.down.mx);
1620 y = ec->mouse.last_down[ec->moveinfo.down.button - 1].y +
1621 (ec->mouse.current.my - ec->moveinfo.down.my);
1625 x = ec->moveinfo.down.x +
1626 (ec->mouse.current.mx - ec->moveinfo.down.mx);
1627 y = ec->moveinfo.down.y +
1628 (ec->mouse.current.my - ec->moveinfo.down.my);
1631 if (e_config->screen_limits == E_CLIENT_OFFSCREEN_LIMIT_ALLOW_NONE)
1632 _e_client_stay_within_canvas(ec, x, y, &x, &y);
1635 _e_client_stay_within_canvas_margin(ec, x, y, &x, &y);
1637 evas_object_move(ec->frame, x, y);
1639 if (e_client_transform_core_enable_get(ec))
1641 e_client_transform_core_update(ec);
1645 static Evas_Object *
1646 _e_client_resize_object_rectangle_get(E_Client *ec)
1648 Evas_Object *resize_obj = NULL;
1650 resize_obj = evas_object_rectangle_add(evas_object_evas_get(ec->frame));
1651 EINA_SAFETY_ON_NULL_RETURN_VAL(resize_obj, NULL);
1653 if (e_config->resize_object.customize)
1655 evas_object_color_set(resize_obj,
1656 e_config->resize_object.r,
1657 e_config->resize_object.g,
1658 e_config->resize_object.b,
1659 e_config->resize_object.a);
1662 evas_object_color_set(resize_obj, 128, 128, 128, 100);
1667 static Evas_Object *
1668 _e_client_resize_object_image_get(E_Client *ec)
1671 Evas_Object *resize_obj = NULL;
1673 if (!e_config->resize_object.image_path)
1675 ELOGF("COMP", "NO resize_object image! Make default resize_object", ec);
1679 resize_obj = evas_object_image_add(evas_object_evas_get(ec->frame));
1680 EINA_SAFETY_ON_NULL_RETURN_VAL(resize_obj, NULL);
1682 evas_object_image_file_set(resize_obj, e_config->resize_object.image_path, NULL);
1683 err = evas_object_image_load_error_get(resize_obj);
1684 if (err != EVAS_LOAD_ERROR_NONE)
1686 ELOGF("COMP", "Image load error. path:%s, errno:%d. Make default resize_object",
1687 ec, e_config->resize_object.image_path, err);
1688 evas_object_del(resize_obj);
1693 evas_object_image_fill_set(resize_obj, 0, 0, ec->w, ec->h);
1694 evas_object_image_filled_set(resize_obj, EINA_TRUE);
1696 evas_object_image_border_set(resize_obj,
1697 e_config->resize_object.border_width.l,
1698 e_config->resize_object.border_width.r,
1699 e_config->resize_object.border_width.t,
1700 e_config->resize_object.border_width.b);
1705 return _e_client_resize_object_rectangle_get(ec);
1708 static Evas_Object *
1709 _e_client_resize_object_create(E_Client *ec)
1711 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->frame, NULL);
1713 Evas_Object *resize_obj = NULL;
1715 if (_e_client_resize_object_create_cb)
1716 resize_obj = _e_client_resize_object_create_cb(ec);
1719 if (e_config->resize_object.type == 1) // image object
1721 resize_obj = _e_client_resize_object_image_get(ec);
1725 resize_obj = _e_client_resize_object_rectangle_get(ec);
1728 EINA_SAFETY_ON_NULL_RETURN_VAL(resize_obj, NULL);
1730 evas_object_pass_events_set(resize_obj, EINA_TRUE);
1731 evas_object_layer_set(resize_obj, evas_object_layer_get(ec->frame));
1732 evas_object_stack_above(resize_obj, ec->frame);
1733 evas_object_name_set(resize_obj, "resize_object");
1739 _e_client_resize_object_del(E_Client *ec)
1741 if (ec == NULL) return;
1742 if (ec->manage_resize.resize_obj == NULL) return;
1744 evas_object_hide(ec->manage_resize.resize_obj);
1745 evas_object_del(ec->manage_resize.resize_obj);
1746 ec->manage_resize.resize_obj = NULL;
1750 _e_client_resize_handle(E_Client *ec)
1753 int new_x, new_y, new_w, new_h;
1755 int trans_x = 0, trans_y = 0;
1756 int trans_w = 0, trans_h = 0;
1758 if (ec->transformed)
1760 _e_client_transform_resize_handle(ec);
1769 if ((ec->resize_mode == E_POINTER_RESIZE_TR) ||
1770 (ec->resize_mode == E_POINTER_RESIZE_R) ||
1771 (ec->resize_mode == E_POINTER_RESIZE_BR))
1773 if ((ec->moveinfo.down.button >= 1) &&
1774 (ec->moveinfo.down.button <= 3))
1775 w = ec->mouse.last_down[ec->moveinfo.down.button - 1].w +
1776 (ec->mouse.current.mx - ec->moveinfo.down.mx);
1778 w = ec->moveinfo.down.w + (ec->mouse.current.mx - ec->moveinfo.down.mx);
1780 else if ((ec->resize_mode == E_POINTER_RESIZE_TL) ||
1781 (ec->resize_mode == E_POINTER_RESIZE_L) ||
1782 (ec->resize_mode == E_POINTER_RESIZE_BL))
1784 if ((ec->moveinfo.down.button >= 1) &&
1785 (ec->moveinfo.down.button <= 3))
1786 w = ec->mouse.last_down[ec->moveinfo.down.button - 1].w -
1787 (ec->mouse.current.mx - ec->moveinfo.down.mx);
1789 w = ec->moveinfo.down.w - (ec->mouse.current.mx - ec->moveinfo.down.mx);
1792 if ((ec->resize_mode == E_POINTER_RESIZE_TL) ||
1793 (ec->resize_mode == E_POINTER_RESIZE_T) ||
1794 (ec->resize_mode == E_POINTER_RESIZE_TR))
1796 if ((ec->moveinfo.down.button >= 1) &&
1797 (ec->moveinfo.down.button <= 3))
1798 h = ec->mouse.last_down[ec->moveinfo.down.button - 1].h -
1799 (ec->mouse.current.my - ec->moveinfo.down.my);
1801 h = ec->moveinfo.down.h - (ec->mouse.current.my - ec->moveinfo.down.my);
1803 else if ((ec->resize_mode == E_POINTER_RESIZE_BL) ||
1804 (ec->resize_mode == E_POINTER_RESIZE_B) ||
1805 (ec->resize_mode == E_POINTER_RESIZE_BR))
1807 if ((ec->moveinfo.down.button >= 1) &&
1808 (ec->moveinfo.down.button <= 3))
1809 h = ec->mouse.last_down[ec->moveinfo.down.button - 1].h +
1810 (ec->mouse.current.my - ec->moveinfo.down.my);
1812 h = ec->moveinfo.down.h + (ec->mouse.current.my - ec->moveinfo.down.my);
1817 if ((ec->resize_mode == E_POINTER_RESIZE_T) ||
1818 (ec->resize_mode == E_POINTER_RESIZE_TL) ||
1819 (ec->resize_mode == E_POINTER_RESIZE_L) ||
1820 (ec->resize_mode == E_POINTER_RESIZE_BL))
1822 if ((ec->resize_mode == E_POINTER_RESIZE_L) ||
1823 (ec->resize_mode == E_POINTER_RESIZE_TL) ||
1824 (ec->resize_mode == E_POINTER_RESIZE_T) ||
1825 (ec->resize_mode == E_POINTER_RESIZE_TR))
1832 if (e_config->screen_limits == E_CLIENT_OFFSCREEN_LIMIT_ALLOW_NONE)
1835 zone = e_comp_zone_find_by_ec(ec);
1838 w = MIN(w, zone->w);
1839 h = MIN(h, zone->h);
1842 e_client_resize_limit(ec, &new_w, &new_h);
1844 if (ec->manage_resize.enable_aspect_ratio)
1846 if ((ec->resize_mode == E_POINTER_RESIZE_TL) ||
1847 (ec->resize_mode == E_POINTER_RESIZE_L) ||
1848 (ec->resize_mode == E_POINTER_RESIZE_BL) ||
1849 (ec->resize_mode == E_POINTER_RESIZE_TR) ||
1850 (ec->resize_mode == E_POINTER_RESIZE_R) ||
1851 (ec->resize_mode == E_POINTER_RESIZE_BR))
1853 new_h = (int) ec->manage_resize.ah / ec->manage_resize.aw * new_w;
1855 else if ((ec->resize_mode == E_POINTER_RESIZE_T) ||
1856 (ec->resize_mode == E_POINTER_RESIZE_B))
1858 new_w = (int) ec->manage_resize.aw / ec->manage_resize.ah * new_h;
1860 new_h += ec->manage_resize.header_h;
1861 new_h += ec->manage_resize.footer_h;
1864 if ((ec->resize_mode == E_POINTER_RESIZE_T) ||
1865 (ec->resize_mode == E_POINTER_RESIZE_TL) ||
1866 (ec->resize_mode == E_POINTER_RESIZE_L) ||
1867 (ec->resize_mode == E_POINTER_RESIZE_BL))
1868 new_x += (w - new_w);
1869 if ((ec->resize_mode == E_POINTER_RESIZE_L) ||
1870 (ec->resize_mode == E_POINTER_RESIZE_TL) ||
1871 (ec->resize_mode == E_POINTER_RESIZE_T) ||
1872 (ec->resize_mode == E_POINTER_RESIZE_TR))
1873 new_y += (h - new_h);
1875 if (e_config->interactive_resize)
1877 evas_object_geometry_set(ec->frame, new_x, new_y, new_w, new_h);
1881 if (ec->manage_resize.resize_obj == NULL)
1883 ec->manage_resize.resize_obj = _e_client_resize_object_create(ec);
1884 EINA_SAFETY_ON_NULL_RETURN(ec->manage_resize.resize_obj);
1887 if (e_client_transform_core_enable_get(ec))
1889 e_client_transform_core_input_inv_transform(ec, new_x, new_y, &trans_x, &trans_y);
1890 e_client_transform_core_input_inv_transform(ec, new_w, new_h, &trans_w, &trans_h);
1891 evas_object_geometry_set(ec->manage_resize.resize_obj, trans_x, trans_y, trans_w, trans_h);
1894 evas_object_geometry_set(ec->manage_resize.resize_obj, new_x, new_y, new_w, new_h);
1895 evas_object_show(ec->manage_resize.resize_obj);
1897 ec->manage_resize.x = new_x;
1898 ec->manage_resize.y = new_y;
1899 ec->manage_resize.w = new_w;
1900 ec->manage_resize.h = new_h;
1905 _e_client_adjust_size_by_ppu(int size, int start_size, unsigned int ppu)
1907 if (ppu <= 1) return size;
1909 unsigned int remainder = size % ppu;
1910 if (remainder == 0) return size;
1912 int gap = size - start_size;
1913 int new_size = size;
1915 new_size = size + (ppu - remainder);
1917 new_size = size - remainder;
1923 _e_client_adjust_position_by_ppu(int pos, int size, int prev_pos, int prev_size)
1927 if (prev_pos == pos)
1930 new_pos = (prev_pos + prev_size) - size;
1936 _e_client_adjust_geometry_by_resize_ppu(E_Client *ec)
1938 if (ec->manage_resize.unit_size <= 1) return;
1940 ec->manage_resize.w = _e_client_adjust_size_by_ppu(ec->manage_resize.w, ec->w, ec->manage_resize.unit_size);
1941 ec->manage_resize.h = _e_client_adjust_size_by_ppu(ec->manage_resize.h, ec->h, ec->manage_resize.unit_size);
1943 ec->manage_resize.x = _e_client_adjust_position_by_ppu(ec->manage_resize.x, ec->manage_resize.w, ec->x, ec->w);
1944 ec->manage_resize.y = _e_client_adjust_position_by_ppu(ec->manage_resize.y, ec->manage_resize.h, ec->y, ec->h);
1948 _e_client_resize_end(E_Client *ec)
1950 ec->resize_mode = E_POINTER_RESIZE_NONE;
1951 _e_client_action_input_win_del();
1953 wl_signal_emit_mutable(&PRI(ec)->events.move_resize_end, NULL);
1954 _e_client_hook_call(E_CLIENT_HOOK_RESIZE_END, ec);
1956 if (ec->transformed)
1957 _e_client_transform_resize_end(ec);
1960 e_comp_client_override_del(ec);
1964 if (!e_config->interactive_resize)
1966 if (ec->manage_resize.resize_obj)
1968 if (ec->manage_resize.unit_size > 1)
1969 _e_client_adjust_geometry_by_resize_ppu(ec);
1971 e_client_frame_geometry_set(ec,
1972 ec->manage_resize.x,
1973 ec->manage_resize.y,
1974 ec->manage_resize.w,
1975 ec->manage_resize.h);
1976 _e_client_resize_object_del(ec);
1984 _e_client_action_resize_timeout(void *data EINA_UNUSED)
1986 _e_client_resize_end(action_client);
1987 _e_client_action_finish();
1988 return ECORE_CALLBACK_CANCEL;
1992 _e_client_action_resize_timeout_add(void)
1994 E_FREE_FUNC(action_timer, ecore_timer_del);
1995 if (e_config->border_keyboard.timeout)
1996 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_client_action_resize_timeout, NULL);
2000 _e_client_resize_mouse_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
2002 if (!comp_grabbed) return ECORE_CALLBACK_RENEW;
2005 ERR("no action_client!");
2007 if (action_client) _e_client_resize_end(action_client);
2008 _e_client_action_finish();
2009 return ECORE_CALLBACK_DONE;
2012 ////////////////////////////////////////////////
2015 _e_client_position_inside_input_rect(E_Client *ec, int tx, int ty)
2018 Eina_Bool res = EINA_FALSE;
2019 Eina_List *list = NULL, *l;
2020 Eina_Rectangle *data;
2022 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
2024 e_client_geometry_get(ec, &x, &y, &w, &h);
2025 e_comp_object_input_rect_get(ec->frame, &list);
2028 EINA_LIST_FOREACH(list, l, data)
2030 if ((tx >= x + data->x) && (tx <= x + data->x + data->w) &&
2031 (ty >= y + data->y) && (ty <= y + data->y + data->h))
2037 list = eina_list_free(list);
2041 if ((tx >= x) && (tx <= x + w) &&
2042 (ty >= y) && (ty <= y + h))
2052 _e_client_under_pointer_helper_ignore_client(E_Desk *desk, E_Client *client)
2054 /* If a border was specified which should be excluded from the list
2055 * (because it will be closed shortly for example), skip */
2056 if (e_client_util_ignored_get(client) || (!e_desk_has_ec(desk, client))) return EINA_TRUE;
2057 if (!evas_object_visible_get(client->frame)) return EINA_TRUE;
2058 if (e_policy_client_is_cursor(client)) return EINA_TRUE;
2064 _e_client_under_pointer_helper(E_Desk *desk, E_Client *exclude, int x, int y)
2066 E_Client *ec = NULL, *cec;
2068 E_CLIENT_REVERSE_FOREACH(cec)
2070 if (_e_client_under_pointer_helper_ignore_client(desk, cec)) continue;
2071 if ((exclude) && (cec == exclude)) continue;
2072 if (!E_INSIDE(x, y, cec->x, cec->y, cec->w, cec->h))
2074 /* If the layer is higher, the position of the window is higher
2075 * (always on top vs always below) */
2076 if (!ec || (cec->layer > ec->layer))
2083 _e_client_input_rect_under_pointer_helper(E_Desk *desk, E_Client *exclude, int x, int y)
2085 E_Client *ec = NULL, *cec;
2088 E_CLIENT_REVERSE_FOREACH(cec)
2090 /* If a border was specified which should be excluded from the list
2091 * (because it will be closed shortly for example), skip */
2092 if (e_client_util_ignored_get(cec) || (!e_desk_has_ec(desk, cec))) continue;
2093 if (!evas_object_visible_get(cec->frame)) continue;
2094 if (e_policy_client_is_cursor(cec)) continue;
2095 if ((exclude) && (cec == exclude)) continue;
2096 e_client_geometry_get(cec, &cx, &cy, &cw, &ch);
2097 if (!E_INSIDE(x, y, cx, cy, cw, ch))
2099 /* If the layer is higher, the position of the window is higher
2100 * (always on top vs always below) */
2101 if (ec && (cec->layer <= ec->layer)) continue;
2102 if (_e_client_position_inside_input_rect(cec, x, y))
2110 _e_client_under_pointer_input_helper(E_Desk *desk, int x, int y)
2112 E_Client *ec = NULL, *cec;
2114 E_CLIENT_REVERSE_FOREACH(cec)
2116 if (_e_client_under_pointer_helper_ignore_client(desk, cec)) continue;
2118 Eina_List *list = NULL;
2119 Eina_Rectangle *rect;
2120 Eina_Bool inside = EINA_FALSE;
2121 e_comp_object_input_rect_get(cec->frame, &list);
2124 EINA_LIST_FREE(list, rect)
2126 if (E_INSIDE(x, y, rect->x, rect->y, rect->w, rect->h))
2130 else if (E_INSIDE(x, y, cec->x, cec->y, cec->w, cec->h))
2135 if (!inside) continue;
2136 /* If the layer is higher, the position of the window is higher
2137 * (always on top vs always below) */
2138 if (!ec || (cec->layer > ec->layer))
2145 ////////////////////////////////////////////////
2148 _e_client_zones_layout_calc(E_Client *ec, int *zx, int *zy, int *zw, int *zh)
2151 E_Zone *zone_above, *zone_below, *zone_left, *zone_right;
2154 zone = e_comp_zone_find_by_ec(ec);
2161 if (eina_list_count(e_comp->zones) == 1)
2170 zone_left = e_comp_zone_xy_get((x - w + 5), y);
2171 zone_right = e_comp_zone_xy_get((x + w + 5), y);
2172 zone_above = e_comp_zone_xy_get(x, (y - h + 5));
2173 zone_below = e_comp_zone_xy_get(x, (y + h + 5));
2175 if (!(zone_above) && (y))
2176 zone_above = e_comp_zone_xy_get(x, (h - 5));
2178 if (!(zone_left) && (x))
2179 zone_left = e_comp_zone_xy_get((x - 5), y);
2182 w = zone_right->x + zone_right->w;
2185 w = zone->x + zone->w;
2188 h = zone_below->y + zone_below->h;
2191 h = zone->y + zone->h;
2193 if ((zone_left) && (zone_right))
2194 w = zone->w + zone_right->x;
2196 if ((zone_above) && (zone_below))
2197 h = zone->h + zone_below->y;
2199 if (x) x -= zone->w;
2200 if (y) y -= zone->h;
2202 if (zx) *zx = x > 0 ? x : 0;
2203 if (zy) *zy = y > 0 ? y : 0;
2209 _e_client_stay_within_canvas(E_Client *ec, int x, int y, int *new_x, int *new_y)
2211 int new_x_max, new_y_max;
2216 zone = e_comp_zone_find_by_ec(ec);
2219 if (new_x) *new_x = x;
2220 if (new_y) *new_y = y;
2224 _e_client_zones_layout_calc(ec, NULL, NULL, &zw, &zh);
2226 new_x_max = zw - ec->w;
2227 new_y_max = zh - ec->h;
2228 lw = ec->w > zw ? EINA_TRUE : EINA_FALSE;
2229 lh = ec->h > zh ? EINA_TRUE : EINA_FALSE;
2263 _e_client_stay_within_canvas_margin(E_Client *ec, int x, int y, int *new_x, int *new_y)
2265 int new_x_max, new_y_max, new_x_min, new_y_min;
2266 int margin_w, margin_h;
2271 zone = e_comp_zone_find_by_ec(ec);
2274 if (new_x) *new_x = x;
2275 if (new_y) *new_y = y;
2282 _e_client_zones_layout_calc(ec, NULL, NULL, &zw, &zh);
2287 new_x_min = (margin_w > cw) ? 0 : -(cw - margin_w);
2288 new_x_max = (margin_w > cw) ? (zw - cw) : (zw - margin_w);
2289 new_y_min = (margin_h > ch) ? 0 : -(ch - margin_h);
2290 new_y_max = (margin_h > ch) ? (zh - ch) : (zh - margin_h);
2294 else if (x <= new_x_min)
2299 else if (y <= new_y_min)
2304 ////////////////////////////////////////////////
2305 #ifdef REFACTOR_ZONE_DESK
2308 _e_client_zone_update(E_Client *ec)
2313 /* still within old zone - leave it there */
2314 zone = e_comp_zone_find_by_ec(ec);
2315 if (zone && E_INTERSECTS(ec->x, ec->y, ec->w, ec->h,
2316 zone->x, zone->y, zone->w, zone->h))
2319 /* find a new zone */
2320 EINA_LIST_FOREACH(e_comp->zones, l, zone)
2322 if (E_INTERSECTS(ec->x, ec->y, ec->w, ec->h,
2323 zone->x, zone->y, zone->w, zone->h))
2325 e_client_zone_set(ec, zone);
2331 ////////////////////////////////////////////////
2334 _e_client_transform_core_activate_set(E_Client *ec, Eina_Bool set)
2336 if (ec->transform_core.activate == set) return;
2338 ec->transform_core.activate = set;
2342 if (ec->transform_core.result.enable)
2343 e_client_map_enable_set(ec, EINA_TRUE);
2347 e_client_map_enable_set(ec, EINA_FALSE);
2352 _e_client_cb_evas_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2354 E_Client *ec = data;
2356 if (stopping) return; //ignore all of this if we're shutting down!
2357 if (e_object_is_del(data)) return; //client is about to die
2358 if (ec->cur_mouse_action)
2360 if (ec->cur_mouse_action->func.end_mouse)
2361 ec->cur_mouse_action->func.end_mouse(E_OBJECT(ec), "", NULL);
2362 else if (ec->cur_mouse_action->func.end)
2363 ec->cur_mouse_action->func.end(E_OBJECT(ec), "");
2364 E_FREE_FUNC(ec->cur_mouse_action, e_object_unref);
2366 if (action_client == ec) _e_client_action_finish();
2368 ec->want_focus = ec->take_focus = 0;
2370 _e_client_transform_core_activate_set(ec, EINA_FALSE);
2372 if (ec->new_client) return;
2373 _e_client_event_hide(ec);
2379 _e_client_cb_evas_shade_done(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2381 E_Client *ec = data;
2383 if (e_object_is_del(data)) return;
2386 ec->shaded = !(ec->shaded);
2387 ec->changes.shaded = 1;
2388 ec->changes.shading = 1;
2389 e_client_comp_hidden_set(ec, ec->shaded);
2393 _e_client_cb_evas_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2395 E_Client *ec = data;
2399 if (e_object_is_del(data)) return;
2401 ec->pre_res_change.valid = 0;
2403 _e_client_event_simple(ec, E_EVENT_CLIENT_MOVE);
2405 #ifdef REFACTOR_ZONE_DESK
2407 _e_client_zone_update(ec);
2409 evas_object_geometry_get(ec->frame, &x, &y, NULL, NULL);
2410 if ((e_config->transient.move) && (ec->transients))
2412 Eina_List *list = eina_list_clone(ec->transients);
2415 EINA_LIST_FREE(list, child)
2417 if (child->vkbd.vkbd) continue;
2419 evas_object_move(child->frame,
2420 child->x + x - ec->pre_cb.x,
2421 child->y + y - ec->pre_cb.y);
2424 if (ec->moving || (ecmove == ec))
2426 wl_signal_emit_mutable(&PRI(ec)->events.move_resize_update, NULL);
2427 _e_client_hook_call(E_CLIENT_HOOK_MOVE_UPDATE, ec);
2430 if ((!ec->moving) && (ec->transformed))
2432 map = e_client_map_get(ec);
2433 _e_client_transform_geometry_save(ec, map);
2437 ec->pre_cb.x = x; ec->pre_cb.y = y;
2439 #ifdef REFACTOR_FOCUS_POLICY
2440 // This code is executed at E_CLIENT_HOOK_MOVE callback
2441 // at e_focus_policy_topmost.c and at e_focus_policy_history.c
2443 wl_signal_emit_mutable(&PRI(ec)->events.move, NULL);
2448 zone = e_comp_zone_find_by_ec(ec);
2449 if (zone && !E_INTERSECTS(ec->x, ec->y, ec->w, ec->h,
2450 zone->x, zone->y, zone->w, zone->h))
2452 e_client_revert_focus(ec);
2457 e_comp_visibility_calculation_set(EINA_TRUE);
2461 _e_client_cb_evas_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2463 E_Client *ec = data;
2464 Evas_Coord x, y, w, h;
2466 if (e_object_is_del(data)) return;
2468 ec->pre_res_change.valid = 0;
2470 _e_client_event_simple(ec, E_EVENT_CLIENT_RESIZE);
2472 #ifdef REFACTOR_ZONE_DESK
2474 _e_client_zone_update(ec);
2476 evas_object_geometry_get(ec->frame, &x, &y, &w, &h);
2477 if ((e_config->transient.resize) && (ec->transients))
2479 Eina_List *list = eina_list_clone(ec->transients);
2482 EINA_LIST_FREE(list, child)
2484 Evas_Coord nx, ny, nw, nh;
2486 if ((ec->pre_cb.w > 0) && (ec->pre_cb.h > 0))
2488 nx = x + (((child->x - x) * w) / ec->pre_cb.w);
2489 ny = y + (((child->y - y) * h) / ec->pre_cb.h);
2490 nw = (child->w * w) / ec->pre_cb.w;
2491 nh = (child->h * h) / ec->pre_cb.h;
2492 nx += ((nw - child->w) / 2);
2493 ny += ((nh - child->h) / 2);
2494 evas_object_move(child->frame, nx, ny);
2499 if (e_client_util_resizing_get(ec) || (ecresize == ec))
2501 wl_signal_emit_mutable(&PRI(ec)->events.move_resize_update, NULL);
2502 _e_client_hook_call(E_CLIENT_HOOK_RESIZE_UPDATE, ec);
2504 ec->pre_cb.w = w; ec->pre_cb.h = h;
2506 e_client_transform_core_update(ec);
2507 e_comp_visibility_calculation_set(EINA_TRUE);
2511 _e_client_cb_evas_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2513 E_Client *ec = data;
2515 if (e_object_is_del(data)) return;
2517 _e_client_transform_core_activate_set(ec, EINA_TRUE);
2519 _e_client_event_show(ec);
2524 _e_client_cb_evas_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2526 E_Client *ec = data;
2527 E_Comp_Wl_Client_Data *child_cdata = NULL;
2529 if (e_object_is_del(data)) return;
2530 if (ec->layer_block) return;
2531 if (ec->layer_pending) return;
2532 if (e_config->transient.raise && ec->transients)
2534 Eina_List *list = eina_list_clone(ec->transients);
2535 E_Client *child, *below = NULL, *above = NULL;
2536 E_Transient transient_policy;
2538 E_LIST_REVERSE_FREE(list, child)
2540 child_cdata = e_client_cdata_get(child);
2541 if (child_cdata && !child_cdata->mapped)
2543 ELOGF("COMP", "STACK CHANGE CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", ec, child, e_client_util_win_get(child));
2547 /* Don't stack iconic transients. If the user wants these shown,
2548 * that's another option.
2550 if (child->iconic && e_client_is_iconified_by_client(child)) continue;
2552 transient_policy = e_client_transient_policy_get(child);
2553 if (transient_policy == E_TRANSIENT_ABOVE)
2556 e_client_stack_below(child, below);
2558 e_client_stack_above(child, ec);
2561 else if (transient_policy == E_TRANSIENT_BELOW)
2564 e_client_stack_below(child, above);
2566 e_client_stack_below(child, ec);
2572 if (ec->unredirected_single) return;
2573 _e_client_event_simple(ec, E_EVENT_CLIENT_STACK);
2575 e_comp_visibility_calculation_set(EINA_TRUE);
2578 ////////////////////////////////////////////////
2580 #ifdef REFACTOR_ZONE_DESK
2583 _e_client_maximize(E_Client *ec, E_Maximize max)
2585 int x1, yy1, x2, y2;
2588 int ecx, ecy, ecw, ech;
2589 int desk_x, desk_y, desk_w, desk_h;
2590 Eina_Bool override = ec->maximize_override;
2593 zx = zy = zw = zh = 0;
2594 ec->maximize_override = 1;
2596 zone = e_comp_zone_find_by_ec(ec);
2599 if (ec->desk_area.enable && ec->desk_area.desk_area)
2601 desk_x = ec->desk_area.desk_area->x;
2602 desk_y = ec->desk_area.desk_area->y;
2603 desk_w = ec->desk_area.desk_area->w;
2604 desk_h = ec->desk_area.desk_area->h;
2608 desk_x = ec->desk->geom.x;
2609 desk_y = ec->desk->geom.y;
2610 desk_w = ec->desk->geom.w;
2611 desk_h = ec->desk->geom.h;
2614 switch (max & E_MAXIMIZE_TYPE)
2616 case E_MAXIMIZE_NONE:
2620 case E_MAXIMIZE_FULLSCREEN:
2624 e_client_resize_limit(ec, &w, &h);
2625 /* center x-direction */
2626 x1 = desk_x + (desk_w - w) / 2;
2627 /* center y-direction */
2628 yy1 = desk_y + (desk_h - h) / 2;
2630 switch (max & E_MAXIMIZE_DIRECTION)
2632 case E_MAXIMIZE_BOTH:
2633 e_client_maximized_geometry_set(ec, x1, yy1, w, h);
2636 case E_MAXIMIZE_VERTICAL:
2637 e_client_maximized_geometry_set(ec, ec->x, yy1, ec->w, h);
2640 case E_MAXIMIZE_HORIZONTAL:
2641 e_client_maximized_geometry_set(ec, x1, ec->y, w, ec->h);
2644 case E_MAXIMIZE_LEFT:
2645 e_client_maximized_geometry_set(ec, desk_x, desk_y, w / 2, h);
2648 case E_MAXIMIZE_RIGHT:
2649 e_client_maximized_geometry_set(ec, x1, desk_y, w / 2, h);
2654 case E_MAXIMIZE_SMART:
2655 case E_MAXIMIZE_EXPAND:
2656 if (ec->desk->visible)
2658 // base_output_resolution
2659 if (ec->base_output_resolution.use)
2663 zw = ec->base_output_resolution.w;
2664 zh = ec->base_output_resolution.h;
2668 e_zone_desk_useful_geometry_get(zone, ec->desk, &zx, &zy, &zw, &zh, EINA_TRUE);
2675 x2 = desk_x + desk_w;
2676 y2 = desk_y + desk_h;
2677 e_maximize_client_shelf_fill(ec, &x1, &yy1, &x2, &y2, max);
2684 evas_object_smart_callback_call(ec->frame, "maximize", NULL);
2685 e_comp_object_frame_xy_unadjust(ec->frame, ec->x, ec->y, &ecx, &ecy);
2686 e_comp_object_frame_wh_unadjust(ec->frame, ec->w, ec->h, &ecw, &ech);
2694 if (ecx < zx) // window left not useful coordinates
2696 else if (ecx + ecw > zx + zw) // window right not useful coordinates
2698 else // window normal position
2701 if (ecy < zy) // window top not useful coordinates
2703 else if (ecy + ech > zy + zh) // window bottom not useful coordinates
2704 yy1 = zy + zh - ech;
2705 else // window normal position
2708 switch (max & E_MAXIMIZE_DIRECTION)
2710 case E_MAXIMIZE_BOTH:
2711 e_client_maximized_geometry_set(ec, zx, zy, zw, zh);
2714 case E_MAXIMIZE_VERTICAL:
2715 e_client_maximized_geometry_set(ec, ec->x, zy, ec->w, zh);
2718 case E_MAXIMIZE_HORIZONTAL:
2719 e_client_maximized_geometry_set(ec, zx, ec->y, zw, ec->h);
2722 case E_MAXIMIZE_LEFT:
2723 e_client_maximized_geometry_set(ec, zx, zy, zw / 2, zh);
2726 case E_MAXIMIZE_RIGHT:
2727 e_client_maximized_geometry_set(ec, zx + zw / 2, zy, zw / 2, zh);
2733 case E_MAXIMIZE_FILL:
2736 x2 = desk_x + desk_w;
2737 y2 = desk_y + desk_h;
2739 /* walk through all shelves */
2740 e_maximize_client_shelf_fill(ec, &x1, &yy1, &x2, &y2, max);
2742 /* walk through all windows */
2743 e_maximize_client_client_fill(ec, &x1, &yy1, &x2, &y2, max);
2749 e_client_resize_limit(ec, &w, &h);
2750 /* center x-direction */
2751 x1 = x1 + (pw - w) / 2;
2752 /* center y-direction */
2753 yy1 = yy1 + (ph - h) / 2;
2755 switch (max & E_MAXIMIZE_DIRECTION)
2757 case E_MAXIMIZE_BOTH:
2758 e_client_maximized_geometry_set(ec, x1, yy1, w, h);
2761 case E_MAXIMIZE_VERTICAL:
2762 e_client_maximized_geometry_set(ec, ec->x, yy1, ec->w, h);
2765 case E_MAXIMIZE_HORIZONTAL:
2766 e_client_maximized_geometry_set(ec, x1, ec->y, w, ec->h);
2769 case E_MAXIMIZE_LEFT:
2770 e_client_maximized_geometry_set(ec, desk_x, desk_y, w / 2, h);
2773 case E_MAXIMIZE_RIGHT:
2774 e_client_maximized_geometry_set(ec, x1, desk_y, w / 2, h);
2779 if (ec->maximize_override)
2780 ec->maximize_override = override;
2784 ////////////////////////////////////////////////
2786 _e_client_aux_hint_eval(E_Client *ec)
2790 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
2792 E_Comp_Wl_Aux_Hint *hint;
2794 if (cdata && cdata->aux_hint.changed)
2796 wl_signal_emit_mutable(&PRI(ec)->events.aux_hint_change, NULL);
2797 _e_client_hook_call(E_CLIENT_HOOK_AUX_HINT_CHANGE, ec);
2799 EINA_LIST_FOREACH_SAFE(cdata->aux_hint.hints, l, ll, hint)
2801 hint->changed = EINA_FALSE;
2804 ELOGF("COMP", "AUX_HINT |Del [%d:%s:%s]", ec, hint->id, hint->hint, hint->val);
2805 if (hint->hint) eina_stringshare_del(hint->hint);
2806 if (hint->val) eina_stringshare_del(hint->val);
2807 cdata->aux_hint.hints = eina_list_remove_list(cdata->aux_hint.hints, l);
2811 cdata->aux_hint.changed = 0;
2815 #ifdef REFACTOR_ZONE_DESK
2818 _e_client_apply_auto_placement(E_Client *ec)
2820 Eina_List *skiplist = NULL;
2821 int new_x, new_y, t = 0;
2823 E_Client *parent_ec;
2826 // intercept auto placement policy
2827 if (!_e_client_intercept_hook_call(E_CLIENT_INTERCEPT_HOOK_AUTO_PLACEMENT, ec))
2829 ELOGF("POL", "Intercepted auto_placement policy.", ec);
2833 int zx = 0, zy = 0, zw = 0, zh = 0;
2835 zone = e_comp_zone_find_by_ec(ec);
2838 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
2840 unsigned int seed = (unsigned int)time(NULL);
2843 new_x = zx + (rand_r(&seed) % (zw - ec->w));
2847 new_y = zy + (rand_r(&seed) % (zh - ec->h));
2851 e_comp_object_frame_geometry_get(ec->frame, NULL, NULL, &t, NULL);
2853 parent_ec = ec->parent;
2857 new_x = parent_ec->x;
2858 new_y = parent_ec->y;
2860 else if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
2863 skiplist = eina_list_append(skiplist, ec);
2865 e_place_desk_region_smart(ec->desk, skiplist,
2866 ec->x, ec->y, ec->w, ec->h,
2869 e_place_zone_region_smart(zone, skiplist,
2870 ec->x, ec->y, ec->w, ec->h,
2873 eina_list_free(skiplist);
2875 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
2878 e_place_zone_manual(zone, ec->w, t, &new_x, &new_y);
2883 e_place_zone_cursor(zone, ec->x, ec->y, ec->w, ec->h,
2887 ELOGF("POL", "Apply auto placement (type:%d). (%d,%d) -> (%d,%d).", ec, type, ec->x, ec->y, new_x, new_y);
2888 e_client_pos_set(ec, new_x, new_y);
2889 ec->changes.pos = 1;
2891 ec->pre_cb.x = ec->x; ec->pre_cb.y = ec->y;
2896 _e_client_eval(E_Client *ec)
2899 unsigned int prop = 0;
2900 #ifdef REFACTOR_ZONE_DESK
2908 if (e_object_is_del(E_OBJECT(ec)))
2910 CRI("_e_client_eval(%p) with deleted border! - %d\n", ec, ec->new_client);
2915 TRACE_DS_BEGIN(CLIENT:EVAL);
2917 wl_signal_emit_mutable(&PRI(ec)->events.eval_pre_new_client, NULL);
2918 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_NEW_CLIENT, ec))
2924 #ifdef REFACTOR_ZONE_DESK
2925 if ((ec->new_client) && (!e_client_util_ignored_get(ec)))
2927 wl_signal_emit_mutable(&PRI(ec)->events.eval_post_new_client, NULL);
2928 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_POST_NEW_CLIENT, ec))
2935 zone = e_comp_zone_find_by_ec(ec);
2936 if ((ec->new_client) && (!e_client_util_ignored_get(ec)) && (zone))
2938 int zx = 0, zy = 0, zw = 0, zh = 0;
2940 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
2941 /* enforce wm size hints for initial sizing */
2942 if (e_config->screen_limits == E_CLIENT_OFFSCREEN_LIMIT_ALLOW_NONE)
2944 tw = MIN(ec->w, zone->w);
2945 th = MIN(ec->h, zone->h);
2946 e_client_size_set(ec, tw, th);
2951 e_client_resize_limit(ec, &nw, &nh);
2952 e_client_size_set(ec, nw, nh);
2956 int x = ec->x, y = ec->y;
2957 if (ec->x) e_comp_object_frame_xy_adjust(ec->frame, ec->x, 0, &ec->x, NULL);
2958 if (ec->y) e_comp_object_frame_xy_adjust(ec->frame, 0, ec->y, NULL, &ec->y);
2959 if ((x != ec->x) || (y != ec->y)) ec->changes.pos = 1;
2961 ec->pre_cb.x = ec->x; ec->pre_cb.y = ec->y;
2967 tx = zx + ((zw - ec->w) / 2);
2968 ty = zy + ((zh - ec->h) / 2);
2969 e_client_pos_set(ec, tx, ty);
2971 ec->changes.pos = 1;
2973 ec->pre_cb.x = ec->x; ec->pre_cb.y = ec->y;
2978 eai = e_appinfo_find_with_pid(ec->netwm.pid);
2982 _e_client_apply_auto_placement(ec);
2986 if (e_appinfo_auto_placement_get(eai))
2987 _e_client_apply_auto_placement(ec);
2990 /* Recreate state */
2991 if (ec->e.state.centered)
2993 tx = zx + (zw - ec->w) / 2;
2994 ty = zy + (zh - ec->h) / 2;
2995 e_client_pos_set(ec, tx, ty);
2996 ec->changes.pos = 1;
2999 /* if the explicit geometry request asks for the app to be
3000 * in another zone - well move it there */
3002 E_Zone *zone1 = NULL;
3007 if ((!ec->re_manage) && ((ec->x != x) || (ec->y != y)))
3008 zone1 = e_comp_zone_xy_get(x, y);
3012 zone1 = e_comp_zone_xy_get(ec->x + (ec->w / 2), ec->y + (ec->h / 2));
3015 E_Zone *z2 = e_comp_zone_xy_get(ec->x, ec->y);
3017 if (z2 && (z2 != zone1))
3023 EINA_LIST_FOREACH(e_comp->zones, l, z2)
3027 x = ec->x, y = ec->y, w = ec->w, h = ec->h;
3028 E_RECTS_CLIP_TO_RECT(x, y, w, h, z2->x, z2->y, z2->w, z2->h);
3029 if (w * h == z2->w * z2->h)
3031 /* client fully covering zone */
3035 if ((unsigned)(w * h) > psz)
3046 zone1 = e_comp_zone_xy_get(ec->x, ec->y);
3048 zone1 = e_comp_zone_xy_get(ec->x + ec->w - 1, ec->y);
3050 zone1 = e_comp_zone_xy_get(ec->x + ec->w - 1, ec->y + ec->h - 1);
3052 zone1 = e_comp_zone_xy_get(ec->x, ec->y + ec->h - 1);
3053 if ((zone1) && (zone1 != zone))
3054 e_client_zone_set(ec, zone1);
3058 wl_signal_emit_mutable(&PRI(ec)->events.eval_post_new_client, NULL);
3059 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_POST_NEW_CLIENT, ec))
3066 /* effect changes to the window border itself */
3067 if ((ec->changes.shading))
3069 /* show at start of unshade (but don't hide until end of shade) */
3070 ec->changes.shading = 0;
3073 if (ec->changes.shaded) send_event = 0;
3074 if ((ec->changes.shaded) && (ec->changes.pos) && (ec->changes.size))
3076 ec->changes.shaded = 0;
3078 else if ((ec->changes.shaded) && (ec->changes.pos))
3080 ec->changes.size = 1;
3081 ec->changes.shaded = 0;
3083 else if ((ec->changes.shaded) && (ec->changes.size))
3085 ec->changes.shaded = 0;
3087 else if (ec->changes.shaded)
3089 ec->changes.shaded = 0;
3092 if (ec->changes.size)
3094 ec->changes.size = 0;
3095 if ((!ec->shaded) && (!ec->shading))
3096 evas_object_resize(ec->frame, ec->w, ec->h);
3098 prop |= E_CLIENT_PROPERTY_SIZE;
3100 if (ec->changes.pos)
3102 ec->changes.tz_position = 0;
3103 ec->changes.pos = 0;
3104 evas_object_move(ec->frame, ec->x, ec->y);
3105 prop |= E_CLIENT_PROPERTY_POS;
3108 if (ec->changes.reset_gravity)
3110 ec->changes.reset_gravity = 0;
3111 prop |= E_CLIENT_PROPERTY_GRAVITY;
3114 if (ec->changes.title)
3116 ec->changes.title = 0;
3117 prop |= E_CLIENT_PROPERTY_TITLE;
3120 if ((ec->changes.visible) && (ec->visible) && (ec->new_client) && (!ec->iconic))
3124 e_input_device_pointer_xy_get(NULL, &x, &y);
3125 if ((!ec->placed) && (!ec->re_manage) &&
3126 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
3127 (!((ec->icccm.transient_for != 0) ||
3129 (!ecmove) && (!ecresize))
3131 /* Set this window into moving state */
3133 ec->cur_mouse_action = e_action_find("window_move");
3134 if (ec->cur_mouse_action)
3136 if ((!ec->cur_mouse_action->func.end_mouse) &&
3137 (!ec->cur_mouse_action->func.end))
3138 ec->cur_mouse_action = NULL;
3139 if (ec->cur_mouse_action)
3142 tx = x - (ec->w >> 1);
3143 e_comp_object_frame_geometry_get(ec->frame, NULL, NULL, &t, NULL);
3145 e_client_pos_set(ec, tx, ty);
3147 ec->changes.pos = 1;
3152 evas_object_show(ec->frame);
3153 if (evas_object_visible_get(ec->frame))
3155 #ifdef REFACTOR_FOCUS_POLICY
3156 // It is useless, Nothing to do.
3158 if (ec->cur_mouse_action)
3160 ec->moveinfo.down.x = ec->x;
3161 ec->moveinfo.down.y = ec->y;
3162 ec->moveinfo.down.w = ec->w;
3163 ec->moveinfo.down.h = ec->h;
3164 ec->mouse.current.mx = x;
3165 ec->mouse.current.my = y;
3166 ec->moveinfo.down.button = 0;
3167 ec->moveinfo.down.mx = x;
3168 ec->moveinfo.down.my = y;
3170 e_object_ref(E_OBJECT(ec->cur_mouse_action));
3171 ec->cur_mouse_action->func.go(E_OBJECT(ec), NULL);
3172 if (e_config->border_raise_on_mouse_action)
3174 if (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK)
3176 ELOGF("FOCUS", "focus set | client eval", ec);
3177 e_client_frame_focus_set(ec, EINA_TRUE);
3181 ec->changes.visible = 0;
3182 _e_client_event_show(ec);
3185 else if ((ec->changes.visible) && (ec->new_client))
3187 ec->changes.visible = 0;
3189 _e_client_event_hide(ec);
3192 if (ec->changes.icon)
3194 ec->changes.icon = 0;
3198 e_comp->new_clients--;
3200 ec->changed = ec->changes.pos || ec->changes.size ||
3201 ec->changes.stack || ec->changes.prop || ec->changes.border ||
3202 ec->changes.reset_gravity || ec->changes.shading || ec->changes.shaded ||
3203 ec->changes.shape || ec->changes.shape_input || ec->changes.icon ||
3204 ec->changes.internal_state ||
3205 ec->changes.need_maximize || ec->changes.need_unmaximize;
3206 ec->changes.stack = 0;
3208 #ifdef REFACTOR_FOCUS_POLICY
3209 // This code executes at E_CLIENT_HOOK_EVAL_END callback at e_focus_policy_topmost.c and e_focus_policy_history.c
3211 zone = e_comp_zone_find_by_ec(ec);
3212 if ((!ec->input_only) && (!ec->iconic) &&
3213 ((!zone) || e_desk_has_ec(e_desk_current_get(zone), ec)) &&
3214 ((ec->take_focus) || (ec->want_focus)))
3220 #if 0 // focus should be set to the top window
3221 e_client_focus_set_with_pointer(ec);
3226 /* focus window by default when it is the only one on desk */
3227 E_Client *ec2 = NULL;
3230 desk = e_zone_desk_find_by_ec(zone, ec);
3231 EINA_LIST_FOREACH(focus_stack, l, ec2)
3233 if (ec == ec2) continue;
3234 if ((!ec2->iconic) && (ec2->visible) &&
3235 ((e_desk_has_ec(desk, ec2)) || ec2->sticky))
3241 e_client_focus_set_with_pointer(ec);
3246 ec->take_focus = ec->want_focus = 0;
3249 if (ec->changes.need_maximize)
3251 E_Maximize max = ec->maximized;
3252 ec->maximized = E_MAXIMIZE_NONE;
3253 e_client_maximize(ec, max);
3254 ec->changes.need_maximize = 0;
3256 else if (ec->changes.need_unmaximize)
3258 e_client_unmaximize(ec, ec->maximized);
3259 ec->changes.need_unmaximize = 0;
3262 if (ec->need_fullscreen)
3264 e_client_fullscreen(ec, e_config->fullscreen_policy);
3265 ec->need_fullscreen = 0;
3268 if (ec->changes.accepts_focus)
3270 if ((!ec->icccm.accepts_focus) && (!ec->icccm.take_focus))
3273 ec->changes.accepts_focus = 0;
3277 if (send_event && prop)
3279 _e_client_event_property(ec, prop);
3282 _e_client_aux_hint_eval(ec);
3284 e_client_transform_core_update(ec);
3286 wl_signal_emit_mutable(&PRI(ec)->events.eval_end, NULL);
3287 _e_client_hook_call(E_CLIENT_HOOK_EVAL_END, ec);
3292 #ifdef REFACTOR_ZONE_DESK
3294 e_client_frame_update(E_Client *ec)
3297 _e_client_frame_update(E_Client *ec)
3300 const char *bordername;
3302 #ifdef REFACTOR_ZONE_DESK
3303 EINA_SAFETY_ON_NULL_RETURN(ec);
3304 if (e_object_is_del(E_OBJECT(ec))) return;
3307 ec->border.changed = 0;
3308 if (!e_comp_object_frame_allowed(ec->frame)) return;
3309 if (ec->fullscreen || ec->borderless)
3310 bordername = "borderless";
3311 else if (ec->bordername)
3312 bordername = ec->bordername;
3313 else if (ec->mwm.borderless)
3314 bordername = "borderless";
3315 else if (((ec->icccm.transient_for != 0) || (ec->dialog)) &&
3316 (ec->icccm.min_w == ec->icccm.max_w) &&
3317 (ec->icccm.min_h == ec->icccm.max_h))
3318 bordername = "noresize_dialog";
3319 else if ((ec->icccm.min_w == ec->icccm.max_w) &&
3320 (ec->icccm.min_h == ec->icccm.max_h))
3321 bordername = "noresize";
3322 else if (ec->shaped)
3323 bordername = "shaped";
3324 else if (ec->urgent)
3325 bordername = "urgent";
3326 else if (ec->netwm.state.modal)
3327 bordername = "modal";
3328 else if ((ec->netwm.state.skip_taskbar) ||
3329 (ec->netwm.state.skip_pager))
3330 bordername = "skipped";
3332 else if ((ec->internal) && (ec->icccm.class) &&
3333 (!strncmp(ec->icccm.class, "e_fwin", 6)))
3334 bordername = "internal_fileman";
3337 bordername = e_config->theme_default_border_style;
3338 if (!bordername) bordername = "default";
3340 e_client_border_set(ec, bordername);
3344 _e_client_type_match(E_Client *ec, E_Config_Client_Type *m)
3346 if (!ec || !m) return EINA_FALSE;
3347 if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
3349 if ((int)ec->netwm.type != m->window_type)
3352 #if defined(__cplusplus) || defined(c_plusplus)
3355 if (!ec->icccm.cpp_class)
3358 if (!e_util_glob_match(ec->icccm.cpp_class, m->clas))
3364 if (!ec->icccm.class)
3367 if (!e_util_glob_match(ec->icccm.class, m->clas))
3374 if (ec->icccm.name && e_util_glob_match(ec->icccm.name, m->name))
3377 if (ec->icccm.title && e_util_glob_match(ec->icccm.title, m->name))
3380 if (ec->netwm.name && e_util_glob_match(ec->netwm.name, m->name))
3388 e_client_type_update(E_Client *ec)
3390 E_Config_Client_Type *m;
3394 if (!e_config->client_types) return 0;
3396 EINA_LIST_FOREACH(e_config->client_types, l, m)
3398 if (!_e_client_type_match(ec, m)) continue;
3401 type = m->client_type;
3406 if (ec->client_type != type)
3408 ec->client_type = type;
3409 _e_client_event_property(ec, E_CLIENT_PROPERTY_CLIENT_TYPE);
3412 return ec->client_type;
3416 _e_client_transform_sub_apply(E_Client *ec, E_Client *epc, double zoom)
3418 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
3422 int ox = 0, oy = 0, ow, oh;
3426 EINA_SAFETY_ON_FALSE_RETURN(e_comp_wl_subsurface_check(ec));
3428 e_comp_wl_subsurface_position_get(ec, &ox, &oy);
3429 ow = cdata->width_from_viewport;
3430 oh = cdata->height_from_viewport;
3432 map = e_client_map_get(epc);
3433 e_map_point_coord_get(map, 0, &px, &py, 0);
3436 mx = ox * zoom + px;
3437 my = oy * zoom + py;
3441 map = e_map_new_with_direct_render(ec->transform_core.direct_render);
3442 e_map_util_points_populate_from_geometry(map, mx, my, mw, mh, 0);
3443 e_map_util_object_move_sync_set(map, EINA_TRUE);
3444 e_client_map_set(ec, map);
3445 e_client_map_enable_set(ec, EINA_TRUE);
3447 EINA_LIST_FOREACH(cdata->sub.list, l, subc)
3448 _e_client_transform_sub_apply(subc, ec, zoom);
3449 EINA_LIST_REVERSE_FOREACH(cdata->sub.below_list, l, subc)
3450 _e_client_transform_sub_apply(subc, ec, zoom);
3456 _e_client_transient_for_group_make(E_Client *ec, Eina_List **list)
3462 if (!e_config->transient.raise) return;
3464 EINA_LIST_FOREACH(ec->transients, l, child)
3466 if (!child) continue;
3467 if (child->iconic) continue;
3468 if (e_client_transient_policy_get(child) == E_TRANSIENT_ABOVE)
3470 *list = eina_list_prepend(*list, child);
3471 _e_client_transient_for_group_make(child, list);
3477 e_client_transient_child_top_get(E_Client *ec, Eina_Bool consider_focus)
3479 E_Client *top_ec = NULL;
3480 Eina_List *transient_list = NULL;
3482 _e_client_transient_for_group_make(ec, &transient_list);
3486 Eina_List *l = NULL;
3487 E_Client *temp_ec = NULL;
3488 E_Client *temp_ec2 = NULL;
3490 E_CLIENT_REVERSE_FOREACH(temp_ec)
3499 EINA_LIST_FOREACH(transient_list, l, temp_ec2)
3501 if (temp_ec == temp_ec2)
3505 if ((temp_ec2->icccm.accepts_focus) ||
3506 (temp_ec2->icccm.take_focus))
3519 eina_list_free(transient_list);
3524 #ifdef EC_IS_NOT_VISIBLE
3525 # undef EC_IS_NOT_VISIBLE
3527 #define EC_IS_NOT_VISIBLE if (ec->visibility.obscured != E_VISIBILITY_UNOBSCURED)
3530 e_client_visibility_touched_check(E_Client *ec)
3534 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
3536 tx = wl_fixed_to_int(e_comp->wl_comp_data->ptr.x);
3537 ty = wl_fixed_to_int(e_comp->wl_comp_data->ptr.y);
3539 return _e_client_position_inside_input_rect(ec, tx, ty);
3543 e_client_visibility_change_notify(E_Client *ec)
3545 EINA_SAFETY_ON_NULL_RETURN(ec);
3547 if (ec->visibility.changed)
3548 _e_client_event_simple(ec, E_EVENT_CLIENT_VISIBILITY_CHANGE);
3550 wl_signal_emit_mutable(&PRI(ec)->events.eval_visibility, NULL);
3551 _e_client_hook_call(E_CLIENT_HOOK_EVAL_VISIBILITY, ec);
3555 e_client_visibility_end_notify(void)
3557 // FIXME: This hook means that the visiblitiy calculation of a zone is done
3558 // at this idle handler.This is a hook for a zone, not for a client.
3559 // Therefore, this hook may be defined as a zone hook,
3560 // ex) E_ZONE_HOOK_EVAL_VISIBILITY_END or E_ZONE_HOOK_EVAL_VISIBILITY_DONE.
3561 _e_client_hook_call(E_CLIENT_HOOK_EVAL_VISIBILITY_END, NULL);
3564 #ifdef REFACTOR_FOCUS_POLICY
3567 _e_client_merge_focus_stack_with_defer_focus(void)
3569 Eina_List *l = NULL;
3570 E_Client *ec = NULL, *defer_ec = NULL;
3571 Eina_Bool find_rel = EINA_FALSE;
3572 Eina_Bool inserted = EINA_FALSE;
3574 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK) return;
3578 focus_stack = eina_list_merge(focus_stack, defer_focus_stack);
3582 E_CLIENT_FOREACH(defer_ec)
3584 if (!eina_list_data_find(defer_focus_stack, defer_ec)) continue;
3586 find_rel = EINA_FALSE;
3587 inserted = EINA_FALSE;
3588 focus_stack = eina_list_remove(focus_stack, defer_ec);
3590 EINA_LIST_FOREACH(focus_stack, l, ec)
3592 if (ec == NULL) continue;
3597 find_rel = EINA_TRUE;
3601 if (ec->layer > defer_ec->layer) continue;
3603 focus_stack = eina_list_prepend_relative_list(focus_stack, defer_ec, l);
3604 inserted = EINA_TRUE;
3609 focus_stack = eina_list_append(focus_stack, defer_ec);
3613 defer_focus_stack = eina_list_free(defer_focus_stack);
3618 _e_client_candidate_focus(E_Zone *zone, E_Client *reverted_focus_ec)
3621 E_Client *defered_focus_ec = NULL;
3622 Eina_List *child_list = NULL;
3623 Eina_List *l = NULL;
3624 Eina_Bool child_deferred;
3627 E_CLIENT_REVERSE_FOREACH(ec)
3629 if (!eina_list_data_find(defer_focus_stack, ec)) continue;
3631 if (e_object_is_del(E_OBJECT(ec))) continue;
3632 if (e_client_util_ignored_get(ec)) continue;
3633 if (!e_zone_has_ec(zone, ec)) continue;
3634 desk = e_desk_current_get(zone);
3635 if (!desk) continue;
3636 if (!e_desk_has_ec(desk, ec)) continue;
3638 if (!(ec->icccm.accepts_focus || ec->icccm.take_focus)) continue;
3639 if (ec->lock_focus_in || ec->lock_focus_out) continue;
3640 if (!evas_object_visible_get(ec->frame)) continue;
3641 if (ec->iconic) continue;
3642 if (ec->bg_state) continue;
3644 if (!(cec = e_client_check_obscured_by_children_group(ec)) ||
3645 e_client_check_really_iconified(cec))
3647 if (ec->visibility.obscured != E_VISIBILITY_UNOBSCURED) continue;
3648 if (e_client_check_fully_contain_by_above(ec, EINA_FALSE)) continue;
3651 if (focused && (focused->layer > ec->layer)) continue;
3652 else if (!focused && reverted_focus_ec && (reverted_focus_ec->layer > ec->layer)) continue;
3654 // check transient_for child defered
3655 child_deferred = EINA_FALSE;
3656 child_list = eina_list_clone(ec->transients);
3657 EINA_LIST_FOREACH(child_list, l, cec)
3659 if (e_client_transient_policy_get(cec) == E_TRANSIENT_BELOW) continue;
3660 if (!(cec->icccm.accepts_focus || cec->icccm.take_focus)) continue;
3661 if (eina_list_data_find(defer_focus_stack, cec))
3663 child_deferred = EINA_TRUE;
3667 eina_list_free(child_list);
3668 if (child_deferred) continue;
3670 defered_focus_ec = ec;
3673 return defered_focus_ec;
3677 e_client_focus_calculate(E_Zone *zone)
3679 E_Client *defered_focus_ec = NULL, *reverted_focus_ec = NULL;
3680 E_Client *ec = NULL, *old_focused = NULL;
3682 EINA_SAFETY_ON_NULL_RETURN(zone);
3683 if (!e_zone_is_displaying(zone)) return;
3685 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK)
3687 ec = _e_client_focus_topmost_focusable_get();
3691 if (!ec) ELOGF("FOCUS", "focus unset | No focusable ec", focused);
3692 e_client_frame_focus_set(focused, EINA_FALSE);
3696 ELOGF("FOCUS", "focus set | topmost focus calculate", ec);
3697 e_client_frame_focus_set(ec, EINA_TRUE);
3704 (focused != eina_list_data_get(focus_stack)) ||
3705 (!_e_client_focus_can_take(focused)))
3707 reverted_focus_ec = _e_client_revert_focus_get(focused);
3708 if (!reverted_focus_ec && focused)
3710 e_client_focus_defer_unset(focused);
3711 old_focused = focused;
3715 defered_focus_ec = _e_client_candidate_focus(zone, reverted_focus_ec);
3717 if (defered_focus_ec)
3719 if (defered_focus_ec != focused)
3721 ELOGF("FOCUS", "focus set | focus calculate (defer_focus)", defered_focus_ec);
3723 e_client_focus_defer_unset(focused);
3724 e_client_frame_focus_set(defered_focus_ec, EINA_TRUE);
3727 e_client_focus_defer_unset(defered_focus_ec);
3729 _e_client_merge_focus_stack_with_defer_focus();
3731 else if(reverted_focus_ec)
3733 if (reverted_focus_ec != focused)
3735 ELOGF("FOCUS", "focus set | focus calculate (revert_focus)", reverted_focus_ec);
3737 e_client_focus_defer_unset(focused);
3738 e_client_frame_focus_set(reverted_focus_ec, EINA_TRUE);
3741 else if (old_focused)
3743 ELOGF("FOCUS", "focus unset | focus calculate", old_focused);
3744 e_client_frame_focus_set(old_focused, EINA_FALSE);
3752 _e_client_transform_core_check_change(E_Client *ec)
3756 Eina_Bool check = EINA_FALSE;
3757 if (!ec) return EINA_FALSE;
3760 evas_object_geometry_get(ec->frame, 0, 0, &w, &h);
3762 // check client position or size change
3763 if (ec->x != ec->transform_core.backup.client_x ||
3764 ec->y != ec->transform_core.backup.client_y ||
3765 ec->w != ec->transform_core.backup.client_w ||
3766 ec->h != ec->transform_core.backup.client_h ||
3767 w != ec->transform_core.backup.frame_w ||
3768 h != ec->transform_core.backup.frame_h ||
3769 ec->argb != ec->transform_core.backup.argb)
3772 ec->transform_core.backup.client_x = ec->x;
3773 ec->transform_core.backup.client_y = ec->y;
3774 ec->transform_core.backup.client_w = ec->w;
3775 ec->transform_core.backup.client_h = ec->h;
3776 ec->transform_core.backup.frame_w = w;
3777 ec->transform_core.backup.frame_h = h;
3778 ec->transform_core.backup.argb = ec->argb;
3781 // check new transform or del transform
3782 if (ec->transform_core.changed)
3785 ec->transform_core.changed = EINA_FALSE;
3788 // check each transform change
3789 if (ec->transform_core.transform_list)
3793 E_Util_Transform *transform;
3795 EINA_LIST_FOREACH_SAFE(ec->transform_core.transform_list, l, l_next, transform)
3797 // del transform check
3798 if (e_util_transform_ref_count_get(transform) <= 1)
3800 ec->transform_core.transform_list = eina_list_remove(ec->transform_core.transform_list, transform);
3801 e_util_transform_unref(transform);
3806 // transform change test
3807 if (e_util_transform_change_get(transform))
3810 e_util_transform_change_unset(transform);
3815 if (e_comp_wl_subsurface_check(ec))
3817 // check parent matrix change
3818 E_Client *parent = e_comp_wl_subsurface_parent_get(ec);
3819 if (parent && parent->transform_core.result.enable)
3821 ec->transform_core.parent.enable = EINA_TRUE;
3823 if (!e_util_transform_matrix_equal_check(&ec->transform_core.parent.matrix,
3824 &parent->transform_core.result.matrix))
3827 ec->transform_core.parent.matrix = parent->transform_core.result.matrix;
3829 if (memcmp(&ec->transform_core.parent.zoom, &parent->transform_core.result.transform.zoom, sizeof(E_Util_Transform_Zoom)) != 0)
3832 ec->transform_core.parent.zoom = parent->transform_core.result.transform.zoom;
3835 else if (ec->transform_core.parent.enable)
3837 ec->transform_core.parent.enable = EINA_FALSE;
3838 e_util_transform_matrix_load_identity(&ec->transform_core.parent.matrix);
3839 ec->transform_core.parent.zoom.zoom_x = 1.0;
3840 ec->transform_core.parent.zoom.zoom_y = 1.0;
3841 ec->transform_core.parent.zoom.cx = 0;
3842 ec->transform_core.parent.zoom.cy = 0;
3851 _e_client_transform_core_boundary_update(E_Client *ec, E_Util_Transform_Rect_Vertex *vertices)
3853 int minx = 99999, miny = 99999;
3854 int maxx = -99999, maxy = -99999;
3859 if (!ec->frame) return;
3860 if (!ec->transform_core.result.enable) return;
3861 if (!vertices) return;
3863 for (i = 0; i < 4; ++i)
3868 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
3870 if (x < minx) minx = x;
3871 if (y < miny) miny = y;
3872 if (x > maxx) maxx = x;
3873 if (y > maxy) maxy = y;
3876 ec->transform_core.result.boundary.x = minx;
3877 ec->transform_core.result.boundary.y = miny;
3878 ec->transform_core.result.boundary.w = maxx - minx;
3879 ec->transform_core.result.boundary.h = maxy - miny;
3881 ELOGF("COMP", "[Transform][boundary][%d %d %d %d]",
3883 ec->transform_core.result.boundary.x,
3884 ec->transform_core.result.boundary.y,
3885 ec->transform_core.result.boundary.w,
3886 ec->transform_core.result.boundary.h);
3890 _e_client_transform_core_map_new(Evas_Object *obj,
3891 E_Util_Transform_Rect_Vertex *vertices,
3892 E_Util_Transform *transform,
3893 Eina_Bool direct_render)
3900 map = e_map_new_with_direct_render(direct_render);
3901 EINA_SAFETY_ON_NULL_RETURN_VAL(map, NULL);
3903 e_map_util_points_populate_from_object_full(map, obj, 0);
3904 e_map_util_points_color_set(map, 255, 255, 255, 255);
3906 for (i = 0 ; i < 4 ; ++i)
3911 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
3912 e_map_point_coord_set(map, i, x, y, 1.0);
3914 if (transform && e_util_transform_texcoord_flag_get(transform))
3919 e_util_transform_texcoord_get(transform, i, &u, &v);
3920 e_map_point_image_uv_set(map, i, u, v);
3928 _e_client_transform_core_vertices_apply_with_zoom(E_Client *ec,
3930 E_Util_Transform_Rect_Vertex *vertices,
3931 E_Util_Transform *transform,
3932 E_Util_Transform_Zoom zoom)
3940 map = _e_client_transform_core_map_new(obj, vertices, transform,
3941 ec->transform_core.direct_render);
3942 EINA_SAFETY_ON_NULL_RETURN(map);
3944 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
3946 e_comp_object_map_set(obj, map);
3948 if (ec->transform_core.activate)
3949 e_comp_object_map_enable_set(obj, EINA_TRUE);
3951 e_comp_object_map_enable_set(obj, EINA_FALSE);
3956 evas_object_map_enable_set(obj, EINA_FALSE);
3960 _e_client_transform_core_vertices_apply(E_Client *ec,
3962 E_Util_Transform_Rect_Vertex *vertices,
3963 E_Util_Transform *transform)
3971 map = _e_client_transform_core_map_new(obj, vertices, transform,
3972 ec->transform_core.direct_render);
3973 EINA_SAFETY_ON_NULL_RETURN(map);
3975 e_comp_object_map_set(obj, map);
3977 if (ec->transform_core.activate)
3978 e_comp_object_map_enable_set(obj, EINA_TRUE);
3980 e_comp_object_map_enable_set(obj, EINA_FALSE);
3985 evas_object_map_enable_set(obj, EINA_FALSE);
3989 _e_client_transform_core_sub_update(E_Client *ec, E_Util_Transform_Rect_Vertex *vertices)
3993 E_Comp_Wl_Client_Data *cdata;
3997 cdata = e_client_cdata_get(ec);
4000 EINA_LIST_FOREACH(cdata->sub.list, l, subc)
4001 e_client_transform_core_update(subc);
4003 EINA_LIST_FOREACH(cdata->sub.below_list, l, subc)
4004 e_client_transform_core_update(subc);
4008 _e_client_cb_hook_shell_surface_ready(void *data EINA_UNUSED, E_Client *ec)
4010 if (EINA_UNLIKELY(!ec))
4013 _e_client_aux_hint_eval(ec);
4016 // FIXME: This function has to be deleted and it remains for the backward compatibility.
4017 // Please find and fix to use e_comp_visibility_calculation_set(EINA_TRUE)
4018 // instead of e_client_visibility_calculate() call at e20 modules.
4020 e_client_visibility_calculate(void)
4022 e_comp_visibility_calculation_set(EINA_TRUE);
4026 e_client_visibility_skip_set(E_Client *ec, Eina_Bool skip)
4030 ELOGF("POL_VIS", "visibility skip set to %d", ec, skip);
4031 ec->visibility.skip = skip;
4035 e_client_post_raise_lower_set(E_Client *ec, Eina_Bool raise_set, Eina_Bool lower_set)
4039 ec->post_raise = raise_set;
4040 ec->post_lower = lower_set;
4044 e_client_first_mapped_get(E_Client *ec)
4046 if (!ec) return EINA_FALSE;
4048 return ec->first_mapped;
4051 EINTERN Eina_Bool e_client_mapped_get(E_Client *ec)
4053 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
4054 EINA_SAFETY_ON_NULL_RETURN_VAL(cdata, EINA_FALSE);
4056 return cdata->mapped;
4060 e_client_mapped_set(E_Client *ec, Eina_Bool set)
4062 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
4063 EINA_SAFETY_ON_NULL_RETURN(cdata);
4065 cdata->mapped = set;
4069 ////////////////////////////////////////////////
4071 e_client_clients_hash_exist()
4075 for (pix_id = 0; pix_id < E_PIXMAP_TYPE_MAX; pix_id++)
4077 if (eina_hash_population(clients_hash[pix_id]))
4085 e_client_idler_before(Eina_Bool *check_focus)
4090 *check_focus = EINA_FALSE;
4092 if (!e_client_clients_hash_exist()) return;
4094 TRACE_DS_BEGIN(CLIENT:IDLE BEFORE);
4096 EINA_LIST_FOREACH(e_comp->clients, l, ec)
4098 // pass 1 - eval0. fetch properties on new or on change and
4099 // call hooks to decide what to do - maybe move/resize
4100 if (ec->ignored || (!ec->changed)) continue;
4102 wl_signal_emit_mutable(&PRI(ec)->events.eval_pre_fetch, NULL);
4103 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_FETCH, ec)) continue;
4106 /* FETCH is hooked by the compositor to get client hints */
4107 wl_signal_emit_mutable(&PRI(ec)->events.eval_fetch, NULL);
4108 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_FETCH, ec)) continue;
4112 e_client_type_update(ec);
4115 /* PRE_POST_FETCH calls e_remember apply for new client */
4116 wl_signal_emit_mutable(&PRI(ec)->events.eval_pre_post_fetch, NULL);
4117 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_POST_FETCH, ec)) continue;
4118 wl_signal_emit_mutable(&PRI(ec)->events.eval_post_fetch, NULL);
4119 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_POST_FETCH, ec)) continue;
4120 wl_signal_emit_mutable(&PRI(ec)->events.eval_pre_frame_assign, NULL);
4121 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_FRAME_ASSIGN, ec)) continue;
4123 wl_signal_emit_mutable(&PRI(ec)->events.eval_post_frame_assign, NULL);
4124 _e_client_hook_call(E_CLIENT_HOOK_EVAL_POST_FRAME_ASSIGN, ec);
4126 // pass 2 - show and hide windows needing hide and eval (main eval)
4127 E_CLIENT_FOREACH(ec)
4129 if (e_object_is_del(E_OBJECT(ec))) continue;
4132 // ignored client but needing eval (aux hint) such as remote surfaces
4135 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
4136 if (cdata && cdata->first_commit)
4137 _e_client_aux_hint_eval(ec);
4142 if (ec->changes.visible)
4146 if ((!ec->new_client) &&
4147 (!ec->changes.pos) &&
4148 (!ec->changes.size))
4150 evas_object_show(ec->frame);
4151 ec->changes.visible = !evas_object_visible_get(ec->frame);
4156 evas_object_hide(ec->frame);
4157 ec->changes.visible = 0;
4164 e_comp_visibility_calculation_set(EINA_TRUE);
4165 if (ec->changes.accepts_focus)
4166 *check_focus = EINA_TRUE;
4167 ec->changes.accepts_focus = 0;
4170 if ((ec->changes.visible) && (ec->visible) && (!ec->changed))
4172 evas_object_show(ec->frame);
4173 ec->changes.visible = !evas_object_visible_get(ec->frame);
4174 ec->changed = ec->changes.visible;
4175 e_comp_visibility_calculation_set(EINA_TRUE);
4187 for (pix_id = 0; pix_id < E_PIXMAP_TYPE_MAX; pix_id++)
4188 clients_hash[pix_id] = eina_hash_pointer_new(NULL);
4190 E_COMP_WL_HOOK_APPEND(hooks, E_COMP_WL_HOOK_SHELL_SURFACE_READY, _e_client_cb_hook_shell_surface_ready, NULL);
4192 #ifdef REFACTOR_FOCUS_POLICY
4194 g_mutex_init(&focused_ec_mutex);
4197 E_EVENT_CLIENT_ADD = ecore_event_type_new();
4198 E_EVENT_CLIENT_REMOVE = ecore_event_type_new();
4199 E_EVENT_CLIENT_DESK_SET = ecore_event_type_new();
4200 E_EVENT_CLIENT_ZONE_SET = ecore_event_type_new();
4201 E_EVENT_CLIENT_RESIZE = ecore_event_type_new();
4202 E_EVENT_CLIENT_MOVE = ecore_event_type_new();
4203 E_EVENT_CLIENT_SHOW = ecore_event_type_new();
4204 E_EVENT_CLIENT_HIDE = ecore_event_type_new();
4205 E_EVENT_CLIENT_ICONIFY = ecore_event_type_new();
4206 E_EVENT_CLIENT_UNICONIFY = ecore_event_type_new();
4207 E_EVENT_CLIENT_STACK = ecore_event_type_new();
4208 E_EVENT_CLIENT_FOCUS_IN = ecore_event_type_new();
4209 E_EVENT_CLIENT_FOCUS_OUT = ecore_event_type_new();
4210 E_EVENT_CLIENT_PROPERTY = ecore_event_type_new();
4211 E_EVENT_CLIENT_FULLSCREEN = ecore_event_type_new();
4212 E_EVENT_CLIENT_UNFULLSCREEN = ecore_event_type_new();
4213 #ifdef _F_ZONE_WINDOW_ROTATION_
4214 E_EVENT_CLIENT_ROTATION_CHANGE_BEGIN = ecore_event_type_new();
4215 E_EVENT_CLIENT_ROTATION_CHANGE_CANCEL = ecore_event_type_new();
4216 E_EVENT_CLIENT_ROTATION_CHANGE_END = ecore_event_type_new();
4217 E_EVENT_CLIENT_ROTATION_GEOMETRY_SET = ecore_event_type_new();
4219 E_EVENT_CLIENT_VISIBILITY_CHANGE = ecore_event_type_new();
4220 E_EVENT_CLIENT_BUFFER_CHANGE = ecore_event_type_new();
4221 E_EVENT_CLIENT_FOCUS_SKIP_SET = ecore_event_type_new();;
4222 E_EVENT_CLIENT_FOCUS_SKIP_UNSET = ecore_event_type_new();;
4224 return (!!clients_hash[1]);
4228 e_client_shutdown(void)
4231 for (pix_id = 0; pix_id < E_PIXMAP_TYPE_MAX; pix_id++)
4232 E_FREE_FUNC(clients_hash[pix_id], eina_hash_free);
4234 E_FREE_LIST(hooks, e_comp_wl_hook_del);
4235 E_FREE_LIST(handlers, ecore_event_handler_del);
4237 #ifdef REFACTOR_FOCUS_POLICY
4239 g_mutex_clear(&focused_ec_mutex);
4244 e_client_unignore(E_Client *ec)
4247 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
4248 if (!ec->ignored) return;
4251 _e_client_event_add(ec);
4255 e_client_new(E_Pixmap *cp, int first_map, int internal)
4260 type = e_pixmap_type_get(cp);
4261 if (type >= E_PIXMAP_TYPE_MAX) return NULL;
4262 if (eina_hash_find(clients_hash[type], &cp)) return NULL;
4264 ec = E_OBJECT_ALLOC(E_Client, E_CLIENT_TYPE, _e_client_free);
4265 if (!ec) return NULL;
4266 e_object_del_func_set(E_OBJECT(ec), E_OBJECT_CLEANUP_FUNC(_e_client_del));
4268 if (!_e_client_private_init(ec))
4270 e_object_del(E_OBJECT(ec));
4274 uuid_generate(ec->uuid);
4276 ec->focus_policy_override = E_FOCUS_LAST;
4277 e_client_size_set(ec, 1, 1);
4278 ec->internal = internal;
4281 e_pixmap_client_set(cp, ec);
4282 ec->resize_mode = E_POINTER_RESIZE_NONE;
4283 ec->layer = E_LAYER_CLIENT_NORMAL;
4284 ec->first_mapped = EINA_FALSE;
4285 ec->post_raise = EINA_TRUE;
4286 ec->post_lower = EINA_FALSE;
4287 ec->animatable = EINA_TRUE;
4288 ec->maximize_type = e_config->maximize_policy & E_MAXIMIZE_TYPE;
4290 /* FIXME: if first_map is 1 then we should ignore the first hide event
4291 * or ensure the window is already hidden and events flushed before we
4292 * create a border for it */
4295 ec->changes.pos = 1;
4297 // needed to be 1 for internal windw and on restart.
4298 // ec->ignore_first_unmap = 2;
4300 ec->offer_resistance = 1;
4302 e_comp->new_clients++;
4304 ec->exp_iconify.by_client = 0;
4305 ec->exp_iconify.not_raise = 0;
4306 ec->exp_iconify.skip_iconify = 0;
4307 ec->exp_iconify.skip_by_remote = 0;
4308 if (e_config->deiconify_approve)
4309 ec->exp_iconify.deiconify_update= 1;
4311 ec->exp_iconify.deiconify_update= 0;
4312 if (e_config->use_buffer_flush)
4313 ec->exp_iconify.buffer_flush = 1;
4315 ec->exp_iconify.buffer_flush = 0;
4317 e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_NONE);
4319 wl_signal_emit_mutable(&PRI(ec)->events.new_client, NULL);
4320 if (!_e_client_hook_call(E_CLIENT_HOOK_NEW_CLIENT, ec))
4322 /* delete the above allocated object */
4323 //e_object_del(E_OBJECT(ec));
4327 _e_client_aux_hint_eval(ec);
4329 ec->icccm.title = NULL;
4330 ec->icccm.name = NULL;
4331 #if defined(__cplusplus) || defined(c_plusplus)
4332 ec->icccm.cpp_class = NULL;
4334 ec->icccm.class = NULL;
4336 ec->icccm.icon_name = NULL;
4337 ec->icccm.machine = NULL;
4338 ec->icccm.min_w = 1;
4339 ec->icccm.min_h = 1;
4340 ec->icccm.max_w = 32767;
4341 ec->icccm.max_h = 32767;
4342 ec->icccm.base_w = 0;
4343 ec->icccm.base_h = 0;
4344 ec->icccm.step_w = -1;
4345 ec->icccm.step_h = -1;
4346 ec->icccm.min_aspect = 0.0;
4347 ec->icccm.max_aspect = 0.0;
4350 ec->netwm.name = NULL;
4351 ec->netwm.icon_name = NULL;
4352 ec->netwm.desktop = 0;
4353 ec->netwm.state.modal = 0;
4354 ec->netwm.state.sticky = 0;
4355 ec->netwm.state.shaded = 0;
4356 ec->netwm.state.hidden = 0;
4357 ec->netwm.state.maximized_v = 0;
4358 ec->netwm.state.maximized_h = 0;
4359 ec->netwm.state.skip_taskbar = 0;
4360 ec->netwm.state.skip_pager = 0;
4361 ec->netwm.state.fullscreen = 0;
4362 ec->netwm.state.stacking = E_STACKING_NONE;
4363 ec->netwm.action.move = 0;
4364 ec->netwm.action.resize = 0;
4365 ec->netwm.action.minimize = 0;
4366 ec->netwm.action.shade = 0;
4367 ec->netwm.action.stick = 0;
4368 ec->netwm.action.maximized_h = 0;
4369 ec->netwm.action.maximized_v = 0;
4370 ec->netwm.action.fullscreen = 0;
4371 ec->netwm.action.change_desktop = 0;
4372 ec->netwm.action.close = 0;
4373 ec->netwm.opacity = 255;
4375 ec->visibility.obscured = E_VISIBILITY_UNKNOWN;
4376 ec->visibility.opaque = -1;
4377 ec->visibility.changed = 0;
4378 ec->visibility.skip = 0;
4379 ec->visibility.last_sent_type = E_VISIBILITY_UNKNOWN;
4381 ec->transform.zoom = 1.0;
4382 ec->transform.angle = 0.0;
4383 ec->transform_core.direct_render = EINA_TRUE;
4384 ec->transform_core.activate = EINA_TRUE;
4386 ec->pointer_enter_sent = EINA_FALSE;
4388 ec->acquire_fence_fd = -1;
4392 e_comp->clients = eina_list_append(e_comp->clients, ec);
4393 eina_hash_add(clients_hash[type], &ec->pixmap, ec);
4395 ELOGF("COMP", "CLIENT ADD. cp:%p, argb:%d, internal:%d, ignored:%d", ec, cp, ec->argb, internal, ec->ignored);
4397 _e_client_event_add(ec);
4398 e_comp_object_client_add(ec);
4401 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW, _e_client_cb_evas_show, ec);
4402 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_HIDE, _e_client_cb_evas_hide, ec);
4403 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOVE, _e_client_cb_evas_move, ec);
4404 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESIZE, _e_client_cb_evas_resize, ec);
4405 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESTACK, _e_client_cb_evas_restack, ec);
4406 evas_object_smart_callback_add(ec->frame, "shade_done", _e_client_cb_evas_shade_done, ec);
4409 #ifdef REFACTOR_ZONE_DESK
4412 _e_client_zone_update(ec);
4414 e_client_desk_set(ec, e_desk_current_get(e_zone_current_get()));
4417 wl_signal_emit_mutable(&PRI(ec)->events.new_client_post, NULL);
4418 #ifdef _F_E_CLIENT_NEW_CLIENT_POST_HOOK_
4419 _e_client_hook_call(E_CLIENT_HOOK_NEW_CLIENT_POST, ec);
4422 ec->manage_resize.resize_obj = NULL;
4423 ec->manage_resize.x = ec->manage_resize.y = ec->manage_resize.w = ec->manage_resize.h = 0;
4424 ec->manage_resize.enable_aspect_ratio = EINA_FALSE;
4425 ec->manage_resize.aw = ec->manage_resize.ah = 0;
4426 ec->manage_resize.header_h = 0;
4427 ec->manage_resize.footer_h = 0;
4429 ec->visibility.ignore_geometry = e_config->calc_vis_ignore_geometry;
4434 E_API Eina_Bool e_client_is_internal(E_Client *ec)
4436 E_OBJECT_CHECK_RETURN(ec, EINA_TRUE);
4437 return ec->internal;
4440 #ifdef REFACTOR_ZONE_DESK
4443 e_client_desk_set(E_Client *ec, E_Desk *desk)
4445 E_Event_Client_Desk_Set *ev;
4450 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
4451 E_OBJECT_CHECK(desk);
4452 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
4453 if (e_desk_has_ec(desk, ec)) return;
4457 ec->desk->fullscreen_clients = eina_list_remove(ec->desk->fullscreen_clients, ec);
4458 desk->fullscreen_clients = eina_list_append(desk->fullscreen_clients, ec);
4460 old_desk = ec->desk;
4462 e_desk_client_del(old_desk, ec);
4464 e_desk_client_add(desk, ec);
4465 if (!ec->new_client)
4469 e_comp_object_effect_unclip(ec->frame);
4470 e_comp_object_effect_set(ec->frame, NULL);
4472 if (desk->visible || ec->sticky)
4474 if ((!ec->hidden) && (!ec->iconic))
4475 evas_object_show(ec->frame);
4480 evas_object_hide(ec->frame);
4483 e_client_comp_hidden_set(ec, (!desk->visible) && (!ec->sticky));
4484 e_client_zone_set(ec, desk->zone);
4488 ev = E_NEW(E_Event_Client_Desk_Set, 1);
4493 e_object_ref(E_OBJECT(ec));
4494 ev->desk = old_desk;
4495 e_object_ref(E_OBJECT(old_desk));
4496 ecore_event_add(E_EVENT_CLIENT_DESK_SET, ev, (Ecore_End_Cb)_e_client_event_desk_set_free, NULL);
4499 zone = e_comp_zone_find_by_ec(ec);
4500 if (old_desk->zone == zone)
4502 e_client_res_change_geometry_save(ec);
4503 e_client_res_change_geometry_restore(ec);
4504 ec->pre_res_change.valid = 0;
4508 if (e_config->transient.desktop)
4513 EINA_LIST_FOREACH(ec->transients, l, child)
4514 e_client_desk_set(child, ec->desk);
4517 _e_client_hook_call(E_CLIENT_HOOK_DESK_SET, ec);
4518 evas_object_smart_callback_call(ec->frame, "desk_change", ec);
4520 if (ec->desk->desk_area.enable)
4522 if (!ec->desk_area.desk_area)
4525 eda = e_desk_desk_area_base_get(ec->desk);
4526 e_client_desk_area_set(ec, eda);
4529 e_client_desk_area_enable_set(ec, EINA_TRUE);
4535 e_client_desk_iconify_skip_set(E_Client *ec, Eina_Bool skip)
4538 ec->user_skip_winlist = skip;
4542 e_client_desk_iconify_skip_get(E_Client *ec)
4544 if (!ec) return EINA_FALSE;
4545 return ec->user_skip_winlist;
4549 e_client_comp_grabbed_get(void)
4551 return comp_grabbed;
4555 e_client_action_get(void)
4557 return action_client;
4561 //////////////////////////////////////////////////////////
4564 e_client_mouse_in(E_Client *ec, int x, int y)
4568 if (comp_grabbed) return;
4569 if (e_object_is_del(E_OBJECT(ec))) return;
4570 desk = e_comp_desk_find_by_ec(ec);
4571 if (desk && desk->animate_count) return;
4572 ec->mouse.current.mx = x;
4573 ec->mouse.current.my = y;
4576 #ifdef REFACTOR_FOCUS_POLICY
4577 wl_signal_emit_mutable(&PRI(ec)->events.mouse_in, NULL);
4579 if ((!ec->iconic) && (!e_client_util_ignored_get(ec)))
4580 e_focus_event_mouse_in(ec);
4585 e_client_mouse_out(E_Client *ec, int x, int y)
4589 if (comp_grabbed) return;
4590 if (ec->fullscreen) return;
4591 if (e_object_is_del(E_OBJECT(ec))) return;
4592 desk = e_comp_desk_find_by_ec(ec);
4593 if (desk && desk->animate_count) return;
4595 ec->mouse.current.mx = x;
4596 ec->mouse.current.my = y;
4599 #ifdef REFACTOR_FOCUS_POLICY
4600 wl_signal_emit_mutable(&PRI(ec)->events.mouse_out, NULL);
4602 if ((!ec->iconic) && (!e_client_util_ignored_get(ec)))
4603 e_focus_event_mouse_out(ec);
4608 e_client_mouse_wheel(E_Client *ec, Evas_Point *output, E_Binding_Event_Wheel *ev)
4610 EINA_SAFETY_ON_NULL_RETURN(ec);
4611 if (action_client) return;
4612 ec->mouse.current.mx = output->x;
4613 ec->mouse.current.my = output->y;
4617 e_client_mouse_down(E_Client *ec, int button, Evas_Point *output, E_Binding_Event_Mouse_Button *ev)
4619 #ifdef REFACTOR_FOCUS_POLICY
4624 EINA_SAFETY_ON_NULL_RETURN(ec);
4625 if (action_client || ec->iconic || e_client_util_ignored_get(ec)) return;
4626 if ((button >= 1) && (button <= 3))
4628 ec->mouse.last_down[button - 1].mx = output->x;
4629 ec->mouse.last_down[button - 1].my = output->y;
4630 ec->mouse.last_down[button - 1].x = ec->x;
4631 ec->mouse.last_down[button - 1].y = ec->y;
4632 ec->mouse.last_down[button - 1].w = ec->w;
4633 ec->mouse.last_down[button - 1].h = ec->h;
4637 ec->moveinfo.down.x = ec->x;
4638 ec->moveinfo.down.y = ec->y;
4639 ec->moveinfo.down.w = ec->w;
4640 ec->moveinfo.down.h = ec->h;
4642 ec->mouse.current.mx = output->x;
4643 ec->mouse.current.my = output->y;
4644 if ((button >= 1) && (button <= 3))
4646 ec->mouse.last_down[button - 1].mx = output->x;
4647 ec->mouse.last_down[button - 1].my = output->y;
4648 ec->mouse.last_down[button - 1].x = ec->x;
4649 ec->mouse.last_down[button - 1].y = ec->y;
4650 ec->mouse.last_down[button - 1].w = ec->w;
4651 ec->mouse.last_down[button - 1].h = ec->h;
4655 ec->moveinfo.down.x = ec->x;
4656 ec->moveinfo.down.y = ec->y;
4657 ec->moveinfo.down.w = ec->w;
4658 ec->moveinfo.down.h = ec->h;
4660 ec->mouse.current.mx = output->x;
4661 ec->mouse.current.my = output->y;
4663 #ifdef REFACTOR_FOCUS_POLICY
4664 wl_signal_emit_mutable(&PRI(ec)->events.mouse_down, NULL);
4666 focused = e_client_focused_get();
4667 if ((focused) && (ec != focused))
4669 e_focus_event_mouse_down(ec);
4675 e_client_mouse_up(E_Client *ec, int button, Evas_Point *output, E_Binding_Event_Mouse_Button* ev)
4677 EINA_SAFETY_ON_NULL_RETURN(ec);
4678 if (ec->iconic || e_client_util_ignored_get(ec)) return;
4679 if ((button >= 1) && (button <= 3))
4681 ec->mouse.last_up[button - 1].mx = output->x;
4682 ec->mouse.last_up[button - 1].my = output->y;
4683 ec->mouse.last_up[button - 1].x = ec->x;
4684 ec->mouse.last_up[button - 1].y = ec->y;
4686 ec->mouse.current.mx = output->x;
4687 ec->mouse.current.my = output->y;
4688 /* also we don't pass the same params that went in - then again that */
4689 /* should be ok as we are just ending the action if it has an end */
4690 if (ec->cur_mouse_action)
4692 if (ec->cur_mouse_action->func.end_mouse)
4693 ec->cur_mouse_action->func.end_mouse(E_OBJECT(ec), "", ev);
4694 else if (ec->cur_mouse_action->func.end)
4695 ec->cur_mouse_action->func.end(E_OBJECT(ec), "");
4696 e_object_unref(E_OBJECT(ec->cur_mouse_action));
4697 ec->cur_mouse_action = NULL;
4700 if ((button >= 1) && (button <= 3))
4702 ec->mouse.last_up[button - 1].mx = output->x;
4703 ec->mouse.last_up[button - 1].my = output->y;
4704 ec->mouse.last_up[button - 1].x = ec->x;
4705 ec->mouse.last_up[button - 1].y = ec->y;
4710 e_client_stay_within_canvas_margin(E_Client *ec)
4717 _e_client_stay_within_canvas_margin(ec, ec->x, ec->y, &new_x, &new_y);
4719 if ((ec->x != new_x) || (ec->y != new_y))
4720 evas_object_move(ec->frame, new_x, new_y);
4725 e_client_mouse_move(E_Client *ec, Evas_Point *output)
4727 EINA_SAFETY_ON_NULL_RETURN(ec);
4728 if (ec->iconic || e_client_util_ignored_get(ec)) return;
4729 ec->mouse.current.mx = output->x;
4730 ec->mouse.current.my = output->y;
4731 if (e_client_util_moving_get(ec))
4733 _e_client_move_handle(ec);
4735 else if (e_client_util_resizing_get(ec))
4737 _e_client_resize_handle(ec);
4740 ///////////////////////////////////////////////////////
4743 e_client_res_change_geometry_save(E_Client *ec)
4746 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
4748 if (ec->pre_res_change.valid) return;
4749 ec->pre_res_change.valid = 1;
4750 ec->pre_res_change.x = ec->x;
4751 ec->pre_res_change.y = ec->y;
4752 ec->pre_res_change.w = ec->w;
4753 ec->pre_res_change.h = ec->h;
4754 ec->pre_res_change.saved.x = ec->saved.x;
4755 ec->pre_res_change.saved.y = ec->saved.y;
4756 ec->pre_res_change.saved.w = ec->saved.w;
4757 ec->pre_res_change.saved.h = ec->saved.h;
4761 e_client_res_change_geometry_restore(E_Client *ec)
4767 unsigned char valid : 1;
4776 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
4777 if (!ec->pre_res_change.valid) return;
4778 if (ec->new_client) return;
4780 zone = e_comp_zone_find_by_ec(ec);
4783 memcpy(&pre_res_change, &ec->pre_res_change, sizeof(pre_res_change));
4787 e_client_unfullscreen(ec);
4788 e_client_fullscreen(ec, e_config->fullscreen_policy);
4790 else if (ec->maximized != E_MAXIMIZE_NONE)
4794 max = ec->maximized;
4795 e_client_unmaximize(ec, E_MAXIMIZE_BOTH);
4796 e_client_maximize(ec, max);
4800 int x, y, w, h, zx, zy, zw, zh;
4802 ec->saved.x = ec->pre_res_change.saved.x;
4803 ec->saved.y = ec->pre_res_change.saved.y;
4804 ec->saved.w = ec->pre_res_change.saved.w;
4805 ec->saved.h = ec->pre_res_change.saved.h;
4807 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4809 if (ec->saved.w > zw)
4811 if ((ec->saved.x + ec->saved.w) > (zx + zw))
4812 ec->saved.x = zx + zw - ec->saved.w;
4814 if (ec->saved.h > zh)
4816 if ((ec->saved.y + ec->saved.h) > (zy + zh))
4817 ec->saved.y = zy + zh - ec->saved.h;
4819 x = ec->pre_res_change.x;
4820 y = ec->pre_res_change.y;
4821 w = ec->pre_res_change.w;
4822 h = ec->pre_res_change.h;
4827 if ((x + w) > (zx + zw))
4829 if ((y + h) > (zy + zh))
4831 evas_object_geometry_set(ec->frame, x, y, w, h);
4833 memcpy(&ec->pre_res_change, &pre_res_change, sizeof(pre_res_change));
4836 #ifdef REFACTOR_ZONE_DESK
4839 e_client_zone_set(E_Client *ec, E_Zone *zone)
4841 E_Event_Client_Zone_Set *ev;
4844 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
4845 E_OBJECT_CHECK(zone);
4846 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
4847 if (e_zone_has_ec(zone, ec)) return;
4849 ev = E_NEW(E_Event_Client_Zone_Set, 1);
4852 /* if the window does not lie in the new zone, move it so that it does */
4853 if (!E_INTERSECTS(ec->x, ec->y, ec->w, ec->h, zone->x, zone->y, zone->w, zone->h))
4857 x = ec->x, y = ec->y;
4859 /* keep window from hanging off bottom and left */
4860 if (x + ec->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + ec->w);
4861 if (y + ec->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + ec->h);
4863 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
4864 if (x < zone->x) x = zone->x;
4865 if (y < zone->y) y = zone->y;
4867 if (!E_INTERSECTS(x, y, ec->w, ec->h, zone->x, zone->y, zone->w, zone->h))
4869 /* still not in zone at all, so just move it to closest edge */
4870 if (x < zone->x) x = zone->x;
4871 if (x >= zone->x + zone->w) x = zone->x + zone->w - ec->w;
4872 if (y < zone->y) y = zone->y;
4873 if (y >= zone->y + zone->h) y = zone->y + zone->h - ec->h;
4875 evas_object_move(ec->frame, x, y);
4878 // TODO: NEED TO DELETE LINE BELOW
4883 e_object_ref(E_OBJECT(ec));
4885 e_object_ref(E_OBJECT(zone));
4887 ecore_event_add(E_EVENT_CLIENT_ZONE_SET, ev, (Ecore_End_Cb)_e_client_event_zone_set_free, NULL);
4889 // TODO: change all use of e_client_zone_set() to e_zone_client_add()
4890 e_zone_client_add(zone, ec);
4895 e_client_pos_set(E_Client *ec, int x, int y)
4903 e_client_pos_get(E_Client *ec, int *x, int *y)
4919 e_client_size_set(E_Client *ec, int w, int h)
4927 e_client_size_get(E_Client *ec, int *w, int *h)
4943 e_client_geometry_get(E_Client *ec, int *x, int *y, int *w, int *h)
4951 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
4953 if (e_client_transform_core_enable_get(ec))
4955 gx = ec->transform_core.result.boundary.x;
4956 gy = ec->transform_core.result.boundary.y;
4957 gw = ec->transform_core.result.boundary.w;
4958 gh = ec->transform_core.result.boundary.h;
4964 evas_object_geometry_get(ec->frame, &gx, &gy, &gw, &gh);
4965 if (gw == 0 && gh == 0)
4967 /* In this case, there is no image buffer in e_comp_object, thus it
4968 * should return geometry value of ec itself. It usually happens if
4969 * new ec is not mapped yet.
4993 e_client_above_get(const E_Client *ec)
4998 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
4999 if (EINA_INLIST_GET(ec)->next) //check current layer
5001 EINA_INLIST_FOREACH(EINA_INLIST_GET(ec)->next, ec2)
5005 ELOGF("FATAL", "CHECK the ec inlist next", ec);
5008 if (!e_object_is_del(E_OBJECT(ec2)))
5012 if (ec->layer == E_LAYER_CLIENT_CURSOR) return NULL;
5013 if (e_comp_canvas_client_layer_map(ec->layer) == 9999) return NULL;
5015 g_rec_mutex_lock(&e_comp->input_key_grabs_mutex);
5016 /* go up the layers until we find one */
5017 for (x = e_comp_canvas_layer_map(ec->layer) + 1; x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
5019 if (!e_comp->layers[x].clients) continue;
5020 EINA_INLIST_FOREACH(e_comp->layers[x].clients, ec2)
5024 ELOGF("FATAL", "EC exist above layer. ec layer_map:%d, cur layer_map:%d",
5025 ec, e_comp_canvas_layer_map(ec->layer), x);
5028 if (!e_object_is_del(E_OBJECT(ec2)))
5030 g_rec_mutex_unlock(&e_comp->input_key_grabs_mutex);
5035 g_rec_mutex_unlock(&e_comp->input_key_grabs_mutex);
5041 e_client_below_get(const E_Client *ec)
5046 E_Layer ec_layer, ec_layer_cw;
5049 E_OBJECT_CHECK_RETURN(ec, NULL);
5050 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, NULL);
5052 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
5053 if (EINA_INLIST_GET(ec)->prev) //check current layer
5055 for (l = EINA_INLIST_GET(ec)->prev; l; l = l->prev)
5057 ec2 = EINA_INLIST_CONTAINER_GET(l, E_Client);
5060 ELOGF("FATAL", "CHECK the ec inlist prev", ec);
5063 if (!e_object_is_del(E_OBJECT(ec2)))
5068 // check layer validation
5069 ec_layer = ec->layer;
5070 if (ec->layer_block || ec->layer_pending)
5072 cw_layer = e_comp_object_layer_get(ec->frame);
5075 ec_layer_cw = e_comp_canvas_layer_map_to(cw_layer);
5076 if (ec_layer != ec_layer_cw)
5078 ELOGF("COMP", "LAYER is not same. USE obj layer! (ec->layer:%d, obj:%d). block:%d, pending:%d)", ec, ec_layer, ec_layer_cw, ec->layer_block, ec->layer_pending);
5079 ec_layer = ec_layer_cw;
5084 if (ec_layer == E_LAYER_CLIENT_DESKTOP) return NULL;
5085 if (e_comp_canvas_client_layer_map(ec_layer) == 9999) return NULL;
5087 /* go down the layers until we find one */
5088 x = e_comp_canvas_layer_map(ec_layer);
5091 g_rec_mutex_lock(&e_comp->input_key_grabs_mutex);
5092 for (; x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
5094 if (!e_comp->layers[x].clients) continue;
5095 EINA_INLIST_REVERSE_FOREACH(e_comp->layers[x].clients, ec2)
5099 ELOGF("FATAL", "EC exist below layer. ec layer_map:%d, cur layer_map:%d",
5100 ec, e_comp_canvas_layer_map(ec_layer), x);
5103 if (!e_object_is_del(E_OBJECT(ec2)))
5105 g_rec_mutex_unlock(&e_comp->input_key_grabs_mutex);
5110 g_rec_mutex_unlock(&e_comp->input_key_grabs_mutex);
5116 e_client_bottom_get(void)
5119 g_rec_mutex_lock(&e_comp->input_key_grabs_mutex);
5120 for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
5124 if (!e_comp->layers[x].clients) continue;
5125 EINA_INLIST_FOREACH(e_comp->layers[x].clients, ec2)
5126 if (!e_object_is_del(E_OBJECT(ec2)))
5128 g_rec_mutex_unlock(&e_comp->input_key_grabs_mutex);
5132 g_rec_mutex_unlock(&e_comp->input_key_grabs_mutex);
5138 e_client_top_get(void)
5141 g_rec_mutex_lock(&e_comp->input_key_grabs_mutex);
5142 for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
5146 if (!e_comp->layers[x].clients) continue;
5147 EINA_INLIST_REVERSE_FOREACH(e_comp->layers[x].clients, ec2)
5148 if (!e_object_is_del(E_OBJECT(ec2)))
5150 g_rec_mutex_unlock(&e_comp->input_key_grabs_mutex);
5154 g_rec_mutex_unlock(&e_comp->input_key_grabs_mutex);
5159 EINTERN unsigned int
5160 e_clients_count(void)
5162 return eina_list_count(e_comp->clients);
5167 * Set a callback which will be called just prior to updating the
5168 * move coordinates for a border
5171 e_client_move_intercept_cb_set(E_Client *ec, E_Client_Move_Intercept_Cb cb)
5173 ec->move_intercept_cb = cb;
5176 ///////////////////////////////////////
5178 E_API E_Client_Hook *
5179 e_client_hook_add(E_Client_Hook_Point hookpoint, E_Client_Hook_Cb func, const void *data)
5183 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_CLIENT_HOOK_LAST, NULL);
5184 ch = E_NEW(E_Client_Hook, 1);
5185 if (!ch) return NULL;
5186 ch->hookpoint = hookpoint;
5188 ch->data = (void*)data;
5189 _e_client_hooks[hookpoint] = eina_inlist_append(_e_client_hooks[hookpoint], EINA_INLIST_GET(ch));
5194 e_client_hook_del(E_Client_Hook *ch)
5197 if (_e_client_hooks_walking == 0)
5199 _e_client_hooks[ch->hookpoint] = eina_inlist_remove(_e_client_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
5203 _e_client_hooks_delete++;
5206 ///////////////////////////////////////
5208 E_API E_Client_Intercept_Hook *
5209 e_client_intercept_hook_add(E_Client_Intercept_Hook_Point hookpoint, E_Client_Intercept_Hook_Cb func, const void *data)
5211 E_Client_Intercept_Hook *ch;
5213 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_CLIENT_INTERCEPT_HOOK_LAST, NULL);
5214 ch = E_NEW(E_Client_Intercept_Hook, 1);
5215 if (!ch) return NULL;
5216 ch->hookpoint = hookpoint;
5218 ch->data = (void*)data;
5219 _e_client_intercept_hooks[hookpoint] = eina_inlist_append(_e_client_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
5224 e_client_intercept_hook_del(E_Client_Intercept_Hook *ch)
5229 if (_e_client_intercept_hooks_walking == 0)
5231 _e_client_intercept_hooks[ch->hookpoint] =
5232 eina_inlist_remove(_e_client_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
5236 _e_client_intercept_hooks_delete++;
5239 #ifdef REFACTOR_FOCUS_POLICY
5242 e_client_focus_stack_lower(E_Client *ec)
5244 Eina_List *l = NULL;
5245 E_Client *ec2 = NULL;
5247 EINA_SAFETY_ON_NULL_RETURN(ec);
5249 focus_stack = eina_list_remove(focus_stack, ec);
5251 EINA_LIST_REVERSE_FOREACH(focus_stack, l, ec2)
5253 if (ec2 == NULL) continue;
5254 if (ec2->layer < ec->layer) continue;
5256 focus_stack = eina_list_append_relative_list(focus_stack, ec, l);
5260 focus_stack = eina_list_prepend(focus_stack, ec);
5266 e_client_focus_latest_set(E_Client *ec)
5268 EINA_SAFETY_ON_NULL_RETURN(ec);
5270 #ifdef REFACTOR_FOCUS_POLICY
5271 wl_signal_emit_mutable(&PRI(ec)->events.focus_latest_set, NULL);
5273 focus_stack = eina_list_remove(focus_stack, ec);
5274 focus_stack = eina_list_prepend(focus_stack, ec);
5278 #ifdef REFACTOR_FOCUS_POLICY
5281 e_client_focus_stack_append_current_focused(E_Client *ec)
5283 Eina_List *l = NULL;
5284 E_Client *temp_ec = NULL;
5286 if (!ec) CRI("ACK");
5288 focus_stack = eina_list_remove(focus_stack, ec);
5290 EINA_LIST_FOREACH(focus_stack, l, temp_ec)
5292 if (temp_ec != focused) continue;
5294 focus_stack = eina_list_append_relative_list(focus_stack, ec, l);
5298 focus_stack = eina_list_prepend(focus_stack, ec);
5304 e_client_focus_defer_set(E_Client *ec)
5306 EINA_SAFETY_ON_NULL_RETURN(ec);
5307 #ifdef REFACTOR_FOCUS_POLICY
5308 wl_signal_emit_mutable(&PRI(ec)->events.focus_defer_set, NULL);
5310 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK) return;
5312 ELOGF("FOCUS", "focus defer set", ec);
5314 defer_focus_stack = eina_list_remove(defer_focus_stack, ec);
5315 defer_focus_stack = eina_list_prepend(defer_focus_stack, ec);
5319 #ifdef REFACTOR_FOCUS_POLICY
5322 e_client_focus_defer_unset(E_Client *ec)
5324 EINA_SAFETY_ON_NULL_RETURN(ec);
5325 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK) return;
5327 ELOGF("FOCUS", "focus defer unset", ec);
5329 defer_focus_stack = eina_list_remove(defer_focus_stack, ec);
5333 e_client_focus_defer_clear(void)
5335 if (!defer_focus_stack) return;
5337 ELOGF("FOCUS", "focus defer clear", NULL);
5339 defer_focus_stack = eina_list_free(defer_focus_stack);
5343 e_client_refocus(void)
5349 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK) return;
5351 EINA_LIST_FOREACH(e_client_focus_stack_get(), l, ec)
5353 desk = e_comp_desk_find_by_ec(ec);
5354 if (!desk) continue;
5355 if (desk->visible && (!ec->iconic))
5357 g_rec_mutex_lock(&e_comp->input_key_grabs_mutex);
5358 if (e_comp->input_key_grabs || e_comp->input_mouse_grabs)
5360 g_rec_mutex_unlock(&e_comp->input_key_grabs_mutex);
5363 g_rec_mutex_unlock(&e_comp->input_key_grabs_mutex);
5364 ELOGF("FOCUS", "focus set | refocus", ec);
5365 e_client_frame_focus_set(ec, EINA_TRUE);
5373 * Sets the focus to the given client if necessary
5374 * There are 3 cases of different focus_policy-configurations:
5376 * - E_FOCUS_CLICK: just set the focus, the most simple one
5378 * - E_FOCUS_MOUSE: focus is where the mouse is, so try to
5379 * warp the pointer to the window. If this fails (because
5380 * the pointer is already in the window), just set the focus.
5382 * - E_FOCUS_SLOPPY: focus is where the mouse is or on the
5383 * last window which was focused, if the mouse is on the
5384 * desktop. So, we need to look if there is another window
5385 * under the pointer and warp to pointer to the right
5386 * one if so (also, we set the focus afterwards). In case
5387 * there is no window under pointer, the pointer is on the
5388 * desktop and so we just set the focus.
5391 * This function is to be called when setting the focus was not
5392 * explicitly triggered by the user (by moving the mouse or
5393 * clicking for example), but implicitly (by closing a window,
5394 * the last focused window should get focus).
5398 e_client_focus_set_with_pointer(E_Client *ec)
5401 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5402 /* note: this is here as it seems there are enough apps that do not even
5403 * expect us to emulate a look of focus but not actually set x input
5404 * focus as we do - so simply abort any focuse set on such windows */
5405 /* be strict about accepting focus hint */
5406 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK) return;
5408 if ((!ec->icccm.accepts_focus) &&
5409 (!ec->icccm.take_focus)) return;
5410 if (ec->lock_focus_out) return;
5411 if (ec == focused) return;
5413 TRACE_DS_BEGIN(CLIENT:FOCUS SET WITH POINTER);
5414 ELOGF("FOCUS", "focus set | focus with pointer", ec);
5415 e_client_frame_focus_set(ec, EINA_TRUE);
5417 if (e_config->focus_policy == E_FOCUS_CLICK)
5433 e_client_focused_set(E_Client *ec)
5435 #ifdef REFACTOR_FOCUS_POLICY
5436 E_Client *focused_ec;
5440 ELOGF("FOCUS", "CLIENT FOCUSED_SET : SET", ec);
5442 ELOGF("FOCUS", "CLIENT FOCUSED_SET : UNSET", NULL);
5444 focused_ec = e_comp_focused_ec_get();
5445 if (ec == focused_ec) return;
5447 TRACE_DS_BEGIN(CLIENT:FOCUSED SET);
5449 // unset the current focused_ec if focused_ec is not being deleted
5452 if (!e_object_is_del(E_OBJECT(focused_ec)))
5454 // FIXME: Remove focus_unset event of client.
5455 // Instead, make zone focus_unset event and use it.
5456 wl_signal_emit_mutable(&PRI(focused_ec)->events.focus_unset, NULL);
5457 _e_client_hook_call(E_CLIENT_HOOK_FOCUS_UNSET, focused_ec);
5459 if (e_object_ref_get(E_OBJECT(focused_ec)) > 0)
5461 _e_client_event_simple(focused_ec, E_EVENT_CLIENT_FOCUS_OUT);
5462 e_client_urgent_set(focused_ec, focused_ec->icccm.urgent);
5467 // clear the current focused_ec when ec is NULL
5470 zone = e_comp_zone_find_by_ec(focused_ec);
5471 e_zone_focus_clear(zone);
5476 // FIXME: Remove focus_set event of client.
5477 // Instead, make zone focus_set event and use it.
5478 // set the new current focused_ec
5479 wl_signal_emit_mutable(&PRI(ec)->events.focus_set, NULL);
5480 _e_client_hook_call(E_CLIENT_HOOK_FOCUS_SET, ec);
5482 // send the client_focuse_in event
5483 _e_client_event_simple(ec, E_EVENT_CLIENT_FOCUS_IN);
5485 #ifdef REFACTOR_ZONE_DESK
5487 // TODO: This is not for focus, but for Window Placement policy.
5488 // Move this code to the better place.
5489 if (ec->sticky && ec->desk && (!ec->desk->visible))
5490 e_client_desk_set(ec, e_desk_current_get(zone));
5495 E_Client *ec2, *ec_unfocus = focused;
5499 if (ec == focused) return;
5501 TRACE_DS_BEGIN(CLIENT:FOCUSED SET);
5503 ELOGF("FOCUS", "CLIENT FOCUS_SET", ec);
5505 g_mutex_lock(&focused_ec_mutex);
5507 g_mutex_unlock(&focused_ec_mutex);
5509 zone = e_comp_zone_find_by_ec(ec);
5513 e_client_urgent_set(ec, 0);
5514 int x, total = zone->desk_x_count * zone->desk_y_count;
5516 for (x = 0; x < total; x++)
5518 E_Desk *desk = zone->desks[x];
5519 /* if there's any fullscreen non-parents on this desk, unfullscreen them */
5520 EINA_LIST_FOREACH_SAFE(desk->fullscreen_clients, l, ll, ec2)
5522 if (ec2 == ec) continue;
5523 if (e_object_is_del(E_OBJECT(ec2))) continue;
5524 /* but only if it's the same desk or one of the clients is sticky */
5525 if ((e_desk_has_ec(desk, ec)) || (ec->sticky || ec2->sticky))
5527 if (!eina_list_data_find(ec->transients, ec2))
5528 e_client_unfullscreen(ec2);
5534 while ((ec_unfocus) && (ec_unfocus->zone))
5536 ec_unfocus->want_focus = ec_unfocus->focused = 0;
5537 if (ec_unfocus->mouse.in && ec && (!e_client_util_is_popup(ec)) &&
5538 (e_config->focus_policy != E_FOCUS_CLICK))
5539 e_client_mouse_out(ec_unfocus, ec_unfocus->x - 1, ec_unfocus->y - 1);
5541 /* if there unfocus client is fullscreen and visible */
5542 if ((ec_unfocus->fullscreen) && (!ec_unfocus->iconic) && (!ec_unfocus->hidden) &&
5543 (ec_unfocus->zone == e_zone_current_get()) &&
5544 ((ec_unfocus->desk == e_desk_current_get(ec_unfocus->zone)) || (ec_unfocus->sticky)))
5546 Eina_Bool have_vis_child = EINA_FALSE;
5548 /* if any of its children are visible */
5549 EINA_LIST_FOREACH(ec_unfocus->transients, l, ec2)
5551 if ((ec2->zone == ec_unfocus->zone) &&
5552 ((ec2->desk == ec_unfocus->desk) ||
5553 (ec2->sticky) || (ec_unfocus->sticky)))
5555 have_vis_child = EINA_TRUE;
5559 /* if no children are visible, unfullscreen */
5560 if ((!e_object_is_del(E_OBJECT(ec_unfocus))) && (!have_vis_child))
5561 e_client_unfullscreen(ec_unfocus);
5564 if (!e_object_is_del(E_OBJECT(ec_unfocus)))
5566 wl_signal_emit_mutable(&PRI(ec)->events.focus_unset, focused_ec);
5567 _e_client_hook_call(E_CLIENT_HOOK_FOCUS_UNSET, ec_unfocus);
5569 /* only send event here if we're not being deleted */
5570 if ((!e_object_is_del(E_OBJECT(ec_unfocus))) &&
5571 (e_object_ref_get(E_OBJECT(ec_unfocus)) > 0))
5573 _e_client_event_simple(ec_unfocus, E_EVENT_CLIENT_FOCUS_OUT);
5574 e_client_urgent_set(ec_unfocus, ec_unfocus->icccm.urgent);
5577 e_client_focus_defer_unset(ec_unfocus);
5586 wl_signal_emit_mutable(&PRI(ec)->events.focus_set, ec);
5587 _e_client_hook_call(E_CLIENT_HOOK_FOCUS_SET, ec);
5589 e_client_focus_latest_set(ec);
5591 _e_client_event_simple(ec, E_EVENT_CLIENT_FOCUS_IN);
5593 #ifdef REFACTOR_ZONE_DESK
5595 if (ec->sticky && ec->desk && (!ec->desk->visible))
5596 e_client_desk_set(ec, e_desk_current_get(zone));
5604 e_client_activate(E_Client *ec)
5607 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5609 TRACE_DS_BEGIN(CLIENT:ACTIVATE);
5611 ELOGF("COMP", "Set launching flag..", ec);
5612 ec->launching = EINA_TRUE;
5614 ec->exp_iconify.not_raise = 0;
5618 if (!ec->lock_user_iconify)
5619 e_client_uniconify(ec);
5621 ELOGF("COMP", "Un-Set ICONIFY BY CLIENT", ec);
5622 ec->exp_iconify.by_client = 0;
5623 e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_NONE);
5625 #ifdef REFACTOR_ZONE_DESK
5627 if ((!ec->iconic) && (!ec->sticky))
5629 e_desk_show(ec->desk);
5631 if (!ec->lock_user_stacking)
5633 if (ec->shaded || ec->shading)
5634 e_client_unshade(ec, ec->shade_dir);
5637 #ifdef REFACTOR_FOCUS_POLICY
5638 // This code will be executed at E_CLIENT_HOOK_ACTIVATE_DONE callback at e_focus_policy_history.c
5640 if (!ec->lock_focus_out)
5642 E_Client *focus_ec = NULL;
5643 E_Client *obscured_above = NULL;
5646 focus_ec = e_client_transient_child_top_get(ec, EINA_TRUE);
5652 e_client_focus_latest_set(ec);
5653 e_client_focus_latest_set(focus_ec);
5654 e_client_focus_defer_unset(ec);
5657 obscured_above = e_client_check_fully_contain_by_above(focus_ec, EINA_FALSE);
5658 if (!obscured_above)
5660 if (!e_policy_visibility_client_is_uniconic(ec))
5662 e_client_focus_defer_set(focus_ec);
5663 e_client_focus_latest_set(focus_ec);
5667 if (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK)
5669 ELOGF("FOCUS", "focus set | client activate", focus_ec);
5670 e_client_frame_focus_set(focus_ec, EINA_TRUE);
5676 e_client_focus_defer_set(focus_ec);
5677 e_client_focus_latest_set(focus_ec);
5682 #ifdef REFACTOR_ZONE_DESK
5684 if (!e_client_desk_iconify_skip_get(ec))
5686 e_desk_visible_client_iconified_list_remove_all(ec->desk);
5690 wl_signal_emit_mutable(&PRI(ec)->events.activate_done, NULL);
5691 _e_client_hook_call(E_CLIENT_HOOK_ACTIVATE_DONE, ec);
5697 e_client_focused_get(void)
5699 #ifdef REFACTOR_FOCUS_POLICY
5700 return e_comp_focused_ec_get();
5702 E_Client *focused_ec = NULL;
5704 g_mutex_lock(&focused_ec_mutex);
5705 focused_ec = focused;
5706 g_mutex_unlock(&focused_ec_mutex);
5712 #ifdef REFACTOR_FOCUS_POLICY
5715 e_client_focus_stack_get(void)
5721 e_client_defer_focus_stack_get(void)
5723 return defer_focus_stack;
5727 e_client_focus_stack_set(Eina_List *l)
5733 e_client_focus_stack_clear(void)
5735 if (!focus_stack) return;
5737 focus_stack = eina_list_free(focus_stack);
5742 e_client_lost_windows_get(E_Zone *zone)
5744 Eina_List *list = NULL;
5747 int loss_overlap = 5;
5749 E_OBJECT_CHECK_RETURN(zone, NULL);
5750 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
5751 EINA_LIST_FOREACH(e_comp->clients, l, ec)
5753 if (!e_zone_has_ec(zone, ec)) continue;
5754 if (e_client_util_ignored_get(ec)) continue;
5756 if (!E_INTERSECTS(zone->x + loss_overlap,
5757 zone->y + loss_overlap,
5758 zone->w - (2 * loss_overlap),
5759 zone->h - (2 * loss_overlap),
5760 ec->x, ec->y, ec->w, ec->h))
5762 list = eina_list_append(list, ec);
5768 ///////////////////////////////////////
5771 e_client_shade(E_Client *ec, E_Direction dir)
5774 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5775 if ((ec->shaded) || (ec->shading) || (ec->fullscreen) ||
5776 ((ec->maximized) && (!e_config->allow_manip))) return;
5777 if (!e_util_strcmp("borderless", ec->bordername)) return;
5778 if (!e_comp_object_frame_allowed(ec->frame)) return;
5782 ec->shade_dir = dir;
5784 evas_object_smart_callback_call(ec->frame, "shaded", (uintptr_t*)dir);
5788 e_client_unshade(E_Client *ec, E_Direction dir)
5791 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5792 if ((!ec->shaded) || (ec->shading))
5798 evas_object_smart_callback_call(ec->frame, "unshaded", (uintptr_t*)dir);
5801 ///////////////////////////////////////
5804 e_client_maximized_geometry_set(E_Client *ec, int x, int y, int w, int h)
5808 ec->maximized_info.x = x;
5809 ec->maximized_info.y = y;
5810 ec->maximized_info.w = w;
5811 ec->maximized_info.h = h;
5813 e_client_frame_geometry_set(ec, x, y, w, h);
5817 e_client_maximized_geometry_get(E_Client *ec, int *x, int *y, int *w, int *h)
5821 if (x) *x = ec->maximized_info.x;
5822 if (y) *y = ec->maximized_info.y;
5823 if (w) *w = ec->maximized_info.w;
5824 if (h) *h = ec->maximized_info.h;
5828 e_client_maximize_update(E_Client *ec)
5833 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5837 max = ec->maximized;
5839 e_client_maximize(ec, max);
5844 e_client_maximize(E_Client *ec, E_Maximize max)
5846 #ifdef REFACTOR_ZONE_DESK
5848 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5850 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
5852 if ((ec->shaded) || (ec->shading)) return;
5854 if ((ec->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION))
5856 if ((ec->maximized & E_MAXIMIZE_TYPE) == (max & E_MAXIMIZE_TYPE))
5862 ec->changes.need_maximize = 1;
5863 ec->maximized &= ~E_MAXIMIZE_TYPE;
5864 ec->maximized |= max;
5869 // store the E_Maximize value requested
5870 ec->requested_max = max;
5872 // call the maximize hook of a client
5873 wl_signal_emit_mutable(&PRI(ec)->events.maximize, &max);
5874 _e_client_hook_call(E_CLIENT_HOOK_MAXIMIZE, ec);
5876 // clear the E_Maximize value requested
5877 ec->requested_max = E_MAXIMIZE_NONE;
5879 // store the E_Maximize value
5880 ec->maximized = max;
5881 ec->changes.need_unmaximize = 0;
5883 evas_object_smart_callback_call(ec->frame, "maximize_done", NULL);
5889 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5891 zone = e_comp_zone_find_by_ec(ec);
5893 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
5895 if ((ec->shaded) || (ec->shading)) return;
5897 if ((ec->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION))
5899 if ((ec->maximized & E_MAXIMIZE_TYPE) == (max & E_MAXIMIZE_TYPE))
5905 ec->changes.need_maximize = 1;
5906 ec->maximized &= ~E_MAXIMIZE_TYPE;
5907 ec->maximized |= max;
5912 if (ec->desk_area.enable && ec->desk_area.desk_area)
5914 desk_x = ec->desk_area.desk_area->x;
5915 desk_y = ec->desk_area.desk_area->y;
5919 desk_x = ec->desk->geom.x;
5920 desk_y = ec->desk->geom.y;
5923 evas_object_smart_callback_call(ec->frame, "maximize_pre", NULL);
5926 e_client_unfullscreen(ec);
5927 ec->pre_res_change.valid = 0;
5928 if (!(ec->maximized & E_MAXIMIZE_HORIZONTAL))
5930 /* Horizontal hasn't been set */
5931 ec->saved.x = ec->client.x - desk_x;
5932 ec->saved.w = ec->client.w;
5934 if (!(ec->maximized & E_MAXIMIZE_VERTICAL))
5936 /* Vertical hasn't been set */
5937 ec->saved.y = ec->client.y - desk_y;
5938 ec->saved.h = ec->client.h;
5941 ec->saved.zone = zone->num;
5943 _e_client_maximize(ec, max);
5945 ec->maximized = max;
5946 ec->changes.need_unmaximize = 0;
5948 evas_object_smart_callback_call(ec->frame, "maximize_done", NULL);
5953 e_client_unmaximize(E_Client *ec, E_Maximize max)
5955 #ifdef REFACTOR_ZONE_DESK
5957 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5959 if (!(max & E_MAXIMIZE_DIRECTION))
5961 CRI("BUG: Unmaximize call without direction!");
5966 ec->changes.need_unmaximize = 1;
5971 if ((ec->shaded) || (ec->shading)) return;
5973 /* Remove directions not used */
5974 max &= (ec->maximized & E_MAXIMIZE_DIRECTION);
5975 /* Can only remove existing maximization directions */
5978 evas_object_smart_callback_call(ec->frame, "unmaximize_pre", NULL);
5980 // store the E_Maximize value requested
5981 ec->requested_max = max;
5983 // call the unmaximize hook of a client
5984 wl_signal_emit_mutable(&PRI(ec)->events.unmaximize, &max);
5985 _e_client_hook_call(E_CLIENT_HOOK_UNMAXIMIZE, ec);
5987 // clear the E_Maximize value requested
5988 ec->requested_max = E_MAXIMIZE_NONE;
5990 evas_object_smart_callback_call(ec->frame, "unmaximize_done", NULL);
5991 ec->changes.need_unmaximize = 0;
5996 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5998 zone = e_comp_zone_find_by_ec(ec);
6000 if (!(max & E_MAXIMIZE_DIRECTION))
6002 CRI("BUG: Unmaximize call without direction!");
6007 ec->changes.need_unmaximize = 1;
6012 if ((ec->shaded) || (ec->shading)) return;
6014 /* Remove directions not used */
6015 max &= (ec->maximized & E_MAXIMIZE_DIRECTION);
6016 /* Can only remove existing maximization directions */
6019 evas_object_smart_callback_call(ec->frame, "unmaximize_pre", NULL);
6021 if (ec->maximized & E_MAXIMIZE_TYPE)
6023 ec->pre_res_change.valid = 0;
6024 ec->changes.need_maximize = 0;
6026 if ((ec->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
6028 E_Maximize tmp_max = ec->maximized;
6030 //un-set maximized state for updating frame.
6031 ec->maximized = E_MAXIMIZE_NONE;
6032 _e_client_frame_update(ec);
6033 // re-set maximized state for unmaximize smart callback.
6034 ec->maximized = tmp_max;
6035 evas_object_smart_callback_call(ec->frame, "unfullscreen", NULL);
6036 // un-set maximized state.
6037 ec->maximized = E_MAXIMIZE_NONE;
6038 e_client_util_move_resize_without_frame(ec,
6039 ec->saved.x + zone->x,
6040 ec->saved.y + zone->y,
6041 ec->saved.w, ec->saved.h);
6042 ec->saved.x = ec->saved.y = ec->saved.w = ec->saved.h = 0;
6047 Eina_Bool horiz = EINA_FALSE, vert = EINA_FALSE;
6054 if (max & E_MAXIMIZE_VERTICAL)
6056 /* Remove vertical */
6059 y = ec->saved.y + zone->y;
6060 if ((max & E_MAXIMIZE_VERTICAL) == E_MAXIMIZE_VERTICAL)
6062 ec->maximized &= ~E_MAXIMIZE_VERTICAL;
6063 ec->maximized &= ~E_MAXIMIZE_LEFT;
6064 ec->maximized &= ~E_MAXIMIZE_RIGHT;
6066 if ((max & E_MAXIMIZE_LEFT) == E_MAXIMIZE_LEFT)
6067 ec->maximized &= ~E_MAXIMIZE_LEFT;
6068 if ((max & E_MAXIMIZE_RIGHT) == E_MAXIMIZE_RIGHT)
6069 ec->maximized &= ~E_MAXIMIZE_RIGHT;
6071 if (max & E_MAXIMIZE_HORIZONTAL)
6073 /* Remove horizontal */
6075 x = ec->saved.x + zone->x;
6077 ec->maximized &= ~E_MAXIMIZE_HORIZONTAL;
6080 if (!(ec->maximized & E_MAXIMIZE_DIRECTION))
6082 ec->maximized = E_MAXIMIZE_NONE;
6083 _e_client_frame_update(ec);
6084 evas_object_smart_callback_call(ec->frame, "unmaximize", NULL);
6085 e_client_resize_limit(ec, &w, &h);
6086 e_client_pos_set(ec, x, y);
6087 if ((ec->saved.w != 0) && (ec->saved.h != 0))
6089 if ((w != ec->saved.w) || (h != ec->saved.h))
6091 e_policy_visibility_client_defer_move(ec);
6097 evas_object_smart_callback_call(ec->frame, "unmaximize", NULL);
6098 e_client_resize_limit(ec, &w, &h);
6099 e_client_pos_set(ec, x, y);
6100 if ((ec->saved.w != 0) && (ec->saved.h != 0))
6102 if ((w != ec->saved.w) || (h != ec->saved.h))
6104 e_policy_visibility_client_defer_move(ec);
6109 ec->saved.h = ec->saved.y = 0;
6111 ec->saved.w = ec->saved.x = 0;
6114 evas_object_smart_callback_call(ec->frame, "unmaximize_done", NULL);
6115 ec->changes.need_unmaximize = 0;
6120 e_client_fullscreen(E_Client *ec, E_Fullscreen policy)
6122 #ifdef REFACTOR_ZONE_DESK
6124 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6126 if ((ec->shaded) || (ec->shading) || (ec->fullscreen)) return;
6128 // call the fullscreen_pre hook of a client
6129 wl_signal_emit_mutable(&PRI(ec)->events.fullscreen_pre, NULL);
6130 _e_client_hook_call(E_CLIENT_HOOK_FULLSCREEN_PRE, ec);
6132 ec->fullscreen_policy = policy;
6134 // call the fullscreen hook of a client
6135 wl_signal_emit_mutable(&PRI(ec)->events.fullscreen, &policy);
6136 _e_client_hook_call(E_CLIENT_HOOK_FULLSCREEN, ec);
6138 _e_client_event_simple(ec, E_EVENT_CLIENT_FULLSCREEN);
6144 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6146 zone = e_comp_zone_find_by_ec(ec);
6149 if ((ec->shaded) || (ec->shading) || (ec->fullscreen)) return;
6151 wl_signal_emit_mutable(&PRI(ec)->events.fullscreen_pre, NULL);
6152 _e_client_hook_call(E_CLIENT_HOOK_FULLSCREEN_PRE, ec);
6154 if (ec->skip_fullscreen) return;
6155 if (!ec->desk->visible) return;
6158 ec->need_fullscreen = 1;
6161 if (e_comp->nocomp_ec && (ec->desk == e_comp->nocomp_ec->desk))
6162 e_comp->nocomp_ec = ec;
6163 ec->desk->fullscreen_clients = eina_list_append(ec->desk->fullscreen_clients, ec);
6164 ec->pre_res_change.valid = 0;
6175 ec->saved.x = ec->client.x - zone->x;
6176 ec->saved.y = ec->client.y - zone->y;
6177 ec->saved.w = ec->client.w;
6178 ec->saved.h = ec->client.h;
6180 ec->saved.maximized = ec->maximized;
6181 ec->saved.zone = zone->num;
6185 e_client_unmaximize(ec, E_MAXIMIZE_BOTH);
6192 ec->saved.layer = ec->layer;
6193 e_client_layer_set(ec, E_LAYER_CLIENT_FULLSCREEN);
6196 if ((eina_list_count(e_comp->zones) > 1) ||
6197 (policy == E_FULLSCREEN_RESIZE))
6199 e_client_frame_geometry_set(ec, zone->x, zone->y, zone->w, zone->h);
6201 else if (policy == E_FULLSCREEN_ZOOM)
6203 /* compositor backends! */
6204 evas_object_smart_callback_call(ec->frame, "fullscreen_zoom", NULL);
6207 if (!e_client_util_ignored_get(ec))
6208 _e_client_frame_update(ec);
6209 ec->fullscreen_policy = policy;
6210 evas_object_smart_callback_call(ec->frame, "fullscreen", NULL);
6212 wl_signal_emit_mutable(&PRI(ec)->events.fullscreen, &policy);
6213 _e_client_event_simple(ec, E_EVENT_CLIENT_FULLSCREEN);
6218 e_client_unfullscreen(E_Client *ec)
6220 #ifdef REFACTOR_ZONE_DESK
6222 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6224 if ((ec->shaded) || (ec->shading)) return;
6225 if (!ec->fullscreen) return;
6227 // call the unfullscreen hook of a client
6228 wl_signal_emit_mutable(&PRI(ec)->events.unfullscreen, NULL);
6229 _e_client_hook_call(E_CLIENT_HOOK_UNFULLSCREEN, ec);
6231 _e_client_event_simple(ec, E_EVENT_CLIENT_UNFULLSCREEN);
6236 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6238 zone = e_comp_zone_find_by_ec(ec);
6240 if ((ec->shaded) || (ec->shading)) return;
6241 if (!ec->fullscreen) return;
6242 ec->pre_res_change.valid = 0;
6244 ec->need_fullscreen = 0;
6245 ec->desk->fullscreen_clients = eina_list_remove(ec->desk->fullscreen_clients, ec);
6247 if (ec->fullscreen_policy == E_FULLSCREEN_ZOOM)
6248 evas_object_smart_callback_call(ec->frame, "unfullscreen_zoom", NULL);
6250 if (!e_client_util_ignored_get(ec))
6251 _e_client_frame_update(ec);
6252 ec->fullscreen_policy = 0;
6253 evas_object_smart_callback_call(ec->frame, "unfullscreen", NULL);
6254 e_client_util_move_resize_without_frame(ec, zone->x + ec->saved.x,
6255 zone->y + ec->saved.y,
6256 ec->saved.w, ec->saved.h);
6258 if (ec->saved.maximized)
6259 e_client_maximize(ec, (e_config->maximize_policy & E_MAXIMIZE_TYPE) |
6260 ec->saved.maximized);
6262 e_client_layer_set(ec, ec->saved.layer);
6264 _e_client_event_simple(ec, E_EVENT_CLIENT_UNFULLSCREEN);
6266 if (!ec->desk->fullscreen_clients)
6267 e_comp_render_queue();
6271 ///////////////////////////////////////
6272 #ifdef REFACTOR_ZONE_DESK
6274 e_client_is_parent_iconify_by_client(E_Client *ec)
6277 _e_client_is_parent_iconify_by_client(E_Client *ec)
6280 E_Client *parent = ec->parent;
6281 if (!parent) return EINA_FALSE;
6283 if ((parent->exp_iconify.type == E_ICONIFIED_TYPE_ICONIFY_BY_CLIENT) ||
6284 (parent->exp_iconify.type == E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT))
6291 e_client_iconify(E_Client *ec)
6294 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6296 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
6297 Eina_Bool iconified_by_client = e_client_is_iconified_by_client(ec);
6299 ELOGF("TZVIS", "ICONIFY |iconic:%d |argb:%d |not_raise:%d |by_client:%d, type:%d",
6300 ec, ec->iconic, ec->argb, (unsigned int)ec->exp_iconify.not_raise,
6301 ec->exp_iconify.by_client, ec->exp_iconify.type);
6303 if (ec->shading || ec->iconic) return;
6304 if (ec->exp_iconify.skip_iconify && !iconified_by_client) return;
6305 if (ec->exp_iconify.skip_by_remote) return;
6306 if (!cdata || !cdata->mapped)
6308 if (!iconified_by_client)
6310 ELOGF("TZVIS", "Not mapped.. So, don't iconify", ec);
6315 ELOGF("TZVIS", "Not mapped.. But, iconify by user request", ec);
6319 TRACE_DS_BEGIN(CLIENT:ICONIFY);
6321 #ifdef REFACTOR_ZONE_DESK
6323 e_comp_wl_remote_surface_image_save(ec);
6326 ec->want_focus = ec->take_focus = 0;
6327 ec->changes.visible = 0;
6329 ec->desk->fullscreen_clients = eina_list_remove(ec->desk->fullscreen_clients, ec);
6330 e_client_comp_hidden_set(ec, 1);
6331 evas_object_hide(ec->frame);
6332 e_client_urgent_set(ec, ec->icccm.urgent);
6334 _e_client_event_simple(ec, E_EVENT_CLIENT_ICONIFY);
6336 if (e_config->transient.iconify)
6339 Eina_List *list = eina_list_clone(ec->transients);
6341 EINA_LIST_FREE(list, child)
6343 if ((child->exp_iconify.type != E_ICONIFIED_TYPE_ICONIFY_BY_CLIENT) &&
6344 (_e_client_is_parent_iconify_by_client(child)))
6346 e_client_iconified_type_set(child, E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT);
6347 child->exp_iconify.by_client = 1;
6348 e_policy_client_iconic_state_change_send(child, 1);
6350 e_client_iconify(child);
6356 wl_signal_emit_mutable(&PRI(ec)->events.iconify, NULL);
6357 _e_client_hook_call(E_CLIENT_HOOK_ICONIFY, ec);
6363 e_client_uniconify(E_Client *ec)
6365 #ifdef REFACTOR_ZONE_DESK
6366 E_Comp_Wl_Client_Data *cdata;
6369 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6371 cdata = e_client_cdata_get(ec);
6373 ELOGF("TZVIS", "UNICONIFY|iconic:%d |argb:%d |not_raise:%d |by_client:%d, type:%d |mapped:%d",
6374 ec, ec->iconic, ec->argb, (unsigned int)ec->exp_iconify.not_raise,
6375 ec->exp_iconify.by_client, ec->exp_iconify.type,
6376 cdata ? cdata->mapped : 0);
6378 if (ec->shading || (!ec->iconic)) return;
6380 TRACE_DS_BEGIN(CLIENT:UNICONIFY);
6382 // call the uniconify hook of a client
6383 wl_signal_emit_mutable(&PRI(ec)->events.uniconify, NULL);
6384 _e_client_hook_call(E_CLIENT_HOOK_UNICONIFY, ec);
6389 Eina_Bool not_raise;
6392 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6394 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
6396 ELOGF("TZVIS", "UNICONIFY|iconic:%d |argb:%d |not_raise:%d |by_client:%d, type:%d |mapped:%d",
6397 ec, ec->iconic, ec->argb, (unsigned int)ec->exp_iconify.not_raise,
6398 ec->exp_iconify.by_client, ec->exp_iconify.type,
6399 cdata ? cdata->mapped : 0);
6401 if (ec->shading || (!ec->iconic)) return;
6403 TRACE_DS_BEGIN(CLIENT:UNICONIFY);
6405 e_comp_wl_remote_surface_image_save_cancel(ec);
6407 desk = e_desk_current_get(ec->desk->zone);
6408 e_client_desk_set(ec, desk);
6409 not_raise = ec->exp_iconify.not_raise;
6411 ec->exp_iconify.by_client = 0;
6412 e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_NONE);
6414 if (e_config->transient.iconify)
6417 Eina_List *list = eina_list_clone(ec->transients);
6419 EINA_LIST_FREE(list, child)
6421 if (e_client_transient_policy_get(child) == E_TRANSIENT_BELOW)
6423 child->exp_iconify.not_raise = not_raise;
6424 e_client_uniconify(child);
6434 ELOGF("TZVIS", "UNICONIFY|internal object force show", ec);
6435 evas_object_show(ec->frame);
6440 if (e_pixmap_usable_get(ec->pixmap))
6442 if (cdata && cdata->mapped)
6444 ELOGF("TZVIS", "UNICONIFY|object show. frame_visible:%d", ec, evas_object_visible_get(ec->frame));
6445 evas_object_show(ec->frame);
6449 ELOGF("TZVIS", "UNICONIFY|object no show. currently unmapped", ec);
6454 if (!ec->exp_iconify.buffer_flush &&
6455 !ec->exp_iconify.deiconify_update)
6457 if (cdata && cdata->mapped)
6459 ELOGF("TZVIS", "UNICONIFY|object show. no use buffer flush. frame_visible:%d", ec, evas_object_visible_get(ec->frame));
6460 evas_object_show(ec->frame);
6465 e_client_comp_hidden_set(ec, 0);
6466 ec->deskshow = ec->iconic = 0;
6468 #if 0 // focus should be set to the top window not uniconify window
6469 if (ec->pixmap && e_pixmap_usable_get(ec->pixmap))
6470 e_client_frame_focus_set(ec, EINA_TRUE);
6473 _e_client_event_simple(ec, E_EVENT_CLIENT_UNICONIFY);
6475 if (e_config->transient.iconify)
6478 Eina_List *list = eina_list_clone(ec->transients);
6480 EINA_LIST_FREE(list, child)
6482 if (e_client_transient_policy_get(child) == E_TRANSIENT_ABOVE)
6484 if (child->exp_iconify.type == E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT)
6485 e_policy_client_iconic_state_change_send(child, 0);
6486 child->exp_iconify.not_raise = not_raise;
6487 e_client_uniconify(child);
6492 wl_signal_emit_mutable(&PRI(ec)->events.uniconify, NULL);
6493 _e_client_hook_call(E_CLIENT_HOOK_UNICONIFY, ec);
6495 ec->exp_iconify.not_raise = 0;
6502 e_client_iconified_type_set(E_Client *ec, E_Iconified_Type type)
6505 ec->exp_iconify.type = type;
6508 EINTERN E_Iconified_Type
6509 e_client_iconified_type_get(E_Client *ec)
6511 if (!ec) return E_ICONIFIED_TYPE_NONE;
6512 return ec->exp_iconify.type;
6515 E_API Eina_Bool e_client_is_iconified_by_client(E_Client *ec)
6517 if (!ec) return EINA_FALSE;
6519 if (ec->exp_iconify.type == E_ICONIFIED_TYPE_ICONIFY_BY_CLIENT)
6522 if (ec->exp_iconify.type == E_ICONIFIED_TYPE_DESK_ICONIFY_BY_CLIENT)
6525 if (ec->exp_iconify.type == E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT)
6528 if (ec->exp_iconify.by_client)
6530 ELOGF("POL", "CHECK. mismatch value. by_client:%d, type:%d", ec, ec->exp_iconify.by_client, ec->exp_iconify.type);
6537 ///////////////////////////////////////
6540 e_client_urgent_set(E_Client *ec, Eina_Bool urgent)
6543 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6546 if (urgent == ec->urgent) return;
6547 _e_client_event_property(ec, E_CLIENT_PROPERTY_URGENCY);
6548 if (urgent && (!ec->focused) && (!ec->want_focus))
6550 e_comp_object_signal_emit(ec->frame, "e,state,urgent", "e");
6551 ec->urgent = urgent;
6555 e_comp_object_signal_emit(ec->frame, "e,state,not_urgent", "e");
6560 ///////////////////////////////////////
6563 e_client_stick(E_Client *ec)
6565 #ifdef REFACTOR_ZONE_DESK
6567 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6568 if (ec->sticky) return;
6570 // call the stick hook of a client
6571 wl_signal_emit_mutable(&PRI(ec)->events.stick, NULL);
6572 _e_client_hook_call(E_CLIENT_HOOK_STICK, ec);
6574 // send the sticky property event of a client
6575 _e_client_event_property(ec, E_CLIENT_PROPERTY_STICKY);
6580 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6581 if (ec->sticky) return;
6586 e_client_desk_set(ec, desk);
6587 evas_object_smart_callback_call(ec->frame, "stick", NULL);
6589 if (e_config->transient.desktop)
6592 Eina_List *list = eina_list_clone(ec->transients);
6594 EINA_LIST_FREE(list, child)
6597 evas_object_show(ec->frame);
6601 _e_client_event_property(ec, E_CLIENT_PROPERTY_STICKY);
6606 e_client_unstick(E_Client *ec)
6608 #ifdef REFACTOR_ZONE_DESK
6610 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6612 if (!ec->sticky) return;
6614 // call the unstick hook of a client
6615 wl_signal_emit_mutable(&PRI(ec)->events.unstick, NULL);
6616 _e_client_hook_call(E_CLIENT_HOOK_UNSTICK, ec);
6618 // send the sticky property event of a client
6619 _e_client_event_property(ec, E_CLIENT_PROPERTY_STICKY);
6625 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6626 /* Set the desk before we unstick the client */
6627 if (!ec->sticky) return;
6629 zone = e_comp_zone_find_by_ec(ec);
6630 desk = e_desk_current_get(zone);
6632 ec->hidden = ec->sticky = 0;
6633 e_client_desk_set(ec, desk);
6634 evas_object_smart_callback_call(ec->frame, "unstick", NULL);
6636 if (e_config->transient.desktop)
6639 Eina_List *list = eina_list_clone(ec->transients);
6641 EINA_LIST_FREE(list, child)
6647 _e_client_event_property(ec, E_CLIENT_PROPERTY_STICKY);
6649 e_client_desk_set(ec, e_desk_current_get(zone));
6654 e_client_pinned_set(E_Client *ec, Eina_Bool set)
6658 EINA_SAFETY_ON_NULL_RETURN(ec);
6660 layer = E_LAYER_CLIENT_ABOVE;
6662 layer = E_LAYER_CLIENT_NORMAL;
6664 e_client_layer_set(ec, layer);
6669 ///////////////////////////////////////
6672 e_client_border_set(E_Client *ec, const char *name)
6674 Eina_Stringshare *pborder;
6676 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
6677 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
6678 if (!e_comp_object_frame_allowed(ec->frame)) return EINA_FALSE;
6679 if (ec->border.changed)
6680 CRI("CALLING WHEN border.changed SET!");
6682 if (!e_util_strcmp(ec->border.name, name)) return EINA_TRUE;
6683 if (ec->mwm.borderless && name && strcmp(name, "borderless"))
6685 CRI("border change attempted for MWM borderless client!");
6687 pborder = ec->border.name;
6688 ec->border.name = eina_stringshare_add(name);
6689 if (e_comp_object_frame_theme_set(ec->frame, name))
6691 eina_stringshare_del(pborder);
6694 eina_stringshare_del(ec->border.name);
6695 ec->border.name = pborder;
6699 ///////////////////////////////////////
6702 e_client_comp_hidden_set(E_Client *ec, Eina_Bool hidden)
6705 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6708 if (ec->comp_hidden == hidden) return;
6709 ec->comp_hidden = hidden;
6710 evas_object_smart_callback_call(ec->frame, "comp_hidden", NULL);
6713 ///////////////////////////////////////
6716 e_client_act_move_keyboard(E_Client *ec)
6718 EINA_SAFETY_ON_NULL_RETURN(ec);
6720 if (!_e_client_move_begin(ec))
6723 _e_client_action_init(ec);
6724 _e_client_action_move_timeout_add();
6726 wl_signal_emit_mutable(&PRI(ec)->events.move_update, NULL);
6727 if (!_e_client_hook_call(E_CLIENT_HOOK_MOVE_UPDATE, ec)) return;
6728 evas_object_freeze_events_set(ec->frame, 1);
6730 if (!action_handler_mouse)
6731 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_client_move_mouse_down, NULL);
6735 e_client_act_resize_keyboard(E_Client *ec)
6737 EINA_SAFETY_ON_NULL_RETURN(ec);
6739 ec->resize_mode = E_POINTER_RESIZE_TL;
6740 ec->keyboard_resizing = 1;
6741 if (!e_client_resize_begin(ec))
6743 ec->keyboard_resizing = 0;
6747 _e_client_action_init(ec);
6748 _e_client_action_resize_timeout_add();
6749 evas_object_freeze_events_set(ec->frame, 1);
6751 if (!action_handler_mouse)
6752 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_client_resize_mouse_down, NULL);
6756 e_client_act_move_begin(E_Client *ec, E_Binding_Event_Mouse_Button *ev)
6759 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6760 if (e_client_util_resizing_get(ec) || (ec->moving)) return;
6765 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->button);
6766 _e_client_moveinfo_gather(ec, source);
6768 if (!_e_client_move_begin(ec))
6771 _e_client_action_init(ec);
6775 e_client_act_move_end(E_Client *ec, E_Binding_Event_Mouse_Button *ev EINA_UNUSED)
6778 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6779 if (!ec->moving) return;
6780 _e_client_move_end(ec);
6781 _e_client_action_finish();
6785 e_client_act_resize_begin(E_Client *ec, E_Binding_Event_Mouse_Button *ev, E_Pointer_Mode resize_mode)
6788 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6789 if (ec->lock_user_size || ec->shaded || ec->shading) return;
6790 if (e_client_util_resizing_get(ec) || (ec->moving)) return;
6794 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->button);
6795 _e_client_moveinfo_gather(ec, source);
6797 if (resize_mode != E_POINTER_RESIZE_NONE)
6799 ec->resize_mode = resize_mode;
6803 /* Use canvas.x, canvas.y of event.
6804 * Transformed coordinates has to be considered for accurate resize_mode
6805 * rather than absolute coordinates. */
6806 if ((ev->canvas.x > (ec->x + ec->w / 5)) &&
6807 (ev->canvas.x < (ec->x + ec->w * 4 / 5)))
6809 if (ev->canvas.y < (ec->y + ec->h / 2)) ec->resize_mode = E_POINTER_RESIZE_T;
6810 else ec->resize_mode = E_POINTER_RESIZE_B;
6812 else if (ev->canvas.x < (ec->x + ec->w / 2))
6814 if ((ev->canvas.y > (ec->y + ec->h / 5)) && (ev->canvas.y < (ec->y + ec->h * 4 / 5))) ec->resize_mode = E_POINTER_RESIZE_L;
6815 else if (ev->canvas.y < (ec->y + ec->h / 2)) ec->resize_mode = E_POINTER_RESIZE_TL;
6816 else ec->resize_mode = E_POINTER_RESIZE_BL;
6820 if ((ev->canvas.y > (ec->y + ec->h / 5)) && (ev->canvas.y < (ec->y + ec->h * 4 / 5))) ec->resize_mode = E_POINTER_RESIZE_R;
6821 else if (ev->canvas.y < (ec->y + ec->h / 2)) ec->resize_mode = E_POINTER_RESIZE_TR;
6822 else ec->resize_mode = E_POINTER_RESIZE_BR;
6826 if (!e_client_resize_begin(ec))
6828 _e_client_action_init(ec);
6832 e_client_act_resize_end(E_Client *ec, E_Binding_Event_Mouse_Button *ev EINA_UNUSED)
6835 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6836 if (e_client_util_resizing_get(ec))
6838 _e_client_resize_end(ec);
6839 ec->changes.reset_gravity = 1;
6840 if (!e_object_is_del(E_OBJECT(ec)))
6843 _e_client_action_finish();
6847 e_client_act_menu_begin(E_Client *ec, E_Binding_Event_Mouse_Button *ev, int key)
6850 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6854 e_client_act_close_begin(E_Client *ec)
6857 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6858 if (ec->lock_close) return;
6859 if (ec->icccm.delete_request)
6861 ec->delete_requested = 1;
6862 evas_object_smart_callback_call(ec->frame, "delete_request", NULL);
6864 else if (e_config->kill_if_close_not_possible)
6866 e_client_act_kill_begin(ec);
6871 e_client_act_kill_begin(E_Client *ec)
6874 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6875 if (ec->internal) return;
6876 if (ec->lock_close) return;
6877 if ((ec->netwm.pid > 1) && (e_config->kill_process))
6879 kill(ec->netwm.pid, SIGINT);
6880 ec->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
6881 _e_client_cb_kill_timer, ec);
6884 evas_object_smart_callback_call(ec->frame, "kill_request", NULL);
6887 ////////////////////////////////////////////
6890 e_client_ping(E_Client *ec)
6893 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6895 if (!e_config->ping_clients) return;
6897 EINA_SAFETY_ON_TRUE_RETURN(e_object_is_del(E_OBJECT(ec)));
6900 evas_object_smart_callback_call(ec->frame, "ping", NULL);
6901 ec->ping = ecore_loop_time_get();
6902 if (ec->ping_poller) ecore_poller_del(ec->ping_poller);
6903 ec->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
6904 e_config->ping_clients_interval,
6905 _e_client_cb_ping_poller, ec);
6908 ////////////////////////////////////////////
6910 e_client_cursor_map_apply(E_Client *ec, int rotation, int x, int y)
6912 // TODO: remove(deprecate) this e_client_cursor_map_apply.
6916 e_client_move_cancel(void)
6918 if (!ecmove) return;
6919 if (ecmove->cur_mouse_action)
6924 e_object_ref(E_OBJECT(ec));
6925 if (ec->cur_mouse_action->func.end_mouse)
6926 ec->cur_mouse_action->func.end_mouse(E_OBJECT(ec), "", NULL);
6927 else if (ec->cur_mouse_action->func.end)
6928 ec->cur_mouse_action->func.end(E_OBJECT(ec), "");
6929 e_object_unref(E_OBJECT(ec->cur_mouse_action));
6930 ec->cur_mouse_action = NULL;
6931 e_object_unref(E_OBJECT(ec));
6934 _e_client_move_end(ecmove);
6938 e_client_resize_cancel(void)
6940 if (!ecresize) return;
6941 if (ecresize->cur_mouse_action)
6946 e_object_ref(E_OBJECT(ec));
6947 if (ec->cur_mouse_action->func.end_mouse)
6948 ec->cur_mouse_action->func.end_mouse(E_OBJECT(ec), "", NULL);
6949 else if (ec->cur_mouse_action->func.end)
6950 ec->cur_mouse_action->func.end(E_OBJECT(ec), "");
6951 e_object_unref(E_OBJECT(ec->cur_mouse_action));
6952 ec->cur_mouse_action = NULL;
6953 e_object_unref(E_OBJECT(ec));
6956 _e_client_resize_end(ecresize);
6960 e_client_resize_begin(E_Client *ec)
6962 if ((ec->shaded) || (ec->shading) ||
6963 (ec->fullscreen) || (ec->lock_user_size))
6965 if (!_e_client_action_input_win_new()) goto error;
6967 if (ec->manage_resize.enable_aspect_ratio)
6969 ELOGF("RESIZE", "Set resize aspect ratio.. ratio(%dx%d)", ec, ec->w, ec->h);
6970 ec->manage_resize.aw = ec->w;
6971 ec->manage_resize.ah = ec->h - ec->manage_resize.header_h - ec->manage_resize.footer_h;
6974 wl_signal_emit_mutable(&PRI(ec)->events.move_begin, NULL);
6975 _e_client_hook_call(E_CLIENT_HOOK_RESIZE_BEGIN, ec);
6976 if (ec->transformed)
6977 _e_client_transform_resize_begin(ec);
6978 if (!e_client_util_resizing_get(ec))
6980 if (ecresize == ec) ecresize = NULL;
6981 _e_client_action_input_win_del();
6984 if (!ec->lock_user_stacking)
6986 if (e_config->border_raise_on_mouse_action)
6991 e_comp_client_override_add(ec);
6995 ec->resize_mode = E_POINTER_RESIZE_NONE;
7000 ////////////////////////////////////////////
7003 e_client_frame_recalc(E_Client *ec)
7005 EINA_SAFETY_ON_NULL_RETURN(ec);
7006 if (!ec->frame) return;
7007 evas_object_smart_callback_call(ec->frame, "frame_recalc", NULL);
7010 ////////////////////////////////////////////
7013 e_client_signal_move_begin(E_Client *ec, const char *sig, const char *src EINA_UNUSED)
7016 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
7018 if (e_client_util_resizing_get(ec) || (ec->moving)) return;
7019 _e_client_moveinfo_gather(ec, sig);
7020 if (!_e_client_move_begin(ec)) return;
7024 e_client_signal_move_end(E_Client *ec, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
7027 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
7028 if (!ec->moving) return;
7029 _e_client_move_end(ec);
7033 e_client_signal_resize_begin(E_Client *ec, const char *dir, const char *sig, const char *src EINA_UNUSED)
7035 int resize_mode = E_POINTER_RESIZE_BR;
7038 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
7040 if (e_client_util_resizing_get(ec) || (ec->moving)) return;
7041 if (!strcmp(dir, "tl"))
7043 resize_mode = E_POINTER_RESIZE_TL;
7045 else if (!strcmp(dir, "t"))
7047 resize_mode = E_POINTER_RESIZE_T;
7049 else if (!strcmp(dir, "tr"))
7051 resize_mode = E_POINTER_RESIZE_TR;
7053 else if (!strcmp(dir, "r"))
7055 resize_mode = E_POINTER_RESIZE_R;
7057 else if (!strcmp(dir, "br"))
7059 resize_mode = E_POINTER_RESIZE_BR;
7061 else if (!strcmp(dir, "b"))
7063 resize_mode = E_POINTER_RESIZE_B;
7065 else if (!strcmp(dir, "bl"))
7067 resize_mode = E_POINTER_RESIZE_BL;
7069 else if (!strcmp(dir, "l"))
7071 resize_mode = E_POINTER_RESIZE_L;
7073 ec->resize_mode = resize_mode;
7074 _e_client_moveinfo_gather(ec, sig);
7075 if (!e_client_resize_begin(ec))
7080 e_client_signal_resize_end(E_Client *ec, const char *dir EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
7083 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
7084 if (!e_client_util_resizing_get(ec)) return;
7085 _e_client_resize_handle(ec);
7086 _e_client_resize_end(ec);
7087 ec->changes.reset_gravity = 1;
7091 ////////////////////////////////////////////
7094 e_client_resize_limit(E_Client *ec, int *w, int *h)
7100 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
7102 inc_h = (*h - ec->h > 0);
7104 e_comp_object_frame_wh_unadjust(ec->frame, *w, *h, w, h);
7107 if ((ec->icccm.base_w >= 0) &&
7108 (ec->icccm.base_h >= 0))
7112 tw = *w - ec->icccm.base_w;
7113 th = *h - ec->icccm.base_h;
7116 a = (double)(tw) / (double)(th);
7117 if ((ec->icccm.min_aspect != 0.0) &&
7118 (a < ec->icccm.min_aspect))
7121 tw = th * ec->icccm.min_aspect;
7123 th = tw / ec->icccm.max_aspect;
7124 *w = tw + ec->icccm.base_w;
7125 *h = th + ec->icccm.base_h;
7127 else if ((ec->icccm.max_aspect != 0.0) &&
7128 (a > ec->icccm.max_aspect))
7130 tw = th * ec->icccm.max_aspect;
7131 *w = tw + ec->icccm.base_w;
7136 a = (double)*w / (double)*h;
7137 if ((ec->icccm.min_aspect != 0.0) &&
7138 (a < ec->icccm.min_aspect))
7141 *w = *h * ec->icccm.min_aspect;
7143 *h = *w / ec->icccm.min_aspect;
7145 else if ((ec->icccm.max_aspect != 0.0) &&
7146 (a > ec->icccm.max_aspect))
7147 *w = *h * ec->icccm.max_aspect;
7149 if (ec->icccm.step_w > 0)
7151 if (ec->icccm.base_w >= 0)
7152 *w = ec->icccm.base_w +
7153 (((*w - ec->icccm.base_w) / ec->icccm.step_w) *
7156 *w = ec->icccm.min_w +
7157 (((*w - ec->icccm.min_w) / ec->icccm.step_w) *
7160 if (ec->icccm.step_h > 0)
7162 if (ec->icccm.base_h >= 0)
7163 *h = ec->icccm.base_h +
7164 (((*h - ec->icccm.base_h) / ec->icccm.step_h) *
7167 *h = ec->icccm.min_h +
7168 (((*h - ec->icccm.min_h) / ec->icccm.step_h) *
7175 if ((ec->icccm.max_w > 0) && (*w > ec->icccm.max_w)) *w = ec->icccm.max_w;
7176 else if (*w < ec->icccm.min_w)
7177 *w = ec->icccm.min_w;
7178 if ((ec->icccm.max_h > 0) && (*h > ec->icccm.max_h)) *h = ec->icccm.max_h;
7179 else if (*h < ec->icccm.min_h)
7180 *h = ec->icccm.min_h;
7183 e_comp_object_frame_wh_adjust(ec->frame, *w, *h, w, h);
7186 ////////////////////////////////////////////
7191 e_client_under_pointer_get(E_Desk *desk, E_Client *exclude)
7195 /* We need to ensure that we can get the comp window for the
7196 * zone of either the given desk or the desk of the excluded
7197 * window, so return if neither is given */
7199 e_input_device_pointer_xy_get(NULL, &x, &y);
7201 e_input_device_pointer_xy_get(NULL, &x, &y);
7207 desk = exclude->desk;
7211 desk = e_desk_current_get(exclude->zone);
7213 desk = e_desk_current_get(e_zone_current_get());
7217 return desk ? _e_client_under_pointer_helper(desk, exclude, x, y) : NULL;
7220 E_API E_Client *e_client_under_position_get(E_Desk *desk, int x, int y, E_Client *exclude)
7222 if (!desk) return NULL;
7224 return _e_client_under_pointer_helper(desk, exclude, x, y);
7227 E_API E_Client *e_client_under_position_input_get(E_Desk *desk, int x, int y)
7229 if (!desk) return NULL;
7231 return _e_client_under_pointer_input_helper(desk, x, y);
7235 e_client_input_rect_under_pointer_get(E_Desk *desk, E_Client *exclude)
7239 /* We need to ensure that we can get the comp window for the
7240 * zone of either the given desk or the desk of the excluded
7241 * window, so return if neither is given */
7243 e_input_device_pointer_xy_get(NULL, &x, &y);
7245 e_input_device_pointer_xy_get(NULL, &x, &y);
7251 desk = exclude->desk;
7255 desk = e_desk_current_get(exclude->zone);
7257 desk = e_desk_current_get(e_zone_current_get());
7261 return desk ? _e_client_input_rect_under_pointer_helper(desk, exclude, x, y) : NULL;
7264 ////////////////////////////////////////////
7266 ////////////////////////////////////////////
7269 e_client_redirected_set(E_Client *ec, Eina_Bool set)
7271 EINA_SAFETY_ON_NULL_RETURN(ec);
7272 if (ec->input_only) return;
7274 if (ec->redirected == set) return;
7277 e_client_frame_recalc(ec);
7279 wl_signal_emit_mutable(&PRI(ec)->events.redirect, NULL);
7280 if (!_e_client_hook_call(E_CLIENT_HOOK_REDIRECT, ec)) return;
7284 wl_signal_emit_mutable(&PRI(ec)->events.unredirect, NULL);
7285 if (!_e_client_hook_call(E_CLIENT_HOOK_UNREDIRECT, ec)) return;
7287 e_comp_object_redirected_set(ec->frame, set);
7288 ec->redirected = !!set;
7291 ////////////////////////////////////////////
7294 e_client_is_stacking(const E_Client *ec)
7296 return e_comp->layers[e_comp_canvas_layer_map(ec->layer)].obj == ec->frame;
7299 ////////////////////////////////////////////
7302 e_client_transform_update(E_Client *ec)
7304 if (e_client_util_resizing_get(ec))
7305 _e_client_transform_resize(ec);
7308 ////////////////////////////////////////////
7311 e_client_transform_apply(E_Client *ec, double angle, double zoom, int cx, int cy)
7314 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
7318 if (e_comp_wl_subsurface_check(ec))
7321 /* check if it's different with current state */
7322 if ((ec->transform.angle == angle) &&
7323 (ec->transform.zoom == zoom) &&
7324 (ec->transform.center.x == cx) &&
7325 (ec->transform.center.y == cy))
7328 /* use previous value if any required value is invalid */
7330 angle = ec->transform.angle;
7332 zoom = ec->transform.zoom;
7333 if (!E_INSIDE(cx, cy,
7334 ec->client.x, ec->client.y,
7335 ec->client.w, ec->client.h))
7337 cx = ec->transform.center.x;
7338 cy = ec->transform.center.y;
7341 if ((angle == 0) && (zoom == 1.0))
7343 e_client_transform_clear(ec);
7347 map = e_map_new_with_direct_render(ec->transform_core.direct_render);
7348 e_map_util_points_populate_from_object_full(map, ec->frame, 0);
7350 e_map_util_rotate(map, angle, cx, cy);
7351 _e_client_transform_geometry_save(ec, map);
7353 e_map_util_zoom(map, zoom, zoom, cx, cy);
7355 e_map_util_object_move_sync_set(map, EINA_TRUE);
7356 e_client_map_set(ec, map);
7357 e_client_map_enable_set(ec, EINA_TRUE);
7359 EINA_LIST_FOREACH(cdata->sub.list, l, subc)
7360 _e_client_transform_sub_apply(subc, ec, zoom);
7361 EINA_LIST_REVERSE_FOREACH(cdata->sub.below_list, l, subc)
7362 _e_client_transform_sub_apply(subc, ec, zoom);
7366 ec->transform.zoom = zoom;
7367 ec->transform.angle = angle;
7368 ec->transform.center.x = cx;
7369 ec->transform.center.y = cy;
7370 ec->transformed = EINA_TRUE;
7373 ////////////////////////////////////////////
7376 e_client_transform_clear(E_Client *ec)
7378 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
7382 e_client_map_enable_set(ec, EINA_FALSE);
7383 e_client_map_set(ec, NULL);
7385 EINA_LIST_FOREACH(cdata->sub.list, l, subc)
7386 _e_client_transform_sub_apply(subc, ec, 1.0);
7387 EINA_LIST_REVERSE_FOREACH(cdata->sub.below_list, l, subc)
7388 _e_client_transform_sub_apply(subc, ec, 1.0);
7390 ec->transform.zoom = 1.0;
7391 ec->transform.angle = 0.0;
7392 ec->transformed = EINA_FALSE;
7396 e_client_transform_core_enable_get(E_Client *ec)
7398 if (!ec) return EINA_FALSE;
7399 return ec->transform_core.result.enable;
7403 e_client_transform_core_add(E_Client *ec, E_Util_Transform *transform)
7406 if (!transform) return;
7408 // duplication check
7409 if (ec->transform_core.transform_list &&
7410 eina_list_data_find(ec->transform_core.transform_list, transform) == transform)
7415 ec->transform_core.transform_list = eina_list_append(ec->transform_core.transform_list, transform);
7416 ec->transform_core.changed = EINA_TRUE;
7417 e_util_transform_ref(transform);
7418 // e_client_transform_core_update(ec);
7422 e_client_transform_core_remove(E_Client *ec, E_Util_Transform *transform)
7425 if (!transform) return;
7427 if (ec->transform_core.transform_list &&
7428 eina_list_data_find(ec->transform_core.transform_list, transform) == transform)
7430 ec->transform_core.transform_list = eina_list_remove(ec->transform_core.transform_list, transform);
7431 e_util_transform_unref(transform);
7432 ec->transform_core.changed = EINA_TRUE;
7435 e_client_transform_core_update(ec);
7439 e_client_transform_core_update(E_Client *ec)
7442 if (ec->new_client) return;
7443 if (!_e_client_transform_core_check_change(ec)) return;
7445 if (ec->transform_core.transform_list || ec->transform_core.parent.enable)
7447 E_Util_Transform_Rect source_rect;
7448 E_Util_Transform_Matrix matrix, boundary_matrix;
7449 E_Util_Transform_Zoom zoom;
7451 Eina_Bool background;
7452 E_Util_Transform *temp_trans;
7455 ec->transform_core.result.enable = EINA_TRUE;
7456 e_util_transform_rect_client_rect_get(&source_rect, ec);
7457 e_util_transform_init(&ec->transform_core.result.transform);
7459 // 2. merge transform
7460 EINA_LIST_FOREACH(ec->transform_core.transform_list, l, temp_trans)
7462 e_util_transform_merge(&ec->transform_core.result.transform, temp_trans);
7464 zoom = ec->transform_core.result.transform.zoom;
7466 // 2.5 check viewport
7467 if (e_util_transform_viewport_flag_get(&ec->transform_core.result.transform))
7469 int vx = 0, vy = 0, vw = 0, vh = 0;
7470 e_util_transform_viewport_get(&ec->transform_core.result.transform, &vx, &vy, &vw, &vh);
7471 e_util_transform_rect_init(&source_rect, vx, vy, vw, vh);
7474 // 3. apply background transform
7475 matrix = e_util_transform_convert_to_matrix(&ec->transform_core.result.transform, &source_rect);
7477 if (e_util_transform_bg_transform_flag_get(&ec->transform_core.result.transform))
7479 boundary_matrix = e_util_transform_bg_convert_to_matrix(&ec->transform_core.result.transform, &source_rect);
7480 background = EINA_TRUE;
7484 background = EINA_FALSE;
7485 boundary_matrix = matrix;
7488 if (background != ec->transform_core.background)
7492 e_comp_object_transform_bg_set(ec->frame, EINA_TRUE);
7496 e_comp_object_transform_bg_set(ec->frame, EINA_FALSE);
7499 ec->transform_core.background = background;
7502 // 3.1 if 24bit window then set transp rect
7507 e_util_transform_rotation_round_get(&ec->transform_core.result.transform, 0, 0, &angle);
7510 if (angle == 0) // when transform angle is 0, 90, 180, 270, 360. then set transp rect
7511 e_comp_object_transform_transp_set(ec->frame, EINA_TRUE);
7513 e_comp_object_transform_transp_set(ec->frame, EINA_FALSE);
7516 e_comp_object_transform_transp_set(ec->frame, EINA_FALSE);
7518 // 3.5 parent matrix multiply
7519 if (ec->transform_core.parent.enable)
7521 matrix = e_util_transform_matrix_multiply(&ec->transform_core.parent.matrix,
7523 boundary_matrix = e_util_transform_matrix_multiply(&ec->transform_core.parent.matrix,
7526 ec->transform_core.result.transform.use_zoom = EINA_TRUE;
7527 zoom.zoom_x *= ec->transform_core.parent.zoom.zoom_x;
7528 zoom.zoom_y *= ec->transform_core.parent.zoom.zoom_y;
7529 zoom.cx += ec->transform_core.parent.zoom.cx;
7530 zoom.cy += ec->transform_core.parent.zoom.cy;
7533 // 4. apply matrix to vertices
7534 ec->transform_core.result.matrix = matrix;
7535 ec->transform_core.result.inv_matrix = e_util_transform_matrix_inverse_get(&matrix);
7536 ec->transform_core.result.vertices = e_util_transform_rect_to_vertices(&source_rect);
7537 ec->transform_core.result.boundary.vertices = e_util_transform_rect_to_vertices(&source_rect);
7538 ec->transform_core.result.vertices = e_util_transform_matrix_multiply_rect_vertex(&matrix,
7539 &ec->transform_core.result.vertices);
7540 ec->transform_core.result.boundary.vertices = e_util_transform_matrix_multiply_rect_vertex(&boundary_matrix,
7541 &ec->transform_core.result.boundary.vertices);
7542 ec->transform_core.result.transform.zoom = zoom;
7544 // 5. apply vertices
7545 if (ec->transform_core.result.transform.use_zoom)
7547 // TODO: apply zoom values to vertices
7548 e_comp_object_transform_transp_vertices_set_with_zoom(ec->frame, &ec->transform_core.result.vertices,
7549 ec->transform_core.result.transform.zoom);
7550 e_comp_object_transform_bg_vertices_set_with_zoom(ec->frame, &ec->transform_core.result.boundary.vertices,
7551 ec->transform_core.result.transform.zoom);
7552 _e_client_transform_core_boundary_update(ec, &ec->transform_core.result.boundary.vertices);
7553 _e_client_transform_core_vertices_apply_with_zoom(ec, ec->frame, &ec->transform_core.result.vertices, &ec->transform_core.result.transform,
7554 ec->transform_core.result.transform.zoom);
7558 e_comp_object_transform_transp_vertices_set(ec->frame, &ec->transform_core.result.vertices);
7559 e_comp_object_transform_bg_vertices_set(ec->frame, &ec->transform_core.result.boundary.vertices);
7560 _e_client_transform_core_boundary_update(ec, &ec->transform_core.result.boundary.vertices);
7561 _e_client_transform_core_vertices_apply(ec, ec->frame, &ec->transform_core.result.vertices, &ec->transform_core.result.transform);
7564 // 6. subsurface update
7565 _e_client_transform_core_sub_update(ec, &ec->transform_core.result.vertices);
7567 if (!e_object_is_del(E_OBJECT(ec)))
7569 wl_signal_emit_mutable(&PRI(ec)->events.transform_change, NULL);
7570 _e_client_hook_call(E_CLIENT_HOOK_TRANSFORM_CHANGE, ec);
7575 if (ec->transform_core.result.enable)
7577 ec->transform_core.result.enable = EINA_FALSE;
7578 _e_client_transform_core_vertices_apply(ec, ec->frame, NULL, NULL);
7579 e_comp_object_transform_bg_set(ec->frame, EINA_FALSE);
7580 ec->transform_core.background = EINA_FALSE;
7581 e_comp_object_transform_transp_set(ec->frame, EINA_FALSE);
7582 _e_client_transform_core_sub_update(ec, NULL);
7584 if (!e_object_is_del(E_OBJECT(ec)))
7586 wl_signal_emit_mutable(&PRI(ec)->events.transform_change, NULL);
7587 _e_client_hook_call(E_CLIENT_HOOK_TRANSFORM_CHANGE, ec);
7592 e_comp_visibility_calculation_set(EINA_TRUE);
7596 e_client_transform_core_transform_count_get(E_Client *ec)
7599 if (!ec->transform_core.transform_list) return 0;
7600 return eina_list_count(ec->transform_core.transform_list);
7603 E_API E_Util_Transform*
7604 e_client_transform_core_transform_get(E_Client *ec, int index)
7606 if (!ec) return NULL;
7607 if (!ec->transform_core.transform_list) return NULL;
7608 if (index < 0 || index >= e_client_transform_core_transform_count_get(ec))
7611 return (E_Util_Transform*)eina_list_nth(ec->transform_core.transform_list, index);
7615 e_client_transform_core_input_transform(E_Client *ec, int x, int y, int *out_x, int *out_y)
7617 E_Util_Transform_Vertex vertex, result_vertex;
7620 if (!e_client_transform_core_enable_get(ec)) return;
7622 e_util_transform_vertex_init(&vertex, x, y, 0.0, 1.0);
7624 result_vertex = e_util_transform_matrix_multiply_vertex(&ec->transform_core.result.inv_matrix, &vertex);
7625 e_util_transform_vertex_pos_round_get(&result_vertex, out_x, out_y, NULL, NULL);
7629 e_client_transform_core_input_inv_transform(E_Client *ec, int x, int y, int *out_x, int *out_y)
7631 E_Util_Transform_Vertex vertex, result_vertex;
7634 if (!e_client_transform_core_enable_get(ec)) return;
7636 e_util_transform_vertex_init(&vertex, x, y, 0.0, 1.0);
7638 result_vertex = e_util_transform_matrix_multiply_vertex(&ec->transform_core.result.matrix, &vertex);
7639 e_util_transform_vertex_pos_round_get(&result_vertex, out_x, out_y, NULL, NULL);
7643 e_client_transform_core_input_inv_rect_transform(E_Client *ec, int x, int y, int *out_x, int *out_y)
7647 if (!e_client_transform_core_enable_get(ec)) return;
7648 e_client_geometry_get(ec, NULL, NULL, &gw, &gh);
7650 e_util_transform_matrix_inv_rect_coords_get(&ec->transform_core.result.transform,
7651 &ec->transform_core.result.vertices,
7653 x, y, out_x, out_y);
7657 e_client_transform_core_direct_render_set(E_Client *ec, Eina_Bool set)
7659 EINA_SAFETY_ON_NULL_RETURN(ec);
7661 if (ec->transform_core.direct_render == set) return;
7663 ec->transform_core.direct_render = set;
7664 ec->transform_core.changed = EINA_TRUE;
7666 e_client_transform_core_update(ec);
7670 e_client_pixmap_change(E_Client *ec, E_Pixmap *newcp)
7672 E_Pixmap_Type oldtype, newtype;
7675 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
7676 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->pixmap, NULL);
7677 EINA_SAFETY_ON_NULL_RETURN_VAL(newcp, NULL);
7681 oldtype = e_pixmap_type_get(oldcp);
7682 if (oldtype >= E_PIXMAP_TYPE_MAX) return NULL;
7684 newtype = e_pixmap_type_get(newcp);
7685 if (newtype >= E_PIXMAP_TYPE_MAX) return NULL;
7687 if (eina_hash_find(clients_hash[oldtype], &oldcp))
7688 eina_hash_del_by_key(clients_hash[oldtype], &oldcp);
7689 e_pixmap_client_set(oldcp, NULL);
7692 e_pixmap_client_set(newcp, ec);
7694 eina_hash_add(clients_hash[newtype], &newcp, ec);
7700 e_client_window_role_set(E_Client *ec, const char *role)
7702 EINA_SAFETY_ON_NULL_RETURN(ec);
7704 if (eina_stringshare_replace(&ec->icccm.window_role, role))
7706 wl_signal_emit_mutable(&PRI(ec)->events.window_role_change, NULL);
7707 _e_client_hook_call(E_CLIENT_HOOK_WINDOW_ROLE_CHANGE, ec);
7712 e_client_key_send(E_Client *ec, int keycode, Eina_Bool pressed, Ecore_Device *dev, unsigned int time)
7716 res = e_comp_wl_key_send(ec, keycode, pressed, dev, time);
7722 e_client_key_cancel(E_Client *ec, int keycode, Ecore_Device *dev, unsigned int time)
7726 res = e_comp_wl_key_cancel(ec, keycode, dev, time);
7732 e_client_touch_send(E_Client *ec, int idx, int x, int y, Eina_Bool pressed, Ecore_Device *dev, double radius_x, double radius_y, double pressure, double angle, unsigned int time)
7736 res = e_comp_wl_touch_send(ec, idx, x, y, pressed, dev, radius_x, radius_y, pressure, angle, time);
7742 e_client_touch_update_send(E_Client *ec, int idx, int x, int y, Ecore_Device *dev, double radius_x, double radius_y, double pressure, double angle, unsigned int time)
7746 res = e_comp_wl_touch_update_send(ec, idx, x, y, dev, radius_x, radius_y, pressure, angle, time);
7752 e_client_touch_cancel_send(E_Client *ec)
7756 res = e_comp_wl_touch_cancel_send(ec);
7762 e_client_mouse_button_send(E_Client *ec, int buttons, Eina_Bool pressed, Ecore_Device *dev, unsigned int time)
7766 res = e_comp_wl_mouse_button_send(ec, buttons, pressed, dev, time);
7772 e_client_mouse_move_send(E_Client *ec, int x, int y, Ecore_Device *dev, unsigned int time)
7776 res = e_comp_wl_mouse_move_send(ec, x, y, dev, time);
7782 e_client_mouse_wheel_send(E_Client *ec, int direction, int z, Ecore_Device *dev, unsigned int time)
7786 res = e_comp_wl_mouse_wheel_send(ec, direction, z, dev, time);
7792 e_client_mouse_in_send(E_Client *ec, int x, int y, Ecore_Device *dev, unsigned int time)
7796 res = e_comp_wl_mouse_in_send(ec, x, y, dev, time);
7802 e_client_mouse_out_send(E_Client *ec, Ecore_Device *dev, unsigned int time)
7806 res = e_comp_wl_mouse_out_send(ec, dev, time);
7812 e_client_video_client_has(E_Client *ec)
7814 return e_comp_wl_video_subsurface_has(ec);
7818 e_client_normal_client_has(E_Client *ec)
7820 return e_comp_wl_normal_subsurface_has(ec);
7824 e_client_cursor_hide(E_Client *ec)
7826 return e_comp_wl_cursor_hide(ec);
7830 e_client_visibility_force_obscured_set(E_Client *ec, Eina_Bool set)
7834 ELOGF("TZVIS", "VIS_FORCE_OBSCURED :%d", ec, set);
7836 ec->visibility.force_obscured = set;
7837 e_comp_visibility_calculation_set(EINA_TRUE);
7840 EINTERN E_Capture_Save_State
7841 e_client_image_save(E_Client *ec, const char *dir, const char *name, E_Capture_Client_Save_End_Cb func_end, void *data, Eina_Bool skip_child)
7843 return e_comp_wl_capture_client_image_save(ec, dir, name, func_end, data, skip_child);
7847 _e_client_base_output_resolution_hook_subsurf_create(void *data, E_Client *subc)
7849 E_Client *ec, *parent;
7855 ec->base_output_resolution.use = 0;
7856 ec->base_output_resolution.w = 0;
7857 ec->base_output_resolution.h = 0;
7858 if (ec->base_output_resolution.transform)
7860 e_client_transform_core_remove(ec, ec->base_output_resolution.transform);
7861 E_FREE_FUNC(ec->base_output_resolution.transform, e_util_transform_del);
7862 ELOGF("POL_APPINFO", "Cancel TRANSFORM for subsurface", ec);
7865 /* Update transform for toplevel surface.
7866 * The transform of subsurface will be updated by its parent accordingly. */
7867 parent = e_comp_wl_topmost_parent_get(ec);
7870 parent->transform_core.changed = EINA_TRUE;
7871 e_client_transform_core_update(parent);
7874 /* TODO: Do we need to apply it again if subsurface is destroyed? */
7878 _e_client_base_output_resolution_set(E_Client *ec, int width, int height)
7881 ec->base_output_resolution.use = 1;
7882 ec->base_output_resolution.w = width;
7883 ec->base_output_resolution.h = height;
7884 ec->base_output_resolution.transform = e_util_transform_new();
7885 e_util_transform_role_set(ec->base_output_resolution.transform, "base_output_resolution");
7886 e_client_transform_core_add(ec, ec->base_output_resolution.transform);
7888 if (!ec->base_output_resolution.hook_subsurf_create)
7890 ec->base_output_resolution.hook_subsurf_create =
7891 e_comp_wl_hook_add(E_COMP_WL_HOOK_SUBSURFACE_CREATE,
7892 _e_client_base_output_resolution_hook_subsurf_create,
7898 e_client_base_output_resolution_transform_adjust(E_Client *ec)
7902 EINA_SAFETY_ON_NULL_RETURN(ec);
7903 if (!ec->base_output_resolution.use) return;
7904 if (!ec->base_output_resolution.transform) return;
7906 desk = e_comp_desk_find_by_ec(ec);
7907 EINA_SAFETY_ON_NULL_RETURN(desk);
7909 ELOGF("POL_APPINFO", "Apply TRANSFORM... desk:(%dx%d), ec:(%dx%d)",
7910 ec, desk->geom.w, desk->geom.h, ec->w, ec->h);
7912 e_util_transform_scale(ec->base_output_resolution.transform,
7913 (double)desk->geom.w /(double)ec->base_output_resolution.w,
7914 (double)desk->geom.h /(double)ec->base_output_resolution.h,
7916 e_client_transform_core_update(ec);
7920 e_client_base_output_resolution_update(E_Client *ec)
7922 E_Appinfo *eai = NULL;
7923 int configured_width, configured_height;
7927 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
7929 if (!e_config->configured_output_resolution.use) return EINA_TRUE;
7930 if (ec->base_output_resolution.use) return EINA_TRUE;
7932 /* Check whether it's subsurface or not
7933 * The resolution of subsurface will follow the resolution of its toplevel surface.
7934 * Transform for subsurface will be applied when toplevel surface does by
7935 * implementation of e_client_transform_core.
7937 if (e_comp_wl_subsurface_check(ec))
7940 desk = e_comp_desk_find_by_ec(ec);
7941 EINA_SAFETY_ON_NULL_RETURN_VAL(desk, EINA_FALSE);
7943 configured_width = e_config->configured_output_resolution.w;
7944 configured_height = e_config->configured_output_resolution.h;
7948 ELOGF("POL_APPINFO", "NO PID... USE configured_output_resolution(%d,%d) pid:%d", ec,
7949 configured_width, configured_height, ec->netwm.pid);
7950 goto use_configured;
7953 eai = e_appinfo_find_with_pid(ec->netwm.pid);
7956 ELOGF("POL_APPINFO", "NO APPINFO... USE configured_output_resolution(%d,%d) pid:%d", ec,
7957 configured_width, configured_height, ec->netwm.pid);
7958 goto use_configured;
7961 if (!e_appinfo_base_output_resolution_get(eai, &width, &height))
7963 ELOGF("POL_APPINFO", "NO BASE SCREEN RESOLUTION... USE configured_output_resolution(%d,%d) pid:%d", ec,
7964 configured_width, configured_height, ec->netwm.pid);
7965 goto use_configured;
7968 if ((width == 0) && (height == 0))
7970 ELOGF("POL_APPINFO", "SKIP SET BASE SCREEN RESOLUTION... base_output_resolution size:(%d,%d) pid:%d", ec, width, height, ec->netwm.pid);
7974 if ((desk->geom.w == width) && (desk->geom.h == height))
7976 ELOGF("POL_APPINFO", "SKIP SET BASE SCREEN RESOLUTION... base_output_resolution is same with desk size:(%d,%d), pid:%d", ec, width, height, ec->netwm.pid);
7980 /* set the base_output_resolution of the e_client */
7981 _e_client_base_output_resolution_set(ec, width, height);
7983 ELOGF("POL_APPINFO", "USE base_output_resolution(%d,%d) pid:%d", ec, width, height, ec->netwm.pid);
7989 if ((desk->geom.w == configured_width) && (desk->geom.h == configured_height))
7991 ELOGF("POL_APPINFO", "SKIP use configured_output_resolution (same with desk size:(%d,%d), pid:%d)", ec, configured_width, configured_height, ec->netwm.pid);
7995 /* set the base_output_resolution of the e_client as a default */
7996 _e_client_base_output_resolution_set(ec, configured_width, configured_height);
8003 e_client_base_output_resolution_useful_geometry_get(E_Client *ec, int *x, int *y, int *w, int *h)
8008 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
8010 zone = e_comp_zone_find_by_ec(ec);
8011 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
8013 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
8020 if (ec->base_output_resolution.use)
8022 if (w) *w = ec->base_output_resolution.w;
8023 if (h) *h = ec->base_output_resolution.h;
8030 e_client_base_output_resolution_desk_useful_geometry_get(E_Client *ec, int *x, int *y, int *w, int *h, Eina_Bool consider_obstacle_area)
8035 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
8037 zone = e_comp_zone_find_by_ec(ec);
8038 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
8040 e_zone_desk_useful_geometry_get(zone, ec->desk, &zx, &zy, &zw, &zh, consider_obstacle_area);
8047 if (ec->base_output_resolution.use)
8049 // TODO: Consider obstacle area
8050 if (w) *w = ec->base_output_resolution.w;
8051 if (h) *h = ec->base_output_resolution.h;
8057 /* change the base_output_resolution of the bind_ec by checking the base_output_resolution of provider_ec's appinfo */
8059 e_client_base_output_resolution_rsm_update(E_Client *bind_ec, E_Client *provider_ec)
8061 E_Appinfo *epai = NULL;
8062 int configured_width, configured_height;
8064 E_Desk *bind_ec_desk;
8066 EINA_SAFETY_ON_NULL_RETURN_VAL(bind_ec, EINA_FALSE);
8067 EINA_SAFETY_ON_NULL_RETURN_VAL(provider_ec, EINA_FALSE);
8069 bind_ec_desk = e_comp_desk_find_by_ec(bind_ec);
8070 EINA_SAFETY_ON_NULL_RETURN_VAL(bind_ec_desk, EINA_FALSE);
8072 if (!e_config->configured_output_resolution.use) return EINA_TRUE;
8074 configured_width = e_config->configured_output_resolution.w;
8075 configured_height = e_config->configured_output_resolution.h;
8077 if (bind_ec->base_output_resolution.use)
8079 ELOGF("POL_APPINFO", "DELETE EXISTED BINDER BASE SCREEN RESOLUTION... base_output_resolution is same with desk size:(%d,%d), bind_pid:%d", bind_ec,
8080 bind_ec->base_output_resolution.w, bind_ec->base_output_resolution.h, bind_ec->netwm.pid);
8082 bind_ec->base_output_resolution.use = 0;
8083 bind_ec->base_output_resolution.w = 0;
8084 bind_ec->base_output_resolution.h = 0;
8085 e_client_transform_core_remove(bind_ec, bind_ec->base_output_resolution.transform);
8086 E_FREE_FUNC(bind_ec->base_output_resolution.transform, e_util_transform_del);
8089 if (!provider_ec->netwm.pid)
8091 ELOGF("POL_APPINFO", "NO PROVIDER PID... USE configured_output_resolution(%d,%d) provider_pid:%d", provider_ec,
8092 configured_width, configured_height, provider_ec->netwm.pid);
8093 goto use_configured;
8096 epai = e_appinfo_find_with_pid(provider_ec->netwm.pid);
8099 ELOGF("POL_APPINFO", "NO PROVIDER APPINFO... USE configured_output_resolution(%d,%d) provider_pid:%d", provider_ec,
8100 configured_width, configured_height, provider_ec->netwm.pid);
8101 goto use_configured;
8104 if (!e_appinfo_base_output_resolution_get(epai, &width, &height))
8106 ELOGF("POL_APPINFO", "NO PROVIDER APPINFO BASE SCREEN RESOLUTION... USE configured_output_resolution(%d,%d) provider_pid:%d", provider_ec,
8107 configured_width, configured_height, provider_ec->netwm.pid);
8108 goto use_configured;
8111 if ((width == 0) && (height == 0))
8113 ELOGF("POL_APPINFO", "NO PROVIDER WIDTH and HEIGHT... SKIP base_output_resolution due to size:(%d,%d) provider_pid:%d", provider_ec,
8114 width, height, provider_ec->netwm.pid);
8118 if ((bind_ec_desk->geom.w == width) && (bind_ec_desk->geom.h == height))
8120 ELOGF("POL_APPINFO", "SKIP SET BINDER BASE SCREEN RESOLUTION... base_output_resolution is same with desk size:(%d,%d), bind_pid:%d", bind_ec,
8121 width, height, bind_ec->netwm.pid);
8125 /* set the base_output_resolution of the e_client */
8126 _e_client_base_output_resolution_set(bind_ec, width, height);
8127 e_client_base_output_resolution_transform_adjust(bind_ec);
8129 ELOGF("POL_APPINFO", "USE BINDER base_output_resolution(%d,%d) bind_pid:%d", bind_ec, width, height, bind_ec->netwm.pid);
8135 if ((bind_ec_desk->geom.w == configured_width) && (bind_ec_desk->geom.h == configured_height))
8137 ELOGF("POL_APPINFO", "SKIP BINDER use configured_output_resolution (same with desk size:(%d,%d), bind_pid:%d)", bind_ec,
8138 configured_width, configured_height, bind_ec->netwm.pid);
8142 /* set the base_output_resolution of the e_client as a default */
8143 _e_client_base_output_resolution_set(bind_ec, configured_width, configured_height);
8149 /* tizen_move_resize */
8151 e_client_pending_geometry_has(E_Client *ec)
8153 if (!eina_list_count(ec->surface_sync.pending_geometry))
8156 return ec->surface_sync.wait_commit;
8160 e_client_pending_geometry_flush(E_Client *ec)
8162 E_Client_Pending_Geometry *geo;
8164 if (!eina_list_count(ec->surface_sync.pending_geometry))
8166 EINA_LIST_FREE(ec->surface_sync.pending_geometry, geo)
8170 ec->surface_sync.wait_commit = EINA_FALSE;
8171 ELOGF("POSSIZE", "pending geometry has flushed", ec);
8176 e_client_pending_geometry_last_geometry_get(E_Client *ec, int *x, int *y, int *w, int *h)
8179 E_Client_Pending_Geometry *geo;
8185 EINA_LIST_REVERSE_FOREACH(ec->surface_sync.pending_geometry, l, geo)
8201 e_client_frame_focus_set(E_Client *ec, Eina_Bool focus)
8204 evas_object_focus_set(ec->frame, focus);
8208 e_client_frame_geometry_set(E_Client *ec, int x, int y, int w, int h)
8212 if (ec->internal || ec->input_only)
8214 evas_object_geometry_set(ec->frame, x, y, w, h);
8218 if ((ec->w != w) || (ec->h != h))
8220 ELOGF("POSSIZE", "Set move_after_resize. old(%d,%d,%dx%d), new(%d,%d,%dx%d)", ec, ec->x, ec->y, ec->w, ec->h, x, y, w, h);
8221 ec->move_after_resize = EINA_TRUE;
8223 e_client_pos_set(ec, x, y);
8224 evas_object_resize(ec->frame, w, h);
8227 evas_object_geometry_set(ec->frame, x, y, w, h);
8232 e_client_util_move_resize_without_frame(E_Client *ec, int x, int y, int w, int h)
8236 if (ec->internal || ec->input_only)
8238 e_client_util_move_without_frame(ec, x, y);
8239 e_client_util_resize_without_frame(ec, w, h);
8243 if ((ec->w != w) || (ec->h != h))
8245 ELOGF("POSSIZE", "Set move_after_resize. old(%d,%d,%dx%d), new(%d,%d,%dx%d)", ec, ec->x, ec->y, ec->w, ec->h, x, y, w, h);
8246 ec->move_after_resize = EINA_TRUE;
8248 e_comp_object_frame_xy_adjust(ec->frame, x, y, &x, &y);
8249 e_client_pos_set(ec, x, y);
8250 e_client_util_resize_without_frame(ec, w, h);
8254 e_client_util_move_without_frame(ec, x, y);
8255 e_client_util_resize_without_frame(ec, w, h);
8261 e_client_layer_set(E_Client *ec,
8264 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
8265 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
8266 if (!ec->frame) return EINA_FALSE;
8268 if (e_comp_canvas_client_layer_map(layer) == 9999)
8269 return EINA_FALSE; //invalid layer is not allowed
8271 if (ec->desk_area.enable)
8273 if (e_client_layer_set_by_desk_area(ec, layer))
8275 // restack according to desk group rule
8276 e_desk_area_ec_rearrange(ec->desk_area.desk_area, ec);
8280 ec->desk_area.layer_backup = layer;
8282 evas_object_layer_set(ec->frame, layer);
8283 if (ec->layer != layer)
8285 /* check exceptional case */
8286 if ((ec->fullscreen) &&
8287 (ec->saved.layer != layer))
8289 ELOGF("LAYER", "(%d) fail to backup at saved.layer for fullscreen", ec, layer);
8292 // if e_comp_object fail to change ec->layer due to ec->layer_pending or block
8293 // leave log and apply ec->layer according to set
8294 // as a result it restores back to given layer when pending or block is free
8295 ELOGF("LAYER", "change layer from %d to %d if in case layer pending(%d) or block(%d)",
8296 ec, ec->layer, layer, ec->layer_pending, ec->layer_block);
8297 if (ec->layer_pending || ec->layer_block)
8304 wl_signal_emit_mutable(&PRI(ec)->events.layer_set, NULL);
8310 e_client_layer_get(E_Client *ec)
8314 E_OBJECT_CHECK_RETURN(ec, E_LAYER_BOTTOM);
8315 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, E_LAYER_BOTTOM);
8316 if (!ec->frame) return E_LAYER_BOTTOM;
8318 layer = evas_object_layer_get(ec->frame);
8319 if (ec->layer != layer)
8321 /* client could be on temperory layer while pending or block,
8322 * in that case, client restores back to ec->layer after pending/block finish */
8323 if (ec->layer_block || ec->layer_pending)
8326 /* otherwise, client is on unexpected layer */
8327 ELOGF("LAYER", "layer dismatch ec->layer %d | evas obj layer %d ",
8328 ec, ec->layer, layer);
8330 if (e_comp_canvas_client_layer_map(layer) == 9999)
8331 return E_LAYER_BOTTOM; //not on E_LAYER_CLIENT
8338 _e_client_desk_area_original_layer_save(E_Client *ec, E_Layer layer)
8341 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
8342 ec->desk_area.layer_backup = layer;
8346 e_client_layer_set_by_desk_area(E_Client *ec, E_Layer layer)
8352 if (!ec) return EINA_FALSE;
8353 if (!ec->frame) return EINA_FALSE;
8354 if (!ec->desk_area.enable) return EINA_FALSE;
8355 if (!ec->desk_area.desk_area) return EINA_FALSE;
8357 eda = ec->desk_area.desk_area;
8359 // save original layer
8360 _e_client_desk_area_original_layer_save(ec, layer);
8362 // get desk_area layer
8363 edg_layer = (E_Layer)e_desk_area_layer_get(eda);
8364 org_layer = e_client_desk_area_original_layer_get(ec);
8366 ELOGF("EDG", "layer_set by desk_area... layer:%d, org_layer:%d, new_layer:%d", ec, layer, org_layer, edg_layer);
8367 if (org_layer == edg_layer)
8373 evas_object_layer_set(ec->frame, edg_layer);
8374 if (edg_layer == ec->layer)
8382 e_client_desk_area_original_layer_restore(E_Client *ec)
8386 // Do we need to check ec->desk_area.enable?
8387 // if ec->desk_area.enable is true, then e_client_layer_set calls
8388 // e_desk_area_ec_edg_layer_set(). that's too bad. :(
8389 // so, we MUST make a policy for ordering of the desk group layer restore
8390 // and the desk group enable.
8391 if (ec->desk_area.enable) return;
8392 e_client_layer_set(ec, ec->desk_area.layer_backup);
8396 e_client_desk_area_original_layer_get(E_Client *ec)
8398 if (!ec) return E_LAYER_DESKTOP;
8400 if (ec->desk_area.enable)
8401 return ec->desk_area.layer_backup;
8407 e_client_desk_area_client_layer_set(E_Client *ec, E_Desk_Area_Client_Layer edgc_layer)
8409 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
8410 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
8411 if ((edgc_layer < E_DESK_AREA_CLIENT_LAYER_DESKTOP) ||
8412 (edgc_layer >= E_DESK_AREA_CLIENT_LAYER_MAX))
8415 ec->desk_area.edgc_layer = edgc_layer;
8419 EINTERN E_Desk_Area_Client_Layer
8420 e_client_desk_area_client_layer_get(E_Client *ec)
8422 E_OBJECT_CHECK_RETURN(ec, E_DESK_AREA_CLIENT_LAYER_DESKTOP);
8424 return ec->desk_area.edgc_layer;
8427 #ifdef REFACTOR_ZONE_DESK
8430 e_client_desk_area_enable_set(E_Client *ec, Eina_Bool enable)
8432 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
8433 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
8435 ec->desk_area.enable = enable;
8437 ELOGF("EDG", "Desk group enable set to %d", ec, enable);
8440 if (!ec->desk_area.transform)
8442 ec->desk_area.transform = e_util_transform_new();
8443 e_util_transform_role_set(ec->desk_area.transform, "desk_area");
8448 if (ec->desk_area.transform)
8450 e_util_transform_del(ec->desk_area.transform);
8451 ec->desk_area.transform = NULL;
8455 e_desk_area_ec_update(ec->desk_area.desk_area, ec);
8460 //FIXME: use e_desk_area_ec_reassign(eda, ec) instead of this api
8462 e_client_desk_area_set(E_Client *ec, E_Desk_Area *eda)
8464 E_Desk_Area *old_edg;
8466 if (!ec) return EINA_FALSE;
8468 #if 0 // if this is removed.. then below if (eda != old_edg) is removed also...
8469 if (ec->desk_area.desk_area == eda)
8473 ELOGF("EDG", "Desk Group Set (new:%p, old:%p)", ec, eda, ec->desk_area.desk_area);
8474 old_edg = ec->desk_area.desk_area;
8476 e_desk_area_ec_remove(old_edg, ec);
8478 ec->desk_area.desk_area = eda;
8479 e_desk_area_ec_add(eda, ec);
8481 #if 0 // if this is removed.. then above if (ec->desk_area.desk_area == eda) is removed also...
8485 e_desk_area_ec_update(eda, ec);
8486 e_desk_area_ec_rearrange(ec->desk_area.desk_area, ec);
8493 _raise_between_sibling_under_parent(E_Client *ec)
8495 ELOGF("POL", "RAISE child window between sibling. So, stack below under the parent (win:%zx, ec:%p)", ec, e_client_util_win_get(ec->parent), ec->parent);
8496 e_client_stack_below(ec, ec->parent);
8500 _raise_between_sibling_on_parent(E_Client *ec)
8502 E_Client *top_child = NULL;
8503 top_child = e_client_transient_child_top_get(ec->parent, EINA_FALSE);
8506 ELOGF("POL", "RAISE child window... Stack above on the parent (win:%zx, ec:%p)", ec, e_client_util_win_get(ec->parent), ec->parent);
8507 e_client_stack_above(ec, ec->parent);
8511 if (top_child != ec)
8513 ELOGF("POL", "RAISE child window between sibling... Stack above on the top child (win:%zx, ec:%p)", ec, e_client_util_win_get(top_child), top_child);
8514 e_client_stack_above(ec, top_child);
8517 ELOGF("POL", "RAISE child window between sibling... already on the top. STAY", ec);
8522 _raise_belong_to_parent(E_Client *ec)
8524 if (e_client_transient_policy_get(ec) == E_TRANSIENT_BELOW)
8525 _raise_between_sibling_under_parent(ec);
8527 _raise_between_sibling_on_parent(ec);
8531 e_client_raise(E_Client *ec)
8535 if (ec->desk_area.enable)
8538 eda = ec->desk_area.desk_area;
8541 e_desk_area_ec_raise(eda, ec);
8546 if (ec->parent && e_client_is_belong_to_parent(ec))
8547 _raise_belong_to_parent(ec);
8549 evas_object_raise(ec->frame);
8551 wl_signal_emit_mutable(&PRI(ec)->events.raise, NULL);
8555 _e_client_transient_for_below_group_make(E_Client *ec, Eina_List **list)
8557 // list : Head is the bottommost child
8563 EINA_LIST_REVERSE_FOREACH(ec->transients, l, child)
8565 if (!child) continue;
8566 if (e_client_transient_policy_get(child) != E_TRANSIENT_BELOW) continue;
8567 if (!e_client_is_belong_to_parent(child)) continue;
8569 *list = eina_list_prepend(*list, child);
8570 _e_client_transient_for_group_make(child, list);
8575 e_client_transient_child_bottom_get(E_Client *ec)
8577 E_Client *bottom_ec = NULL;
8578 Eina_List *transient_below_list = NULL;
8579 Eina_List *l = NULL;
8581 _e_client_transient_for_below_group_make(ec, &transient_below_list);
8583 if (transient_below_list)
8585 E_Client *temp_ec = NULL;
8586 E_Client *temp_ec2 = NULL;
8588 E_CLIENT_FOREACH(temp_ec)
8590 if (bottom_ec) break;
8598 EINA_LIST_FOREACH(transient_below_list, l, temp_ec2)
8600 if (temp_ec == temp_ec2)
8602 bottom_ec = temp_ec2;
8607 eina_list_free(transient_below_list);
8613 _lower_between_sibling_under_parent(E_Client *ec)
8615 E_Client *bottom_child = NULL;
8616 bottom_child = e_client_transient_child_bottom_get(ec->parent);
8619 ELOGF("POL", "LOWER child window between sibling... Stack below under the parent (win:%zx, ec:%p)", ec, e_client_util_win_get(ec->parent), ec->parent);
8620 e_client_stack_below(ec, ec->parent);
8624 if (bottom_child != ec)
8626 ELOGF("POL", "LOWER child window between sibling... Stack below under the bottom child (win:%zx, ec:%p)", ec, e_client_util_win_get(bottom_child), bottom_child);
8627 e_client_stack_below(ec, bottom_child);
8630 ELOGF("POL", "LOWER child window between sibling... already under the bottom. STAY", ec);
8635 _lower_between_sibling_on_parent(E_Client *ec)
8637 ELOGF("POL", "LOWER child window between sibling... So, stack above on the parent (win:%zx, ec:%p)", ec, e_client_util_win_get(ec->parent), ec->parent);
8638 e_client_stack_above(ec, ec->parent);
8642 _lower_belong_to_parent(E_Client *ec)
8644 if (e_client_transient_policy_get(ec) == E_TRANSIENT_BELOW)
8645 _lower_between_sibling_under_parent(ec);
8647 _lower_between_sibling_on_parent(ec);
8651 e_client_lower(E_Client *ec)
8655 if (ec->desk_area.enable)
8658 eda = ec->desk_area.desk_area;
8661 e_desk_area_ec_lower(eda, ec);
8662 #ifdef REFACTOR_FOCUS_POLICY
8663 wl_signal_emit_mutable(&PRI(ec)->events.lower, NULL);
8669 if (ec->parent && e_client_is_belong_to_parent(ec))
8670 _lower_belong_to_parent(ec);
8672 evas_object_lower(ec->frame);
8674 #ifdef REFACTOR_FOCUS_POLICY
8675 wl_signal_emit_mutable(&PRI(ec)->events.lower, NULL);
8680 e_client_stack_above(E_Client *ec, E_Client *above)
8683 if (!ec->frame) return;
8685 if (!above->frame) return;
8687 if (ec->desk_area.enable)
8690 eda = ec->desk_area.desk_area;
8693 e_desk_area_ec_stack_above(eda, ec, above);
8698 evas_object_stack_above(ec->frame, above->frame);
8700 wl_signal_emit_mutable(&PRI(ec)->events.stack_above, NULL);
8704 e_client_stack_below(E_Client *ec, E_Client *below)
8707 if (!ec->frame) return;
8709 if (!below->frame) return;
8711 if (ec->desk_area.enable)
8714 eda = ec->desk_area.desk_area;
8717 e_desk_area_ec_stack_below(eda, ec, below);
8722 evas_object_stack_below(ec->frame, below->frame);
8724 wl_signal_emit_mutable(&PRI(ec)->events.stack_below, NULL);
8728 e_client_show_pending_set(E_Client *ec)
8732 ec->show_pending.count++;
8733 ELOGF("E_CLIENT", "SET show_pending. (count:%d, run:%d)", ec, ec->show_pending.count, ec->show_pending.running);
8734 return ec->show_pending.count;
8738 e_client_show_pending_unset(E_Client *ec)
8741 if (ec->show_pending.count <= 0) return 0;
8743 ec->show_pending.count--;
8744 ELOGF("E_CLIENT", "UNSET show_pending. (count:%d, run:%d)", ec, ec->show_pending.count, ec->show_pending.running);
8745 if (ec->show_pending.count == 0 && ec->show_pending.running)
8747 ec->show_pending.running = EINA_FALSE;
8750 ELOGF("E_CLIENT", "evas_object_show by unset show_pending", ec);
8751 evas_object_show(ec->frame);
8752 //e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
8757 return ec->show_pending.count;
8761 _e_client_surface_tree_foreach_helper(E_Client *ec, E_Client_Surface_Tree_Foreach func, void *data)
8765 Eina_Bool res = EINA_TRUE;
8766 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
8771 EINA_LIST_FOREACH_SAFE(cdata->sub.below_list, l, ll, subc)
8773 res = _e_client_surface_tree_foreach_helper(subc, func, data);
8780 res = func(data, ec);
8783 EINA_LIST_FOREACH_SAFE(cdata->sub.list, l, ll, subc)
8785 res = _e_client_surface_tree_foreach_helper(subc,
8798 e_client_surface_tree_foreach(E_Client *ec, E_Client_Surface_Tree_Foreach func, void *data)
8800 EINA_SAFETY_ON_NULL_RETURN(ec);
8801 EINA_SAFETY_ON_NULL_RETURN(func);
8803 _e_client_surface_tree_foreach_helper(ec, func, data);
8806 EINTERN E_Comp_Wl_Client_Data *
8807 e_client_cdata_new(E_Client *ec)
8809 E_Comp_Wl_Client_Data *cdata;
8811 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
8813 if (!(cdata = E_NEW(E_Comp_Wl_Client_Data, 1)))
8815 ERR("Could not allocate new E_Comp_Wl_Client_Data structure");
8818 ec->comp_data = cdata;
8824 e_client_cdata_free(E_Client *ec)
8826 EINA_SAFETY_ON_NULL_RETURN(ec);
8827 if (!ec->comp_data) return;
8829 E_FREE(ec->comp_data);
8832 EINTERN E_Comp_Wl_Client_Data *
8833 e_client_cdata_get(E_Client *ec)
8835 if (!ec) return NULL;
8837 return ec->comp_data;
8841 e_client_map_set(E_Client *ec, E_Map *em)
8843 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
8845 return e_map_set_to_comp_object(em, ec->frame);
8849 e_client_map_get(const E_Client *ec)
8851 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
8853 return e_map_get_from_comp_object(ec->frame);
8857 e_client_map_enable_set(E_Client *ec, Eina_Bool enable)
8859 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
8860 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->frame, EINA_FALSE);
8862 evas_object_map_enable_set(ec->frame, enable);
8868 e_client_belong_to_parent_set(E_Client *ec, Eina_Bool set)
8871 ec->belong_to_parent = set;
8875 e_client_is_belong_to_parent(E_Client *ec)
8877 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
8878 return ec->belong_to_parent;
8882 e_client_transient_policy_set(E_Client *ec, E_Transient policy)
8885 ec->transient_policy = policy;
8889 e_client_transient_policy_get(E_Client *ec)
8891 if (!ec) return E_TRANSIENT_ABOVE;
8892 return ec->transient_policy;
8896 e_client_resize_object_create_cb_set(E_Client_Resize_Object_Create_Cb cb)
8898 if (_e_client_resize_object_create_cb && cb)
8899 CRI("ATTEMPTING TO OVERWRITE EXISTING CLIENT RESIZE OBJECT CREATE HOOK!!!");
8900 _e_client_resize_object_create_cb = cb;
8904 e_client_resize_unit_size_set(E_Client *ec, unsigned int unit_size)
8908 // FYI, we consider 0 and 1 to be the same value as a default unit size.
8909 ec->manage_resize.unit_size = unit_size;
8913 e_client_desk_zoom_enable_set(E_Client *ec, Eina_Bool enable)
8916 ec->desk_zoom.enable = enable;
8920 e_client_desk_zoom_enable_get(E_Client *ec)
8922 if (!ec) return EINA_FALSE;
8923 return ec->desk_zoom.enable;
8927 e_client_layout_apply(E_Client *ec, Eina_Bool apply)
8930 ec->apply_layout = apply;
8934 e_client_is_layout_apply(E_Client *ec)
8936 if (!ec) return EINA_FALSE;
8937 return ec->apply_layout;
8941 e_client_from_surface_resource(struct wl_resource *surface_resource)
8943 EINA_SAFETY_ON_NULL_RETURN_VAL(surface_resource, NULL);
8945 return e_comp_wl_util_client_from_surface_resource(surface_resource);
8949 e_client_fps_update(E_Client *ec)
8954 EINA_SAFETY_ON_NULL_RETURN(ec);
8956 if (!ec->fps.enabled) return;
8958 tim = ecore_time_get();
8960 dt = tim - ec->fps.frametimes[0];
8962 ec->fps.frametimes[0] = tim;
8966 if (ec->fps.lapse == 0.0)
8968 ec->fps.lapse = tim;
8969 ec->fps.flapse = ec->fps.cframes;
8971 else if ((tim - ec->fps.lapse) >= 0.5)
8973 ec->fps.fps = (ec->fps.cframes - ec->fps.flapse) /
8974 (tim - ec->fps.lapse);
8975 ec->fps.lapse = tim;
8976 ec->fps.flapse = ec->fps.cframes;
8982 e_client_fps_get(E_Client *ec, double *fps)
8984 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
8986 if (ec->fps.old_fps == ec->fps.fps)
8989 if (ec->fps.fps > 0.0)
8992 ec->fps.old_fps = ec->fps.fps;
9000 e_client_fps_enable(E_Client *ec, Eina_Bool enable)
9002 EINA_SAFETY_ON_NULL_RETURN(ec);
9004 ec->fps.enabled = enable;
9008 e_client_explicit_sync_get(E_Client *ec)
9010 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
9012 return ec->explicit_sync;
9016 e_client_explicit_sync_set(E_Client *ec, Eina_Bool enable)
9018 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
9020 ec->explicit_sync = enable;
9026 e_client_explicit_sync_acquire_fence_fd_get(E_Client *ec)
9028 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, -1);
9030 return ec->acquire_fence_fd;
9034 e_client_explicit_sync_acquire_fence_fd_set(E_Client *ec, int fd)
9036 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
9038 ec->acquire_fence_fd = fd;
9043 #ifdef REFACTOR_ZONE_DESK
9045 e_client_intercept_hook_auto_placement_call(E_Client *ec)
9047 // no need to call the intercept hook if ec is NULL.
9048 if (!ec) return EINA_FALSE;
9050 if (!_e_client_intercept_hook_call(E_CLIENT_INTERCEPT_HOOK_AUTO_PLACEMENT, ec))
9052 ELOGF("FOCUS", "E_CLIENT_INTERCEPT_HOOK_AUTO_PLACEMENT Intercepted.", ec);
9060 e_client_iconify_event_send(E_Client *ec)
9062 EINA_SAFETY_ON_NULL_RETURN(ec);
9064 _e_client_event_simple(ec, E_EVENT_CLIENT_ICONIFY);
9068 e_client_uniconify_event_send(E_Client *ec)
9070 EINA_SAFETY_ON_NULL_RETURN(ec);
9072 _e_client_event_simple(ec, E_EVENT_CLIENT_UNICONIFY);
9077 e_client_stack_transient_for_done_notify(E_Client *ec)
9079 EINA_SAFETY_ON_NULL_RETURN(ec);
9081 wl_signal_emit_mutable(&PRI(ec)->events.stack_transient_for_done, NULL);
9085 e_client_eval_pre_fetch_listener_add(E_Client *ec, struct wl_listener *listener)
9088 wl_signal_add(&priv->events.eval_pre_fetch, listener);
9091 EINTERN struct wl_listener *
9092 e_client_eval_pre_fetch_listener_get(E_Client *ec, wl_notify_func_t notify)
9094 API_ENTRY_VAL(NULL);
9095 return wl_signal_get(&priv->events.eval_pre_fetch, notify);
9099 e_client_eval_fetch_listener_add(E_Client *ec, struct wl_listener *listener)
9102 wl_signal_add(&priv->events.eval_fetch, listener);
9105 EINTERN struct wl_listener *
9106 e_client_eval_fetch_listener_get(E_Client *ec, wl_notify_func_t notify)
9108 API_ENTRY_VAL(NULL);
9109 return wl_signal_get(&priv->events.eval_fetch, notify);
9113 e_client_eval_pre_post_fetch_listener_add(E_Client *ec, struct wl_listener *listener)
9116 wl_signal_add(&priv->events.eval_pre_post_fetch, listener);
9119 EINTERN struct wl_listener *
9120 e_client_eval_pre_post_fetch_listener_get(E_Client *ec, wl_notify_func_t notify)
9122 API_ENTRY_VAL(NULL);
9123 return wl_signal_get(&priv->events.eval_pre_post_fetch, notify);
9127 e_client_eval_post_fetch_listener_add(E_Client *ec, struct wl_listener *listener)
9130 wl_signal_add(&priv->events.eval_post_fetch, listener);
9133 EINTERN struct wl_listener *
9134 e_client_eval_post_fetch_listener_get(E_Client *ec, wl_notify_func_t notify)
9136 API_ENTRY_VAL(NULL);
9137 return wl_signal_get(&priv->events.eval_post_fetch, notify);
9141 e_client_eval_pre_frame_assign_listener_add(E_Client *ec, struct wl_listener *listener)
9144 wl_signal_add(&priv->events.eval_pre_frame_assign, listener);
9147 EINTERN struct wl_listener *
9148 e_client_eval_pre_frame_assign_listener_get(E_Client *ec, wl_notify_func_t notify)
9150 API_ENTRY_VAL(NULL);
9151 return wl_signal_get(&priv->events.eval_pre_frame_assign, notify);
9155 e_client_eval_post_frame_assign_listener_add(E_Client *ec, struct wl_listener *listener)
9158 wl_signal_add(&priv->events.eval_post_frame_assign, listener);
9161 EINTERN struct wl_listener *
9162 e_client_eval_post_frame_assign_listener_get(E_Client *ec, wl_notify_func_t notify)
9164 API_ENTRY_VAL(NULL);
9165 return wl_signal_get(&priv->events.eval_post_frame_assign, notify);
9169 e_client_eval_pre_new_client_listener_add(E_Client *ec, struct wl_listener *listener)
9172 wl_signal_add(&priv->events.eval_pre_new_client, listener);
9175 EINTERN struct wl_listener *
9176 e_client_eval_pre_new_client_listener_get(E_Client *ec, wl_notify_func_t notify)
9178 API_ENTRY_VAL(NULL);
9179 return wl_signal_get(&priv->events.eval_pre_new_client, notify);
9183 e_client_eval_post_new_client_listener_add(E_Client *ec, struct wl_listener *listener)
9186 wl_signal_add(&priv->events.eval_post_new_client, listener);
9189 EINTERN struct wl_listener *
9190 e_client_eval_post_new_client_listener_get(E_Client *ec, wl_notify_func_t notify)
9192 API_ENTRY_VAL(NULL);
9193 return wl_signal_get(&priv->events.eval_post_new_client, notify);
9197 e_client_eval_visibility_listener_add(E_Client *ec, struct wl_listener *listener)
9200 wl_signal_add(&priv->events.eval_visibility, listener);
9203 EINTERN struct wl_listener *
9204 e_client_eval_visibility_listener_get(E_Client *ec, wl_notify_func_t notify)
9206 API_ENTRY_VAL(NULL);
9207 return wl_signal_get(&priv->events.eval_visibility, notify);
9211 e_client_eval_visibility_end_listener_add(E_Client *ec, struct wl_listener *listener)
9214 wl_signal_add(&priv->events.eval_visibility_end, listener);
9217 EINTERN struct wl_listener *
9218 e_client_eval_visibility_end_listener_get(E_Client *ec, wl_notify_func_t notify)
9220 API_ENTRY_VAL(NULL);
9221 return wl_signal_get(&priv->events.eval_visibility_end, notify);
9225 e_client_eval_end_listener_add(E_Client *ec, struct wl_listener *listener)
9228 wl_signal_add(&priv->events.eval_end, listener);
9231 EINTERN struct wl_listener *
9232 e_client_eval_end_listener_get(E_Client *ec, wl_notify_func_t notify)
9234 API_ENTRY_VAL(NULL);
9235 return wl_signal_get(&priv->events.eval_end, notify);
9239 e_client_move_begin_listener_add(E_Client *ec, struct wl_listener *listener)
9242 wl_signal_add(&priv->events.move_begin, listener);
9245 EINTERN struct wl_listener *
9246 e_client_move_begin_listener_get(E_Client *ec, wl_notify_func_t notify)
9248 API_ENTRY_VAL(NULL);
9249 return wl_signal_get(&priv->events.move_begin, notify);
9253 e_client_move_update_listener_add(E_Client *ec, struct wl_listener *listener)
9256 wl_signal_add(&priv->events.move_update, listener);
9259 EINTERN struct wl_listener *
9260 e_client_move_update_listener_get(E_Client *ec, wl_notify_func_t notify)
9262 API_ENTRY_VAL(NULL);
9263 return wl_signal_get(&priv->events.move_update, notify);
9267 e_client_move_end_listener_add(E_Client *ec, struct wl_listener *listener)
9270 wl_signal_add(&priv->events.move_end, listener);
9273 EINTERN struct wl_listener *
9274 e_client_move_end_listener_get(E_Client *ec, wl_notify_func_t notify)
9276 API_ENTRY_VAL(NULL);
9277 return wl_signal_get(&priv->events.move_end, notify);
9281 e_client_move_resize_begin_listener_add(E_Client *ec, struct wl_listener *listener)
9284 wl_signal_add(&priv->events.move_resize_begin, listener);
9287 EINTERN struct wl_listener *
9288 e_client_move_resize_begin_listener_get(E_Client *ec, wl_notify_func_t notify)
9290 API_ENTRY_VAL(NULL);
9291 return wl_signal_get(&priv->events.move_resize_begin, notify);
9295 e_client_move_resize_update_listener_add(E_Client *ec, struct wl_listener *listener)
9298 wl_signal_add(&priv->events.move_resize_update, listener);
9301 EINTERN struct wl_listener *
9302 e_client_move_resize_update_listener_get(E_Client *ec, wl_notify_func_t notify)
9304 API_ENTRY_VAL(NULL);
9305 return wl_signal_get(&priv->events.move_resize_update, notify);
9309 e_client_move_resize_end_listener_add(E_Client *ec, struct wl_listener *listener)
9312 wl_signal_add(&priv->events.move_resize_end, listener);
9315 EINTERN struct wl_listener *
9316 e_client_move_resize_end_listener_get(E_Client *ec, wl_notify_func_t notify)
9318 API_ENTRY_VAL(NULL);
9319 return wl_signal_get(&priv->events.move_resize_end, notify);
9323 e_client_destroy_listener_add(E_Client *ec, struct wl_listener *listener)
9326 wl_signal_add(&priv->events.destroy, listener);
9329 EINTERN struct wl_listener *
9330 e_client_destroy_listener_get(E_Client *ec, wl_notify_func_t notify)
9332 API_ENTRY_VAL(NULL);
9333 return wl_signal_get(&priv->events.destroy, notify);
9337 e_client_new_client_listener_add(E_Client *ec, struct wl_listener *listener)
9340 wl_signal_add(&priv->events.new_client, listener);
9343 EINTERN struct wl_listener *
9344 e_client_new_client_listener_get(E_Client *ec, wl_notify_func_t notify)
9346 API_ENTRY_VAL(NULL);
9347 return wl_signal_get(&priv->events.new_client, notify);
9351 e_client_new_client_post_listener_add(E_Client *ec, struct wl_listener *listener)
9354 wl_signal_add(&priv->events.new_client_post, listener);
9357 EINTERN struct wl_listener *
9358 e_client_new_client_post_listener_get(E_Client *ec, wl_notify_func_t notify)
9360 API_ENTRY_VAL(NULL);
9361 return wl_signal_get(&priv->events.new_client_post, notify);
9365 e_client_unredirect_listener_add(E_Client *ec, struct wl_listener *listener)
9368 wl_signal_add(&priv->events.unredirect, listener);
9371 EINTERN struct wl_listener *
9372 e_client_unredirect_listener_get(E_Client *ec, wl_notify_func_t notify)
9374 API_ENTRY_VAL(NULL);
9375 return wl_signal_get(&priv->events.unredirect, notify);
9379 e_client_redirect_listener_add(E_Client *ec, struct wl_listener *listener)
9382 wl_signal_add(&priv->events.redirect, listener);
9385 EINTERN struct wl_listener *
9386 e_client_redirect_listener_get(E_Client *ec, wl_notify_func_t notify)
9388 API_ENTRY_VAL(NULL);
9389 return wl_signal_get(&priv->events.redirect, notify);
9393 e_client_aux_hint_change_listener_add(E_Client *ec, struct wl_listener *listener)
9396 wl_signal_add(&priv->events.aux_hint_change, listener);
9399 EINTERN struct wl_listener *
9400 e_client_aux_hint_change_listener_get(E_Client *ec, wl_notify_func_t notify)
9402 API_ENTRY_VAL(NULL);
9403 return wl_signal_get(&priv->events.aux_hint_change, notify);
9407 e_client_window_role_change_listener_add(E_Client *ec, struct wl_listener *listener)
9410 wl_signal_add(&priv->events.window_role_change, listener);
9413 EINTERN struct wl_listener *
9414 e_client_window_role_change_listener_get(E_Client *ec, wl_notify_func_t notify)
9416 API_ENTRY_VAL(NULL);
9417 return wl_signal_get(&priv->events.window_role_change, notify);
9421 e_client_transform_change_listener_add(E_Client *ec, struct wl_listener *listener)
9424 wl_signal_add(&priv->events.transform_change, listener);
9427 EINTERN struct wl_listener *
9428 e_client_transform_change_listener_get(E_Client *ec, wl_notify_func_t notify)
9430 API_ENTRY_VAL(NULL);
9431 return wl_signal_get(&priv->events.transform_change, notify);
9435 e_client_activate_done_listener_add(E_Client *ec, struct wl_listener *listener)
9438 wl_signal_add(&priv->events.activate_done, listener);
9441 EINTERN struct wl_listener *
9442 e_client_activate_done_listener_get(E_Client *ec, wl_notify_func_t notify)
9444 API_ENTRY_VAL(NULL);
9445 return wl_signal_get(&priv->events.activate_done, notify);
9449 e_client_mouse_in_listener_add(E_Client *ec, struct wl_listener *listener)
9452 wl_signal_add(&priv->events.mouse_in, listener);
9455 EINTERN struct wl_listener *
9456 e_client_mouse_in_listener_get(E_Client *ec, wl_notify_func_t notify)
9458 API_ENTRY_VAL(NULL);
9459 return wl_signal_get(&priv->events.mouse_in, notify);
9463 e_client_mouse_out_listener_add(E_Client *ec, struct wl_listener *listener)
9466 wl_signal_add(&priv->events.mouse_out, listener);
9469 EINTERN struct wl_listener *
9470 e_client_mouse_out_listener_get(E_Client *ec, wl_notify_func_t notify)
9472 API_ENTRY_VAL(NULL);
9473 return wl_signal_get(&priv->events.mouse_out, notify);
9477 e_client_mouse_down_listener_add(E_Client *ec, struct wl_listener *listener)
9480 wl_signal_add(&priv->events.mouse_down, listener);
9483 EINTERN struct wl_listener *
9484 e_client_mouse_down_listener_get(E_Client *ec, wl_notify_func_t notify)
9486 API_ENTRY_VAL(NULL);
9487 return wl_signal_get(&priv->events.mouse_down, notify);
9491 e_client_focus_set_listener_add(E_Client *ec, struct wl_listener *listener)
9494 wl_signal_add(&priv->events.focus_set, listener);
9497 EINTERN struct wl_listener *
9498 e_client_focus_set_listener_get(E_Client *ec, wl_notify_func_t notify)
9500 API_ENTRY_VAL(NULL);
9501 return wl_signal_get(&priv->events.focus_set, notify);
9505 e_client_focus_unset_listener_add(E_Client *ec, struct wl_listener *listener)
9508 wl_signal_add(&priv->events.focus_unset, listener);
9511 EINTERN struct wl_listener *
9512 e_client_focus_unset_listener_get(E_Client *ec, wl_notify_func_t notify)
9514 API_ENTRY_VAL(NULL);
9515 return wl_signal_get(&priv->events.focus_unset, notify);
9519 e_client_focus_defer_set_listener_add(E_Client *ec, struct wl_listener *listener)
9522 wl_signal_add(&priv->events.focus_defer_set, listener);
9525 EINTERN struct wl_listener *
9526 e_client_focus_defer_set_listener_get(E_Client *ec, wl_notify_func_t notify)
9528 API_ENTRY_VAL(NULL);
9529 return wl_signal_get(&priv->events.focus_defer_set, notify);
9533 e_client_focus_latest_set_listener_add(E_Client *ec, struct wl_listener *listener)
9536 wl_signal_add(&priv->events.focus_latest_set, listener);
9539 EINTERN struct wl_listener *
9540 e_client_focus_latest_set_listener_get(E_Client *ec, wl_notify_func_t notify)
9542 API_ENTRY_VAL(NULL);
9543 return wl_signal_get(&priv->events.focus_latest_set, notify);
9547 e_client_iconify_listener_add(E_Client *ec, struct wl_listener *listener)
9550 wl_signal_add(&priv->events.iconify, listener);
9553 EINTERN struct wl_listener *
9554 e_client_iconify_listener_get(E_Client *ec, wl_notify_func_t notify)
9556 API_ENTRY_VAL(NULL);
9557 return wl_signal_get(&priv->events.iconify, notify);
9561 e_client_uniconify_listener_add(E_Client *ec, struct wl_listener *listener)
9564 wl_signal_add(&priv->events.uniconify, listener);
9567 EINTERN struct wl_listener *
9568 e_client_uniconify_listener_get(E_Client *ec, wl_notify_func_t notify)
9570 API_ENTRY_VAL(NULL);
9571 return wl_signal_get(&priv->events.uniconify, notify);
9575 e_client_maximize_listener_add(E_Client *ec, struct wl_listener *listener)
9578 wl_signal_add(&priv->events.maximize, listener);
9581 EINTERN struct wl_listener *
9582 e_client_maximize_listener_get(E_Client *ec, wl_notify_func_t notify)
9584 API_ENTRY_VAL(NULL);
9585 return wl_signal_get(&priv->events.maximize, notify);
9589 e_client_unmaximize_listener_add(E_Client *ec, struct wl_listener *listener)
9592 wl_signal_add(&priv->events.unmaximize, listener);
9595 EINTERN struct wl_listener *
9596 e_client_unmaximize_listener_get(E_Client *ec, wl_notify_func_t notify)
9598 API_ENTRY_VAL(NULL);
9599 return wl_signal_get(&priv->events.unmaximize, notify);
9603 e_client_fullscreen_pre_listener_add(E_Client *ec, struct wl_listener *listener)
9606 wl_signal_add(&priv->events.fullscreen_pre, listener);
9609 EINTERN struct wl_listener *
9610 e_client_fullscreen_pre_listener_get(E_Client *ec, wl_notify_func_t notify)
9612 API_ENTRY_VAL(NULL);
9613 return wl_signal_get(&priv->events.fullscreen_pre, notify);
9617 e_client_fullscreen_listener_add(E_Client *ec, struct wl_listener *listener)
9620 wl_signal_add(&priv->events.fullscreen, listener);
9623 EINTERN struct wl_listener *
9624 e_client_fullscreen_listener_get(E_Client *ec, wl_notify_func_t notify)
9626 API_ENTRY_VAL(NULL);
9627 return wl_signal_get(&priv->events.fullscreen, notify);
9631 e_client_unfullscreen_listener_add(E_Client *ec, struct wl_listener *listener)
9634 wl_signal_add(&priv->events.unfullscreen, listener);
9637 EINTERN struct wl_listener *
9638 e_client_unfullscreen_listener_get(E_Client *ec, wl_notify_func_t notify)
9640 API_ENTRY_VAL(NULL);
9641 return wl_signal_get(&priv->events.unfullscreen, notify);
9645 e_client_move_listener_add(E_Client *ec, struct wl_listener *listener)
9648 wl_signal_add(&priv->events.move, listener);
9651 EINTERN struct wl_listener *
9652 e_client_move_listener_get(E_Client *ec, wl_notify_func_t notify)
9654 API_ENTRY_VAL(NULL);
9655 return wl_signal_get(&priv->events.move, notify);
9659 e_client_raise_listener_add(E_Client *ec, struct wl_listener *listener)
9662 wl_signal_add(&priv->events.raise, listener);
9665 EINTERN struct wl_listener *
9666 e_client_raise_listener_get(E_Client *ec, wl_notify_func_t notify)
9668 API_ENTRY_VAL(NULL);
9669 return wl_signal_get(&priv->events.raise, notify);
9673 e_client_lower_listener_add(E_Client *ec, struct wl_listener *listener)
9676 wl_signal_add(&priv->events.lower, listener);
9679 EINTERN struct wl_listener *
9680 e_client_lower_listener_get(E_Client *ec, wl_notify_func_t notify)
9682 API_ENTRY_VAL(NULL);
9683 return wl_signal_get(&priv->events.lower, notify);
9687 e_client_stack_below_listener_add(E_Client *ec, struct wl_listener *listener)
9690 wl_signal_add(&priv->events.stack_below, listener);
9693 EINTERN struct wl_listener *
9694 e_client_stack_below_listener_get(E_Client *ec, wl_notify_func_t notify)
9696 API_ENTRY_VAL(NULL);
9697 return wl_signal_get(&priv->events.stack_below, notify);
9701 e_client_stack_above_listener_add(E_Client *ec, struct wl_listener *listener)
9704 wl_signal_add(&priv->events.stack_above, listener);
9707 EINTERN struct wl_listener *
9708 e_client_stack_above_listener_get(E_Client *ec, wl_notify_func_t notify)
9710 API_ENTRY_VAL(NULL);
9711 return wl_signal_get(&priv->events.stack_above, notify);
9715 e_client_layer_set_listener_add(E_Client *ec, struct wl_listener *listener)
9718 wl_signal_add(&priv->events.layer_set, listener);
9721 EINTERN struct wl_listener *
9722 e_client_layer_set_listener_get(E_Client *ec, wl_notify_func_t notify)
9724 API_ENTRY_VAL(NULL);
9725 return wl_signal_get(&priv->events.layer_set, notify);
9729 e_client_stack_transient_for_done_listener_add(E_Client *ec, struct wl_listener *listener)
9732 wl_signal_add(&priv->events.stack_transient_for_done, listener);
9735 EINTERN struct wl_listener *
9736 e_client_stack_transient_for_done_listener_get(E_Client *ec, wl_notify_func_t notify)
9738 API_ENTRY_VAL(NULL);
9739 return wl_signal_get(&priv->events.stack_transient_for_done, notify);
9743 e_client_stick_listener_add(E_Client *ec, struct wl_listener *listener)
9746 wl_signal_add(&priv->events.stick, listener);
9749 EINTERN struct wl_listener *
9750 e_client_stick_listener_get(E_Client *ec, wl_notify_func_t notify)
9752 API_ENTRY_VAL(NULL);
9753 return wl_signal_get(&priv->events.stick, notify);
9757 e_client_unstick_listener_add(E_Client *ec, struct wl_listener *listener)
9760 wl_signal_add(&priv->events.unstick, listener);
9763 EINTERN struct wl_listener *
9764 e_client_unstick_listener_get(E_Client *ec, wl_notify_func_t notify)
9766 API_ENTRY_VAL(NULL);
9767 return wl_signal_get(&priv->events.unstick, notify);