1 #include "e_policy_intern.h"
2 #include "e_policy_wl_intern.h"
3 #include "e_policy_conformant_intern.h"
4 #include "e_policy_visibility_intern.h"
5 #include "e_policy_private_data.h"
6 #include "services/e_service_quickpanel_intern.h"
7 #include "e_comp_wl_subsurface_intern.h"
8 #include "e_comp_intern.h"
9 #include "e_pixmap_intern.h"
10 #include "e_client_intern.h"
11 #include "e_desk_intern.h"
12 #include "e_zone_intern.h"
13 #include "e_config_intern.h"
14 #include "e_utils_intern.h"
16 E_Policy *e_policy = NULL;
17 Eina_Hash *hash_policy_desks = NULL;
18 Eina_Hash *hash_policy_clients = NULL;
19 E_Policy_System_Info e_policy_system_info =
25 static int _e_policy_interceptors_walking = 0;
26 static int _e_policy_interceptors_delete = 0;
28 E_Policy_Interceptor *_e_policy_interceptors[] =
30 [E_POLICY_INTERCEPT_LAUNCHSCREEN_OBJECT_SETUP] = NULL,
31 [E_POLICY_INTERCEPT_STACK_TRANSIENT_FOR] = NULL,
32 [E_POLICY_INTERCEPT_ACTIVATE_ABOVE] = NULL,
33 [E_POLICY_INTERCEPT_ACTIVATE_BELOW] = NULL,
34 [E_POLICY_INTERCEPT_SEND_PRE_VISIBILITY] = NULL,
37 static Eina_List *handlers = NULL;
38 static Eina_List *hooks_ec = NULL;
39 static Eina_List *hooks_cp = NULL;
40 static Ecore_Idle_Enterer *_e_pol_idle_enterer = NULL;
41 static Eina_Bool _e_pol_changed_vis = EINA_FALSE;
42 static Eina_List *_e_pol_changed_zone = NULL;
43 static int _e_policy_hooks_delete = 0;
44 static int _e_policy_hooks_walking = 0;
46 static Eina_Inlist *_e_policy_hooks[] =
48 [E_POLICY_HOOK_CLIENT_POSITION_SET] = NULL,
49 [E_POLICY_HOOK_CLIENT_ACTIVE_REQ] = NULL,
50 [E_POLICY_HOOK_CLIENT_RAISE_REQ] = NULL,
51 [E_POLICY_HOOK_CLIENT_LOWER_REQ] = NULL,
52 [E_POLICY_HOOK_CLIENT_ICONIFY_REQ] = NULL,
53 [E_POLICY_HOOK_CLIENT_UNICONIFY_REQ] = NULL,
54 [E_POLICY_HOOK_CLIENT_NOTILAYER_SET] = NULL,
55 [E_POLICY_HOOK_CLIENT_RAISE_REQ_DONE] = NULL,
56 [E_POLICY_HOOK_CLIENT_ROTATION_GEOMETRY_SET] = NULL,
57 [E_POLICY_HOOK_CLIENT_STACK_MODE_SET] = NULL,
58 [E_POLICY_HOOK_CLIENT_AUX_HINT_CHANGED] = NULL,
59 [E_POLICY_HOOK_CLIENT_TYPE_SET] = NULL,
62 E_API int E_EVENT_POLICY_QUICKPANEL_VISIBLE_STATE_CHANGE = -1;
64 static void _e_policy_client_del(E_Policy_Client *pc);
65 static Eina_Bool _e_policy_client_normal_check(E_Client *ec);
66 static Eina_Bool _e_policy_client_maximize_policy_apply(E_Policy_Client *pc);
67 static void _e_policy_client_maximize_policy_cancel(E_Policy_Client *pc);
68 static void _e_policy_client_floating_policy_apply(E_Policy_Client *pc);
69 static void _e_policy_client_floating_policy_cancel(E_Policy_Client *pc);
70 static void _e_policy_client_launcher_set(E_Policy_Client *pc);
71 static void _e_policy_desk_client_add_hook_add(E_Policy_Client *pc);
72 static void _e_policy_desk_client_add_hook_delete(E_Policy_Client *pc);
74 static void _e_policy_cb_hook_client_eval_pre_new_client(void *d EINA_UNUSED, E_Client *ec);
75 static void _e_policy_cb_hook_client_eval_pre_fetch(void *d EINA_UNUSED, E_Client *ec);
76 static void _e_policy_cb_hook_client_eval_pre_post_fetch(void *d EINA_UNUSED, E_Client *ec);
77 static void _e_policy_cb_hook_client_eval_post_fetch(void *d EINA_UNUSED, E_Client *ec);
78 static void _e_policy_cb_hook_client_eval_post_new_client(void *d EINA_UNUSED, E_Client *ec);
80 static void _e_policy_cb_hook_pixmap_del(void *data EINA_UNUSED, E_Pixmap *cp);
81 static void _e_policy_cb_hook_pixmap_unusable(void *data EINA_UNUSED, E_Pixmap *cp);
83 static void _e_policy_cb_desk_data_free(void *data);
84 static void _e_policy_cb_client_data_free(void *data);
85 static Eina_Bool _e_policy_cb_zone_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
86 static Eina_Bool _e_policy_cb_zone_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
87 static Eina_Bool _e_policy_cb_zone_move_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
88 static Eina_Bool _e_policy_cb_zone_desk_count_set(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
89 static Eina_Bool _e_policy_cb_zone_display_state_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
90 static Eina_Bool _e_policy_cb_zone_useful_geometry_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
91 static Eina_Bool _e_policy_cb_desk_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
92 static Eina_Bool _e_policy_cb_client_add(void *data EINA_UNUSED, int type, void *event);
93 static Eina_Bool _e_policy_cb_client_move(void *data EINA_UNUSED, int type, void *event);
94 static Eina_Bool _e_policy_cb_client_resize(void *data EINA_UNUSED, int type, void *event);
95 static Eina_Bool _e_policy_cb_client_stack(void *data EINA_UNUSED, int type, void *event);
96 static Eina_Bool _e_policy_cb_client_property(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
97 static Eina_Bool _e_policy_cb_client_vis_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED);
98 static Eina_Bool _e_policy_cb_client_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
99 static Eina_Bool _e_policy_cb_client_hide(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
101 static Eina_Bool _e_policy_cb_idle_enterer(void *data EINA_UNUSED);
104 _e_policy_client_launcher_set(E_Policy_Client *pc)
106 E_Policy_Client *pc2;
110 EINA_SAFETY_ON_NULL_RETURN(zone);
112 pc2 = e_policy_client_launcher_get(zone);
115 if (pc->ec->netwm.type != e_config->launcher.type)
118 #if defined(__cplusplus) || defined(c_plusplus)
119 if (e_util_strcmp(pc->ec->icccm.cpp_class,
120 e_config->launcher.clas))
123 if (e_util_strcmp(pc->ec->icccm.class,
124 e_config->launcher.clas))
128 if (e_util_strcmp(pc->ec->icccm.title,
129 e_config->launcher.title))
131 /* check netwm name instead, because comp_x had ignored
132 * icccm name when fetching */
133 if (e_util_strcmp(pc->ec->netwm.name,
134 e_config->launcher.title))
140 e_policy->launchers = eina_list_append(e_policy->launchers, pc);
144 _e_policy_cb_hook_desk_client_add(void *d, E_Desk *desk)
150 EINA_SAFETY_ON_NULL_RETURN(desk);
152 pc = (E_Policy_Client *)d;
153 EINA_SAFETY_ON_NULL_RETURN(pc);
156 EINA_SAFETY_ON_NULL_GOTO(ec, delete_hook);
158 if (!e_desk_has_ec(desk, ec)) goto delete_hook;
160 if (e_object_is_del(E_OBJECT(ec))) goto delete_hook;
161 if (!_e_policy_client_normal_check(ec)) goto delete_hook;
162 if (ec->internal) goto delete_hook;
163 if (ec->new_client) goto delete_hook;
165 pd = eina_hash_find(hash_policy_desks, &desk);
167 _e_policy_client_maximize_policy_apply(pc);
169 _e_policy_client_maximize_policy_cancel(pc);
172 // This function should be executed once when e_client adds on a desk.
173 // Therefore, delete the desk_hooks.client_add.
174 _e_policy_desk_client_add_hook_delete(pc);
178 _e_policy_desk_client_add_hook_add(E_Policy_Client *pc)
180 pc->desk_hooks.client_add = e_desk_hook_add(E_DESK_HOOK_CLIENT_ADD, _e_policy_cb_hook_desk_client_add, pc);
184 _e_policy_desk_client_add_hook_delete(E_Policy_Client *pc)
186 if (pc->desk_hooks.client_add)
188 e_desk_hook_del(pc->desk_hooks.client_add);
189 pc->desk_hooks.client_add = NULL;
194 _e_policy_client_del(E_Policy_Client *pc)
196 _e_policy_desk_client_add_hook_delete(pc);
198 eina_hash_del_by_key(hash_policy_clients, &pc->ec);
202 _e_policy_client_normal_check(E_Client *ec)
206 if ((e_client_util_ignored_get(ec)) ||
212 if (e_policy_client_is_quickpanel(ec))
217 if (e_policy_client_is_keyboard(ec) ||
218 e_policy_client_is_keyboard_sub(ec))
220 e_policy_keyboard_layout_apply(ec);
223 else if (e_policy_client_is_volume_tv(ec))
225 else if (!e_util_strcmp("e_demo", ec->icccm.window_role))
227 else if (e_policy_client_is_floating(ec))
229 pc = eina_hash_find(hash_policy_clients, &ec);
230 _e_policy_client_maximize_policy_cancel(pc);
231 _e_policy_client_floating_policy_apply(pc);
234 else if (e_policy_client_is_subsurface(ec))
237 if ((ec->netwm.type == E_WINDOW_TYPE_NORMAL) ||
238 (ec->netwm.type == E_WINDOW_TYPE_UNKNOWN) ||
239 (ec->netwm.type == E_WINDOW_TYPE_NOTIFICATION))
247 pc = eina_hash_find(hash_policy_clients, &ec);
248 _e_policy_client_maximize_policy_cancel(pc);
254 _e_policy_client_maximize_pre(E_Policy_Client *pc)
265 desk = e_zone_desk_find_by_ec(zone, ec);
266 EINA_SAFETY_ON_NULL_RETURN(desk);
269 e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
282 e_client_pos_set(ec, zx, zy);
283 e_client_size_set(ec, zw, zh);
288 _e_policy_client_maximize_policy_apply(E_Policy_Client *pc)
292 if (!pc) return EINA_FALSE;
294 if (pc->max_policy_state) return EINA_TRUE;
295 if (pc->allow_user_geom) return EINA_FALSE;
298 if (ec->netwm.type == E_WINDOW_TYPE_UTILITY) return EINA_FALSE;
300 pc->max_policy_state = EINA_TRUE;
303 # define _SET(a) pc->orig.a = pc->ec->a
307 _SET(lock_user_location);
308 _SET(lock_client_location);
309 _SET(lock_user_size);
310 _SET(lock_client_size);
311 _SET(lock_client_stacking);
312 _SET(lock_user_maximize);
313 _SET(lock_client_maximize);
314 _SET(lock_user_fullscreen);
315 _SET(lock_client_fullscreen);
318 _e_policy_client_launcher_set(pc);
323 ec->border.changed = 1;
329 /* This is added to support e_desk_geometry_set().
330 * The geometry of client is calculated based on E_Desk by
331 * e_client_maximize() from now.
332 * But, if we don't set ec->placed, geometry of new client will be
333 * calculated again based on E_Zone by _e_client_eval().
334 * FIXME: we can delete it if calculation of placement is based on
338 if ((e_policy_client_is_home_screen(ec)) ||
339 (e_policy_client_is_lockscreen(ec)) ||
340 (e_policy_client_is_quickpanel(ec)) ||
341 (e_policy_client_is_taskbar(ec)))
343 ec->maximize_type = E_MAXIMIZE_TYPE_FULLSCREEN;
344 ec->maximize_dir = E_MAXIMIZE_DIRECTION_ALL;
348 ec->maximize_type = E_MAXIMIZE_EXPAND;
349 ec->maximize_dir = E_MAXIMIZE_DIRECTION_ALL;
352 e_client_maximize(ec, ec->maximize_type | ec->maximize_dir);
354 if (ec->changes.need_maximize)
355 _e_policy_client_maximize_pre(pc);
358 /* do not allow client to change these properties */
359 ec->lock_user_location = 1;
360 ec->lock_client_location = 1;
361 ec->lock_user_size = 1;
363 if (!e_policy_client_is_home_screen(ec))
364 ec->lock_client_stacking = 1;
370 _e_policy_client_maximize_policy_cancel(E_Policy_Client *pc)
373 Eina_Bool changed = EINA_FALSE;
376 if (!pc->max_policy_state) return;
378 pc->max_policy_state = EINA_FALSE;
382 if (pc->orig.borderless != ec->borderless)
384 ec->border.changed = 1;
388 if ((pc->orig.fullscreen != ec->fullscreen) &&
389 (pc->orig.fullscreen))
391 ec->need_fullscreen = 1;
395 if (pc->orig.maximized != ec->maximized)
397 if (pc->orig.maximized)
398 ec->changes.need_maximize = 1;
400 e_client_unmaximize(ec, ec->maximized);
405 /* floating mode ec which was launched with fake image is not borderless value.
406 * thus, we should set borderless value to 1 for this ec to prevent choppy
407 * movement of the window when moving the window.
411 pc->orig.borderless = 1;
416 # define _SET(a) ec->a = pc->orig.a
420 _SET(lock_user_location);
421 _SET(lock_client_location);
422 _SET(lock_user_size);
423 _SET(lock_client_size);
424 _SET(lock_client_stacking);
425 _SET(lock_user_maximize);
426 _SET(lock_client_maximize);
427 _SET(lock_user_fullscreen);
428 _SET(lock_client_fullscreen);
431 ec->skip_fullscreen = 0;
433 /* only set it if the border is changed or fullscreen/maximize has changed */
437 e_policy->launchers = eina_list_remove(e_policy->launchers, pc);
441 _e_policy_client_dialog_policy_apply(E_Policy_Client *pc)
450 ec->skip_fullscreen = 1;
451 ec->lock_client_stacking = 1;
452 ec->lock_user_maximize = 1;
453 ec->lock_client_maximize = 1;
454 ec->lock_user_fullscreen = 1;
455 ec->lock_client_fullscreen = 1;
460 e_client_base_output_resolution_useful_geometry_get(ec, &zx, &zy, &zw, &zh);
462 x = zx + ((zw - w) / 2);
463 y = zy + ((zh - h) / 2);
465 if ((x != ec->x) || (y != ec->y))
466 evas_object_move(ec->frame, x, y);
470 _e_policy_client_floating_policy_apply(E_Policy_Client *pc)
473 if (pc->flt_policy_state) return;
475 pc->flt_policy_state = EINA_TRUE;
479 _e_policy_client_floating_policy_cancel(E_Policy_Client *pc)
482 if (!pc->flt_policy_state) return;
484 pc->flt_policy_state = EINA_FALSE;
487 E_Config_Policy_Desk *
488 _e_policy_desk_get_by_num(unsigned int zone_num, int x, int y)
491 E_Config_Policy_Desk *d2;
493 EINA_LIST_FOREACH(e_config->policy_desks, l, d2)
495 if ((d2->zone_num == zone_num) &&
496 (d2->x == x) && (d2->y == y))
506 _e_policy_cb_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
510 if (EINA_UNLIKELY(!ec))
513 pc = eina_hash_find(hash_policy_clients, &ec);
515 if (!pc->zone) return;
518 e_tzsh_indicator_srv_ower_win_update(pc->zone);
519 e_policy_wl_win_brightness_apply(pc->ec);
520 e_policy_wl_client_del(pc->ec);
522 if (e_policy_client_is_lockscreen(pc->ec))
523 e_policy_stack_clients_restack_above_lockscreen(pc->ec, EINA_FALSE);
525 e_policy_stack_cb_client_remove(pc->ec);
526 e_comp_visibility_calculation_set(EINA_TRUE);
528 _e_policy_client_del(pc);
532 _e_policy_cb_hook_client_eval_pre_new_client(void *d EINA_UNUSED, E_Client *ec)
536 if (e_object_is_del(E_OBJECT(ec))) return;
538 if (e_policy_client_is_keyboard_sub(ec))
541 ec->exp_iconify.skip_iconify = EINA_TRUE;
543 EINA_SAFETY_ON_NULL_RETURN(ec->frame);
544 if (ec->layer < E_LAYER_CLIENT_ABOVE)
545 e_client_layer_set(ec, E_LAYER_CLIENT_ABOVE);
547 if (e_policy_client_is_noti(ec))
551 ly = evas_object_layer_get(ec->frame);
552 ELOGF("NOTI", " |ec->layer:%d object->layer:%d", ec, ec->layer, ly);
554 e_client_layer_set(ec, ec->layer);
558 if (e_policy_client_is_dialog(ec))
560 if (ec->frame && !ec->parent)
562 if (ec->layer != E_POLICY_DIALOG_LAYER)
563 e_client_layer_set(ec, E_POLICY_DIALOG_LAYER);
567 if (e_policy_client_is_floating(ec))
571 if (ec->layer != E_LAYER_CLIENT_ABOVE)
572 e_client_layer_set(ec, E_LAYER_CLIENT_ABOVE);
576 if (e_policy_client_is_toast_popup(ec))
580 if (ec->layer != E_POLICY_TOAST_POPUP_LAYER)
581 e_client_layer_set(ec, E_POLICY_TOAST_POPUP_LAYER);
584 if (e_policy_client_is_cbhm(ec))
586 ec->exp_iconify.skip_iconify = EINA_TRUE;
589 if (e_policy_client_is_magnifier(ec))
591 if (ec->layer != E_LAYER_CLIENT_ALERT_HIGH)
592 e_client_layer_set(ec, E_LAYER_CLIENT_ALERT_HIGH);
597 _e_policy_cb_hook_client_eval_pre_fetch(void *d EINA_UNUSED, E_Client *ec)
599 if (e_object_is_del(E_OBJECT(ec))) return;
601 e_policy_stack_transient_for_fetch(ec);
605 _e_policy_cb_hook_client_eval_pre_post_fetch(void *d EINA_UNUSED, E_Client *ec)
607 if (e_object_is_del(E_OBJECT(ec))) return;
609 e_policy_wl_notification_level_fetch(ec);
613 _e_policy_cb_hook_client_eval_post_fetch(void *d EINA_UNUSED, E_Client *ec)
620 if (e_object_is_del(E_OBJECT(ec))) return;
621 /* Following E_Clients will be added to module hash and will be managed.
623 * - Not new client: Updating internal info of E_Client has been finished
624 * by e main evaluation, thus module can classify E_Client and manage it.
626 * - New client that has valid buffer: This E_Client has been passed e main
627 * evaluation, and it has handled first wl_surface::commit request.
629 if ((ec->new_client) && (!e_pixmap_usable_get(ec->pixmap))) return;
631 pc = eina_hash_find(hash_policy_clients, &ec);
637 desk = e_zone_desk_find_by_ec(zone, ec);
640 if (e_policy_client_is_keyboard(ec) ||
641 e_policy_client_is_keyboard_sub(ec))
643 _e_policy_client_maximize_policy_cancel(pc);
644 e_policy_keyboard_layout_apply(ec);
647 if (!e_util_strcmp("wl_pointer-cursor", ec->icccm.window_role))
649 _e_policy_client_maximize_policy_cancel(pc);
653 if (e_policy_client_is_floating(ec))
655 _e_policy_client_maximize_policy_cancel(pc);
656 _e_policy_client_floating_policy_apply(pc);
660 if (e_policy_client_is_dialog(ec))
662 _e_policy_client_maximize_policy_cancel(pc);
663 _e_policy_client_dialog_policy_apply(pc);
667 if (!_e_policy_client_normal_check(ec)) return;
669 pd = eina_hash_find(hash_policy_desks, &desk);
672 pc = eina_hash_find(hash_policy_clients, &ec);
675 if (pc->flt_policy_state)
676 _e_policy_client_floating_policy_cancel(pc);
678 _e_policy_client_maximize_policy_apply(pc);
682 _e_policy_cb_hook_client_eval_post_new_client(void *d EINA_UNUSED, E_Client *ec)
687 if (e_object_is_del(E_OBJECT(ec))) return;
688 if ((ec->new_client) && (!e_pixmap_usable_get(ec->pixmap))) return;
690 pc = eina_hash_find(hash_policy_clients, &ec);
691 EINA_SAFETY_ON_NULL_RETURN(pc);
693 EINA_SAFETY_ON_NULL_RETURN(zone);
695 if (e_policy_client_is_lockscreen(ec))
696 e_policy_stack_clients_restack_above_lockscreen(ec, EINA_TRUE);
700 _e_policy_cb_hook_client_visibility(void *d EINA_UNUSED, E_Client *ec)
707 pc = eina_hash_find(hash_policy_clients, &ec);
708 EINA_SAFETY_ON_NULL_RETURN(pc);
710 EINA_SAFETY_ON_NULL_RETURN(zone);
712 if (ec->visibility.changed)
714 if (e_client_visibility_get(ec) == E_VISIBILITY_UNOBSCURED)
716 e_policy_client_uniconify_by_visibility(ec);
717 if ((ec->iconic == 0) && (ec->exp_iconify.last_sent_iconic != 0))
718 e_policy_wl_iconify_state_change_send(ec, 0);
719 if (ec->visibility.last_sent_type != E_VISIBILITY_PRE_UNOBSCURED)
721 ELOGF("POL_VIS", "SEND pre-unobscured visibility event", ec);
722 e_vis_client_send_pre_visibility_event(ec);
724 e_policy_client_visibility_send(ec);
728 if (e_policy_visibility_client_is_uniconify_render_running(ec))
730 ELOGF("POL_VIS", "cancel uniconify by visibility job", ec);
731 e_policy_visibility_client_uniconify_by_visibility_job_cancel(ec);
732 if ((ec->iconic == 1) && (ec->exp_iconify.last_sent_iconic == 0))
733 e_policy_wl_iconify_state_change_send(ec, 1);
735 e_policy_client_visibility_send(ec);
736 e_policy_client_iconify_by_visibility(ec);
739 e_policy_wl_win_brightness_apply(ec);
741 _e_pol_changed_vis = EINA_TRUE;
742 if (!eina_list_data_find(_e_pol_changed_zone, zone))
743 _e_pol_changed_zone = eina_list_append(_e_pol_changed_zone, zone);
747 if (e_client_visibility_get(ec) == E_VISIBILITY_FULLY_OBSCURED)
749 Eina_Bool obscured_by_alpha_opaque = EINA_FALSE;
750 Eina_Bool find_above = EINA_FALSE;
754 if (e_comp_client_zone_is_displaying(ec))
756 e_client_geometry_get(ec, &ex, &ey, &ew, &eh);
757 // crop ec size with zone size
758 E_RECTS_CLIP_TO_RECT(ex, ey, ew, eh, zone->x, zone->y, zone->w, zone->h);
760 if (!E_INTERSECTS(zone->x, zone->y, zone->w, zone->h, ex, ey, ew, eh))
762 if (ec->visibility.last_sent_type == E_VISIBILITY_PRE_UNOBSCURED)
764 ELOGF("POL_VIS", "SEND unobscured/fully-obscured visibility event because iconify visibility", ec);
765 e_policy_wl_visibility_send(ec, E_VISIBILITY_UNOBSCURED);
766 e_policy_wl_visibility_send(ec, E_VISIBILITY_FULLY_OBSCURED);
768 e_policy_client_iconify_by_visibility(ec);
772 for (o = evas_object_above_get(ec->frame); o; o = evas_object_above_get(o))
774 above_ec = evas_object_data_get(o, "E_Client");
775 if (!above_ec) continue;
776 if (e_client_util_ignored_get(above_ec)) continue;
777 if (!above_ec->visible) continue;
779 if (e_client_is_iconified_by_client(above_ec)) continue;
780 if (above_ec->exp_iconify.skip_by_remote) continue;
781 if (above_ec->bg_state) continue;
785 if (above_ec->visibility.opaque <= 0)
789 if (!above_ec->iconic)
790 obscured_by_alpha_opaque = EINA_TRUE;
794 find_above = EINA_TRUE;
796 e_client_geometry_get(above_ec, &ax, &ay, &aw, &ah);
797 if (E_CONTAINS(ax, ay, aw, ah, ex, ey, ew, eh))
801 if (!find_above) return;
802 if (ec->visibility.last_sent_type == E_VISIBILITY_PRE_UNOBSCURED)
804 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
806 ELOGF("POL_VIS", "SEND unobscured/fully-obscured visibility event because iconify visibility", ec);
807 e_policy_wl_visibility_send(ec, E_VISIBILITY_UNOBSCURED);
808 e_policy_wl_visibility_send(ec, E_VISIBILITY_FULLY_OBSCURED);
811 if (obscured_by_alpha_opaque)
813 e_policy_client_uniconify_by_visibility(ec);
817 e_policy_client_iconify_by_visibility(ec);
822 e_policy_client_iconify_by_visibility(ec);
829 _e_policy_cb_hook_client_uniconify(void *d EINA_UNUSED, E_Client *ec)
831 if (e_object_is_del(E_OBJECT(ec))) return;
832 if (!e_policy_wl_iconify_state_supported_get(ec))
834 ELOGF("TZPOL", "Force Update the client not supporting iconify state",
837 /* force render for an iconifed e_client having shm buffer not used yet*/
838 if ((e_pixmap_image_data_get(ec->pixmap)) &&
839 (!e_pixmap_dirty_get(ec->pixmap)))
841 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
842 e_comp_object_dirty(ec->frame);
843 e_comp_object_render(ec->frame);
849 _e_policy_cb_hook_pixmap_del(void *data EINA_UNUSED, E_Pixmap *cp)
851 e_policy_wl_pixmap_del(cp);
855 _e_policy_cb_hook_pixmap_unusable(void *data EINA_UNUSED, E_Pixmap *cp)
857 E_Client *ec = (E_Client *)e_pixmap_client_get(cp);
860 if (!ec->iconic) return;
861 if (e_client_is_iconified_by_client(ec)) return;
862 if (ec->exp_iconify.skip_iconify) return;
863 if (ec->exp_iconify.skip_by_remote) return;
864 if (ec->remote_surface.bind_ref > 0) return;
866 e_policy_client_unmap(ec);
870 _e_policy_cb_desk_data_free(void *data)
876 _e_policy_cb_client_data_free(void *data)
882 _e_policy_cb_zone_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
884 E_Event_Zone_Add *ev;
886 E_Config_Policy_Desk *d;
887 E_Policy_Softkey *softkey;
892 n = zone->desk_y_count * zone->desk_x_count;
893 for (i = 0; i < n; i++)
895 if (e_config->use_configured_desks)
897 d = _e_policy_desk_get_by_num(zone->num,
901 e_policy_desk_add(zone->desks[i]);
904 e_policy_desk_add(zone->desks[i]);
907 /* add and show softkey */
908 if (e_config->use_softkey)
910 softkey = e_policy_softkey_get(zone);
912 softkey = e_policy_softkey_add(zone);
915 return ECORE_CALLBACK_PASS_ON;
919 _e_policy_cb_zone_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
921 E_Event_Zone_Del *ev;
924 E_Policy_Softkey *softkey;
930 n = zone->desk_y_count * zone->desk_x_count;
931 for (i = 0; i < n; i++)
933 pd = eina_hash_find(hash_policy_desks, &zone->desks[i]);
934 if (pd) e_policy_desk_del(pd);
937 /* add and show softkey */
938 if (e_config->use_softkey)
940 softkey = e_policy_softkey_get(zone);
942 e_policy_softkey_del(softkey);
945 return ECORE_CALLBACK_PASS_ON;
949 _e_policy_cb_zone_move_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
951 E_Event_Zone_Move_Resize *ev;
952 E_Policy_Softkey *softkey;
955 if (!ev) return ECORE_CALLBACK_PASS_ON;
957 if (e_config->use_softkey)
959 softkey = e_policy_softkey_get(ev->zone);
960 e_policy_softkey_update(softkey);
963 return ECORE_CALLBACK_PASS_ON;
967 _e_policy_cb_zone_desk_count_set(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
969 E_Event_Zone_Desk_Count_Set *ev;
974 E_Config_Policy_Desk *d;
977 Eina_List *desks_del = NULL;
982 /* remove deleted desk from hash */
983 it = eina_hash_iterator_data_new(hash_policy_desks);
984 while (eina_iterator_next(it, (void **)&pd))
986 if (pd->zone != zone) continue;
989 n = zone->desk_y_count * zone->desk_x_count;
990 for (i = 0; i < n; i++)
992 if (pd->desk == zone->desks[i])
999 desks_del = eina_list_append(desks_del, pd->desk);
1001 eina_iterator_free(it);
1003 EINA_LIST_FREE(desks_del, desk)
1005 pd = eina_hash_find(hash_policy_desks, &desk);
1006 if (pd) e_policy_desk_del(pd);
1009 /* add newly added desk to hash */
1010 n = zone->desk_y_count * zone->desk_x_count;
1011 for (i = 0; i < n; i++)
1013 if (e_config->use_configured_desks)
1015 d = _e_policy_desk_get_by_num(zone->num,
1019 e_policy_desk_add(zone->desks[i]);
1022 e_policy_desk_add(zone->desks[i]);
1025 return ECORE_CALLBACK_PASS_ON;
1029 _e_policy_cb_zone_display_state_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1031 E_Event_Zone_Display_State_Change *ev;
1034 if (!ev) return ECORE_CALLBACK_PASS_ON;
1036 e_comp_visibility_calculation_set(EINA_TRUE);
1038 return ECORE_CALLBACK_PASS_ON;
1042 _e_policy_cb_zone_useful_geometry_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1044 E_Event_Zone_Useful_Geometry_Change *ev;
1045 E_Policy_Client *pc;
1049 if (!ev) return ECORE_CALLBACK_PASS_ON;
1051 E_CLIENT_FOREACH(ec)
1053 pc = eina_hash_find(hash_policy_clients, &ec);
1055 if (ev->zone != pc->zone) continue;
1058 e_client_maximize_update(ec);
1061 return ECORE_CALLBACK_PASS_ON;
1065 _e_policy_cb_desk_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1067 E_Event_Desk_Show *ev;
1068 E_Policy_Softkey *softkey;
1072 if (e_config->use_softkey)
1074 softkey = e_policy_softkey_get(ev->desk->zone);
1076 softkey = e_policy_softkey_add(ev->desk->zone);
1078 if (eina_hash_find(hash_policy_desks, &ev->desk))
1079 e_policy_softkey_show(softkey);
1081 e_policy_softkey_hide(softkey);
1083 return ECORE_CALLBACK_PASS_ON;
1087 _e_policy_cb_client_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1092 EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
1094 e_policy_wl_client_add(ev->ec);
1096 return ECORE_CALLBACK_PASS_ON;
1100 _e_policy_cb_client_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1104 E_Policy_Client *pc;
1115 pc = eina_hash_find(hash_policy_clients, &ec);
1119 if (!zone) goto end;
1121 e_policy_wl_position_send(ec);
1122 e_comp_visibility_calculation_set(EINA_TRUE);
1124 if (e_policy_client_is_lockscreen(ec))
1131 e_client_geometry_get(ec, &ex, &ey, &ew, &eh);
1133 if (E_CONTAINS(ex, ey, ew, eh, zx, zy, zw, zh))
1134 e_policy_stack_clients_restack_above_lockscreen(ev->ec, EINA_TRUE);
1136 e_policy_stack_clients_restack_above_lockscreen(ev->ec, EINA_FALSE);
1140 return ECORE_CALLBACK_PASS_ON;
1144 _e_policy_cb_client_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1148 E_Policy_Client *pc;
1151 ev = (E_Event_Client *)event;
1152 EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
1155 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, ECORE_CALLBACK_PASS_ON);
1157 pc = eina_hash_find(hash_policy_clients, &ec);
1158 EINA_SAFETY_ON_NULL_RETURN_VAL(pc, ECORE_CALLBACK_PASS_ON);
1160 /* re-calculate window's position with changed size */
1161 if (e_policy_client_is_volume_tv(ec))
1163 e_zone_useful_geometry_get(pc->zone, NULL, NULL, NULL, &zh);
1164 evas_object_move(ec->frame, 0, (zh / 2) - (ec->h / 2));
1166 evas_object_pass_events_set(ec->frame, 1);
1169 /* calculate e_client visibility */
1170 e_comp_visibility_calculation_set(EINA_TRUE);
1172 return ECORE_CALLBACK_PASS_ON;
1176 _e_policy_client_stack_change_send(E_Client *ec)
1178 E_Client *above = NULL;
1179 E_Client *below = NULL;
1183 above = e_client_visible_above_get(ec);
1184 below = e_client_visible_below_get(ec);
1186 if (above) above_pid = above->netwm.pid;
1187 if (below) below_pid = below->netwm.pid;
1189 ELOGF("TZPOL", "Send stack change. above(win:%zx, pid:%d), below(win:%zx, pid:%d)",
1190 ec, e_client_util_win_get(above), above_pid, e_client_util_win_get(below), below_pid);
1192 e_policy_aux_message_send_from_int(ec, "stack_changed", "pid", 2, above_pid, below_pid);
1196 _e_policy_cb_client_stack(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1201 if (!ev) return ECORE_CALLBACK_PASS_ON;
1202 /* calculate e_client visibility */
1203 e_comp_visibility_calculation_set(EINA_TRUE);
1205 // send stack change event
1206 _e_policy_client_stack_change_send(ev->ec);
1208 return ECORE_CALLBACK_PASS_ON;
1212 _e_policy_cb_client_property(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1214 E_Event_Client_Property *ev;
1218 if (!ev || (!ev->ec)) return ECORE_CALLBACK_PASS_ON;
1221 if (ev->property & E_CLIENT_PROPERTY_CLIENT_TYPE)
1223 if (e_policy_client_is_home_screen(ec))
1225 ec->lock_client_stacking = 0;
1226 e_client_desk_iconify_skip_set(ec, EINA_TRUE);
1229 ec->maximize_type = E_MAXIMIZE_TYPE_FULLSCREEN;
1230 ec->maximize_dir = E_MAXIMIZE_DIRECTION_ALL;
1231 e_client_maximize(ec, ec->maximize_type | ec->maximize_dir);
1236 return ECORE_CALLBACK_PASS_ON;
1240 _e_policy_cb_client_vis_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
1242 e_policy_wl_win_scrmode_apply();
1243 return ECORE_CALLBACK_PASS_ON;
1247 _e_policy_cb_client_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1253 if (!ev) return ECORE_CALLBACK_PASS_ON;
1256 e_policy_stack_check_above_lockscreen(ec, ec->layer);
1258 return ECORE_CALLBACK_PASS_ON;
1262 _e_policy_cb_client_hide(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1266 E_Policy_Client *pc;
1269 if (!ev) return ECORE_CALLBACK_PASS_ON;
1272 pc = eina_hash_find(hash_policy_clients, &ec);
1273 if (!pc) return ECORE_CALLBACK_PASS_ON;
1275 e_tzsh_indicator_srv_ower_win_update(pc->zone);
1277 return ECORE_CALLBACK_PASS_ON;
1281 _e_policy_cb_client_zone_set(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1283 E_Event_Client_Zone_Set *ev;
1284 E_Policy_Client *pc;
1288 pc = eina_hash_find(hash_policy_clients, &ev->ec);
1292 if (pc->ec != ev->ec)
1295 if (pc->zone == ev->zone)
1298 ELOGF("CBHM", "Change Zone | e_policy %p old(%p) new(%p)",
1299 ev->ec, pc, pc->zone, ev->zone);
1301 pc->zone = ev->zone;
1304 return ECORE_CALLBACK_PASS_ON;
1309 _e_policy_cb_idle_enterer(void *data EINA_UNUSED)
1313 if (_e_pol_changed_vis)
1315 EINA_LIST_FREE(_e_pol_changed_zone, zone)
1317 e_tzsh_indicator_srv_ower_win_update(zone);
1319 _e_pol_changed_zone = NULL;
1321 _e_pol_changed_vis = EINA_FALSE;
1323 return ECORE_CALLBACK_RENEW;
1327 e_policy_desk_add(E_Desk *desk)
1331 E_Policy_Client *pc;
1333 pd = eina_hash_find(hash_policy_desks, &desk);
1336 pd = E_NEW(E_Policy_Desk, 1);
1340 pd->zone = desk->zone;
1342 eina_hash_add(hash_policy_desks, &desk, pd);
1345 E_CLIENT_FOREACH(ec)
1347 if (e_desk_has_ec(pd->desk, ec))
1349 pc = eina_hash_find(hash_policy_clients, &ec);
1350 _e_policy_client_maximize_policy_apply(pc);
1356 e_policy_desk_del(E_Policy_Desk *pd)
1359 E_Policy_Client *pc;
1361 Eina_List *clients_del = NULL;
1362 E_Policy_Softkey *softkey;
1364 /* hide and delete softkey */
1365 if (e_config->use_softkey)
1367 softkey = e_policy_softkey_get(pd->zone);
1368 if (e_desk_current_get(pd->zone) == pd->desk)
1369 e_policy_softkey_hide(softkey);
1372 /* remove clients */
1373 it = eina_hash_iterator_data_new(hash_policy_clients);
1374 while (eina_iterator_next(it, (void **)&pc))
1376 if (e_desk_has_ec(pd->desk, pc->ec))
1377 clients_del = eina_list_append(clients_del, pc->ec);
1379 eina_iterator_free(it);
1381 EINA_LIST_FREE(clients_del, ec)
1383 pc = eina_hash_find(hash_policy_clients, &ec);
1384 _e_policy_client_maximize_policy_cancel(pc);
1387 eina_hash_del_by_key(hash_policy_desks, &pd->desk);
1390 EINTERN E_Policy_Client *
1391 e_policy_client_launcher_get(E_Zone *zone)
1393 E_Policy_Client *pc;
1396 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, NULL);
1398 EINA_LIST_FOREACH(e_policy->launchers, l, pc)
1400 if (pc->zone == zone)
1407 e_policy_client_unmap(E_Client *ec)
1409 Eina_Bool send_event = EINA_FALSE;
1412 if (e_object_is_del(E_OBJECT(ec))) return;
1414 ELOGF("TZPOL", "Reset ec information by unmap", ec);
1417 send_event = EINA_TRUE;
1422 ec->exp_iconify.by_client = 0;
1423 e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_NONE);
1424 ec->exp_iconify.not_raise = 0;
1425 ec->exp_iconify.skip_iconify = 0;
1428 e_policy_wl_iconify_state_change_send(ec, 0);
1430 e_comp_object_effect_set(ec->frame, NULL);
1434 e_policy_client_maximize(E_Client *ec)
1437 E_Policy_Client *pc;
1440 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1441 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1443 if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
1445 if ((e_policy_client_is_keyboard(ec)) ||
1446 (e_policy_client_is_keyboard_sub(ec)) ||
1447 (e_policy_client_is_floating(ec)) ||
1448 (e_policy_client_is_quickpanel(ec)) ||
1449 (e_policy_client_is_volume(ec)) ||
1450 (!e_util_strcmp("wl_pointer-cursor", ec->icccm.window_role)) ||
1451 (!e_util_strcmp("e_demo", ec->icccm.window_role)))
1454 if (e_policy_client_is_subsurface(ec)) return EINA_FALSE;
1456 if ((ec->netwm.type != E_WINDOW_TYPE_NORMAL) &&
1457 (ec->netwm.type != E_WINDOW_TYPE_UNKNOWN) &&
1458 (ec->netwm.type != E_WINDOW_TYPE_NOTIFICATION))
1461 pc = eina_hash_find(hash_policy_clients, &ec);
1462 EINA_SAFETY_ON_NULL_RETURN_VAL(pc, EINA_FALSE);
1464 desk = e_zone_desk_find_by_ec(pc->zone, ec);
1465 EINA_SAFETY_ON_NULL_RETURN_VAL(desk, EINA_FALSE);
1467 pd = eina_hash_find(hash_policy_desks, &desk);
1468 if (!pd) return EINA_FALSE;
1470 if (pc->flt_policy_state)
1471 _e_policy_client_floating_policy_cancel(pc);
1473 return _e_policy_client_maximize_policy_apply(pc);
1477 e_policy_keyboard_layout_apply(E_Client *ec EINA_UNUSED)
1479 /* FIXME: do not resize and move client.
1480 * ec->e.state.rot.geom[].w/h is always 0,
1481 * then the geometry calculated here is not valid. */
1485 int kbd_x, kbd_y, kbd_w, kbd_h;
1486 E_Policy_Client *pc;
1488 if (!e_policy_client_is_keyboard(ec) &&
1489 !e_policy_client_is_keyboard_sub(ec))
1492 angle = e_client_rotation_curr_angle_get(ec);
1496 case 0: angle_id = 0; break;
1497 case 90: angle_id = 1; break;
1498 case 180: angle_id = 2; break;
1499 case 270: angle_id = 3; break;
1500 default: angle_id = 0; break;
1503 kbd_w = ec->e.state.rot.geom[angle_id].w;
1504 kbd_h = ec->e.state.rot.geom[angle_id].h;
1506 pc = eina_hash_find(hash_policy_clients, &ec);
1507 if (!pc->ec) return;
1508 if (!pc->zone) return;
1513 kbd_x = pc->zone->w - kbd_w;
1514 kbd_y = pc->zone->h - kbd_h;
1518 kbd_x = pc->zone->w - kbd_w;
1519 kbd_y = pc->zone->h - kbd_h;
1533 kbd_x = pc->zone->w - kbd_w;
1534 kbd_y = pc->zone->h - kbd_h;
1539 ((ec->w != kbd_w) || (ec->h != kbd_h)))
1540 e_client_util_resize_without_frame(ec, kbd_w, kbd_h);
1542 if ((e_policy_client_is_keyboard(ec)) &&
1544 ((ec->x != kbd_x) || (ec->y != kbd_y)))
1545 e_client_util_move_without_frame(ec, kbd_x, kbd_y);
1550 e_policy_client_is_lockscreen(E_Client *ec)
1552 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1553 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1555 if (ec->client_type == 2)
1558 if (!e_util_strcmp(ec->icccm.title, "LOCKSCREEN"))
1561 if (!e_util_strcmp(ec->icccm.window_role, "lockscreen"))
1568 e_policy_client_is_home_screen(E_Client *ec)
1570 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1571 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1573 if (ec->client_type == 1)
1581 e_policy_client_is_quickpanel(E_Client *ec)
1583 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1584 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1586 if (!e_util_strcmp(ec->icccm.window_role, "quickpanel_system_default"))
1589 if (!e_util_strcmp(ec->icccm.window_role, "quickpanel_context_menu"))
1592 if (!e_util_strcmp(ec->icccm.window_role, "quickpanel_apps_menu"))
1599 e_policy_client_is_conformant(E_Client *ec)
1601 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1602 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
1604 E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data *)ec->comp_data;
1605 if (cdata->conformant == 1)
1614 e_policy_client_is_volume(E_Client *ec)
1616 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1617 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1619 if (!e_util_strcmp(ec->netwm.name, "volume"))
1622 if (!e_util_strcmp(ec->icccm.title, "volume"))
1629 e_policy_client_is_volume_tv(E_Client *ec)
1631 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1632 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1634 if (!e_util_strcmp(ec->icccm.window_role, "tv-volume-popup"))
1641 e_policy_client_is_noti(E_Client *ec)
1643 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1644 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1646 if (!e_util_strcmp(ec->icccm.title, "noti_win"))
1649 if (ec->netwm.type == E_WINDOW_TYPE_NOTIFICATION)
1656 e_policy_client_is_subsurface(E_Client *ec)
1658 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1659 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1661 if (e_comp_wl_subsurface_check(ec))
1668 e_policy_client_is_floating(E_Client *ec)
1670 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1671 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1673 return ec->floating;
1677 e_policy_client_is_magnifier(E_Client *ec)
1679 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1680 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1682 return ec->is_magnifier;
1686 e_policy_client_is_cursor(E_Client *ec)
1688 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1689 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1691 if (!e_util_strcmp("wl_pointer-cursor", ec->icccm.window_role))
1698 e_policy_client_is_cbhm(E_Client *ec)
1700 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1701 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1703 if (!e_util_strcmp("cbhm", ec->icccm.window_role))
1710 e_policy_client_is_toast_popup(E_Client *ec)
1712 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1713 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1715 #if defined(__cplusplus) || defined(c_plusplus)
1716 if (!e_util_strcmp("TOAST_POPUP", ec->icccm.cpp_class))
1719 if (!e_util_strcmp("TOAST_POPUP", ec->icccm.class))
1722 if (!e_util_strcmp("toast_popup", ec->icccm.window_role))
1729 e_policy_client_is_dialog(E_Client *ec)
1731 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1732 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1734 if (ec->netwm.type == E_WINDOW_TYPE_DIALOG)
1741 e_policy_client_is_keyboard(E_Client *ec)
1743 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1744 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1746 if (ec->vkbd.vkbd) return EINA_TRUE;
1752 e_policy_client_is_keyboard_sub(E_Client *ec)
1754 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1755 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1757 if (ec->vkbd.vkbd) return EINA_FALSE;
1759 #if defined(__cplusplus) || defined(c_plusplus)
1760 if ((ec->icccm.cpp_class) &&
1761 (!strcmp(ec->icccm.cpp_class, "ISF")))
1764 if ((ec->icccm.class) &&
1765 (!strcmp(ec->icccm.class, "ISF")))
1768 if ((ec->icccm.title) &&
1769 ((!strcmp(ec->icccm.title, "ISF Popup")) || (!strcmp(ec->icccm.title, "ISF Magnifier"))))
1776 e_policy_client_is_keyboard_magnifier(E_Client *ec)
1778 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1779 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1781 if (ec->vkbd.vkbd) return EINA_FALSE;
1783 if ((ec->icccm.title) && (!strcmp(ec->icccm.title, "ISF Magnifier")))
1790 e_policy_client_is_watch_viewer(E_Client *ec)
1792 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1793 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1795 if (!e_util_strcmp(e_client_util_name_get(ec), "WATCH_WINDOW"))
1802 e_policy_client_is_taskbar(E_Client *ec)
1804 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1805 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1807 if (ec->client_type == 3)
1810 if (!e_util_strcmp(ec->icccm.title, "TaskBar"))
1813 if (!e_util_strcmp(ec->icccm.window_role, "taskbar"))
1820 e_policy_client_is_KVM(E_Client *ec)
1822 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1824 if (!e_util_strcmp(ec->icccm.window_role, "KVM"))
1831 e_policy_client_is_waydroid(E_Client *ec)
1833 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1835 if (!e_util_strcmp(ec->icccm.title, "Waydroid"))
1841 E_API E_Service_Quickpanel_Type
1842 e_policy_quickpanel_type_get(E_Client *ec)
1844 E_Service_Quickpanel_Type type = E_SERVICE_QUICKPANEL_TYPE_UNKNOWN;
1846 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1847 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1849 type = e_service_quickpanel_type_get(ec);
1854 e_policy_base_output_resolution_info_update(pid_t pid)
1856 e_policy_wl_base_output_resolution_info_update(pid);
1860 e_policy_interceptors_clean(void)
1862 E_Policy_Interceptor *pi;
1865 for (x = 0; x < E_POLICY_INTERCEPT_LAST; x++)
1867 pi = _e_policy_interceptors[x];
1868 if (!pi->delete_me) continue;
1869 _e_policy_interceptors[x] = NULL;
1877 * if interceptor process something successfully at its intercept point,
1879 * if interceptor failed or there is no interceptor.
1882 e_policy_interceptor_call(E_Policy_Intercept_Point ipoint, E_Client *ec, ...)
1885 E_Policy_Interceptor *pi;
1886 Eina_Bool ret = EINA_TRUE;
1888 if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
1889 pi = _e_policy_interceptors[ipoint];
1890 if (!pi) return EINA_FALSE;
1894 e_object_ref(E_OBJECT(ec));
1895 _e_policy_interceptors_walking++;
1898 if (!(pi->func(pi->data, ec, list)))
1901 _e_policy_interceptors_walking--;
1902 if ((_e_policy_interceptors_walking == 0) && (_e_policy_interceptors_delete > 0))
1903 e_policy_interceptors_clean();
1906 e_object_unref(E_OBJECT(ec));
1911 _e_policy_event_simple_free(void *d EINA_UNUSED, E_Event_Client *ev)
1913 e_object_unref(E_OBJECT(ev->ec));
1918 e_policy_event_simple(E_Client *ec, int type)
1922 ev = E_NEW(E_Event_Client, 1);
1926 e_object_ref(E_OBJECT(ec));
1927 ecore_event_add(type, ev, (Ecore_End_Cb)_e_policy_event_simple_free, NULL);
1931 e_policy_aux_message_use_get(E_Client *ec)
1933 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1934 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
1936 E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data *)ec->comp_data;
1937 if (cdata->aux_hint.use_msg)
1946 e_policy_aux_message_send_from_int(E_Client *ec, const char *key, const char *val, int count, ...)
1950 Eina_List *options_list = NULL;
1955 va_start(opt_args, count);
1956 for(itor = 0; itor < count; itor ++)
1958 opt = va_arg(opt_args, int);
1959 eina_convert_itoa(opt, option);
1960 options_list = eina_list_append(options_list, eina_stringshare_add(option));
1964 e_policy_aux_message_send(ec, key, val, options_list);
1966 EINA_LIST_FREE(options_list, str_itor)
1968 eina_stringshare_del(str_itor);
1973 e_policy_aux_message_send(E_Client *ec, const char *key, const char *val, Eina_List *options)
1976 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
1978 e_policy_wl_aux_message_send(ec, key, val, options);
1981 E_API E_Policy_Interceptor *
1982 e_policy_interceptor_add(E_Policy_Intercept_Point ipoint, E_Policy_Intercept_Cb func, const void *data)
1984 E_Policy_Interceptor *pi;
1986 EINA_SAFETY_ON_TRUE_RETURN_VAL(ipoint >= E_POLICY_INTERCEPT_LAST, NULL);
1987 EINA_SAFETY_ON_TRUE_RETURN_VAL(!!_e_policy_interceptors[ipoint], NULL);
1988 pi = E_NEW(E_Policy_Interceptor, 1);
1989 if (!pi) return NULL;
1990 pi->ipoint = ipoint;
1992 pi->data = (void*)data;
1993 _e_policy_interceptors[ipoint] = pi;
1998 e_policy_interceptor_del(E_Policy_Interceptor *pi)
2001 if (_e_policy_interceptors_walking == 0)
2003 _e_policy_interceptors[pi->ipoint] = NULL;
2007 _e_policy_interceptors_delete++;
2010 E_API E_Policy_Hook *
2011 e_policy_hook_add(E_Policy_Hook_Point hookpoint, E_Policy_Hook_Cb func, const void *data)
2015 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_POLICY_HOOK_LAST, NULL);
2016 ph = E_NEW(E_Policy_Hook, 1);
2017 if (!ph) return NULL;
2018 ph->hookpoint = hookpoint;
2020 ph->data = (void*)data;
2021 _e_policy_hooks[hookpoint] = eina_inlist_append(_e_policy_hooks[hookpoint], EINA_INLIST_GET(ph));
2026 e_policy_hook_del(E_Policy_Hook *ph)
2029 if (_e_policy_hooks_walking == 0)
2031 _e_policy_hooks[ph->hookpoint] = eina_inlist_remove(_e_policy_hooks[ph->hookpoint], EINA_INLIST_GET(ph));
2035 _e_policy_hooks_delete++;
2039 _e_policy_hooks_clean(void)
2045 for (x = 0; x < E_POLICY_HOOK_LAST; x++)
2047 EINA_INLIST_FOREACH_SAFE(_e_policy_hooks[x], l, ph)
2049 if (!ph->delete_me) continue;
2050 _e_policy_hooks[x] = eina_inlist_remove(_e_policy_hooks[x], EINA_INLIST_GET(ph));
2057 e_policy_hook_call(E_Policy_Hook_Point hookpoint, E_Client *ec)
2061 e_object_ref(E_OBJECT(ec));
2062 _e_policy_hooks_walking++;
2064 EINA_INLIST_FOREACH(_e_policy_hooks[hookpoint], ch)
2066 if (ch->delete_me) continue;
2067 ch->func(ch->data, ec);
2069 _e_policy_hooks_walking--;
2070 if ((_e_policy_hooks_walking == 0) && (_e_policy_hooks_delete > 0))
2071 _e_policy_hooks_clean();
2072 return !!e_object_unref(E_OBJECT(ec));
2076 e_policy_user_geometry_set(E_Client *ec,
2077 E_Policy_Allow_User_Geometry type,
2080 E_Policy_Client *pc;
2082 if (EINA_UNLIKELY(!ec))
2085 pc = eina_hash_find(hash_policy_clients, &ec);
2086 if (EINA_UNLIKELY(!pc))
2090 pc->user_geom_state |= type;
2092 pc->user_geom_state &= ~(type);
2094 if (pc->user_geom_state)
2095 e_policy_allow_user_geometry_set(ec, EINA_TRUE);
2097 e_policy_allow_user_geometry_set(ec, EINA_FALSE);
2101 e_policy_allow_user_geometry_set(E_Client *ec, Eina_Bool set)
2103 E_Policy_Client *pc;
2105 if (EINA_UNLIKELY(!ec))
2108 pc = eina_hash_find(hash_policy_clients, &ec);
2109 if (EINA_UNLIKELY(!pc))
2112 if (set && !pc->allow_user_geom)
2114 pc->allow_user_geom = EINA_TRUE;
2116 if (!e_policy_client_is_noti(ec))
2118 ec->netwm.type = E_WINDOW_TYPE_UTILITY;
2119 ec->lock_client_location = EINA_FALSE;
2122 _e_policy_client_maximize_policy_cancel(pc);
2124 ec->lock_client_location = EINA_FALSE;
2125 ec->lock_client_size = EINA_FALSE;
2130 else if (!set && pc->allow_user_geom)
2132 pc->allow_user_geom = EINA_FALSE;
2134 ec->lock_client_location = EINA_TRUE;
2135 ec->lock_client_size = EINA_TRUE;
2137 ec->netwm.type = E_WINDOW_TYPE_NORMAL;
2139 e_client_pending_geometry_flush(ec);
2140 ec->icccm.min_w = ec->icccm.min_h = 0;
2141 ec->icccm.max_w = ec->icccm.max_h = 0;
2147 e_policy_allow_user_geometry_get(E_Client *ec)
2149 E_Policy_Client *pc;
2151 if (EINA_UNLIKELY(!ec))
2154 pc = eina_hash_find(hash_policy_clients, &ec);
2155 if (EINA_UNLIKELY(!pc))
2158 return pc->allow_user_geom;
2162 e_policy_animatable_lock(E_Client *ec,
2163 E_Policy_Animatable_Lock lock,
2166 E_Policy_Client *pc;
2168 if (EINA_UNLIKELY(!ec))
2171 pc = eina_hash_find(hash_policy_clients, &ec);
2172 if (EINA_UNLIKELY(!pc))
2176 pc->lock_animatable |= lock;
2178 pc->lock_animatable &= ~(lock);
2180 if (pc->lock_animatable)
2181 ec->animatable = EINA_FALSE;
2183 ec->animatable = EINA_TRUE;
2185 ELOGF("TZPOL","EFFECT(animatable:%d) due to %d is applied on the state %d --> result:%d", ec,
2186 ec->animatable, set, lock, pc->lock_animatable);
2190 e_policy_deferred_job(void)
2192 if (!e_policy) return;
2194 e_policy_wl_defer_job();
2197 EINTERN E_Policy_Client *
2198 e_policy_client_add(E_Client *ec)
2200 E_Policy_Client *pc;
2202 if (e_object_is_del(E_OBJECT(ec))) return NULL;
2204 pc = eina_hash_find(hash_policy_clients, &ec);
2207 pc = E_NEW(E_Policy_Client, 1);
2208 if (!pc) return NULL;
2211 pc->zone = e_comp_zone_find_by_ec(ec);
2213 eina_hash_add(hash_policy_clients, &ec, pc);
2215 // This client_add hook of desk will be deleted at the hook callback for it.
2216 _e_policy_desk_client_add_hook_add(pc);
2226 E_Config_Policy_Desk *d;
2230 pol = E_NEW(E_Policy, 1);
2231 EINA_SAFETY_ON_NULL_RETURN_VAL(pol, EINA_FALSE);
2235 hash_policy_clients = eina_hash_pointer_new(_e_policy_cb_client_data_free);
2236 hash_policy_desks = eina_hash_pointer_new(_e_policy_cb_desk_data_free);
2238 E_EVENT_POLICY_QUICKPANEL_VISIBLE_STATE_CHANGE = ecore_event_type_new();
2240 e_policy_stack_init();
2242 e_policy_wl_aux_hint_init();
2244 EINA_LIST_FOREACH(e_comp->zones, l, zone)
2246 n = zone->desk_y_count * zone->desk_x_count;
2247 for (i = 0; i < n; i++)
2249 if (e_config->use_configured_desks)
2251 d = _e_policy_desk_get_by_num(zone->num,
2255 e_policy_desk_add(zone->desks[i]);
2258 e_policy_desk_add(zone->desks[i]);
2262 E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_ADD, _e_policy_cb_zone_add, NULL);
2263 E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DEL, _e_policy_cb_zone_del, NULL);
2264 E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_MOVE_RESIZE, _e_policy_cb_zone_move_resize, NULL);
2265 E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DESK_COUNT_SET, _e_policy_cb_zone_desk_count_set, NULL);
2266 E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DISPLAY_STATE_CHANGE, _e_policy_cb_zone_display_state_change, NULL);
2267 E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_USEFUL_GEOMETRY_CHANGE, _e_policy_cb_zone_useful_geometry_change, NULL);
2268 E_LIST_HANDLER_APPEND(handlers, E_EVENT_DESK_SHOW, _e_policy_cb_desk_show, NULL);
2269 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_ADD, _e_policy_cb_client_add, NULL);
2270 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_MOVE, _e_policy_cb_client_move, NULL);
2271 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_RESIZE, _e_policy_cb_client_resize, NULL);
2272 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_STACK, _e_policy_cb_client_stack, NULL);
2273 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_PROPERTY, _e_policy_cb_client_property, NULL);
2274 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_VISIBILITY_CHANGE, _e_policy_cb_client_vis_change, NULL);
2275 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_SHOW, _e_policy_cb_client_show, NULL);
2276 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_HIDE, _e_policy_cb_client_hide, NULL);
2277 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_ZONE_SET, _e_policy_cb_client_zone_set, NULL);
2279 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_DEL, _e_policy_cb_hook_client_del, NULL);
2280 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_EVAL_PRE_NEW_CLIENT, _e_policy_cb_hook_client_eval_pre_new_client, NULL);
2281 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_EVAL_PRE_FETCH, _e_policy_cb_hook_client_eval_pre_fetch, NULL);
2282 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_EVAL_PRE_POST_FETCH, _e_policy_cb_hook_client_eval_pre_post_fetch, NULL);
2283 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_EVAL_POST_FETCH, _e_policy_cb_hook_client_eval_post_fetch, NULL);
2284 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_EVAL_POST_NEW_CLIENT,_e_policy_cb_hook_client_eval_post_new_client,NULL);
2285 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_EVAL_VISIBILITY, _e_policy_cb_hook_client_visibility, NULL);
2286 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_UNICONIFY, _e_policy_cb_hook_client_uniconify, NULL);
2288 E_PIXMAP_HOOK_APPEND(hooks_cp, E_PIXMAP_HOOK_DEL, _e_policy_cb_hook_pixmap_del, NULL);
2289 E_PIXMAP_HOOK_APPEND(hooks_cp, E_PIXMAP_HOOK_UNUSABLE, _e_policy_cb_hook_pixmap_unusable, NULL);
2291 _e_pol_idle_enterer = ecore_idle_enterer_add(_e_policy_cb_idle_enterer, NULL);
2293 e_policy_conformant_init();
2294 e_policy_visibility_init();
2300 e_policy_shutdown(void)
2302 E_Policy *pol = e_policy;
2304 E_Policy_Softkey *softkey;
2306 eina_list_free(_e_pol_changed_zone);
2307 eina_list_free(pol->launchers);
2308 EINA_INLIST_FOREACH_SAFE(pol->softkeys, l, softkey)
2309 e_policy_softkey_del(softkey);
2311 E_FREE_LIST(hooks_cp, e_pixmap_hook_del);
2312 E_FREE_LIST(hooks_ec, e_client_hook_del);
2313 E_FREE_LIST(handlers, ecore_event_handler_del);
2315 E_FREE_FUNC(hash_policy_desks, eina_hash_free);
2316 E_FREE_FUNC(hash_policy_clients, eina_hash_free);
2318 e_policy_stack_shutdown();
2319 e_policy_wl_shutdown();
2321 e_policy_conformant_shutdown();
2322 e_policy_visibility_shutdown();