3 static int _e_client_hooks_delete = 0;
4 static int _e_client_hooks_walking = 0;
6 static int _e_client_intercept_hooks_delete = 0;
7 static int _e_client_intercept_hooks_walking = 0;
9 E_API int E_EVENT_CLIENT_ADD = -1;
10 E_API int E_EVENT_CLIENT_REMOVE = -1;
11 E_API int E_EVENT_CLIENT_ZONE_SET = -1;
12 E_API int E_EVENT_CLIENT_DESK_SET = -1;
13 E_API int E_EVENT_CLIENT_RESIZE = -1;
14 E_API int E_EVENT_CLIENT_MOVE = -1;
15 E_API int E_EVENT_CLIENT_SHOW = -1;
16 E_API int E_EVENT_CLIENT_HIDE = -1;
17 E_API int E_EVENT_CLIENT_ICONIFY = -1;
18 E_API int E_EVENT_CLIENT_UNICONIFY = -1;
19 E_API int E_EVENT_CLIENT_STACK = -1;
20 E_API int E_EVENT_CLIENT_FOCUS_IN = -1;
21 E_API int E_EVENT_CLIENT_FOCUS_OUT = -1;
22 E_API int E_EVENT_CLIENT_PROPERTY = -1;
23 E_API int E_EVENT_CLIENT_FULLSCREEN = -1;
24 E_API int E_EVENT_CLIENT_UNFULLSCREEN = -1;
25 #ifdef _F_ZONE_WINDOW_ROTATION_
26 E_API int E_EVENT_CLIENT_ROTATION_CHANGE_BEGIN = -1;
27 E_API int E_EVENT_CLIENT_ROTATION_CHANGE_CANCEL = -1;
28 E_API int E_EVENT_CLIENT_ROTATION_CHANGE_END = -1;
29 E_API int E_EVENT_CLIENT_ROTATION_GEOMETRY_SET = -1;
31 E_API int E_EVENT_CLIENT_VISIBILITY_CHANGE = -1;
32 E_API int E_EVENT_CLIENT_BUFFER_CHANGE = -1;
33 E_API int E_EVENT_CLIENT_FOCUS_SKIP_SET = -1;
34 E_API int E_EVENT_CLIENT_FOCUS_SKIP_UNSET = -1;
36 static Eina_Hash *clients_hash[E_PIXMAP_TYPE_MAX] = {NULL}; // pixmap->client
38 #ifdef REFACTOR_FOCUS_POLICY
40 static E_Client *focused = NULL;
42 static E_Client *ecmove = NULL;
43 static E_Client *ecresize = NULL;
44 static E_Client *action_client = NULL;
46 #ifdef REFACTOR_FOCUS_POLICY
48 static Eina_List *focus_stack = NULL;
49 static Eina_List *defer_focus_stack = NULL;
52 static Eina_Bool comp_grabbed = EINA_FALSE;
54 static Eina_List *handlers = NULL;
55 static Eina_List *hooks = NULL;
57 static Ecore_Event_Handler *action_handler_mouse = NULL;
58 static Ecore_Timer *action_timer = NULL;
59 static Eina_Rectangle action_orig = {0, 0, 0, 0};
61 static E_Client_Resize_Object_Create_Cb _e_client_resize_object_create_cb = NULL;
63 #ifdef REFACTOR_FOCUS_POLICY
65 static GMutex focused_ec_mutex;
68 EINTERN void e_client_focused_set(E_Client *ec);
69 static void _e_client_transient_for_group_make(E_Client *ec, Eina_List **list);
70 static Evas_Object *_e_client_resize_object_create(E_Client *ec);
71 static void _e_client_resize_object_del(E_Client *ec);
72 static void _e_client_stay_within_canvas(E_Client *ec, int x, int y, int *new_x, int *new_y);
73 static void _e_client_stay_within_canvas_margin(E_Client *ec, int x, int y, int *new_x, int *new_y);
75 static Eina_Inlist *_e_client_hooks[] =
77 [E_CLIENT_HOOK_EVAL_PRE_FETCH] = NULL,
78 [E_CLIENT_HOOK_EVAL_FETCH] = NULL,
79 [E_CLIENT_HOOK_EVAL_PRE_POST_FETCH] = NULL,
80 [E_CLIENT_HOOK_EVAL_POST_FETCH] = NULL,
81 [E_CLIENT_HOOK_EVAL_PRE_FRAME_ASSIGN] = NULL,
82 [E_CLIENT_HOOK_EVAL_POST_FRAME_ASSIGN] = NULL,
83 [E_CLIENT_HOOK_EVAL_PRE_NEW_CLIENT] = NULL,
84 [E_CLIENT_HOOK_EVAL_POST_NEW_CLIENT] = NULL,
85 [E_CLIENT_HOOK_EVAL_END] = NULL,
86 [E_CLIENT_HOOK_FOCUS_SET] = NULL,
87 [E_CLIENT_HOOK_FOCUS_UNSET] = NULL,
88 [E_CLIENT_HOOK_NEW_CLIENT] = NULL,
89 //#ifdef REFACTOR_ZONE_DESK
91 [E_CLIENT_HOOK_DESK_SET] = NULL,
93 [E_CLIENT_HOOK_MOVE_BEGIN] = NULL,
94 [E_CLIENT_HOOK_MOVE_UPDATE] = NULL,
95 [E_CLIENT_HOOK_MOVE_END] = NULL,
96 [E_CLIENT_HOOK_RESIZE_BEGIN] = NULL,
97 [E_CLIENT_HOOK_RESIZE_UPDATE] = NULL,
98 [E_CLIENT_HOOK_RESIZE_END] = NULL,
99 [E_CLIENT_HOOK_FULLSCREEN_PRE] = NULL,
100 //#ifdef REFACTOR_ZONE_DESK
101 [E_CLIENT_HOOK_FULLSCREEN] = NULL,
102 [E_CLIENT_HOOK_UNFULLSCREEN] = NULL,
104 [E_CLIENT_HOOK_DEL] = NULL,
105 [E_CLIENT_HOOK_UNREDIRECT] = NULL,
106 [E_CLIENT_HOOK_REDIRECT] = NULL,
107 #ifdef _F_E_CLIENT_NEW_CLIENT_POST_HOOK_
108 [E_CLIENT_HOOK_NEW_CLIENT_POST] = NULL,
110 [E_CLIENT_HOOK_EVAL_VISIBILITY] = NULL,
111 [E_CLIENT_HOOK_ICONIFY] = NULL,
112 [E_CLIENT_HOOK_UNICONIFY] = NULL,
113 [E_CLIENT_HOOK_AUX_HINT_CHANGE] = NULL,
114 [E_CLIENT_HOOK_WINDOW_ROLE_CHANGE] = NULL,
115 [E_CLIENT_HOOK_TRANSFORM_CHANGE] = NULL,
116 [E_CLIENT_HOOK_ACTIVATE_DONE] = NULL,
117 [E_CLIENT_HOOK_EVAL_VISIBILITY_END] = NULL,
118 //#ifdef REFACTOR_FOCUS_POLICY
119 [E_CLIENT_HOOK_MOUSE_IN] = NULL,
120 [E_CLIENT_HOOK_MOUSE_OUT] = NULL,
121 [E_CLIENT_HOOK_MOUSE_DOWN] = NULL,
122 [E_CLIENT_HOOK_LOWER] = NULL,
123 [E_CLIENT_HOOK_MOVE] = NULL,
124 [E_CLIENT_HOOK_FOCUS_DEFER_SET] = NULL,
125 [E_CLIENT_HOOK_FOCUS_LATEST_SET] = NULL,
127 //#ifdef REFACTOR_ZONE_DESK
128 [E_CLIENT_HOOK_STICK] = NULL,
129 [E_CLIENT_HOOK_UNSTICK] = NULL,
130 [E_CLIENT_HOOK_MAXIMIZE] = NULL,
131 [E_CLIENT_HOOK_UNMAXIMIZE] = NULL,
135 static Eina_Inlist *_e_client_intercept_hooks[] =
137 [E_CLIENT_INTERCEPT_HOOK_FOCUS_REVERT] = NULL,
138 [E_CLIENT_INTERCEPT_HOOK_AUTO_PLACEMENT] = NULL,
141 ///////////////////////////////////////////
144 _e_client_hooks_clean(void)
150 for (x = 0; x < E_CLIENT_HOOK_LAST; x++)
151 EINA_INLIST_FOREACH_SAFE(_e_client_hooks[x], l, ch)
153 if (!ch->delete_me) continue;
154 _e_client_hooks[x] = eina_inlist_remove(_e_client_hooks[x], EINA_INLIST_GET(ch));
160 _e_client_hook_call(E_Client_Hook_Point hookpoint, E_Client *ec)
164 e_object_ref(E_OBJECT(ec));
165 _e_client_hooks_walking++;
166 EINA_INLIST_FOREACH(_e_client_hooks[hookpoint], ch)
168 if (ch->delete_me) continue;
169 ch->func(ch->data, ec);
170 if ((hookpoint != E_CLIENT_HOOK_DEL) &&
171 (hookpoint != E_CLIENT_HOOK_MOVE_END) &&
172 (hookpoint != E_CLIENT_HOOK_RESIZE_END) &&
173 (hookpoint != E_CLIENT_HOOK_FOCUS_UNSET) &&
174 e_object_is_del(E_OBJECT(ec)))
177 _e_client_hooks_walking--;
178 if ((_e_client_hooks_walking == 0) && (_e_client_hooks_delete > 0))
179 _e_client_hooks_clean();
180 return !!e_object_unref(E_OBJECT(ec));
183 ///////////////////////////////////////////
186 _e_client_intercept_hooks_clean(void)
189 E_Client_Intercept_Hook *ch;
192 for (x = 0; x < E_CLIENT_INTERCEPT_HOOK_LAST; x++)
193 EINA_INLIST_FOREACH_SAFE(_e_client_intercept_hooks[x], l, ch)
195 if (!ch->delete_me) continue;
196 _e_client_intercept_hooks[x] =
197 eina_inlist_remove(_e_client_intercept_hooks[x], EINA_INLIST_GET(ch));
203 _e_client_intercept_hook_call(E_Client_Intercept_Hook_Point hookpoint, E_Client *ec)
205 E_Client_Intercept_Hook *ch;
206 Eina_Bool ret = EINA_TRUE;
208 if (e_object_is_del(E_OBJECT(ec)))
210 if (hookpoint != E_CLIENT_INTERCEPT_HOOK_FOCUS_REVERT)
216 e_object_ref(E_OBJECT(ec));
217 _e_client_intercept_hooks_walking++;
218 EINA_INLIST_FOREACH(_e_client_intercept_hooks[hookpoint], ch)
220 if (ch->delete_me) continue;
221 if (!(ch->func(ch->data, ec)))
227 _e_client_intercept_hooks_walking--;
228 if ((_e_client_intercept_hooks_walking == 0) &&
229 (_e_client_intercept_hooks_delete > 0))
230 _e_client_intercept_hooks_clean();
232 e_object_unref(E_OBJECT(ec));
237 _e_client_event_simple_free(void *d EINA_UNUSED, E_Event_Client *ev)
240 e_object_unref(E_OBJECT(ev->ec));
245 _e_client_event_simple(E_Client *ec, int type)
249 ev = E_NEW(E_Event_Client, 1);
253 e_object_ref(E_OBJECT(ec));
254 ecore_event_add(type, ev, (Ecore_End_Cb)_e_client_event_simple_free, NULL);
258 _e_client_event_add(E_Client *ec)
263 ec->reg_ev.add = EINA_TRUE;
264 ELOGF("COMP", "SEND E_EVENT_CLIENT_ADD event", ec);
265 _e_client_event_simple(ec, E_EVENT_CLIENT_ADD);
269 _e_client_event_remove(E_Client *ec)
274 ec->reg_ev.add = EINA_FALSE;
275 ELOGF("COMP", "SEND E_EVENT_CLIENT_REMOVE event", ec);
276 _e_client_event_simple(ec, E_EVENT_CLIENT_REMOVE);
280 _e_client_event_show(E_Client *ec)
285 ec->reg_ev.show = EINA_TRUE;
286 _e_client_event_simple(ec, E_EVENT_CLIENT_SHOW);
290 _e_client_event_hide(E_Client *ec)
292 if (!ec->reg_ev.show)
295 ec->reg_ev.show = EINA_FALSE;
296 _e_client_event_simple(ec, E_EVENT_CLIENT_HIDE);
300 _e_client_event_property(E_Client *ec, int prop)
302 E_Event_Client_Property *ev;
304 ev = E_NEW(E_Event_Client_Property, 1);
309 e_object_ref(E_OBJECT(ec));
310 ecore_event_add(E_EVENT_CLIENT_PROPERTY, ev, (Ecore_End_Cb)_e_client_event_simple_free, NULL);
313 #ifdef REFACTOR_ZONE_DESK
316 _e_client_event_desk_set_free(void *d EINA_UNUSED, E_Event_Client_Desk_Set *ev)
319 e_object_unref(E_OBJECT(ev->ec));
320 e_object_unref(E_OBJECT(ev->desk));
325 _e_client_event_zone_set_free(void *d EINA_UNUSED, E_Event_Client_Zone_Set *ev)
328 e_object_unref(E_OBJECT(ev->ec));
329 e_object_unref(E_OBJECT(ev->zone));
333 ////////////////////////////////////////////////
336 _e_client_action_input_win_del(void)
338 if (!comp_grabbed) return 0;
340 e_comp_ungrab_input(1, 1);
346 _e_client_action_finish(void)
349 _e_client_action_input_win_del();
351 E_FREE_FUNC(action_timer, ecore_timer_del);
352 E_FREE_FUNC(action_handler_mouse, ecore_event_handler_del);
355 action_client->keyboard_resizing = 0;
357 action_client = NULL;
361 _e_client_transform_point_transform(int cx, int cy, double angle, int x, int y, int *tx, int *ty)
363 double s = sin(angle * M_PI / 180);
364 double c = cos(angle * M_PI / 180);
371 ry = - x * s + y * c;
381 _e_client_transform_geometry_save(E_Client *ec, E_Map *map)
387 for (i = 0; i < 4; i ++)
389 e_map_point_precise_coord_get(map, i,
390 &ec->transform.saved[i].x,
391 &ec->transform.saved[i].y,
392 &ec->transform.saved[i].z);
397 _e_client_transform_resize(E_Client *ec)
401 double dx = 0, dy = 0;
406 if (!ec->transformed) return;
408 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
414 cx = ec->client.x + pw / 2;
415 cy = ec->client.y + ph / 2;
417 /* step 1: Rotate resized object and get map points */
418 map = e_map_new_with_direct_render(ec->transform_core.direct_render);
419 e_map_util_points_populate_from_geometry(map,
420 ec->client.x, ec->client.y,
423 e_map_util_rotate(map, ec->transform.angle, cx, cy);
424 e_map_util_zoom(map, ec->transform.zoom, ec->transform.zoom, cx, cy);
426 for (i = 0; i < 4; i++)
427 e_map_point_precise_coord_get(map, i, &px[i], &py[i], NULL);
431 /* step 2: get adjusted values to keep up fixed position according
433 switch (ec->resize_mode)
435 case E_POINTER_RESIZE_R:
436 case E_POINTER_RESIZE_BR:
437 dx = ec->transform.saved[0].x - px[0];
438 dy = ec->transform.saved[0].y - py[0];
440 case E_POINTER_RESIZE_BL:
441 case E_POINTER_RESIZE_B:
442 dx = ec->transform.saved[1].x - px[1];
443 dy = ec->transform.saved[1].y - py[1];
445 case E_POINTER_RESIZE_TL:
446 case E_POINTER_RESIZE_L:
447 dx = ec->transform.saved[2].x - px[2];
448 dy = ec->transform.saved[2].y - py[2];
450 case E_POINTER_RESIZE_T:
451 case E_POINTER_RESIZE_TR:
452 dx = ec->transform.saved[3].x - px[3];
453 dy = ec->transform.saved[3].y - py[3];
459 ec->transform.adjusted.x = dx;
460 ec->transform.adjusted.y = dy;
462 /* step 3: set each points of the quadrangle */
463 map = e_map_new_with_direct_render(ec->transform_core.direct_render);
464 e_map_util_points_populate_from_object_full(map, ec->frame, 0);
466 for (i = 0; i < 4; i++)
467 e_map_point_precise_coord_set(map, i, px[i] + dx, py[i] + dy, 0);
469 e_client_map_set(ec, map);
470 e_client_map_enable_set(ec, EINA_TRUE);
475 _e_client_transform_resize_handle(E_Client *ec)
478 int new_x, new_y, new_w, new_h;
482 Evas_Point current, moveinfo;
485 if (e_object_is_del(E_OBJECT(ec))) return;
486 if (e_client_util_ignored_get(ec)) return;
487 if (!ec->transformed) return;
489 zone = e_comp_zone_find_by_ec(ec);
492 button_id = ec->moveinfo.down.button;
494 org_w = ec->mouse.last_down[button_id - 1].w;
495 org_h = ec->mouse.last_down[button_id - 1].h;
497 new_w = ec->client.w;
498 new_h = ec->client.h;
499 new_x = ec->client.x;
500 new_y = ec->client.y;
502 /* step 1: get center coordinate its' based on original object geometry*/
503 cx = ec->client.x + org_w / 2;
504 cy = ec->client.y + org_h / 2;
506 /* step 2: transform coordinates of mouse position
507 * subtract adjusted value from mouse position is needed */
508 current.x = ec->mouse.current.mx - ec->transform.adjusted.x;
509 current.y = ec->mouse.current.my - ec->transform.adjusted.y;
510 moveinfo.x = ec->moveinfo.down.mx - ec->transform.adjusted.x;
511 moveinfo.y = ec->moveinfo.down.my - ec->transform.adjusted.y;
513 _e_client_transform_point_transform(cx, cy, ec->transform.angle,
514 current.x, current.y,
515 ¤t.x, ¤t.y);
516 _e_client_transform_point_transform(cx, cy, ec->transform.angle,
517 moveinfo.x, moveinfo.y,
518 &moveinfo.x, &moveinfo.y);
520 /* step 3: calculate new size */
521 if ((ec->resize_mode == E_POINTER_RESIZE_TR) ||
522 (ec->resize_mode == E_POINTER_RESIZE_R) ||
523 (ec->resize_mode == E_POINTER_RESIZE_BR))
525 if ((button_id >= 1) && (button_id <= 3))
526 new_w = org_w + (current.x - moveinfo.x);
528 new_w = ec->moveinfo.down.w + (current.x - moveinfo.x);
530 else if ((ec->resize_mode == E_POINTER_RESIZE_TL) ||
531 (ec->resize_mode == E_POINTER_RESIZE_L) ||
532 (ec->resize_mode == E_POINTER_RESIZE_BL))
534 if ((button_id >= 1) && (button_id <= 3))
535 new_w = org_w - (current.x - moveinfo.x);
537 new_w = ec->moveinfo.down.w - (current.x - moveinfo.x);
540 if ((ec->resize_mode == E_POINTER_RESIZE_TL) ||
541 (ec->resize_mode == E_POINTER_RESIZE_T) ||
542 (ec->resize_mode == E_POINTER_RESIZE_TR))
544 if ((button_id >= 1) && (button_id <= 3))
545 new_h = org_h - (current.y - moveinfo.y);
547 new_h = ec->moveinfo.down.h - (current.y - moveinfo.y);
549 else if ((ec->resize_mode == E_POINTER_RESIZE_BL) ||
550 (ec->resize_mode == E_POINTER_RESIZE_B) ||
551 (ec->resize_mode == E_POINTER_RESIZE_BR))
553 if ((button_id >= 1) && (button_id <= 3))
554 new_h = org_h + (current.y - moveinfo.y);
556 new_h = ec->moveinfo.down.h + (current.y - moveinfo.y);
559 new_w = MIN(new_w, zone->w);
560 new_h = MIN(new_h, zone->h);
562 /* step 4: move to new position */
563 if ((ec->resize_mode == E_POINTER_RESIZE_TL) ||
564 (ec->resize_mode == E_POINTER_RESIZE_L) ||
565 (ec->resize_mode == E_POINTER_RESIZE_BL))
566 new_x += (new_w - org_w);
567 if ((ec->resize_mode == E_POINTER_RESIZE_TL) ||
568 (ec->resize_mode == E_POINTER_RESIZE_T) ||
569 (ec->resize_mode == E_POINTER_RESIZE_TR))
570 new_y += (new_h - org_h);
572 /* step 5: set geometry to new value */
573 evas_object_geometry_set(ec->frame, new_x, new_y, new_w, new_h);
577 _e_client_transform_resize_begin(E_Client *ec)
580 if (!ec->transformed) return;
582 map = e_client_map_get(ec);
583 _e_client_transform_geometry_save(ec, map);
588 _e_client_transform_resize_end(E_Client *ec)
591 int new_x = 0, new_y = 0;
594 if (!ec->transformed) return;
596 map = e_client_map_get(ec);
599 if (!e_pixmap_size_get(ec->pixmap, &pw, &ph))
605 cx = ec->client.x + pw / 2 + ec->transform.adjusted.x;
606 cy = ec->client.y + ph / 2 + ec->transform.adjusted.y;
608 if (ec->transform.zoom != 1.0)
612 tmp_map = e_map_dup(map);
613 e_map_util_zoom(tmp_map,
614 1 / ec->transform.zoom,
615 1 / ec->transform.zoom,
618 _e_client_transform_geometry_save(ec, tmp_map);
623 _e_client_transform_geometry_save(ec, map);
626 /* move original object to adjusted position after resizing */
627 _e_client_transform_point_transform(cx, cy,
629 ec->transform.saved[0].x,
630 ec->transform.saved[0].y,
632 e_client_util_move_without_frame(ec, new_x, new_y);
633 e_map_util_object_move_sync_set(map, EINA_TRUE);
638 _e_client_transform_move_end(E_Client *ec)
642 double dx, dy, px, py;
645 if (!ec->transformed) return;
647 map = e_client_map_get(ec);
650 if (ec->transform.zoom != 1.0)
652 e_map_point_precise_coord_get(map, 0, &px, &py, NULL);
654 dx = px - ec->transform.saved[0].x;
655 dy = py - ec->transform.saved[0].y;
657 for (i = 0; i < 4; i++)
659 ec->transform.saved[i].x += dx;
660 ec->transform.saved[i].y += dy;
664 _e_client_transform_geometry_save(ec, map);
669 e_client_intercept_hook_focus_revert_call(E_Client *ec)
671 // no need to call the intercept hook if ec is NULL.
672 if (!ec) return EINA_FALSE;
674 if (!_e_client_intercept_hook_call(E_CLIENT_INTERCEPT_HOOK_FOCUS_REVERT, ec))
676 ELOGF("FOCUS", "E_CLIENT_INTERCEPT_HOOK_FOCUS_REVERT Intercepted.", ec);
684 e_client_check_fully_contain_by_above(E_Client *ec, Eina_Bool check_layer)
686 E_Client *above = NULL;
688 int x = 0, y = 0, w = 0, h = 0;
689 int ax = 0, ay = 0, aw = 0, ah = 0;
691 if (!ec) return NULL;
693 e_client_geometry_get(ec, &x, &y, &w, &h);
695 zone = e_comp_zone_find_by_ec(ec);
697 E_RECTS_CLIP_TO_RECT(x, y, w, h, zone->x, zone->y, zone->w, zone->h);
699 above = e_client_above_get(ec);
703 (above->layer <= ec->layer))
705 above = e_client_above_get(above);
709 if ((!e_object_is_del(E_OBJECT(above))) &&
710 (!e_client_util_ignored_get(above)) &&
712 (!above->iconic || e_policy_visibility_client_is_uniconic(above)) &&
713 (!above->bg_state) &&
715 (!above->visibility.force_obscured) &&
718 e_client_geometry_get(above, &ax, &ay, &aw, &ah);
719 if (E_CONTAINS(ax, ay, aw, ah, x, y, w, h))
722 above = e_client_above_get(above);
729 e_client_check_obscured_by_children_group(E_Client *ec)
731 E_Client *cec = NULL;
732 Eina_List *transients = NULL, *l = NULL;
734 _e_client_transient_for_group_make(ec, &transients);
735 if (!transients) return NULL;
737 EINA_LIST_FOREACH(transients, l, cec)
739 if (E_CONTAINS(cec->x, cec->y, cec->w, cec->h, ec->x, ec->y, ec->w, ec->h))
741 if (!cec->argb) break;
742 if (cec->visibility.opaque > 0) break;
746 eina_list_free(transients);
752 e_client_check_really_iconified(E_Client *ec)
754 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
756 if (!ec->iconic) return EINA_FALSE;
758 return ((!e_policy_visibility_client_is_uniconic(ec) &&
759 !e_policy_visibility_client_is_uniconify_render_running(ec)) ||
760 (e_client_is_iconified_by_client(ec)));
763 #ifdef REFACTOR_FOCUS_POLICY
766 _e_client_focus_can_take_by_vis_obscured(E_Client *ec)
768 switch (ec->visibility.obscured)
770 case E_VISIBILITY_UNKNOWN:
771 if (e_client_check_really_iconified(ec))
774 if (!evas_object_visible_get(ec->frame) &&
775 !eina_list_data_find(defer_focus_stack, ec))
779 case E_VISIBILITY_FULLY_OBSCURED:
780 if (e_client_check_really_iconified(ec))
783 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK)
785 if (!evas_object_visible_get(ec->frame))
787 ELOGF("FOCUS", "client is hidden, skip focus", ec);
793 case E_VISIBILITY_UNOBSCURED:
794 case E_VISIBILITY_PARTIALLY_OBSCURED:
795 case E_VISIBILITY_PRE_UNOBSCURED:
803 _e_client_focus_can_take(E_Client *ec)
806 E_Client *child_ec = NULL;
807 E_Client *above_ec = NULL;
808 int x = 0, y = 0, w = 0, h = 0;
810 if (!ec) return EINA_FALSE;
811 if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
812 if (e_client_util_ignored_get(ec)) return EINA_FALSE;
814 if (!(ec->icccm.accepts_focus || ec->icccm.take_focus)) return EINA_FALSE;
815 if (ec->lock_focus_in || ec->lock_focus_out) return EINA_FALSE;
817 if (!ec->visible) return EINA_FALSE;
818 if (ec->bg_state) return EINA_FALSE;
819 if (ec->visibility.force_obscured) return EINA_FALSE;
820 if (!_e_client_focus_can_take_by_vis_obscured(ec)) return EINA_FALSE;
822 zone = e_comp_zone_find_by_ec(ec);
825 e_client_geometry_get(ec, &x, &y, &w, &h);
826 if (!E_INTERSECTS(zone->x, zone->y, zone->w, zone->h, x, y, w, h))
830 above_ec = e_client_check_fully_contain_by_above(ec, EINA_FALSE);
833 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK)
835 if (!evas_object_visible_get(above_ec->frame))
839 child_ec = e_client_check_obscured_by_children_group(ec);
840 if (!child_ec) return EINA_FALSE;
841 if (above_ec != child_ec) return EINA_FALSE;
843 if (_e_client_focus_can_take(child_ec))
845 else if (e_client_check_fully_contain_by_above(child_ec, EINA_FALSE))
853 e_client_focus_can_take(E_Client *ec)
855 return _e_client_focus_can_take(ec);
859 _e_client_focus_topmost_focusable_get(void)
863 E_CLIENT_REVERSE_FOREACH(ec)
865 if (_e_client_focus_can_take(ec))
872 _e_client_find_next_focus(E_Client *ec)
875 E_Client *temp_ec = NULL;
877 // call the intercept hook of the revert focus
878 if (e_client_intercept_hook_focus_revert_call(ec))
881 EINA_LIST_FOREACH(focus_stack, l, temp_ec)
883 if (_e_client_focus_can_take(temp_ec))
891 _e_client_revert_focus_get(E_Client *ec)
893 E_Client *pec = NULL, *focus_ec = NULL;
897 if (stopping) return NULL;
899 return _e_client_find_next_focus(NULL);
901 zone = e_comp_zone_find_by_ec(ec);
902 if (!zone) return NULL;
903 desk = e_desk_current_get(zone);
904 if (!desk) return NULL;
905 if (!e_comp_client_zone_is_displaying(ec)) return NULL;
907 if (e_config->focus_policy == E_FOCUS_MOUSE)
909 // set mouse over focus
910 pec = e_client_under_pointer_get(desk, ec);
913 /* no autoraise/revert here because it's probably annoying */
916 focus_ec = _e_client_find_next_focus(ec);
923 _e_client_event_focus_skip_set(E_Client *ec, Eina_Bool by_client)
925 E_Event_Client_Focus_Skip_Set *ev;
927 ev = E_NEW(E_Event_Client_Focus_Skip_Set, 1);
931 ev->by_client = by_client;
932 e_object_ref(E_OBJECT(ec));
934 ecore_event_add(E_EVENT_CLIENT_FOCUS_SKIP_SET, ev, (Ecore_End_Cb)_e_client_event_simple_free, NULL);
938 _e_client_event_focus_skip_unset(E_Client *ec, Eina_Bool by_client)
940 E_Event_Client_Focus_Skip_Unset *ev;
942 ev = E_NEW(E_Event_Client_Focus_Skip_Unset, 1);
946 ev->by_client = by_client;
947 e_object_ref(E_OBJECT(ec));
949 ecore_event_add(E_EVENT_CLIENT_FOCUS_SKIP_UNSET, ev, (Ecore_End_Cb)_e_client_event_simple_free, NULL);
953 e_client_focus_skip_set(E_Client *ec, Eina_Bool skip, Eina_Bool by_client)
959 if (ec->icccm.accepts_focus)
961 ELOGF("TZPOL", "FOCUS|SKIP SET (by_client:%d)", ec, by_client);
962 ec->icccm.accepts_focus = ec->icccm.take_focus = 0;
963 ec->changes.accepts_focus = 1;
966 _e_client_event_focus_skip_set(ec, by_client);
971 if (!ec->icccm.accepts_focus)
973 ELOGF("TZPOL", "FOCUS|SKIP UNSET (by_client:%d)", ec, by_client);
974 ec->icccm.accepts_focus = ec->icccm.take_focus = 1;
975 ec->changes.accepts_focus = 1;
978 _e_client_event_focus_skip_unset(ec, by_client);
983 #ifdef REFACTOR_FOCUS_POLICY
986 e_client_revert_focus(E_Client *ec)
988 E_Client *focus_ec = NULL;
990 // check topmost focus policy
991 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK)
993 focus_ec = _e_client_focus_topmost_focusable_get();
994 if (focused == focus_ec) return;
998 if (!focus_ec->iconic || focus_ec->exp_iconify.buffer_flush)
1000 ELOGF("FOCUS", "focus set | topmost_focus", focus_ec);
1001 if (focused) e_client_frame_focus_set(focused, EINA_FALSE);
1002 e_client_frame_focus_set(focus_ec, EINA_TRUE);
1007 ELOGF("FOCUS", "focus unset | No focusable ec", focused);
1008 e_client_frame_focus_set(focused, EINA_FALSE);
1014 focus_ec = _e_client_revert_focus_get(ec);
1015 if (!focus_ec) return;
1019 e_client_focus_defer_unset(ec);
1020 ELOGF("FOCUS", "focus unset | revert_focus", ec);
1021 e_client_frame_focus_set(ec, EINA_FALSE);
1024 if (!focus_ec->iconic || focus_ec->exp_iconify.buffer_flush)
1026 ELOGF("FOCUS", "focus set | revert_focus", focus_ec);
1027 e_client_frame_focus_set(focus_ec, EINA_TRUE);
1033 e_client_check_above_focused(E_Client *ec)
1035 E_Client *focus = NULL;
1036 E_Client *above = NULL;
1038 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
1040 focus = e_client_focused_get();
1041 if (!focus) return EINA_FALSE;
1043 above = e_client_above_get(ec);
1049 above = e_client_above_get(above);
1056 _e_client_free(E_Client *ec)
1058 e_comp_object_redirected_set(ec->frame, 0);
1059 e_comp_object_render_update_del(ec->frame);
1061 E_OBJECT(ec)->references++;
1062 #ifdef REFACTOR_ZONE_DESK
1066 ec->desk->fullscreen_clients = eina_list_remove(ec->desk->fullscreen_clients, ec);
1067 if (!ec->desk->fullscreen_clients)
1068 e_comp_render_queue();
1072 e_comp->new_clients--;
1074 if (ec->e.state.video_parent && ec->e.state.video_parent_client)
1076 ec->e.state.video_parent_client->e.state.video_child =
1077 eina_list_remove(ec->e.state.video_parent_client->e.state.video_child, ec);
1079 if (ec->e.state.video_child)
1083 EINA_LIST_FREE(ec->e.state.video_child, tmp)
1084 tmp->e.state.video_parent_client = NULL;
1086 E_FREE_FUNC(ec->kill_timer, ecore_timer_del);
1087 E_FREE_LIST(ec->pending_resize, free);
1089 E_FREE_FUNC(ec->map_timer, ecore_timer_del);
1091 ec->transients = eina_list_free(ec->transients);
1092 if (ec->netwm.icons)
1095 for (i = 0; i < ec->netwm.num_icons; i++)
1096 free(ec->netwm.icons[i].data);
1097 E_FREE(ec->netwm.icons);
1099 E_FREE(ec->netwm.extra_types);
1100 eina_stringshare_replace(&ec->border.name, NULL);
1101 eina_stringshare_replace(&ec->bordername, NULL);
1102 eina_stringshare_replace(&ec->icccm.name, NULL);
1103 #if defined(__cplusplus) || defined(c_plusplus)
1104 eina_stringshare_replace(&ec->icccm.cpp_class, NULL);
1106 eina_stringshare_replace(&ec->icccm.class, NULL);
1108 eina_stringshare_replace(&ec->icccm.title, NULL);
1109 eina_stringshare_replace(&ec->icccm.icon_name, NULL);
1110 eina_stringshare_replace(&ec->icccm.machine, NULL);
1111 eina_stringshare_replace(&ec->icccm.window_role, NULL);
1112 if ((ec->icccm.command.argc > 0) && (ec->icccm.command.argv))
1116 for (i = 0; i < ec->icccm.command.argc; i++)
1117 free(ec->icccm.command.argv[i]);
1118 E_FREE(ec->icccm.command.argv);
1120 eina_stringshare_replace(&ec->netwm.name, NULL);
1121 eina_stringshare_replace(&ec->netwm.icon_name, NULL);
1122 eina_stringshare_replace(&ec->internal_icon, NULL);
1123 eina_stringshare_replace(&ec->internal_icon_key, NULL);
1125 #ifdef REFACTOR_FOCUS_POLICY
1126 // This code is executed at E_CLIENT_HOOK_DEL callback at e_focus_policy_history.c
1128 focus_stack = eina_list_remove(focus_stack, ec);
1129 e_client_focus_defer_unset(ec);
1132 E_FREE_FUNC(ec->frame, evas_object_del);
1134 #ifdef REFACTOR_FOCUS_POLICY
1135 // This code is executed at E_CLIENT_HOOK_DEL callback at e_focus_policy_topmost.c and e_focus_policy_history.c
1139 ELOGF("COMP", "CRITICAL. focused is deleted ec.", ec);
1140 ELOGF("FOCUS", "CLIENT FOCUS_SET", NULL);
1141 g_mutex_lock(&focused_ec_mutex);
1143 g_mutex_unlock(&focused_ec_mutex);
1147 E_OBJECT(ec)->references--;
1148 ELOGF("COMP", "CLIENT FREE", ec);
1150 e_uuid_store_entry_del(ec->uuid);
1151 #ifdef REFACTOR_ZONE_DESK
1153 e_desk_client_del(ec->desk, ec);
1159 _e_client_del(E_Client *ec)
1166 #ifdef REFACTOR_FOCUS_POLICY
1167 // This code is executed at E_CLIENT_HOOK_DEL callback at e_focus_policy_history.c
1169 focus_stack = eina_list_remove(focus_stack, ec);
1170 e_client_focus_defer_unset(ec);
1172 #ifdef REFACTOR_ZONE_DESK
1174 e_desk_visible_client_iconified_list_remove(ec->desk, ec);
1176 if (ec == e_comp_object_dim_client_get())
1178 INF("[DIM] client deleted\n");
1179 e_comp_object_dim_client_set(NULL);
1182 if (ec->cur_mouse_action)
1184 if (ec->cur_mouse_action->func.end)
1185 ec->cur_mouse_action->func.end(E_OBJECT(ec), "");
1187 if (action_client == ec) _e_client_action_finish();
1191 e_client_comp_hidden_set(ec, 1);
1192 evas_object_pass_events_set(ec->frame, 1);
1194 #ifdef REFACTOR_FOCUS_POLICY
1195 // This code is executed at E_CLIENT_HOOK_DEL callback at e_focus_policy_history.c
1198 e_client_revert_focus(ec);
1201 E_FREE_FUNC(ec->ping_poller, ecore_poller_del);
1202 /* must be called before parent/child clear */
1203 _e_client_hook_call(E_CLIENT_HOOK_DEL, ec);
1205 _e_client_event_remove(ec);
1207 ELOGF("COMP", "CLIENT DEL", ec);
1211 ec->parent->transients = eina_list_remove(ec->parent->transients, ec);
1214 EINA_LIST_FREE(ec->transients, child)
1215 child->parent = NULL;
1217 type = e_pixmap_type_get(ec->pixmap);
1218 if (type < E_PIXMAP_TYPE_MAX)
1219 eina_hash_del_by_key(clients_hash[type], &ec->pixmap);
1220 e_comp->clients = eina_list_remove(e_comp->clients, ec);
1221 e_comp_object_render_update_del(ec->frame);
1222 e_comp_post_update_purge(ec);
1223 if (e_pixmap_free(ec->pixmap))
1224 e_pixmap_client_set(ec->pixmap, NULL);
1227 // base_output_resolution
1228 e_client_transform_core_remove(ec, ec->base_output_resolution.transform);
1229 e_util_transform_del(ec->base_output_resolution.transform);
1230 ec->base_output_resolution.transform = NULL;
1231 E_FREE_FUNC(ec->base_output_resolution.hook_subsurf_create, e_comp_wl_hook_del);
1233 #ifdef REFACTOR_ZONE_DESK
1236 e_client_transform_core_remove(ec, ec->desk_zoom.transform);
1237 e_util_transform_del(ec->desk_zoom.transform);
1238 ec->desk_zoom.transform = NULL;
1239 E_FREE_FUNC(ec->desk_zoom.hook_subsurf_create, e_comp_wl_hook_del);
1242 if (ec->transform_core.transform_list)
1244 E_Util_Transform *transform;
1246 EINA_LIST_FREE(ec->transform_core.transform_list, transform)
1248 e_util_transform_unref(transform);
1252 ec->transform_core.result.enable = EINA_FALSE;
1254 #ifdef REFACTOR_ZONE_DESK
1256 e_client_desk_area_set(ec, NULL);
1257 e_util_transform_del(ec->desk_area.transform);
1258 ec->desk_area.transform = NULL;
1261 _e_client_resize_object_del(ec);
1263 e_comp_visibility_calculation_set(EINA_TRUE);
1266 ///////////////////////////////////////////
1269 _e_client_cb_kill_timer(void *data)
1271 E_Client *ec = data;
1273 // dont wait until it's hung -
1276 if (ec->netwm.pid > 1)
1277 kill(ec->netwm.pid, SIGKILL);
1279 ec->kill_timer = NULL;
1280 return ECORE_CALLBACK_CANCEL;
1284 _e_client_cb_ping_poller(void *data)
1289 if (e_object_is_del(E_OBJECT(ec)))
1291 ec->ping_poller = NULL;
1292 return ECORE_CALLBACK_CANCEL;
1300 evas_object_smart_callback_call(ec->frame, "unhung", NULL);
1301 E_FREE_FUNC(ec->kill_timer, ecore_timer_del);
1306 /* if time between last ping and now is greater
1307 * than half the ping interval... */
1308 if ((ecore_loop_time_get() - ec->ping) >
1309 ((e_config->ping_clients_interval *
1310 ecore_poller_poll_interval_get(ECORE_POLLER_CORE)) / 2.0))
1315 evas_object_smart_callback_call(ec->frame, "hung", NULL);
1316 /* FIXME: if below dialog is up - hide it now */
1318 if (ec->delete_requested)
1320 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
1321 e_client_act_kill_begin(ec);
1325 ec->ping_poller = NULL;
1327 return ECORE_CALLBACK_CANCEL;
1330 ///////////////////////////////////////////
1333 _e_client_action_input_win_new(void)
1337 CRI("DOUBLE COMP GRAB! ACK!!!!");
1340 comp_grabbed = e_comp_grab_input(1, 1);
1341 if (!comp_grabbed) _e_client_action_input_win_del();
1342 return comp_grabbed;
1346 _e_client_action_init(E_Client *ec)
1348 action_orig.x = ec->x;
1349 action_orig.y = ec->y;
1350 action_orig.w = ec->w;
1351 action_orig.h = ec->h;
1355 action_client->keyboard_resizing = 0;
1361 _e_client_move_begin(E_Client *ec)
1363 if ((ec->fullscreen) || (ec->lock_user_location))
1366 if (!_e_client_action_input_win_new()) return 0;
1369 _e_client_hook_call(E_CLIENT_HOOK_MOVE_BEGIN, ec);
1372 if (ecmove == ec) ecmove = NULL;
1373 _e_client_action_input_win_del();
1376 if (!ec->lock_user_stacking)
1378 if (e_config->border_raise_on_mouse_action)
1383 e_comp_client_override_add(ec);
1389 _e_client_move_end(E_Client *ec)
1392 _e_client_action_input_win_del();
1393 _e_client_hook_call(E_CLIENT_HOOK_MOVE_END, ec);
1395 if (ec->transformed)
1396 _e_client_transform_move_end(ec);
1399 e_comp_client_override_del(ec);
1406 _e_client_action_move_timeout(void *data EINA_UNUSED)
1408 _e_client_move_end(action_client);
1409 _e_client_action_finish();
1410 return ECORE_CALLBACK_CANCEL;
1414 _e_client_action_move_timeout_add(void)
1416 E_FREE_FUNC(action_timer, ecore_timer_del);
1417 if (e_config->border_keyboard.timeout)
1418 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_client_action_move_timeout, NULL);
1422 _e_client_move_mouse_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
1424 if (!comp_grabbed) return ECORE_CALLBACK_RENEW;
1427 ERR("no action_client!");
1429 if (action_client) _e_client_move_end(action_client);
1430 _e_client_action_finish();
1431 return ECORE_CALLBACK_DONE;
1435 _e_client_moveinfo_gather(E_Client *ec, const char *source)
1437 if (e_util_glob_match(source, "mouse,*,1"))
1438 ec->moveinfo.down.button = 1;
1439 else if (e_util_glob_match(source, "mouse,*,2"))
1440 ec->moveinfo.down.button = 2;
1441 else if (e_util_glob_match(source, "mouse,*,3"))
1442 ec->moveinfo.down.button = 3;
1444 ec->moveinfo.down.button = 0;
1445 if ((ec->moveinfo.down.button >= 1) && (ec->moveinfo.down.button <= 3))
1447 ec->moveinfo.down.mx = ec->mouse.last_down[ec->moveinfo.down.button - 1].mx;
1448 ec->moveinfo.down.my = ec->mouse.last_down[ec->moveinfo.down.button - 1].my;
1452 ec->moveinfo.down.mx = ec->mouse.current.mx;
1453 ec->moveinfo.down.my = ec->mouse.current.my;
1458 _e_client_move_handle(E_Client *ec)
1462 if ((ec->moveinfo.down.button >= 1) && (ec->moveinfo.down.button <= 3))
1464 x = ec->mouse.last_down[ec->moveinfo.down.button - 1].x +
1465 (ec->mouse.current.mx - ec->moveinfo.down.mx);
1466 y = ec->mouse.last_down[ec->moveinfo.down.button - 1].y +
1467 (ec->mouse.current.my - ec->moveinfo.down.my);
1471 x = ec->moveinfo.down.x +
1472 (ec->mouse.current.mx - ec->moveinfo.down.mx);
1473 y = ec->moveinfo.down.y +
1474 (ec->mouse.current.my - ec->moveinfo.down.my);
1477 if (e_config->screen_limits == E_CLIENT_OFFSCREEN_LIMIT_ALLOW_NONE)
1478 _e_client_stay_within_canvas(ec, x, y, &x, &y);
1481 _e_client_stay_within_canvas_margin(ec, x, y, &x, &y);
1483 evas_object_move(ec->frame, x, y);
1485 if (e_client_transform_core_enable_get(ec))
1487 e_client_transform_core_update(ec);
1491 static Evas_Object *
1492 _e_client_resize_object_rectangle_get(E_Client *ec)
1494 Evas_Object *resize_obj = NULL;
1496 resize_obj = evas_object_rectangle_add(evas_object_evas_get(ec->frame));
1497 EINA_SAFETY_ON_NULL_RETURN_VAL(resize_obj, NULL);
1499 if (e_config->resize_object.customize)
1501 evas_object_color_set(resize_obj,
1502 e_config->resize_object.r,
1503 e_config->resize_object.g,
1504 e_config->resize_object.b,
1505 e_config->resize_object.a);
1508 evas_object_color_set(resize_obj, 128, 128, 128, 100);
1513 static Evas_Object *
1514 _e_client_resize_object_image_get(E_Client *ec)
1517 Evas_Object *resize_obj = NULL;
1519 if (!e_config->resize_object.image_path)
1521 ELOGF("COMP", "NO resize_object image! Make default resize_object", ec);
1525 resize_obj = evas_object_image_add(evas_object_evas_get(ec->frame));
1526 EINA_SAFETY_ON_NULL_RETURN_VAL(resize_obj, NULL);
1528 evas_object_image_file_set(resize_obj, e_config->resize_object.image_path, NULL);
1529 err = evas_object_image_load_error_get(resize_obj);
1530 if (err != EVAS_LOAD_ERROR_NONE)
1532 ELOGF("COMP", "Image load error. path:%s, errno:%d. Make default resize_object",
1533 ec, e_config->resize_object.image_path, err);
1534 evas_object_del(resize_obj);
1539 evas_object_image_fill_set(resize_obj, 0, 0, ec->w, ec->h);
1540 evas_object_image_filled_set(resize_obj, EINA_TRUE);
1542 evas_object_image_border_set(resize_obj,
1543 e_config->resize_object.border_width.l,
1544 e_config->resize_object.border_width.r,
1545 e_config->resize_object.border_width.t,
1546 e_config->resize_object.border_width.b);
1551 return _e_client_resize_object_rectangle_get(ec);
1554 static Evas_Object *
1555 _e_client_resize_object_create(E_Client *ec)
1557 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->frame, NULL);
1559 Evas_Object *resize_obj = NULL;
1561 if (_e_client_resize_object_create_cb)
1562 resize_obj = _e_client_resize_object_create_cb(ec);
1565 if (e_config->resize_object.type == 1) // image object
1567 resize_obj = _e_client_resize_object_image_get(ec);
1571 resize_obj = _e_client_resize_object_rectangle_get(ec);
1574 EINA_SAFETY_ON_NULL_RETURN_VAL(resize_obj, NULL);
1576 evas_object_pass_events_set(resize_obj, EINA_TRUE);
1577 evas_object_layer_set(resize_obj, evas_object_layer_get(ec->frame));
1578 evas_object_stack_above(resize_obj, ec->frame);
1579 evas_object_name_set(resize_obj, "resize_object");
1585 _e_client_resize_object_del(E_Client *ec)
1587 if (ec == NULL) return;
1588 if (ec->manage_resize.resize_obj == NULL) return;
1590 evas_object_hide(ec->manage_resize.resize_obj);
1591 evas_object_del(ec->manage_resize.resize_obj);
1592 ec->manage_resize.resize_obj = NULL;
1596 _e_client_resize_handle(E_Client *ec)
1599 int new_x, new_y, new_w, new_h;
1601 int trans_x = 0, trans_y = 0;
1602 int trans_w = 0, trans_h = 0;
1604 if (ec->transformed)
1606 _e_client_transform_resize_handle(ec);
1615 if ((ec->resize_mode == E_POINTER_RESIZE_TR) ||
1616 (ec->resize_mode == E_POINTER_RESIZE_R) ||
1617 (ec->resize_mode == E_POINTER_RESIZE_BR))
1619 if ((ec->moveinfo.down.button >= 1) &&
1620 (ec->moveinfo.down.button <= 3))
1621 w = ec->mouse.last_down[ec->moveinfo.down.button - 1].w +
1622 (ec->mouse.current.mx - ec->moveinfo.down.mx);
1624 w = ec->moveinfo.down.w + (ec->mouse.current.mx - ec->moveinfo.down.mx);
1626 else if ((ec->resize_mode == E_POINTER_RESIZE_TL) ||
1627 (ec->resize_mode == E_POINTER_RESIZE_L) ||
1628 (ec->resize_mode == E_POINTER_RESIZE_BL))
1630 if ((ec->moveinfo.down.button >= 1) &&
1631 (ec->moveinfo.down.button <= 3))
1632 w = ec->mouse.last_down[ec->moveinfo.down.button - 1].w -
1633 (ec->mouse.current.mx - ec->moveinfo.down.mx);
1635 w = ec->moveinfo.down.w - (ec->mouse.current.mx - ec->moveinfo.down.mx);
1638 if ((ec->resize_mode == E_POINTER_RESIZE_TL) ||
1639 (ec->resize_mode == E_POINTER_RESIZE_T) ||
1640 (ec->resize_mode == E_POINTER_RESIZE_TR))
1642 if ((ec->moveinfo.down.button >= 1) &&
1643 (ec->moveinfo.down.button <= 3))
1644 h = ec->mouse.last_down[ec->moveinfo.down.button - 1].h -
1645 (ec->mouse.current.my - ec->moveinfo.down.my);
1647 h = ec->moveinfo.down.h - (ec->mouse.current.my - ec->moveinfo.down.my);
1649 else if ((ec->resize_mode == E_POINTER_RESIZE_BL) ||
1650 (ec->resize_mode == E_POINTER_RESIZE_B) ||
1651 (ec->resize_mode == E_POINTER_RESIZE_BR))
1653 if ((ec->moveinfo.down.button >= 1) &&
1654 (ec->moveinfo.down.button <= 3))
1655 h = ec->mouse.last_down[ec->moveinfo.down.button - 1].h +
1656 (ec->mouse.current.my - ec->moveinfo.down.my);
1658 h = ec->moveinfo.down.h + (ec->mouse.current.my - ec->moveinfo.down.my);
1663 if ((ec->resize_mode == E_POINTER_RESIZE_T) ||
1664 (ec->resize_mode == E_POINTER_RESIZE_TL) ||
1665 (ec->resize_mode == E_POINTER_RESIZE_L) ||
1666 (ec->resize_mode == E_POINTER_RESIZE_BL))
1668 if ((ec->resize_mode == E_POINTER_RESIZE_L) ||
1669 (ec->resize_mode == E_POINTER_RESIZE_TL) ||
1670 (ec->resize_mode == E_POINTER_RESIZE_T) ||
1671 (ec->resize_mode == E_POINTER_RESIZE_TR))
1678 if (e_config->screen_limits == E_CLIENT_OFFSCREEN_LIMIT_ALLOW_NONE)
1681 zone = e_comp_zone_find_by_ec(ec);
1684 w = MIN(w, zone->w);
1685 h = MIN(h, zone->h);
1688 e_client_resize_limit(ec, &new_w, &new_h);
1690 if (ec->manage_resize.enable_aspect_ratio)
1692 if ((ec->resize_mode == E_POINTER_RESIZE_TL) ||
1693 (ec->resize_mode == E_POINTER_RESIZE_L) ||
1694 (ec->resize_mode == E_POINTER_RESIZE_BL) ||
1695 (ec->resize_mode == E_POINTER_RESIZE_TR) ||
1696 (ec->resize_mode == E_POINTER_RESIZE_R) ||
1697 (ec->resize_mode == E_POINTER_RESIZE_BR))
1699 new_h = (int) ec->manage_resize.ah / ec->manage_resize.aw * new_w;
1701 else if ((ec->resize_mode == E_POINTER_RESIZE_T) ||
1702 (ec->resize_mode == E_POINTER_RESIZE_B))
1704 new_w = (int) ec->manage_resize.aw / ec->manage_resize.ah * new_h;
1706 new_h += ec->manage_resize.header_h;
1707 new_h += ec->manage_resize.footer_h;
1710 if ((ec->resize_mode == E_POINTER_RESIZE_T) ||
1711 (ec->resize_mode == E_POINTER_RESIZE_TL) ||
1712 (ec->resize_mode == E_POINTER_RESIZE_L) ||
1713 (ec->resize_mode == E_POINTER_RESIZE_BL))
1714 new_x += (w - new_w);
1715 if ((ec->resize_mode == E_POINTER_RESIZE_L) ||
1716 (ec->resize_mode == E_POINTER_RESIZE_TL) ||
1717 (ec->resize_mode == E_POINTER_RESIZE_T) ||
1718 (ec->resize_mode == E_POINTER_RESIZE_TR))
1719 new_y += (h - new_h);
1721 if (e_config->interactive_resize)
1723 evas_object_geometry_set(ec->frame, new_x, new_y, new_w, new_h);
1727 if (ec->manage_resize.resize_obj == NULL)
1729 ec->manage_resize.resize_obj = _e_client_resize_object_create(ec);
1730 EINA_SAFETY_ON_NULL_RETURN(ec->manage_resize.resize_obj);
1733 if (e_client_transform_core_enable_get(ec))
1735 e_client_transform_core_input_inv_transform(ec, new_x, new_y, &trans_x, &trans_y);
1736 e_client_transform_core_input_inv_transform(ec, new_w, new_h, &trans_w, &trans_h);
1737 evas_object_geometry_set(ec->manage_resize.resize_obj, trans_x, trans_y, trans_w, trans_h);
1740 evas_object_geometry_set(ec->manage_resize.resize_obj, new_x, new_y, new_w, new_h);
1741 evas_object_show(ec->manage_resize.resize_obj);
1743 ec->manage_resize.x = new_x;
1744 ec->manage_resize.y = new_y;
1745 ec->manage_resize.w = new_w;
1746 ec->manage_resize.h = new_h;
1751 _e_client_adjust_size_by_ppu(int size, int start_size, unsigned int ppu)
1753 if (ppu <= 1) return size;
1755 unsigned int remainder = size % ppu;
1756 if (remainder == 0) return size;
1758 int gap = size - start_size;
1759 int new_size = size;
1761 new_size = size + (ppu - remainder);
1763 new_size = size - remainder;
1769 _e_client_adjust_position_by_ppu(int pos, int size, int prev_pos, int prev_size)
1773 if (prev_pos == pos)
1776 new_pos = (prev_pos + prev_size) - size;
1782 _e_client_adjust_geometry_by_resize_ppu(E_Client *ec)
1784 if (ec->manage_resize.unit_size <= 1) return;
1786 ec->manage_resize.w = _e_client_adjust_size_by_ppu(ec->manage_resize.w, ec->w, ec->manage_resize.unit_size);
1787 ec->manage_resize.h = _e_client_adjust_size_by_ppu(ec->manage_resize.h, ec->h, ec->manage_resize.unit_size);
1789 ec->manage_resize.x = _e_client_adjust_position_by_ppu(ec->manage_resize.x, ec->manage_resize.w, ec->x, ec->w);
1790 ec->manage_resize.y = _e_client_adjust_position_by_ppu(ec->manage_resize.y, ec->manage_resize.h, ec->y, ec->h);
1794 _e_client_resize_end(E_Client *ec)
1796 ec->resize_mode = E_POINTER_RESIZE_NONE;
1797 _e_client_action_input_win_del();
1799 _e_client_hook_call(E_CLIENT_HOOK_RESIZE_END, ec);
1801 if (ec->transformed)
1802 _e_client_transform_resize_end(ec);
1805 e_comp_client_override_del(ec);
1809 if (!e_config->interactive_resize)
1811 if (ec->manage_resize.resize_obj)
1813 if (ec->manage_resize.unit_size > 1)
1814 _e_client_adjust_geometry_by_resize_ppu(ec);
1816 e_client_frame_geometry_set(ec,
1817 ec->manage_resize.x,
1818 ec->manage_resize.y,
1819 ec->manage_resize.w,
1820 ec->manage_resize.h);
1821 _e_client_resize_object_del(ec);
1829 _e_client_action_resize_timeout(void *data EINA_UNUSED)
1831 _e_client_resize_end(action_client);
1832 _e_client_action_finish();
1833 return ECORE_CALLBACK_CANCEL;
1837 _e_client_action_resize_timeout_add(void)
1839 E_FREE_FUNC(action_timer, ecore_timer_del);
1840 if (e_config->border_keyboard.timeout)
1841 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_client_action_resize_timeout, NULL);
1845 _e_client_resize_mouse_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
1847 if (!comp_grabbed) return ECORE_CALLBACK_RENEW;
1850 ERR("no action_client!");
1852 if (action_client) _e_client_resize_end(action_client);
1853 _e_client_action_finish();
1854 return ECORE_CALLBACK_DONE;
1857 ////////////////////////////////////////////////
1860 _e_client_position_inside_input_rect(E_Client *ec, int tx, int ty)
1863 Eina_Bool res = EINA_FALSE;
1864 Eina_List *list = NULL, *l;
1865 Eina_Rectangle *data;
1867 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
1869 e_client_geometry_get(ec, &x, &y, &w, &h);
1870 e_comp_object_input_rect_get(ec->frame, &list);
1873 EINA_LIST_FOREACH(list, l, data)
1875 if ((tx >= x + data->x) && (tx <= x + data->x + data->w) &&
1876 (ty >= y + data->y) && (ty <= y + data->y + data->h))
1882 list = eina_list_free(list);
1886 if ((tx >= x) && (tx <= x + w) &&
1887 (ty >= y) && (ty <= y + h))
1897 _e_client_under_pointer_helper_ignore_client(E_Desk *desk, E_Client *client)
1899 /* If a border was specified which should be excluded from the list
1900 * (because it will be closed shortly for example), skip */
1901 if (e_client_util_ignored_get(client) || (!e_desk_has_ec(desk, client))) return EINA_TRUE;
1902 if (!evas_object_visible_get(client->frame)) return EINA_TRUE;
1903 if (e_policy_client_is_cursor(client)) return EINA_TRUE;
1909 _e_client_under_pointer_helper(E_Desk *desk, E_Client *exclude, int x, int y)
1911 E_Client *ec = NULL, *cec;
1913 E_CLIENT_REVERSE_FOREACH(cec)
1915 if (_e_client_under_pointer_helper_ignore_client(desk, cec)) continue;
1916 if ((exclude) && (cec == exclude)) continue;
1917 if (!E_INSIDE(x, y, cec->x, cec->y, cec->w, cec->h))
1919 /* If the layer is higher, the position of the window is higher
1920 * (always on top vs always below) */
1921 if (!ec || (cec->layer > ec->layer))
1928 _e_client_input_rect_under_pointer_helper(E_Desk *desk, E_Client *exclude, int x, int y)
1930 E_Client *ec = NULL, *cec;
1932 E_CLIENT_REVERSE_FOREACH(cec)
1934 /* If a border was specified which should be excluded from the list
1935 * (because it will be closed shortly for example), skip */
1936 if (e_client_util_ignored_get(cec) || (!e_desk_has_ec(desk, cec))) continue;
1937 if (!evas_object_visible_get(cec->frame)) continue;
1938 if (e_policy_client_is_cursor(cec)) continue;
1939 if ((exclude) && (cec == exclude)) continue;
1940 if (!E_INSIDE(x, y, cec->x, cec->y, cec->w, cec->h))
1942 /* If the layer is higher, the position of the window is higher
1943 * (always on top vs always below) */
1944 if (ec && (cec->layer <= ec->layer)) continue;
1945 if (_e_client_position_inside_input_rect(cec, x, y))
1953 _e_client_under_pointer_input_helper(E_Desk *desk, int x, int y)
1955 E_Client *ec = NULL, *cec;
1957 E_CLIENT_REVERSE_FOREACH(cec)
1959 if (_e_client_under_pointer_helper_ignore_client(desk, cec)) continue;
1961 Eina_List *list = NULL;
1962 Eina_Rectangle *rect;
1963 Eina_Bool inside = EINA_FALSE;
1964 e_comp_object_input_rect_get(cec->frame, &list);
1967 EINA_LIST_FREE(list, rect)
1969 if (E_INSIDE(x, y, rect->x, rect->y, rect->w, rect->h))
1973 else if (E_INSIDE(x, y, cec->x, cec->y, cec->w, cec->h))
1978 if (!inside) continue;
1979 /* If the layer is higher, the position of the window is higher
1980 * (always on top vs always below) */
1981 if (!ec || (cec->layer > ec->layer))
1988 ////////////////////////////////////////////////
1991 _e_client_zones_layout_calc(E_Client *ec, int *zx, int *zy, int *zw, int *zh)
1994 E_Zone *zone_above, *zone_below, *zone_left, *zone_right;
1997 zone = e_comp_zone_find_by_ec(ec);
2004 if (eina_list_count(e_comp->zones) == 1)
2013 zone_left = e_comp_zone_xy_get((x - w + 5), y);
2014 zone_right = e_comp_zone_xy_get((x + w + 5), y);
2015 zone_above = e_comp_zone_xy_get(x, (y - h + 5));
2016 zone_below = e_comp_zone_xy_get(x, (y + h + 5));
2018 if (!(zone_above) && (y))
2019 zone_above = e_comp_zone_xy_get(x, (h - 5));
2021 if (!(zone_left) && (x))
2022 zone_left = e_comp_zone_xy_get((x - 5), y);
2025 w = zone_right->x + zone_right->w;
2028 w = zone->x + zone->w;
2031 h = zone_below->y + zone_below->h;
2034 h = zone->y + zone->h;
2036 if ((zone_left) && (zone_right))
2037 w = zone->w + zone_right->x;
2039 if ((zone_above) && (zone_below))
2040 h = zone->h + zone_below->y;
2042 if (x) x -= zone->w;
2043 if (y) y -= zone->h;
2045 if (zx) *zx = x > 0 ? x : 0;
2046 if (zy) *zy = y > 0 ? y : 0;
2052 _e_client_stay_within_canvas(E_Client *ec, int x, int y, int *new_x, int *new_y)
2054 int new_x_max, new_y_max;
2059 zone = e_comp_zone_find_by_ec(ec);
2062 if (new_x) *new_x = x;
2063 if (new_y) *new_y = y;
2067 _e_client_zones_layout_calc(ec, NULL, NULL, &zw, &zh);
2069 new_x_max = zw - ec->w;
2070 new_y_max = zh - ec->h;
2071 lw = ec->w > zw ? EINA_TRUE : EINA_FALSE;
2072 lh = ec->h > zh ? EINA_TRUE : EINA_FALSE;
2106 _e_client_stay_within_canvas_margin(E_Client *ec, int x, int y, int *new_x, int *new_y)
2108 int new_x_max, new_y_max, new_x_min, new_y_min;
2109 int margin_w, margin_h;
2114 zone = e_comp_zone_find_by_ec(ec);
2117 if (new_x) *new_x = x;
2118 if (new_y) *new_y = y;
2125 _e_client_zones_layout_calc(ec, NULL, NULL, &zw, &zh);
2130 new_x_min = (margin_w > cw) ? 0 : -(cw - margin_w);
2131 new_x_max = (margin_w > cw) ? (zw - cw) : (zw - margin_w);
2132 new_y_min = (margin_h > ch) ? 0 : -(ch - margin_h);
2133 new_y_max = (margin_h > ch) ? (zh - ch) : (zh - margin_h);
2137 else if (x <= new_x_min)
2142 else if (y <= new_y_min)
2147 ////////////////////////////////////////////////
2148 #ifdef REFACTOR_ZONE_DESK
2151 _e_client_zone_update(E_Client *ec)
2156 /* still within old zone - leave it there */
2157 zone = e_comp_zone_find_by_ec(ec);
2158 if (zone && E_INTERSECTS(ec->x, ec->y, ec->w, ec->h,
2159 zone->x, zone->y, zone->w, zone->h))
2162 /* find a new zone */
2163 EINA_LIST_FOREACH(e_comp->zones, l, zone)
2165 if (E_INTERSECTS(ec->x, ec->y, ec->w, ec->h,
2166 zone->x, zone->y, zone->w, zone->h))
2168 e_client_zone_set(ec, zone);
2174 ////////////////////////////////////////////////
2177 _e_client_transform_core_activate_set(E_Client *ec, Eina_Bool set)
2179 if (ec->transform_core.activate == set) return;
2181 ec->transform_core.activate = set;
2185 ec->transform_core.changed = EINA_TRUE;
2186 e_client_transform_core_update(ec);
2190 e_client_map_enable_set(ec, EINA_FALSE);
2195 _e_client_cb_evas_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2197 E_Client *ec = data;
2199 if (stopping) return; //ignore all of this if we're shutting down!
2200 if (e_object_is_del(data)) return; //client is about to die
2201 if (ec->cur_mouse_action)
2203 if (ec->cur_mouse_action->func.end_mouse)
2204 ec->cur_mouse_action->func.end_mouse(E_OBJECT(ec), "", NULL);
2205 else if (ec->cur_mouse_action->func.end)
2206 ec->cur_mouse_action->func.end(E_OBJECT(ec), "");
2207 E_FREE_FUNC(ec->cur_mouse_action, e_object_unref);
2209 if (action_client == ec) _e_client_action_finish();
2211 ec->want_focus = ec->take_focus = 0;
2213 _e_client_transform_core_activate_set(ec, EINA_FALSE);
2215 if (ec->new_client) return;
2216 _e_client_event_hide(ec);
2222 _e_client_cb_evas_shade_done(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2224 E_Client *ec = data;
2226 if (e_object_is_del(data)) return;
2229 ec->shaded = !(ec->shaded);
2230 ec->changes.shaded = 1;
2231 ec->changes.shading = 1;
2232 e_client_comp_hidden_set(ec, ec->shaded);
2236 _e_client_cb_evas_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2238 E_Client *ec = data;
2242 if (e_object_is_del(data)) return;
2244 ec->pre_res_change.valid = 0;
2246 _e_client_event_simple(ec, E_EVENT_CLIENT_MOVE);
2248 #ifdef REFACTOR_ZONE_DESK
2250 _e_client_zone_update(ec);
2252 evas_object_geometry_get(ec->frame, &x, &y, NULL, NULL);
2253 if ((e_config->transient.move) && (ec->transients))
2255 Eina_List *list = eina_list_clone(ec->transients);
2258 EINA_LIST_FREE(list, child)
2260 if (child->vkbd.vkbd) continue;
2262 evas_object_move(child->frame,
2263 child->x + x - ec->pre_cb.x,
2264 child->y + y - ec->pre_cb.y);
2267 if (ec->moving || (ecmove == ec))
2268 _e_client_hook_call(E_CLIENT_HOOK_MOVE_UPDATE, ec);
2270 if ((!ec->moving) && (ec->transformed))
2272 map = e_client_map_get(ec);
2273 _e_client_transform_geometry_save(ec, map);
2277 ec->pre_cb.x = x; ec->pre_cb.y = y;
2279 #ifdef REFACTOR_FOCUS_POLICY
2280 // This code is executed at E_CLIENT_HOOK_MOVE callback
2281 // at e_focus_policy_topmost.c and at e_focus_policy_history.c
2283 _e_client_hook_call(E_CLIENT_HOOK_MOVE, ec);
2288 zone = e_comp_zone_find_by_ec(ec);
2289 if (zone && !E_INTERSECTS(ec->x, ec->y, ec->w, ec->h,
2290 zone->x, zone->y, zone->w, zone->h))
2292 e_client_revert_focus(ec);
2297 e_comp_visibility_calculation_set(EINA_TRUE);
2301 _e_client_cb_evas_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2303 E_Client *ec = data;
2304 Evas_Coord x, y, w, h;
2306 if (e_object_is_del(data)) return;
2308 ec->pre_res_change.valid = 0;
2310 _e_client_event_simple(ec, E_EVENT_CLIENT_RESIZE);
2312 #ifdef REFACTOR_ZONE_DESK
2314 _e_client_zone_update(ec);
2316 evas_object_geometry_get(ec->frame, &x, &y, &w, &h);
2317 if ((e_config->transient.resize) && (ec->transients))
2319 Eina_List *list = eina_list_clone(ec->transients);
2322 EINA_LIST_FREE(list, child)
2324 Evas_Coord nx, ny, nw, nh;
2326 if ((ec->pre_cb.w > 0) && (ec->pre_cb.h > 0))
2328 nx = x + (((child->x - x) * w) / ec->pre_cb.w);
2329 ny = y + (((child->y - y) * h) / ec->pre_cb.h);
2330 nw = (child->w * w) / ec->pre_cb.w;
2331 nh = (child->h * h) / ec->pre_cb.h;
2332 nx += ((nw - child->w) / 2);
2333 ny += ((nh - child->h) / 2);
2334 evas_object_move(child->frame, nx, ny);
2339 if (e_client_util_resizing_get(ec) || (ecresize == ec))
2340 _e_client_hook_call(E_CLIENT_HOOK_RESIZE_UPDATE, ec);
2341 ec->pre_cb.w = w; ec->pre_cb.h = h;
2343 e_client_transform_core_update(ec);
2344 e_comp_visibility_calculation_set(EINA_TRUE);
2348 _e_client_cb_evas_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2350 E_Client *ec = data;
2352 if (e_object_is_del(data)) return;
2354 _e_client_transform_core_activate_set(ec, EINA_TRUE);
2356 _e_client_event_show(ec);
2361 _e_client_cb_evas_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
2363 E_Client *ec = data;
2364 E_Comp_Wl_Client_Data *child_cdata = NULL;
2366 if (e_object_is_del(data)) return;
2367 if (ec->layer_block) return;
2368 if (ec->layer_pending) return;
2369 if (e_config->transient.raise && ec->transients)
2371 Eina_List *list = eina_list_clone(ec->transients);
2372 E_Client *child, *below = NULL, *above = NULL;
2373 E_Transient transient_policy;
2375 E_LIST_REVERSE_FREE(list, child)
2377 child_cdata = e_client_cdata_get(child);
2378 if (child_cdata && !child_cdata->mapped)
2380 ELOGF("COMP", "STACK CHANGE CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", ec, child, e_client_util_win_get(child));
2384 /* Don't stack iconic transients. If the user wants these shown,
2385 * that's another option.
2387 if (child->iconic && e_client_is_iconified_by_client(child)) continue;
2389 transient_policy = e_client_transient_policy_get(child);
2390 if (transient_policy == E_TRANSIENT_ABOVE)
2393 e_client_stack_below(child, below);
2395 e_client_stack_above(child, ec);
2398 else if (transient_policy == E_TRANSIENT_BELOW)
2401 e_client_stack_below(child, above);
2403 e_client_stack_below(child, ec);
2409 if (ec->unredirected_single) return;
2410 _e_client_event_simple(ec, E_EVENT_CLIENT_STACK);
2412 e_comp_visibility_calculation_set(EINA_TRUE);
2415 ////////////////////////////////////////////////
2417 #ifdef REFACTOR_ZONE_DESK
2420 _e_client_maximize(E_Client *ec, E_Maximize max)
2422 int x1, yy1, x2, y2;
2425 int ecx, ecy, ecw, ech;
2426 int desk_x, desk_y, desk_w, desk_h;
2427 Eina_Bool override = ec->maximize_override;
2430 zx = zy = zw = zh = 0;
2431 ec->maximize_override = 1;
2433 zone = e_comp_zone_find_by_ec(ec);
2436 if (ec->desk_area.enable && ec->desk_area.desk_area)
2438 desk_x = ec->desk_area.desk_area->x;
2439 desk_y = ec->desk_area.desk_area->y;
2440 desk_w = ec->desk_area.desk_area->w;
2441 desk_h = ec->desk_area.desk_area->h;
2445 desk_x = ec->desk->geom.x;
2446 desk_y = ec->desk->geom.y;
2447 desk_w = ec->desk->geom.w;
2448 desk_h = ec->desk->geom.h;
2451 switch (max & E_MAXIMIZE_TYPE)
2453 case E_MAXIMIZE_NONE:
2457 case E_MAXIMIZE_FULLSCREEN:
2461 e_client_resize_limit(ec, &w, &h);
2462 /* center x-direction */
2463 x1 = desk_x + (desk_w - w) / 2;
2464 /* center y-direction */
2465 yy1 = desk_y + (desk_h - h) / 2;
2467 switch (max & E_MAXIMIZE_DIRECTION)
2469 case E_MAXIMIZE_BOTH:
2470 e_client_maximized_geometry_set(ec, x1, yy1, w, h);
2473 case E_MAXIMIZE_VERTICAL:
2474 e_client_maximized_geometry_set(ec, ec->x, yy1, ec->w, h);
2477 case E_MAXIMIZE_HORIZONTAL:
2478 e_client_maximized_geometry_set(ec, x1, ec->y, w, ec->h);
2481 case E_MAXIMIZE_LEFT:
2482 e_client_maximized_geometry_set(ec, desk_x, desk_y, w / 2, h);
2485 case E_MAXIMIZE_RIGHT:
2486 e_client_maximized_geometry_set(ec, x1, desk_y, w / 2, h);
2491 case E_MAXIMIZE_SMART:
2492 case E_MAXIMIZE_EXPAND:
2493 if (ec->desk->visible)
2495 // base_output_resolution
2496 if (ec->base_output_resolution.use)
2500 zw = ec->base_output_resolution.w;
2501 zh = ec->base_output_resolution.h;
2505 e_zone_desk_useful_geometry_get(zone, ec->desk, &zx, &zy, &zw, &zh);
2512 x2 = desk_x + desk_w;
2513 y2 = desk_y + desk_h;
2514 e_maximize_client_shelf_fill(ec, &x1, &yy1, &x2, &y2, max);
2521 evas_object_smart_callback_call(ec->frame, "maximize", NULL);
2522 e_comp_object_frame_xy_unadjust(ec->frame, ec->x, ec->y, &ecx, &ecy);
2523 e_comp_object_frame_wh_unadjust(ec->frame, ec->w, ec->h, &ecw, &ech);
2531 if (ecx < zx) // window left not useful coordinates
2533 else if (ecx + ecw > zx + zw) // window right not useful coordinates
2535 else // window normal position
2538 if (ecy < zy) // window top not useful coordinates
2540 else if (ecy + ech > zy + zh) // window bottom not useful coordinates
2541 yy1 = zy + zh - ech;
2542 else // window normal position
2545 switch (max & E_MAXIMIZE_DIRECTION)
2547 case E_MAXIMIZE_BOTH:
2548 e_client_maximized_geometry_set(ec, zx, zy, zw, zh);
2551 case E_MAXIMIZE_VERTICAL:
2552 e_client_maximized_geometry_set(ec, ec->x, zy, ec->w, zh);
2555 case E_MAXIMIZE_HORIZONTAL:
2556 e_client_maximized_geometry_set(ec, zx, ec->y, zw, ec->h);
2559 case E_MAXIMIZE_LEFT:
2560 e_client_maximized_geometry_set(ec, zx, zy, zw / 2, zh);
2563 case E_MAXIMIZE_RIGHT:
2564 e_client_maximized_geometry_set(ec, zx + zw / 2, zy, zw / 2, zh);
2570 case E_MAXIMIZE_FILL:
2573 x2 = desk_x + desk_w;
2574 y2 = desk_y + desk_h;
2576 /* walk through all shelves */
2577 e_maximize_client_shelf_fill(ec, &x1, &yy1, &x2, &y2, max);
2579 /* walk through all windows */
2580 e_maximize_client_client_fill(ec, &x1, &yy1, &x2, &y2, max);
2586 e_client_resize_limit(ec, &w, &h);
2587 /* center x-direction */
2588 x1 = x1 + (pw - w) / 2;
2589 /* center y-direction */
2590 yy1 = yy1 + (ph - h) / 2;
2592 switch (max & E_MAXIMIZE_DIRECTION)
2594 case E_MAXIMIZE_BOTH:
2595 e_client_maximized_geometry_set(ec, x1, yy1, w, h);
2598 case E_MAXIMIZE_VERTICAL:
2599 e_client_maximized_geometry_set(ec, ec->x, yy1, ec->w, h);
2602 case E_MAXIMIZE_HORIZONTAL:
2603 e_client_maximized_geometry_set(ec, x1, ec->y, w, ec->h);
2606 case E_MAXIMIZE_LEFT:
2607 e_client_maximized_geometry_set(ec, desk_x, desk_y, w / 2, h);
2610 case E_MAXIMIZE_RIGHT:
2611 e_client_maximized_geometry_set(ec, x1, desk_y, w / 2, h);
2616 if (ec->maximize_override)
2617 ec->maximize_override = override;
2621 ////////////////////////////////////////////////
2623 _e_client_aux_hint_eval(E_Client *ec)
2627 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
2629 E_Comp_Wl_Aux_Hint *hint;
2631 if (cdata && cdata->aux_hint.changed)
2633 _e_client_hook_call(E_CLIENT_HOOK_AUX_HINT_CHANGE, ec);
2635 EINA_LIST_FOREACH_SAFE(cdata->aux_hint.hints, l, ll, hint)
2637 hint->changed = EINA_FALSE;
2640 ELOGF("COMP", "AUX_HINT |Del [%d:%s:%s]", ec, hint->id, hint->hint, hint->val);
2641 if (hint->hint) eina_stringshare_del(hint->hint);
2642 if (hint->val) eina_stringshare_del(hint->val);
2643 cdata->aux_hint.hints = eina_list_remove_list(cdata->aux_hint.hints, l);
2647 cdata->aux_hint.changed = 0;
2651 #ifdef REFACTOR_ZONE_DESK
2654 _e_client_apply_auto_placement(E_Client *ec)
2656 Eina_List *skiplist = NULL;
2657 int new_x, new_y, t = 0;
2659 E_Client *parent_ec;
2662 // intercept auto placement policy
2663 if (!_e_client_intercept_hook_call(E_CLIENT_INTERCEPT_HOOK_AUTO_PLACEMENT, ec))
2665 ELOGF("POL", "Intercepted auto_placement policy.", ec);
2669 int zx = 0, zy = 0, zw = 0, zh = 0;
2671 zone = e_comp_zone_find_by_ec(ec);
2674 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
2676 unsigned int seed = (unsigned int)time(NULL);
2679 new_x = zx + (rand_r(&seed) % (zw - ec->w));
2683 new_y = zy + (rand_r(&seed) % (zh - ec->h));
2687 e_comp_object_frame_geometry_get(ec->frame, NULL, NULL, &t, NULL);
2689 parent_ec = ec->parent;
2693 new_x = parent_ec->x;
2694 new_y = parent_ec->y;
2696 else if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
2699 skiplist = eina_list_append(skiplist, ec);
2701 e_place_desk_region_smart(ec->desk, skiplist,
2702 ec->x, ec->y, ec->w, ec->h,
2705 e_place_zone_region_smart(zone, skiplist,
2706 ec->x, ec->y, ec->w, ec->h,
2709 eina_list_free(skiplist);
2711 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
2714 e_place_zone_manual(zone, ec->w, t, &new_x, &new_y);
2719 e_place_zone_cursor(zone, ec->x, ec->y, ec->w, ec->h,
2723 ELOGF("POL", "Apply auto placement (type:%d). (%d,%d) -> (%d,%d).", ec, type, ec->x, ec->y, new_x, new_y);
2724 e_client_pos_set(ec, new_x, new_y);
2725 ec->changes.pos = 1;
2727 ec->pre_cb.x = ec->x; ec->pre_cb.y = ec->y;
2732 _e_client_eval(E_Client *ec)
2735 unsigned int prop = 0;
2736 #ifdef REFACTOR_ZONE_DESK
2744 if (e_object_is_del(E_OBJECT(ec)))
2746 CRI("_e_client_eval(%p) with deleted border! - %d\n", ec, ec->new_client);
2751 TRACE_DS_BEGIN(CLIENT:EVAL);
2753 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_NEW_CLIENT, ec))
2759 #ifdef REFACTOR_ZONE_DESK
2760 if ((ec->new_client) && (!e_client_util_ignored_get(ec)))
2762 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_POST_NEW_CLIENT, ec))
2769 zone = e_comp_zone_find_by_ec(ec);
2770 if ((ec->new_client) && (!e_client_util_ignored_get(ec)) && (zone))
2772 int zx = 0, zy = 0, zw = 0, zh = 0;
2774 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
2775 /* enforce wm size hints for initial sizing */
2776 if (e_config->screen_limits == E_CLIENT_OFFSCREEN_LIMIT_ALLOW_NONE)
2778 tw = MIN(ec->w, zone->w);
2779 th = MIN(ec->h, zone->h);
2780 e_client_size_set(ec, tw, th);
2785 e_client_resize_limit(ec, &nw, &nh);
2786 e_client_size_set(ec, nw, nh);
2790 int x = ec->x, y = ec->y;
2791 if (ec->x) e_comp_object_frame_xy_adjust(ec->frame, ec->x, 0, &ec->x, NULL);
2792 if (ec->y) e_comp_object_frame_xy_adjust(ec->frame, 0, ec->y, NULL, &ec->y);
2793 if ((x != ec->x) || (y != ec->y)) ec->changes.pos = 1;
2795 ec->pre_cb.x = ec->x; ec->pre_cb.y = ec->y;
2801 tx = zx + ((zw - ec->w) / 2);
2802 ty = zy + ((zh - ec->h) / 2);
2803 e_client_pos_set(ec, tx, ty);
2805 ec->changes.pos = 1;
2807 ec->pre_cb.x = ec->x; ec->pre_cb.y = ec->y;
2812 eai = e_appinfo_find_with_pid(ec->netwm.pid);
2816 _e_client_apply_auto_placement(ec);
2820 if (e_appinfo_auto_placement_get(eai))
2821 _e_client_apply_auto_placement(ec);
2824 /* Recreate state */
2825 if (ec->e.state.centered)
2827 tx = zx + (zw - ec->w) / 2;
2828 ty = zy + (zh - ec->h) / 2;
2829 e_client_pos_set(ec, tx, ty);
2830 ec->changes.pos = 1;
2833 /* if the explicit geometry request asks for the app to be
2834 * in another zone - well move it there */
2836 E_Zone *zone1 = NULL;
2841 if ((!ec->re_manage) && ((ec->x != x) || (ec->y != y)))
2842 zone1 = e_comp_zone_xy_get(x, y);
2846 zone1 = e_comp_zone_xy_get(ec->x + (ec->w / 2), ec->y + (ec->h / 2));
2849 E_Zone *z2 = e_comp_zone_xy_get(ec->x, ec->y);
2851 if (z2 && (z2 != zone1))
2857 EINA_LIST_FOREACH(e_comp->zones, l, z2)
2861 x = ec->x, y = ec->y, w = ec->w, h = ec->h;
2862 E_RECTS_CLIP_TO_RECT(x, y, w, h, z2->x, z2->y, z2->w, z2->h);
2863 if (w * h == z2->w * z2->h)
2865 /* client fully covering zone */
2869 if ((unsigned)(w * h) > psz)
2880 zone1 = e_comp_zone_xy_get(ec->x, ec->y);
2882 zone1 = e_comp_zone_xy_get(ec->x + ec->w - 1, ec->y);
2884 zone1 = e_comp_zone_xy_get(ec->x + ec->w - 1, ec->y + ec->h - 1);
2886 zone1 = e_comp_zone_xy_get(ec->x, ec->y + ec->h - 1);
2887 if ((zone1) && (zone1 != zone))
2888 e_client_zone_set(ec, zone1);
2892 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_POST_NEW_CLIENT, ec))
2899 /* effect changes to the window border itself */
2900 if ((ec->changes.shading))
2902 /* show at start of unshade (but don't hide until end of shade) */
2903 ec->changes.shading = 0;
2906 if (ec->changes.shaded) send_event = 0;
2907 if ((ec->changes.shaded) && (ec->changes.pos) && (ec->changes.size))
2909 ec->changes.shaded = 0;
2911 else if ((ec->changes.shaded) && (ec->changes.pos))
2913 ec->changes.size = 1;
2914 ec->changes.shaded = 0;
2916 else if ((ec->changes.shaded) && (ec->changes.size))
2918 ec->changes.shaded = 0;
2920 else if (ec->changes.shaded)
2922 ec->changes.shaded = 0;
2925 if (ec->changes.size)
2927 ec->changes.size = 0;
2928 if ((!ec->shaded) && (!ec->shading))
2929 evas_object_resize(ec->frame, ec->w, ec->h);
2931 prop |= E_CLIENT_PROPERTY_SIZE;
2933 if (ec->changes.pos)
2935 ec->changes.tz_position = 0;
2936 ec->changes.pos = 0;
2937 evas_object_move(ec->frame, ec->x, ec->y);
2938 prop |= E_CLIENT_PROPERTY_POS;
2941 if (ec->changes.reset_gravity)
2943 ec->changes.reset_gravity = 0;
2944 prop |= E_CLIENT_PROPERTY_GRAVITY;
2947 if (ec->changes.title)
2949 ec->changes.title = 0;
2950 prop |= E_CLIENT_PROPERTY_TITLE;
2953 if ((ec->changes.visible) && (ec->visible) && (ec->new_client) && (!ec->iconic))
2957 e_input_device_pointer_xy_get(NULL, &x, &y);
2958 if ((!ec->placed) && (!ec->re_manage) &&
2959 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
2960 (!((ec->icccm.transient_for != 0) ||
2962 (!ecmove) && (!ecresize))
2964 /* Set this window into moving state */
2966 ec->cur_mouse_action = e_action_find("window_move");
2967 if (ec->cur_mouse_action)
2969 if ((!ec->cur_mouse_action->func.end_mouse) &&
2970 (!ec->cur_mouse_action->func.end))
2971 ec->cur_mouse_action = NULL;
2972 if (ec->cur_mouse_action)
2975 tx = x - (ec->w >> 1);
2976 e_comp_object_frame_geometry_get(ec->frame, NULL, NULL, &t, NULL);
2978 e_client_pos_set(ec, tx, ty);
2980 ec->changes.pos = 1;
2985 evas_object_show(ec->frame);
2986 if (evas_object_visible_get(ec->frame))
2988 #ifdef REFACTOR_FOCUS_POLICY
2989 // It is useless, Nothing to do.
2991 if (ec->cur_mouse_action)
2993 ec->moveinfo.down.x = ec->x;
2994 ec->moveinfo.down.y = ec->y;
2995 ec->moveinfo.down.w = ec->w;
2996 ec->moveinfo.down.h = ec->h;
2997 ec->mouse.current.mx = x;
2998 ec->mouse.current.my = y;
2999 ec->moveinfo.down.button = 0;
3000 ec->moveinfo.down.mx = x;
3001 ec->moveinfo.down.my = y;
3003 e_object_ref(E_OBJECT(ec->cur_mouse_action));
3004 ec->cur_mouse_action->func.go(E_OBJECT(ec), NULL);
3005 if (e_config->border_raise_on_mouse_action)
3007 if (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK)
3009 ELOGF("FOCUS", "focus set | client eval", ec);
3010 e_client_frame_focus_set(ec, EINA_TRUE);
3014 ec->changes.visible = 0;
3015 _e_client_event_show(ec);
3018 else if ((ec->changes.visible) && (ec->new_client))
3020 ec->changes.visible = 0;
3022 _e_client_event_hide(ec);
3025 if (ec->changes.icon)
3027 ec->changes.icon = 0;
3031 e_comp->new_clients--;
3033 ec->changed = ec->changes.pos || ec->changes.size ||
3034 ec->changes.stack || ec->changes.prop || ec->changes.border ||
3035 ec->changes.reset_gravity || ec->changes.shading || ec->changes.shaded ||
3036 ec->changes.shape || ec->changes.shape_input || ec->changes.icon ||
3037 ec->changes.internal_state ||
3038 ec->changes.need_maximize || ec->changes.need_unmaximize;
3039 ec->changes.stack = 0;
3041 #ifdef REFACTOR_FOCUS_POLICY
3042 // This code executes at E_CLIENT_HOOK_EVAL_END callback at e_focus_policy_topmost.c and e_focus_policy_history.c
3044 zone = e_comp_zone_find_by_ec(ec);
3045 if ((!ec->input_only) && (!ec->iconic) &&
3046 ((!zone) || e_desk_has_ec(e_desk_current_get(zone), ec)) &&
3047 ((ec->take_focus) || (ec->want_focus)))
3053 #if 0 // focus should be set to the top window
3054 e_client_focus_set_with_pointer(ec);
3059 /* focus window by default when it is the only one on desk */
3060 E_Client *ec2 = NULL;
3063 desk = e_zone_desk_find_by_ec(zone, ec);
3064 EINA_LIST_FOREACH(focus_stack, l, ec2)
3066 if (ec == ec2) continue;
3067 if ((!ec2->iconic) && (ec2->visible) &&
3068 ((e_desk_has_ec(desk, ec2)) || ec2->sticky))
3074 e_client_focus_set_with_pointer(ec);
3079 ec->take_focus = ec->want_focus = 0;
3082 if (ec->changes.need_maximize)
3084 E_Maximize max = ec->maximized;
3085 ec->maximized = E_MAXIMIZE_NONE;
3086 e_client_maximize(ec, max);
3087 ec->changes.need_maximize = 0;
3089 else if (ec->changes.need_unmaximize)
3091 e_client_unmaximize(ec, ec->maximized);
3092 ec->changes.need_unmaximize = 0;
3095 if (ec->need_fullscreen)
3097 e_client_fullscreen(ec, e_config->fullscreen_policy);
3098 ec->need_fullscreen = 0;
3101 if (ec->changes.accepts_focus)
3103 if ((!ec->icccm.accepts_focus) && (!ec->icccm.take_focus))
3106 ec->changes.accepts_focus = 0;
3110 if (send_event && prop)
3112 _e_client_event_property(ec, prop);
3115 _e_client_aux_hint_eval(ec);
3117 e_client_transform_core_update(ec);
3118 _e_client_hook_call(E_CLIENT_HOOK_EVAL_END, ec);
3123 #ifdef REFACTOR_ZONE_DESK
3125 e_client_frame_update(E_Client *ec)
3128 _e_client_frame_update(E_Client *ec)
3131 const char *bordername;
3133 #ifdef REFACTOR_ZONE_DESK
3134 EINA_SAFETY_ON_NULL_RETURN(ec);
3135 if (e_object_is_del(E_OBJECT(ec))) return;
3138 ec->border.changed = 0;
3139 if (!e_comp_object_frame_allowed(ec->frame)) return;
3140 if (ec->fullscreen || ec->borderless)
3141 bordername = "borderless";
3142 else if (ec->bordername)
3143 bordername = ec->bordername;
3144 else if (ec->mwm.borderless)
3145 bordername = "borderless";
3146 else if (((ec->icccm.transient_for != 0) || (ec->dialog)) &&
3147 (ec->icccm.min_w == ec->icccm.max_w) &&
3148 (ec->icccm.min_h == ec->icccm.max_h))
3149 bordername = "noresize_dialog";
3150 else if ((ec->icccm.min_w == ec->icccm.max_w) &&
3151 (ec->icccm.min_h == ec->icccm.max_h))
3152 bordername = "noresize";
3153 else if (ec->shaped)
3154 bordername = "shaped";
3155 else if (ec->urgent)
3156 bordername = "urgent";
3157 else if (ec->netwm.state.modal)
3158 bordername = "modal";
3159 else if ((ec->netwm.state.skip_taskbar) ||
3160 (ec->netwm.state.skip_pager))
3161 bordername = "skipped";
3163 else if ((ec->internal) && (ec->icccm.class) &&
3164 (!strncmp(ec->icccm.class, "e_fwin", 6)))
3165 bordername = "internal_fileman";
3168 bordername = e_config->theme_default_border_style;
3169 if (!bordername) bordername = "default";
3171 e_client_border_set(ec, bordername);
3175 _e_client_type_match(E_Client *ec, E_Config_Client_Type *m)
3177 if (!ec || !m) return EINA_FALSE;
3178 if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
3180 if ((int)ec->netwm.type != m->window_type)
3183 #if defined(__cplusplus) || defined(c_plusplus)
3186 if (!ec->icccm.cpp_class)
3189 if (!e_util_glob_match(ec->icccm.cpp_class, m->clas))
3195 if (!ec->icccm.class)
3198 if (!e_util_glob_match(ec->icccm.class, m->clas))
3205 if (ec->icccm.name && e_util_glob_match(ec->icccm.name, m->name))
3208 if (ec->icccm.title && e_util_glob_match(ec->icccm.title, m->name))
3211 if (ec->netwm.name && e_util_glob_match(ec->netwm.name, m->name))
3219 _e_client_type_get(E_Client *ec)
3221 E_Config_Client_Type *m;
3225 if (!e_config->client_types) return 0;
3227 EINA_LIST_FOREACH(e_config->client_types, l, m)
3229 if (!_e_client_type_match(ec, m)) continue;
3232 type = m->client_type;
3237 ec->client_type = type;
3239 return ec->client_type;
3243 _e_client_transform_sub_apply(E_Client *ec, E_Client *epc, double zoom)
3245 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
3249 int ox = 0, oy = 0, ow, oh;
3253 EINA_SAFETY_ON_FALSE_RETURN(e_comp_wl_subsurface_check(ec));
3255 e_comp_wl_subsurface_position_get(ec, &ox, &oy);
3256 ow = cdata->width_from_viewport;
3257 oh = cdata->height_from_viewport;
3259 map = e_client_map_get(epc);
3260 e_map_point_coord_get(map, 0, &px, &py, 0);
3263 mx = ox * zoom + px;
3264 my = oy * zoom + py;
3268 map = e_map_new_with_direct_render(ec->transform_core.direct_render);
3269 e_map_util_points_populate_from_geometry(map, mx, my, mw, mh, 0);
3270 e_map_util_object_move_sync_set(map, EINA_TRUE);
3271 e_client_map_set(ec, map);
3272 e_client_map_enable_set(ec, EINA_TRUE);
3274 EINA_LIST_FOREACH(cdata->sub.list, l, subc)
3275 _e_client_transform_sub_apply(subc, ec, zoom);
3276 EINA_LIST_REVERSE_FOREACH(cdata->sub.below_list, l, subc)
3277 _e_client_transform_sub_apply(subc, ec, zoom);
3283 _e_client_transient_for_group_make(E_Client *ec, Eina_List **list)
3289 if (!e_config->transient.raise) return;
3291 EINA_LIST_FOREACH(ec->transients, l, child)
3293 if (!child) continue;
3294 if (child->iconic) continue;
3295 if (e_client_transient_policy_get(child) == E_TRANSIENT_ABOVE)
3297 *list = eina_list_prepend(*list, child);
3298 _e_client_transient_for_group_make(child, list);
3304 e_client_transient_child_top_get(E_Client *ec, Eina_Bool consider_focus)
3306 E_Client *top_ec = NULL;
3307 Eina_List *transient_list = NULL;
3309 _e_client_transient_for_group_make(ec, &transient_list);
3313 Eina_List *l = NULL;
3314 E_Client *temp_ec = NULL;
3315 E_Client *temp_ec2 = NULL;
3317 E_CLIENT_REVERSE_FOREACH(temp_ec)
3326 EINA_LIST_FOREACH(transient_list, l, temp_ec2)
3328 if (temp_ec == temp_ec2)
3332 if ((temp_ec2->icccm.accepts_focus) ||
3333 (temp_ec2->icccm.take_focus))
3346 eina_list_free(transient_list);
3351 #ifdef EC_IS_NOT_VISIBLE
3352 # undef EC_IS_NOT_VISIBLE
3354 #define EC_IS_NOT_VISIBLE if (ec->visibility.obscured != E_VISIBILITY_UNOBSCURED)
3357 e_client_visibility_touched_check(E_Client *ec)
3361 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
3363 tx = wl_fixed_to_int(e_comp->wl_comp_data->ptr.x);
3364 ty = wl_fixed_to_int(e_comp->wl_comp_data->ptr.y);
3366 return _e_client_position_inside_input_rect(ec, tx, ty);
3370 e_client_visibility_change_notify(E_Client *ec)
3372 EINA_SAFETY_ON_NULL_RETURN(ec);
3374 if (ec->visibility.changed)
3375 _e_client_event_simple(ec, E_EVENT_CLIENT_VISIBILITY_CHANGE);
3377 _e_client_hook_call(E_CLIENT_HOOK_EVAL_VISIBILITY, ec);
3381 e_client_visibility_end_notify(void)
3383 // FIXME: This hook means that the visiblitiy calculation of a zone is done
3384 // at this idle handler.This is a hook for a zone, not for a client.
3385 // Therefore, this hook may be defined as a zone hook,
3386 // ex) E_ZONE_HOOK_EVAL_VISIBILITY_END or E_ZONE_HOOK_EVAL_VISIBILITY_DONE.
3387 _e_client_hook_call(E_CLIENT_HOOK_EVAL_VISIBILITY_END, NULL);
3390 #ifdef REFACTOR_FOCUS_POLICY
3393 _e_client_merge_focus_stack_with_defer_focus(void)
3395 Eina_List *l = NULL;
3396 E_Client *ec = NULL, *defer_ec = NULL;
3397 Eina_Bool find_rel = EINA_FALSE;
3398 Eina_Bool inserted = EINA_FALSE;
3400 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK) return;
3404 focus_stack = eina_list_merge(focus_stack, defer_focus_stack);
3408 E_CLIENT_FOREACH(defer_ec)
3410 if (!eina_list_data_find(defer_focus_stack, defer_ec)) continue;
3412 find_rel = EINA_FALSE;
3413 inserted = EINA_FALSE;
3414 focus_stack = eina_list_remove(focus_stack, defer_ec);
3416 EINA_LIST_FOREACH(focus_stack, l, ec)
3418 if (ec == NULL) continue;
3423 find_rel = EINA_TRUE;
3427 if (ec->layer > defer_ec->layer) continue;
3429 focus_stack = eina_list_prepend_relative_list(focus_stack, defer_ec, l);
3430 inserted = EINA_TRUE;
3435 focus_stack = eina_list_append(focus_stack, defer_ec);
3439 defer_focus_stack = eina_list_free(defer_focus_stack);
3444 _e_client_candidate_focus(E_Zone *zone, E_Client *reverted_focus_ec)
3447 E_Client *defered_focus_ec = NULL;
3448 Eina_List *child_list = NULL;
3449 Eina_List *l = NULL;
3450 Eina_Bool child_deferred;
3453 E_CLIENT_REVERSE_FOREACH(ec)
3455 if (!eina_list_data_find(defer_focus_stack, ec)) continue;
3457 if (e_object_is_del(E_OBJECT(ec))) continue;
3458 if (e_client_util_ignored_get(ec)) continue;
3459 if (!e_zone_has_ec(zone, ec)) continue;
3460 desk = e_desk_current_get(zone);
3461 if (!desk) continue;
3462 if (!e_desk_has_ec(desk, ec)) continue;
3464 if (!(ec->icccm.accepts_focus || ec->icccm.take_focus)) continue;
3465 if (ec->lock_focus_in || ec->lock_focus_out) continue;
3466 if (!evas_object_visible_get(ec->frame)) continue;
3467 if (ec->iconic) continue;
3468 if (ec->bg_state) continue;
3470 if (!(cec = e_client_check_obscured_by_children_group(ec)) ||
3471 e_client_check_really_iconified(cec))
3473 if (ec->visibility.obscured != E_VISIBILITY_UNOBSCURED) continue;
3474 if (e_client_check_fully_contain_by_above(ec, EINA_FALSE)) continue;
3477 if (focused && (focused->layer > ec->layer)) continue;
3478 else if (!focused && reverted_focus_ec && (reverted_focus_ec->layer > ec->layer)) continue;
3480 // check transient_for child defered
3481 child_deferred = EINA_FALSE;
3482 child_list = eina_list_clone(ec->transients);
3483 EINA_LIST_FOREACH(child_list, l, cec)
3485 if (e_client_transient_policy_get(cec) == E_TRANSIENT_BELOW) continue;
3486 if (!(cec->icccm.accepts_focus || cec->icccm.take_focus)) continue;
3487 if (eina_list_data_find(defer_focus_stack, cec))
3489 child_deferred = EINA_TRUE;
3493 eina_list_free(child_list);
3494 if (child_deferred) continue;
3496 defered_focus_ec = ec;
3499 return defered_focus_ec;
3503 e_client_focus_calculate(E_Zone *zone)
3505 E_Client *defered_focus_ec = NULL, *reverted_focus_ec = NULL;
3506 E_Client *ec = NULL, *old_focused = NULL;
3508 EINA_SAFETY_ON_NULL_RETURN(zone);
3509 if (!e_zone_is_displaying(zone)) return;
3511 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK)
3513 ec = _e_client_focus_topmost_focusable_get();
3517 if (!ec) ELOGF("FOCUS", "focus unset | No focusable ec", focused);
3518 e_client_frame_focus_set(focused, EINA_FALSE);
3522 ELOGF("FOCUS", "focus set | topmost focus calculate", ec);
3523 e_client_frame_focus_set(ec, EINA_TRUE);
3530 (focused != eina_list_data_get(focus_stack)) ||
3531 (!_e_client_focus_can_take(focused)))
3533 reverted_focus_ec = _e_client_revert_focus_get(focused);
3534 if (!reverted_focus_ec && focused)
3536 e_client_focus_defer_unset(focused);
3537 old_focused = focused;
3541 defered_focus_ec = _e_client_candidate_focus(zone, reverted_focus_ec);
3543 if (defered_focus_ec)
3545 if (defered_focus_ec != focused)
3547 ELOGF("FOCUS", "focus set | focus calculate (defer_focus)", defered_focus_ec);
3549 e_client_focus_defer_unset(focused);
3550 e_client_frame_focus_set(defered_focus_ec, EINA_TRUE);
3553 e_client_focus_defer_unset(defered_focus_ec);
3555 _e_client_merge_focus_stack_with_defer_focus();
3557 else if(reverted_focus_ec)
3559 if (reverted_focus_ec != focused)
3561 ELOGF("FOCUS", "focus set | focus calculate (revert_focus)", reverted_focus_ec);
3563 e_client_focus_defer_unset(focused);
3564 e_client_frame_focus_set(reverted_focus_ec, EINA_TRUE);
3567 else if (old_focused)
3569 ELOGF("FOCUS", "focus unset | focus calculate", old_focused);
3570 e_client_frame_focus_set(old_focused, EINA_FALSE);
3578 _e_client_transform_core_check_change(E_Client *ec)
3582 Eina_Bool check = EINA_FALSE;
3583 if (!ec) return EINA_FALSE;
3586 evas_object_geometry_get(ec->frame, 0, 0, &w, &h);
3588 // check client position or size change
3589 if (ec->x != ec->transform_core.backup.client_x ||
3590 ec->y != ec->transform_core.backup.client_y ||
3591 ec->w != ec->transform_core.backup.client_w ||
3592 ec->h != ec->transform_core.backup.client_h ||
3593 w != ec->transform_core.backup.frame_w ||
3594 h != ec->transform_core.backup.frame_h ||
3595 ec->argb != ec->transform_core.backup.argb)
3598 ec->transform_core.backup.client_x = ec->x;
3599 ec->transform_core.backup.client_y = ec->y;
3600 ec->transform_core.backup.client_w = ec->w;
3601 ec->transform_core.backup.client_h = ec->h;
3602 ec->transform_core.backup.frame_w = w;
3603 ec->transform_core.backup.frame_h = h;
3604 ec->transform_core.backup.argb = ec->argb;
3607 // check new transform or del transform
3608 if (ec->transform_core.changed)
3611 ec->transform_core.changed = EINA_FALSE;
3614 // check each transform change
3615 if (ec->transform_core.transform_list)
3619 E_Util_Transform *transform;
3621 EINA_LIST_FOREACH_SAFE(ec->transform_core.transform_list, l, l_next, transform)
3623 // del transform check
3624 if (e_util_transform_ref_count_get(transform) <= 1)
3626 ec->transform_core.transform_list = eina_list_remove(ec->transform_core.transform_list, transform);
3627 e_util_transform_unref(transform);
3632 // transform change test
3633 if (e_util_transform_change_get(transform))
3636 e_util_transform_change_unset(transform);
3641 if (e_comp_wl_subsurface_check(ec))
3643 // check parent matrix change
3644 E_Client *parent = e_comp_wl_subsurface_parent_get(ec);
3645 if (parent && parent->transform_core.result.enable)
3647 ec->transform_core.parent.enable = EINA_TRUE;
3649 if (!e_util_transform_matrix_equal_check(&ec->transform_core.parent.matrix,
3650 &parent->transform_core.result.matrix))
3653 ec->transform_core.parent.matrix = parent->transform_core.result.matrix;
3655 if (memcmp(&ec->transform_core.parent.zoom, &parent->transform_core.result.transform.zoom, sizeof(E_Util_Transform_Zoom)) != 0)
3658 ec->transform_core.parent.zoom = parent->transform_core.result.transform.zoom;
3661 else if (ec->transform_core.parent.enable)
3663 ec->transform_core.parent.enable = EINA_FALSE;
3664 e_util_transform_matrix_load_identity(&ec->transform_core.parent.matrix);
3665 ec->transform_core.parent.zoom.zoom_x = 1.0;
3666 ec->transform_core.parent.zoom.zoom_y = 1.0;
3667 ec->transform_core.parent.zoom.cx = 0;
3668 ec->transform_core.parent.zoom.cy = 0;
3677 _e_client_transform_core_boundary_update(E_Client *ec, E_Util_Transform_Rect_Vertex *vertices)
3679 int minx = 99999, miny = 99999;
3680 int maxx = -99999, maxy = -99999;
3685 if (!ec->frame) return;
3686 if (!ec->transform_core.result.enable) return;
3687 if (!vertices) return;
3689 for (i = 0; i < 4; ++i)
3694 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
3696 if (x < minx) minx = x;
3697 if (y < miny) miny = y;
3698 if (x > maxx) maxx = x;
3699 if (y > maxy) maxy = y;
3702 ec->transform_core.result.boundary.x = minx;
3703 ec->transform_core.result.boundary.y = miny;
3704 ec->transform_core.result.boundary.w = maxx - minx;
3705 ec->transform_core.result.boundary.h = maxy - miny;
3707 ELOGF("COMP", "[Transform][boundary][%d %d %d %d]",
3709 ec->transform_core.result.boundary.x,
3710 ec->transform_core.result.boundary.y,
3711 ec->transform_core.result.boundary.w,
3712 ec->transform_core.result.boundary.h);
3716 _e_client_transform_core_map_new(Evas_Object *obj,
3717 E_Util_Transform_Rect_Vertex *vertices,
3718 E_Util_Transform *transform,
3719 Eina_Bool direct_render)
3726 map = e_map_new_with_direct_render(direct_render);
3727 EINA_SAFETY_ON_NULL_RETURN_VAL(map, NULL);
3729 e_map_util_points_populate_from_object_full(map, obj, 0);
3730 e_map_util_points_color_set(map, 255, 255, 255, 255);
3732 for (i = 0 ; i < 4 ; ++i)
3737 e_util_transform_vertices_pos_round_get(vertices, i, &x, &y, 0, 0);
3738 e_map_point_coord_set(map, i, x, y, 1.0);
3740 if (transform && e_util_transform_texcoord_flag_get(transform))
3745 e_util_transform_texcoord_get(transform, i, &u, &v);
3746 e_map_point_image_uv_set(map, i, u, v);
3754 _e_client_transform_core_vertices_apply_with_zoom(E_Client *ec,
3756 E_Util_Transform_Rect_Vertex *vertices,
3757 E_Util_Transform *transform,
3758 E_Util_Transform_Zoom zoom)
3766 map = _e_client_transform_core_map_new(obj, vertices, transform,
3767 ec->transform_core.direct_render);
3768 EINA_SAFETY_ON_NULL_RETURN(map);
3770 e_map_util_zoom(map, zoom.zoom_x, zoom.zoom_y, zoom.cx, zoom.cy);
3772 e_comp_object_map_set(obj, map);
3773 e_comp_object_map_enable_set(obj, EINA_TRUE);
3778 evas_object_map_enable_set(obj, EINA_FALSE);
3782 _e_client_transform_core_vertices_apply(E_Client *ec,
3784 E_Util_Transform_Rect_Vertex *vertices,
3785 E_Util_Transform *transform)
3793 map = _e_client_transform_core_map_new(obj, vertices, transform,
3794 ec->transform_core.direct_render);
3795 EINA_SAFETY_ON_NULL_RETURN(map);
3797 e_comp_object_map_set(obj, map);
3798 e_comp_object_map_enable_set(obj, EINA_TRUE);
3803 evas_object_map_enable_set(obj, EINA_FALSE);
3807 _e_client_transform_core_sub_update(E_Client *ec, E_Util_Transform_Rect_Vertex *vertices)
3811 E_Comp_Wl_Client_Data *cdata;
3815 cdata = e_client_cdata_get(ec);
3818 EINA_LIST_FOREACH(cdata->sub.list, l, subc)
3819 e_client_transform_core_update(subc);
3821 EINA_LIST_FOREACH(cdata->sub.below_list, l, subc)
3822 e_client_transform_core_update(subc);
3826 _e_client_cb_hook_shell_surface_ready(void *data EINA_UNUSED, E_Client *ec)
3828 if (EINA_UNLIKELY(!ec))
3831 _e_client_aux_hint_eval(ec);
3834 // FIXME: This function has to be deleted and it remains for the backward compatibility.
3835 // Please find and fix to use e_comp_visibility_calculation_set(EINA_TRUE)
3836 // instead of e_client_visibility_calculate() call at e20 modules.
3838 e_client_visibility_calculate(void)
3840 e_comp_visibility_calculation_set(EINA_TRUE);
3844 e_client_visibility_skip_set(E_Client *ec, Eina_Bool skip)
3848 ELOGF("POL_VIS", "visibility skip set to %d", ec, skip);
3849 ec->visibility.skip = skip;
3853 e_client_post_raise_lower_set(E_Client *ec, Eina_Bool raise_set, Eina_Bool lower_set)
3857 ec->post_raise = raise_set;
3858 ec->post_lower = lower_set;
3862 e_client_first_mapped_get(E_Client *ec)
3864 if (!ec) return EINA_FALSE;
3866 return ec->first_mapped;
3869 EINTERN Eina_Bool e_client_mapped_get(E_Client *ec)
3871 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
3872 EINA_SAFETY_ON_NULL_RETURN_VAL(cdata, EINA_FALSE);
3874 return cdata->mapped;
3878 e_client_mapped_set(E_Client *ec, Eina_Bool set)
3880 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
3881 EINA_SAFETY_ON_NULL_RETURN(cdata);
3883 cdata->mapped = set;
3887 ////////////////////////////////////////////////
3889 e_client_clients_hash_exist()
3893 for (pix_id = 0; pix_id < E_PIXMAP_TYPE_MAX; pix_id++)
3895 if (eina_hash_population(clients_hash[pix_id]))
3903 e_client_idler_before(Eina_Bool *check_focus)
3908 *check_focus = EINA_FALSE;
3910 if (!e_client_clients_hash_exist()) return;
3912 TRACE_DS_BEGIN(CLIENT:IDLE BEFORE);
3914 EINA_LIST_FOREACH(e_comp->clients, l, ec)
3918 // pass 1 - eval0. fetch properties on new or on change and
3919 // call hooks to decide what to do - maybe move/resize
3920 if (ec->ignored || (!ec->changed)) continue;
3922 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_FETCH, ec)) continue;
3923 /* FETCH is hooked by the compositor to get client hints */
3924 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_FETCH, ec)) continue;
3928 client_type = ec->client_type;
3929 if (client_type != _e_client_type_get(ec))
3930 _e_client_event_property(ec, E_CLIENT_PROPERTY_CLIENT_TYPE);
3933 /* PRE_POST_FETCH calls e_remember apply for new client */
3934 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_POST_FETCH, ec)) continue;
3935 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_POST_FETCH, ec)) continue;
3936 if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_FRAME_ASSIGN, ec)) continue;
3938 _e_client_hook_call(E_CLIENT_HOOK_EVAL_POST_FRAME_ASSIGN, ec);
3940 // pass 2 - show and hide windows needing hide and eval (main eval)
3941 E_CLIENT_FOREACH(ec)
3943 if (e_object_is_del(E_OBJECT(ec))) continue;
3946 // ignored client but needing eval (aux hint) such as remote surfaces
3949 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
3950 if (cdata && cdata->first_commit)
3951 _e_client_aux_hint_eval(ec);
3956 if (ec->changes.visible)
3960 if ((!ec->new_client) &&
3961 (!ec->changes.pos) &&
3962 (!ec->changes.size))
3964 evas_object_show(ec->frame);
3965 ec->changes.visible = !evas_object_visible_get(ec->frame);
3970 evas_object_hide(ec->frame);
3971 ec->changes.visible = 0;
3978 e_comp_visibility_calculation_set(EINA_TRUE);
3979 if (ec->changes.accepts_focus)
3980 *check_focus = EINA_TRUE;
3981 ec->changes.accepts_focus = 0;
3984 if ((ec->changes.visible) && (ec->visible) && (!ec->changed))
3986 evas_object_show(ec->frame);
3987 ec->changes.visible = !evas_object_visible_get(ec->frame);
3988 ec->changed = ec->changes.visible;
3989 e_comp_visibility_calculation_set(EINA_TRUE);
4001 for (pix_id = 0; pix_id < E_PIXMAP_TYPE_MAX; pix_id++)
4002 clients_hash[pix_id] = eina_hash_pointer_new(NULL);
4004 E_COMP_WL_HOOK_APPEND(hooks, E_COMP_WL_HOOK_SHELL_SURFACE_READY, _e_client_cb_hook_shell_surface_ready, NULL);
4006 #ifdef REFACTOR_FOCUS_POLICY
4008 g_mutex_init(&focused_ec_mutex);
4011 E_EVENT_CLIENT_ADD = ecore_event_type_new();
4012 E_EVENT_CLIENT_REMOVE = ecore_event_type_new();
4013 E_EVENT_CLIENT_DESK_SET = ecore_event_type_new();
4014 E_EVENT_CLIENT_ZONE_SET = ecore_event_type_new();
4015 E_EVENT_CLIENT_RESIZE = ecore_event_type_new();
4016 E_EVENT_CLIENT_MOVE = ecore_event_type_new();
4017 E_EVENT_CLIENT_SHOW = ecore_event_type_new();
4018 E_EVENT_CLIENT_HIDE = ecore_event_type_new();
4019 E_EVENT_CLIENT_ICONIFY = ecore_event_type_new();
4020 E_EVENT_CLIENT_UNICONIFY = ecore_event_type_new();
4021 E_EVENT_CLIENT_STACK = ecore_event_type_new();
4022 E_EVENT_CLIENT_FOCUS_IN = ecore_event_type_new();
4023 E_EVENT_CLIENT_FOCUS_OUT = ecore_event_type_new();
4024 E_EVENT_CLIENT_PROPERTY = ecore_event_type_new();
4025 E_EVENT_CLIENT_FULLSCREEN = ecore_event_type_new();
4026 E_EVENT_CLIENT_UNFULLSCREEN = ecore_event_type_new();
4027 #ifdef _F_ZONE_WINDOW_ROTATION_
4028 E_EVENT_CLIENT_ROTATION_CHANGE_BEGIN = ecore_event_type_new();
4029 E_EVENT_CLIENT_ROTATION_CHANGE_CANCEL = ecore_event_type_new();
4030 E_EVENT_CLIENT_ROTATION_CHANGE_END = ecore_event_type_new();
4031 E_EVENT_CLIENT_ROTATION_GEOMETRY_SET = ecore_event_type_new();
4033 E_EVENT_CLIENT_VISIBILITY_CHANGE = ecore_event_type_new();
4034 E_EVENT_CLIENT_BUFFER_CHANGE = ecore_event_type_new();
4035 E_EVENT_CLIENT_FOCUS_SKIP_SET = ecore_event_type_new();;
4036 E_EVENT_CLIENT_FOCUS_SKIP_UNSET = ecore_event_type_new();;
4038 return (!!clients_hash[1]);
4042 e_client_shutdown(void)
4045 for (pix_id = 0; pix_id < E_PIXMAP_TYPE_MAX; pix_id++)
4046 E_FREE_FUNC(clients_hash[pix_id], eina_hash_free);
4048 E_FREE_LIST(hooks, e_comp_wl_hook_del);
4049 E_FREE_LIST(handlers, ecore_event_handler_del);
4051 #ifdef REFACTOR_FOCUS_POLICY
4053 g_mutex_clear(&focused_ec_mutex);
4058 e_client_unignore(E_Client *ec)
4061 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
4062 if (!ec->ignored) return;
4065 _e_client_event_add(ec);
4069 e_client_new(E_Pixmap *cp, int first_map, int internal)
4074 type = e_pixmap_type_get(cp);
4075 if (type >= E_PIXMAP_TYPE_MAX) return NULL;
4076 if (eina_hash_find(clients_hash[type], &cp)) return NULL;
4078 ec = E_OBJECT_ALLOC(E_Client, E_CLIENT_TYPE, _e_client_free);
4079 if (!ec) return NULL;
4080 e_object_del_func_set(E_OBJECT(ec), E_OBJECT_CLEANUP_FUNC(_e_client_del));
4082 uuid_generate(ec->uuid);
4084 ec->focus_policy_override = E_FOCUS_LAST;
4085 e_client_size_set(ec, 1, 1);
4086 ec->internal = internal;
4089 e_pixmap_client_set(cp, ec);
4090 ec->resize_mode = E_POINTER_RESIZE_NONE;
4091 ec->layer = E_LAYER_CLIENT_NORMAL;
4092 ec->first_mapped = EINA_FALSE;
4093 ec->post_raise = EINA_TRUE;
4094 ec->post_lower = EINA_FALSE;
4095 ec->animatable = EINA_TRUE;
4097 /* FIXME: if first_map is 1 then we should ignore the first hide event
4098 * or ensure the window is already hidden and events flushed before we
4099 * create a border for it */
4102 ec->changes.pos = 1;
4104 // needed to be 1 for internal windw and on restart.
4105 // ec->ignore_first_unmap = 2;
4107 ec->offer_resistance = 1;
4109 e_comp->new_clients++;
4111 ec->exp_iconify.by_client = 0;
4112 ec->exp_iconify.not_raise = 0;
4113 ec->exp_iconify.skip_iconify = 0;
4114 ec->exp_iconify.skip_by_remote = 0;
4115 if (e_config->deiconify_approve)
4116 ec->exp_iconify.deiconify_update= 1;
4118 ec->exp_iconify.deiconify_update= 0;
4119 if (e_config->use_buffer_flush)
4120 ec->exp_iconify.buffer_flush = 1;
4122 ec->exp_iconify.buffer_flush = 0;
4124 e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_NONE);
4126 if (!_e_client_hook_call(E_CLIENT_HOOK_NEW_CLIENT, ec))
4128 /* delete the above allocated object */
4129 //e_object_del(E_OBJECT(ec));
4133 _e_client_aux_hint_eval(ec);
4135 ec->icccm.title = NULL;
4136 ec->icccm.name = NULL;
4137 #if defined(__cplusplus) || defined(c_plusplus)
4138 ec->icccm.cpp_class = NULL;
4140 ec->icccm.class = NULL;
4142 ec->icccm.icon_name = NULL;
4143 ec->icccm.machine = NULL;
4144 ec->icccm.min_w = 1;
4145 ec->icccm.min_h = 1;
4146 ec->icccm.max_w = 32767;
4147 ec->icccm.max_h = 32767;
4148 ec->icccm.base_w = 0;
4149 ec->icccm.base_h = 0;
4150 ec->icccm.step_w = -1;
4151 ec->icccm.step_h = -1;
4152 ec->icccm.min_aspect = 0.0;
4153 ec->icccm.max_aspect = 0.0;
4156 ec->netwm.name = NULL;
4157 ec->netwm.icon_name = NULL;
4158 ec->netwm.desktop = 0;
4159 ec->netwm.state.modal = 0;
4160 ec->netwm.state.sticky = 0;
4161 ec->netwm.state.shaded = 0;
4162 ec->netwm.state.hidden = 0;
4163 ec->netwm.state.maximized_v = 0;
4164 ec->netwm.state.maximized_h = 0;
4165 ec->netwm.state.skip_taskbar = 0;
4166 ec->netwm.state.skip_pager = 0;
4167 ec->netwm.state.fullscreen = 0;
4168 ec->netwm.state.stacking = E_STACKING_NONE;
4169 ec->netwm.action.move = 0;
4170 ec->netwm.action.resize = 0;
4171 ec->netwm.action.minimize = 0;
4172 ec->netwm.action.shade = 0;
4173 ec->netwm.action.stick = 0;
4174 ec->netwm.action.maximized_h = 0;
4175 ec->netwm.action.maximized_v = 0;
4176 ec->netwm.action.fullscreen = 0;
4177 ec->netwm.action.change_desktop = 0;
4178 ec->netwm.action.close = 0;
4179 ec->netwm.opacity = 255;
4181 ec->visibility.obscured = E_VISIBILITY_UNKNOWN;
4182 ec->visibility.opaque = -1;
4183 ec->visibility.changed = 0;
4184 ec->visibility.skip = 0;
4185 ec->visibility.last_sent_type = E_VISIBILITY_UNKNOWN;
4187 ec->transform.zoom = 1.0;
4188 ec->transform.angle = 0.0;
4189 ec->transform_core.direct_render = EINA_TRUE;
4190 ec->transform_core.activate = EINA_TRUE;
4192 ec->pointer_enter_sent = EINA_FALSE;
4194 ec->acquire_fence_fd = -1;
4198 e_comp->clients = eina_list_append(e_comp->clients, ec);
4199 eina_hash_add(clients_hash[type], &ec->pixmap, ec);
4201 ELOGF("COMP", "CLIENT ADD. cp:%p, argb:%d, internal:%d, ignored:%d", ec, cp, ec->argb, internal, ec->ignored);
4203 _e_client_event_add(ec);
4204 e_comp_object_client_add(ec);
4207 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW, _e_client_cb_evas_show, ec);
4208 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_HIDE, _e_client_cb_evas_hide, ec);
4209 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOVE, _e_client_cb_evas_move, ec);
4210 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESIZE, _e_client_cb_evas_resize, ec);
4211 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESTACK, _e_client_cb_evas_restack, ec);
4212 evas_object_smart_callback_add(ec->frame, "shade_done", _e_client_cb_evas_shade_done, ec);
4214 e_client_layer_set(ec, E_LAYER_CLIENT_ABOVE);
4216 e_client_layer_set(ec, E_LAYER_CLIENT_NORMAL);
4219 #ifdef REFACTOR_ZONE_DESK
4222 _e_client_zone_update(ec);
4224 e_client_desk_set(ec, e_desk_current_get(e_zone_current_get()));
4227 #ifdef _F_E_CLIENT_NEW_CLIENT_POST_HOOK_
4228 _e_client_hook_call(E_CLIENT_HOOK_NEW_CLIENT_POST, ec);
4231 ec->manage_resize.resize_obj = NULL;
4232 ec->manage_resize.x = ec->manage_resize.y = ec->manage_resize.w = ec->manage_resize.h = 0;
4233 ec->manage_resize.enable_aspect_ratio = EINA_FALSE;
4234 ec->manage_resize.aw = ec->manage_resize.ah = 0;
4235 ec->manage_resize.header_h = 0;
4236 ec->manage_resize.footer_h = 0;
4238 ec->visibility.ignore_geometry = e_config->calc_vis_ignore_geometry;
4243 E_API Eina_Bool e_client_is_internal(E_Client *ec)
4245 E_OBJECT_CHECK_RETURN(ec, EINA_TRUE);
4246 return ec->internal;
4249 #ifdef REFACTOR_ZONE_DESK
4252 e_client_desk_set(E_Client *ec, E_Desk *desk)
4254 E_Event_Client_Desk_Set *ev;
4259 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
4260 E_OBJECT_CHECK(desk);
4261 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
4262 if (e_desk_has_ec(desk, ec)) return;
4266 ec->desk->fullscreen_clients = eina_list_remove(ec->desk->fullscreen_clients, ec);
4267 desk->fullscreen_clients = eina_list_append(desk->fullscreen_clients, ec);
4269 old_desk = ec->desk;
4271 e_desk_client_del(old_desk, ec);
4273 e_desk_client_add(desk, ec);
4274 if (!ec->new_client)
4278 e_comp_object_effect_unclip(ec->frame);
4279 e_comp_object_effect_set(ec->frame, NULL);
4281 if (desk->visible || ec->sticky)
4283 if ((!ec->hidden) && (!ec->iconic))
4284 evas_object_show(ec->frame);
4289 evas_object_hide(ec->frame);
4292 e_client_comp_hidden_set(ec, (!desk->visible) && (!ec->sticky));
4293 e_client_zone_set(ec, desk->zone);
4297 ev = E_NEW(E_Event_Client_Desk_Set, 1);
4302 e_object_ref(E_OBJECT(ec));
4303 ev->desk = old_desk;
4304 e_object_ref(E_OBJECT(old_desk));
4305 ecore_event_add(E_EVENT_CLIENT_DESK_SET, ev, (Ecore_End_Cb)_e_client_event_desk_set_free, NULL);
4308 zone = e_comp_zone_find_by_ec(ec);
4309 if (old_desk->zone == zone)
4311 e_client_res_change_geometry_save(ec);
4312 e_client_res_change_geometry_restore(ec);
4313 ec->pre_res_change.valid = 0;
4317 if (e_config->transient.desktop)
4322 EINA_LIST_FOREACH(ec->transients, l, child)
4323 e_client_desk_set(child, ec->desk);
4326 _e_client_hook_call(E_CLIENT_HOOK_DESK_SET, ec);
4327 evas_object_smart_callback_call(ec->frame, "desk_change", ec);
4329 if (ec->desk->desk_area.enable)
4331 if (!ec->desk_area.desk_area)
4334 eda = e_desk_desk_area_base_get(ec->desk);
4335 e_client_desk_area_set(ec, eda);
4338 e_client_desk_area_enable_set(ec, EINA_TRUE);
4344 e_client_desk_iconify_skip_set(E_Client *ec, Eina_Bool skip)
4347 ec->user_skip_winlist = skip;
4351 e_client_desk_iconify_skip_get(E_Client *ec)
4353 if (!ec) return EINA_FALSE;
4354 return ec->user_skip_winlist;
4358 e_client_comp_grabbed_get(void)
4360 return comp_grabbed;
4364 e_client_action_get(void)
4366 return action_client;
4370 //////////////////////////////////////////////////////////
4373 e_client_mouse_in(E_Client *ec, int x, int y)
4377 if (comp_grabbed) return;
4378 if (e_object_is_del(E_OBJECT(ec))) return;
4379 desk = e_comp_desk_find_by_ec(ec);
4380 if (desk && desk->animate_count) return;
4381 ec->mouse.current.mx = x;
4382 ec->mouse.current.my = y;
4385 #ifdef REFACTOR_FOCUS_POLICY
4386 _e_client_hook_call(E_CLIENT_HOOK_MOUSE_IN, ec);
4388 if ((!ec->iconic) && (!e_client_util_ignored_get(ec)))
4389 e_focus_event_mouse_in(ec);
4394 e_client_mouse_out(E_Client *ec, int x, int y)
4398 if (comp_grabbed) return;
4399 if (ec->fullscreen) return;
4400 if (e_object_is_del(E_OBJECT(ec))) return;
4401 desk = e_comp_desk_find_by_ec(ec);
4402 if (desk && desk->animate_count) return;
4404 ec->mouse.current.mx = x;
4405 ec->mouse.current.my = y;
4408 #ifdef REFACTOR_FOCUS_POLICY
4409 _e_client_hook_call(E_CLIENT_HOOK_MOUSE_OUT, ec);
4411 if ((!ec->iconic) && (!e_client_util_ignored_get(ec)))
4412 e_focus_event_mouse_out(ec);
4417 e_client_mouse_wheel(E_Client *ec, Evas_Point *output, E_Binding_Event_Wheel *ev)
4419 EINA_SAFETY_ON_NULL_RETURN(ec);
4420 if (action_client) return;
4421 ec->mouse.current.mx = output->x;
4422 ec->mouse.current.my = output->y;
4426 e_client_mouse_down(E_Client *ec, int button, Evas_Point *output, E_Binding_Event_Mouse_Button *ev)
4428 #ifdef REFACTOR_FOCUS_POLICY
4433 EINA_SAFETY_ON_NULL_RETURN(ec);
4434 if (action_client || ec->iconic || e_client_util_ignored_get(ec)) return;
4435 if ((button >= 1) && (button <= 3))
4437 ec->mouse.last_down[button - 1].mx = output->x;
4438 ec->mouse.last_down[button - 1].my = output->y;
4439 ec->mouse.last_down[button - 1].x = ec->x;
4440 ec->mouse.last_down[button - 1].y = ec->y;
4441 ec->mouse.last_down[button - 1].w = ec->w;
4442 ec->mouse.last_down[button - 1].h = ec->h;
4446 ec->moveinfo.down.x = ec->x;
4447 ec->moveinfo.down.y = ec->y;
4448 ec->moveinfo.down.w = ec->w;
4449 ec->moveinfo.down.h = ec->h;
4451 ec->mouse.current.mx = output->x;
4452 ec->mouse.current.my = output->y;
4453 if ((button >= 1) && (button <= 3))
4455 ec->mouse.last_down[button - 1].mx = output->x;
4456 ec->mouse.last_down[button - 1].my = output->y;
4457 ec->mouse.last_down[button - 1].x = ec->x;
4458 ec->mouse.last_down[button - 1].y = ec->y;
4459 ec->mouse.last_down[button - 1].w = ec->w;
4460 ec->mouse.last_down[button - 1].h = ec->h;
4464 ec->moveinfo.down.x = ec->x;
4465 ec->moveinfo.down.y = ec->y;
4466 ec->moveinfo.down.w = ec->w;
4467 ec->moveinfo.down.h = ec->h;
4469 ec->mouse.current.mx = output->x;
4470 ec->mouse.current.my = output->y;
4472 #ifdef REFACTOR_FOCUS_POLICY
4473 _e_client_hook_call(E_CLIENT_HOOK_MOUSE_DOWN, ec);
4475 focused = e_client_focused_get();
4476 if ((focused) && (ec != focused))
4478 e_focus_event_mouse_down(ec);
4484 e_client_mouse_up(E_Client *ec, int button, Evas_Point *output, E_Binding_Event_Mouse_Button* ev)
4486 EINA_SAFETY_ON_NULL_RETURN(ec);
4487 if (ec->iconic || e_client_util_ignored_get(ec)) return;
4488 if ((button >= 1) && (button <= 3))
4490 ec->mouse.last_up[button - 1].mx = output->x;
4491 ec->mouse.last_up[button - 1].my = output->y;
4492 ec->mouse.last_up[button - 1].x = ec->x;
4493 ec->mouse.last_up[button - 1].y = ec->y;
4495 ec->mouse.current.mx = output->x;
4496 ec->mouse.current.my = output->y;
4497 /* also we don't pass the same params that went in - then again that */
4498 /* should be ok as we are just ending the action if it has an end */
4499 if (ec->cur_mouse_action)
4501 if (ec->cur_mouse_action->func.end_mouse)
4502 ec->cur_mouse_action->func.end_mouse(E_OBJECT(ec), "", ev);
4503 else if (ec->cur_mouse_action->func.end)
4504 ec->cur_mouse_action->func.end(E_OBJECT(ec), "");
4505 e_object_unref(E_OBJECT(ec->cur_mouse_action));
4506 ec->cur_mouse_action = NULL;
4509 if ((button >= 1) && (button <= 3))
4511 ec->mouse.last_up[button - 1].mx = output->x;
4512 ec->mouse.last_up[button - 1].my = output->y;
4513 ec->mouse.last_up[button - 1].x = ec->x;
4514 ec->mouse.last_up[button - 1].y = ec->y;
4519 e_client_stay_within_canvas_margin(E_Client *ec)
4526 _e_client_stay_within_canvas_margin(ec, ec->x, ec->y, &new_x, &new_y);
4528 if ((ec->x != new_x) || (ec->y != new_y))
4529 evas_object_move(ec->frame, new_x, new_y);
4534 e_client_mouse_move(E_Client *ec, Evas_Point *output)
4536 EINA_SAFETY_ON_NULL_RETURN(ec);
4537 if (ec->iconic || e_client_util_ignored_get(ec)) return;
4538 ec->mouse.current.mx = output->x;
4539 ec->mouse.current.my = output->y;
4540 if (e_client_util_moving_get(ec))
4542 _e_client_move_handle(ec);
4544 else if (e_client_util_resizing_get(ec))
4546 _e_client_resize_handle(ec);
4549 ///////////////////////////////////////////////////////
4552 e_client_res_change_geometry_save(E_Client *ec)
4555 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
4557 if (ec->pre_res_change.valid) return;
4558 ec->pre_res_change.valid = 1;
4559 ec->pre_res_change.x = ec->x;
4560 ec->pre_res_change.y = ec->y;
4561 ec->pre_res_change.w = ec->w;
4562 ec->pre_res_change.h = ec->h;
4563 ec->pre_res_change.saved.x = ec->saved.x;
4564 ec->pre_res_change.saved.y = ec->saved.y;
4565 ec->pre_res_change.saved.w = ec->saved.w;
4566 ec->pre_res_change.saved.h = ec->saved.h;
4570 e_client_res_change_geometry_restore(E_Client *ec)
4576 unsigned char valid : 1;
4585 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
4586 if (!ec->pre_res_change.valid) return;
4587 if (ec->new_client) return;
4589 zone = e_comp_zone_find_by_ec(ec);
4592 memcpy(&pre_res_change, &ec->pre_res_change, sizeof(pre_res_change));
4596 e_client_unfullscreen(ec);
4597 e_client_fullscreen(ec, e_config->fullscreen_policy);
4599 else if (ec->maximized != E_MAXIMIZE_NONE)
4603 max = ec->maximized;
4604 e_client_unmaximize(ec, E_MAXIMIZE_BOTH);
4605 e_client_maximize(ec, max);
4609 int x, y, w, h, zx, zy, zw, zh;
4611 ec->saved.x = ec->pre_res_change.saved.x;
4612 ec->saved.y = ec->pre_res_change.saved.y;
4613 ec->saved.w = ec->pre_res_change.saved.w;
4614 ec->saved.h = ec->pre_res_change.saved.h;
4616 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
4618 if (ec->saved.w > zw)
4620 if ((ec->saved.x + ec->saved.w) > (zx + zw))
4621 ec->saved.x = zx + zw - ec->saved.w;
4623 if (ec->saved.h > zh)
4625 if ((ec->saved.y + ec->saved.h) > (zy + zh))
4626 ec->saved.y = zy + zh - ec->saved.h;
4628 x = ec->pre_res_change.x;
4629 y = ec->pre_res_change.y;
4630 w = ec->pre_res_change.w;
4631 h = ec->pre_res_change.h;
4636 if ((x + w) > (zx + zw))
4638 if ((y + h) > (zy + zh))
4640 evas_object_geometry_set(ec->frame, x, y, w, h);
4642 memcpy(&ec->pre_res_change, &pre_res_change, sizeof(pre_res_change));
4645 #ifdef REFACTOR_ZONE_DESK
4648 e_client_zone_set(E_Client *ec, E_Zone *zone)
4650 E_Event_Client_Zone_Set *ev;
4653 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
4654 E_OBJECT_CHECK(zone);
4655 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
4656 if (e_zone_has_ec(zone, ec)) return;
4658 ev = E_NEW(E_Event_Client_Zone_Set, 1);
4661 /* if the window does not lie in the new zone, move it so that it does */
4662 if (!E_INTERSECTS(ec->x, ec->y, ec->w, ec->h, zone->x, zone->y, zone->w, zone->h))
4666 x = ec->x, y = ec->y;
4668 /* keep window from hanging off bottom and left */
4669 if (x + ec->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + ec->w);
4670 if (y + ec->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + ec->h);
4672 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
4673 if (x < zone->x) x = zone->x;
4674 if (y < zone->y) y = zone->y;
4676 if (!E_INTERSECTS(x, y, ec->w, ec->h, zone->x, zone->y, zone->w, zone->h))
4678 /* still not in zone at all, so just move it to closest edge */
4679 if (x < zone->x) x = zone->x;
4680 if (x >= zone->x + zone->w) x = zone->x + zone->w - ec->w;
4681 if (y < zone->y) y = zone->y;
4682 if (y >= zone->y + zone->h) y = zone->y + zone->h - ec->h;
4684 evas_object_move(ec->frame, x, y);
4687 // TODO: NEED TO DELETE LINE BELOW
4692 e_object_ref(E_OBJECT(ec));
4694 e_object_ref(E_OBJECT(zone));
4696 ecore_event_add(E_EVENT_CLIENT_ZONE_SET, ev, (Ecore_End_Cb)_e_client_event_zone_set_free, NULL);
4698 // TODO: change all use of e_client_zone_set() to e_zone_client_add()
4699 e_zone_client_add(zone, ec);
4704 e_client_pos_set(E_Client *ec, int x, int y)
4712 e_client_pos_get(E_Client *ec, int *x, int *y)
4728 e_client_size_set(E_Client *ec, int w, int h)
4736 e_client_size_get(E_Client *ec, int *w, int *h)
4752 e_client_geometry_get(E_Client *ec, int *x, int *y, int *w, int *h)
4760 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
4762 if (e_client_transform_core_enable_get(ec))
4764 gx = ec->transform_core.result.boundary.x;
4765 gy = ec->transform_core.result.boundary.y;
4766 gw = ec->transform_core.result.boundary.w;
4767 gh = ec->transform_core.result.boundary.h;
4773 evas_object_geometry_get(ec->frame, &gx, &gy, &gw, &gh);
4774 if (gw == 0 && gh == 0)
4776 /* In this case, there is no image buffer in e_comp_object, thus it
4777 * should return geometry value of ec itself. It usually happens if
4778 * new ec is not mapped yet.
4802 e_client_above_get(const E_Client *ec)
4807 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
4808 if (EINA_INLIST_GET(ec)->next) //check current layer
4810 EINA_INLIST_FOREACH(EINA_INLIST_GET(ec)->next, ec2)
4814 ELOGF("FATAL", "CHECK the ec inlist next", ec);
4817 if (!e_object_is_del(E_OBJECT(ec2)))
4821 if (ec->layer == E_LAYER_CLIENT_CURSOR) return NULL;
4822 if (e_comp_canvas_client_layer_map(ec->layer) == 9999) return NULL;
4824 /* go up the layers until we find one */
4825 for (x = e_comp_canvas_layer_map(ec->layer) + 1; x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
4827 if (!e_comp->layers[x].clients) continue;
4828 EINA_INLIST_FOREACH(e_comp->layers[x].clients, ec2)
4832 ELOGF("FATAL", "EC exist above layer. ec layer_map:%d, cur layer_map:%d",
4833 ec, e_comp_canvas_layer_map(ec->layer), x);
4836 if (!e_object_is_del(E_OBJECT(ec2)))
4844 e_client_below_get(const E_Client *ec)
4849 E_Layer ec_layer, ec_layer_cw;
4852 E_OBJECT_CHECK_RETURN(ec, NULL);
4853 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, NULL);
4855 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
4856 if (EINA_INLIST_GET(ec)->prev) //check current layer
4858 for (l = EINA_INLIST_GET(ec)->prev; l; l = l->prev)
4860 ec2 = EINA_INLIST_CONTAINER_GET(l, E_Client);
4863 ELOGF("FATAL", "CHECK the ec inlist prev", ec);
4866 if (!e_object_is_del(E_OBJECT(ec2)))
4871 // check layer validation
4872 ec_layer = ec->layer;
4873 if (ec->layer_block || ec->layer_pending)
4875 cw_layer = e_comp_object_layer_get(ec->frame);
4878 ec_layer_cw = e_comp_canvas_layer_map_to(cw_layer);
4879 if (ec_layer != ec_layer_cw)
4881 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);
4882 ec_layer = ec_layer_cw;
4887 if (ec_layer == E_LAYER_CLIENT_DESKTOP) return NULL;
4888 if (e_comp_canvas_client_layer_map(ec_layer) == 9999) return NULL;
4890 /* go down the layers until we find one */
4891 x = e_comp_canvas_layer_map(ec_layer);
4894 for (; x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
4896 if (!e_comp->layers[x].clients) continue;
4897 EINA_INLIST_REVERSE_FOREACH(e_comp->layers[x].clients, ec2)
4901 ELOGF("FATAL", "EC exist below layer. ec layer_map:%d, cur layer_map:%d",
4902 ec, e_comp_canvas_layer_map(ec_layer), x);
4905 if (!e_object_is_del(E_OBJECT(ec2)))
4913 e_client_bottom_get(void)
4916 for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
4920 if (!e_comp->layers[x].clients) continue;
4921 EINA_INLIST_FOREACH(e_comp->layers[x].clients, ec2)
4922 if (!e_object_is_del(E_OBJECT(ec2)))
4929 e_client_top_get(void)
4932 for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
4936 if (!e_comp->layers[x].clients) continue;
4937 EINA_INLIST_REVERSE_FOREACH(e_comp->layers[x].clients, ec2)
4938 if (!e_object_is_del(E_OBJECT(ec2)))
4944 EINTERN unsigned int
4945 e_clients_count(void)
4947 return eina_list_count(e_comp->clients);
4952 * Set a callback which will be called just prior to updating the
4953 * move coordinates for a border
4956 e_client_move_intercept_cb_set(E_Client *ec, E_Client_Move_Intercept_Cb cb)
4958 ec->move_intercept_cb = cb;
4961 ///////////////////////////////////////
4963 E_API E_Client_Hook *
4964 e_client_hook_add(E_Client_Hook_Point hookpoint, E_Client_Hook_Cb func, const void *data)
4968 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_CLIENT_HOOK_LAST, NULL);
4969 ch = E_NEW(E_Client_Hook, 1);
4970 if (!ch) return NULL;
4971 ch->hookpoint = hookpoint;
4973 ch->data = (void*)data;
4974 _e_client_hooks[hookpoint] = eina_inlist_append(_e_client_hooks[hookpoint], EINA_INLIST_GET(ch));
4979 e_client_hook_del(E_Client_Hook *ch)
4982 if (_e_client_hooks_walking == 0)
4984 _e_client_hooks[ch->hookpoint] = eina_inlist_remove(_e_client_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
4988 _e_client_hooks_delete++;
4991 ///////////////////////////////////////
4993 E_API E_Client_Intercept_Hook *
4994 e_client_intercept_hook_add(E_Client_Intercept_Hook_Point hookpoint, E_Client_Intercept_Hook_Cb func, const void *data)
4996 E_Client_Intercept_Hook *ch;
4998 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_CLIENT_INTERCEPT_HOOK_LAST, NULL);
4999 ch = E_NEW(E_Client_Intercept_Hook, 1);
5000 if (!ch) return NULL;
5001 ch->hookpoint = hookpoint;
5003 ch->data = (void*)data;
5004 _e_client_intercept_hooks[hookpoint] = eina_inlist_append(_e_client_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
5009 e_client_intercept_hook_del(E_Client_Intercept_Hook *ch)
5014 if (_e_client_intercept_hooks_walking == 0)
5016 _e_client_intercept_hooks[ch->hookpoint] =
5017 eina_inlist_remove(_e_client_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
5021 _e_client_intercept_hooks_delete++;
5024 #ifdef REFACTOR_FOCUS_POLICY
5027 e_client_focus_stack_lower(E_Client *ec)
5029 Eina_List *l = NULL;
5030 E_Client *ec2 = NULL;
5032 EINA_SAFETY_ON_NULL_RETURN(ec);
5034 focus_stack = eina_list_remove(focus_stack, ec);
5036 EINA_LIST_REVERSE_FOREACH(focus_stack, l, ec2)
5038 if (ec2 == NULL) continue;
5039 if (ec2->layer < ec->layer) continue;
5041 focus_stack = eina_list_append_relative_list(focus_stack, ec, l);
5045 focus_stack = eina_list_prepend(focus_stack, ec);
5051 e_client_focus_latest_set(E_Client *ec)
5053 EINA_SAFETY_ON_NULL_RETURN(ec);
5055 #ifdef REFACTOR_FOCUS_POLICY
5056 _e_client_hook_call(E_CLIENT_HOOK_FOCUS_LATEST_SET, ec);
5058 focus_stack = eina_list_remove(focus_stack, ec);
5059 focus_stack = eina_list_prepend(focus_stack, ec);
5063 #ifdef REFACTOR_FOCUS_POLICY
5066 e_client_focus_stack_append_current_focused(E_Client *ec)
5068 Eina_List *l = NULL;
5069 E_Client *temp_ec = NULL;
5071 if (!ec) CRI("ACK");
5073 focus_stack = eina_list_remove(focus_stack, ec);
5075 EINA_LIST_FOREACH(focus_stack, l, temp_ec)
5077 if (temp_ec != focused) continue;
5079 focus_stack = eina_list_append_relative_list(focus_stack, ec, l);
5083 focus_stack = eina_list_prepend(focus_stack, ec);
5089 e_client_focus_defer_set(E_Client *ec)
5091 EINA_SAFETY_ON_NULL_RETURN(ec);
5092 #ifdef REFACTOR_FOCUS_POLICY
5093 _e_client_hook_call(E_CLIENT_HOOK_FOCUS_DEFER_SET, ec);
5095 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK) return;
5097 ELOGF("FOCUS", "focus defer set", ec);
5099 defer_focus_stack = eina_list_remove(defer_focus_stack, ec);
5100 defer_focus_stack = eina_list_prepend(defer_focus_stack, ec);
5104 #ifdef REFACTOR_FOCUS_POLICY
5107 e_client_focus_defer_unset(E_Client *ec)
5109 EINA_SAFETY_ON_NULL_RETURN(ec);
5110 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK) return;
5112 ELOGF("FOCUS", "focus defer unset", ec);
5114 defer_focus_stack = eina_list_remove(defer_focus_stack, ec);
5118 e_client_focus_defer_clear(void)
5120 if (!defer_focus_stack) return;
5122 ELOGF("FOCUS", "focus defer clear", NULL);
5124 defer_focus_stack = eina_list_free(defer_focus_stack);
5128 e_client_refocus(void)
5134 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK) return;
5136 EINA_LIST_FOREACH(e_client_focus_stack_get(), l, ec)
5138 desk = e_comp_desk_find_by_ec(ec);
5139 if (!desk) continue;
5140 if (desk->visible && (!ec->iconic))
5142 g_mutex_lock(&e_comp->input_key_grabs_mutex);
5143 if (e_comp->input_key_grabs || e_comp->input_mouse_grabs)
5145 g_mutex_unlock(&e_comp->input_key_grabs_mutex);
5148 g_mutex_unlock(&e_comp->input_key_grabs_mutex);
5149 ELOGF("FOCUS", "focus set | refocus", ec);
5150 e_client_frame_focus_set(ec, EINA_TRUE);
5158 * Sets the focus to the given client if necessary
5159 * There are 3 cases of different focus_policy-configurations:
5161 * - E_FOCUS_CLICK: just set the focus, the most simple one
5163 * - E_FOCUS_MOUSE: focus is where the mouse is, so try to
5164 * warp the pointer to the window. If this fails (because
5165 * the pointer is already in the window), just set the focus.
5167 * - E_FOCUS_SLOPPY: focus is where the mouse is or on the
5168 * last window which was focused, if the mouse is on the
5169 * desktop. So, we need to look if there is another window
5170 * under the pointer and warp to pointer to the right
5171 * one if so (also, we set the focus afterwards). In case
5172 * there is no window under pointer, the pointer is on the
5173 * desktop and so we just set the focus.
5176 * This function is to be called when setting the focus was not
5177 * explicitly triggered by the user (by moving the mouse or
5178 * clicking for example), but implicitly (by closing a window,
5179 * the last focused window should get focus).
5183 e_client_focus_set_with_pointer(E_Client *ec)
5186 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5187 /* note: this is here as it seems there are enough apps that do not even
5188 * expect us to emulate a look of focus but not actually set x input
5189 * focus as we do - so simply abort any focuse set on such windows */
5190 /* be strict about accepting focus hint */
5191 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK) return;
5193 if ((!ec->icccm.accepts_focus) &&
5194 (!ec->icccm.take_focus)) return;
5195 if (ec->lock_focus_out) return;
5196 if (ec == focused) return;
5198 TRACE_DS_BEGIN(CLIENT:FOCUS SET WITH POINTER);
5199 ELOGF("FOCUS", "focus set | focus with pointer", ec);
5200 e_client_frame_focus_set(ec, EINA_TRUE);
5202 if (e_config->focus_policy == E_FOCUS_CLICK)
5218 e_client_focused_set(E_Client *ec)
5220 #ifdef REFACTOR_FOCUS_POLICY
5221 E_Client *focused_ec;
5225 ELOGF("FOCUS", "CLIENT FOCUSED_SET : SET", ec);
5227 ELOGF("FOCUS", "CLIENT FOCUSED_SET : UNSET", NULL);
5229 focused_ec = e_comp_focused_ec_get();
5230 if (ec == focused_ec) return;
5232 TRACE_DS_BEGIN(CLIENT:FOCUSED SET);
5234 // unset the current focused_ec if focused_ec is not being deleted
5237 if (!e_object_is_del(E_OBJECT(focused_ec)))
5239 _e_client_hook_call(E_CLIENT_HOOK_FOCUS_UNSET, focused_ec);
5241 if (e_object_ref_get(E_OBJECT(focused_ec)) > 0)
5243 _e_client_event_simple(focused_ec, E_EVENT_CLIENT_FOCUS_OUT);
5244 e_client_urgent_set(focused_ec, focused_ec->icccm.urgent);
5249 // clear the current focused_ec when ec is NULL
5252 zone = e_comp_zone_find_by_ec(focused_ec);
5253 e_zone_focus_clear(zone);
5258 // set the new current focused_ec
5259 _e_client_hook_call(E_CLIENT_HOOK_FOCUS_SET, ec);
5261 // send the client_focuse_in event
5262 _e_client_event_simple(ec, E_EVENT_CLIENT_FOCUS_IN);
5264 #ifdef REFACTOR_ZONE_DESK
5266 // TODO: This is not for focus, but for Window Placement policy.
5267 // Move this code to the better place.
5268 if (ec->sticky && ec->desk && (!ec->desk->visible))
5269 e_client_desk_set(ec, e_desk_current_get(zone));
5274 E_Client *ec2, *ec_unfocus = focused;
5278 if (ec == focused) return;
5280 TRACE_DS_BEGIN(CLIENT:FOCUSED SET);
5282 ELOGF("FOCUS", "CLIENT FOCUS_SET", ec);
5284 g_mutex_lock(&focused_ec_mutex);
5286 g_mutex_unlock(&focused_ec_mutex);
5288 zone = e_comp_zone_find_by_ec(ec);
5292 e_client_urgent_set(ec, 0);
5293 int x, total = zone->desk_x_count * zone->desk_y_count;
5295 for (x = 0; x < total; x++)
5297 E_Desk *desk = zone->desks[x];
5298 /* if there's any fullscreen non-parents on this desk, unfullscreen them */
5299 EINA_LIST_FOREACH_SAFE(desk->fullscreen_clients, l, ll, ec2)
5301 if (ec2 == ec) continue;
5302 if (e_object_is_del(E_OBJECT(ec2))) continue;
5303 /* but only if it's the same desk or one of the clients is sticky */
5304 if ((e_desk_has_ec(desk, ec)) || (ec->sticky || ec2->sticky))
5306 if (!eina_list_data_find(ec->transients, ec2))
5307 e_client_unfullscreen(ec2);
5313 while ((ec_unfocus) && (ec_unfocus->zone))
5315 ec_unfocus->want_focus = ec_unfocus->focused = 0;
5316 if (ec_unfocus->mouse.in && ec && (!e_client_util_is_popup(ec)) &&
5317 (e_config->focus_policy != E_FOCUS_CLICK))
5318 e_client_mouse_out(ec_unfocus, ec_unfocus->x - 1, ec_unfocus->y - 1);
5320 /* if there unfocus client is fullscreen and visible */
5321 if ((ec_unfocus->fullscreen) && (!ec_unfocus->iconic) && (!ec_unfocus->hidden) &&
5322 (ec_unfocus->zone == e_zone_current_get()) &&
5323 ((ec_unfocus->desk == e_desk_current_get(ec_unfocus->zone)) || (ec_unfocus->sticky)))
5325 Eina_Bool have_vis_child = EINA_FALSE;
5327 /* if any of its children are visible */
5328 EINA_LIST_FOREACH(ec_unfocus->transients, l, ec2)
5330 if ((ec2->zone == ec_unfocus->zone) &&
5331 ((ec2->desk == ec_unfocus->desk) ||
5332 (ec2->sticky) || (ec_unfocus->sticky)))
5334 have_vis_child = EINA_TRUE;
5338 /* if no children are visible, unfullscreen */
5339 if ((!e_object_is_del(E_OBJECT(ec_unfocus))) && (!have_vis_child))
5340 e_client_unfullscreen(ec_unfocus);
5343 if (!e_object_is_del(E_OBJECT(ec_unfocus)))
5344 _e_client_hook_call(E_CLIENT_HOOK_FOCUS_UNSET, ec_unfocus);
5345 /* only send event here if we're not being deleted */
5346 if ((!e_object_is_del(E_OBJECT(ec_unfocus))) &&
5347 (e_object_ref_get(E_OBJECT(ec_unfocus)) > 0))
5349 _e_client_event_simple(ec_unfocus, E_EVENT_CLIENT_FOCUS_OUT);
5350 e_client_urgent_set(ec_unfocus, ec_unfocus->icccm.urgent);
5353 e_client_focus_defer_unset(ec_unfocus);
5362 _e_client_hook_call(E_CLIENT_HOOK_FOCUS_SET, ec);
5364 e_client_focus_latest_set(ec);
5366 _e_client_event_simple(ec, E_EVENT_CLIENT_FOCUS_IN);
5368 #ifdef REFACTOR_ZONE_DESK
5370 if (ec->sticky && ec->desk && (!ec->desk->visible))
5371 e_client_desk_set(ec, e_desk_current_get(zone));
5379 e_client_activate(E_Client *ec)
5382 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5384 TRACE_DS_BEGIN(CLIENT:ACTIVATE);
5386 ELOGF("COMP", "Set launching flag..", ec);
5387 ec->launching = EINA_TRUE;
5389 ec->exp_iconify.not_raise = 0;
5393 if (!ec->lock_user_iconify)
5394 e_client_uniconify(ec);
5396 ELOGF("COMP", "Un-Set ICONIFY BY CLIENT", ec);
5397 ec->exp_iconify.by_client = 0;
5398 e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_NONE);
5400 #ifdef REFACTOR_ZONE_DESK
5402 if ((!ec->iconic) && (!ec->sticky))
5404 e_desk_show(ec->desk);
5406 if (!ec->lock_user_stacking)
5408 if (ec->shaded || ec->shading)
5409 e_client_unshade(ec, ec->shade_dir);
5412 #ifdef REFACTOR_FOCUS_POLICY
5413 // This code will be executed at E_CLIENT_HOOK_ACTIVATE_DONE callback at e_focus_policy_history.c
5415 if (!ec->lock_focus_out)
5417 E_Client *focus_ec = NULL;
5418 E_Client *obscured_above = NULL;
5421 focus_ec = e_client_transient_child_top_get(ec, EINA_TRUE);
5427 e_client_focus_latest_set(ec);
5428 e_client_focus_latest_set(focus_ec);
5429 e_client_focus_defer_unset(ec);
5432 obscured_above = e_client_check_fully_contain_by_above(focus_ec, EINA_FALSE);
5433 if (!obscured_above)
5435 if (!e_policy_visibility_client_is_uniconic(ec))
5437 e_client_focus_defer_set(focus_ec);
5438 e_client_focus_latest_set(focus_ec);
5442 if (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK)
5444 ELOGF("FOCUS", "focus set | client activate", focus_ec);
5445 e_client_frame_focus_set(focus_ec, EINA_TRUE);
5451 e_client_focus_defer_set(focus_ec);
5452 e_client_focus_latest_set(focus_ec);
5457 #ifdef REFACTOR_ZONE_DESK
5459 if (!e_client_desk_iconify_skip_get(ec))
5461 e_desk_visible_client_iconified_list_remove_all(ec->desk);
5465 _e_client_hook_call(E_CLIENT_HOOK_ACTIVATE_DONE, ec);
5471 e_client_focused_get(void)
5473 #ifdef REFACTOR_FOCUS_POLICY
5474 return e_comp_focused_ec_get();
5476 E_Client *focused_ec = NULL;
5478 g_mutex_lock(&focused_ec_mutex);
5479 focused_ec = focused;
5480 g_mutex_unlock(&focused_ec_mutex);
5486 #ifdef REFACTOR_FOCUS_POLICY
5489 e_client_focus_stack_get(void)
5495 e_client_defer_focus_stack_get(void)
5497 return defer_focus_stack;
5501 e_client_focus_stack_set(Eina_List *l)
5507 e_client_focus_stack_clear(void)
5509 if (!focus_stack) return;
5511 focus_stack = eina_list_free(focus_stack);
5516 e_client_lost_windows_get(E_Zone *zone)
5518 Eina_List *list = NULL;
5521 int loss_overlap = 5;
5523 E_OBJECT_CHECK_RETURN(zone, NULL);
5524 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
5525 EINA_LIST_FOREACH(e_comp->clients, l, ec)
5527 if (!e_zone_has_ec(zone, ec)) continue;
5528 if (e_client_util_ignored_get(ec)) continue;
5530 if (!E_INTERSECTS(zone->x + loss_overlap,
5531 zone->y + loss_overlap,
5532 zone->w - (2 * loss_overlap),
5533 zone->h - (2 * loss_overlap),
5534 ec->x, ec->y, ec->w, ec->h))
5536 list = eina_list_append(list, ec);
5542 ///////////////////////////////////////
5545 e_client_shade(E_Client *ec, E_Direction dir)
5548 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5549 if ((ec->shaded) || (ec->shading) || (ec->fullscreen) ||
5550 ((ec->maximized) && (!e_config->allow_manip))) return;
5551 if (!e_util_strcmp("borderless", ec->bordername)) return;
5552 if (!e_comp_object_frame_allowed(ec->frame)) return;
5556 ec->shade_dir = dir;
5558 evas_object_smart_callback_call(ec->frame, "shaded", (uintptr_t*)dir);
5562 e_client_unshade(E_Client *ec, E_Direction dir)
5565 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5566 if ((!ec->shaded) || (ec->shading))
5572 evas_object_smart_callback_call(ec->frame, "unshaded", (uintptr_t*)dir);
5575 ///////////////////////////////////////
5578 e_client_maximized_geometry_set(E_Client *ec, int x, int y, int w, int h)
5582 ec->maximized_info.x = x;
5583 ec->maximized_info.y = y;
5584 ec->maximized_info.w = w;
5585 ec->maximized_info.h = h;
5587 e_client_frame_geometry_set(ec, x, y, w, h);
5591 e_client_maximized_geometry_get(E_Client *ec, int *x, int *y, int *w, int *h)
5595 if (x) *x = ec->maximized_info.x;
5596 if (y) *y = ec->maximized_info.y;
5597 if (w) *w = ec->maximized_info.w;
5598 if (h) *h = ec->maximized_info.h;
5602 e_client_maximize_update(E_Client *ec)
5607 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5611 max = ec->maximized;
5613 e_client_maximize(ec, max);
5618 e_client_maximize(E_Client *ec, E_Maximize max)
5620 #ifdef REFACTOR_ZONE_DESK
5622 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5624 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
5626 if ((ec->shaded) || (ec->shading)) return;
5628 if ((ec->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION))
5630 if ((ec->maximized & E_MAXIMIZE_TYPE) == (max & E_MAXIMIZE_TYPE))
5636 ec->changes.need_maximize = 1;
5637 ec->maximized &= ~E_MAXIMIZE_TYPE;
5638 ec->maximized |= max;
5643 // store the E_Maximize value requested
5644 ec->requested_max = max;
5646 // call the maximize hook of a client
5647 _e_client_hook_call(E_CLIENT_HOOK_MAXIMIZE, ec);
5649 // clear the E_Maximize value requested
5650 ec->requested_max = E_MAXIMIZE_NONE;
5652 // store the E_Maximize value
5653 ec->maximized = max;
5654 ec->changes.need_unmaximize = 0;
5656 evas_object_smart_callback_call(ec->frame, "maximize_done", NULL);
5662 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5664 zone = e_comp_zone_find_by_ec(ec);
5666 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
5668 if ((ec->shaded) || (ec->shading)) return;
5670 if ((ec->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION))
5672 if ((ec->maximized & E_MAXIMIZE_TYPE) == (max & E_MAXIMIZE_TYPE))
5678 ec->changes.need_maximize = 1;
5679 ec->maximized &= ~E_MAXIMIZE_TYPE;
5680 ec->maximized |= max;
5685 if (ec->desk_area.enable && ec->desk_area.desk_area)
5687 desk_x = ec->desk_area.desk_area->x;
5688 desk_y = ec->desk_area.desk_area->y;
5692 desk_x = ec->desk->geom.x;
5693 desk_y = ec->desk->geom.y;
5696 evas_object_smart_callback_call(ec->frame, "maximize_pre", NULL);
5699 e_client_unfullscreen(ec);
5700 ec->pre_res_change.valid = 0;
5701 if (!(ec->maximized & E_MAXIMIZE_HORIZONTAL))
5703 /* Horizontal hasn't been set */
5704 ec->saved.x = ec->client.x - desk_x;
5705 ec->saved.w = ec->client.w;
5707 if (!(ec->maximized & E_MAXIMIZE_VERTICAL))
5709 /* Vertical hasn't been set */
5710 ec->saved.y = ec->client.y - desk_y;
5711 ec->saved.h = ec->client.h;
5714 ec->saved.zone = zone->num;
5716 _e_client_maximize(ec, max);
5718 ec->maximized = max;
5719 ec->changes.need_unmaximize = 0;
5721 evas_object_smart_callback_call(ec->frame, "maximize_done", NULL);
5726 e_client_unmaximize(E_Client *ec, E_Maximize max)
5728 #ifdef REFACTOR_ZONE_DESK
5730 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5732 if (!(max & E_MAXIMIZE_DIRECTION))
5734 CRI("BUG: Unmaximize call without direction!");
5739 ec->changes.need_unmaximize = 1;
5744 if ((ec->shaded) || (ec->shading)) return;
5746 /* Remove directions not used */
5747 max &= (ec->maximized & E_MAXIMIZE_DIRECTION);
5748 /* Can only remove existing maximization directions */
5751 evas_object_smart_callback_call(ec->frame, "unmaximize_pre", NULL);
5753 // store the E_Maximize value requested
5754 ec->requested_max = max;
5756 // call the unmaximize hook of a client
5757 _e_client_hook_call(E_CLIENT_HOOK_UNMAXIMIZE, ec);
5759 // clear the E_Maximize value requested
5760 ec->requested_max = E_MAXIMIZE_NONE;
5762 evas_object_smart_callback_call(ec->frame, "unmaximize_done", NULL);
5763 ec->changes.need_unmaximize = 0;
5768 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5770 zone = e_comp_zone_find_by_ec(ec);
5772 if (!(max & E_MAXIMIZE_DIRECTION))
5774 CRI("BUG: Unmaximize call without direction!");
5779 ec->changes.need_unmaximize = 1;
5784 if ((ec->shaded) || (ec->shading)) return;
5786 /* Remove directions not used */
5787 max &= (ec->maximized & E_MAXIMIZE_DIRECTION);
5788 /* Can only remove existing maximization directions */
5791 evas_object_smart_callback_call(ec->frame, "unmaximize_pre", NULL);
5793 if (ec->maximized & E_MAXIMIZE_TYPE)
5795 ec->pre_res_change.valid = 0;
5796 ec->changes.need_maximize = 0;
5798 if ((ec->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
5800 E_Maximize tmp_max = ec->maximized;
5802 //un-set maximized state for updating frame.
5803 ec->maximized = E_MAXIMIZE_NONE;
5804 _e_client_frame_update(ec);
5805 // re-set maximized state for unmaximize smart callback.
5806 ec->maximized = tmp_max;
5807 evas_object_smart_callback_call(ec->frame, "unfullscreen", NULL);
5808 // un-set maximized state.
5809 ec->maximized = E_MAXIMIZE_NONE;
5810 e_client_util_move_resize_without_frame(ec,
5811 ec->saved.x + zone->x,
5812 ec->saved.y + zone->y,
5813 ec->saved.w, ec->saved.h);
5814 ec->saved.x = ec->saved.y = ec->saved.w = ec->saved.h = 0;
5819 Eina_Bool horiz = EINA_FALSE, vert = EINA_FALSE;
5826 if (max & E_MAXIMIZE_VERTICAL)
5828 /* Remove vertical */
5831 y = ec->saved.y + zone->y;
5832 if ((max & E_MAXIMIZE_VERTICAL) == E_MAXIMIZE_VERTICAL)
5834 ec->maximized &= ~E_MAXIMIZE_VERTICAL;
5835 ec->maximized &= ~E_MAXIMIZE_LEFT;
5836 ec->maximized &= ~E_MAXIMIZE_RIGHT;
5838 if ((max & E_MAXIMIZE_LEFT) == E_MAXIMIZE_LEFT)
5839 ec->maximized &= ~E_MAXIMIZE_LEFT;
5840 if ((max & E_MAXIMIZE_RIGHT) == E_MAXIMIZE_RIGHT)
5841 ec->maximized &= ~E_MAXIMIZE_RIGHT;
5843 if (max & E_MAXIMIZE_HORIZONTAL)
5845 /* Remove horizontal */
5847 x = ec->saved.x + zone->x;
5849 ec->maximized &= ~E_MAXIMIZE_HORIZONTAL;
5852 if (!(ec->maximized & E_MAXIMIZE_DIRECTION))
5854 ec->maximized = E_MAXIMIZE_NONE;
5855 _e_client_frame_update(ec);
5856 evas_object_smart_callback_call(ec->frame, "unmaximize", NULL);
5857 e_client_resize_limit(ec, &w, &h);
5858 e_client_pos_set(ec, x, y);
5859 if ((ec->saved.w != 0) && (ec->saved.h != 0))
5861 if ((w != ec->saved.w) || (h != ec->saved.h))
5863 e_policy_visibility_client_defer_move(ec);
5869 evas_object_smart_callback_call(ec->frame, "unmaximize", NULL);
5870 e_client_resize_limit(ec, &w, &h);
5871 e_client_pos_set(ec, x, y);
5872 if ((ec->saved.w != 0) && (ec->saved.h != 0))
5874 if ((w != ec->saved.w) || (h != ec->saved.h))
5876 e_policy_visibility_client_defer_move(ec);
5881 ec->saved.h = ec->saved.y = 0;
5883 ec->saved.w = ec->saved.x = 0;
5886 evas_object_smart_callback_call(ec->frame, "unmaximize_done", NULL);
5887 ec->changes.need_unmaximize = 0;
5892 e_client_fullscreen(E_Client *ec, E_Fullscreen policy)
5894 #ifdef REFACTOR_ZONE_DESK
5896 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5898 if ((ec->shaded) || (ec->shading) || (ec->fullscreen)) return;
5900 // call the fullscreen_pre hook of a client
5901 _e_client_hook_call(E_CLIENT_HOOK_FULLSCREEN_PRE, ec);
5903 ec->fullscreen_policy = policy;
5905 // call the fullscreen hook of a client
5906 _e_client_hook_call(E_CLIENT_HOOK_FULLSCREEN, ec);
5908 _e_client_event_simple(ec, E_EVENT_CLIENT_FULLSCREEN);
5914 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5916 zone = e_comp_zone_find_by_ec(ec);
5919 if ((ec->shaded) || (ec->shading) || (ec->fullscreen)) return;
5921 _e_client_hook_call(E_CLIENT_HOOK_FULLSCREEN_PRE, ec);
5923 if (ec->skip_fullscreen) return;
5924 if (!ec->desk->visible) return;
5927 ec->need_fullscreen = 1;
5930 if (e_comp->nocomp_ec && (ec->desk == e_comp->nocomp_ec->desk))
5931 e_comp->nocomp_ec = ec;
5932 ec->desk->fullscreen_clients = eina_list_append(ec->desk->fullscreen_clients, ec);
5933 ec->pre_res_change.valid = 0;
5944 ec->saved.x = ec->client.x - zone->x;
5945 ec->saved.y = ec->client.y - zone->y;
5946 ec->saved.w = ec->client.w;
5947 ec->saved.h = ec->client.h;
5949 ec->saved.maximized = ec->maximized;
5950 ec->saved.zone = zone->num;
5954 e_client_unmaximize(ec, E_MAXIMIZE_BOTH);
5961 ec->saved.layer = ec->layer;
5962 e_client_layer_set(ec, E_LAYER_CLIENT_FULLSCREEN);
5965 if ((eina_list_count(e_comp->zones) > 1) ||
5966 (policy == E_FULLSCREEN_RESIZE))
5968 e_client_frame_geometry_set(ec, zone->x, zone->y, zone->w, zone->h);
5970 else if (policy == E_FULLSCREEN_ZOOM)
5972 /* compositor backends! */
5973 evas_object_smart_callback_call(ec->frame, "fullscreen_zoom", NULL);
5976 if (!e_client_util_ignored_get(ec))
5977 _e_client_frame_update(ec);
5978 ec->fullscreen_policy = policy;
5979 evas_object_smart_callback_call(ec->frame, "fullscreen", NULL);
5981 _e_client_event_simple(ec, E_EVENT_CLIENT_FULLSCREEN);
5986 e_client_unfullscreen(E_Client *ec)
5988 #ifdef REFACTOR_ZONE_DESK
5990 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
5992 if ((ec->shaded) || (ec->shading)) return;
5993 if (!ec->fullscreen) return;
5995 // call the unfullscreen hook of a client
5996 _e_client_hook_call(E_CLIENT_HOOK_UNFULLSCREEN, ec);
5998 _e_client_event_simple(ec, E_EVENT_CLIENT_UNFULLSCREEN);
6003 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6005 zone = e_comp_zone_find_by_ec(ec);
6007 if ((ec->shaded) || (ec->shading)) return;
6008 if (!ec->fullscreen) return;
6009 ec->pre_res_change.valid = 0;
6011 ec->need_fullscreen = 0;
6012 ec->desk->fullscreen_clients = eina_list_remove(ec->desk->fullscreen_clients, ec);
6014 if (ec->fullscreen_policy == E_FULLSCREEN_ZOOM)
6015 evas_object_smart_callback_call(ec->frame, "unfullscreen_zoom", NULL);
6017 if (!e_client_util_ignored_get(ec))
6018 _e_client_frame_update(ec);
6019 ec->fullscreen_policy = 0;
6020 evas_object_smart_callback_call(ec->frame, "unfullscreen", NULL);
6021 e_client_util_move_resize_without_frame(ec, zone->x + ec->saved.x,
6022 zone->y + ec->saved.y,
6023 ec->saved.w, ec->saved.h);
6025 if (ec->saved.maximized)
6026 e_client_maximize(ec, (e_config->maximize_policy & E_MAXIMIZE_TYPE) |
6027 ec->saved.maximized);
6029 e_client_layer_set(ec, ec->saved.layer);
6031 _e_client_event_simple(ec, E_EVENT_CLIENT_UNFULLSCREEN);
6033 if (!ec->desk->fullscreen_clients)
6034 e_comp_render_queue();
6038 ///////////////////////////////////////
6039 #ifdef REFACTOR_ZONE_DESK
6041 e_client_is_parent_iconify_by_client(E_Client *ec)
6044 _e_client_is_parent_iconify_by_client(E_Client *ec)
6047 E_Client *parent = ec->parent;
6048 if (!parent) return EINA_FALSE;
6050 if ((parent->exp_iconify.type == E_ICONIFIED_TYPE_ICONIFY_BY_CLIENT) ||
6051 (parent->exp_iconify.type == E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT))
6058 e_client_iconify(E_Client *ec)
6061 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6063 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
6064 Eina_Bool iconified_by_client = e_client_is_iconified_by_client(ec);
6066 ELOGF("TZVIS", "ICONIFY |iconic:%d |argb:%d |not_raise:%d |by_client:%d, type:%d",
6067 ec, ec->iconic, ec->argb, (unsigned int)ec->exp_iconify.not_raise,
6068 ec->exp_iconify.by_client, ec->exp_iconify.type);
6070 if (ec->shading || ec->iconic) return;
6071 if (ec->exp_iconify.skip_iconify && !iconified_by_client) return;
6072 if (ec->exp_iconify.skip_by_remote) return;
6073 if (!cdata || !cdata->mapped)
6075 if (!iconified_by_client)
6077 ELOGF("TZVIS", "Not mapped.. So, don't iconify", ec);
6082 ELOGF("TZVIS", "Not mapped.. But, iconify by user request", ec);
6086 TRACE_DS_BEGIN(CLIENT:ICONIFY);
6088 #ifdef REFACTOR_ZONE_DESK
6090 e_comp_wl_remote_surface_image_save(ec);
6093 ec->want_focus = ec->take_focus = 0;
6094 ec->changes.visible = 0;
6096 ec->desk->fullscreen_clients = eina_list_remove(ec->desk->fullscreen_clients, ec);
6097 e_client_comp_hidden_set(ec, 1);
6098 evas_object_hide(ec->frame);
6099 e_client_urgent_set(ec, ec->icccm.urgent);
6101 _e_client_event_simple(ec, E_EVENT_CLIENT_ICONIFY);
6103 if (e_config->transient.iconify)
6106 Eina_List *list = eina_list_clone(ec->transients);
6108 EINA_LIST_FREE(list, child)
6110 if ((child->exp_iconify.type != E_ICONIFIED_TYPE_ICONIFY_BY_CLIENT) &&
6111 (_e_client_is_parent_iconify_by_client(child)))
6113 e_client_iconified_type_set(child, E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT);
6114 child->exp_iconify.by_client = 1;
6115 e_policy_client_iconic_state_change_send(child, 1);
6117 e_client_iconify(child);
6123 _e_client_hook_call(E_CLIENT_HOOK_ICONIFY, ec);
6129 e_client_uniconify(E_Client *ec)
6131 #ifdef REFACTOR_ZONE_DESK
6132 E_Comp_Wl_Client_Data *cdata;
6135 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6137 cdata = e_client_cdata_get(ec);
6139 ELOGF("TZVIS", "UNICONIFY|iconic:%d |argb:%d |not_raise:%d |by_client:%d, type:%d |mapped:%d",
6140 ec, ec->iconic, ec->argb, (unsigned int)ec->exp_iconify.not_raise,
6141 ec->exp_iconify.by_client, ec->exp_iconify.type,
6142 cdata ? cdata->mapped : 0);
6144 if (ec->shading || (!ec->iconic)) return;
6146 TRACE_DS_BEGIN(CLIENT:UNICONIFY);
6148 // call the uniconify hook of a client
6149 _e_client_hook_call(E_CLIENT_HOOK_UNICONIFY, ec);
6154 Eina_Bool not_raise;
6157 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6159 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
6161 ELOGF("TZVIS", "UNICONIFY|iconic:%d |argb:%d |not_raise:%d |by_client:%d, type:%d |mapped:%d",
6162 ec, ec->iconic, ec->argb, (unsigned int)ec->exp_iconify.not_raise,
6163 ec->exp_iconify.by_client, ec->exp_iconify.type,
6164 cdata ? cdata->mapped : 0);
6166 if (ec->shading || (!ec->iconic)) return;
6168 TRACE_DS_BEGIN(CLIENT:UNICONIFY);
6170 e_comp_wl_remote_surface_image_save_cancel(ec);
6172 desk = e_desk_current_get(ec->desk->zone);
6173 e_client_desk_set(ec, desk);
6174 not_raise = ec->exp_iconify.not_raise;
6176 ec->exp_iconify.by_client = 0;
6177 e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_NONE);
6179 if (e_config->transient.iconify)
6182 Eina_List *list = eina_list_clone(ec->transients);
6184 EINA_LIST_FREE(list, child)
6186 if (e_client_transient_policy_get(child) == E_TRANSIENT_BELOW)
6188 child->exp_iconify.not_raise = not_raise;
6189 e_client_uniconify(child);
6199 ELOGF("TZVIS", "UNICONIFY|internal object force show", ec);
6200 evas_object_show(ec->frame);
6205 if (e_pixmap_usable_get(ec->pixmap))
6207 if (cdata && cdata->mapped)
6209 ELOGF("TZVIS", "UNICONIFY|object show. frame_visible:%d", ec, evas_object_visible_get(ec->frame));
6210 evas_object_show(ec->frame);
6214 ELOGF("TZVIS", "UNICONIFY|object no show. currently unmapped", ec);
6219 if (!ec->exp_iconify.buffer_flush &&
6220 !ec->exp_iconify.deiconify_update)
6222 if (cdata && cdata->mapped)
6224 ELOGF("TZVIS", "UNICONIFY|object show. no use buffer flush. frame_visible:%d", ec, evas_object_visible_get(ec->frame));
6225 evas_object_show(ec->frame);
6230 e_client_comp_hidden_set(ec, 0);
6231 ec->deskshow = ec->iconic = 0;
6233 #if 0 // focus should be set to the top window not uniconify window
6234 if (ec->pixmap && e_pixmap_usable_get(ec->pixmap))
6235 e_client_frame_focus_set(ec, EINA_TRUE);
6238 _e_client_event_simple(ec, E_EVENT_CLIENT_UNICONIFY);
6240 if (e_config->transient.iconify)
6243 Eina_List *list = eina_list_clone(ec->transients);
6245 EINA_LIST_FREE(list, child)
6247 if (e_client_transient_policy_get(child) == E_TRANSIENT_ABOVE)
6249 if (child->exp_iconify.type == E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT)
6250 e_policy_client_iconic_state_change_send(child, 0);
6251 child->exp_iconify.not_raise = not_raise;
6252 e_client_uniconify(child);
6257 _e_client_hook_call(E_CLIENT_HOOK_UNICONIFY, ec);
6259 ec->exp_iconify.not_raise = 0;
6266 e_client_iconified_type_set(E_Client *ec, E_Iconified_Type type)
6269 ec->exp_iconify.type = type;
6272 EINTERN E_Iconified_Type
6273 e_client_iconified_type_get(E_Client *ec)
6275 if (!ec) return E_ICONIFIED_TYPE_NONE;
6276 return ec->exp_iconify.type;
6279 E_API Eina_Bool e_client_is_iconified_by_client(E_Client *ec)
6281 if (!ec) return EINA_FALSE;
6283 if (ec->exp_iconify.type == E_ICONIFIED_TYPE_ICONIFY_BY_CLIENT)
6286 if (ec->exp_iconify.type == E_ICONIFIED_TYPE_DESK_ICONIFY_BY_CLIENT)
6289 if (ec->exp_iconify.type == E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT)
6292 if (ec->exp_iconify.by_client)
6294 ELOGF("POL", "CHECK. mismatch value. by_client:%d, type:%d", ec, ec->exp_iconify.by_client, ec->exp_iconify.type);
6301 ///////////////////////////////////////
6304 e_client_urgent_set(E_Client *ec, Eina_Bool urgent)
6307 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6310 if (urgent == ec->urgent) return;
6311 _e_client_event_property(ec, E_CLIENT_PROPERTY_URGENCY);
6312 if (urgent && (!ec->focused) && (!ec->want_focus))
6314 e_comp_object_signal_emit(ec->frame, "e,state,urgent", "e");
6315 ec->urgent = urgent;
6319 e_comp_object_signal_emit(ec->frame, "e,state,not_urgent", "e");
6324 ///////////////////////////////////////
6327 e_client_stick(E_Client *ec)
6329 #ifdef REFACTOR_ZONE_DESK
6331 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6332 if (ec->sticky) return;
6334 // call the stick hook of a client
6335 _e_client_hook_call(E_CLIENT_HOOK_STICK, ec);
6337 // send the sticky property event of a client
6338 _e_client_event_property(ec, E_CLIENT_PROPERTY_STICKY);
6343 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6344 if (ec->sticky) return;
6349 e_client_desk_set(ec, desk);
6350 evas_object_smart_callback_call(ec->frame, "stick", NULL);
6352 if (e_config->transient.desktop)
6355 Eina_List *list = eina_list_clone(ec->transients);
6357 EINA_LIST_FREE(list, child)
6360 evas_object_show(ec->frame);
6364 _e_client_event_property(ec, E_CLIENT_PROPERTY_STICKY);
6369 e_client_unstick(E_Client *ec)
6371 #ifdef REFACTOR_ZONE_DESK
6373 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6375 if (!ec->sticky) return;
6377 // call the unstick hook of a client
6378 _e_client_hook_call(E_CLIENT_HOOK_UNSTICK, ec);
6380 // send the sticky property event of a client
6381 _e_client_event_property(ec, E_CLIENT_PROPERTY_STICKY);
6387 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6388 /* Set the desk before we unstick the client */
6389 if (!ec->sticky) return;
6391 zone = e_comp_zone_find_by_ec(ec);
6392 desk = e_desk_current_get(zone);
6394 ec->hidden = ec->sticky = 0;
6395 e_client_desk_set(ec, desk);
6396 evas_object_smart_callback_call(ec->frame, "unstick", NULL);
6398 if (e_config->transient.desktop)
6401 Eina_List *list = eina_list_clone(ec->transients);
6403 EINA_LIST_FREE(list, child)
6409 _e_client_event_property(ec, E_CLIENT_PROPERTY_STICKY);
6411 e_client_desk_set(ec, e_desk_current_get(zone));
6416 e_client_pinned_set(E_Client *ec, Eina_Bool set)
6420 EINA_SAFETY_ON_NULL_RETURN(ec);
6422 layer = E_LAYER_CLIENT_ABOVE;
6424 layer = E_LAYER_CLIENT_NORMAL;
6426 e_client_layer_set(ec, layer);
6431 ///////////////////////////////////////
6434 e_client_border_set(E_Client *ec, const char *name)
6436 Eina_Stringshare *pborder;
6438 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
6439 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
6440 if (!e_comp_object_frame_allowed(ec->frame)) return EINA_FALSE;
6441 if (ec->border.changed)
6442 CRI("CALLING WHEN border.changed SET!");
6444 if (!e_util_strcmp(ec->border.name, name)) return EINA_TRUE;
6445 if (ec->mwm.borderless && name && strcmp(name, "borderless"))
6447 CRI("border change attempted for MWM borderless client!");
6449 pborder = ec->border.name;
6450 ec->border.name = eina_stringshare_add(name);
6451 if (e_comp_object_frame_theme_set(ec->frame, name))
6453 eina_stringshare_del(pborder);
6456 eina_stringshare_del(ec->border.name);
6457 ec->border.name = pborder;
6461 ///////////////////////////////////////
6464 e_client_comp_hidden_set(E_Client *ec, Eina_Bool hidden)
6467 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6470 if (ec->comp_hidden == hidden) return;
6471 ec->comp_hidden = hidden;
6472 evas_object_smart_callback_call(ec->frame, "comp_hidden", NULL);
6475 ///////////////////////////////////////
6478 e_client_act_move_keyboard(E_Client *ec)
6480 EINA_SAFETY_ON_NULL_RETURN(ec);
6482 if (!_e_client_move_begin(ec))
6485 _e_client_action_init(ec);
6486 _e_client_action_move_timeout_add();
6487 if (!_e_client_hook_call(E_CLIENT_HOOK_MOVE_UPDATE, ec)) return;
6488 evas_object_freeze_events_set(ec->frame, 1);
6490 if (!action_handler_mouse)
6491 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_client_move_mouse_down, NULL);
6495 e_client_act_resize_keyboard(E_Client *ec)
6497 EINA_SAFETY_ON_NULL_RETURN(ec);
6499 ec->resize_mode = E_POINTER_RESIZE_TL;
6500 ec->keyboard_resizing = 1;
6501 if (!e_client_resize_begin(ec))
6503 ec->keyboard_resizing = 0;
6507 _e_client_action_init(ec);
6508 _e_client_action_resize_timeout_add();
6509 evas_object_freeze_events_set(ec->frame, 1);
6511 if (!action_handler_mouse)
6512 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_client_resize_mouse_down, NULL);
6516 e_client_act_move_begin(E_Client *ec, E_Binding_Event_Mouse_Button *ev)
6519 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6520 if (e_client_util_resizing_get(ec) || (ec->moving)) return;
6525 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->button);
6526 _e_client_moveinfo_gather(ec, source);
6528 if (!_e_client_move_begin(ec))
6531 _e_client_action_init(ec);
6535 e_client_act_move_end(E_Client *ec, E_Binding_Event_Mouse_Button *ev EINA_UNUSED)
6538 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6539 if (!ec->moving) return;
6540 _e_client_move_end(ec);
6541 _e_client_action_finish();
6545 e_client_act_resize_begin(E_Client *ec, E_Binding_Event_Mouse_Button *ev, E_Pointer_Mode resize_mode)
6548 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6549 if (ec->lock_user_size || ec->shaded || ec->shading) return;
6550 if (e_client_util_resizing_get(ec) || (ec->moving)) return;
6554 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->button);
6555 _e_client_moveinfo_gather(ec, source);
6557 if (resize_mode != E_POINTER_RESIZE_NONE)
6559 ec->resize_mode = resize_mode;
6563 /* Use canvas.x, canvas.y of event.
6564 * Transformed coordinates has to be considered for accurate resize_mode
6565 * rather than absolute coordinates. */
6566 if ((ev->canvas.x > (ec->x + ec->w / 5)) &&
6567 (ev->canvas.x < (ec->x + ec->w * 4 / 5)))
6569 if (ev->canvas.y < (ec->y + ec->h / 2)) ec->resize_mode = E_POINTER_RESIZE_T;
6570 else ec->resize_mode = E_POINTER_RESIZE_B;
6572 else if (ev->canvas.x < (ec->x + ec->w / 2))
6574 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;
6575 else if (ev->canvas.y < (ec->y + ec->h / 2)) ec->resize_mode = E_POINTER_RESIZE_TL;
6576 else ec->resize_mode = E_POINTER_RESIZE_BL;
6580 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;
6581 else if (ev->canvas.y < (ec->y + ec->h / 2)) ec->resize_mode = E_POINTER_RESIZE_TR;
6582 else ec->resize_mode = E_POINTER_RESIZE_BR;
6586 if (!e_client_resize_begin(ec))
6588 _e_client_action_init(ec);
6592 e_client_act_resize_end(E_Client *ec, E_Binding_Event_Mouse_Button *ev EINA_UNUSED)
6595 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6596 if (e_client_util_resizing_get(ec))
6598 _e_client_resize_end(ec);
6599 ec->changes.reset_gravity = 1;
6600 if (!e_object_is_del(E_OBJECT(ec)))
6603 _e_client_action_finish();
6607 e_client_act_menu_begin(E_Client *ec, E_Binding_Event_Mouse_Button *ev, int key)
6610 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6614 e_client_act_close_begin(E_Client *ec)
6617 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6618 if (ec->lock_close) return;
6619 if (ec->icccm.delete_request)
6621 ec->delete_requested = 1;
6622 evas_object_smart_callback_call(ec->frame, "delete_request", NULL);
6624 else if (e_config->kill_if_close_not_possible)
6626 e_client_act_kill_begin(ec);
6631 e_client_act_kill_begin(E_Client *ec)
6634 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6635 if (ec->internal) return;
6636 if (ec->lock_close) return;
6637 if ((ec->netwm.pid > 1) && (e_config->kill_process))
6639 kill(ec->netwm.pid, SIGINT);
6640 ec->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
6641 _e_client_cb_kill_timer, ec);
6644 evas_object_smart_callback_call(ec->frame, "kill_request", NULL);
6647 ////////////////////////////////////////////
6650 e_client_ping(E_Client *ec)
6653 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6655 if (!e_config->ping_clients) return;
6657 EINA_SAFETY_ON_TRUE_RETURN(e_object_is_del(E_OBJECT(ec)));
6660 evas_object_smart_callback_call(ec->frame, "ping", NULL);
6661 ec->ping = ecore_loop_time_get();
6662 if (ec->ping_poller) ecore_poller_del(ec->ping_poller);
6663 ec->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
6664 e_config->ping_clients_interval,
6665 _e_client_cb_ping_poller, ec);
6668 ////////////////////////////////////////////
6670 e_client_cursor_map_apply(E_Client *ec, int rotation, int x, int y)
6672 // TODO: remove(deprecate) this e_client_cursor_map_apply.
6676 e_client_move_cancel(void)
6678 if (!ecmove) return;
6679 if (ecmove->cur_mouse_action)
6684 e_object_ref(E_OBJECT(ec));
6685 if (ec->cur_mouse_action->func.end_mouse)
6686 ec->cur_mouse_action->func.end_mouse(E_OBJECT(ec), "", NULL);
6687 else if (ec->cur_mouse_action->func.end)
6688 ec->cur_mouse_action->func.end(E_OBJECT(ec), "");
6689 e_object_unref(E_OBJECT(ec->cur_mouse_action));
6690 ec->cur_mouse_action = NULL;
6691 e_object_unref(E_OBJECT(ec));
6694 _e_client_move_end(ecmove);
6698 e_client_resize_cancel(void)
6700 if (!ecresize) return;
6701 if (ecresize->cur_mouse_action)
6706 e_object_ref(E_OBJECT(ec));
6707 if (ec->cur_mouse_action->func.end_mouse)
6708 ec->cur_mouse_action->func.end_mouse(E_OBJECT(ec), "", NULL);
6709 else if (ec->cur_mouse_action->func.end)
6710 ec->cur_mouse_action->func.end(E_OBJECT(ec), "");
6711 e_object_unref(E_OBJECT(ec->cur_mouse_action));
6712 ec->cur_mouse_action = NULL;
6713 e_object_unref(E_OBJECT(ec));
6716 _e_client_resize_end(ecresize);
6720 e_client_resize_begin(E_Client *ec)
6722 if ((ec->shaded) || (ec->shading) ||
6723 (ec->fullscreen) || (ec->lock_user_size))
6725 if (!_e_client_action_input_win_new()) goto error;
6727 if (ec->manage_resize.enable_aspect_ratio)
6729 ELOGF("RESIZE", "Set resize aspect ratio.. ratio(%dx%d)", ec, ec->w, ec->h);
6730 ec->manage_resize.aw = ec->w;
6731 ec->manage_resize.ah = ec->h - ec->manage_resize.header_h - ec->manage_resize.footer_h;
6733 _e_client_hook_call(E_CLIENT_HOOK_RESIZE_BEGIN, ec);
6734 if (ec->transformed)
6735 _e_client_transform_resize_begin(ec);
6736 if (!e_client_util_resizing_get(ec))
6738 if (ecresize == ec) ecresize = NULL;
6739 _e_client_action_input_win_del();
6742 if (!ec->lock_user_stacking)
6744 if (e_config->border_raise_on_mouse_action)
6749 e_comp_client_override_add(ec);
6753 ec->resize_mode = E_POINTER_RESIZE_NONE;
6758 ////////////////////////////////////////////
6761 e_client_frame_recalc(E_Client *ec)
6763 EINA_SAFETY_ON_NULL_RETURN(ec);
6764 if (!ec->frame) return;
6765 evas_object_smart_callback_call(ec->frame, "frame_recalc", NULL);
6768 ////////////////////////////////////////////
6771 e_client_signal_move_begin(E_Client *ec, const char *sig, const char *src EINA_UNUSED)
6774 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6776 if (e_client_util_resizing_get(ec) || (ec->moving)) return;
6777 _e_client_moveinfo_gather(ec, sig);
6778 if (!_e_client_move_begin(ec)) return;
6782 e_client_signal_move_end(E_Client *ec, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
6785 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6786 if (!ec->moving) return;
6787 _e_client_move_end(ec);
6791 e_client_signal_resize_begin(E_Client *ec, const char *dir, const char *sig, const char *src EINA_UNUSED)
6793 int resize_mode = E_POINTER_RESIZE_BR;
6796 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6798 if (e_client_util_resizing_get(ec) || (ec->moving)) return;
6799 if (!strcmp(dir, "tl"))
6801 resize_mode = E_POINTER_RESIZE_TL;
6803 else if (!strcmp(dir, "t"))
6805 resize_mode = E_POINTER_RESIZE_T;
6807 else if (!strcmp(dir, "tr"))
6809 resize_mode = E_POINTER_RESIZE_TR;
6811 else if (!strcmp(dir, "r"))
6813 resize_mode = E_POINTER_RESIZE_R;
6815 else if (!strcmp(dir, "br"))
6817 resize_mode = E_POINTER_RESIZE_BR;
6819 else if (!strcmp(dir, "b"))
6821 resize_mode = E_POINTER_RESIZE_B;
6823 else if (!strcmp(dir, "bl"))
6825 resize_mode = E_POINTER_RESIZE_BL;
6827 else if (!strcmp(dir, "l"))
6829 resize_mode = E_POINTER_RESIZE_L;
6831 ec->resize_mode = resize_mode;
6832 _e_client_moveinfo_gather(ec, sig);
6833 if (!e_client_resize_begin(ec))
6838 e_client_signal_resize_end(E_Client *ec, const char *dir EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
6841 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6842 if (!e_client_util_resizing_get(ec)) return;
6843 _e_client_resize_handle(ec);
6844 _e_client_resize_end(ec);
6845 ec->changes.reset_gravity = 1;
6849 ////////////////////////////////////////////
6852 e_client_resize_limit(E_Client *ec, int *w, int *h)
6858 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
6860 inc_h = (*h - ec->h > 0);
6862 e_comp_object_frame_wh_unadjust(ec->frame, *w, *h, w, h);
6865 if ((ec->icccm.base_w >= 0) &&
6866 (ec->icccm.base_h >= 0))
6870 tw = *w - ec->icccm.base_w;
6871 th = *h - ec->icccm.base_h;
6874 a = (double)(tw) / (double)(th);
6875 if ((ec->icccm.min_aspect != 0.0) &&
6876 (a < ec->icccm.min_aspect))
6879 tw = th * ec->icccm.min_aspect;
6881 th = tw / ec->icccm.max_aspect;
6882 *w = tw + ec->icccm.base_w;
6883 *h = th + ec->icccm.base_h;
6885 else if ((ec->icccm.max_aspect != 0.0) &&
6886 (a > ec->icccm.max_aspect))
6888 tw = th * ec->icccm.max_aspect;
6889 *w = tw + ec->icccm.base_w;
6894 a = (double)*w / (double)*h;
6895 if ((ec->icccm.min_aspect != 0.0) &&
6896 (a < ec->icccm.min_aspect))
6899 *w = *h * ec->icccm.min_aspect;
6901 *h = *w / ec->icccm.min_aspect;
6903 else if ((ec->icccm.max_aspect != 0.0) &&
6904 (a > ec->icccm.max_aspect))
6905 *w = *h * ec->icccm.max_aspect;
6907 if (ec->icccm.step_w > 0)
6909 if (ec->icccm.base_w >= 0)
6910 *w = ec->icccm.base_w +
6911 (((*w - ec->icccm.base_w) / ec->icccm.step_w) *
6914 *w = ec->icccm.min_w +
6915 (((*w - ec->icccm.min_w) / ec->icccm.step_w) *
6918 if (ec->icccm.step_h > 0)
6920 if (ec->icccm.base_h >= 0)
6921 *h = ec->icccm.base_h +
6922 (((*h - ec->icccm.base_h) / ec->icccm.step_h) *
6925 *h = ec->icccm.min_h +
6926 (((*h - ec->icccm.min_h) / ec->icccm.step_h) *
6933 if ((ec->icccm.max_w > 0) && (*w > ec->icccm.max_w)) *w = ec->icccm.max_w;
6934 else if (*w < ec->icccm.min_w)
6935 *w = ec->icccm.min_w;
6936 if ((ec->icccm.max_h > 0) && (*h > ec->icccm.max_h)) *h = ec->icccm.max_h;
6937 else if (*h < ec->icccm.min_h)
6938 *h = ec->icccm.min_h;
6941 e_comp_object_frame_wh_adjust(ec->frame, *w, *h, w, h);
6944 ////////////////////////////////////////////
6949 e_client_under_pointer_get(E_Desk *desk, E_Client *exclude)
6953 /* We need to ensure that we can get the comp window for the
6954 * zone of either the given desk or the desk of the excluded
6955 * window, so return if neither is given */
6957 e_input_device_pointer_xy_get(NULL, &x, &y);
6959 e_input_device_pointer_xy_get(NULL, &x, &y);
6965 desk = exclude->desk;
6969 desk = e_desk_current_get(exclude->zone);
6971 desk = e_desk_current_get(e_zone_current_get());
6975 return desk ? _e_client_under_pointer_helper(desk, exclude, x, y) : NULL;
6978 E_API E_Client *e_client_under_position_get(E_Desk *desk, int x, int y, E_Client *exclude)
6980 if (!desk) return NULL;
6982 return _e_client_under_pointer_helper(desk, exclude, x, y);
6985 E_API E_Client *e_client_under_position_input_get(E_Desk *desk, int x, int y)
6987 if (!desk) return NULL;
6989 return _e_client_under_pointer_input_helper(desk, x, y);
6993 e_client_input_rect_under_pointer_get(E_Desk *desk, E_Client *exclude)
6997 /* We need to ensure that we can get the comp window for the
6998 * zone of either the given desk or the desk of the excluded
6999 * window, so return if neither is given */
7001 e_input_device_pointer_xy_get(NULL, &x, &y);
7003 e_input_device_pointer_xy_get(NULL, &x, &y);
7009 desk = exclude->desk;
7013 desk = e_desk_current_get(exclude->zone);
7015 desk = e_desk_current_get(e_zone_current_get());
7019 return desk ? _e_client_input_rect_under_pointer_helper(desk, exclude, x, y) : NULL;
7022 ////////////////////////////////////////////
7024 ////////////////////////////////////////////
7027 e_client_redirected_set(E_Client *ec, Eina_Bool set)
7029 EINA_SAFETY_ON_NULL_RETURN(ec);
7030 if (ec->input_only) return;
7032 if (ec->redirected == set) return;
7035 e_client_frame_recalc(ec);
7036 if (!_e_client_hook_call(E_CLIENT_HOOK_REDIRECT, ec)) return;
7040 if (!_e_client_hook_call(E_CLIENT_HOOK_UNREDIRECT, ec)) return;
7042 e_comp_object_redirected_set(ec->frame, set);
7043 ec->redirected = !!set;
7046 ////////////////////////////////////////////
7049 e_client_is_stacking(const E_Client *ec)
7051 return e_comp->layers[e_comp_canvas_layer_map(ec->layer)].obj == ec->frame;
7054 ////////////////////////////////////////////
7057 e_client_transform_update(E_Client *ec)
7059 if (e_client_util_resizing_get(ec))
7060 _e_client_transform_resize(ec);
7063 ////////////////////////////////////////////
7066 e_client_transform_apply(E_Client *ec, double angle, double zoom, int cx, int cy)
7069 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
7073 if (e_comp_wl_subsurface_check(ec))
7076 /* check if it's different with current state */
7077 if ((ec->transform.angle == angle) &&
7078 (ec->transform.zoom == zoom) &&
7079 (ec->transform.center.x == cx) &&
7080 (ec->transform.center.y == cy))
7083 /* use previous value if any required value is invalid */
7085 angle = ec->transform.angle;
7087 zoom = ec->transform.zoom;
7088 if (!E_INSIDE(cx, cy,
7089 ec->client.x, ec->client.y,
7090 ec->client.w, ec->client.h))
7092 cx = ec->transform.center.x;
7093 cy = ec->transform.center.y;
7096 if ((angle == 0) && (zoom == 1.0))
7098 e_client_transform_clear(ec);
7102 map = e_map_new_with_direct_render(ec->transform_core.direct_render);
7103 e_map_util_points_populate_from_object_full(map, ec->frame, 0);
7105 e_map_util_rotate(map, angle, cx, cy);
7106 _e_client_transform_geometry_save(ec, map);
7108 e_map_util_zoom(map, zoom, zoom, cx, cy);
7110 e_map_util_object_move_sync_set(map, EINA_TRUE);
7111 e_client_map_set(ec, map);
7112 e_client_map_enable_set(ec, EINA_TRUE);
7114 EINA_LIST_FOREACH(cdata->sub.list, l, subc)
7115 _e_client_transform_sub_apply(subc, ec, zoom);
7116 EINA_LIST_REVERSE_FOREACH(cdata->sub.below_list, l, subc)
7117 _e_client_transform_sub_apply(subc, ec, zoom);
7121 ec->transform.zoom = zoom;
7122 ec->transform.angle = angle;
7123 ec->transform.center.x = cx;
7124 ec->transform.center.y = cy;
7125 ec->transformed = EINA_TRUE;
7128 ////////////////////////////////////////////
7131 e_client_transform_clear(E_Client *ec)
7133 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
7137 e_client_map_enable_set(ec, EINA_FALSE);
7138 e_client_map_set(ec, NULL);
7140 EINA_LIST_FOREACH(cdata->sub.list, l, subc)
7141 _e_client_transform_sub_apply(subc, ec, 1.0);
7142 EINA_LIST_REVERSE_FOREACH(cdata->sub.below_list, l, subc)
7143 _e_client_transform_sub_apply(subc, ec, 1.0);
7145 ec->transform.zoom = 1.0;
7146 ec->transform.angle = 0.0;
7147 ec->transformed = EINA_FALSE;
7151 e_client_transform_core_enable_get(E_Client *ec)
7153 if (!ec) return EINA_FALSE;
7154 return ec->transform_core.result.enable;
7158 e_client_transform_core_add(E_Client *ec, E_Util_Transform *transform)
7161 if (!transform) return;
7163 // duplication check
7164 if (ec->transform_core.transform_list &&
7165 eina_list_data_find(ec->transform_core.transform_list, transform) == transform)
7170 ec->transform_core.transform_list = eina_list_append(ec->transform_core.transform_list, transform);
7171 ec->transform_core.changed = EINA_TRUE;
7172 e_util_transform_ref(transform);
7173 // e_client_transform_core_update(ec);
7177 e_client_transform_core_remove(E_Client *ec, E_Util_Transform *transform)
7180 if (!transform) return;
7182 if (ec->transform_core.transform_list &&
7183 eina_list_data_find(ec->transform_core.transform_list, transform) == transform)
7185 ec->transform_core.transform_list = eina_list_remove(ec->transform_core.transform_list, transform);
7186 e_util_transform_unref(transform);
7187 ec->transform_core.changed = EINA_TRUE;
7190 e_client_transform_core_update(ec);
7194 e_client_transform_core_update(E_Client *ec)
7197 if (ec->new_client) return;
7198 if (!_e_client_transform_core_check_change(ec)) return;
7199 if (!ec->transform_core.activate) return;
7201 if (ec->transform_core.transform_list || ec->transform_core.parent.enable)
7203 E_Util_Transform_Rect source_rect;
7204 E_Util_Transform_Matrix matrix, boundary_matrix;
7205 E_Util_Transform_Zoom zoom;
7207 Eina_Bool background;
7208 E_Util_Transform *temp_trans;
7211 ec->transform_core.result.enable = EINA_TRUE;
7212 e_util_transform_rect_client_rect_get(&source_rect, ec);
7213 e_util_transform_init(&ec->transform_core.result.transform);
7215 // 2. merge transform
7216 EINA_LIST_FOREACH(ec->transform_core.transform_list, l, temp_trans)
7218 e_util_transform_merge(&ec->transform_core.result.transform, temp_trans);
7220 zoom = ec->transform_core.result.transform.zoom;
7222 // 2.5 check viewport
7223 if (e_util_transform_viewport_flag_get(&ec->transform_core.result.transform))
7225 int vx = 0, vy = 0, vw = 0, vh = 0;
7226 e_util_transform_viewport_get(&ec->transform_core.result.transform, &vx, &vy, &vw, &vh);
7227 e_util_transform_rect_init(&source_rect, vx, vy, vw, vh);
7230 // 3. apply background transform
7231 matrix = e_util_transform_convert_to_matrix(&ec->transform_core.result.transform, &source_rect);
7233 if (e_util_transform_bg_transform_flag_get(&ec->transform_core.result.transform))
7235 boundary_matrix = e_util_transform_bg_convert_to_matrix(&ec->transform_core.result.transform, &source_rect);
7236 background = EINA_TRUE;
7240 background = EINA_FALSE;
7241 boundary_matrix = matrix;
7244 if (background != ec->transform_core.background)
7248 e_comp_object_transform_bg_set(ec->frame, EINA_TRUE);
7252 e_comp_object_transform_bg_set(ec->frame, EINA_FALSE);
7255 ec->transform_core.background = background;
7258 // 3.1 if 24bit window then set transp rect
7263 e_util_transform_rotation_round_get(&ec->transform_core.result.transform, 0, 0, &angle);
7266 if (angle == 0) // when transform angle is 0, 90, 180, 270, 360. then set transp rect
7267 e_comp_object_transform_transp_set(ec->frame, EINA_TRUE);
7269 e_comp_object_transform_transp_set(ec->frame, EINA_FALSE);
7272 e_comp_object_transform_transp_set(ec->frame, EINA_FALSE);
7274 // 3.5 parent matrix multiply
7275 if (ec->transform_core.parent.enable)
7277 matrix = e_util_transform_matrix_multiply(&ec->transform_core.parent.matrix,
7279 boundary_matrix = e_util_transform_matrix_multiply(&ec->transform_core.parent.matrix,
7282 ec->transform_core.result.transform.use_zoom = EINA_TRUE;
7283 zoom.zoom_x *= ec->transform_core.parent.zoom.zoom_x;
7284 zoom.zoom_y *= ec->transform_core.parent.zoom.zoom_y;
7285 zoom.cx += ec->transform_core.parent.zoom.cx;
7286 zoom.cy += ec->transform_core.parent.zoom.cy;
7289 // 4. apply matrix to vertices
7290 ec->transform_core.result.matrix = matrix;
7291 ec->transform_core.result.inv_matrix = e_util_transform_matrix_inverse_get(&matrix);
7292 ec->transform_core.result.vertices = e_util_transform_rect_to_vertices(&source_rect);
7293 ec->transform_core.result.boundary.vertices = e_util_transform_rect_to_vertices(&source_rect);
7294 ec->transform_core.result.vertices = e_util_transform_matrix_multiply_rect_vertex(&matrix,
7295 &ec->transform_core.result.vertices);
7296 ec->transform_core.result.boundary.vertices = e_util_transform_matrix_multiply_rect_vertex(&boundary_matrix,
7297 &ec->transform_core.result.boundary.vertices);
7298 ec->transform_core.result.transform.zoom = zoom;
7300 // 5. apply vertices
7301 if (ec->transform_core.result.transform.use_zoom)
7303 // TODO: apply zoom values to vertices
7304 e_comp_object_transform_transp_vertices_set_with_zoom(ec->frame, &ec->transform_core.result.vertices,
7305 ec->transform_core.result.transform.zoom);
7306 e_comp_object_transform_bg_vertices_set_with_zoom(ec->frame, &ec->transform_core.result.boundary.vertices,
7307 ec->transform_core.result.transform.zoom);
7308 _e_client_transform_core_boundary_update(ec, &ec->transform_core.result.boundary.vertices);
7309 _e_client_transform_core_vertices_apply_with_zoom(ec, ec->frame, &ec->transform_core.result.vertices, &ec->transform_core.result.transform,
7310 ec->transform_core.result.transform.zoom);
7314 e_comp_object_transform_transp_vertices_set(ec->frame, &ec->transform_core.result.vertices);
7315 e_comp_object_transform_bg_vertices_set(ec->frame, &ec->transform_core.result.boundary.vertices);
7316 _e_client_transform_core_boundary_update(ec, &ec->transform_core.result.boundary.vertices);
7317 _e_client_transform_core_vertices_apply(ec, ec->frame, &ec->transform_core.result.vertices, &ec->transform_core.result.transform);
7320 // 6. subsurface update
7321 _e_client_transform_core_sub_update(ec, &ec->transform_core.result.vertices);
7323 if (!e_object_is_del(E_OBJECT(ec)))
7324 _e_client_hook_call(E_CLIENT_HOOK_TRANSFORM_CHANGE, ec);
7328 if (ec->transform_core.result.enable)
7330 ec->transform_core.result.enable = EINA_FALSE;
7331 _e_client_transform_core_vertices_apply(ec, ec->frame, NULL, NULL);
7332 e_comp_object_transform_bg_set(ec->frame, EINA_FALSE);
7333 ec->transform_core.background = EINA_FALSE;
7334 e_comp_object_transform_transp_set(ec->frame, EINA_FALSE);
7335 _e_client_transform_core_sub_update(ec, NULL);
7337 if (!e_object_is_del(E_OBJECT(ec)))
7338 _e_client_hook_call(E_CLIENT_HOOK_TRANSFORM_CHANGE, ec);
7342 e_comp_visibility_calculation_set(EINA_TRUE);
7346 e_client_transform_core_transform_count_get(E_Client *ec)
7349 if (!ec->transform_core.transform_list) return 0;
7350 return eina_list_count(ec->transform_core.transform_list);
7353 E_API E_Util_Transform*
7354 e_client_transform_core_transform_get(E_Client *ec, int index)
7356 if (!ec) return NULL;
7357 if (!ec->transform_core.transform_list) return NULL;
7358 if (index < 0 || index >= e_client_transform_core_transform_count_get(ec))
7361 return (E_Util_Transform*)eina_list_nth(ec->transform_core.transform_list, index);
7365 e_client_transform_core_input_transform(E_Client *ec, int x, int y, int *out_x, int *out_y)
7367 E_Util_Transform_Vertex vertex, result_vertex;
7370 if (!e_client_transform_core_enable_get(ec)) return;
7372 e_util_transform_vertex_init(&vertex, x, y, 0.0, 1.0);
7374 result_vertex = e_util_transform_matrix_multiply_vertex(&ec->transform_core.result.inv_matrix, &vertex);
7375 e_util_transform_vertex_pos_round_get(&result_vertex, out_x, out_y, NULL, NULL);
7379 e_client_transform_core_input_inv_transform(E_Client *ec, int x, int y, int *out_x, int *out_y)
7381 E_Util_Transform_Vertex vertex, result_vertex;
7384 if (!e_client_transform_core_enable_get(ec)) return;
7386 e_util_transform_vertex_init(&vertex, x, y, 0.0, 1.0);
7388 result_vertex = e_util_transform_matrix_multiply_vertex(&ec->transform_core.result.matrix, &vertex);
7389 e_util_transform_vertex_pos_round_get(&result_vertex, out_x, out_y, NULL, NULL);
7393 e_client_transform_core_input_inv_rect_transform(E_Client *ec, int x, int y, int *out_x, int *out_y)
7397 if (!e_client_transform_core_enable_get(ec)) return;
7398 e_client_geometry_get(ec, NULL, NULL, &gw, &gh);
7400 e_util_transform_matrix_inv_rect_coords_get(&ec->transform_core.result.transform,
7401 &ec->transform_core.result.vertices,
7403 x, y, out_x, out_y);
7407 e_client_transform_core_direct_render_set(E_Client *ec, Eina_Bool set)
7409 EINA_SAFETY_ON_NULL_RETURN(ec);
7411 if (ec->transform_core.direct_render == set) return;
7413 ec->transform_core.direct_render = set;
7414 ec->transform_core.changed = EINA_TRUE;
7416 e_client_transform_core_update(ec);
7420 e_client_pixmap_change(E_Client *ec, E_Pixmap *newcp)
7422 E_Pixmap_Type oldtype, newtype;
7425 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
7426 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->pixmap, NULL);
7427 EINA_SAFETY_ON_NULL_RETURN_VAL(newcp, NULL);
7431 oldtype = e_pixmap_type_get(oldcp);
7432 if (oldtype >= E_PIXMAP_TYPE_MAX) return NULL;
7434 newtype = e_pixmap_type_get(newcp);
7435 if (newtype >= E_PIXMAP_TYPE_MAX) return NULL;
7437 if (eina_hash_find(clients_hash[oldtype], &oldcp))
7438 eina_hash_del_by_key(clients_hash[oldtype], &oldcp);
7439 e_pixmap_client_set(oldcp, NULL);
7442 e_pixmap_client_set(newcp, ec);
7444 eina_hash_add(clients_hash[newtype], &newcp, ec);
7450 e_client_window_role_set(E_Client *ec, const char *role)
7452 EINA_SAFETY_ON_NULL_RETURN(ec);
7454 if (eina_stringshare_replace(&ec->icccm.window_role, role))
7455 _e_client_hook_call(E_CLIENT_HOOK_WINDOW_ROLE_CHANGE, ec);
7459 e_client_key_send(E_Client *ec, int keycode, Eina_Bool pressed, Ecore_Device *dev, unsigned int time)
7463 res = e_comp_wl_key_send(ec, keycode, pressed, dev, time);
7469 e_client_key_cancel(E_Client *ec, int keycode, Ecore_Device *dev, unsigned int time)
7473 res = e_comp_wl_key_cancel(ec, keycode, dev, time);
7479 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)
7483 res = e_comp_wl_touch_send(ec, idx, x, y, pressed, dev, radius_x, radius_y, pressure, angle, time);
7489 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)
7493 res = e_comp_wl_touch_update_send(ec, idx, x, y, dev, radius_x, radius_y, pressure, angle, time);
7499 e_client_touch_cancel_send(E_Client *ec)
7503 res = e_comp_wl_touch_cancel_send(ec);
7509 e_client_mouse_button_send(E_Client *ec, int buttons, Eina_Bool pressed, Ecore_Device *dev, unsigned int time)
7513 res = e_comp_wl_mouse_button_send(ec, buttons, pressed, dev, time);
7519 e_client_mouse_move_send(E_Client *ec, int x, int y, Ecore_Device *dev, unsigned int time)
7523 res = e_comp_wl_mouse_move_send(ec, x, y, dev, time);
7529 e_client_mouse_wheel_send(E_Client *ec, int direction, int z, Ecore_Device *dev, unsigned int time)
7533 res = e_comp_wl_mouse_wheel_send(ec, direction, z, dev, time);
7539 e_client_mouse_in_send(E_Client *ec, int x, int y, Ecore_Device *dev, unsigned int time)
7543 res = e_comp_wl_mouse_in_send(ec, x, y, dev, time);
7549 e_client_mouse_out_send(E_Client *ec, Ecore_Device *dev, unsigned int time)
7553 res = e_comp_wl_mouse_out_send(ec, dev, time);
7559 e_client_video_client_has(E_Client *ec)
7561 return e_comp_wl_video_subsurface_has(ec);
7565 e_client_normal_client_has(E_Client *ec)
7567 return e_comp_wl_normal_subsurface_has(ec);
7571 e_client_cursor_hide(E_Client *ec)
7573 return e_comp_wl_cursor_hide(ec);
7577 e_client_visibility_force_obscured_set(E_Client *ec, Eina_Bool set)
7581 ELOGF("TZVIS", "VIS_FORCE_OBSCURED :%d", ec, set);
7583 ec->visibility.force_obscured = set;
7584 e_comp_visibility_calculation_set(EINA_TRUE);
7587 EINTERN E_Capture_Save_State
7588 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)
7590 return e_comp_wl_capture_client_image_save(ec, dir, name, func_end, data, skip_child);
7594 _e_client_base_output_resolution_hook_subsurf_create(void *data, E_Client *subc)
7596 E_Client *ec, *parent;
7602 ec->base_output_resolution.use = 0;
7603 ec->base_output_resolution.w = 0;
7604 ec->base_output_resolution.h = 0;
7605 if (ec->base_output_resolution.transform)
7607 e_client_transform_core_remove(ec, ec->base_output_resolution.transform);
7608 E_FREE_FUNC(ec->base_output_resolution.transform, e_util_transform_del);
7609 ELOGF("POL_APPINFO", "Cancel TRANSFORM for subsurface", ec);
7612 /* Update transform for toplevel surface.
7613 * The transform of subsurface will be updated by its parent accordingly. */
7614 parent = e_comp_wl_topmost_parent_get(ec);
7617 parent->transform_core.changed = EINA_TRUE;
7618 e_client_transform_core_update(parent);
7621 /* TODO: Do we need to apply it again if subsurface is destroyed? */
7625 _e_client_base_output_resolution_set(E_Client *ec, int width, int height)
7628 ec->base_output_resolution.use = 1;
7629 ec->base_output_resolution.w = width;
7630 ec->base_output_resolution.h = height;
7631 ec->base_output_resolution.transform = e_util_transform_new();
7632 e_util_transform_role_set(ec->base_output_resolution.transform, "base_output_resolution");
7633 e_client_transform_core_add(ec, ec->base_output_resolution.transform);
7635 if (!ec->base_output_resolution.hook_subsurf_create)
7637 ec->base_output_resolution.hook_subsurf_create =
7638 e_comp_wl_hook_add(E_COMP_WL_HOOK_SUBSURFACE_CREATE,
7639 _e_client_base_output_resolution_hook_subsurf_create,
7645 e_client_base_output_resolution_transform_adjust(E_Client *ec)
7649 EINA_SAFETY_ON_NULL_RETURN(ec);
7650 if (!ec->base_output_resolution.use) return;
7651 if (!ec->base_output_resolution.transform) return;
7653 desk = e_comp_desk_find_by_ec(ec);
7654 EINA_SAFETY_ON_NULL_RETURN(desk);
7656 ELOGF("POL_APPINFO", "Apply TRANSFORM... desk:(%dx%d), ec:(%dx%d)",
7657 ec, desk->geom.w, desk->geom.h, ec->w, ec->h);
7659 e_util_transform_scale(ec->base_output_resolution.transform,
7660 (double)desk->geom.w /(double)ec->base_output_resolution.w,
7661 (double)desk->geom.h /(double)ec->base_output_resolution.h,
7663 e_client_transform_core_update(ec);
7667 e_client_base_output_resolution_update(E_Client *ec)
7669 E_Appinfo *eai = NULL;
7670 int configured_width, configured_height;
7674 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
7676 if (!e_config->configured_output_resolution.use) return EINA_TRUE;
7677 if (ec->base_output_resolution.use) return EINA_TRUE;
7679 /* Check whether it's subsurface or not
7680 * The resolution of subsurface will follow the resolution of its toplevel surface.
7681 * Transform for subsurface will be applied when toplevel surface does by
7682 * implementation of e_client_transform_core.
7684 if (e_comp_wl_subsurface_check(ec))
7687 desk = e_comp_desk_find_by_ec(ec);
7688 EINA_SAFETY_ON_NULL_RETURN_VAL(desk, EINA_FALSE);
7690 configured_width = e_config->configured_output_resolution.w;
7691 configured_height = e_config->configured_output_resolution.h;
7695 ELOGF("POL_APPINFO", "NO PID... USE configured_output_resolution(%d,%d) pid:%d", ec,
7696 configured_width, configured_height, ec->netwm.pid);
7697 goto use_configured;
7700 eai = e_appinfo_find_with_pid(ec->netwm.pid);
7703 ELOGF("POL_APPINFO", "NO APPINFO... USE configured_output_resolution(%d,%d) pid:%d", ec,
7704 configured_width, configured_height, ec->netwm.pid);
7705 goto use_configured;
7708 if (!e_appinfo_base_output_resolution_get(eai, &width, &height))
7710 ELOGF("POL_APPINFO", "NO BASE SCREEN RESOLUTION... USE configured_output_resolution(%d,%d) pid:%d", ec,
7711 configured_width, configured_height, ec->netwm.pid);
7712 goto use_configured;
7715 if ((width == 0) && (height == 0))
7717 ELOGF("POL_APPINFO", "SKIP SET BASE SCREEN RESOLUTION... base_output_resolution size:(%d,%d) pid:%d", ec, width, height, ec->netwm.pid);
7721 if ((desk->geom.w == width) && (desk->geom.h == height))
7723 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);
7727 /* set the base_output_resolution of the e_client */
7728 _e_client_base_output_resolution_set(ec, width, height);
7730 ELOGF("POL_APPINFO", "USE base_output_resolution(%d,%d) pid:%d", ec, width, height, ec->netwm.pid);
7736 if ((desk->geom.w == configured_width) && (desk->geom.h == configured_height))
7738 ELOGF("POL_APPINFO", "SKIP use configured_output_resolution (same with desk size:(%d,%d), pid:%d)", ec, configured_width, configured_height, ec->netwm.pid);
7742 /* set the base_output_resolution of the e_client as a default */
7743 _e_client_base_output_resolution_set(ec, configured_width, configured_height);
7750 e_client_base_output_resolution_useful_geometry_get(E_Client *ec, int *x, int *y, int *w, int *h)
7755 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
7757 zone = e_comp_zone_find_by_ec(ec);
7758 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
7760 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
7767 if (ec->base_output_resolution.use)
7769 if (w) *w = ec->base_output_resolution.w;
7770 if (h) *h = ec->base_output_resolution.h;
7776 /* change the base_output_resolution of the bind_ec by checking the base_output_resolution of provider_ec's appinfo */
7778 e_client_base_output_resolution_rsm_update(E_Client *bind_ec, E_Client *provider_ec)
7780 E_Appinfo *epai = NULL;
7781 int configured_width, configured_height;
7783 E_Desk *bind_ec_desk;
7785 EINA_SAFETY_ON_NULL_RETURN_VAL(bind_ec, EINA_FALSE);
7786 EINA_SAFETY_ON_NULL_RETURN_VAL(provider_ec, EINA_FALSE);
7788 bind_ec_desk = e_comp_desk_find_by_ec(bind_ec);
7789 EINA_SAFETY_ON_NULL_RETURN_VAL(bind_ec_desk, EINA_FALSE);
7791 if (!e_config->configured_output_resolution.use) return EINA_TRUE;
7793 configured_width = e_config->configured_output_resolution.w;
7794 configured_height = e_config->configured_output_resolution.h;
7796 if (bind_ec->base_output_resolution.use)
7798 ELOGF("POL_APPINFO", "DELETE EXISTED BINDER BASE SCREEN RESOLUTION... base_output_resolution is same with desk size:(%d,%d), bind_pid:%d", bind_ec,
7799 bind_ec->base_output_resolution.w, bind_ec->base_output_resolution.h, bind_ec->netwm.pid);
7801 bind_ec->base_output_resolution.use = 0;
7802 bind_ec->base_output_resolution.w = 0;
7803 bind_ec->base_output_resolution.h = 0;
7804 e_client_transform_core_remove(bind_ec, bind_ec->base_output_resolution.transform);
7805 E_FREE_FUNC(bind_ec->base_output_resolution.transform, e_util_transform_del);
7808 if (!provider_ec->netwm.pid)
7810 ELOGF("POL_APPINFO", "NO PROVIDER PID... USE configured_output_resolution(%d,%d) provider_pid:%d", provider_ec,
7811 configured_width, configured_height, provider_ec->netwm.pid);
7812 goto use_configured;
7815 epai = e_appinfo_find_with_pid(provider_ec->netwm.pid);
7818 ELOGF("POL_APPINFO", "NO PROVIDER APPINFO... USE configured_output_resolution(%d,%d) provider_pid:%d", provider_ec,
7819 configured_width, configured_height, provider_ec->netwm.pid);
7820 goto use_configured;
7823 if (!e_appinfo_base_output_resolution_get(epai, &width, &height))
7825 ELOGF("POL_APPINFO", "NO PROVIDER APPINFO BASE SCREEN RESOLUTION... USE configured_output_resolution(%d,%d) provider_pid:%d", provider_ec,
7826 configured_width, configured_height, provider_ec->netwm.pid);
7827 goto use_configured;
7830 if ((width == 0) && (height == 0))
7832 ELOGF("POL_APPINFO", "NO PROVIDER WIDTH and HEIGHT... SKIP base_output_resolution due to size:(%d,%d) provider_pid:%d", provider_ec,
7833 width, height, provider_ec->netwm.pid);
7837 if ((bind_ec_desk->geom.w == width) && (bind_ec_desk->geom.h == height))
7839 ELOGF("POL_APPINFO", "SKIP SET BINDER BASE SCREEN RESOLUTION... base_output_resolution is same with desk size:(%d,%d), bind_pid:%d", bind_ec,
7840 width, height, bind_ec->netwm.pid);
7844 /* set the base_output_resolution of the e_client */
7845 _e_client_base_output_resolution_set(bind_ec, width, height);
7846 e_client_base_output_resolution_transform_adjust(bind_ec);
7848 ELOGF("POL_APPINFO", "USE BINDER base_output_resolution(%d,%d) bind_pid:%d", bind_ec, width, height, bind_ec->netwm.pid);
7854 if ((bind_ec_desk->geom.w == configured_width) && (bind_ec_desk->geom.h == configured_height))
7856 ELOGF("POL_APPINFO", "SKIP BINDER use configured_output_resolution (same with desk size:(%d,%d), bind_pid:%d)", bind_ec,
7857 configured_width, configured_height, bind_ec->netwm.pid);
7861 /* set the base_output_resolution of the e_client as a default */
7862 _e_client_base_output_resolution_set(bind_ec, configured_width, configured_height);
7868 /* tizen_move_resize */
7870 e_client_pending_geometry_has(E_Client *ec)
7872 if (!eina_list_count(ec->surface_sync.pending_geometry))
7875 return ec->surface_sync.wait_commit;
7879 e_client_pending_geometry_flush(E_Client *ec)
7881 E_Client_Pending_Geometry *geo;
7883 if (!eina_list_count(ec->surface_sync.pending_geometry))
7885 EINA_LIST_FREE(ec->surface_sync.pending_geometry, geo)
7889 ec->surface_sync.wait_commit = EINA_FALSE;
7890 ELOGF("POSSIZE", "pending geometry has flushed", ec);
7895 e_client_pending_geometry_last_geometry_get(E_Client *ec, int *x, int *y, int *w, int *h)
7898 E_Client_Pending_Geometry *geo;
7904 EINA_LIST_REVERSE_FOREACH(ec->surface_sync.pending_geometry, l, geo)
7920 e_client_frame_focus_set(E_Client *ec, Eina_Bool focus)
7923 evas_object_focus_set(ec->frame, focus);
7927 e_client_frame_geometry_set(E_Client *ec, int x, int y, int w, int h)
7931 if (ec->internal || ec->input_only)
7933 evas_object_geometry_set(ec->frame, x, y, w, h);
7937 if ((ec->w != w) || (ec->h != h))
7939 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);
7940 ec->move_after_resize = EINA_TRUE;
7942 e_client_pos_set(ec, x, y);
7943 evas_object_resize(ec->frame, w, h);
7946 evas_object_geometry_set(ec->frame, x, y, w, h);
7951 e_client_util_move_resize_without_frame(E_Client *ec, int x, int y, int w, int h)
7955 if (ec->internal || ec->input_only)
7957 e_client_util_move_without_frame(ec, x, y);
7958 e_client_util_resize_without_frame(ec, w, h);
7962 if ((ec->w != w) || (ec->h != h))
7964 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);
7965 ec->move_after_resize = EINA_TRUE;
7967 e_comp_object_frame_xy_adjust(ec->frame, x, y, &x, &y);
7968 e_client_pos_set(ec, x, y);
7969 e_client_util_resize_without_frame(ec, w, h);
7973 e_client_util_move_without_frame(ec, x, y);
7974 e_client_util_resize_without_frame(ec, w, h);
7980 e_client_layer_set(E_Client *ec,
7983 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
7984 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
7985 if (!ec->frame) return EINA_FALSE;
7987 if (e_comp_canvas_client_layer_map(layer) == 9999)
7988 return EINA_FALSE; //invalid layer is not allowed
7990 if (ec->desk_area.enable)
7992 if (e_client_layer_set_by_desk_area(ec, layer))
7994 // restack according to desk group rule
7995 e_desk_area_ec_rearrange(ec->desk_area.desk_area, ec);
7999 ec->desk_area.layer_backup = layer;
8001 evas_object_layer_set(ec->frame, layer);
8002 if (ec->layer != layer)
8004 /* check exceptional case */
8005 if ((ec->fullscreen) &&
8006 (ec->saved.layer != layer))
8008 ELOGF("LAYER", "(%d) fail to backup at saved.layer for fullscreen", ec, layer);
8011 // if e_comp_object fail to change ec->layer due to ec->layer_pending or block
8012 // leave log and apply ec->layer according to set
8013 // as a result it restores back to given layer when pending or block is free
8014 ELOGF("LAYER", "change layer from %d to %d if in case layer pending(%d) or block(%d)",
8015 ec, ec->layer, layer, ec->layer_pending, ec->layer_block);
8016 if (ec->layer_pending || ec->layer_block)
8027 e_client_layer_get(E_Client *ec)
8031 E_OBJECT_CHECK_RETURN(ec, E_LAYER_BOTTOM);
8032 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, E_LAYER_BOTTOM);
8033 if (!ec->frame) return E_LAYER_BOTTOM;
8035 layer = evas_object_layer_get(ec->frame);
8036 if (ec->layer != layer)
8038 /* client could be on temperory layer while pending or block,
8039 * in that case, client restores back to ec->layer after pending/block finish */
8040 if (ec->layer_block || ec->layer_pending)
8043 /* otherwise, client is on unexpected layer */
8044 ELOGF("LAYER", "layer dismatch ec->layer %d | evas obj layer %d ",
8045 ec, ec->layer, layer);
8047 if (e_comp_canvas_client_layer_map(layer) == 9999)
8048 return E_LAYER_BOTTOM; //not on E_LAYER_CLIENT
8055 _e_client_desk_area_original_layer_save(E_Client *ec, E_Layer layer)
8058 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
8059 ec->desk_area.layer_backup = layer;
8063 e_client_layer_set_by_desk_area(E_Client *ec, E_Layer layer)
8069 if (!ec) return EINA_FALSE;
8070 if (!ec->frame) return EINA_FALSE;
8071 if (!ec->desk_area.enable) return EINA_FALSE;
8072 if (!ec->desk_area.desk_area) return EINA_FALSE;
8074 eda = ec->desk_area.desk_area;
8076 // save original layer
8077 _e_client_desk_area_original_layer_save(ec, layer);
8079 // get desk_area layer
8080 edg_layer = (E_Layer)e_desk_area_layer_get(eda);
8081 org_layer = e_client_desk_area_original_layer_get(ec);
8083 ELOGF("EDG", "layer_set by desk_area... layer:%d, org_layer:%d, new_layer:%d", ec, layer, org_layer, edg_layer);
8084 if (org_layer == edg_layer)
8090 evas_object_layer_set(ec->frame, edg_layer);
8091 if (edg_layer == ec->layer)
8099 e_client_desk_area_original_layer_restore(E_Client *ec)
8103 // Do we need to check ec->desk_area.enable?
8104 // if ec->desk_area.enable is true, then e_client_layer_set calls
8105 // e_desk_area_ec_layer_set(). that's too bad. :(
8106 // so, we MUST make a policy for ordering of the desk group layer restore
8107 // and the desk group enable.
8108 if (ec->desk_area.enable) return;
8109 e_client_layer_set(ec, ec->desk_area.layer_backup);
8113 e_client_desk_area_original_layer_get(E_Client *ec)
8115 if (!ec) return E_LAYER_DESKTOP;
8117 if (ec->desk_area.enable)
8118 return ec->desk_area.layer_backup;
8124 e_client_desk_area_client_layer_set(E_Client *ec, E_Desk_Area_Client_Layer edgc_layer)
8126 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
8127 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
8128 if ((edgc_layer < E_DESK_AREA_CLIENT_LAYER_DESKTOP) ||
8129 (edgc_layer >= E_DESK_AREA_CLIENT_LAYER_MAX))
8132 ec->desk_area.edgc_layer = edgc_layer;
8136 EINTERN E_Desk_Area_Client_Layer
8137 e_client_desk_area_client_layer_get(E_Client *ec)
8139 E_OBJECT_CHECK_RETURN(ec, E_DESK_AREA_CLIENT_LAYER_DESKTOP);
8141 return ec->desk_area.edgc_layer;
8145 e_client_desk_area_enable_set(E_Client *ec, Eina_Bool enable)
8147 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
8148 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
8150 ec->desk_area.enable = enable;
8152 ELOGF("EDG", "Desk group enable set to %d", ec, enable);
8155 if (!ec->desk_area.transform)
8157 ec->desk_area.transform = e_util_transform_new();
8158 e_util_transform_role_set(ec->desk_area.transform, "desk_area");
8163 if (ec->desk_area.transform)
8165 e_util_transform_del(ec->desk_area.transform);
8166 ec->desk_area.transform = NULL;
8170 e_desk_area_ec_update(ec->desk_area.desk_area, ec);
8175 e_client_desk_area_set(E_Client *ec, E_Desk_Area *eda)
8177 E_Desk_Area *old_edg;
8179 if (!ec) return EINA_FALSE;
8181 #if 0 // if this is removed.. then below if (eda != old_edg) is removed also...
8182 if (ec->desk_area.desk_area == eda)
8186 ELOGF("EDG", "Desk Group Set (new:%p, old:%p)", ec, eda, ec->desk_area.desk_area);
8187 old_edg = ec->desk_area.desk_area;
8189 e_desk_area_ec_remove(old_edg, ec);
8191 ec->desk_area.desk_area = eda;
8192 e_desk_area_ec_add(eda, ec);
8194 #if 0 // if this is removed.. then above if (ec->desk_area.desk_area == eda) is removed also...
8198 e_desk_area_ec_update(eda, ec);
8199 e_desk_area_ec_rearrange(ec->desk_area.desk_area, ec);
8206 _raise_between_sibling_under_parent(E_Client *ec)
8208 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);
8209 e_client_stack_below(ec, ec->parent);
8213 _raise_between_sibling_on_parent(E_Client *ec)
8215 E_Client *top_child = NULL;
8216 top_child = e_client_transient_child_top_get(ec->parent, EINA_FALSE);
8219 ELOGF("POL", "RAISE child window... Stack above on the parent (win:%zx, ec:%p)", ec, e_client_util_win_get(ec->parent), ec->parent);
8220 e_client_stack_above(ec, ec->parent);
8224 if (top_child != ec)
8226 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);
8227 e_client_stack_above(ec, top_child);
8230 ELOGF("POL", "RAISE child window between sibling... already on the top. STAY", ec);
8235 _raise_belong_to_parent(E_Client *ec)
8237 if (e_client_transient_policy_get(ec) == E_TRANSIENT_BELOW)
8238 _raise_between_sibling_under_parent(ec);
8240 _raise_between_sibling_on_parent(ec);
8244 e_client_raise(E_Client *ec)
8248 if (ec->desk_area.enable)
8251 eda = ec->desk_area.desk_area;
8254 e_desk_area_ec_raise(eda, ec);
8259 if (ec->parent && e_client_is_belong_to_parent(ec))
8260 _raise_belong_to_parent(ec);
8262 evas_object_raise(ec->frame);
8266 _e_client_transient_for_below_group_make(E_Client *ec, Eina_List **list)
8268 // list : Head is the bottommost child
8274 EINA_LIST_REVERSE_FOREACH(ec->transients, l, child)
8276 if (!child) continue;
8277 if (e_client_transient_policy_get(child) != E_TRANSIENT_BELOW) continue;
8278 if (!e_client_is_belong_to_parent(child)) continue;
8280 *list = eina_list_prepend(*list, child);
8281 _e_client_transient_for_group_make(child, list);
8286 e_client_transient_child_bottom_get(E_Client *ec)
8288 E_Client *bottom_ec = NULL;
8289 Eina_List *transient_below_list = NULL;
8290 Eina_List *l = NULL;
8292 _e_client_transient_for_below_group_make(ec, &transient_below_list);
8294 if (transient_below_list)
8296 E_Client *temp_ec = NULL;
8297 E_Client *temp_ec2 = NULL;
8299 E_CLIENT_FOREACH(temp_ec)
8301 if (bottom_ec) break;
8309 EINA_LIST_FOREACH(transient_below_list, l, temp_ec2)
8311 if (temp_ec == temp_ec2)
8313 bottom_ec = temp_ec2;
8318 eina_list_free(transient_below_list);
8324 _lower_between_sibling_under_parent(E_Client *ec)
8326 E_Client *bottom_child = NULL;
8327 bottom_child = e_client_transient_child_bottom_get(ec->parent);
8330 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);
8331 e_client_stack_below(ec, ec->parent);
8335 if (bottom_child != ec)
8337 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);
8338 e_client_stack_below(ec, bottom_child);
8341 ELOGF("POL", "LOWER child window between sibling... already under the bottom. STAY", ec);
8346 _lower_between_sibling_on_parent(E_Client *ec)
8348 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);
8349 e_client_stack_above(ec, ec->parent);
8353 _lower_belong_to_parent(E_Client *ec)
8355 if (e_client_transient_policy_get(ec) == E_TRANSIENT_BELOW)
8356 _lower_between_sibling_under_parent(ec);
8358 _lower_between_sibling_on_parent(ec);
8362 e_client_lower(E_Client *ec)
8366 if (ec->desk_area.enable)
8369 eda = ec->desk_area.desk_area;
8372 e_desk_area_ec_lower(eda, ec);
8373 #ifdef REFACTOR_FOCUS_POLICY
8374 _e_client_hook_call(E_CLIENT_HOOK_LOWER, ec);
8380 if (ec->parent && e_client_is_belong_to_parent(ec))
8381 _lower_belong_to_parent(ec);
8383 evas_object_lower(ec->frame);
8385 #ifdef REFACTOR_FOCUS_POLICY
8386 _e_client_hook_call(E_CLIENT_HOOK_LOWER, ec);
8391 e_client_stack_above(E_Client *ec, E_Client *above)
8394 if (!ec->frame) return;
8396 if (!above->frame) return;
8398 if (ec->desk_area.enable)
8401 eda = ec->desk_area.desk_area;
8404 e_desk_area_ec_stack_above(eda, ec, above);
8409 evas_object_stack_above(ec->frame, above->frame);
8413 e_client_stack_below(E_Client *ec, E_Client *below)
8416 if (!ec->frame) return;
8418 if (!below->frame) return;
8420 if (ec->desk_area.enable)
8423 eda = ec->desk_area.desk_area;
8426 e_desk_area_ec_stack_below(eda, ec, below);
8431 evas_object_stack_below(ec->frame, below->frame);
8435 e_client_show_pending_set(E_Client *ec)
8439 ec->show_pending.count++;
8440 ELOGF("E_CLIENT", "SET show_pending. (count:%d, run:%d)", ec, ec->show_pending.count, ec->show_pending.running);
8441 return ec->show_pending.count;
8445 e_client_show_pending_unset(E_Client *ec)
8448 if (ec->show_pending.count <= 0) return 0;
8450 ec->show_pending.count--;
8451 ELOGF("E_CLIENT", "UNSET show_pending. (count:%d, run:%d)", ec, ec->show_pending.count, ec->show_pending.running);
8452 if (ec->show_pending.count == 0 && ec->show_pending.running)
8454 ec->show_pending.running = EINA_FALSE;
8457 ELOGF("E_CLIENT", "evas_object_show by unset show_pending", ec);
8458 evas_object_show(ec->frame);
8459 //e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
8464 return ec->show_pending.count;
8468 _e_client_surface_tree_foreach_helper(E_Client *ec, E_Client_Surface_Tree_Foreach func, void *data)
8472 Eina_Bool res = EINA_TRUE;
8473 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
8478 EINA_LIST_FOREACH_SAFE(cdata->sub.below_list, l, ll, subc)
8480 res = _e_client_surface_tree_foreach_helper(subc, func, data);
8487 res = func(data, ec);
8490 EINA_LIST_FOREACH_SAFE(cdata->sub.list, l, ll, subc)
8492 res = _e_client_surface_tree_foreach_helper(subc,
8505 e_client_surface_tree_foreach(E_Client *ec, E_Client_Surface_Tree_Foreach func, void *data)
8507 EINA_SAFETY_ON_NULL_RETURN(ec);
8508 EINA_SAFETY_ON_NULL_RETURN(func);
8510 _e_client_surface_tree_foreach_helper(ec, func, data);
8513 EINTERN E_Comp_Wl_Client_Data *
8514 e_client_cdata_new(E_Client *ec)
8516 E_Comp_Wl_Client_Data *cdata;
8518 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
8520 if (!(cdata = E_NEW(E_Comp_Wl_Client_Data, 1)))
8522 ERR("Could not allocate new E_Comp_Wl_Client_Data structure");
8525 ec->comp_data = cdata;
8531 e_client_cdata_free(E_Client *ec)
8533 EINA_SAFETY_ON_NULL_RETURN(ec);
8534 if (!ec->comp_data) return;
8536 E_FREE(ec->comp_data);
8539 EINTERN E_Comp_Wl_Client_Data *
8540 e_client_cdata_get(E_Client *ec)
8542 if (!ec) return NULL;
8544 return ec->comp_data;
8548 e_client_map_set(E_Client *ec, E_Map *em)
8550 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
8552 return e_map_set_to_comp_object(em, ec->frame);
8556 e_client_map_get(const E_Client *ec)
8558 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
8560 return e_map_get_from_comp_object(ec->frame);
8564 e_client_map_enable_set(E_Client *ec, Eina_Bool enable)
8566 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
8567 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->frame, EINA_FALSE);
8569 evas_object_map_enable_set(ec->frame, enable);
8575 e_client_belong_to_parent_set(E_Client *ec, Eina_Bool set)
8578 ec->belong_to_parent = set;
8582 e_client_is_belong_to_parent(E_Client *ec)
8584 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
8585 return ec->belong_to_parent;
8589 e_client_transient_policy_set(E_Client *ec, E_Transient policy)
8592 ec->transient_policy = policy;
8596 e_client_transient_policy_get(E_Client *ec)
8598 if (!ec) return E_TRANSIENT_ABOVE;
8599 return ec->transient_policy;
8603 e_client_resize_object_create_cb_set(E_Client_Resize_Object_Create_Cb cb)
8605 if (_e_client_resize_object_create_cb && cb)
8606 CRI("ATTEMPTING TO OVERWRITE EXISTING CLIENT RESIZE OBJECT CREATE HOOK!!!");
8607 _e_client_resize_object_create_cb = cb;
8611 e_client_resize_unit_size_set(E_Client *ec, unsigned int unit_size)
8615 // FYI, we consider 0 and 1 to be the same value as a default unit size.
8616 ec->manage_resize.unit_size = unit_size;
8620 e_client_desk_zoom_enable_set(E_Client *ec, Eina_Bool enable)
8623 ec->desk_zoom.enable = enable;
8627 e_client_desk_zoom_enable_get(E_Client *ec)
8629 if (!ec) return EINA_FALSE;
8630 return ec->desk_zoom.enable;
8634 e_client_layout_apply(E_Client *ec, Eina_Bool apply)
8637 ec->apply_layout = apply;
8641 e_client_is_layout_apply(E_Client *ec)
8643 if (!ec) return EINA_FALSE;
8644 return ec->apply_layout;
8648 e_client_from_surface_resource(struct wl_resource *surface_resource)
8650 EINA_SAFETY_ON_NULL_RETURN_VAL(surface_resource, NULL);
8652 return e_comp_wl_util_client_from_surface_resource(surface_resource);
8656 e_client_fps_update(E_Client *ec)
8661 EINA_SAFETY_ON_NULL_RETURN(ec);
8663 if (!ec->fps.enabled) return;
8665 tim = ecore_time_get();
8667 dt = tim - ec->fps.frametimes[0];
8669 ec->fps.frametimes[0] = tim;
8673 if (ec->fps.lapse == 0.0)
8675 ec->fps.lapse = tim;
8676 ec->fps.flapse = ec->fps.cframes;
8678 else if ((tim - ec->fps.lapse) >= 0.5)
8680 ec->fps.fps = (ec->fps.cframes - ec->fps.flapse) /
8681 (tim - ec->fps.lapse);
8682 ec->fps.lapse = tim;
8683 ec->fps.flapse = ec->fps.cframes;
8689 e_client_fps_get(E_Client *ec, double *fps)
8691 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
8693 if (ec->fps.old_fps == ec->fps.fps)
8696 if (ec->fps.fps > 0.0)
8699 ec->fps.old_fps = ec->fps.fps;
8707 e_client_fps_enable(E_Client *ec, Eina_Bool enable)
8709 EINA_SAFETY_ON_NULL_RETURN(ec);
8711 ec->fps.enabled = enable;
8715 e_client_explicit_sync_get(E_Client *ec)
8717 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
8719 return ec->explicit_sync;
8723 e_client_explicit_sync_set(E_Client *ec, Eina_Bool enable)
8725 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
8727 ec->explicit_sync = enable;
8733 e_client_explicit_sync_acquire_fence_fd_get(E_Client *ec)
8735 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, -1);
8737 return ec->acquire_fence_fd;
8741 e_client_explicit_sync_acquire_fence_fd_set(E_Client *ec, int fd)
8743 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
8745 ec->acquire_fence_fd = fd;
8750 #ifdef REFACTOR_ZONE_DESK
8752 e_client_intercept_hook_auto_placement_call(E_Client *ec)
8754 // no need to call the intercept hook if ec is NULL.
8755 if (!ec) return EINA_FALSE;
8757 if (!_e_client_intercept_hook_call(E_CLIENT_INTERCEPT_HOOK_AUTO_PLACEMENT, ec))
8759 ELOGF("FOCUS", "E_CLIENT_INTERCEPT_HOOK_AUTO_PLACEMENT Intercepted.", ec);
8767 e_client_iconify_event_send(E_Client *ec)
8769 EINA_SAFETY_ON_NULL_RETURN(ec);
8771 _e_client_event_simple(ec, E_EVENT_CLIENT_ICONIFY);
8775 e_client_uniconify_event_send(E_Client *ec)
8777 EINA_SAFETY_ON_NULL_RETURN(ec);
8779 _e_client_event_simple(ec, E_EVENT_CLIENT_UNICONIFY);