2 #include "e_policy_conformant_internal.h"
3 #include "e_policy_wl.h"
4 #include "e_policy_visibility.h"
5 #include "e_policy_private_data.h"
6 #include "services/e_service_quickpanel.h"
8 E_Policy *e_policy = NULL;
9 Eina_Hash *hash_policy_desks = NULL;
10 Eina_Hash *hash_policy_clients = NULL;
11 E_Policy_System_Info e_policy_system_info =
17 static int _e_policy_interceptors_walking = 0;
18 static int _e_policy_interceptors_delete = 0;
20 E_Policy_Interceptor *_e_policy_interceptors[] =
22 [E_POLICY_INTERCEPT_LAUNCHSCREEN_OBJECT_SETUP] = NULL,
23 [E_POLICY_INTERCEPT_STACK_TRANSIENT_FOR] = NULL,
24 [E_POLICY_INTERCEPT_ACTIVATE_ABOVE] = NULL,
25 [E_POLICY_INTERCEPT_ACTIVATE_BELOW] = NULL,
26 [E_POLICY_INTERCEPT_SEND_PRE_VISIBILITY] = NULL,
29 static Eina_List *handlers = NULL;
30 static Eina_List *hooks_ec = NULL;
31 static Eina_List *hooks_cp = NULL;
32 static Ecore_Idle_Enterer *_e_pol_idle_enterer = NULL;
33 static Eina_Bool _e_pol_changed_vis = EINA_FALSE;
34 static Eina_List *_e_pol_changed_zone = NULL;
35 static int _e_policy_hooks_delete = 0;
36 static int _e_policy_hooks_walking = 0;
38 static Eina_Inlist *_e_policy_hooks[] =
40 [E_POLICY_HOOK_CLIENT_POSITION_SET] = NULL,
41 [E_POLICY_HOOK_CLIENT_ACTIVE_REQ] = NULL,
42 [E_POLICY_HOOK_CLIENT_RAISE_REQ] = NULL,
43 [E_POLICY_HOOK_CLIENT_LOWER_REQ] = NULL,
44 [E_POLICY_HOOK_CLIENT_ICONIFY_REQ] = NULL,
45 [E_POLICY_HOOK_CLIENT_UNICONIFY_REQ] = NULL,
46 [E_POLICY_HOOK_CLIENT_NOTILAYER_SET] = NULL,
47 [E_POLICY_HOOK_CLIENT_RAISE_REQ_DONE] = NULL,
48 [E_POLICY_HOOK_CLIENT_ROTATION_GEOMETRY_SET] = NULL,
49 [E_POLICY_HOOK_CLIENT_STACK_MODE_SET] = NULL,
50 [E_POLICY_HOOK_CLIENT_AUX_HINT_CHANGED] = NULL,
53 E_API int E_EVENT_POLICY_QUICKPANEL_VISIBLE_STATE_CHANGE = -1;
55 static E_Policy_Client *_e_policy_client_add(E_Client *ec);
56 static void _e_policy_client_del(E_Policy_Client *pc);
57 static Eina_Bool _e_policy_client_normal_check(E_Client *ec);
58 static Eina_Bool _e_policy_client_maximize_policy_apply(E_Policy_Client *pc);
59 static void _e_policy_client_maximize_policy_cancel(E_Policy_Client *pc);
60 static void _e_policy_client_floating_policy_apply(E_Policy_Client *pc);
61 static void _e_policy_client_floating_policy_cancel(E_Policy_Client *pc);
62 static void _e_policy_client_launcher_set(E_Policy_Client *pc);
64 static void _e_policy_cb_hook_client_eval_pre_new_client(void *d EINA_UNUSED, E_Client *ec);
65 static void _e_policy_cb_hook_client_eval_pre_fetch(void *d EINA_UNUSED, E_Client *ec);
66 static void _e_policy_cb_hook_client_eval_pre_post_fetch(void *d EINA_UNUSED, E_Client *ec);
67 static void _e_policy_cb_hook_client_eval_post_fetch(void *d EINA_UNUSED, E_Client *ec);
68 static void _e_policy_cb_hook_client_eval_post_new_client(void *d EINA_UNUSED, E_Client *ec);
69 static void _e_policy_cb_hook_client_desk_set(void *d EINA_UNUSED, E_Client *ec);
70 static void _e_policy_cb_hook_client_fullscreen_pre(void *data EINA_UNUSED, E_Client *ec);
72 static void _e_policy_cb_hook_pixmap_del(void *data EINA_UNUSED, E_Pixmap *cp);
73 static void _e_policy_cb_hook_pixmap_unusable(void *data EINA_UNUSED, E_Pixmap *cp);
75 static void _e_policy_cb_desk_data_free(void *data);
76 static void _e_policy_cb_client_data_free(void *data);
77 static Eina_Bool _e_policy_cb_zone_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
78 static Eina_Bool _e_policy_cb_zone_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
79 static Eina_Bool _e_policy_cb_zone_move_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
80 static Eina_Bool _e_policy_cb_zone_desk_count_set(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
81 static Eina_Bool _e_policy_cb_zone_display_state_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
82 static Eina_Bool _e_policy_cb_zone_useful_geometry_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
83 static Eina_Bool _e_policy_cb_desk_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
84 static Eina_Bool _e_policy_cb_client_add(void *data EINA_UNUSED, int type, void *event);
85 static Eina_Bool _e_policy_cb_client_move(void *data EINA_UNUSED, int type, void *event);
86 static Eina_Bool _e_policy_cb_client_resize(void *data EINA_UNUSED, int type, void *event);
87 static Eina_Bool _e_policy_cb_client_stack(void *data EINA_UNUSED, int type, void *event);
88 static Eina_Bool _e_policy_cb_client_property(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
89 static Eina_Bool _e_policy_cb_client_vis_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED);
90 static Eina_Bool _e_policy_cb_client_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
91 static Eina_Bool _e_policy_cb_client_hide(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
93 static Eina_Bool _e_policy_cb_idle_enterer(void *data EINA_UNUSED);
96 _e_policy_client_launcher_set(E_Policy_Client *pc)
100 pc2 = e_policy_client_launcher_get(pc->ec->zone);
103 if (pc->ec->netwm.type != e_config->launcher.type)
106 #if defined(__cplusplus) || defined(c_plusplus)
107 if (e_util_strcmp(pc->ec->icccm.cpp_class,
108 e_config->launcher.clas))
111 if (e_util_strcmp(pc->ec->icccm.class,
112 e_config->launcher.clas))
116 if (e_util_strcmp(pc->ec->icccm.title,
117 e_config->launcher.title))
119 /* check netwm name instead, because comp_x had ignored
120 * icccm name when fetching */
121 if (e_util_strcmp(pc->ec->netwm.name,
122 e_config->launcher.title))
128 e_policy->launchers = eina_list_append(e_policy->launchers, pc);
131 static E_Policy_Client *
132 _e_policy_client_add(E_Client *ec)
136 if (e_object_is_del(E_OBJECT(ec))) return NULL;
138 pc = eina_hash_find(hash_policy_clients, &ec);
141 pc = E_NEW(E_Policy_Client, 1);
142 if (!pc) return NULL;
146 eina_hash_add(hash_policy_clients, &ec, pc);
152 _e_policy_client_del(E_Policy_Client *pc)
154 eina_hash_del_by_key(hash_policy_clients, &pc->ec);
158 _e_policy_client_normal_check(E_Client *ec)
162 if ((e_client_util_ignored_get(ec)) ||
168 if (e_policy_client_is_quickpanel(ec))
173 if (e_policy_client_is_keyboard(ec) ||
174 e_policy_client_is_keyboard_sub(ec))
176 e_policy_keyboard_layout_apply(ec);
179 else if (e_policy_client_is_volume_tv(ec))
181 else if (!e_util_strcmp("e_demo", ec->icccm.window_role))
183 else if (e_policy_client_is_floating(ec))
185 pc = eina_hash_find(hash_policy_clients, &ec);
186 _e_policy_client_maximize_policy_cancel(pc);
187 _e_policy_client_floating_policy_apply(pc);
190 else if (e_policy_client_is_subsurface(ec))
193 if ((ec->netwm.type == E_WINDOW_TYPE_NORMAL) ||
194 (ec->netwm.type == E_WINDOW_TYPE_UNKNOWN) ||
195 (ec->netwm.type == E_WINDOW_TYPE_NOTIFICATION))
203 pc = eina_hash_find(hash_policy_clients, &ec);
204 _e_policy_client_maximize_policy_cancel(pc);
210 _e_policy_client_maximize_pre(E_Policy_Client *pc)
217 if (ec->desk->visible)
218 e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh);
231 e_client_pos_set(ec, zx, zy);
232 e_client_size_set(ec, zw, zh);
237 _e_policy_client_maximize_policy_apply(E_Policy_Client *pc)
241 if (!pc) return EINA_FALSE;
243 if (pc->max_policy_state) return EINA_TRUE;
244 if (pc->allow_user_geom) return EINA_FALSE;
247 if (ec->netwm.type == E_WINDOW_TYPE_UTILITY) return EINA_FALSE;
249 pc->max_policy_state = EINA_TRUE;
252 # define _SET(a) pc->orig.a = pc->ec->a
256 _SET(lock_user_location);
257 _SET(lock_client_location);
258 _SET(lock_user_size);
259 _SET(lock_client_size);
260 _SET(lock_client_stacking);
261 _SET(lock_user_shade);
262 _SET(lock_client_shade);
263 _SET(lock_user_maximize);
264 _SET(lock_client_maximize);
265 _SET(lock_user_fullscreen);
266 _SET(lock_client_fullscreen);
269 _e_policy_client_launcher_set(pc);
274 ec->border.changed = 1;
280 /* This is added to support e_desk_geometry_set().
281 * The geometry of client is calculated based on E_Desk by
282 * e_client_maximize() from now.
283 * But, if we don't set ec->placed, geometry of new client will be
284 * calculated again based on E_Zone by _e_client_eval().
285 * FIXME: we can delete it if calculation of placement is based on
290 if ((e_policy_client_is_home_screen(ec)) ||
291 (e_policy_client_is_lockscreen(ec)) ||
292 (e_policy_client_is_quickpanel(ec)) ||
293 (e_policy_client_is_taskbar(ec)))
295 max = E_MAXIMIZE_FULLSCREEN | E_MAXIMIZE_BOTH;
299 max = E_MAXIMIZE_EXPAND | E_MAXIMIZE_BOTH;
302 e_client_maximize(ec, max);
304 if (ec->changes.need_maximize)
305 _e_policy_client_maximize_pre(pc);
308 /* do not allow client to change these properties */
309 ec->lock_user_location = 1;
310 ec->lock_client_location = 1;
311 ec->lock_user_size = 1;
312 ec->lock_client_size = 1;
313 ec->lock_user_shade = 1;
314 ec->lock_client_shade = 1;
315 ec->lock_user_maximize = 1;
316 ec->lock_client_maximize = 1;
317 ec->lock_user_fullscreen = 1;
318 ec->lock_client_fullscreen = 1;
319 ec->skip_fullscreen = 1;
321 if (!e_policy_client_is_home_screen(ec))
322 ec->lock_client_stacking = 1;
328 _e_policy_client_maximize_policy_cancel(E_Policy_Client *pc)
331 Eina_Bool changed = EINA_FALSE;
334 if (!pc->max_policy_state) return;
336 pc->max_policy_state = EINA_FALSE;
340 if (pc->orig.borderless != ec->borderless)
342 ec->border.changed = 1;
346 if ((pc->orig.fullscreen != ec->fullscreen) &&
347 (pc->orig.fullscreen))
349 ec->need_fullscreen = 1;
353 if (pc->orig.maximized != ec->maximized)
355 if (pc->orig.maximized)
356 ec->changes.need_maximize = 1;
358 e_client_unmaximize(ec, ec->maximized);
363 /* floating mode ec which was launched with fake image is not borderless value.
364 * thus, we should set borderless value to 1 for this ec to prevent choppy
365 * movement of the window when moving the window.
369 pc->orig.borderless = 1;
374 # define _SET(a) ec->a = pc->orig.a
378 _SET(lock_user_location);
379 _SET(lock_client_location);
380 _SET(lock_user_size);
381 _SET(lock_client_size);
382 _SET(lock_client_stacking);
383 _SET(lock_user_shade);
384 _SET(lock_client_shade);
385 _SET(lock_user_maximize);
386 _SET(lock_client_maximize);
387 _SET(lock_user_fullscreen);
388 _SET(lock_client_fullscreen);
391 ec->skip_fullscreen = 0;
393 /* only set it if the border is changed or fullscreen/maximize has changed */
397 e_policy->launchers = eina_list_remove(e_policy->launchers, pc);
401 _e_policy_client_dialog_policy_apply(E_Policy_Client *pc)
410 ec->skip_fullscreen = 1;
411 ec->lock_client_stacking = 1;
412 ec->lock_user_shade = 1;
413 ec->lock_client_shade = 1;
414 ec->lock_user_maximize = 1;
415 ec->lock_client_maximize = 1;
416 ec->lock_user_fullscreen = 1;
417 ec->lock_client_fullscreen = 1;
422 e_client_base_output_resolution_useful_geometry_get(ec, &zx, &zy, &zw, &zh);
424 x = zx + ((zw - w) / 2);
425 y = zy + ((zh - h) / 2);
427 if ((x != ec->x) || (y != ec->y))
428 evas_object_move(ec->frame, x, y);
432 _e_policy_client_floating_policy_apply(E_Policy_Client *pc)
435 if (pc->flt_policy_state) return;
437 pc->flt_policy_state = EINA_TRUE;
441 _e_policy_client_floating_policy_cancel(E_Policy_Client *pc)
444 if (!pc->flt_policy_state) return;
446 pc->flt_policy_state = EINA_FALSE;
449 E_Config_Policy_Desk *
450 _e_policy_desk_get_by_num(unsigned int zone_num, int x, int y)
453 E_Config_Policy_Desk *d2;
455 EINA_LIST_FOREACH(e_config->policy_desks, l, d2)
457 if ((d2->zone_num == zone_num) &&
458 (d2->x == x) && (d2->y == y))
469 _e_policy_cb_hook_client_new(void *d EINA_UNUSED, E_Client *ec)
471 if (EINA_UNLIKELY(!ec))
474 _e_policy_client_add(ec);
478 _e_policy_cb_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
482 if (EINA_UNLIKELY(!ec))
485 e_tzsh_indicator_srv_ower_win_update(ec->zone);
486 e_policy_wl_win_brightness_apply(ec);
487 e_policy_wl_client_del(ec);
489 if (e_policy_client_is_lockscreen(ec))
490 e_policy_stack_clients_restack_above_lockscreen(ec, EINA_FALSE);
492 e_policy_stack_cb_client_remove(ec);
493 e_client_visibility_calculate();
495 pc = eina_hash_find(hash_policy_clients, &ec);
496 _e_policy_client_del(pc);
500 _e_policy_cb_hook_client_eval_pre_new_client(void *d EINA_UNUSED, E_Client *ec)
504 if (e_object_is_del(E_OBJECT(ec))) return;
506 if (e_policy_client_is_keyboard_sub(ec))
509 ec->exp_iconify.skip_iconify = EINA_TRUE;
511 EINA_SAFETY_ON_NULL_RETURN(ec->frame);
512 if (ec->layer < E_LAYER_CLIENT_ABOVE)
513 e_client_layer_set(ec, E_LAYER_CLIENT_ABOVE);
515 if (e_policy_client_is_noti(ec))
519 ly = evas_object_layer_get(ec->frame);
520 ELOGF("NOTI", " |ec->layer:%d object->layer:%d", ec, ec->layer, ly);
522 e_client_layer_set(ec, ec->layer);
526 if (e_policy_client_is_dialog(ec))
528 if (ec->frame && !ec->parent)
530 if (ec->layer != E_POLICY_DIALOG_LAYER)
531 e_client_layer_set(ec, E_POLICY_DIALOG_LAYER);
535 if (e_policy_client_is_floating(ec))
539 if (ec->layer != E_LAYER_CLIENT_ABOVE)
540 e_client_layer_set(ec, E_LAYER_CLIENT_ABOVE);
544 if (e_policy_client_is_toast_popup(ec))
548 if (ec->layer != E_POLICY_TOAST_POPUP_LAYER)
549 e_client_layer_set(ec, E_POLICY_TOAST_POPUP_LAYER);
552 if (e_policy_client_is_cbhm(ec))
554 ec->exp_iconify.skip_iconify = EINA_TRUE;
557 if (e_policy_client_is_magnifier(ec))
559 if (ec->layer != E_LAYER_CLIENT_ALERT_HIGH)
560 e_client_layer_set(ec, E_LAYER_CLIENT_ALERT_HIGH);
565 _e_policy_cb_hook_client_eval_pre_fetch(void *d EINA_UNUSED, E_Client *ec)
567 if (e_object_is_del(E_OBJECT(ec))) return;
569 e_policy_stack_transient_for_apply(ec);
573 _e_policy_cb_hook_client_eval_pre_post_fetch(void *d EINA_UNUSED, E_Client *ec)
575 if (e_object_is_del(E_OBJECT(ec))) return;
577 e_policy_wl_notification_level_fetch(ec);
581 _e_policy_cb_hook_client_eval_post_fetch(void *d EINA_UNUSED, E_Client *ec)
586 if (e_object_is_del(E_OBJECT(ec))) return;
587 /* Following E_Clients will be added to module hash and will be managed.
589 * - Not new client: Updating internal info of E_Client has been finished
590 * by e main evaluation, thus module can classify E_Client and manage it.
592 * - New client that has valid buffer: This E_Client has been passed e main
593 * evaluation, and it has handled first wl_surface::commit request.
595 if ((ec->new_client) && (!e_pixmap_usable_get(ec->pixmap))) return;
597 if (e_policy_client_is_keyboard(ec) ||
598 e_policy_client_is_keyboard_sub(ec))
601 pc = eina_hash_find(hash_policy_clients, &ec);
602 _e_policy_client_maximize_policy_cancel(pc);
604 e_policy_keyboard_layout_apply(ec);
607 if (!e_util_strcmp("wl_pointer-cursor", ec->icccm.window_role))
610 pc = eina_hash_find(hash_policy_clients, &ec);
611 _e_policy_client_maximize_policy_cancel(pc);
615 if (e_policy_client_is_floating(ec))
618 pc = eina_hash_find(hash_policy_clients, &ec);
619 _e_policy_client_maximize_policy_cancel(pc);
620 _e_policy_client_floating_policy_apply(pc);
624 if (e_policy_client_is_dialog(ec))
627 pc = eina_hash_find(hash_policy_clients, &ec);
628 _e_policy_client_maximize_policy_cancel(pc);
629 _e_policy_client_dialog_policy_apply(pc);
633 if (!_e_policy_client_normal_check(ec)) return;
635 pd = eina_hash_find(hash_policy_desks, &ec->desk);
638 pc = eina_hash_find(hash_policy_clients, &ec);
641 if (pc->flt_policy_state)
642 _e_policy_client_floating_policy_cancel(pc);
644 _e_policy_client_maximize_policy_apply(pc);
648 _e_policy_cb_hook_client_eval_post_new_client(void *d EINA_UNUSED, E_Client *ec)
650 if (e_object_is_del(E_OBJECT(ec))) return;
651 if ((ec->new_client) && (!e_pixmap_usable_get(ec->pixmap))) return;
653 if (e_policy_client_is_lockscreen(ec))
654 e_policy_stack_clients_restack_above_lockscreen(ec, EINA_TRUE);
658 _e_policy_cb_hook_client_desk_set(void *d EINA_UNUSED, E_Client *ec)
663 if (e_object_is_del(E_OBJECT(ec))) return;
664 if (!_e_policy_client_normal_check(ec)) return;
665 if (ec->internal) return;
666 if (ec->new_client) return;
668 pc = eina_hash_find(hash_policy_clients, &ec);
669 if (EINA_UNLIKELY(!pc))
672 pd = eina_hash_find(hash_policy_desks, &ec->desk);
675 _e_policy_client_maximize_policy_apply(pc);
677 _e_policy_client_maximize_policy_cancel(pc);
681 _e_policy_cb_hook_client_fullscreen_pre(void* data EINA_UNUSED, E_Client *ec)
683 if (e_object_is_del(E_OBJECT(ec))) return;
684 if (!_e_policy_client_normal_check(ec)) return;
685 if (ec->internal) return;
687 ec->skip_fullscreen = 1;
691 _e_policy_cb_hook_client_visibility(void *d EINA_UNUSED, E_Client *ec)
696 if (ec->visibility.changed)
698 if (ec->visibility.obscured == E_VISIBILITY_UNOBSCURED)
700 e_policy_client_uniconify_by_visibility(ec);
701 if ((ec->iconic == 0) && (ec->exp_iconify.last_sent_iconic != 0))
702 e_policy_wl_iconify_state_change_send(ec, 0);
703 if (ec->visibility.last_sent_type != E_VISIBILITY_PRE_UNOBSCURED)
705 ELOGF("POL_VIS", "SEND pre-unobscured visibility event", ec);
706 e_vis_client_send_pre_visibility_event(ec);
708 e_policy_client_visibility_send(ec);
712 if (e_policy_visibility_client_is_uniconify_render_running(ec))
714 ELOGF("POL_VIS", "cancel uniconify by visibility job", ec);
715 e_policy_visibility_client_uniconify_by_visibility_job_cancel(ec);
716 if ((ec->iconic == 1) && (ec->exp_iconify.last_sent_iconic == 0))
717 e_policy_wl_iconify_state_change_send(ec, 1);
719 e_policy_client_visibility_send(ec);
720 e_policy_client_iconify_by_visibility(ec);
723 e_policy_wl_win_brightness_apply(ec);
725 _e_pol_changed_vis = EINA_TRUE;
726 if (!eina_list_data_find(_e_pol_changed_zone, ec->zone))
727 _e_pol_changed_zone = eina_list_append(_e_pol_changed_zone, ec->zone);
731 if (ec->visibility.obscured == E_VISIBILITY_FULLY_OBSCURED)
733 Eina_Bool obscured_by_alpha_opaque = EINA_FALSE;
734 Eina_Bool find_above = EINA_FALSE;
738 if (ec->zone->display_state == E_ZONE_DISPLAY_STATE_ON)
740 e_client_geometry_get(ec, &ex, &ey, &ew, &eh);
741 // crop ec size with zone size
742 E_RECTS_CLIP_TO_RECT(ex, ey, ew, eh, ec->zone->x, ec->zone->y, ec->zone->w, ec->zone->h);
744 if (!E_INTERSECTS(ec->zone->x, ec->zone->y, ec->zone->w, ec->zone->h, ex, ey, ew, eh))
746 if (ec->visibility.last_sent_type == E_VISIBILITY_PRE_UNOBSCURED)
748 ELOGF("POL_VIS", "SEND unobscured/fully-obscured visibility event because iconify visibility", ec);
749 e_policy_wl_visibility_send(ec, E_VISIBILITY_UNOBSCURED);
750 e_policy_wl_visibility_send(ec, E_VISIBILITY_FULLY_OBSCURED);
752 e_policy_client_iconify_by_visibility(ec);
756 for (o = evas_object_above_get(ec->frame); o; o = evas_object_above_get(o))
758 above_ec = evas_object_data_get(o, "E_Client");
759 if (!above_ec) continue;
760 if (e_client_util_ignored_get(above_ec)) continue;
761 if (!above_ec->visible) continue;
763 if (e_client_is_iconified_by_client(above_ec)) continue;
764 if (above_ec->exp_iconify.skip_by_remote) continue;
765 if (above_ec->bg_state) continue;
769 if (above_ec->visibility.opaque <= 0)
773 if (!above_ec->iconic)
774 obscured_by_alpha_opaque = EINA_TRUE;
778 find_above = EINA_TRUE;
780 e_client_geometry_get(above_ec, &ax, &ay, &aw, &ah);
781 if (E_CONTAINS(ax, ay, aw, ah, ex, ey, ew, eh))
785 if (!find_above) return;
786 if (obscured_by_alpha_opaque)
788 e_policy_client_uniconify_by_visibility(ec);
792 if (ec->visibility.last_sent_type == E_VISIBILITY_PRE_UNOBSCURED)
794 if (!e_policy_visibility_client_is_uniconify_render_running(ec))
796 ELOGF("POL_VIS", "SEND unobscured/fully-obscured visibility event because iconify visibility", ec);
797 e_policy_wl_visibility_send(ec, E_VISIBILITY_UNOBSCURED);
798 e_policy_wl_visibility_send(ec, E_VISIBILITY_FULLY_OBSCURED);
801 e_policy_client_iconify_by_visibility(ec);
804 else if (ec->zone->display_state == E_ZONE_DISPLAY_STATE_OFF)
806 if (e_client_util_ignored_get(ec)) return;
807 if (e_client_is_iconified_by_client(ec)) return;
808 if (ec->bg_state) return;
809 if (ec->exp_iconify.skip_iconify) return;
810 if (ec->exp_iconify.skip_by_remote) return;
813 e_policy_client_iconify_by_visibility(ec);
821 _e_policy_cb_hook_client_uniconify(void *d EINA_UNUSED, E_Client *ec)
823 if (e_object_is_del(E_OBJECT(ec))) return;
824 if (!e_policy_wl_iconify_state_supported_get(ec))
826 ELOGF("TZPOL", "Force Update the client not supporting iconify state",
829 /* force render for an iconifed e_client having shm buffer not used yet*/
830 if ((e_pixmap_image_data_get(ec->pixmap)) &&
831 (!e_pixmap_dirty_get(ec->pixmap)))
833 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
834 e_comp_object_dirty(ec->frame);
835 e_comp_object_render(ec->frame);
841 _e_policy_cb_hook_pixmap_del(void *data EINA_UNUSED, E_Pixmap *cp)
843 e_policy_wl_pixmap_del(cp);
847 _e_policy_cb_hook_pixmap_unusable(void *data EINA_UNUSED, E_Pixmap *cp)
849 E_Client *ec = (E_Client *)e_pixmap_client_get(cp);
852 if (!ec->iconic) return;
853 if (e_client_is_iconified_by_client(ec)) return;
854 if (ec->exp_iconify.skip_iconify) return;
855 if (ec->exp_iconify.skip_by_remote) return;
856 if (ec->remote_surface.bind_ref > 0) return;
858 e_policy_client_unmap(ec);
862 _e_policy_cb_desk_data_free(void *data)
868 _e_policy_cb_client_data_free(void *data)
874 _e_policy_cb_zone_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
876 E_Event_Zone_Add *ev;
878 E_Config_Policy_Desk *d;
879 E_Policy_Softkey *softkey;
884 n = zone->desk_y_count * zone->desk_x_count;
885 for (i = 0; i < n; i++)
887 if (e_config->use_configured_desks)
889 d = _e_policy_desk_get_by_num(zone->num,
893 e_policy_desk_add(zone->desks[i]);
896 e_policy_desk_add(zone->desks[i]);
899 /* add and show softkey */
900 if (e_config->use_softkey)
902 softkey = e_policy_softkey_get(zone);
904 softkey = e_policy_softkey_add(zone);
907 return ECORE_CALLBACK_PASS_ON;
911 _e_policy_cb_zone_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
913 E_Event_Zone_Del *ev;
916 E_Policy_Softkey *softkey;
922 n = zone->desk_y_count * zone->desk_x_count;
923 for (i = 0; i < n; i++)
925 pd = eina_hash_find(hash_policy_desks, &zone->desks[i]);
926 if (pd) e_policy_desk_del(pd);
929 /* add and show softkey */
930 if (e_config->use_softkey)
932 softkey = e_policy_softkey_get(zone);
934 e_policy_softkey_del(softkey);
937 return ECORE_CALLBACK_PASS_ON;
941 _e_policy_client_maximize_update(E_Zone *zone)
944 E_Policy_Client *pc = NULL;
948 if (ec->zone != zone) continue;
950 pc = eina_hash_find(hash_policy_clients, &ec);
951 if (pc && pc->max_policy_state)
953 _e_policy_client_maximize_policy_cancel(pc);
954 _e_policy_client_maximize_policy_apply(pc);
960 _e_policy_cb_zone_move_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
962 E_Event_Zone_Move_Resize *ev;
963 E_Policy_Softkey *softkey;
967 if (e_config->use_softkey)
969 softkey = e_policy_softkey_get(ev->zone);
970 e_policy_softkey_update(softkey);
973 if (!e_config->use_desk_smart_obj)
974 _e_policy_client_maximize_update(ev->zone);
976 return ECORE_CALLBACK_PASS_ON;
980 _e_policy_cb_zone_desk_count_set(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
982 E_Event_Zone_Desk_Count_Set *ev;
987 E_Config_Policy_Desk *d;
990 Eina_List *desks_del = NULL;
995 /* remove deleted desk from hash */
996 it = eina_hash_iterator_data_new(hash_policy_desks);
997 while (eina_iterator_next(it, (void **)&pd))
999 if (pd->zone != zone) continue;
1002 n = zone->desk_y_count * zone->desk_x_count;
1003 for (i = 0; i < n; i++)
1005 if (pd->desk == zone->desks[i])
1012 desks_del = eina_list_append(desks_del, pd->desk);
1014 eina_iterator_free(it);
1016 EINA_LIST_FREE(desks_del, desk)
1018 pd = eina_hash_find(hash_policy_desks, &desk);
1019 if (pd) e_policy_desk_del(pd);
1022 /* add newly added desk to hash */
1023 n = zone->desk_y_count * zone->desk_x_count;
1024 for (i = 0; i < n; i++)
1026 if (e_config->use_configured_desks)
1028 d = _e_policy_desk_get_by_num(zone->num,
1032 e_policy_desk_add(zone->desks[i]);
1035 e_policy_desk_add(zone->desks[i]);
1038 return ECORE_CALLBACK_PASS_ON;
1042 _e_policy_cb_zone_display_state_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1044 E_Event_Zone_Display_State_Change *ev;
1047 if (!ev) return ECORE_CALLBACK_PASS_ON;
1049 e_client_visibility_calculate();
1051 return ECORE_CALLBACK_PASS_ON;
1055 _e_policy_cb_zone_useful_geometry_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1057 E_Event_Zone_Useful_Geometry_Change *ev;
1061 if (!ev) return ECORE_CALLBACK_PASS_ON;
1063 E_CLIENT_FOREACH(ec)
1065 if (ev->zone != ec->zone)
1069 e_client_maximize_update(ec);
1072 return ECORE_CALLBACK_PASS_ON;
1076 _e_policy_cb_desk_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1078 E_Event_Desk_Show *ev;
1079 E_Policy_Softkey *softkey;
1083 if (e_config->use_softkey)
1085 softkey = e_policy_softkey_get(ev->desk->zone);
1087 softkey = e_policy_softkey_add(ev->desk->zone);
1089 if (eina_hash_find(hash_policy_desks, &ev->desk))
1090 e_policy_softkey_show(softkey);
1092 e_policy_softkey_hide(softkey);
1094 return ECORE_CALLBACK_PASS_ON;
1098 _e_policy_cb_client_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1103 EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
1105 e_policy_wl_client_add(ev->ec);
1107 return ECORE_CALLBACK_PASS_ON;
1111 _e_policy_cb_client_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1124 e_policy_wl_position_send(ec);
1125 e_client_visibility_calculate();
1127 if (e_policy_client_is_lockscreen(ec))
1134 e_client_geometry_get(ec, &ex, &ey, &ew, &eh);
1136 if (E_CONTAINS(ex, ey, ew, eh, zx, zy, zw, zh))
1137 e_policy_stack_clients_restack_above_lockscreen(ev->ec, EINA_TRUE);
1139 e_policy_stack_clients_restack_above_lockscreen(ev->ec, EINA_FALSE);
1143 return ECORE_CALLBACK_PASS_ON;
1147 _e_policy_cb_client_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1153 ev = (E_Event_Client *)event;
1154 EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
1157 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, ECORE_CALLBACK_PASS_ON);
1159 /* re-calculate window's position with changed size */
1160 if (e_policy_client_is_volume_tv(ec))
1162 e_zone_useful_geometry_get(ec->zone, NULL, NULL, NULL, &zh);
1163 evas_object_move(ec->frame, 0, (zh / 2) - (ec->h / 2));
1165 evas_object_pass_events_set(ec->frame, 1);
1168 /* calculate e_client visibility */
1169 e_client_visibility_calculate();
1171 return ECORE_CALLBACK_PASS_ON;
1175 _e_policy_client_find_above(const E_Client *ec)
1180 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1181 if (EINA_INLIST_GET(ec)->next) //check current layer
1183 EINA_INLIST_FOREACH(EINA_INLIST_GET(ec)->next, ec2)
1185 if ((!e_object_is_del(E_OBJECT(ec2))) &&
1186 (!e_client_util_ignored_get(ec2)) &&
1192 if (ec->layer == E_LAYER_CLIENT_ALERT) return NULL;
1193 if (e_comp_canvas_client_layer_map(ec->layer) == 9999) return NULL;
1195 /* go up the layers until we find one */
1196 for (x = e_comp_canvas_layer_map(ec->layer) + 1; x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT); x++)
1198 if (!e_comp->layers[x].clients) continue;
1199 EINA_INLIST_FOREACH(e_comp->layers[x].clients, ec2)
1201 if (ec2 == ec) continue;
1202 if ((!e_object_is_del(E_OBJECT(ec2))) &&
1203 (!e_client_util_ignored_get(ec2)) &&
1213 _e_policy_client_find_below(const E_Client *ec)
1219 E_OBJECT_CHECK_RETURN(ec, NULL);
1220 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, NULL);
1222 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1223 if (EINA_INLIST_GET(ec)->prev) //check current layer
1225 for (l = EINA_INLIST_GET(ec)->prev; l; l = l->prev)
1227 ec2 = EINA_INLIST_CONTAINER_GET(l, E_Client);
1228 if ((!e_object_is_del(E_OBJECT(ec2))) &&
1229 (!e_client_util_ignored_get(ec2)) &&
1236 /* go down the layers until we find one */
1237 if (e_comp_canvas_layer_map(ec->layer) > e_comp_canvas_layer_map(E_LAYER_MAX)) return NULL;
1238 x = e_comp_canvas_layer_map(ec->layer);
1241 for (; x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
1243 if (!e_comp->layers[x].clients) continue;
1244 EINA_INLIST_REVERSE_FOREACH(e_comp->layers[x].clients, ec2)
1246 if (ec2 == ec) continue;
1247 if ((!e_object_is_del(E_OBJECT(ec2))) &&
1248 (!e_client_util_ignored_get(ec2)) &&
1258 _e_policy_client_stack_change_send(E_Client *ec)
1260 E_Client *above = NULL;
1261 E_Client *below = NULL;
1265 above = _e_policy_client_find_above(ec);
1266 below = _e_policy_client_find_below(ec);
1268 if (above) above_pid = above->netwm.pid;
1269 if (below) below_pid = below->netwm.pid;
1271 ELOGF("TZPOL", "Send stack change. above(win:%zx, pid:%d), below(win:%zx, pid:%d)",
1272 ec, e_client_util_win_get(above), above_pid, e_client_util_win_get(below), below_pid);
1274 e_policy_aux_message_send_from_int(ec, "stack_changed", "pid", 2, above_pid, below_pid);
1278 _e_policy_cb_client_stack(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1283 if (!ev) return ECORE_CALLBACK_PASS_ON;
1284 /* calculate e_client visibility */
1285 e_client_visibility_calculate();
1287 // send stack change event
1288 _e_policy_client_stack_change_send(ev->ec);
1290 return ECORE_CALLBACK_PASS_ON;
1294 _e_policy_cb_client_property(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1296 E_Event_Client_Property *ev;
1299 if (!ev || (!ev->ec)) return ECORE_CALLBACK_PASS_ON;
1300 if (ev->property & E_CLIENT_PROPERTY_CLIENT_TYPE)
1302 if (e_policy_client_is_home_screen(ev->ec))
1304 ev->ec->lock_client_stacking = 0;
1305 e_client_desk_iconify_skip_set(ev->ec, EINA_TRUE);
1306 if (ev->ec->maximized)
1307 e_client_maximize(ev->ec, E_MAXIMIZE_FULLSCREEN | E_MAXIMIZE_BOTH);
1311 return ECORE_CALLBACK_PASS_ON;
1315 _e_policy_cb_client_vis_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
1317 e_policy_wl_win_scrmode_apply();
1318 return ECORE_CALLBACK_PASS_ON;
1322 _e_policy_cb_client_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1328 if (!ev) return ECORE_CALLBACK_PASS_ON;
1331 e_policy_stack_check_above_lockscreen(ec, ec->layer);
1333 return ECORE_CALLBACK_PASS_ON;
1337 _e_policy_cb_client_hide(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1343 if (!ev) return ECORE_CALLBACK_PASS_ON;
1346 e_tzsh_indicator_srv_ower_win_update(ec->zone);
1348 return ECORE_CALLBACK_PASS_ON;
1352 _e_policy_cb_idle_enterer(void *data EINA_UNUSED)
1356 if (_e_pol_changed_vis)
1358 EINA_LIST_FREE(_e_pol_changed_zone, zone)
1360 e_tzsh_indicator_srv_ower_win_update(zone);
1362 _e_pol_changed_zone = NULL;
1364 _e_pol_changed_vis = EINA_FALSE;
1366 return ECORE_CALLBACK_RENEW;
1370 e_policy_desk_add(E_Desk *desk)
1374 E_Policy_Client *pc;
1376 pd = eina_hash_find(hash_policy_desks, &desk);
1379 pd = E_NEW(E_Policy_Desk, 1);
1383 pd->zone = desk->zone;
1385 eina_hash_add(hash_policy_desks, &desk, pd);
1388 E_CLIENT_FOREACH(ec)
1390 if (pd->desk == ec->desk)
1392 pc = eina_hash_find(hash_policy_clients, &ec);
1393 _e_policy_client_maximize_policy_apply(pc);
1399 e_policy_desk_del(E_Policy_Desk *pd)
1402 E_Policy_Client *pc;
1404 Eina_List *clients_del = NULL;
1405 E_Policy_Softkey *softkey;
1407 /* hide and delete softkey */
1408 if (e_config->use_softkey)
1410 softkey = e_policy_softkey_get(pd->zone);
1411 if (e_desk_current_get(pd->zone) == pd->desk)
1412 e_policy_softkey_hide(softkey);
1415 /* remove clients */
1416 it = eina_hash_iterator_data_new(hash_policy_clients);
1417 while (eina_iterator_next(it, (void **)&pc))
1419 if (pc->ec->desk == pd->desk)
1420 clients_del = eina_list_append(clients_del, pc->ec);
1422 eina_iterator_free(it);
1424 EINA_LIST_FREE(clients_del, ec)
1426 pc = eina_hash_find(hash_policy_clients, &ec);
1427 _e_policy_client_maximize_policy_cancel(pc);
1430 eina_hash_del_by_key(hash_policy_desks, &pd->desk);
1433 EINTERN E_Policy_Client *
1434 e_policy_client_launcher_get(E_Zone *zone)
1436 E_Policy_Client *pc;
1439 EINA_LIST_FOREACH(e_policy->launchers, l, pc)
1441 if (pc->ec->zone == zone)
1448 e_policy_client_unmap(E_Client *ec)
1450 Eina_Bool send_event = EINA_FALSE;
1453 if (e_object_is_del(E_OBJECT(ec))) return;
1455 ELOGF("TZPOL", "Reset ec information by unmap", ec);
1458 send_event = EINA_TRUE;
1463 ec->exp_iconify.by_client = 0;
1464 e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_NONE);
1465 ec->exp_iconify.not_raise = 0;
1466 ec->exp_iconify.skip_iconify = 0;
1469 e_policy_wl_iconify_state_change_send(ec, 0);
1471 e_comp_object_effect_set(ec->frame, NULL);
1475 e_policy_client_maximize(E_Client *ec)
1478 E_Policy_Client *pc;
1480 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1481 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1483 if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
1485 if ((e_policy_client_is_keyboard(ec)) ||
1486 (e_policy_client_is_keyboard_sub(ec)) ||
1487 (e_policy_client_is_floating(ec)) ||
1488 (e_policy_client_is_quickpanel(ec)) ||
1489 (e_policy_client_is_volume(ec)) ||
1490 (!e_util_strcmp("wl_pointer-cursor", ec->icccm.window_role)) ||
1491 (!e_util_strcmp("e_demo", ec->icccm.window_role)))
1494 if (e_policy_client_is_subsurface(ec)) return EINA_FALSE;
1496 if ((ec->netwm.type != E_WINDOW_TYPE_NORMAL) &&
1497 (ec->netwm.type != E_WINDOW_TYPE_UNKNOWN) &&
1498 (ec->netwm.type != E_WINDOW_TYPE_NOTIFICATION))
1501 pd = eina_hash_find(hash_policy_desks, &ec->desk);
1502 if (!pd) return EINA_FALSE;
1504 pc = eina_hash_find(hash_policy_clients, &ec);
1505 EINA_SAFETY_ON_NULL_RETURN_VAL(pc, EINA_FALSE);
1507 if (pc->flt_policy_state)
1508 _e_policy_client_floating_policy_cancel(pc);
1510 return _e_policy_client_maximize_policy_apply(pc);
1514 e_policy_keyboard_layout_apply(E_Client *ec EINA_UNUSED)
1516 /* FIXME: do not resize and move client.
1517 * ec->e.state.rot.geom[].w/h is always 0,
1518 * then the geometry calculated here is not valid. */
1522 int kbd_x, kbd_y, kbd_w, kbd_h;
1524 if (!e_policy_client_is_keyboard(ec) &&
1525 !e_policy_client_is_keyboard_sub(ec))
1528 angle = e_client_rotation_curr_angle_get(ec);
1532 case 0: angle_id = 0; break;
1533 case 90: angle_id = 1; break;
1534 case 180: angle_id = 2; break;
1535 case 270: angle_id = 3; break;
1536 default: angle_id = 0; break;
1539 kbd_w = ec->e.state.rot.geom[angle_id].w;
1540 kbd_h = ec->e.state.rot.geom[angle_id].h;
1545 kbd_x = ec->zone->w - kbd_w;
1546 kbd_y = ec->zone->h - kbd_h;
1550 kbd_x = ec->zone->w - kbd_w;
1551 kbd_y = ec->zone->h - kbd_h;
1565 kbd_x = ec->zone->w - kbd_w;
1566 kbd_y = ec->zone->h - kbd_h;
1571 ((ec->w != kbd_w) || (ec->h != kbd_h)))
1572 e_client_util_resize_without_frame(ec, kbd_w, kbd_h);
1574 if ((e_policy_client_is_keyboard(ec)) &&
1576 ((ec->x != kbd_x) || (ec->y != kbd_y)))
1577 e_client_util_move_without_frame(ec, kbd_x, kbd_y);
1582 e_policy_client_is_lockscreen(E_Client *ec)
1584 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1585 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1587 if (ec->client_type == 2)
1590 if (!e_util_strcmp(ec->icccm.title, "LOCKSCREEN"))
1593 if (!e_util_strcmp(ec->icccm.window_role, "lockscreen"))
1600 e_policy_client_is_home_screen(E_Client *ec)
1602 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1603 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1605 if (ec->client_type == 1)
1613 e_policy_client_is_quickpanel(E_Client *ec)
1615 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1616 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1618 if (!e_util_strcmp(ec->icccm.window_role, "quickpanel_system_default"))
1621 if (!e_util_strcmp(ec->icccm.window_role, "quickpanel_context_menu"))
1624 if (!e_util_strcmp(ec->icccm.window_role, "quickpanel_apps_menu"))
1631 e_policy_client_is_conformant(E_Client *ec)
1633 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1634 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
1636 E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data *)ec->comp_data;
1637 if (cdata->conformant == 1)
1646 e_policy_client_is_volume(E_Client *ec)
1648 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1649 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1651 if (!e_util_strcmp(ec->netwm.name, "volume"))
1654 if (!e_util_strcmp(ec->icccm.title, "volume"))
1661 e_policy_client_is_volume_tv(E_Client *ec)
1663 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1664 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1666 if (!e_util_strcmp(ec->icccm.window_role, "tv-volume-popup"))
1673 e_policy_client_is_noti(E_Client *ec)
1675 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1676 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1678 if (!e_util_strcmp(ec->icccm.title, "noti_win"))
1681 if (ec->netwm.type == E_WINDOW_TYPE_NOTIFICATION)
1688 e_policy_client_is_subsurface(E_Client *ec)
1690 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1691 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1693 if (e_comp_wl_subsurface_check(ec))
1700 e_policy_client_is_floating(E_Client *ec)
1702 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1703 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1705 return ec->floating;
1709 e_policy_client_is_magnifier(E_Client *ec)
1711 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1712 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1714 return ec->is_magnifier;
1718 e_policy_client_is_cursor(E_Client *ec)
1720 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1721 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1723 if (!e_util_strcmp("wl_pointer-cursor", ec->icccm.window_role))
1730 e_policy_client_is_cbhm(E_Client *ec)
1732 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1733 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1735 if (!e_util_strcmp("cbhm", ec->icccm.window_role))
1742 e_policy_client_is_toast_popup(E_Client *ec)
1744 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1745 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1747 #if defined(__cplusplus) || defined(c_plusplus)
1748 if (!e_util_strcmp("TOAST_POPUP", ec->icccm.cpp_class))
1751 if (!e_util_strcmp("TOAST_POPUP", ec->icccm.class))
1754 if (!e_util_strcmp("toast_popup", ec->icccm.window_role))
1761 e_policy_client_is_dialog(E_Client *ec)
1763 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1764 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1766 if (ec->netwm.type == E_WINDOW_TYPE_DIALOG)
1773 e_policy_client_is_keyboard(E_Client *ec)
1775 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1776 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1778 if (ec->vkbd.vkbd) return EINA_TRUE;
1784 e_policy_client_is_keyboard_sub(E_Client *ec)
1786 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1787 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1789 if (ec->vkbd.vkbd) return EINA_FALSE;
1791 #if defined(__cplusplus) || defined(c_plusplus)
1792 if ((ec->icccm.cpp_class) &&
1793 (!strcmp(ec->icccm.cpp_class, "ISF")))
1796 if ((ec->icccm.class) &&
1797 (!strcmp(ec->icccm.class, "ISF")))
1800 if ((ec->icccm.title) &&
1801 ((!strcmp(ec->icccm.title, "ISF Popup")) || (!strcmp(ec->icccm.title, "ISF Magnifier"))))
1808 e_policy_client_is_keyboard_magnifier(E_Client *ec)
1810 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1811 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1813 if (ec->vkbd.vkbd) return EINA_FALSE;
1815 if ((ec->icccm.title) && (!strcmp(ec->icccm.title, "ISF Magnifier")))
1822 e_policy_client_is_watch_viewer(E_Client *ec)
1824 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1825 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1827 if (!e_util_strcmp(e_client_util_name_get(ec), "WATCH_WINDOW"))
1834 e_policy_client_is_taskbar(E_Client *ec)
1836 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1837 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1839 if (ec->client_type == 3)
1842 if (!e_util_strcmp(ec->icccm.title, "TaskBar"))
1845 if (!e_util_strcmp(ec->icccm.window_role, "taskbar"))
1851 E_API E_Service_Quickpanel_Type
1852 e_policy_quickpanel_type_get(E_Client *ec)
1854 E_Service_Quickpanel_Type type = E_SERVICE_QUICKPANEL_TYPE_UNKNOWN;
1856 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1857 E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE);
1859 type = e_service_quickpanel_type_get(ec);
1864 e_policy_interceptors_clean(void)
1866 E_Policy_Interceptor *pi;
1869 for (x = 0; x < E_POLICY_INTERCEPT_LAST; x++)
1871 pi = _e_policy_interceptors[x];
1872 if (!pi->delete_me) continue;
1873 _e_policy_interceptors[x] = NULL;
1881 * if interceptor process something successfully at its intercept point,
1883 * if interceptor failed or there is no interceptor.
1886 e_policy_interceptor_call(E_Policy_Intercept_Point ipoint, E_Client *ec, ...)
1889 E_Policy_Interceptor *pi;
1890 Eina_Bool ret = EINA_TRUE;
1892 if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
1893 pi = _e_policy_interceptors[ipoint];
1894 if (!pi) return EINA_FALSE;
1898 e_object_ref(E_OBJECT(ec));
1899 _e_policy_interceptors_walking++;
1902 if (!(pi->func(pi->data, ec, list)))
1905 _e_policy_interceptors_walking--;
1906 if ((_e_policy_interceptors_walking == 0) && (_e_policy_interceptors_delete > 0))
1907 e_policy_interceptors_clean();
1910 e_object_unref(E_OBJECT(ec));
1915 _e_policy_event_simple_free(void *d EINA_UNUSED, E_Event_Client *ev)
1917 e_object_unref(E_OBJECT(ev->ec));
1922 e_policy_event_simple(E_Client *ec, int type)
1926 ev = E_NEW(E_Event_Client, 1);
1930 e_object_ref(E_OBJECT(ec));
1931 ecore_event_add(type, ev, (Ecore_End_Cb)_e_policy_event_simple_free, NULL);
1935 e_policy_aux_message_use_get(E_Client *ec)
1937 E_OBJECT_CHECK_RETURN(ec, EINA_FALSE);
1938 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
1940 E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data *)ec->comp_data;
1941 if (cdata->aux_hint.use_msg)
1950 e_policy_aux_message_send_from_int(E_Client *ec, const char *key, const char *val, int count, ...)
1954 Eina_List *options_list = NULL;
1959 va_start(opt_args, count);
1960 for(itor = 0; itor < count; itor ++)
1962 opt = va_arg(opt_args, int);
1963 eina_convert_itoa(opt, option);
1964 options_list = eina_list_append(options_list, eina_stringshare_add(option));
1968 e_policy_aux_message_send(ec, key, val, options_list);
1970 EINA_LIST_FREE(options_list, str_itor)
1972 eina_stringshare_del(str_itor);
1977 e_policy_aux_message_send(E_Client *ec, const char *key, const char *val, Eina_List *options)
1980 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
1982 e_policy_wl_aux_message_send(ec, key, val, options);
1985 E_API E_Policy_Interceptor *
1986 e_policy_interceptor_add(E_Policy_Intercept_Point ipoint, E_Policy_Intercept_Cb func, const void *data)
1988 E_Policy_Interceptor *pi;
1990 EINA_SAFETY_ON_TRUE_RETURN_VAL(ipoint >= E_POLICY_INTERCEPT_LAST, NULL);
1991 EINA_SAFETY_ON_TRUE_RETURN_VAL(!!_e_policy_interceptors[ipoint], NULL);
1992 pi = E_NEW(E_Policy_Interceptor, 1);
1993 if (!pi) return NULL;
1994 pi->ipoint = ipoint;
1996 pi->data = (void*)data;
1997 _e_policy_interceptors[ipoint] = pi;
2002 e_policy_interceptor_del(E_Policy_Interceptor *pi)
2005 if (_e_policy_interceptors_walking == 0)
2007 _e_policy_interceptors[pi->ipoint] = NULL;
2011 _e_policy_interceptors_delete++;
2014 E_API E_Policy_Hook *
2015 e_policy_hook_add(E_Policy_Hook_Point hookpoint, E_Policy_Hook_Cb func, const void *data)
2019 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_POLICY_HOOK_LAST, NULL);
2020 ph = E_NEW(E_Policy_Hook, 1);
2021 if (!ph) return NULL;
2022 ph->hookpoint = hookpoint;
2024 ph->data = (void*)data;
2025 _e_policy_hooks[hookpoint] = eina_inlist_append(_e_policy_hooks[hookpoint], EINA_INLIST_GET(ph));
2030 e_policy_hook_del(E_Policy_Hook *ph)
2033 if (_e_policy_hooks_walking == 0)
2035 _e_policy_hooks[ph->hookpoint] = eina_inlist_remove(_e_policy_hooks[ph->hookpoint], EINA_INLIST_GET(ph));
2039 _e_policy_hooks_delete++;
2043 _e_policy_hooks_clean(void)
2049 for (x = 0; x < E_POLICY_HOOK_LAST; x++)
2051 EINA_INLIST_FOREACH_SAFE(_e_policy_hooks[x], l, ph)
2053 if (!ph->delete_me) continue;
2054 _e_policy_hooks[x] = eina_inlist_remove(_e_policy_hooks[x], EINA_INLIST_GET(ph));
2061 e_policy_hook_call(E_Policy_Hook_Point hookpoint, E_Client *ec)
2065 e_object_ref(E_OBJECT(ec));
2066 _e_policy_hooks_walking++;
2068 EINA_INLIST_FOREACH(_e_policy_hooks[hookpoint], ch)
2070 if (ch->delete_me) continue;
2071 ch->func(ch->data, ec);
2073 _e_policy_hooks_walking--;
2074 if ((_e_policy_hooks_walking == 0) && (_e_policy_hooks_delete > 0))
2075 _e_policy_hooks_clean();
2076 return !!e_object_unref(E_OBJECT(ec));
2080 e_policy_user_geometry_set(E_Client *ec,
2081 E_Policy_Allow_User_Geometry type,
2084 E_Policy_Client *pc;
2086 if (EINA_UNLIKELY(!ec))
2089 pc = eina_hash_find(hash_policy_clients, &ec);
2090 if (EINA_UNLIKELY(!pc))
2094 pc->user_geom_state |= type;
2096 pc->user_geom_state &= ~(type);
2098 if (pc->user_geom_state)
2099 e_policy_allow_user_geometry_set(ec, EINA_TRUE);
2101 e_policy_allow_user_geometry_set(ec, EINA_FALSE);
2105 e_policy_allow_user_geometry_set(E_Client *ec, Eina_Bool set)
2107 E_Policy_Client *pc;
2109 if (EINA_UNLIKELY(!ec))
2112 pc = eina_hash_find(hash_policy_clients, &ec);
2113 if (EINA_UNLIKELY(!pc))
2116 if (set && !pc->allow_user_geom)
2118 pc->allow_user_geom = EINA_TRUE;
2120 if (!e_policy_client_is_noti(ec))
2122 ec->netwm.type = E_WINDOW_TYPE_UTILITY;
2123 ec->lock_client_location = EINA_FALSE;
2126 _e_policy_client_maximize_policy_cancel(pc);
2128 ec->lock_client_location = EINA_FALSE;
2129 ec->lock_client_size = EINA_FALSE;
2134 else if (!set && pc->allow_user_geom)
2136 pc->allow_user_geom = EINA_FALSE;
2138 ec->lock_client_location = EINA_TRUE;
2139 ec->lock_client_size = EINA_TRUE;
2141 ec->netwm.type = E_WINDOW_TYPE_NORMAL;
2143 e_client_pending_geometry_flush(ec);
2144 ec->icccm.min_w = ec->icccm.min_h = 0;
2145 ec->icccm.max_w = ec->icccm.max_h = 0;
2151 e_policy_allow_user_geometry_get(E_Client *ec)
2153 E_Policy_Client *pc;
2155 if (EINA_UNLIKELY(!ec))
2158 pc = eina_hash_find(hash_policy_clients, &ec);
2159 if (EINA_UNLIKELY(!pc))
2162 return pc->allow_user_geom;
2166 e_policy_animatable_lock(E_Client *ec,
2167 E_Policy_Animatable_Lock lock,
2170 E_Policy_Client *pc;
2172 if (EINA_UNLIKELY(!ec))
2175 pc = eina_hash_find(hash_policy_clients, &ec);
2176 if (EINA_UNLIKELY(!pc))
2180 pc->lock_animatable |= lock;
2182 pc->lock_animatable &= ~(lock);
2184 if (pc->lock_animatable)
2185 ec->animatable = EINA_FALSE;
2187 ec->animatable = EINA_TRUE;
2189 ELOGF("TZPOL","EFFECT(animatable:%d) due to %d is applied on the state %d --> result:%d", ec,
2190 ec->animatable, set, lock, pc->lock_animatable);
2194 e_policy_deferred_job(void)
2196 if (!e_policy) return;
2198 e_policy_wl_defer_job();
2206 E_Config_Policy_Desk *d;
2210 pol = E_NEW(E_Policy, 1);
2211 EINA_SAFETY_ON_NULL_RETURN_VAL(pol, EINA_FALSE);
2215 hash_policy_clients = eina_hash_pointer_new(_e_policy_cb_client_data_free);
2216 hash_policy_desks = eina_hash_pointer_new(_e_policy_cb_desk_data_free);
2218 E_EVENT_POLICY_QUICKPANEL_VISIBLE_STATE_CHANGE = ecore_event_type_new();
2220 e_policy_stack_init();
2222 e_policy_wl_aux_hint_init();
2224 EINA_LIST_FOREACH(e_comp->zones, l, zone)
2226 n = zone->desk_y_count * zone->desk_x_count;
2227 for (i = 0; i < n; i++)
2229 if (e_config->use_configured_desks)
2231 d = _e_policy_desk_get_by_num(zone->num,
2235 e_policy_desk_add(zone->desks[i]);
2238 e_policy_desk_add(zone->desks[i]);
2242 E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_ADD, _e_policy_cb_zone_add, NULL);
2243 E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DEL, _e_policy_cb_zone_del, NULL);
2244 E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_MOVE_RESIZE, _e_policy_cb_zone_move_resize, NULL);
2245 E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DESK_COUNT_SET, _e_policy_cb_zone_desk_count_set, NULL);
2246 E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DISPLAY_STATE_CHANGE, _e_policy_cb_zone_display_state_change, NULL);
2247 E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_USEFUL_GEOMETRY_CHANGE, _e_policy_cb_zone_useful_geometry_change, NULL);
2248 E_LIST_HANDLER_APPEND(handlers, E_EVENT_DESK_SHOW, _e_policy_cb_desk_show, NULL);
2249 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_ADD, _e_policy_cb_client_add, NULL);
2250 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_MOVE, _e_policy_cb_client_move, NULL);
2251 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_RESIZE, _e_policy_cb_client_resize, NULL);
2252 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_STACK, _e_policy_cb_client_stack, NULL);
2253 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_PROPERTY, _e_policy_cb_client_property, NULL);
2254 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_VISIBILITY_CHANGE, _e_policy_cb_client_vis_change, NULL);
2255 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_SHOW, _e_policy_cb_client_show, NULL);
2256 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_HIDE, _e_policy_cb_client_hide, NULL);
2258 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_NEW_CLIENT, _e_policy_cb_hook_client_new, NULL);
2259 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_DEL, _e_policy_cb_hook_client_del, NULL);
2260 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_EVAL_PRE_NEW_CLIENT, _e_policy_cb_hook_client_eval_pre_new_client, NULL);
2261 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_EVAL_PRE_FETCH, _e_policy_cb_hook_client_eval_pre_fetch, NULL);
2262 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_EVAL_PRE_POST_FETCH, _e_policy_cb_hook_client_eval_pre_post_fetch, NULL);
2263 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_EVAL_POST_FETCH, _e_policy_cb_hook_client_eval_post_fetch, NULL);
2264 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_EVAL_POST_NEW_CLIENT,_e_policy_cb_hook_client_eval_post_new_client,NULL);
2265 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_DESK_SET, _e_policy_cb_hook_client_desk_set, NULL);
2266 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_FULLSCREEN_PRE, _e_policy_cb_hook_client_fullscreen_pre, NULL);
2267 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_EVAL_VISIBILITY, _e_policy_cb_hook_client_visibility, NULL);
2268 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_UNICONIFY, _e_policy_cb_hook_client_uniconify, NULL);
2270 E_PIXMAP_HOOK_APPEND(hooks_cp, E_PIXMAP_HOOK_DEL, _e_policy_cb_hook_pixmap_del, NULL);
2271 E_PIXMAP_HOOK_APPEND(hooks_cp, E_PIXMAP_HOOK_UNUSABLE, _e_policy_cb_hook_pixmap_unusable, NULL);
2273 _e_pol_idle_enterer = ecore_idle_enterer_add(_e_policy_cb_idle_enterer, NULL);
2275 e_policy_conformant_init();
2276 e_policy_visibility_init();
2282 e_policy_shutdown(void)
2284 E_Policy *pol = e_policy;
2286 E_Policy_Softkey *softkey;
2288 eina_list_free(_e_pol_changed_zone);
2289 eina_list_free(pol->launchers);
2290 EINA_INLIST_FOREACH_SAFE(pol->softkeys, l, softkey)
2291 e_policy_softkey_del(softkey);
2292 E_FREE_LIST(hooks_cp, e_pixmap_hook_del);
2293 E_FREE_LIST(hooks_ec, e_client_hook_del);
2294 E_FREE_LIST(handlers, ecore_event_handler_del);
2296 E_FREE_FUNC(hash_policy_desks, eina_hash_free);
2297 E_FREE_FUNC(hash_policy_clients, eina_hash_free);
2299 e_policy_stack_shutdown();
2300 e_policy_wl_shutdown();
2302 e_policy_conformant_shutdown();
2303 e_policy_visibility_shutdown();