1 #include "e_zone_intern.h"
2 #include "e_client_intern.h"
3 #include "e_desk_intern.h"
4 #include "e_actions_intern.h"
5 #include "e_appinfo_intern.h"
6 #include "e_bg_intern.h"
7 #include "e_bindings_intern.h"
8 #include "e_comp_wl_rsm_intern.h"
9 #include "e_comp_wl_subsurface_intern.h"
10 #include "e_comp_intern.h"
11 #include "e_input_intern.h"
12 #include "e_place_intern.h"
13 #include "e_policy_intern.h"
14 #include "e_maximize_intern.h"
15 #include "e_focus_intern.h"
16 #include "e_policy_visibility_intern.h"
17 #include "e_comp_object_intern.h"
18 #include "e_comp_canvas_intern.h"
20 #include <libds-tizen/screen.h>
22 #define ZONE_EC_DATA_KEY "E_Zone_Client"
24 #define PRI(zone) ((E_Zone_Private *)e_object_data_get(E_OBJECT(zone)))
27 EINA_SAFETY_ON_NULL_RETURN(zone); \
28 E_Zone_Private *priv = PRI(zone)
30 #define API_ENTRY_VAL(ret) \
31 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, ret); \
32 E_Zone_Private *priv = PRI(zone)
34 typedef struct _E_Zone_Private E_Zone_Private;
35 typedef struct _E_Zone_Private_Client E_Zone_Private_Client;
37 struct _E_Zone_Private
43 struct wl_signal client_add;
44 struct wl_signal client_remove;
45 struct wl_signal display_state_change;
46 struct wl_signal focus_clear;
47 struct wl_signal focus_reset;
50 struct ds_tizen_screen *tizen_screen;
51 struct wl_listener screen_destroy;
52 struct wl_listener screen_get_splitscreen;
55 struct _E_Zone_Private_Client
60 struct wl_listener client_destroy;
61 struct wl_listener client_eval_post_new_client;
62 struct wl_listener client_focus_set;
63 #ifdef REFACTOR_DESK_AREA
65 struct wl_listener client_iconify;
66 struct wl_listener client_uniconify;
67 struct wl_listener client_stick;
68 struct wl_listener client_unstick;
69 struct wl_listener client_maximize;
70 struct wl_listener client_unmaximize;
71 struct wl_listener client_activate_done;
72 struct wl_listener client_fullscreen;
73 struct wl_listener client_unfullscreen;
78 /* E_Zone is a child object of E_Comp. There is one zone per screen
79 * in a xinerama setup. Each zone has one or more desktops.
82 static void _e_zone_free(E_Zone *zone);
83 static void _e_zone_cb_bg_mouse_down(void *data,
87 static void _e_zone_cb_bg_mouse_up(void *data,
91 static void _e_zone_event_generic_free(void *data, void *ev);
92 static void _e_zone_object_del_attach(void *o);
93 static void _e_zone_hooks_clean(void);
94 static Eina_Bool _e_zone_hook_call(E_Zone_Hook_Point hookpoint, E_Zone *zone);
96 EINTERN int E_EVENT_ZONE_DESK_COUNT_SET = 0;
97 E_API int E_EVENT_ZONE_MOVE_RESIZE = 0;
98 EINTERN int E_EVENT_ZONE_ADD = 0;
99 EINTERN int E_EVENT_ZONE_DEL = 0;
100 #ifdef _F_ZONE_WINDOW_ROTATION_
101 E_API int E_EVENT_ZONE_ROTATION_CHANGE_BEGIN = 0;
102 E_API int E_EVENT_ZONE_ROTATION_CHANGE_CANCEL = 0;
103 E_API int E_EVENT_ZONE_ROTATION_CHANGE_END = 0;
104 E_API int E_EVENT_ZONE_ROTATION_EFFECT_READY = 0;
105 E_API int E_EVENT_ZONE_ROTATION_EFFECT_CANCEL = 0;
106 E_API int E_EVENT_ZONE_ROTATION_EFFECT_DONE = 0;
108 EINTERN int E_EVENT_ZONE_DISPLAY_STATE_CHANGE = 0;
109 EINTERN int E_EVENT_ZONE_USEFUL_GEOMETRY_CHANGE = 0;
111 #define E_ZONE_CORNER_RATIO 0.025;
113 static int _e_zone_hooks_delete = 0;
114 static int _e_zone_hooks_walking = 0;
116 static Eina_Inlist *_e_zone_hooks[] =
118 [E_ZONE_HOOK_DISPLAY_STATE_CHANGE] = NULL,
122 _e_zone_private_init(E_Zone *zone)
124 E_Zone_Private *priv;
126 priv = E_NEW(E_Zone_Private, 1);
132 wl_signal_init(&priv->events.client_add);
133 wl_signal_init(&priv->events.client_remove);
134 wl_signal_init(&priv->events.display_state_change);
135 wl_signal_init(&priv->events.focus_clear);
136 wl_signal_init(&priv->events.focus_reset);
138 e_object_data_set(E_OBJECT(zone), priv);
144 _e_zone_private_finish(E_Zone *zone)
146 E_Zone_Private *priv;
149 e_object_data_set(E_OBJECT(zone), NULL);
151 wl_list_remove(&priv->screen_get_splitscreen.link);
152 wl_list_remove(&priv->screen_destroy.link);
162 E_EVENT_ZONE_DESK_COUNT_SET = ecore_event_type_new();
163 E_EVENT_ZONE_MOVE_RESIZE = ecore_event_type_new();
164 E_EVENT_ZONE_ADD = ecore_event_type_new();
165 E_EVENT_ZONE_DEL = ecore_event_type_new();
166 #ifdef _F_ZONE_WINDOW_ROTATION_
167 E_EVENT_ZONE_ROTATION_CHANGE_BEGIN = ecore_event_type_new();
168 E_EVENT_ZONE_ROTATION_CHANGE_CANCEL = ecore_event_type_new();
169 E_EVENT_ZONE_ROTATION_CHANGE_END = ecore_event_type_new();
170 E_EVENT_ZONE_ROTATION_EFFECT_READY = ecore_event_type_new();
171 E_EVENT_ZONE_ROTATION_EFFECT_CANCEL = ecore_event_type_new();
172 E_EVENT_ZONE_ROTATION_EFFECT_DONE = ecore_event_type_new();
174 E_EVENT_ZONE_DISPLAY_STATE_CHANGE = ecore_event_type_new();
175 E_EVENT_ZONE_USEFUL_GEOMETRY_CHANGE = ecore_event_type_new();
181 e_zone_shutdown(void)
186 #ifdef REFACTOR_DESK_AREA
189 _e_zone_client_maximize(E_Zone *zone, E_Desk *desk, E_Client *ec, E_Maximize max)
193 int desk_x, desk_y, desk_w, desk_h;
194 Eina_Bool override = ec->maximize_override;
196 zx = zy = zw = zh = 0;
197 ec->maximize_override = 1;
199 if (ec->desk_area.enable && ec->desk_area.desk_area)
201 desk_x = ec->desk_area.desk_area->x;
202 desk_y = ec->desk_area.desk_area->y;
203 desk_w = ec->desk_area.desk_area->w;
204 desk_h = ec->desk_area.desk_area->h;
208 desk_x = desk->geom.x;
209 desk_y = desk->geom.y;
210 desk_w = desk->geom.w;
211 desk_h = desk->geom.h;
214 switch (max & E_MAXIMIZE_TYPE)
216 case E_MAXIMIZE_NONE:
220 case E_MAXIMIZE_FULLSCREEN:
221 case E_MAXIMIZE_FILL:
222 if (ec->base_output_resolution.use)
226 zw = ec->base_output_resolution.w;
227 zh = ec->base_output_resolution.h;
231 e_zone_desk_useful_geometry_get(zone, desk, &zx, &zy, &zw, &zh, EINA_FALSE);
234 switch (max & E_MAXIMIZE_DIRECTION)
236 case E_MAXIMIZE_BOTH:
237 e_client_maximized_geometry_set(ec, zx, zy, zw, zh);
240 case E_MAXIMIZE_VERTICAL:
241 e_client_maximized_geometry_set(ec, ec->x, zy, ec->w, zh);
244 case E_MAXIMIZE_HORIZONTAL:
245 e_client_maximized_geometry_set(ec, zx, ec->y, zw, ec->h);
248 case E_MAXIMIZE_LEFT:
249 e_client_maximized_geometry_set(ec, zx, zy, zw / 2, zh);
252 case E_MAXIMIZE_RIGHT:
253 e_client_maximized_geometry_set(ec, zx + zw / 2, zy, zw / 2, zh);
258 case E_MAXIMIZE_SMART:
259 case E_MAXIMIZE_EXPAND:
262 // base_output_resolution
263 if (ec->base_output_resolution.use)
267 zw = ec->base_output_resolution.w;
268 zh = ec->base_output_resolution.h;
272 e_zone_desk_useful_geometry_get(zone, desk, &zx, &zy, &zw, &zh, EINA_TRUE);
279 x2 = desk_x + desk_w;
280 y2 = desk_y + desk_h;
281 e_maximize_client_shelf_fill(ec, &x1, &yy1, &x2, &y2, max);
287 evas_object_smart_callback_call(ec->frame, "maximize", NULL);
289 switch (max & E_MAXIMIZE_DIRECTION)
291 case E_MAXIMIZE_BOTH:
292 e_client_maximized_geometry_set(ec, zx, zy, zw, zh);
295 case E_MAXIMIZE_VERTICAL:
296 e_client_maximized_geometry_set(ec, ec->x, zy, ec->w, zh);
299 case E_MAXIMIZE_HORIZONTAL:
300 e_client_maximized_geometry_set(ec, zx, ec->y, zw, ec->h);
303 case E_MAXIMIZE_LEFT:
304 e_client_maximized_geometry_set(ec, zx, zy, zw / 2, zh);
307 case E_MAXIMIZE_RIGHT:
308 e_client_maximized_geometry_set(ec, zx + zw / 2, zy, zw / 2, zh);
314 if (ec->maximize_override)
315 ec->maximize_override = override;
320 _e_zone_client_apply_auto_placement(E_Zone *zone, E_Client *ec)
323 Eina_List *skiplist = NULL;
324 int new_x, new_y, t = 0;
327 int zx = 0, zy = 0, zw = 0, zh = 0;
328 unsigned int seed = (unsigned int)time(NULL);
330 // call the intercept hook of the auto placement
331 if (e_client_intercept_hook_auto_placement_call(ec))
333 ELOGF("POL", "Intercepted auto_placement policy.", ec);
337 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
340 new_x = zx + (rand_r(&seed) % (zw - ec->w));
344 new_y = zy + (rand_r(&seed) % (zh - ec->h));
348 e_comp_object_frame_geometry_get(ec->frame, NULL, NULL, &t, NULL);
350 parent_ec = ec->parent;
354 new_x = parent_ec->x;
355 new_y = parent_ec->y;
357 else if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) ||
358 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
361 skiplist = eina_list_append(skiplist, ec);
362 desk = e_zone_desk_find_by_ec(zone, ec);
364 e_place_desk_region_smart(desk, skiplist,
365 ec->x, ec->y, ec->w, ec->h,
368 e_place_zone_region_smart(zone, skiplist,
369 ec->x, ec->y, ec->w, ec->h,
372 eina_list_free(skiplist);
374 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
377 e_place_zone_manual(zone, ec->w, t, &new_x, &new_y);
382 e_place_zone_cursor(zone, ec->x, ec->y, ec->w, ec->h,
386 ELOGF("POL", "Apply auto placement (type:%d). (%d,%d) -> (%d,%d).", ec, type, ec->x, ec->y, new_x, new_y);
387 e_client_pos_set(ec, new_x, new_y);
390 ec->pre_cb.x = ec->x; ec->pre_cb.y = ec->y;
394 _zone_cb_client_destroy(struct wl_listener *listener, void *data)
396 E_Zone_Private_Client *zone_client;
401 zone_client = wl_container_of(listener, zone_client, client_destroy);
402 zone = zone_client->zone;
403 ec = zone_client->ec;
405 desk = e_zone_desk_find_by_ec(zone, ec);
406 EINA_SAFETY_ON_NULL_RETURN(desk);
408 ELOGF("ZONE", "CLIENT DEL", ec);
410 e_desk_visible_client_iconified_list_remove(desk, ec);
413 e_client_transform_core_remove(ec, ec->desk_zoom.transform);
414 e_util_transform_del(ec->desk_zoom.transform);
415 ec->desk_zoom.transform = NULL;
416 E_FREE_FUNC(ec->desk_zoom.hook_subsurf_create, e_comp_wl_hook_del);
418 #ifdef REFACTOR_DESK_AREA
420 if (ec->desk_area.desk_area)
421 e_desk_area_ec_remove(ec->desk_area.desk_area, ec);
422 e_util_transform_del(ec->desk_area.transform);
423 ec->desk_area.transform = NULL;
427 desk->fullscreen_clients = eina_list_remove(desk->fullscreen_clients, ec);
428 if (!desk->fullscreen_clients)
429 e_comp_render_queue();
433 wl_signal_emit_mutable(&PRI(zone)->events.client_remove, ec);
435 e_desk_client_del(desk, ec);
437 #ifdef REFACTOR_DESK_AREA
439 wl_list_remove(&zone_client->client_unfullscreen.link);
440 wl_list_remove(&zone_client->client_fullscreen.link);
441 wl_list_remove(&zone_client->client_activate_done.link);
442 wl_list_remove(&zone_client->client_unmaximize.link);
443 wl_list_remove(&zone_client->client_maximize.link);
444 wl_list_remove(&zone_client->client_unstick.link);
445 wl_list_remove(&zone_client->client_stick.link);
446 wl_list_remove(&zone_client->client_uniconify.link);
447 wl_list_remove(&zone_client->client_iconify.link);
449 wl_list_remove(&zone_client->client_focus_set.link);
450 wl_list_remove(&zone_client->client_eval_post_new_client.link);
451 wl_list_remove(&zone_client->client_destroy.link);
457 _e_zone_cb_hook_client_new_client_post(void *d, E_Client *ec)
461 EINA_SAFETY_ON_NULL_RETURN(ec);
464 EINA_SAFETY_ON_NULL_RETURN(zone);
466 // FIXME: A ec is set the current zone now.
467 // We need to make a policy for the placement of the ec at the zone.
468 if (zone != e_zone_current_get()) return;
470 e_policy_client_add(ec);
471 e_zone_client_add(zone, ec);
475 _zone_cb_client_eval_post_new_client(struct wl_listener *listener, void *data)
477 E_Zone_Private_Client *zone_client;
482 int zx = 0, zy = 0, zw = 0, zh = 0;
484 zone_client = wl_container_of(listener, zone_client, client_eval_post_new_client);
485 zone = zone_client->zone;
486 ec = zone_client->ec;
488 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
489 /* enforce wm size hints for initial sizing */
490 if (e_config->screen_limits == E_CLIENT_OFFSCREEN_LIMIT_ALLOW_NONE)
492 tw = MIN(ec->w, zone->w);
493 th = MIN(ec->h, zone->h);
494 e_client_size_set(ec, tw, th);
499 e_client_resize_limit(ec, &nw, &nh);
500 e_client_size_set(ec, nw, nh);
504 int x = ec->x, y = ec->y;
505 if (ec->x) e_comp_object_frame_xy_adjust(ec->frame, ec->x, 0, &ec->x, NULL);
506 if (ec->y) e_comp_object_frame_xy_adjust(ec->frame, 0, ec->y, NULL, &ec->y);
507 if ((x != ec->x) || (y != ec->y)) ec->changes.pos = 1;
509 ec->pre_cb.x = ec->x; ec->pre_cb.y = ec->y;
516 tx = zx + ((zw - ec->w) / 2);
517 ty = zy + ((zh - ec->h) / 2);
518 e_client_pos_set(ec, tx, ty);
522 ec->pre_cb.x = ec->x; ec->pre_cb.y = ec->y;
527 eai = e_appinfo_find_with_pid(ec->netwm.pid);
531 _e_zone_client_apply_auto_placement(zone, ec);
535 if (e_appinfo_auto_placement_get(eai))
536 _e_zone_client_apply_auto_placement(zone, ec);
540 if (ec->e.state.centered)
542 tx = zx + (zw - ec->w) / 2;
543 ty = zy + (zh - ec->h) / 2;
544 e_client_pos_set(ec, tx, ty);
548 /* if the explicit geometry request asks for the app to be
549 * in another zone - well move it there */
551 E_Zone *zone1 = NULL;
556 if ((!ec->re_manage) && ((ec->x != x) || (ec->y != y)))
557 zone1 = e_comp_zone_xy_get(x, y);
561 zone1 = e_comp_zone_xy_get(ec->x + (ec->w / 2), ec->y + (ec->h / 2));
564 E_Zone *z2 = e_comp_zone_xy_get(ec->x, ec->y);
566 if (z2 && (z2 != zone1))
572 EINA_LIST_FOREACH(e_comp->zones, l, z2)
576 x = ec->x, y = ec->y, w = ec->w, h = ec->h;
577 E_RECTS_CLIP_TO_RECT(x, y, w, h, z2->x, z2->y, z2->w, z2->h);
578 if (w * h == z2->w * z2->h)
580 /* client fully covering zone */
584 if ((unsigned)(w * h) > psz)
595 zone1 = e_comp_zone_xy_get(ec->x, ec->y);
597 zone1 = e_comp_zone_xy_get(ec->x + ec->w - 1, ec->y);
599 zone1 = e_comp_zone_xy_get(ec->x + ec->w - 1, ec->y + ec->h - 1);
601 zone1 = e_comp_zone_xy_get(ec->x, ec->y + ec->h - 1);
602 if ((zone1) && (zone1 != zone))
603 e_zone_client_add(zone1, ec);
608 _zone_cb_client_focus_set(struct wl_listener *listener, void *data)
610 E_Zone_Private_Client *zone_client;
615 zone_client = wl_container_of(listener, zone_client, client_focus_set);
616 zone = zone_client->zone;
617 ec = zone_client->ec;
619 desk = e_zone_desk_find_by_ec(zone, ec);
620 EINA_SAFETY_ON_NULL_RETURN(desk);
622 if (!desk->visible && ec->sticky)
623 e_desk_client_add(e_desk_current_get(zone), ec);
626 #ifdef REFACTOR_DESK_AREA
629 _zone_cb_client_iconify(struct wl_listener *listener, void *data)
631 E_Zone_Private_Client *zone_client;
636 zone_client = wl_container_of(listener, zone_client, client_iconify);
637 zone = zone_client->zone;
638 ec = zone_client->ec;
640 desk = e_zone_desk_find_by_ec(zone, ec);
641 EINA_SAFETY_ON_NULL_RETURN(desk);
643 e_comp_wl_remote_surface_image_save(ec);
646 ec->want_focus = ec->take_focus = 0;
647 ec->changes.visible = 0;
649 desk->fullscreen_clients = eina_list_remove(desk->fullscreen_clients, ec);
650 e_client_comp_hidden_set(ec, 1);
651 evas_object_hide(ec->frame);
653 e_client_iconify_event_send(ec);
655 if (e_config->transient.iconify)
658 Eina_List *list = eina_list_clone(ec->transients);
660 EINA_LIST_FREE(list, child)
662 if ((child->exp_iconify.type != E_ICONIFIED_TYPE_ICONIFY_BY_CLIENT) &&
663 (e_client_is_parent_iconify_by_client(child)))
665 e_client_iconified_type_set(child, E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT);
666 child->exp_iconify.by_client = 1;
667 e_policy_client_iconic_state_change_send(child, 1);
669 e_client_iconify(child);
675 _zone_cb_client_uniconify(struct wl_listener *listener, void *data)
677 E_Zone_Private_Client *zone_client;
683 zone_client = wl_container_of(listener, zone_client, client_uniconify);
684 zone = zone_client->zone;
685 ec = zone_client->ec;
687 desk = e_zone_desk_find_by_ec(zone, ec);
688 EINA_SAFETY_ON_NULL_RETURN(desk);
690 e_comp_wl_remote_surface_image_save_cancel(ec);
692 e_desk_client_add(desk, ec);
693 not_raise = ec->exp_iconify.not_raise;
695 ec->exp_iconify.by_client = 0;
696 e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_NONE);
698 if (e_config->transient.iconify)
701 Eina_List *list = eina_list_clone(ec->transients);
703 EINA_LIST_FREE(list, child)
705 if (e_client_transient_policy_get(child) == E_TRANSIENT_BELOW)
707 child->exp_iconify.not_raise = not_raise;
708 e_client_uniconify(child);
718 ELOGF("TZVIS", "UNICONIFY|internal object force show", ec);
719 evas_object_show(ec->frame);
724 E_Comp_Wl_Client_Data *cdata;
726 cdata = e_client_cdata_get(ec);
728 if (e_pixmap_usable_get(ec->pixmap))
730 if (cdata && cdata->mapped)
732 ELOGF("TZVIS", "UNICONIFY|object show. frame_visible:%d", ec,
733 evas_object_visible_get(ec->frame));
734 evas_object_show(ec->frame);
738 ELOGF("TZVIS", "UNICONIFY|object no show. currently unmapped", ec);
743 if (!ec->exp_iconify.buffer_flush &&
744 !ec->exp_iconify.deiconify_update)
746 if (cdata && cdata->mapped)
748 ELOGF("TZVIS", "UNICONIFY|object show. no use buffer flush. frame_visible:%d", ec,
749 evas_object_visible_get(ec->frame));
750 evas_object_show(ec->frame);
755 e_client_comp_hidden_set(ec, 0);
756 ec->deskshow = ec->iconic = 0;
758 #if 0 // focus should be set to the top window not uniconify window
759 if (ec->pixmap && e_pixmap_usable_get(ec->pixmap))
760 e_client_frame_focus_set(ec, EINA_TRUE);
763 // send the uniconify event of a client
764 e_client_uniconify_event_send(ec);
766 if (e_config->transient.iconify)
769 Eina_List *list = eina_list_clone(ec->transients);
771 EINA_LIST_FREE(list, child)
773 if (e_client_transient_policy_get(child) == E_TRANSIENT_ABOVE)
775 if (child->exp_iconify.type == E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT)
776 e_policy_client_iconic_state_change_send(child, 0);
777 child->exp_iconify.not_raise = not_raise;
778 e_client_uniconify(child);
783 ec->exp_iconify.not_raise = 0;
787 _zone_cb_client_stick(struct wl_listener *listener, void *data)
789 E_Zone_Private_Client *zone_client;
794 zone_client = wl_container_of(listener, zone_client, client_stick);
795 zone = zone_client->zone;
796 ec = zone_client->ec;
798 desk = e_zone_desk_find_by_ec(zone, ec);
799 EINA_SAFETY_ON_NULL_RETURN(desk);
801 e_desk_client_del(desk, ec);
805 e_desk_client_add(desk, ec);
807 evas_object_smart_callback_call(ec->frame, "stick", NULL);
809 if (e_config->transient.desktop)
812 Eina_List *list = eina_list_clone(ec->transients);
814 EINA_LIST_FREE(list, child)
817 evas_object_show(ec->frame);
823 _zone_cb_client_unstick(struct wl_listener *listener, void *data)
825 E_Zone_Private_Client *zone_client;
828 E_Desk *desk, *curr_desk;
830 zone_client = wl_container_of(listener, zone_client, client_unstick);
831 zone = zone_client->zone;
832 ec = zone_client->ec;
834 desk = e_zone_desk_find_by_ec(zone, ec);
835 EINA_SAFETY_ON_NULL_RETURN(desk);
837 e_desk_client_del(desk, ec);
838 ec->hidden = ec->sticky = 0;
840 curr_desk = e_desk_current_get(zone);
841 e_desk_client_add(curr_desk, ec);
843 evas_object_smart_callback_call(ec->frame, "unstick", NULL);
845 if (e_config->transient.desktop)
848 Eina_List *list = eina_list_clone(ec->transients);
850 EINA_LIST_FREE(list, child)
858 _zone_cb_client_maximize(struct wl_listener *listener, void *data)
860 E_Zone_Private_Client *zone_client;
867 zone_client = wl_container_of(listener, zone_client, client_maximize);
868 zone = zone_client->zone;
869 ec = zone_client->ec;
871 max = *((E_Maximize *)data);
873 desk = e_zone_desk_find_by_ec(zone, ec);
874 EINA_SAFETY_ON_NULL_RETURN(desk);
876 if (ec->desk_area.enable && ec->desk_area.desk_area)
878 desk_x = ec->desk_area.desk_area->x;
879 desk_y = ec->desk_area.desk_area->y;
883 desk_x = desk->geom.x;
884 desk_y = desk->geom.y;
887 ec->pre_res_change.valid = 0;
891 evas_object_smart_callback_call(ec->frame, "maximize_pre", NULL);
893 if (!(ec->maximized & E_MAXIMIZE_HORIZONTAL))
895 /* Horizontal hasn't been set */
896 ec->saved.x = ec->client.x - desk_x;
897 ec->saved.w = ec->client.w;
899 if (!(ec->maximized & E_MAXIMIZE_VERTICAL))
901 /* Vertical hasn't been set */
902 ec->saved.y = ec->client.y - desk_y;
903 ec->saved.h = ec->client.h;
906 ec->saved.zone = zone->num;
908 _e_zone_client_maximize(zone, desk, ec, max);
913 _zone_cb_client_unmaximize(struct wl_listener *listener, void *data)
915 E_Zone_Private_Client *zone_client;
920 zone_client = wl_container_of(listener, zone_client, client_unmaximize);
921 zone = zone_client->zone;
922 ec = zone_client->ec;
924 if (ec->fullscreen) return;
926 max = *((E_Maximize *)data);
928 if (ec->maximized & E_MAXIMIZE_TYPE)
930 ec->pre_res_change.valid = 0;
931 ec->changes.need_maximize = 0;
933 if ((ec->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
935 E_Maximize tmp_max = ec->maximized;
937 //un-set maximized state for updating frame.
938 ec->maximized = E_MAXIMIZE_NONE;
939 e_client_frame_update(ec);
940 // re-set maximized state for unmaximize smart callback.
941 ec->maximized = tmp_max;
942 evas_object_smart_callback_call(ec->frame, "unfullscreen", NULL);
943 // un-set maximized state.
944 ec->maximized = E_MAXIMIZE_NONE;
945 e_client_util_move_resize_without_frame(ec,
946 ec->saved.x + zone->x,
947 ec->saved.y + zone->y,
948 ec->saved.w, ec->saved.h);
949 ec->saved.x = ec->saved.y = ec->saved.w = ec->saved.h = 0;
954 Eina_Bool horiz = EINA_FALSE, vert = EINA_FALSE;
961 if (max & E_MAXIMIZE_VERTICAL)
963 /* Remove vertical */
966 y = ec->saved.y + zone->y;
967 if ((max & E_MAXIMIZE_VERTICAL) == E_MAXIMIZE_VERTICAL)
969 ec->maximized &= ~E_MAXIMIZE_VERTICAL;
970 ec->maximized &= ~E_MAXIMIZE_LEFT;
971 ec->maximized &= ~E_MAXIMIZE_RIGHT;
973 if ((max & E_MAXIMIZE_LEFT) == E_MAXIMIZE_LEFT)
974 ec->maximized &= ~E_MAXIMIZE_LEFT;
975 if ((max & E_MAXIMIZE_RIGHT) == E_MAXIMIZE_RIGHT)
976 ec->maximized &= ~E_MAXIMIZE_RIGHT;
978 if (max & E_MAXIMIZE_HORIZONTAL)
980 /* Remove horizontal */
982 x = ec->saved.x + zone->x;
984 ec->maximized &= ~E_MAXIMIZE_HORIZONTAL;
987 if (!(ec->maximized & E_MAXIMIZE_DIRECTION))
989 ec->maximized = E_MAXIMIZE_NONE;
990 e_client_frame_update(ec);
991 evas_object_smart_callback_call(ec->frame, "unmaximize", NULL);
992 e_client_resize_limit(ec, &w, &h);
993 e_client_pos_set(ec, x, y);
994 if ((ec->saved.w != 0) && (ec->saved.h != 0))
996 if ((w != ec->saved.w) || (h != ec->saved.h))
998 e_policy_visibility_client_defer_move(ec);
1004 evas_object_smart_callback_call(ec->frame, "unmaximize", NULL);
1005 e_client_resize_limit(ec, &w, &h);
1006 e_client_pos_set(ec, x, y);
1007 if ((ec->saved.w != 0) && (ec->saved.h != 0))
1009 if ((w != ec->saved.w) || (h != ec->saved.h))
1011 e_policy_visibility_client_defer_move(ec);
1016 ec->saved.h = ec->saved.y = 0;
1018 ec->saved.w = ec->saved.x = 0;
1024 _zone_cb_client_activate_done(struct wl_listener *listener, void *data)
1026 E_Zone_Private_Client *zone_client;
1031 zone_client = wl_container_of(listener, zone_client, client_activate_done);
1032 zone = zone_client->zone;
1033 ec = zone_client->ec;
1035 desk = e_zone_desk_find_by_ec(zone, ec);
1036 EINA_SAFETY_ON_NULL_RETURN(desk);
1038 if ((!ec->iconic) && (!ec->sticky))
1043 if (!ec->lock_user_stacking)
1046 if (!e_client_desk_iconify_skip_get(ec))
1048 e_desk_visible_client_iconified_list_remove_all(desk);
1053 _zone_cb_client_fullscreen(struct wl_listener *listener, void *data)
1055 E_Zone_Private_Client *zone_client;
1059 E_Fullscreen fullscreen_policy;
1061 zone_client = wl_container_of(listener, zone_client, client_fullscreen);
1062 zone = zone_client->zone;
1063 ec = zone_client->ec;
1065 fullscreen_policy = *((E_Fullscreen *)data);
1067 desk = e_zone_desk_find_by_ec(zone, ec);
1068 EINA_SAFETY_ON_NULL_RETURN(desk);
1070 if (!desk->visible) return;
1072 if (e_comp->nocomp_ec && (e_desk_has_ec(desk, e_comp->nocomp_ec)))
1073 e_comp->nocomp_ec = ec;
1074 desk->fullscreen_clients = eina_list_append(desk->fullscreen_clients, ec);
1075 ec->pre_res_change.valid = 0;
1079 ec->saved.x = ec->client.x - zone->x;
1080 ec->saved.y = ec->client.y - zone->y;
1081 ec->saved.w = ec->client.w;
1082 ec->saved.h = ec->client.h;
1084 ec->saved.maximized = ec->maximized;
1085 ec->saved.zone = zone->num;
1087 if ((eina_list_count(e_comp->zones) > 1) ||
1088 (fullscreen_policy == E_FULLSCREEN_RESIZE))
1090 e_client_frame_geometry_set(ec, zone->x, zone->y, zone->w, zone->h);
1093 if (!e_client_util_ignored_get(ec))
1094 e_client_frame_update(ec);
1096 evas_object_smart_callback_call(ec->frame, "fullscreen", NULL);
1100 _zone_cb_client_unfullscreen(struct wl_listener *listener, void *data)
1102 E_Zone_Private_Client *zone_client;
1107 zone_client = wl_container_of(listener, zone_client, client_unfullscreen);
1108 zone = zone_client->zone;
1109 ec = zone_client->ec;
1111 desk = e_zone_desk_find_by_ec(zone, ec);
1112 EINA_SAFETY_ON_NULL_RETURN(desk);
1114 ec->pre_res_change.valid = 0;
1115 desk->fullscreen_clients = eina_list_remove(desk->fullscreen_clients, ec);
1117 if (!e_client_util_ignored_get(ec))
1118 e_client_frame_update(ec);
1120 evas_object_smart_callback_call(ec->frame, "unfullscreen", NULL);
1124 int saved_x = ec->saved.x;
1125 int saved_y = ec->saved.y;
1126 int saved_w = ec->saved.w;
1127 int saved_h = ec->saved.h;
1128 e_client_maximize_update(ec);
1129 ec->saved.x = saved_x;
1130 ec->saved.y = saved_y;
1131 ec->saved.w = saved_w;
1132 ec->saved.h = saved_h;
1136 e_client_util_move_resize_without_frame(ec, zone->x + ec->saved.x,
1137 zone->y + ec->saved.y,
1138 ec->saved.w, ec->saved.h);
1141 if (!desk->fullscreen_clients)
1142 e_comp_render_queue();
1147 _e_zone_client_data_set(E_Zone *zone, E_Client *ec)
1151 data = evas_object_data_get(ec->frame, ZONE_EC_DATA_KEY);
1156 ELOGF("E_Zone", "EC is already added to zone_id:%d", ec, zone->id);
1160 evas_object_data_del(ec->frame, ZONE_EC_DATA_KEY);
1163 evas_object_data_set(ec->frame, ZONE_EC_DATA_KEY, zone);
1167 e_zone_new(int num, int id, int x, int y, int w, int h)
1171 E_Event_Zone_Add *ev;
1174 zone = E_OBJECT_ALLOC(E_Zone, E_ZONE_TYPE, _e_zone_free);
1175 if (!zone) return NULL;
1177 if (!_e_zone_private_init(zone))
1179 e_object_del(E_OBJECT(zone));
1190 zone->display_state = E_ZONE_DISPLAY_STATE_ON;
1192 // Create E_Focus at only default zone which the zone num is 0
1195 if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK)
1196 zone->focus = e_focus_new(zone, E_FOCUS_EXT_TOP_STACK);
1198 // default focus policy is E_FOCUS_EXT_HISTORY
1199 zone->focus = e_focus_new(zone, E_FOCUS_EXT_HISTORY);
1202 e_object_del(E_OBJECT(zone));
1203 ERR("Fail to create focus object at zone %d", zone->num);
1208 //printf("@@@@@@@@@@ e_zone_new: %i %i | %i %i %ix%i = %p\n", num, id, x, y, w, h, zone);
1210 snprintf(name, sizeof(name), "Zone %d", zone->num);
1211 zone->name = eina_stringshare_add(name);
1213 e_comp->zones = eina_list_append(e_comp->zones, zone);
1215 o = evas_object_rectangle_add(e_comp->evas);
1216 zone->bg_clip_object = o;
1217 evas_object_repeat_events_set(o, 1);
1218 evas_object_layer_set(o, E_LAYER_BG);
1219 evas_object_name_set(o, "zone->bg_clip_object");
1220 evas_object_move(o, x, y);
1221 evas_object_resize(o, w, h);
1222 evas_object_color_set(o, 255, 255, 255, 255);
1223 evas_object_show(o);
1225 o = evas_object_rectangle_add(e_comp->evas);
1226 zone->bg_event_object = o;
1227 evas_object_name_set(o, "zone->bg_event_object");
1228 evas_object_clip_set(o, zone->bg_clip_object);
1229 evas_object_layer_set(o, E_LAYER_BG);
1230 evas_object_repeat_events_set(o, 1);
1231 evas_object_move(o, x, y);
1232 evas_object_resize(o, w, h);
1233 evas_object_color_set(o, 0, 0, 0, 0);
1234 evas_object_repeat_events_set(o, 1);
1235 evas_object_show(o);
1236 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _e_zone_cb_bg_mouse_down, zone);
1237 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _e_zone_cb_bg_mouse_up, zone);
1239 /* TODO: config the ecore_evas type. */
1241 zone->desk_x_count = 0;
1242 zone->desk_y_count = 0;
1243 zone->desk_x_current = 0;
1244 zone->desk_y_current = 0;
1245 e_zone_desk_count_set(zone, e_config->zone_desks_x_count,
1246 e_config->zone_desks_y_count);
1248 e_object_del_attach_func_set(E_OBJECT(zone), _e_zone_object_del_attach);
1250 // CLIENT HOOK Handlers
1251 E_LIST_HOOK_APPEND(zone->ec_hooks, E_CLIENT_HOOK_NEW_CLIENT_POST, _e_zone_cb_hook_client_new_client_post, zone);
1253 if (starting) return zone;
1255 ev = E_NEW(E_Event_Zone_Add, 1);
1259 e_object_ref(E_OBJECT(ev->zone));
1260 ecore_event_add(E_EVENT_ZONE_ADD, ev, _e_zone_event_generic_free, NULL);
1267 e_zone_name_set(E_Zone *zone,
1270 E_OBJECT_CHECK(zone);
1271 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1273 if (zone->name) eina_stringshare_del(zone->name);
1274 zone->name = eina_stringshare_add(name);
1278 e_zone_reconfigure_clients(E_Zone *zone, int dx, int dy, int dw, int dh)
1282 E_CLIENT_FOREACH(ec)
1284 if (!e_zone_has_ec(zone, ec)) continue;
1286 if ((dx != 0) || (dy != 0))
1287 evas_object_move(ec->frame, ec->x + dx, ec->y + dy);
1288 // we shrank the zone - adjust windows more
1289 if ((dw < 0) || (dh < 0))
1291 e_client_res_change_geometry_save(ec);
1292 e_client_res_change_geometry_restore(ec);
1298 e_zone_move(E_Zone *zone,
1302 E_Event_Zone_Move_Resize *ev;
1305 E_OBJECT_CHECK(zone);
1306 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1308 if ((x == zone->x) && (y == zone->y)) return;
1313 evas_object_move(zone->bg_object, x, y);
1314 evas_object_move(zone->bg_event_object, x, y);
1315 evas_object_move(zone->bg_clip_object, x, y);
1317 ev = E_NEW(E_Event_Zone_Move_Resize, 1);
1321 e_object_ref(E_OBJECT(ev->zone));
1322 ecore_event_add(E_EVENT_ZONE_MOVE_RESIZE, ev, _e_zone_event_generic_free, NULL);
1325 e_zone_bg_reconfigure(zone);
1326 e_zone_reconfigure_clients(zone, dx, dy, 0, 0);
1330 e_zone_resize(E_Zone *zone,
1334 E_Event_Zone_Move_Resize *ev;
1337 E_OBJECT_CHECK(zone);
1338 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1340 if ((w == zone->w) && (h == zone->h)) return;
1346 evas_object_resize(zone->bg_object, w, h);
1347 evas_object_resize(zone->bg_event_object, w, h);
1348 evas_object_resize(zone->bg_clip_object, w, h);
1350 ev = E_NEW(E_Event_Zone_Move_Resize, 1);
1354 e_object_ref(E_OBJECT(ev->zone));
1355 ecore_event_add(E_EVENT_ZONE_MOVE_RESIZE, ev,
1356 _e_zone_event_generic_free, NULL);
1359 e_zone_bg_reconfigure(zone);
1360 e_zone_reconfigure_clients(zone, 0, 0, dw, dh);
1364 e_zone_move_resize(E_Zone *zone,
1370 E_Event_Zone_Move_Resize *ev;
1373 E_OBJECT_CHECK_RETURN(zone, EINA_FALSE);
1374 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, EINA_FALSE);
1376 if ((x == zone->x) && (y == zone->y) && (w == zone->w) && (h == zone->h))
1388 evas_object_move(zone->bg_object, x, y);
1389 evas_object_move(zone->bg_event_object, x, y);
1390 evas_object_move(zone->bg_clip_object, x, y);
1391 evas_object_resize(zone->bg_object, w, h);
1392 evas_object_resize(zone->bg_event_object, w, h);
1393 evas_object_resize(zone->bg_clip_object, w, h);
1395 ev = E_NEW(E_Event_Zone_Move_Resize, 1);
1399 e_object_ref(E_OBJECT(ev->zone));
1400 ecore_event_add(E_EVENT_ZONE_MOVE_RESIZE, ev,
1401 _e_zone_event_generic_free, NULL);
1404 e_zone_bg_reconfigure(zone);
1405 e_zone_reconfigure_clients(zone, dx, dy, dw, dh);
1410 e_zone_current_get(void)
1412 Eina_List *l = NULL;
1419 e_input_device_pointer_xy_get(NULL, &x, &y);
1421 EINA_LIST_FOREACH(e_comp->zones, l, zone)
1423 if (E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h))
1427 if (!e_comp->zones) return NULL;
1428 return eina_list_data_get(e_comp->zones);
1432 e_zone_get_by_id(int id)
1434 Eina_List *l = NULL;
1437 EINA_LIST_FOREACH(e_comp->zones, l, zone)
1445 ELOGF("E_ZONE", "No zone id:%d", NULL, id);
1450 e_zone_get_by_position(int x, int y)
1452 Eina_List *l = NULL;
1455 EINA_LIST_FOREACH(e_comp->zones, l, zone)
1457 if (E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h))
1463 ELOGF("E_ZONE", "No zone under position(%d,%d)", NULL, x, y);
1468 e_zone_bg_reconfigure(E_Zone *zone)
1470 E_OBJECT_CHECK(zone);
1471 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1473 e_bg_zone_update(zone, E_BG_TRANSITION_CHANGE);
1477 e_zone_desk_count_set(E_Zone *zone,
1482 E_Desk *desk, *new_desk;
1484 E_Event_Zone_Desk_Count_Set *ev;
1485 int x, y, xx, yy, moved, nx, ny;
1487 E_OBJECT_CHECK(zone);
1488 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1495 /* Orphaned window catcher; in case desk count gets reset */
1497 if (zone->desk_x_current >= xx) moved = 1;
1498 if (zone->desk_y_current >= yy) moved = 1;
1501 nx = zone->desk_x_current;
1502 ny = zone->desk_y_current;
1503 if (zone->desk_x_current >= xx) nx = xx - 1;
1504 if (zone->desk_y_current >= yy) ny = yy - 1;
1505 e_desk_show(e_desk_at_xy_get(zone, nx, ny));
1508 new_desks = malloc(xx * yy * sizeof(E_Desk *));
1509 if (!new_desks) return;
1510 for (x = 0; x < xx; x++)
1512 for (y = 0; y < yy; y++)
1514 if ((x < zone->desk_x_count) && (y < zone->desk_y_count))
1515 desk = zone->desks[x + (y * zone->desk_x_count)];
1517 desk = e_desk_new(zone, x, y);
1518 new_desks[x + (y * xx)] = desk;
1522 /* catch windows that have fallen off the end if we got smaller */
1523 if (xx < zone->desk_x_count)
1525 for (y = 0; y < zone->desk_y_count; y++)
1527 new_desk = zone->desks[xx - 1 + (y * zone->desk_x_count)];
1528 for (x = xx; x < zone->desk_x_count; x++)
1530 desk = zone->desks[x + (y * zone->desk_x_count)];
1532 E_CLIENT_FOREACH(ec)
1534 if (e_desk_has_ec(desk, ec))
1535 e_desk_client_add(new_desk, ec);
1537 e_object_del(E_OBJECT(desk));
1541 if (yy < zone->desk_y_count)
1543 for (x = 0; x < zone->desk_x_count; x++)
1545 new_desk = zone->desks[x + ((yy - 1) * zone->desk_x_count)];
1546 for (y = yy; y < zone->desk_y_count; y++)
1548 desk = zone->desks[x + (y * zone->desk_x_count)];
1550 E_CLIENT_FOREACH(ec)
1552 if (e_desk_has_ec(desk, ec))
1553 e_desk_client_add(new_desk, ec);
1555 e_object_del(E_OBJECT(desk));
1560 zone->desks = new_desks;
1562 zone->desk_x_count = xx;
1563 zone->desk_y_count = yy;
1564 e_config->zone_desks_x_count = xx;
1565 e_config->zone_desks_y_count = yy;
1566 e_config_save_queue();
1568 /* Cannot call desk_current_get until the zone desk counts have been set
1569 * or else we end up with a "white background" because desk_current_get will
1572 desk = e_desk_current_get(zone);
1575 /* need to simulate "startup" conditions to force desk show to reevaluate here */
1583 ev = E_NEW(E_Event_Zone_Desk_Count_Set, 1);
1586 e_object_ref(E_OBJECT(ev->zone));
1587 ecore_event_add(E_EVENT_ZONE_DESK_COUNT_SET, ev,
1588 _e_zone_event_generic_free, NULL);
1592 e_zone_desk_count_get(E_Zone *zone,
1596 E_OBJECT_CHECK(zone);
1597 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1599 if (x_count) *x_count = zone->desk_x_count;
1600 if (y_count) *y_count = zone->desk_y_count;
1604 e_zone_obstacle_add(E_Zone *zone, E_Client *ec, Eina_Rectangle *geom, Eina_Bool vertical)
1606 E_Zone_Obstacle *obs;
1609 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
1610 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
1611 EINA_SAFETY_ON_NULL_RETURN_VAL(geom, EINA_FALSE);
1612 EINA_SAFETY_ON_FALSE_RETURN_VAL(e_zone_has_ec(zone, ec), EINA_FALSE);
1614 // check in the list...
1615 EINA_LIST_FOREACH(zone->obstacles, l, obs)
1619 ELOGF("E_ZONE", "Already ADDED in the obstacle list", ec);
1624 obs = E_NEW(E_Zone_Obstacle, 1);
1625 if (!obs) return EINA_FALSE;
1631 obs->vertical = !!vertical;
1633 ELOGF("E_ZONE", "ADD obstacle... geo(%d,%d,%dx%d), vertical:%d", ec, obs->x, obs->y, obs->w, obs->h, obs->vertical);
1635 zone->obstacles = eina_list_append(zone->obstacles, obs);
1637 e_zone_useful_geometry_dirty(zone);
1642 e_zone_obstacle_update(E_Zone *zone, E_Client *ec, Eina_Rectangle *geom, Eina_Bool vertical)
1644 E_Zone_Obstacle *obs;
1646 Eina_Bool changed = EINA_FALSE;
1648 if (!zone) return EINA_FALSE;
1649 if (!ec) return EINA_FALSE;
1650 if (!e_zone_has_ec(zone, ec)) return EINA_FALSE;
1652 EINA_LIST_FOREACH(zone->obstacles, l, obs)
1660 ELOGF("E_ZONE", "Not found in the obstacle list", ec);
1666 if ((obs->x != geom->x) ||
1667 (obs->y != geom->y) ||
1668 (obs->w != geom->w) ||
1669 (obs->h != geom->h))
1675 changed = EINA_TRUE;
1679 if (obs->vertical != vertical)
1681 obs->vertical = !!vertical;
1682 changed = EINA_TRUE;
1685 ELOGF("E_ZONE", "UPDATE obstacle... geo(%d,%d,%dx%d), vertical:%d", ec, obs->x, obs->y, obs->w, obs->h, obs->vertical);
1688 e_zone_useful_geometry_dirty(zone);
1694 e_zone_obstacle_remove(E_Zone *zone, E_Client *ec)
1696 E_Zone_Obstacle *obs;
1701 if (!e_zone_has_ec(zone, ec)) return;
1703 EINA_LIST_FOREACH_SAFE(zone->obstacles, l, ll, obs)
1707 ELOGF("E_ZONE", "REMOVE obstacle...", ec);
1708 zone->obstacles = eina_list_remove_list(zone->obstacles, l);
1714 e_zone_useful_geometry_dirty(zone);
1718 _e_zone_useful_geometry_calc(const E_Zone *zone, E_Desk *desk, int *x, int *y, int *w, int *h)
1721 E_Zone_Obstacle *obs;
1725 Eina_Rectangle geom = { 0 } , *rect;
1741 tiler = eina_tiler_new(zw, zh);
1742 eina_tiler_tile_size_set(tiler, 1, 1);
1743 eina_tiler_rect_add(tiler, &(Eina_Rectangle){0, 0, zw, zh});
1745 EINA_LIST_FOREACH(zone->obstacles, l, obs)
1747 if (!E_INTERSECTS(obs->x, obs->y, obs->w, obs->h, zx, zy, zw, zh)) continue;
1750 eina_tiler_rect_del(tiler, &(Eina_Rectangle){obs->x - zx, 0, obs->w, zh});
1752 eina_tiler_rect_del(tiler, &(Eina_Rectangle){0, obs->y - zy, zw, obs->h});
1755 it = eina_tiler_iterator_new(tiler);
1756 EINA_ITERATOR_FOREACH(it, rect)
1758 if (rect->w * rect->h < size) continue;
1759 size = rect->w * rect->h;
1762 eina_iterator_free(it);
1763 eina_tiler_free(tiler);
1765 if (x) *x = geom.x + zx;
1766 if (y) *y = geom.y + zy;
1772 * Get (or calculate) the useful (or free, without any shelves) area.
1775 e_zone_useful_geometry_get(E_Zone *zone,
1781 E_OBJECT_CHECK(zone);
1782 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1784 if (x) *x = zone->x;
1785 if (y) *y = zone->y;
1786 if (w) *w = zone->w;
1787 if (h) *h = zone->h;
1791 e_zone_desk_useful_geometry_get(E_Zone *zone, E_Desk *desk, int *x, int *y, int *w, int *h, Eina_Bool consider_obstacle_area)
1793 E_OBJECT_CHECK(zone);
1794 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1795 E_OBJECT_CHECK(desk);
1796 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1797 E_OBJECT_CHECK(desk->zone);
1799 if (desk->zone != zone)
1801 ELOGF("E_ZONE", "CRI... Zone(%d) and Desk's zone(%d) mismatch!", NULL, zone->id, desk->zone->id);
1805 if (consider_obstacle_area)
1806 _e_zone_useful_geometry_calc(zone, desk, x, y, w, h);
1808 e_zone_useful_geometry_get(zone, x, y, w, h);
1812 * Mark as dirty so e_zone_useful_geometry_get() will need to recalculate.
1814 * Call this function when shelves are added or important properties changed.
1817 e_zone_useful_geometry_dirty(E_Zone *zone)
1819 E_Event_Zone_Useful_Geometry_Change *ev;
1821 E_OBJECT_CHECK(zone);
1822 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1824 ev = E_NEW(E_Event_Zone_Useful_Geometry_Change, 1);
1827 e_object_ref(E_OBJECT(ev->zone));
1828 ecore_event_add(E_EVENT_ZONE_USEFUL_GEOMETRY_CHANGE, ev, _e_zone_event_generic_free, NULL);
1832 e_zone_display_state_set(E_Zone *zone, E_Zone_Display_State state)
1834 E_Event_Zone_Display_State_Change *ev;
1836 E_OBJECT_CHECK(zone);
1837 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1839 zone->display_state = state;
1841 wl_signal_emit_mutable(&PRI(zone)->events.display_state_change, NULL);
1842 _e_zone_hook_call(E_ZONE_HOOK_DISPLAY_STATE_CHANGE, zone);
1844 ev = E_NEW(E_Event_Zone_Display_State_Change, 1);
1847 e_object_ref(E_OBJECT(ev->zone));
1848 ecore_event_add(E_EVENT_ZONE_DISPLAY_STATE_CHANGE, ev, _e_zone_event_generic_free, NULL);
1851 EINTERN E_Zone_Display_State
1852 e_zone_display_state_get(E_Zone *zone)
1854 E_OBJECT_CHECK_RETURN(zone, E_ZONE_DISPLAY_STATE_OFF);
1855 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, E_ZONE_DISPLAY_STATE_OFF);
1857 return zone->display_state;
1861 e_zone_orientation_callback_set(E_Zone *zone,
1862 E_Zone_Cb_Orientation_Block_Set block_set,
1863 E_Zone_Cb_Orientation_Force_Update_Add force_update_add,
1864 E_Zone_Cb_Orientation_Force_Update_Del force_update_del)
1866 E_OBJECT_CHECK(zone);
1867 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1869 zone->orientation.block_set = block_set;
1870 zone->orientation.force_update_add = force_update_add;
1871 zone->orientation.force_update_del = force_update_del;
1875 e_zone_orientation_block_set(E_Zone *zone, const char* name_hint, Eina_Bool set)
1877 E_OBJECT_CHECK_RETURN(zone, EINA_FALSE);
1878 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, EINA_FALSE);
1880 if (zone->orientation.block_set)
1881 return zone->orientation.block_set(zone, name_hint, set);
1887 e_zone_orientation_force_update_add(E_Zone *zone, E_Client *client)
1889 E_OBJECT_CHECK(zone);
1890 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1892 if (zone->orientation.force_update_add)
1893 zone->orientation.force_update_add(zone, (void*)client);
1897 e_zone_orientation_force_update_del(E_Zone *zone, E_Client *client)
1899 E_OBJECT_CHECK(zone);
1900 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1902 if (zone->orientation.force_update_del)
1903 zone->orientation.force_update_del(zone, (void*)client);
1906 /* local subsystem functions */
1908 _e_zone_free(E_Zone *zone)
1911 E_Zone_Obstacle *obs;
1913 if(zone->focus) e_focus_del(zone->focus);
1915 /* Delete the hooks */
1916 E_FREE_LIST(zone->ec_hooks, e_client_hook_del);
1918 /* Delete the object event callbacks */
1919 evas_object_event_callback_del(zone->bg_event_object,
1920 EVAS_CALLBACK_MOUSE_DOWN,
1921 _e_zone_cb_bg_mouse_down);
1922 evas_object_event_callback_del(zone->bg_event_object,
1923 EVAS_CALLBACK_MOUSE_UP,
1924 _e_zone_cb_bg_mouse_up);
1926 E_FREE_FUNC(zone->cur_mouse_action, e_object_unref);
1928 /* remove handlers */
1929 E_FREE_LIST(zone->handlers, ecore_event_handler_del);
1931 if (zone->name) eina_stringshare_del(zone->name);
1932 e_comp->zones = eina_list_remove(e_comp->zones, zone);
1933 evas_object_del(zone->bg_event_object);
1934 evas_object_del(zone->bg_clip_object);
1935 evas_object_del(zone->bg_object);
1936 if (zone->prev_bg_object) evas_object_del(zone->prev_bg_object);
1937 if (zone->transition_object) evas_object_del(zone->transition_object);
1939 evas_object_del(zone->base);
1940 evas_object_del(zone->over);
1943 for (x = 0; x < zone->desk_x_count; x++)
1945 for (y = 0; y < zone->desk_y_count; y++)
1946 e_object_del(E_OBJECT(zone->desks[x + (y * zone->desk_x_count)]));
1948 EINA_LIST_FREE(zone->obstacles, obs)
1953 free(zone->output_id);
1955 _e_zone_private_finish(zone);
1960 _e_zone_cb_bg_mouse_down(void *data,
1961 Evas *evas EINA_UNUSED,
1962 Evas_Object *obj EINA_UNUSED,
1968 if (e_comp_util_mouse_grabbed()) return;
1970 if (!zone->cur_mouse_action)
1972 zone->cur_mouse_action =
1973 e_bindings_mouse_down_evas_event_handle(E_BINDING_CONTEXT_ZONE,
1974 E_OBJECT(zone), event_info);
1975 if (zone->cur_mouse_action)
1977 if ((!zone->cur_mouse_action->func.end_mouse) &&
1978 (!zone->cur_mouse_action->func.end))
1979 zone->cur_mouse_action = NULL;
1980 if (zone->cur_mouse_action)
1981 e_object_ref(E_OBJECT(zone->cur_mouse_action));
1987 _e_zone_cb_bg_mouse_up(void *data,
1988 Evas *evas EINA_UNUSED,
1989 Evas_Object *obj EINA_UNUSED,
1995 if (zone->cur_mouse_action)
1997 E_Binding_Event_Mouse_Button event;
1999 e_bindings_evas_event_mouse_up_button_convert(event_info, &event);
2000 if (zone->cur_mouse_action->func.end_mouse)
2001 zone->cur_mouse_action->func.end_mouse(E_OBJECT(zone), "", &event);
2002 else if (zone->cur_mouse_action->func.end)
2003 zone->cur_mouse_action->func.end(E_OBJECT(zone), "");
2005 e_object_unref(E_OBJECT(zone->cur_mouse_action));
2006 zone->cur_mouse_action = NULL;
2010 E_Binding_Event_Mouse_Button event;
2012 e_bindings_ecore_event_mouse_button_convert(event_info, &event);
2013 e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_ZONE,
2014 E_OBJECT(zone), &event);
2019 _e_zone_event_generic_free(void *data EINA_UNUSED, void *ev)
2021 struct _E_Event_Zone_Generic *e;
2022 // also handes E_Event_Zone_Add, E_Event_Zone_Del, E_Event_Zone_Stow,
2023 // E_Event_Zone_Unstow, E_Event_Zone_Desk_Count_Set due to them all
2024 // having the same content
2027 e_object_unref(E_OBJECT(e->zone));
2032 _e_zone_object_del_attach(void *o)
2035 E_Event_Zone_Del *ev;
2038 if (stopping) return;
2039 ev = E_NEW(E_Event_Zone_Del, 1);
2042 e_object_ref(E_OBJECT(ev->zone));
2043 ecore_event_add(E_EVENT_ZONE_DEL, ev, _e_zone_event_generic_free, NULL);
2046 wl_global_destroy(zone->global);
2050 _e_zone_hooks_clean(void)
2056 for (x = 0; x < E_ZONE_HOOK_LAST; x++)
2057 EINA_INLIST_FOREACH_SAFE(_e_zone_hooks[x], l, zh)
2059 if (!zh->delete_me) continue;
2060 _e_zone_hooks[x] = eina_inlist_remove(_e_zone_hooks[x], EINA_INLIST_GET(zh));
2066 _e_zone_hook_call(E_Zone_Hook_Point hookpoint, E_Zone *zone)
2070 e_object_ref(E_OBJECT(zone));
2071 _e_zone_hooks_walking++;
2072 EINA_INLIST_FOREACH(_e_zone_hooks[hookpoint], zh)
2074 if (zh->delete_me) continue;
2075 zh->func(zh->data, zone);
2077 _e_zone_hooks_walking--;
2078 if ((_e_zone_hooks_walking == 0) && (_e_zone_hooks_delete > 0))
2079 _e_zone_hooks_clean();
2081 return !!e_object_unref(E_OBJECT(zone));
2085 e_zone_hook_add(E_Zone_Hook_Point hookpoint, E_Zone_Hook_Cb func, const void *data)
2089 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_ZONE_HOOK_LAST, NULL);
2090 zh = E_NEW(E_Zone_Hook, 1);
2091 if (!zh) return NULL;
2092 zh->hookpoint = hookpoint;
2094 zh->data = (void*)data;
2095 _e_zone_hooks[hookpoint] = eina_inlist_append(_e_zone_hooks[hookpoint], EINA_INLIST_GET(zh));
2100 e_zone_hook_del(E_Zone_Hook *zh)
2103 if (_e_zone_hooks_walking == 0)
2105 _e_zone_hooks[zh->hookpoint] = eina_inlist_remove(_e_zone_hooks[zh->hookpoint], EINA_INLIST_GET(zh));
2109 _e_zone_hooks_delete++;
2113 _e_zone_cb_get_splitscreen(struct wl_listener *listener, void *data)
2115 E_Zone_Private *priv;
2117 struct ds_tizen_splitscreen *splitscreen;
2119 priv = container_of(listener, E_Zone_Private, screen_get_splitscreen);
2120 splitscreen = (struct ds_tizen_splitscreen *)data;
2122 // The splitscreen_regions are the e_desk_areas associated with this
2123 // E_Zone(E_Desk) and these are already created by the e20 module with the
2124 // specific policy. So e20 sends the splitscreen_regions associated with each
2126 desk = e_desk_current_get(priv->zone);
2127 if (!e_desk_splitscreen_enable(desk, splitscreen))
2129 ELOGF("E_Zone", "e_desk_splitscreen_enable() failed.", NULL);
2133 ELOGF("E_Zone", "Enable SplitScreen. zone_id:%d", NULL, priv->zone->id);
2137 _e_zone_cb_screen_destroy(struct wl_listener *listener EINA_UNUSED, void *data EINA_UNUSED)
2139 E_Zone_Private *priv;
2141 priv = container_of(listener, E_Zone_Private, screen_destroy);
2142 priv->tizen_screen = NULL;
2146 e_zone_screen_new(int num, int w, int h)
2149 E_Zone_Private *priv;
2151 zone = e_zone_new(num, num, 0, 0, w, h);
2152 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, NULL);
2156 priv->tizen_screen = ds_tizen_screen_create(e_comp_wl->wl.disp);
2157 EINA_SAFETY_ON_NULL_RETURN_VAL(priv->tizen_screen, NULL);
2159 priv->screen_destroy.notify = _e_zone_cb_screen_destroy;
2160 ds_tizen_screen_add_destroy_listener(priv->tizen_screen, &priv->screen_destroy);
2162 priv->screen_get_splitscreen.notify = _e_zone_cb_get_splitscreen;
2163 ds_tizen_screen_add_get_splitscreen_listener(priv->tizen_screen, &priv->screen_get_splitscreen);
2169 e_zone_screen_splitscreen_enable(E_Zone *zone)
2171 E_OBJECT_CHECK_RETURN(zone, EINA_FALSE);
2172 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, EINA_FALSE);
2174 if (zone->splitscreen_enabled)
2176 ELOGF("E_Zone", "Splitscreen is already enabled. zone_id:%d", NULL,
2181 zone->splitscreen_enabled = EINA_TRUE;
2187 _e_client_event_zone_set_free(void *d EINA_UNUSED, E_Event_Client_Zone_Set *ev)
2190 e_object_unref(E_OBJECT(ev->ec));
2191 e_object_unref(E_OBJECT(ev->zone));
2196 _e_zone_client_set(E_Zone *zone, E_Client *ec)
2198 E_Event_Client_Zone_Set *ev;
2200 ev = E_NEW(E_Event_Client_Zone_Set, 1);
2203 /* if the window does not lie in the new zone, move it so that it does */
2204 if (!E_INTERSECTS(ec->x, ec->y, ec->w, ec->h, zone->x, zone->y, zone->w, zone->h))
2208 x = ec->x, y = ec->y;
2210 /* keep window from hanging off bottom and left */
2211 if (x + ec->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + ec->w);
2212 if (y + ec->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + ec->h);
2214 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
2215 if (x < zone->x) x = zone->x;
2216 if (y < zone->y) y = zone->y;
2218 if (!E_INTERSECTS(x, y, ec->w, ec->h, zone->x, zone->y, zone->w, zone->h))
2220 /* still not in zone at all, so just move it to closest edge */
2221 if (x < zone->x) x = zone->x;
2222 if (x >= zone->x + zone->w) x = zone->x + zone->w - ec->w;
2223 if (y < zone->y) y = zone->y;
2224 if (y >= zone->y + zone->h) y = zone->y + zone->h - ec->h;
2226 evas_object_move(ec->frame, x, y);
2229 ec->zone = zone; // FIXME: This line must be deleted.
2233 e_object_ref(E_OBJECT(ec));
2235 e_object_ref(E_OBJECT(zone));
2237 ecore_event_add(E_EVENT_CLIENT_ZONE_SET, ev, (Ecore_End_Cb)_e_client_event_zone_set_free, NULL);
2241 e_zone_client_add(E_Zone *zone, E_Client *ec)
2244 E_Zone_Private_Client *zone_client;
2246 EINA_SAFETY_ON_NULL_RETURN(zone);
2247 EINA_SAFETY_ON_NULL_RETURN(ec);
2248 if (e_zone_has_ec(zone, ec)) return;
2250 ELOGF("ZONE", "CLIENT ADD", ec);
2252 zone_client = E_NEW(E_Zone_Private_Client, 1);
2253 EINA_SAFETY_ON_NULL_RETURN(zone_client);
2255 zone_client->zone = zone;
2256 zone_client->ec = ec;
2258 // e_client listeners
2259 zone_client->client_destroy.notify = _zone_cb_client_destroy;
2260 e_client_destroy_listener_add(ec, &zone_client->client_destroy);
2262 zone_client->client_eval_post_new_client.notify = _zone_cb_client_eval_post_new_client;
2263 e_client_eval_post_new_client_listener_add(ec, &zone_client->client_eval_post_new_client);
2265 zone_client->client_focus_set.notify = _zone_cb_client_focus_set;
2266 e_client_focus_set_listener_add(ec, &zone_client->client_focus_set);
2268 #ifdef REFACTOR_DESK_AREA
2270 zone_client->client_iconify.notify = _zone_cb_client_iconify;
2271 e_client_iconify_listener_add(ec, &zone_client->client_iconify);
2273 zone_client->client_uniconify.notify = _zone_cb_client_uniconify;
2274 e_client_uniconify_listener_add(ec, &zone_client->client_uniconify);
2276 zone_client->client_stick.notify = _zone_cb_client_stick;
2277 e_client_stick_listener_add(ec, &zone_client->client_stick);
2279 zone_client->client_unstick.notify = _zone_cb_client_unstick;
2280 e_client_unstick_listener_add(ec, &zone_client->client_unstick);
2282 zone_client->client_maximize.notify = _zone_cb_client_maximize;
2283 e_client_maximize_listener_add(ec, &zone_client->client_maximize);
2285 zone_client->client_unmaximize.notify = _zone_cb_client_unmaximize;
2286 e_client_unmaximize_listener_add(ec, &zone_client->client_unmaximize);
2288 zone_client->client_activate_done.notify = _zone_cb_client_activate_done;
2289 e_client_activate_done_listener_add(ec, &zone_client->client_activate_done);
2291 zone_client->client_fullscreen.notify = _zone_cb_client_fullscreen;
2292 e_client_fullscreen_listener_add(ec, &zone_client->client_fullscreen);
2294 zone_client->client_unfullscreen.notify = _zone_cb_client_unfullscreen;
2295 e_client_unfullscreen_listener_add(ec, &zone_client->client_unfullscreen);
2298 _e_zone_client_set(zone, ec);
2299 _e_zone_client_data_set(zone, ec);
2301 wl_signal_emit_mutable(&PRI(zone)->events.client_add, ec);
2303 // Currently, ec is set to the current desk now.
2304 // At this moment, ec should not belong to any desk
2305 desk = e_desk_current_get(zone);
2306 e_desk_client_add(desk, ec);
2309 e_client_layer_set(ec, E_LAYER_CLIENT_ABOVE);
2311 e_client_layer_set(ec, E_LAYER_CLIENT_NORMAL);
2313 e_client_res_change_geometry_save(ec);
2314 e_client_res_change_geometry_restore(ec);
2315 ec->pre_res_change.valid = 0;
2319 e_zone_has_ec(E_Zone *zone, E_Client *ec)
2323 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
2325 data = evas_object_data_get(ec->frame, ZONE_EC_DATA_KEY);
2326 if (data == zone) return EINA_TRUE;
2332 e_zone_is_displaying(E_Zone *zone)
2334 Eina_Bool ret = EINA_FALSE;
2336 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
2338 if (zone->display_state == E_ZONE_DISPLAY_STATE_ON)
2344 #ifdef EC_IS_NOT_VISIBLE
2345 # undef EC_IS_NOT_VISIBLE
2347 #define EC_IS_NOT_VISIBLE if (e_client_visibility_get(ec) != E_VISIBILITY_UNOBSCURED)
2350 e_zone_visibility_calculate(E_Zone *zone)
2355 Eina_Rectangle r, *_r;
2357 Eina_Bool canvas_vis = EINA_TRUE;
2358 Eina_Bool ec_vis, ec_opaque, calc_region;
2359 Eina_Bool skip_rot_pending_show = EINA_FALSE;
2360 int skip_by_pending_show = 0;
2361 Eina_Bool is_above_show_pending = EINA_FALSE;
2362 Eina_Bool is_launching_effect = EINA_FALSE;
2363 Eina_Bool is_vis_on_skip = EINA_FALSE;
2365 int x = 0, y = 0, w = 0, h = 0;
2367 E_Comp_Wl_Client_Data *cdata;
2368 Eina_List *changed_list = NULL;
2369 Eina_List *l = NULL;
2370 Eina_Bool effect_running = EINA_FALSE;
2371 Eina_Bool ec_frame_visible = EINA_FALSE;
2372 int calc_skip_type = 0;
2374 Eina_Bool touched_win_changed = EINA_FALSE;
2375 E_Client *touched_ec;
2377 Eina_Bool iconified_by_client = EINA_FALSE;
2378 Eina_Bool e_visibility_changed = EINA_FALSE;
2380 if (!e_config->calc_vis_without_effect)
2382 if (e_comp->animating) return EINA_FALSE;
2385 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
2387 TRACE_DS_BEGIN(CLIENT:VISIBILITY CALCULATE);
2389 t = eina_tiler_new(zone->w + zone->x + edge, zone->h + zone->y + edge);
2390 eina_tiler_tile_size_set(t, 1, 1);
2392 if (e_zone_is_displaying(zone))
2394 EINA_RECTANGLE_SET(&r, zone->x, zone->y, zone->w, zone->h);
2395 eina_tiler_rect_add(t, &r);
2399 canvas_vis = EINA_FALSE;
2402 E_CLIENT_REVERSE_FOREACH(ec)
2405 if (e_object_is_del(E_OBJECT(ec))) continue;
2406 if (e_client_util_ignored_get(ec)) continue;
2407 if (!e_zone_has_ec(zone, ec)) continue;
2408 if (!ec->frame) continue;
2409 if (ec->visibility.skip) continue;
2410 if (ec->is_cursor) continue;
2411 cdata = e_client_cdata_get(ec);
2412 if (e_comp_wl_subsurface_check(ec)) continue;
2413 if ((!ec->first_mapped) &&
2414 (e_comp_object_content_type_get(ec->frame) == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)) continue;
2416 /* TODO: need to check whether window intersects with entire screen, not zone. */
2417 /* if (!E_INTERSECTS(ec->x, ec->y, ec->w, ec->h, zone->x, zone->y, zone->w, zone->h)) continue; */
2419 if (!e_zone_is_displaying(zone))
2421 if ((e_client_visibility_get(ec) == E_VISIBILITY_FULLY_OBSCURED) &&
2422 (ec->visibility.last_sent_type != E_VISIBILITY_FULLY_OBSCURED))
2424 ec->visibility.changed = 1;
2428 if (!e_config->calc_vis_without_effect)
2430 if ((e_comp_object_is_animating(ec->frame)) ||
2431 (evas_object_data_get(ec->frame, "effect_running")))
2433 effect_running = EINA_TRUE;
2435 is_launching_effect = EINA_TRUE;
2440 e_client_geometry_get(ec, &x, &y, &w, &h);
2444 ec_vis = ec_opaque = skip_rot_pending_show = is_vis_on_skip = EINA_FALSE;
2445 skip_by_pending_show = 0;
2446 calc_region = EINA_TRUE;
2447 ec_frame_visible = evas_object_visible_get(ec->frame);
2448 iconified_by_client = e_client_is_iconified_by_client(ec);
2452 EC_IS_NOT_VISIBLE continue;
2453 calc_region = EINA_FALSE;
2454 calc_skip_type |= 0x01;
2456 else if (!ec_frame_visible)
2458 if (ec->e.state.rot.pending_show)
2460 calc_region = EINA_FALSE;
2461 calc_skip_type |= 0x02;
2462 skip_rot_pending_show = EINA_TRUE;
2463 skip_by_pending_show = 1;
2465 else if (ec->show_pending.count > 0)
2467 calc_region = EINA_FALSE;
2468 calc_skip_type |= 0x100;
2469 skip_by_pending_show = 2;
2473 if (cdata && !cdata->mapped)
2475 EC_IS_NOT_VISIBLE continue;
2476 calc_region = EINA_FALSE;
2477 calc_skip_type |= 0x04;
2482 EC_IS_NOT_VISIBLE continue;
2483 calc_region = EINA_FALSE;
2484 calc_skip_type |= 0x08;
2488 if (iconified_by_client)
2490 EC_IS_NOT_VISIBLE continue;
2492 E_Iconified_Type iconified_type;
2493 iconified_type = e_client_iconified_type_get(ec);
2494 if (iconified_type == E_ICONIFIED_TYPE_ICONIFY_BY_CLIENT)
2495 calc_skip_type |= 0x10;
2496 else if (iconified_type == E_ICONIFIED_TYPE_DESK_ICONIFY_BY_CLIENT)
2497 calc_skip_type |= 0x20;
2498 else if (iconified_type == E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT)
2499 calc_skip_type |= 0x40;
2502 ELOGF("POL_VIS", "CRI. Check iconified_type... cur type:%d", ec, iconified_type);
2503 calc_skip_type |= 0x80;
2505 calc_region = EINA_FALSE;
2511 EC_IS_NOT_VISIBLE continue;
2512 calc_region = EINA_FALSE;
2513 calc_skip_type |= 0x200;
2518 if (ec->visibility.ignore_geometry)
2520 calc_region = EINA_FALSE;
2521 if (e_zone_is_displaying(zone) && ec_frame_visible)
2528 (!ec->visibility.force_obscured) &&
2529 (!ec->iconic || (ec->iconic && (!iconified_by_client))))
2531 it = eina_tiler_iterator_new(t);
2532 EINA_ITERATOR_FOREACH(it, _r)
2534 if (E_INTERSECTS(x, y, w, h,
2535 _r->x, _r->y, _r->w, _r->h))
2541 eina_iterator_free(it);
2547 /* unobscured case */
2550 if ((!is_above_show_pending) &&
2551 ((!effect_running) ||
2552 ((effect_running) && (!is_launching_effect))))
2554 /* previous state is obscured: -1 or 1 */
2555 e_client_visibility_set(ec, E_VISIBILITY_UNOBSCURED);
2556 ec->visibility.changed = 1;
2557 ELOGF("POL_VIS", "CLIENT VIS ON. argb:%d, opaque:%2d, frame_v:%d, ignore_geometry:%d, cdata:%p, geo(%d,%d,%dx%d), asp:%d, er:%d, le:%d", ec, ec->argb, ec->visibility.opaque, ec_frame_visible, ec->visibility.ignore_geometry, cdata, x, y, w, h, is_above_show_pending, effect_running, is_launching_effect);
2561 if (!is_above_show_pending)
2562 is_vis_on_skip = EINA_TRUE;
2563 ELOGF("POL_VIS", "CLIENT VIS ON-SKIP. argb:%d, opaque:%2d, frame_v:%d, ignore_geometry:%d, cdata:%p, geo(%d,%d,%dx%d), asp:%d, er:%d, le:%d", ec, ec->argb, ec->visibility.opaque, ec_frame_visible, ec->visibility.ignore_geometry, cdata, x, y, w, h, is_above_show_pending, effect_running, is_launching_effect);
2567 /* subtract window region from canvas region */
2568 if (canvas_vis && !skip_by_pending_show && !is_vis_on_skip)
2570 /* check alpha window is opaque or not. */
2571 if ((ec->visibility.opaque > 0) && (ec->argb))
2572 ec_opaque = EINA_TRUE;
2574 /* if e_client is not alpha or opaque then delete intersect rect */
2575 if (((!ec->argb) || (ec_opaque)) &&
2578 EINA_RECTANGLE_SET(&r,
2583 eina_tiler_rect_del(t, &r);
2585 if (eina_tiler_empty(t))
2586 canvas_vis = EINA_FALSE;
2592 /* It prevents unwanted iconification of the top visible window
2593 * while showing an window with rotation mode.
2594 * However, with rotation mode, iconification is done if client
2595 * is iconified by itself.
2597 if ((!skip_by_pending_show) ||
2598 (ec->visibility.force_obscured) ||
2600 (iconified_by_client))
2603 if (e_client_visibility_get(ec) != E_VISIBILITY_FULLY_OBSCURED)
2605 /* previous state is unobscured: -1 or 0 */
2606 e_client_visibility_set(ec, E_VISIBILITY_FULLY_OBSCURED);
2607 ec->visibility.changed = 1;
2608 ELOGF("POL_VIS", "CLIENT VIS OFF. argb:%d, opaque:%2d, frame_v:%d, canvas_v:%d, calc_r:%d(%d), ignore_geometry:%d, show_p:%d, geo(%d,%d,%dx%d)",
2609 ec, ec->argb, ec->visibility.opaque,
2610 ec_frame_visible, canvas_vis, calc_region, calc_skip_type, ec->visibility.ignore_geometry, skip_by_pending_show, x, y, w, h);
2615 if (!is_vis_on_skip &&
2616 (!skip_rot_pending_show || ec->visibility.changed))
2617 changed_list = eina_list_append(changed_list, ec);
2619 if (skip_rot_pending_show)
2621 if (ec->e.state.rot.pending_show && !ec->argb)
2622 is_above_show_pending = EINA_TRUE;
2623 ELOGF("POL_VIS", "Rotation pending show. srps:%d, rps:%d, argb:%d, asp:%d", ec, skip_rot_pending_show, ec->e.state.rot.pending_show, ec->argb, is_above_show_pending);
2629 touched_ec = e_comp_wl->ptr.ec ? e_comp_wl->ptr.ec : e_comp_wl->touch.faked_ec;
2630 EINA_LIST_FOREACH(changed_list, l, ec)
2632 e_client_visibility_change_notify(ec);
2634 if (ec == touched_ec)
2635 touched_win_changed = EINA_TRUE;
2637 if (e_client_visibility_get(ec) == E_VISIBILITY_UNOBSCURED)
2639 if (e_comp_wl->touch.pressed && !touched_win_changed && !e_policy_client_is_keyboard_sub(ec))
2641 if (e_client_visibility_touched_check(ec))
2643 touched_win_changed = EINA_TRUE;
2644 e_comp_wl_touch_cancel();
2649 ec->visibility.changed = 0;
2650 e_visibility_changed = EINA_TRUE;
2653 changed_list = eina_list_free(changed_list);
2657 // FIXME: need to notify a hook call for zone, not for client
2658 e_client_visibility_end_notify();
2662 return e_visibility_changed;
2666 e_zone_desk_find_by_ec(E_Zone *zone, E_Client *ec)
2670 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, NULL);
2671 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
2673 n = zone->desk_y_count * zone->desk_x_count;
2674 for (i = 0; i < n; i++)
2676 if (e_desk_has_ec(zone->desks[i], ec))
2677 return zone->desks[i];
2685 e_zone_focus_clear(E_Zone *zone)
2687 EINA_SAFETY_ON_NULL_RETURN(zone);
2689 wl_signal_emit_mutable(&PRI(zone)->events.focus_clear, NULL);
2693 e_zone_focus_reset(E_Zone *zone)
2695 EINA_SAFETY_ON_NULL_RETURN(zone);
2697 wl_signal_emit_mutable(&PRI(zone)->events.focus_reset, NULL);
2701 e_zone_client_add_listener_add(E_Zone *zone, struct wl_listener *listener)
2704 wl_signal_add(&priv->events.client_add, listener);
2708 e_zone_client_remove_listener_add(E_Zone *zone, struct wl_listener *listener)
2711 wl_signal_add(&priv->events.client_remove, listener);
2715 e_zone_display_state_change_listener_add(E_Zone *zone, struct wl_listener *listener)
2718 wl_signal_add(&priv->events.display_state_change, listener);
2722 e_zone_focus_clear_listener_add(E_Zone *zone, struct wl_listener *listener)
2725 wl_signal_add(&priv->events.focus_clear, listener);
2729 e_zone_focus_reset_listener_add(E_Zone *zone, struct wl_listener *listener)
2732 wl_signal_add(&priv->events.focus_reset, listener);