5 /* local function prototypes */
6 static void _policy_border_set_focus(E_Border *bd);
7 static void _policy_border_move(E_Border *bd, int x, int y);
8 static void _policy_border_resize(E_Border *bd, int w, int h);
9 static void _policy_border_hide_below(E_Border *bd);
10 static void _policy_zone_layout_update(E_Zone *zone);
11 static void _policy_zone_layout_indicator(E_Border *bd, E_Illume_Config_Zone *cz);
12 static void _policy_zone_layout_quickpanel(E_Border *bd);
13 static void _policy_zone_layout_softkey(E_Border *bd, E_Illume_Config_Zone *cz);
14 static void _policy_zone_layout_keyboard(E_Border *bd, E_Illume_Config_Zone *cz);
15 static void _policy_zone_layout_home_single(E_Border *bd, E_Illume_Config_Zone *cz);
16 static void _policy_zone_layout_fullscreen(E_Border *bd);
17 static void _policy_zone_layout_app_single(E_Border *bd, E_Illume_Config_Zone *cz);
18 static void _policy_zone_layout_app_dual_top(E_Border *bd, E_Illume_Config_Zone *cz);
19 static void _policy_zone_layout_app_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz);
20 static void _policy_zone_layout_app_dual_left(E_Border *bd, E_Illume_Config_Zone *cz, Eina_Bool force);
21 static void _policy_zone_layout_dialog(E_Border *bd, E_Illume_Config_Zone *cz);
22 static void _policy_zone_layout_splash(E_Border *bd, E_Illume_Config_Zone *cz);
23 static void _policy_zone_layout_conformant_single(E_Border *bd, E_Illume_Config_Zone *cz);
25 static void _policy_zone_layout_conformant_dual_top(E_Border *bd, E_Illume_Config_Zone *cz);
26 static void _policy_zone_layout_conformant_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz);
27 static void _policy_zone_layout_conformant_dual_left(E_Border *bd, E_Illume_Config_Zone *cz);
30 static Eina_List *_pol_focus_stack;
34 _policy_border_set_focus(E_Border *bd)
37 /* printf("_policy_border_set_focus %s\n", e_border_name_get(bd)); */
39 /* if focus is locked out then get out */
40 if (bd->lock_focus_out) return;
42 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
44 /* check E's focus settings */
45 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
47 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
48 ((bd->parent->focused) &&
49 (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))))
51 /* if the border was hidden due to layout, we need to unhide */
52 if (!bd->visible) e_illume_border_show(bd);
54 if ((bd->iconic) && (!bd->lock_user_iconify))
55 e_border_uniconify(bd);
57 if (!bd->lock_user_stacking) e_border_raise(bd);
59 /* focus the border */
60 e_border_focus_set(bd, 1, 1);
61 /* e_border_raise(bd); */
62 /* hide the border below this one */
63 _policy_border_hide_below(bd);
65 /* NB: since we skip needless border evals when container layout
66 * is called (to save cpu cycles), we need to
67 * signal this border that it's focused so that the edj gets
70 * This is potentially useless as THIS policy
71 * makes all windows borderless anyway, but it's in here for
73 e_border_focus_latest_set(bd);
75 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
77 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
78 e_focus_event_focus_in(bd);
85 _policy_border_move(E_Border *bd, int x, int y)
96 _policy_border_resize(E_Border *bd, int w, int h)
102 bd->client.w = (bd->w - (bd->client_inset.l + bd->client_inset.r));
103 bd->client.h = (bd->h - (bd->client_inset.t + bd->client_inset.b));
104 bd->changes.size = 1;
109 _policy_border_hide_below(E_Border *bd)
115 // printf("Hide Borders Below: %s %d %d\n",
116 // bd->client.icccm.name, bd->x, bd->y);
119 /* printf("_policy_border_hide_below %s\n", e_border_name_get(bd)); */
120 /* determine layering position */
121 if (bd->layer <= 0) pos = 0;
122 else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1;
123 else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2;
124 else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3;
125 else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4;
128 /* Find the windows below this one */
129 for (i = pos; i >= 2; i--)
134 EINA_LIST_FOREACH(bd->zone->container->layers[i].clients, l, b)
136 /* skip if it's the same border */
137 if (b == bd) continue;
139 /* skip if it's not on this zone */
140 if (b->zone != bd->zone) continue;
142 /* skip special borders */
143 if (e_illume_border_is_indicator(b)) continue;
144 if (e_illume_border_is_softkey(b)) continue;
145 if (e_illume_border_is_keyboard(b)) continue;
146 if (e_illume_border_is_quickpanel(b)) continue;
147 if (e_illume_border_is_home(b)) continue;
149 if ((bd->fullscreen) || (bd->need_fullscreen))
151 if (b->visible) e_illume_border_hide(b);
155 /* we need to check x/y position */
156 if (E_CONTAINS(bd->x, bd->y, bd->w, bd->h,
157 b->x, b->y, b->w, b->h))
159 if (b->visible) e_illume_border_hide(b);
168 _policy_border_show_below(E_Border *bd)
174 // printf("Show Borders Below: %s %d %d\n",
175 // bd->client.icccm.class, bd->x, bd->y);
178 /* printf("_policy_border_show_below %s\n", e_border_name_get(bd)); */
179 if (bd->client.icccm.transient_for)
181 if ((prev = e_border_find_by_client_window(bd->client.icccm.transient_for)))
183 _policy_border_set_focus(prev);
188 /* determine layering position */
189 if (bd->layer <= 0) pos = 0;
190 else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1;
191 else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2;
192 else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3;
193 else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4;
196 /* Find the windows below this one */
197 for (i = pos; i >= 2; i--)
201 EINA_LIST_REVERSE_FOREACH(bd->zone->container->layers[i].clients, l, b)
203 /* skip if it's the same border */
204 if (b == bd) continue;
206 /* skip if it's not on this zone */
207 if (b->zone != bd->zone) continue;
209 /* skip special borders */
210 if (e_illume_border_is_indicator(b)) continue;
211 if (e_illume_border_is_softkey(b)) continue;
212 if (e_illume_border_is_keyboard(b)) continue;
213 if (e_illume_border_is_quickpanel(b)) continue;
214 if (e_illume_border_is_home(b)) continue;
216 if ((bd->fullscreen) || (bd->need_fullscreen))
218 _policy_border_set_focus(b);
223 /* need to check x/y position */
224 if (E_CONTAINS(bd->x, bd->y, bd->w, bd->h,
225 b->x, b->y, b->w, b->h))
227 _policy_border_set_focus(b);
234 /* if we reach here, then there is a problem with showing a window below
235 * this one, so show previous window in stack */
236 EINA_LIST_REVERSE_FOREACH(_pol_focus_stack, l, prev)
238 if (prev->zone != bd->zone) continue;
239 _policy_border_set_focus(prev);
243 /* Fallback to focusing home if all above fails */
244 _policy_focus_home(bd->zone);
249 _policy_zone_layout_update(E_Zone *zone)
256 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
258 /* skip borders not on this zone */
259 if (bd->zone != zone) continue;
261 /* skip special windows */
262 if (e_illume_border_is_keyboard(bd)) continue;
263 if (e_illume_border_is_quickpanel(bd)) continue;
265 /* signal a changed pos here so layout gets updated */
272 _policy_zone_layout_indicator(E_Border *bd, E_Illume_Config_Zone *cz)
274 if ((!bd) || (!cz)) return;
276 /* grab minimum indicator size */
277 e_illume_border_min_get(bd, NULL, &cz->indicator.size);
279 /* no point in doing anything here if indicator is hidden */
280 if ((!bd->new_client) && (!bd->visible))
282 ecore_x_e_illume_indicator_geometry_set(bd->zone->black_win,
287 /* if we are dragging, then skip it for now */
288 if (bd->client.illume.drag.drag)
290 /* when dragging indicator, we need to trigger a layout update */
291 ecore_x_e_illume_indicator_geometry_set(bd->zone->black_win,
293 _policy_zone_layout_update(bd->zone);
297 // printf("\tLayout Indicator: %d\n", bd->zone->num);
299 /* lock indicator window from dragging if we need to */
300 if ((cz->mode.dual == 1) && (cz->mode.side == 0))
301 ecore_x_e_illume_drag_locked_set(bd->client.win, 0);
303 ecore_x_e_illume_drag_locked_set(bd->client.win, 1);
305 if ((bd->w != bd->zone->w) || (bd->h != cz->indicator.size))
306 _policy_border_resize(bd, bd->zone->w, cz->indicator.size);
310 /* move to 0, 0 (relative to zone) if needed */
311 if ((bd->x != bd->zone->x) || (bd->y != bd->zone->y))
313 _policy_border_move(bd, bd->zone->x, bd->zone->y);
314 ecore_x_e_illume_quickpanel_position_update_send(bd->client.win);
319 if (cz->mode.side == 0)
321 /* top mode...indicator is draggable so just set X.
322 * in this case, the indicator itself should be responsible for
323 * sending the quickpanel position update message when it is
324 * finished dragging */
325 if (bd->x != bd->zone->x)
326 _policy_border_move(bd, bd->zone->x, bd->y);
330 /* move to 0, 0 (relative to zone) if needed */
331 if ((bd->x != bd->zone->x) || (bd->y != bd->zone->y))
333 _policy_border_move(bd, bd->zone->x, bd->zone->y);
334 ecore_x_e_illume_quickpanel_position_update_send(bd->client.win);
338 ecore_x_e_illume_indicator_geometry_set(bd->zone->black_win,
342 if (bd->layer != POL_INDICATOR_LAYER)
343 e_border_layer_set(bd, POL_INDICATOR_LAYER);
346 #define ZONE_GEOMETRY \
348 e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h); \
353 _border_geometry_set(E_Border *bd, int x, int y, int w, int h, int layer)
355 if ((bd->w != w) || (bd->h != h))
356 _policy_border_resize(bd, w, h);
358 if ((bd->x != x) || (bd->y != y))
359 _policy_border_move(bd, x, y);
361 if ((int)bd->layer != layer) e_border_layer_set(bd, layer);
365 _policy_zone_layout_quickpanel(E_Border *bd)
371 e_illume_border_min_get(bd, NULL, &mh);
373 if ((bd->w != bd->zone->w) || (bd->h != mh))
374 _policy_border_resize(bd, bd->zone->w, mh);
376 if (bd->layer != POL_QUICKPANEL_LAYER)
377 e_border_layer_set(bd, POL_QUICKPANEL_LAYER);
381 _policy_zone_layout_softkey(E_Border *bd, E_Illume_Config_Zone *cz)
385 if ((!bd) || (!cz)) return;
388 ecore_x_e_illume_softkey_geometry_set(bd->zone->black_win, 0, 0, 0, 0);
394 e_illume_border_min_get(bd, NULL, &cz->softkey.size);
396 /* if we are dragging, then skip it for now */
397 /* NB: Disabled currently until we confirm that softkey should be draggable */
398 // if (bd->client.illume.drag.drag) return;
400 if ((bd->w != w) || (bd->h != cz->softkey.size))
401 _policy_border_resize(bd, w, cz->softkey.size);
403 ny = ((bd->zone->y + bd->zone->h) - cz->softkey.size);
405 /* NB: not sure why yet, but on startup the border->y is reporting
406 * that it is already in this position...but it's actually not.
407 * So for now, just disable the ny check until this gets sorted out */
409 if ((bd->x != x) || (bd->y != ny))
410 _policy_border_move(bd, x, ny);
412 /* _border_geometry_set(bd, x, ny, nw, nh, bd, POL_CONFORMANT_LAYER); */
414 ecore_x_e_illume_softkey_geometry_set(bd->zone->black_win,
418 if (bd->layer != POL_SOFTKEY_LAYER) e_border_layer_set(bd, POL_SOFTKEY_LAYER);
423 #define MIN_HEIGHT 100
426 _policy_layout_app_check(E_Border *bd)
434 if ((bd->desk != e_desk_current_get(bd->zone)) && (!bd->sticky))
442 _policy_keyboard_restrict(E_Border *bd, int *h)
446 if (bd->client.vkbd.state > ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF)
448 e_illume_keyboard_safe_app_region_get(bd->zone, NULL, NULL, NULL, &kh);
449 kh -= bd->zone->h - *h;
450 if ((kh < *h) && (kh > MIN_HEIGHT))
456 _policy_indicator_restrict(E_Illume_Config_Zone *cz, int *y, int *h)
458 if ((cz->indicator.size) && (*y < cz->indicator.size))
460 *h -= cz->indicator.size;
461 *y = cz->indicator.size;
466 _policy_softkey_restrict(E_Illume_Config_Zone *cz, int *y, int *h)
468 if ((cz->softkey.size) && ((*y + *h) > cz->softkey.size))
469 *h -= (*y + *h) - cz->softkey.size;
473 _policy_zone_layout_keyboard(E_Border *bd, E_Illume_Config_Zone *cz)
477 if ((!bd) || (!cz) || (!bd->visible)) return;
481 e_illume_border_min_get(bd, NULL, &cz->vkbd.size);
483 ny = ((bd->zone->y + bd->zone->h) - cz->vkbd.size);
485 /* if ((bd->fullscreen) || (bd->need_fullscreen))
486 * layer = POL_FULLSCREEN_LAYER;
488 layer = POL_KEYBOARD_LAYER;
490 _border_geometry_set(bd, x, ny, w, cz->vkbd.size, layer);
494 _policy_zone_layout_home_single(E_Border *bd, E_Illume_Config_Zone *cz)
496 if ((!bd) || (!cz) || (!bd->visible)) return;
499 _policy_indicator_restrict(cz, &y, &h);
500 _border_geometry_set(bd, x, y, w, h, POL_HOME_LAYER);
504 _policy_zone_layout_fullscreen(E_Border *bd)
506 if (!_policy_layout_app_check(bd)) return;
510 _policy_keyboard_restrict(bd, &h);
512 _border_geometry_set(bd, x, y, w, h, POL_FULLSCREEN_LAYER);
516 _policy_zone_layout_app_single(E_Border *bd, E_Illume_Config_Zone *cz)
518 if (!_policy_layout_app_check(bd)) return;
522 _policy_keyboard_restrict(bd, &h);
523 _policy_indicator_restrict(cz, &y, &h);
524 _policy_softkey_restrict(cz, &y, &h);
526 _border_geometry_set(bd, x, y, w, h, POL_APP_LAYER);
530 _policy_zone_layout_app_dual_top(E_Border *bd, E_Illume_Config_Zone *cz)
534 if (!_policy_layout_app_check(bd)) return;
538 _policy_keyboard_restrict(bd, &h);
539 _policy_indicator_restrict(cz, &y, &h);
540 _policy_softkey_restrict(cz, &y, &h);
542 bd2 = e_illume_border_at_xy_get(bd->zone, x, y);
543 if ((bd2) && (bd2 != bd))
545 if ((bd->focused) && (bd->client.vkbd.state > ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF))
546 _border_geometry_set(bd2, x, h/2 + y, w, h/2, POL_APP_LAYER);
551 _border_geometry_set(bd, x, y, w, h/2, POL_APP_LAYER);
555 _policy_zone_layout_app_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz)
560 if (!_policy_layout_app_check(bd)) return;
564 e_illume_border_indicator_pos_get(bd->zone, NULL, &iy);
569 app = e_illume_border_at_xy_get(bd->zone, bd->zone->x, bd->zone->y);
570 if ((app) && (bd != app))
572 ny = (iy + cz->indicator.size);
573 nh = ((bd->zone->y + bd->zone->h) - ny - cz->softkey.size);
576 _border_geometry_set(bd, x, ny, w, nh, POL_APP_LAYER);
580 _policy_zone_layout_app_dual_left(E_Border *bd, E_Illume_Config_Zone *cz, Eina_Bool force)
585 if (!_policy_layout_app_check(bd)) return;
589 e_illume_keyboard_safe_app_region_get(bd->zone, NULL, &ky, NULL, &kh);
591 if (kh >= bd->zone->h)
592 kh = (kh - cz->indicator.size - cz->softkey.size);
594 kh = (kh - cz->indicator.size);
601 /* see if there is a border already there. if so, place at right */
602 bd2 = e_illume_border_at_xy_get(bd->zone, nx, y);
603 if ((bd2) && (bd != bd2)) nx = x + nw;
606 _border_geometry_set(bd, nx, y, nw, kh, POL_APP_LAYER);
610 _policy_zone_layout_dialog(E_Border *bd, E_Illume_Config_Zone *cz)
615 /* if (!_policy_layout_app_check(bd)) return; */
616 if ((!bd) || (!cz)) return;
617 printf("place dialog %d - %dx%d\n", bd->placed, bd->w, bd->h);
627 if (e_illume_border_is_fixed_size(bd))
641 parent = e_illume_border_parent_get(bd);
643 if ((!parent) || (cz->mode.dual == 1))
645 nx = (x + ((w - mw) / 2));
646 ny = (y + ((h - mh) / 2));
650 if (mw > parent->w) mw = parent->w;
651 if (mh > parent->h) mh = parent->h;
653 nx = (parent->x + ((parent->w - mw) / 2));
654 ny = (parent->y + ((parent->h - mh) / 2));
659 _border_geometry_set(bd, nx, ny, mw, mh, POL_DIALOG_LAYER);
660 printf("set geom %d %d\n", mw, mh);
664 _policy_zone_layout_splash(E_Border *bd, E_Illume_Config_Zone *cz)
666 _policy_zone_layout_dialog(bd, cz);
668 if (bd->layer != POL_SPLASH_LAYER) e_border_layer_set(bd, POL_SPLASH_LAYER);
672 _policy_zone_layout_conformant_single(E_Border *bd, E_Illume_Config_Zone *cz __UNUSED__)
674 if (!_policy_layout_app_check(bd)) return;
676 _border_geometry_set(bd, bd->zone->x, bd->zone->y,
677 bd->zone->w, bd->zone->h,
678 POL_CONFORMANT_LAYER);
682 typedef struct _App_Desk App_Desk;
691 static Eina_List *desks = NULL;
693 #define EINA_LIST_FIND(_list, _item, _match) \
696 EINA_LIST_FOREACH(_list, _l, _item) \
702 /* policy functions */
704 _policy_border_add(E_Border *bd)
706 // printf("Border added: %s\n", bd->client.icccm.class);
710 /* NB: this call sets an atom on the window that specifices the zone.
711 * the logic here is that any new windows created can access the zone
712 * window by a 'get' call. This is useful for elementary apps as they
713 * normally would not have access to the zone window. Typical use case
714 * is for indicator & softkey windows so that they can send messages
715 * that apply to their respective zone only. Example: softkey sends close
716 * messages (or back messages to cycle focus) that should pertain just
717 * to it's current zone */
718 ecore_x_e_illume_zone_set(bd->client.win, bd->zone->black_win);
720 if (e_illume_border_is_keyboard(bd))
723 e_hints_window_sticky_set(bd, 1);
726 if (e_illume_border_is_home(bd))
729 e_hints_window_sticky_set(bd, 1);
732 if (e_illume_border_is_indicator(bd))
735 e_hints_window_sticky_set(bd, 1);
738 if (e_illume_border_is_softkey(bd))
741 e_hints_window_sticky_set(bd, 1);
744 /* ignore stolen borders. These are typically quickpanel or keyboards */
745 if (bd->stolen) return;
747 /* if this is a fullscreen window, than we need to hide indicator window */
748 /* NB: we could use the e_illume_border_is_fullscreen function here
749 * but we save ourselves a function call this way */
750 if ((bd->fullscreen) || (bd->need_fullscreen))
754 if ((ind = e_illume_border_indicator_get(bd->zone)))
756 if (ind->visible) e_illume_border_hide(ind);
758 if ((sft = e_illume_border_softkey_get(bd->zone)))
760 if (e_illume_border_is_conformant(bd))
763 e_illume_border_hide(sft);
764 else if (!sft->visible)
765 e_illume_border_show(sft);
772 if (bd->client.icccm.class)
777 EINA_LIST_FIND(desks, d, (d->class == bd->client.icccm.class));
781 d = E_NEW(App_Desk, 1);
785 d->borders = eina_list_append(d->borders, bd);
786 e_border_desk_set(bd, d->desk);
790 /* Add this border to our focus stack if it can accept or take focus */
791 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
792 _pol_focus_stack = eina_list_append(_pol_focus_stack, bd);
794 if ((e_illume_border_is_softkey(bd)) || (e_illume_border_is_indicator(bd)))
795 _policy_zone_layout_update(bd->zone);
798 /* set focus on new border if we can */
799 _policy_border_set_focus(bd);
804 _policy_border_del(E_Border *bd)
806 // printf("Policy Border deleted: %s\n", bd->client.icccm.class);
810 /* if this is a fullscreen window, than we need to show indicator window */
811 /* NB: we could use the e_illume_border_is_fullscreen function here
812 * but we save ourselves a function call this way */
813 if ((bd->fullscreen) || (bd->need_fullscreen))
817 /* try to get the Indicator on this zone */
818 if ((ind = e_illume_border_indicator_get(bd->zone)))
820 if (!ind->visible) e_illume_border_show(ind);
822 _policy_zone_layout_update(bd->zone);
825 /* remove from focus stack */
826 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
827 _pol_focus_stack = eina_list_remove(_pol_focus_stack, bd);
829 if (e_illume_border_is_softkey(bd))
831 E_Illume_Config_Zone *cz;
833 cz = e_illume_zone_config_get(bd->zone->num);
834 cz->softkey.size = 0;
835 _policy_zone_layout_update(bd->zone);
837 else if (e_illume_border_is_indicator(bd))
839 E_Illume_Config_Zone *cz;
841 cz = e_illume_zone_config_get(bd->zone->num);
842 cz->indicator.size = 0;
843 _policy_zone_layout_update(bd->zone);
847 * _policy_border_show_below(bd);
852 _policy_border_focus_in(E_Border *bd __UNUSED__)
856 // printf("Border focus in: %s\n", bd->client.icccm.name);
857 if ((bd->fullscreen) || (bd->need_fullscreen))
859 /* try to get the Indicator on this zone */
860 if ((ind = e_illume_border_indicator_get(bd->zone)))
862 /* we have the indicator, show it if needed */
863 if (ind->visible) e_illume_border_hide(ind);
868 /* try to get the Indicator on this zone */
869 if ((ind = e_illume_border_indicator_get(bd->zone)))
871 /* we have the indicator, show it if needed */
872 if (!ind->visible) e_illume_border_show(ind);
875 _policy_zone_layout_update(bd->zone);
879 _policy_border_focus_out(E_Border *bd)
881 // printf("Border focus out: %s\n", bd->client.icccm.name);
885 /* NB: if we got this focus_out event on a deleted border, we check if
886 * it is a transient (child) of another window. If it is, then we
887 * transfer focus back to the parent window */
888 if (e_object_is_del(E_OBJECT(bd)))
890 if (e_illume_border_is_dialog(bd))
894 if ((parent = e_illume_border_parent_get(bd)))
895 _policy_border_set_focus(parent);
901 _policy_border_activate(E_Border *bd)
905 // printf("Border Activate: %s\n", bd->client.icccm.name);
909 /* NB: stolen borders may or may not need focus call...have to test */
910 if (bd->stolen) return;
912 /* conformant windows hide the softkey */
913 if ((sft = e_illume_border_softkey_get(bd->zone)))
915 if (e_illume_border_is_conformant(bd))
917 if (sft->visible) e_illume_border_hide(sft);
921 if (!sft->visible) e_illume_border_show(sft);
925 /* NB: We cannot use our set_focus function here because it does,
926 * occasionally fall through wrt E's focus policy, so cherry pick the good
927 * parts and use here :) */
928 if (bd->desk != e_desk_current_get(bd->zone))
929 e_desk_show(bd->desk);
931 /* if the border is iconified then uniconify if allowed */
932 if ((bd->iconic) && (!bd->lock_user_iconify))
933 e_border_uniconify(bd);
935 /* set very high layer for this window as it needs attention and thus
936 * should show above everything */
937 e_border_layer_set(bd, POL_ACTIVATE_LAYER);
939 /* if we can raise the border do it */
940 if (!bd->lock_user_stacking) e_border_raise(bd);
942 /* focus the border */
943 e_border_focus_set(bd, 1, 1);
945 /* NB: since we skip needless border evals when container layout
946 * is called (to save cpu cycles), we need to
947 * signal this border that it's focused so that the edj gets
950 * This is potentially useless as THIS policy
951 * makes all windows borderless anyway, but it's in here for
953 e_border_focus_latest_set(bd);
955 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
957 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
958 e_focus_event_focus_in(bd);
962 _policy_border_is_dialog(E_Border *bd)
964 if (e_illume_border_is_dialog(bd))
967 if (bd->client.e.state.centered)
972 if (bd->client.icccm.class)
974 if (!strncmp(bd->client.icccm.class, "Illume", 6))
976 if (!strncmp(bd->client.icccm.class, "e_fwin", 6))
978 if (!strncmp(bd->client.icccm.class, "every", 5))
989 _policy_border_post_fetch(E_Border *bd)
993 /* NB: for this policy we disable all remembers set on a border */
994 if (bd->remember) e_remember_del(bd->remember);
997 if (_policy_border_is_dialog(bd))
1001 else if (e_illume_border_is_fixed_size(bd))
1005 else if (!bd->borderless)
1008 bd->client.border.changed = 1;
1013 _policy_border_post_assign(E_Border *bd)
1017 bd->internal_no_remember = 1;
1019 if (_policy_border_is_dialog(bd) ||
1020 e_illume_border_is_fixed_size(bd))
1023 /* do not allow client to change these properties */
1024 bd->lock_client_size = 1;
1025 bd->lock_client_shade = 1;
1026 bd->lock_client_maximize = 1;
1027 bd->lock_client_location = 1;
1028 bd->lock_client_stacking = 1;
1030 /* do not allow the user to change these properties */
1031 /* bd->lock_user_location = 1;
1032 * bd->lock_user_size = 1;
1033 * bd->lock_user_shade = 1; */
1035 /* clear any centered states */
1036 /* NB: this is mainly needed for E's main config dialog */
1037 bd->client.e.state.centered = 0;
1039 /* lock the border type so user/client cannot change */
1040 bd->lock_border = 1;
1042 /* disable e's placement (and honoring of icccm.request_pos) */
1047 _policy_border_show(E_Border *bd)
1051 /* printf("_policy_border_show %s\n", e_border_name_get(bd)); */
1053 if (!bd->client.icccm.name) return;
1055 // printf("Border Show: %s\n", bd->client.icccm.class);
1057 /* trap for special windows so we can ignore hides below them */
1058 if (e_illume_border_is_indicator(bd)) return;
1059 if (e_illume_border_is_softkey(bd)) return;
1060 if (e_illume_border_is_quickpanel(bd)) return;
1061 if (e_illume_border_is_keyboard(bd)) return;
1063 _policy_border_hide_below(bd);
1066 /* called on E_BORDER_HOOK_CONTAINER_LAYOUT (after e_border/eval0) */
1068 _policy_zone_layout(E_Zone *zone)
1070 E_Illume_Config_Zone *cz;
1076 cz = e_illume_zone_config_get(zone->num);
1078 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1080 if (e_object_is_del(E_OBJECT(bd))) continue;
1082 if (bd->zone != zone) continue;
1084 if ((!bd->new_client) && (!bd->changes.pos) && (!bd->changes.size) &&
1085 (!bd->changes.visible) && (!bd->pending_move_resize) &&
1086 (!bd->need_shape_export) && (!bd->need_shape_merge)) continue;
1088 if (e_illume_border_is_indicator(bd))
1089 _policy_zone_layout_indicator(bd, cz);
1091 else if (e_illume_border_is_quickpanel(bd))
1092 _policy_zone_layout_quickpanel(bd);
1094 else if (e_illume_border_is_softkey(bd))
1095 _policy_zone_layout_softkey(bd, cz);
1097 else if (e_illume_border_is_keyboard(bd))
1098 _policy_zone_layout_keyboard(bd, cz);
1100 else if (e_illume_border_is_home(bd))
1101 _policy_zone_layout_home_single(bd, cz);
1103 else if ((bd->fullscreen) || (bd->need_fullscreen))
1104 _policy_zone_layout_fullscreen(bd);
1106 else if (e_illume_border_is_splash(bd))
1107 _policy_zone_layout_splash(bd, cz);
1109 else if (_policy_border_is_dialog(bd))
1110 _policy_zone_layout_dialog(bd, cz);
1112 else if (e_illume_border_is_conformant(bd))
1113 _policy_zone_layout_conformant_single(bd, cz);
1115 else if (e_illume_border_is_fixed_size(bd))
1116 _policy_zone_layout_dialog(bd, cz);
1118 else if (bd->internal && bd->client.icccm.class &&
1119 (!strcmp(bd->client.icccm.class, "everything-window")))
1121 if (bd->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_ON)
1122 _policy_zone_layout_app_single(bd, cz);
1124 * _policy_zone_layout_app_dual_left(bd, cz, EINA_TRUE); */
1125 if (bd->layer != POL_ACTIVATE_LAYER)
1126 e_border_layer_set(bd, POL_ACTIVATE_LAYER);
1128 /* if (bd->layer != POL_SPLASH_LAYER)
1129 * e_border_layer_set(bd, POL_SPLASH_LAYER); */
1131 else if (bd->client.e.state.centered)
1132 _policy_zone_layout_dialog(bd, cz);
1133 else if (!cz->mode.dual)
1134 _policy_zone_layout_app_single(bd, cz);
1137 if (cz->mode.side == 0)
1141 /* grab the indicator position so we can tell if it
1142 * is in a custom position or not (user dragged it) */
1143 e_illume_border_indicator_pos_get(bd->zone, NULL, &ty);
1144 if (ty <= bd->zone->y)
1145 _policy_zone_layout_app_dual_top(bd, cz);
1147 _policy_zone_layout_app_dual_custom(bd, cz);
1150 _policy_zone_layout_app_dual_left(bd, cz, EINA_FALSE);
1156 _policy_zone_move_resize(E_Zone *zone)
1163 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1165 if (bd->zone != zone) continue;
1167 bd->changes.pos = 1;
1173 _policy_zone_mode_change(E_Zone *zone, Ecore_X_Atom mode)
1175 E_Illume_Config_Zone *cz;
1176 /* Eina_List *homes = NULL; */
1182 cz = e_illume_zone_config_get(zone->num);
1184 if (mode == ECORE_X_ATOM_E_ILLUME_MODE_SINGLE)
1189 if (mode == ECORE_X_ATOM_E_ILLUME_MODE_DUAL_TOP)
1191 else if (mode == ECORE_X_ATOM_E_ILLUME_MODE_DUAL_LEFT)
1194 e_config_save_queue();
1196 /* lock indicator window from dragging if we need to */
1197 bd = e_illume_border_indicator_get(zone);
1200 /* only dual-top mode can drag */
1201 if ((cz->mode.dual == 1) && (cz->mode.side == 0))
1203 /* only set locked if we need to */
1204 if (bd->client.illume.drag.locked != 0)
1205 ecore_x_e_illume_drag_locked_set(bd->client.win, 0);
1209 /* only set locked if we need to */
1210 if (bd->client.illume.drag.locked != 1)
1211 ecore_x_e_illume_drag_locked_set(bd->client.win, 1);
1214 #if 0 /* split home window? wtf?! go home! */
1215 if (!(homes = e_illume_border_home_borders_get(zone))) return;
1217 count = eina_list_count(homes);
1219 /* create a new home window (if needed) for dual mode */
1220 if (cz->mode.dual == 1)
1223 ecore_x_e_illume_home_new_send(zone->black_win);
1225 else if (cz->mode.dual == 0)
1227 /* if we went to single mode, delete any extra home windows */
1232 /* try to get a home window on this zone and remove it */
1233 if ((home = e_illume_border_home_get(zone)))
1234 ecore_x_e_illume_home_del_send(home->client.win);
1239 _policy_zone_layout_update(zone);
1243 _policy_zone_close(E_Zone *zone)
1249 if (!(bd = e_border_focused_get())) return;
1251 if (bd->zone != zone) return;
1253 /* close this border */
1254 e_border_act_close_begin(bd);
1258 _policy_drag_start(E_Border *bd)
1262 if (bd->stolen) return;
1264 ecore_x_e_illume_drag_set(bd->client.win, 1);
1265 ecore_x_e_illume_drag_set(bd->zone->black_win, 1);
1269 _policy_drag_end(E_Border *bd)
1271 // printf("Drag end\n");
1275 if (bd->stolen) return;
1277 /* set property on this border to say we are done dragging */
1278 ecore_x_e_illume_drag_set(bd->client.win, 0);
1280 /* set property on zone window that a drag is finished */
1281 ecore_x_e_illume_drag_set(bd->zone->black_win, 0);
1285 _policy_focus_back(E_Zone *zone)
1287 Eina_List *l, *fl = NULL;
1291 if (eina_list_count(_pol_focus_stack) < 1) return;
1293 // printf("Focus back\n");
1295 EINA_LIST_REVERSE_FOREACH(_pol_focus_stack, l, bd)
1297 if (bd->zone != zone) continue;
1298 fl = eina_list_append(fl, bd);
1301 if (!(fbd = e_border_focused_get())) return;
1302 if (fbd->parent) return;
1304 EINA_LIST_REVERSE_FOREACH(fl, l, bd)
1306 if ((fbd) && (bd == fbd))
1310 if ((l->next) && (b = l->next->data))
1312 _policy_border_set_focus(b);
1317 /* we've reached the end of the list. Set focus to first */
1318 if ((b = eina_list_nth(fl, 0)))
1320 _policy_border_set_focus(b);
1330 _policy_focus_forward(E_Zone *zone)
1332 Eina_List *l, *fl = NULL;
1336 if (eina_list_count(_pol_focus_stack) < 1) return;
1338 // printf("Focus forward\n");
1340 EINA_LIST_FOREACH(_pol_focus_stack, l, bd)
1342 if (bd->zone != zone) continue;
1343 fl = eina_list_append(fl, bd);
1346 if (!(fbd = e_border_focused_get())) return;
1347 if (fbd->parent) return;
1349 EINA_LIST_FOREACH(fl, l, bd)
1351 if ((fbd) && (bd == fbd))
1355 if ((l->next) && (b = l->next->data))
1357 _policy_border_set_focus(b);
1362 /* we've reached the end of the list. Set focus to first */
1363 if ((b = eina_list_nth(fl, 0)))
1365 _policy_border_set_focus(b);
1375 _policy_focus_home(E_Zone *zone)
1380 if (!(bd = e_illume_border_home_get(zone))) return;
1381 _policy_border_set_focus(bd);
1385 _policy_property_change(Ecore_X_Event_Window_Property *event)
1387 if (event->atom == ECORE_X_ATOM_NET_WM_STATE)
1391 if (!(bd = e_border_find_by_client_window(event->win))) return;
1393 /* not interested in stolen or invisible borders */
1394 if ((bd->stolen) || (!bd->visible)) return;
1396 /* make sure the border has a name or class */
1397 /* NB: this check is here because some E borders get State Changes
1398 * but do not have a name/class associated with them. Not entirely sure
1399 * which ones they are, but I would guess Managers, Containers, or Zones.
1400 * At any rate, we're not interested in those types of borders */
1401 if ((!bd->client.icccm.name) || (!bd->client.icccm.class)) return;
1403 /* NB: If we have reached this point, then it should be a fullscreen
1404 * border that has toggled fullscreen on/off */
1406 /* try to get the Indicator on this zone */
1407 if (!(ind = e_illume_border_indicator_get(bd->zone))) return;
1409 /* if we are fullscreen, hide the indicator...else we show it */
1410 /* NB: we could use the e_illume_border_is_fullscreen function here
1411 * but we save ourselves a function call this way */
1412 if ((bd->fullscreen) || (bd->need_fullscreen))
1416 e_illume_border_hide(ind);
1417 _policy_zone_layout_update(bd->zone);
1424 e_illume_border_show(ind);
1425 _policy_zone_layout_update(bd->zone);
1429 else if (event->atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY)
1436 if (!(zone = e_util_zone_window_find(event->win))) return;
1438 if (!(bd = e_illume_border_indicator_get(zone))) return;
1444 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1446 if (bd->zone != zone) continue;
1447 if (!e_illume_border_is_conformant(bd)) continue;
1448 /* set indicator geometry on conformant window */
1449 /* NB: This is needed so that conformant apps get told about
1450 * the indicator size/position...else they have no way of
1451 * knowing that the geometry has been updated */
1452 ecore_x_e_illume_indicator_geometry_set(bd->client.win, x, y, w, h);
1455 else if (event->atom == ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY)
1462 if (!(zone = e_util_zone_window_find(event->win))) return;
1464 if (!(bd = e_illume_border_softkey_get(zone))) return;
1470 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1472 if (bd->zone != zone) continue;
1473 if (!e_illume_border_is_conformant(bd)) continue;
1474 /* set softkey geometry on conformant window */
1475 /* NB: This is needed so that conformant apps get told about
1476 * the softkey size/position...else they have no way of
1477 * knowing that the geometry has been updated */
1478 ecore_x_e_illume_softkey_geometry_set(bd->client.win, x, y, w, h);
1481 else if (event->atom == ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY)
1485 E_Illume_Keyboard *kbd;
1489 if (!(zone = e_util_zone_window_find(event->win))) return;
1491 if (!(kbd = e_illume_keyboard_get())) return;
1492 if (!kbd->border) return;
1498 /* adjust Y for keyboard visibility because keyboard uses fx_offset */
1500 if (kbd->border->fx.y <= 0) y = kbd->border->y;
1502 /* look for conformant borders */
1503 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1505 if (bd->zone != zone) continue;
1506 if (!e_illume_border_is_conformant(bd)) continue;
1507 /* set keyboard geometry on conformant window */
1508 /* NB: This is needed so that conformant apps get told about
1509 * the keyboard size/position...else they have no way of
1510 * knowing that the geometry has been updated */
1511 ecore_x_e_illume_keyboard_geometry_set(bd->client.win, x, y, w, h);
1514 else if (event->atom == ATM_ENLIGHTENMENT_SCALE)
1519 EINA_LIST_FOREACH(e_manager_list(), ml, man)
1524 if (event->win != man->root) continue;
1525 EINA_LIST_FOREACH(man->containers, cl, con)
1530 EINA_LIST_FOREACH(con->zones, zl, zone)
1531 _policy_zone_layout_update(zone);