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_border_show_below(E_Border *bd);
11 static void _policy_zone_layout_update(E_Zone *zone);
12 static void _policy_zone_layout_indicator(E_Border *bd, E_Illume_Config_Zone *cz);
13 static void _policy_zone_layout_quickpanel(E_Border *bd);
14 static void _policy_zone_layout_softkey(E_Border *bd, E_Illume_Config_Zone *cz);
15 static void _policy_zone_layout_keyboard(E_Border *bd, E_Illume_Config_Zone *cz);
16 static void _policy_zone_layout_home_single(E_Border *bd, E_Illume_Config_Zone *cz);
17 static void _policy_zone_layout_fullscreen(E_Border *bd);
18 static void _policy_zone_layout_app_single(E_Border *bd, E_Illume_Config_Zone *cz);
19 static void _policy_zone_layout_app_dual_top(E_Border *bd, E_Illume_Config_Zone *cz);
20 static void _policy_zone_layout_app_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz);
21 static void _policy_zone_layout_app_dual_left(E_Border *bd, E_Illume_Config_Zone *cz, Eina_Bool force);
22 static void _policy_zone_layout_dialog(E_Border *bd, E_Illume_Config_Zone *cz);
23 static void _policy_zone_layout_splash(E_Border *bd, E_Illume_Config_Zone *cz);
24 static void _policy_zone_layout_conformant_single(E_Border *bd, E_Illume_Config_Zone *cz);
26 static void _policy_zone_layout_conformant_dual_top(E_Border *bd, E_Illume_Config_Zone *cz);
27 static void _policy_zone_layout_conformant_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz);
28 static void _policy_zone_layout_conformant_dual_left(E_Border *bd, E_Illume_Config_Zone *cz);
31 static Eina_List *_pol_focus_stack;
35 _policy_border_set_focus(E_Border *bd)
38 /* printf("_policy_border_set_focus %s\n", e_border_name_get(bd)); */
40 /* if focus is locked out then get out */
41 if (bd->lock_focus_out) return;
43 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
45 /* check E's focus settings */
46 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
48 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
49 ((bd->parent->focused) &&
50 (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))))
52 /* if the border was hidden due to layout, we need to unhide */
53 if (!bd->visible) e_illume_border_show(bd);
55 if ((bd->iconic) && (!bd->lock_user_iconify))
56 e_border_uniconify(bd);
58 if (!bd->lock_user_stacking) e_border_raise(bd);
60 /* focus the border */
61 e_border_focus_set(bd, 1, 1);
62 /* e_border_raise(bd); */
63 /* hide the border below this one */
64 _policy_border_hide_below(bd);
66 /* NB: since we skip needless border evals when container layout
67 * is called (to save cpu cycles), we need to
68 * signal this border that it's focused so that the edj gets
71 * This is potentially useless as THIS policy
72 * makes all windows borderless anyway, but it's in here for
74 e_border_focus_latest_set(bd);
76 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
78 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
79 e_focus_event_focus_in(bd);
86 _policy_border_move(E_Border *bd, int x, int y)
97 _policy_border_resize(E_Border *bd, int w, int h)
103 bd->client.w = (bd->w - (bd->client_inset.l + bd->client_inset.r));
104 bd->client.h = (bd->h - (bd->client_inset.t + bd->client_inset.b));
105 bd->changes.size = 1;
110 _policy_border_hide_below(E_Border *bd)
116 // printf("Hide Borders Below: %s %d %d\n",
117 // bd->client.icccm.name, bd->x, bd->y);
120 /* printf("_policy_border_hide_below %s\n", e_border_name_get(bd)); */
121 /* determine layering position */
122 if (bd->layer <= 0) pos = 0;
123 else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1;
124 else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2;
125 else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3;
126 else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4;
129 /* Find the windows below this one */
130 for (i = pos; i >= 2; i--)
135 EINA_LIST_FOREACH(bd->zone->container->layers[i].clients, l, b)
137 /* skip if it's the same border */
138 if (b == bd) continue;
140 /* skip if it's not on this zone */
141 if (b->zone != bd->zone) continue;
143 /* skip special borders */
144 if (e_illume_border_is_indicator(b)) continue;
145 if (e_illume_border_is_softkey(b)) continue;
146 if (e_illume_border_is_keyboard(b)) continue;
147 if (e_illume_border_is_quickpanel(b)) continue;
148 if (e_illume_border_is_home(b)) continue;
150 if ((bd->fullscreen) || (bd->need_fullscreen))
152 if (b->visible) e_illume_border_hide(b);
156 /* we need to check x/y position */
157 if (E_CONTAINS(bd->x, bd->y, bd->w, bd->h,
158 b->x, b->y, b->w, b->h))
160 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);
248 _policy_zone_layout_update(E_Zone *zone)
255 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
257 /* skip borders not on this zone */
258 if (bd->zone != zone) continue;
260 /* skip special windows */
261 if (e_illume_border_is_keyboard(bd)) continue;
262 if (e_illume_border_is_quickpanel(bd)) continue;
264 /* signal a changed pos here so layout gets updated */
271 _policy_zone_layout_indicator(E_Border *bd, E_Illume_Config_Zone *cz)
273 if ((!bd) || (!cz)) return;
275 /* grab minimum indicator size */
276 e_illume_border_min_get(bd, NULL, &cz->indicator.size);
278 /* no point in doing anything here if indicator is hidden */
279 if ((!bd->new_client) && (!bd->visible))
281 ecore_x_e_illume_indicator_geometry_set(bd->zone->black_win,
286 /* if we are dragging, then skip it for now */
287 if (bd->client.illume.drag.drag)
289 /* when dragging indicator, we need to trigger a layout update */
290 ecore_x_e_illume_indicator_geometry_set(bd->zone->black_win,
292 _policy_zone_layout_update(bd->zone);
296 // printf("\tLayout Indicator: %d\n", bd->zone->id);
298 /* lock indicator window from dragging if we need to */
299 if ((cz->mode.dual == 1) && (cz->mode.side == 0))
300 ecore_x_e_illume_drag_locked_set(bd->client.win, 0);
302 ecore_x_e_illume_drag_locked_set(bd->client.win, 1);
304 if ((bd->w != bd->zone->w) || (bd->h != cz->indicator.size))
305 _policy_border_resize(bd, bd->zone->w, cz->indicator.size);
309 /* move to 0, 0 (relative to zone) if needed */
310 if ((bd->x != bd->zone->x) || (bd->y != bd->zone->y))
312 _policy_border_move(bd, bd->zone->x, bd->zone->y);
313 ecore_x_e_illume_quickpanel_position_update_send(bd->client.win);
318 if (cz->mode.side == 0)
320 /* top mode...indicator is draggable so just set X.
321 * in this case, the indicator itself should be responsible for
322 * sending the quickpanel position update message when it is
323 * finished dragging */
324 if (bd->x != bd->zone->x)
325 _policy_border_move(bd, bd->zone->x, bd->y);
329 /* move to 0, 0 (relative to zone) if needed */
330 if ((bd->x != bd->zone->x) || (bd->y != bd->zone->y))
332 _policy_border_move(bd, bd->zone->x, bd->zone->y);
333 ecore_x_e_illume_quickpanel_position_update_send(bd->client.win);
337 ecore_x_e_illume_indicator_geometry_set(bd->zone->black_win,
341 if (bd->layer != POL_INDICATOR_LAYER)
342 e_border_layer_set(bd, POL_INDICATOR_LAYER);
345 #define ZONE_GEOMETRY \
347 e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h); \
352 _border_geometry_set(E_Border *bd, int x, int y, int w, int h, int layer)
354 if ((bd->w != w) || (bd->h != h))
355 _policy_border_resize(bd, w, h);
357 if ((bd->x != x) || (bd->y != y))
358 _policy_border_move(bd, x, y);
360 if ((int)bd->layer != layer) e_border_layer_set(bd, layer);
364 _policy_zone_layout_quickpanel(E_Border *bd)
370 e_illume_border_min_get(bd, NULL, &mh);
372 if ((bd->w != bd->zone->w) || (bd->h != mh))
373 _policy_border_resize(bd, bd->zone->w, mh);
375 if (bd->layer != POL_QUICKPANEL_LAYER)
376 e_border_layer_set(bd, POL_QUICKPANEL_LAYER);
380 _policy_zone_layout_softkey(E_Border *bd, E_Illume_Config_Zone *cz)
384 if ((!bd) || (!cz)) return;
387 ecore_x_e_illume_softkey_geometry_set(bd->zone->black_win, 0, 0, 0, 0);
393 e_illume_border_min_get(bd, NULL, &cz->softkey.size);
395 /* if we are dragging, then skip it for now */
396 /* NB: Disabled currently until we confirm that softkey should be draggable */
397 // if (bd->client.illume.drag.drag) return;
399 if ((bd->w != w) || (bd->h != cz->softkey.size))
400 _policy_border_resize(bd, w, cz->softkey.size);
402 ny = ((bd->zone->y + bd->zone->h) - cz->softkey.size);
404 /* NB: not sure why yet, but on startup the border->y is reporting
405 * that it is already in this position...but it's actually not.
406 * So for now, just disable the ny check until this gets sorted out */
408 if ((bd->x != x) || (bd->y != ny))
409 _policy_border_move(bd, x, ny);
411 /* _border_geometry_set(bd, x, ny, nw, nh, bd, POL_CONFORMANT_LAYER); */
413 ecore_x_e_illume_softkey_geometry_set(bd->zone->black_win,
417 if (bd->layer != POL_SOFTKEY_LAYER) e_border_layer_set(bd, POL_SOFTKEY_LAYER);
422 #define MIN_HEIGHT 100
425 _policy_layout_app_check(E_Border *bd)
433 if ((bd->desk != e_desk_current_get(bd->zone)) && (!bd->sticky))
441 _policy_keyboard_restrict(E_Border *bd, int *h)
445 if (bd->client.vkbd.state > ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF)
447 e_illume_keyboard_safe_app_region_get(bd->zone, NULL, NULL, NULL, &kh);
448 kh -= bd->zone->h - *h;
449 if ((kh < *h) && (kh > MIN_HEIGHT))
455 _policy_indicator_restrict(E_Illume_Config_Zone *cz, int *y, int *h)
457 if ((cz->indicator.size) && (*y < cz->indicator.size))
459 *h -= cz->indicator.size;
460 *y = cz->indicator.size;
465 _policy_softkey_restrict(E_Illume_Config_Zone *cz, int *y, int *h)
467 if ((cz->softkey.size) && ((*y + *h) > cz->softkey.size))
468 *h -= (*y + *h) - cz->softkey.size;
472 _policy_zone_layout_keyboard(E_Border *bd, E_Illume_Config_Zone *cz)
476 if ((!bd) || (!cz) || (!bd->visible)) return;
480 e_illume_border_min_get(bd, NULL, &cz->vkbd.size);
482 ny = ((bd->zone->y + bd->zone->h) - cz->vkbd.size);
484 /* if ((bd->fullscreen) || (bd->need_fullscreen))
485 * layer = POL_FULLSCREEN_LAYER;
487 layer = POL_KEYBOARD_LAYER;
489 _border_geometry_set(bd, x, ny, w, cz->vkbd.size, layer);
493 _policy_zone_layout_home_single(E_Border *bd, E_Illume_Config_Zone *cz)
495 if ((!bd) || (!cz) || (!bd->visible)) return;
498 _policy_indicator_restrict(cz, &y, &h);
499 _border_geometry_set(bd, x, y, w, h, POL_HOME_LAYER);
503 _policy_zone_layout_fullscreen(E_Border *bd)
505 if (!_policy_layout_app_check(bd)) return;
509 _policy_keyboard_restrict(bd, &h);
511 _border_geometry_set(bd, x, y, w, h, POL_FULLSCREEN_LAYER);
515 _policy_zone_layout_app_single(E_Border *bd, E_Illume_Config_Zone *cz)
517 if (!_policy_layout_app_check(bd)) return;
521 _policy_keyboard_restrict(bd, &h);
522 _policy_indicator_restrict(cz, &y, &h);
523 _policy_softkey_restrict(cz, &y, &h);
525 _border_geometry_set(bd, x, y, w, h, POL_APP_LAYER);
529 _policy_zone_layout_app_dual_top(E_Border *bd, E_Illume_Config_Zone *cz)
533 if (!_policy_layout_app_check(bd)) return;
537 _policy_keyboard_restrict(bd, &h);
538 _policy_indicator_restrict(cz, &y, &h);
539 _policy_softkey_restrict(cz, &y, &h);
541 bd2 = e_illume_border_at_xy_get(bd->zone, x, y);
542 if ((bd2) && (bd2 != bd))
544 if ((bd->focused) && (bd->client.vkbd.state > ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF))
545 _border_geometry_set(bd2, x, h/2 + y, w, h/2, POL_APP_LAYER);
550 _border_geometry_set(bd, x, y, w, h/2, POL_APP_LAYER);
554 _policy_zone_layout_app_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz)
559 if (!_policy_layout_app_check(bd)) return;
563 e_illume_border_indicator_pos_get(bd->zone, NULL, &iy);
568 app = e_illume_border_at_xy_get(bd->zone, bd->zone->x, bd->zone->y);
569 if ((app) && (bd != app))
571 ny = (iy + cz->indicator.size);
572 nh = ((bd->zone->y + bd->zone->h) - ny - cz->softkey.size);
575 _border_geometry_set(bd, x, ny, w, nh, POL_APP_LAYER);
579 _policy_zone_layout_app_dual_left(E_Border *bd, E_Illume_Config_Zone *cz, Eina_Bool force)
584 if (!_policy_layout_app_check(bd)) return;
588 e_illume_keyboard_safe_app_region_get(bd->zone, NULL, &ky, NULL, &kh);
590 if (kh >= bd->zone->h)
591 kh = (kh - cz->indicator.size - cz->softkey.size);
593 kh = (kh - cz->indicator.size);
600 /* see if there is a border already there. if so, place at right */
601 bd2 = e_illume_border_at_xy_get(bd->zone, nx, y);
602 if ((bd2) && (bd != bd2)) nx = x + nw;
605 _border_geometry_set(bd, nx, y, nw, kh, POL_APP_LAYER);
609 _policy_zone_layout_dialog(E_Border *bd, E_Illume_Config_Zone *cz)
614 /* if (!_policy_layout_app_check(bd)) return; */
615 if ((!bd) || (!cz)) return;
616 printf("place dialog %d - %dx%d\n", bd->placed, bd->w, bd->h);
626 if (e_illume_border_is_fixed_size(bd))
640 parent = e_illume_border_parent_get(bd);
642 if ((!parent) || (cz->mode.dual == 1))
644 nx = (x + ((w - mw) / 2));
645 ny = (y + ((h - mh) / 2));
649 if (mw > parent->w) mw = parent->w;
650 if (mh > parent->h) mh = parent->h;
652 nx = (parent->x + ((parent->w - mw) / 2));
653 ny = (parent->y + ((parent->h - mh) / 2));
658 _border_geometry_set(bd, nx, ny, mw, mh, POL_DIALOG_LAYER);
659 printf("set geom %d %d\n", mw, mh);
663 _policy_zone_layout_splash(E_Border *bd, E_Illume_Config_Zone *cz)
665 _policy_zone_layout_dialog(bd, cz);
667 if (bd->layer != POL_SPLASH_LAYER) e_border_layer_set(bd, POL_SPLASH_LAYER);
671 _policy_zone_layout_conformant_single(E_Border *bd, E_Illume_Config_Zone *cz __UNUSED__)
673 if (!_policy_layout_app_check(bd)) return;
675 _border_geometry_set(bd, bd->zone->x, bd->zone->y,
676 bd->zone->w, bd->zone->h,
677 POL_CONFORMANT_LAYER);
681 typedef struct _App_Desk App_Desk;
690 static Eina_List *desks = NULL;
692 #define EINA_LIST_FIND(_list, _item, _match) \
695 EINA_LIST_FOREACH(_list, _l, _item) \
701 /* policy functions */
703 _policy_border_add(E_Border *bd)
705 // printf("Border added: %s\n", bd->client.icccm.class);
709 /* NB: this call sets an atom on the window that specifices the zone.
710 * the logic here is that any new windows created can access the zone
711 * window by a 'get' call. This is useful for elementary apps as they
712 * normally would not have access to the zone window. Typical use case
713 * is for indicator & softkey windows so that they can send messages
714 * that apply to their respective zone only. Example: softkey sends close
715 * messages (or back messages to cycle focus) that should pertain just
716 * to it's current zone */
717 ecore_x_e_illume_zone_set(bd->client.win, bd->zone->black_win);
719 if (e_illume_border_is_keyboard(bd))
722 e_hints_window_sticky_set(bd, 1);
725 if (e_illume_border_is_home(bd))
728 e_hints_window_sticky_set(bd, 1);
731 if (e_illume_border_is_indicator(bd))
734 e_hints_window_sticky_set(bd, 1);
737 if (e_illume_border_is_softkey(bd))
740 e_hints_window_sticky_set(bd, 1);
743 /* ignore stolen borders. These are typically quickpanel or keyboards */
744 if (bd->stolen) return;
746 /* if this is a fullscreen window, than we need to hide indicator window */
747 /* NB: we could use the e_illume_border_is_fullscreen function here
748 * but we save ourselves a function call this way */
749 if ((bd->fullscreen) || (bd->need_fullscreen))
753 if ((ind = e_illume_border_indicator_get(bd->zone)))
755 if (ind->visible) e_illume_border_hide(ind);
757 if ((sft = e_illume_border_softkey_get(bd->zone)))
759 if (e_illume_border_is_conformant(bd))
762 e_illume_border_hide(sft);
763 else if (!sft->visible)
764 e_illume_border_show(sft);
771 if (bd->client.icccm.class)
776 EINA_LIST_FIND(desks, d, (d->class == bd->client.icccm.class));
780 d = E_NEW(App_Desk, 1);
784 d->borders = eina_list_append(d->borders, bd);
785 e_border_desk_set(bd, d->desk);
789 /* Add this border to our focus stack if it can accept or take focus */
790 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
791 _pol_focus_stack = eina_list_append(_pol_focus_stack, bd);
793 if ((e_illume_border_is_softkey(bd)) || (e_illume_border_is_indicator(bd)))
794 _policy_zone_layout_update(bd->zone);
797 /* set focus on new border if we can */
798 _policy_border_set_focus(bd);
803 _policy_border_del(E_Border *bd)
805 // printf("Policy Border deleted: %s\n", bd->client.icccm.class);
809 /* if this is a fullscreen window, than we need to show indicator window */
810 /* NB: we could use the e_illume_border_is_fullscreen function here
811 * but we save ourselves a function call this way */
812 if ((bd->fullscreen) || (bd->need_fullscreen))
816 /* try to get the Indicator on this zone */
817 if ((ind = e_illume_border_indicator_get(bd->zone)))
819 if (!ind->visible) e_illume_border_show(ind);
821 _policy_zone_layout_update(bd->zone);
824 /* remove from focus stack */
825 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
826 _pol_focus_stack = eina_list_remove(_pol_focus_stack, bd);
828 if (e_illume_border_is_softkey(bd))
830 E_Illume_Config_Zone *cz;
832 cz = e_illume_zone_config_get(bd->zone->id);
833 cz->softkey.size = 0;
834 _policy_zone_layout_update(bd->zone);
836 else if (e_illume_border_is_indicator(bd))
838 E_Illume_Config_Zone *cz;
840 cz = e_illume_zone_config_get(bd->zone->id);
841 cz->indicator.size = 0;
842 _policy_zone_layout_update(bd->zone);
846 * _policy_border_show_below(bd);
851 _policy_border_focus_in(E_Border *bd __UNUSED__)
855 // printf("Border focus in: %s\n", bd->client.icccm.name);
856 if ((bd->fullscreen) || (bd->need_fullscreen))
858 /* try to get the Indicator on this zone */
859 if ((ind = e_illume_border_indicator_get(bd->zone)))
861 /* we have the indicator, show it if needed */
862 if (ind->visible) e_illume_border_hide(ind);
867 /* try to get the Indicator on this zone */
868 if ((ind = e_illume_border_indicator_get(bd->zone)))
870 /* we have the indicator, show it if needed */
871 if (!ind->visible) e_illume_border_show(ind);
874 _policy_zone_layout_update(bd->zone);
878 _policy_border_focus_out(E_Border *bd)
880 // printf("Border focus out: %s\n", bd->client.icccm.name);
884 /* NB: if we got this focus_out event on a deleted border, we check if
885 * it is a transient (child) of another window. If it is, then we
886 * transfer focus back to the parent window */
887 if (e_object_is_del(E_OBJECT(bd)))
889 if (e_illume_border_is_dialog(bd))
893 if ((parent = e_illume_border_parent_get(bd)))
894 _policy_border_set_focus(parent);
900 _policy_border_activate(E_Border *bd)
904 // printf("Border Activate: %s\n", bd->client.icccm.name);
908 /* NB: stolen borders may or may not need focus call...have to test */
909 if (bd->stolen) return;
911 /* conformant windows hide the softkey */
912 if ((sft = e_illume_border_softkey_get(bd->zone)))
914 if (e_illume_border_is_conformant(bd))
916 if (sft->visible) e_illume_border_hide(sft);
920 if (!sft->visible) e_illume_border_show(sft);
924 /* NB: We cannot use our set_focus function here because it does,
925 * occasionally fall through wrt E's focus policy, so cherry pick the good
926 * parts and use here :) */
927 if (bd->desk != e_desk_current_get(bd->zone))
928 e_desk_show(bd->desk);
930 /* if the border is iconified then uniconify if allowed */
931 if ((bd->iconic) && (!bd->lock_user_iconify))
932 e_border_uniconify(bd);
934 /* set very high layer for this window as it needs attention and thus
935 * should show above everything */
936 e_border_layer_set(bd, POL_ACTIVATE_LAYER);
938 /* if we can raise the border do it */
939 if (!bd->lock_user_stacking) e_border_raise(bd);
941 /* focus the border */
942 e_border_focus_set(bd, 1, 1);
944 /* NB: since we skip needless border evals when container layout
945 * is called (to save cpu cycles), we need to
946 * signal this border that it's focused so that the edj gets
949 * This is potentially useless as THIS policy
950 * makes all windows borderless anyway, but it's in here for
952 e_border_focus_latest_set(bd);
954 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
956 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
957 e_focus_event_focus_in(bd);
961 _policy_border_is_dialog(E_Border *bd)
963 if (e_illume_border_is_dialog(bd))
966 if (bd->client.e.state.centered)
971 if (bd->client.icccm.class)
973 if (!strncmp(bd->client.icccm.class, "Illume", 6))
975 if (!strncmp(bd->client.icccm.class, "e_fwin", 6))
977 if (!strncmp(bd->client.icccm.class, "every", 5))
988 _policy_border_post_fetch(E_Border *bd)
992 /* NB: for this policy we disable all remembers set on a border */
993 if (bd->remember) e_remember_del(bd->remember);
996 if (_policy_border_is_dialog(bd))
1000 else if (e_illume_border_is_fixed_size(bd))
1004 else if (!bd->borderless)
1007 bd->client.border.changed = 1;
1012 _policy_border_post_assign(E_Border *bd)
1016 bd->internal_no_remember = 1;
1018 if (_policy_border_is_dialog(bd) ||
1019 e_illume_border_is_fixed_size(bd))
1022 /* do not allow client to change these properties */
1023 bd->lock_client_size = 1;
1024 bd->lock_client_shade = 1;
1025 bd->lock_client_maximize = 1;
1026 bd->lock_client_location = 1;
1027 bd->lock_client_stacking = 1;
1029 /* do not allow the user to change these properties */
1030 /* bd->lock_user_location = 1;
1031 * bd->lock_user_size = 1;
1032 * bd->lock_user_shade = 1; */
1034 /* clear any centered states */
1035 /* NB: this is mainly needed for E's main config dialog */
1036 bd->client.e.state.centered = 0;
1038 /* lock the border type so user/client cannot change */
1039 bd->lock_border = 1;
1041 /* disable e's placement (and honoring of icccm.request_pos) */
1046 _policy_border_show(E_Border *bd)
1050 /* printf("_policy_border_show %s\n", e_border_name_get(bd)); */
1052 if (!bd->client.icccm.name) return;
1054 // printf("Border Show: %s\n", bd->client.icccm.class);
1056 /* trap for special windows so we can ignore hides below them */
1057 if (e_illume_border_is_indicator(bd)) return;
1058 if (e_illume_border_is_softkey(bd)) return;
1059 if (e_illume_border_is_quickpanel(bd)) return;
1060 if (e_illume_border_is_keyboard(bd)) return;
1062 _policy_border_hide_below(bd);
1065 /* called on E_BORDER_HOOK_CONTAINER_LAYOUT (after e_border/eval0) */
1067 _policy_zone_layout(E_Zone *zone)
1069 E_Illume_Config_Zone *cz;
1075 cz = e_illume_zone_config_get(zone->id);
1077 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1079 if (e_object_is_del(E_OBJECT(bd))) continue;
1081 if (bd->zone != zone) continue;
1083 if ((!bd->new_client) && (!bd->changes.pos) && (!bd->changes.size) &&
1084 (!bd->changes.visible) && (!bd->pending_move_resize) &&
1085 (!bd->need_shape_export) && (!bd->need_shape_merge)) continue;
1087 if (e_illume_border_is_indicator(bd))
1088 _policy_zone_layout_indicator(bd, cz);
1090 else if (e_illume_border_is_quickpanel(bd))
1091 _policy_zone_layout_quickpanel(bd);
1093 else if (e_illume_border_is_softkey(bd))
1094 _policy_zone_layout_softkey(bd, cz);
1096 else if (e_illume_border_is_keyboard(bd))
1097 _policy_zone_layout_keyboard(bd, cz);
1099 else if (e_illume_border_is_home(bd))
1100 _policy_zone_layout_home_single(bd, cz);
1102 else if ((bd->fullscreen) || (bd->need_fullscreen))
1103 _policy_zone_layout_fullscreen(bd);
1105 else if (e_illume_border_is_splash(bd))
1106 _policy_zone_layout_splash(bd, cz);
1108 else if (_policy_border_is_dialog(bd))
1109 _policy_zone_layout_dialog(bd, cz);
1111 else if (e_illume_border_is_conformant(bd))
1112 _policy_zone_layout_conformant_single(bd, cz);
1114 else if (e_illume_border_is_fixed_size(bd))
1115 _policy_zone_layout_dialog(bd, cz);
1117 else if (bd->internal && bd->client.icccm.class &&
1118 (!strcmp(bd->client.icccm.class, "everything-window")))
1120 if (bd->client.vkbd.state == ECORE_X_VIRTUAL_KEYBOARD_STATE_ON)
1121 _policy_zone_layout_app_single(bd, cz);
1123 * _policy_zone_layout_app_dual_left(bd, cz, EINA_TRUE); */
1124 if (bd->layer != POL_ACTIVATE_LAYER)
1125 e_border_layer_set(bd, POL_ACTIVATE_LAYER);
1127 /* if (bd->layer != POL_SPLASH_LAYER)
1128 * e_border_layer_set(bd, POL_SPLASH_LAYER); */
1130 else if (bd->client.e.state.centered)
1131 _policy_zone_layout_dialog(bd, cz);
1132 else if (!cz->mode.dual)
1133 _policy_zone_layout_app_single(bd, cz);
1136 if (cz->mode.side == 0)
1140 /* grab the indicator position so we can tell if it
1141 * is in a custom position or not (user dragged it) */
1142 e_illume_border_indicator_pos_get(bd->zone, NULL, &ty);
1143 if (ty <= bd->zone->y)
1144 _policy_zone_layout_app_dual_top(bd, cz);
1146 _policy_zone_layout_app_dual_custom(bd, cz);
1149 _policy_zone_layout_app_dual_left(bd, cz, EINA_FALSE);
1155 _policy_zone_move_resize(E_Zone *zone)
1162 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1164 if (bd->zone != zone) continue;
1166 bd->changes.pos = 1;
1172 _policy_zone_mode_change(E_Zone *zone, Ecore_X_Atom mode)
1174 E_Illume_Config_Zone *cz;
1175 /* Eina_List *homes = NULL; */
1181 cz = e_illume_zone_config_get(zone->id);
1183 if (mode == ECORE_X_ATOM_E_ILLUME_MODE_SINGLE)
1188 if (mode == ECORE_X_ATOM_E_ILLUME_MODE_DUAL_TOP)
1190 else if (mode == ECORE_X_ATOM_E_ILLUME_MODE_DUAL_LEFT)
1193 e_config_save_queue();
1195 /* lock indicator window from dragging if we need to */
1196 bd = e_illume_border_indicator_get(zone);
1199 /* only dual-top mode can drag */
1200 if ((cz->mode.dual == 1) && (cz->mode.side == 0))
1202 /* only set locked if we need to */
1203 if (bd->client.illume.drag.locked != 0)
1204 ecore_x_e_illume_drag_locked_set(bd->client.win, 0);
1208 /* only set locked if we need to */
1209 if (bd->client.illume.drag.locked != 1)
1210 ecore_x_e_illume_drag_locked_set(bd->client.win, 1);
1213 #if 0 /* split home window? wtf?! go home! */
1214 if (!(homes = e_illume_border_home_borders_get(zone))) return;
1216 count = eina_list_count(homes);
1218 /* create a new home window (if needed) for dual mode */
1219 if (cz->mode.dual == 1)
1222 ecore_x_e_illume_home_new_send(zone->black_win);
1224 else if (cz->mode.dual == 0)
1226 /* if we went to single mode, delete any extra home windows */
1231 /* try to get a home window on this zone and remove it */
1232 if ((home = e_illume_border_home_get(zone)))
1233 ecore_x_e_illume_home_del_send(home->client.win);
1238 _policy_zone_layout_update(zone);
1242 _policy_zone_close(E_Zone *zone)
1248 if (!(bd = e_border_focused_get())) return;
1250 if (bd->zone != zone) return;
1252 /* close this border */
1253 e_border_act_close_begin(bd);
1257 _policy_drag_start(E_Border *bd)
1261 if (bd->stolen) return;
1263 ecore_x_e_illume_drag_set(bd->client.win, 1);
1264 ecore_x_e_illume_drag_set(bd->zone->black_win, 1);
1268 _policy_drag_end(E_Border *bd)
1270 // printf("Drag end\n");
1274 if (bd->stolen) return;
1276 /* set property on this border to say we are done dragging */
1277 ecore_x_e_illume_drag_set(bd->client.win, 0);
1279 /* set property on zone window that a drag is finished */
1280 ecore_x_e_illume_drag_set(bd->zone->black_win, 0);
1284 _policy_focus_back(E_Zone *zone)
1286 Eina_List *l, *fl = NULL;
1290 if (eina_list_count(_pol_focus_stack) < 1) return;
1292 // printf("Focus back\n");
1294 EINA_LIST_REVERSE_FOREACH(_pol_focus_stack, l, bd)
1296 if (bd->zone != zone) continue;
1297 fl = eina_list_append(fl, bd);
1300 if (!(fbd = e_border_focused_get())) return;
1301 if (fbd->parent) return;
1303 EINA_LIST_REVERSE_FOREACH(fl, l, bd)
1305 if ((fbd) && (bd == fbd))
1309 if ((l->next) && (b = l->next->data))
1311 _policy_border_set_focus(b);
1316 /* we've reached the end of the list. Set focus to first */
1317 if ((b = eina_list_nth(fl, 0)))
1319 _policy_border_set_focus(b);
1329 _policy_focus_forward(E_Zone *zone)
1331 Eina_List *l, *fl = NULL;
1335 if (eina_list_count(_pol_focus_stack) < 1) return;
1337 // printf("Focus forward\n");
1339 EINA_LIST_FOREACH(_pol_focus_stack, l, bd)
1341 if (bd->zone != zone) continue;
1342 fl = eina_list_append(fl, bd);
1345 if (!(fbd = e_border_focused_get())) return;
1346 if (fbd->parent) return;
1348 EINA_LIST_FOREACH(fl, l, bd)
1350 if ((fbd) && (bd == fbd))
1354 if ((l->next) && (b = l->next->data))
1356 _policy_border_set_focus(b);
1361 /* we've reached the end of the list. Set focus to first */
1362 if ((b = eina_list_nth(fl, 0)))
1364 _policy_border_set_focus(b);
1374 _policy_focus_home(E_Zone *zone)
1379 if (!(bd = e_illume_border_home_get(zone))) return;
1380 _policy_border_set_focus(bd);
1384 _policy_property_change(Ecore_X_Event_Window_Property *event)
1386 if (event->atom == ECORE_X_ATOM_NET_WM_STATE)
1390 if (!(bd = e_border_find_by_client_window(event->win))) return;
1392 /* not interested in stolen or invisible borders */
1393 if ((bd->stolen) || (!bd->visible)) return;
1395 /* make sure the border has a name or class */
1396 /* NB: this check is here because some E borders get State Changes
1397 * but do not have a name/class associated with them. Not entirely sure
1398 * which ones they are, but I would guess Managers, Containers, or Zones.
1399 * At any rate, we're not interested in those types of borders */
1400 if ((!bd->client.icccm.name) || (!bd->client.icccm.class)) return;
1402 /* NB: If we have reached this point, then it should be a fullscreen
1403 * border that has toggled fullscreen on/off */
1405 /* try to get the Indicator on this zone */
1406 if (!(ind = e_illume_border_indicator_get(bd->zone))) return;
1408 /* if we are fullscreen, hide the indicator...else we show it */
1409 /* NB: we could use the e_illume_border_is_fullscreen function here
1410 * but we save ourselves a function call this way */
1411 if ((bd->fullscreen) || (bd->need_fullscreen))
1415 e_illume_border_hide(ind);
1416 _policy_zone_layout_update(bd->zone);
1423 e_illume_border_show(ind);
1424 _policy_zone_layout_update(bd->zone);
1428 else if (event->atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY)
1435 if (!(zone = e_util_zone_window_find(event->win))) return;
1437 if (!(bd = e_illume_border_indicator_get(zone))) return;
1443 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1445 if (bd->zone != zone) continue;
1446 if (!e_illume_border_is_conformant(bd)) continue;
1447 /* set indicator geometry on conformant window */
1448 /* NB: This is needed so that conformant apps get told about
1449 * the indicator size/position...else they have no way of
1450 * knowing that the geometry has been updated */
1451 ecore_x_e_illume_indicator_geometry_set(bd->client.win, x, y, w, h);
1454 else if (event->atom == ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY)
1461 if (!(zone = e_util_zone_window_find(event->win))) return;
1463 if (!(bd = e_illume_border_softkey_get(zone))) return;
1469 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1471 if (bd->zone != zone) continue;
1472 if (!e_illume_border_is_conformant(bd)) continue;
1473 /* set softkey geometry on conformant window */
1474 /* NB: This is needed so that conformant apps get told about
1475 * the softkey size/position...else they have no way of
1476 * knowing that the geometry has been updated */
1477 ecore_x_e_illume_softkey_geometry_set(bd->client.win, x, y, w, h);
1480 else if (event->atom == ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY)
1484 E_Illume_Keyboard *kbd;
1488 if (!(zone = e_util_zone_window_find(event->win))) return;
1490 if (!(kbd = e_illume_keyboard_get())) return;
1491 if (!kbd->border) return;
1497 /* adjust Y for keyboard visibility because keyboard uses fx_offset */
1499 if (kbd->border->fx.y <= 0) y = kbd->border->y;
1501 /* look for conformant borders */
1502 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1504 if (bd->zone != zone) continue;
1505 if (!e_illume_border_is_conformant(bd)) continue;
1506 /* set keyboard geometry on conformant window */
1507 /* NB: This is needed so that conformant apps get told about
1508 * the keyboard size/position...else they have no way of
1509 * knowing that the geometry has been updated */
1510 ecore_x_e_illume_keyboard_geometry_set(bd->client.win, x, y, w, h);
1513 else if (event->atom == ATM_ENLIGHTENMENT_SCALE)
1518 EINA_LIST_FOREACH(e_manager_list(), ml, man)
1523 if (event->win != man->root) continue;
1524 EINA_LIST_FOREACH(man->containers, cl, con)
1529 EINA_LIST_FOREACH(con->zones, zl, zone)
1530 _policy_zone_layout_update(zone);