4 /* NB: DIALOG_USES_PIXEL_BORDER is an experiment in setting dialog windows
5 * to use the 'pixel' type border. This is done because some dialogs,
6 * when shown, blend into other windows too much. Pixel border adds a
7 * little distinction between the dialog window and an app window.
8 * Disable if this is not wanted */
9 #define DIALOG_USES_PIXEL_BORDER 1
11 /* local function prototypes */
12 static void _policy_border_set_focus(E_Border *bd);
13 static void _policy_border_move(E_Border *bd, int x, int y);
14 static void _policy_border_resize(E_Border *bd, int w, int h);
15 static void _policy_border_hide_below(E_Border *bd);
16 static void _policy_border_show_below(E_Border *bd);
17 static void _policy_zone_layout_update(E_Zone *zone);
18 static void _policy_zone_layout_indicator(E_Border *bd, E_Illume_Config_Zone *cz);
19 static void _policy_zone_layout_quickpanel(E_Border *bd);
20 static void _policy_zone_layout_softkey(E_Border *bd, E_Illume_Config_Zone *cz);
21 static void _policy_zone_layout_keyboard(E_Border *bd, E_Illume_Config_Zone *cz);
22 static void _policy_zone_layout_home_single(E_Border *bd, E_Illume_Config_Zone *cz);
23 static void _policy_zone_layout_home_dual_top(E_Border *bd, E_Illume_Config_Zone *cz);
24 static void _policy_zone_layout_home_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz);
25 static void _policy_zone_layout_home_dual_left(E_Border *bd, E_Illume_Config_Zone *cz);
26 static void _policy_zone_layout_fullscreen(E_Border *bd);
27 static void _policy_zone_layout_app_single(E_Border *bd, E_Illume_Config_Zone *cz);
28 static void _policy_zone_layout_app_dual_top(E_Border *bd, E_Illume_Config_Zone *cz);
29 static void _policy_zone_layout_app_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz);
30 static void _policy_zone_layout_app_dual_left(E_Border *bd, E_Illume_Config_Zone *cz);
31 static void _policy_zone_layout_dialog(E_Border *bd, E_Illume_Config_Zone *cz);
32 static void _policy_zone_layout_splash(E_Border *bd, E_Illume_Config_Zone *cz);
33 static void _policy_zone_layout_conformant_single(E_Border *bd, E_Illume_Config_Zone *cz);
34 static void _policy_zone_layout_conformant_dual_top(E_Border *bd, E_Illume_Config_Zone *cz);
35 static void _policy_zone_layout_conformant_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz);
36 static void _policy_zone_layout_conformant_dual_left(E_Border *bd, E_Illume_Config_Zone *cz);
38 static Eina_List *_pol_focus_stack;
42 _policy_border_set_focus(E_Border *bd)
46 /* if focus is locked out then get out */
47 if (bd->lock_focus_out) return;
49 /* make sure the border can accept or take focus */
50 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
52 /* check E's focus settings */
53 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
55 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
56 ((bd->parent->focused) &&
57 (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))))
59 /* if the border was hidden due to layout, we need to unhide */
60 if (!bd->visible) e_illume_border_show(bd);
62 if ((bd->iconic) && (!bd->lock_user_iconify))
63 e_border_uniconify(bd);
65 if (!bd->lock_user_stacking) e_border_raise(bd);
67 /* focus the border */
68 e_border_focus_set(bd, 1, 1);
70 /* hide the border below this one */
71 _policy_border_hide_below(bd);
73 /* NB: since we skip needless border evals when container layout
74 * is called (to save cpu cycles), we need to
75 * signal this border that it's focused so that the edj gets
78 * This is potentially useless as THIS policy
79 * makes all windows borderless anyway, but it's in here for
81 e_border_focus_latest_set(bd);
83 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
85 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
86 e_focus_event_focus_in(bd);
93 _policy_border_move(E_Border *bd, int x, int y)
97 /* NB: Qt uses a weird window type called 'VCLSalFrame' that needs to
98 * have bd->placed set else it doesn't position correctly...
99 * this could be a result of E honoring the icccm request position,
102 /* NB: Seems something similar happens with elementary windows also
103 * so for now just set bd->placed on all windows until this
104 * gets investigated */
113 _policy_border_resize(E_Border *bd, int w, int h)
119 bd->client.w = (bd->w - (bd->client_inset.l + bd->client_inset.r));
120 bd->client.h = (bd->h - (bd->client_inset.t + bd->client_inset.b));
121 bd->changes.size = 1;
126 _policy_border_hide_below(E_Border *bd)
130 // printf("Hide Borders Below: %s %d %d\n",
131 // bd->client.icccm.name, bd->x, bd->y);
135 /* determine layering position */
136 if (bd->layer <= 0) pos = 0;
137 else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1;
138 else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2;
139 else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3;
140 else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4;
143 /* Find the windows below this one */
144 for (i = pos; i >= 2; i--)
149 EINA_LIST_FOREACH(bd->zone->container->layers[i].clients, l, b)
151 /* skip if it's the same border */
152 if (b == bd) continue;
154 /* skip if it's not on this zone */
155 if (b->zone != bd->zone) continue;
157 /* skip special borders */
158 if (e_illume_border_is_indicator(b)) continue;
159 if (e_illume_border_is_softkey(b)) continue;
160 if (e_illume_border_is_keyboard(b)) continue;
161 if (e_illume_border_is_quickpanel(b)) continue;
162 if (e_illume_border_is_home(b)) continue;
164 if ((bd->fullscreen) || (bd->need_fullscreen))
166 if (b->visible) e_illume_border_hide(b);
170 /* we need to check x/y position */
171 if (E_CONTAINS(bd->x, bd->y, bd->w, bd->h,
172 b->x, b->y, b->w, b->h))
174 if (b->visible) e_illume_border_hide(b);
182 _policy_border_show_below(E_Border *bd)
188 // printf("Show Borders Below: %s %d %d\n",
189 // bd->client.icccm.class, bd->x, bd->y);
193 if (bd->client.icccm.transient_for)
195 if ((prev = e_border_find_by_client_window(bd->client.icccm.transient_for)))
197 _policy_border_set_focus(prev);
202 /* determine layering position */
203 if (bd->layer <= 0) pos = 0;
204 else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1;
205 else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2;
206 else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3;
207 else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4;
210 /* Find the windows below this one */
211 for (i = pos; i >= 2; i--)
215 EINA_LIST_REVERSE_FOREACH(bd->zone->container->layers[i].clients, l, b)
217 /* skip if it's the same border */
218 if (b == bd) continue;
220 /* skip if it's not on this zone */
221 if (b->zone != bd->zone) continue;
223 /* skip special borders */
224 if (e_illume_border_is_indicator(b)) continue;
225 if (e_illume_border_is_softkey(b)) continue;
226 if (e_illume_border_is_keyboard(b)) continue;
227 if (e_illume_border_is_quickpanel(b)) continue;
228 if (e_illume_border_is_home(b)) continue;
230 if ((bd->fullscreen) || (bd->need_fullscreen))
232 _policy_border_set_focus(b);
237 /* need to check x/y position */
238 if (E_CONTAINS(bd->x, bd->y, bd->w, bd->h,
239 b->x, b->y, b->w, b->h))
241 _policy_border_set_focus(b);
248 /* if we reach here, then there is a problem with showing a window below
249 * this one, so show previous window in stack */
250 EINA_LIST_REVERSE_FOREACH(_pol_focus_stack, l, prev)
252 if (prev->zone != bd->zone) continue;
253 _policy_border_set_focus(prev);
257 /* Fallback to focusing home if all above fails */
258 _policy_focus_home(bd->zone);
262 _policy_zone_layout_update(E_Zone *zone)
269 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
271 /* skip borders not on this zone */
272 if (bd->zone != zone) continue;
274 /* skip special windows */
275 if (e_illume_border_is_keyboard(bd)) continue;
276 if (e_illume_border_is_quickpanel(bd)) continue;
278 /* signal a changed pos here so layout gets updated */
285 _policy_zone_layout_indicator(E_Border *bd, E_Illume_Config_Zone *cz)
287 if ((!bd) || (!cz)) return;
289 /* grab minimum indicator size */
290 e_illume_border_min_get(bd, NULL, &cz->indicator.size);
292 /* no point in doing anything here if indicator is hidden */
293 if ((!bd->new_client) && (!bd->visible))
295 ecore_x_e_illume_indicator_geometry_set(bd->zone->black_win,
300 /* if we are dragging, then skip it for now */
301 if (bd->client.illume.drag.drag)
303 /* when dragging indicator, we need to trigger a layout update */
304 ecore_x_e_illume_indicator_geometry_set(bd->zone->black_win,
306 _policy_zone_layout_update(bd->zone);
310 // printf("\tLayout Indicator: %d\n", bd->zone->id);
312 /* lock indicator window from dragging if we need to */
313 if ((cz->mode.dual == 1) && (cz->mode.side == 0))
314 ecore_x_e_illume_drag_locked_set(bd->client.win, 0);
316 ecore_x_e_illume_drag_locked_set(bd->client.win, 1);
318 /* make sure it's the required width & height */
319 if ((bd->w != bd->zone->w) || (bd->h != cz->indicator.size))
320 _policy_border_resize(bd, bd->zone->w, cz->indicator.size);
322 /* are we in single mode ? */
325 /* move to 0, 0 (relative to zone) if needed */
326 if ((bd->x != bd->zone->x) || (bd->y != bd->zone->y))
328 _policy_border_move(bd, bd->zone->x, bd->zone->y);
329 ecore_x_e_illume_quickpanel_position_update_send(bd->client.win);
334 /* dual app mode top */
335 if (cz->mode.side == 0)
337 /* top mode...indicator is draggable so just set X.
338 * in this case, the indicator itself should be responsible for
339 * sending the quickpanel position update message when it is
340 * finished dragging */
341 if (bd->x != bd->zone->x)
342 _policy_border_move(bd, bd->zone->x, bd->y);
346 /* move to 0, 0 (relative to zone) if needed */
347 if ((bd->x != bd->zone->x) || (bd->y != bd->zone->y))
349 _policy_border_move(bd, bd->zone->x, bd->zone->y);
350 ecore_x_e_illume_quickpanel_position_update_send(bd->client.win);
354 ecore_x_e_illume_indicator_geometry_set(bd->zone->black_win,
358 /* set layer if needed */
359 if (bd->layer != POL_INDICATOR_LAYER)
360 e_border_layer_set(bd, POL_INDICATOR_LAYER);
364 _policy_zone_layout_quickpanel(E_Border *bd)
370 /* grab minimum size */
371 e_illume_border_min_get(bd, NULL, &mh);
373 /* resize if needed */
374 if ((bd->w != bd->zone->w) || (bd->h != mh))
375 _policy_border_resize(bd, bd->zone->w, mh);
377 /* set layer if needed */
378 if (bd->layer != POL_QUICKPANEL_LAYER)
379 e_border_layer_set(bd, POL_QUICKPANEL_LAYER);
383 _policy_zone_layout_softkey(E_Border *bd, E_Illume_Config_Zone *cz)
389 /* grab minimum softkey size */
390 e_illume_border_min_get(bd, NULL, &cz->softkey.size);
392 /* no point in doing anything here if softkey is hidden */
395 ecore_x_e_illume_softkey_geometry_set(bd->zone->black_win,
400 /* if we are dragging, then skip it for now */
401 /* NB: Disabled currently until we confirm that softkey should be draggable */
402 // if (bd->client.illume.drag.drag) return;
404 /* make sure it's the required width & height */
405 if ((bd->w != bd->zone->w) || (bd->h != cz->softkey.size))
406 _policy_border_resize(bd, bd->zone->w, cz->softkey.size);
408 /* make sure it's in the correct position */
409 ny = ((bd->zone->y + bd->zone->h) - cz->softkey.size);
411 /* NB: not sure why yet, but on startup the border->y is reporting
412 * that it is already in this position...but it's actually not.
413 * So for now, just disable the ny check until this gets sorted out */
414 // if ((bd->x != bd->zone->x) || (bd->y != ny))
415 _policy_border_move(bd, bd->zone->x, ny);
416 // set property for apps to find out they are
417 ecore_x_e_illume_softkey_geometry_set(bd->zone->black_win,
421 /* set layer if needed */
422 if (bd->layer != POL_SOFTKEY_LAYER)
423 e_border_layer_set(bd, POL_SOFTKEY_LAYER);
427 _policy_zone_layout_keyboard(E_Border *bd, E_Illume_Config_Zone *cz)
431 // printf("\tLayout Keyboard\n");
433 if ((!bd) || (!cz)) return;
435 /* no point in adjusting size or position if it's not visible */
436 if (!bd->visible) return;
438 /* grab minimum keyboard size */
439 e_illume_border_min_get(bd, NULL, &cz->vkbd.size);
441 /* make sure it's the required width & height */
442 if ((bd->w != bd->zone->w) || (bd->h != cz->vkbd.size))
443 _policy_border_resize(bd, bd->zone->w, cz->vkbd.size);
445 /* make sure it's in the correct position */
446 ny = ((bd->zone->y + bd->zone->h) - cz->vkbd.size);
447 if ((bd->x != bd->zone->x) || (bd->y != ny))
448 _policy_border_move(bd, bd->zone->x, ny);
450 /* check layer according to fullscreen state */
451 if ((bd->fullscreen) || (bd->need_fullscreen))
452 layer = POL_FULLSCREEN_LAYER;
454 layer = POL_KEYBOARD_LAYER;
456 /* set layer if needed */
457 if ((int)bd->layer != layer) e_border_layer_set(bd, layer);
461 _policy_zone_layout_home_single(E_Border *bd, E_Illume_Config_Zone *cz)
463 int ny, nh, indsz = 0, sftsz = 0;
466 if ((!bd) || (!cz)) return;
468 /* no point in adjusting size or position if it's not visible */
469 if (!bd->visible) return;
471 printf("\tLayout Home Single: %s\n", bd->client.icccm.class);
473 indsz = cz->indicator.size;
474 sftsz = cz->softkey.size;
475 if ((ind = e_illume_border_indicator_get(bd->zone)))
477 if (!ind->visible) indsz = 0;
479 if ((sft = e_illume_border_softkey_get(bd->zone)))
481 if (!sft->visible) sftsz = 0;
483 /* make sure it's the required width & height */
484 if (e_illume_border_is_conformant(bd)) nh = bd->zone->h;
485 else nh = (bd->zone->h - indsz - sftsz);
487 if ((bd->w != bd->zone->w) || (bd->h != nh))
488 _policy_border_resize(bd, bd->zone->w, nh);
490 /* move to correct position (relative to zone) if needed */
491 if (e_illume_border_is_conformant(bd)) ny = bd->zone->y;
492 else ny = (bd->zone->y + indsz);
493 if ((bd->x != bd->zone->x) || (bd->y != ny))
494 _policy_border_move(bd, bd->zone->x, ny);
496 /* set layer if needed */
497 if (bd->layer != POL_HOME_LAYER) e_border_layer_set(bd, POL_HOME_LAYER);
501 _policy_zone_layout_home_dual_top(E_Border *bd, E_Illume_Config_Zone *cz)
503 E_Border *home, *ind, *sft;
504 int ny, nh, indsz = 0, sftsz = 0;
506 if ((!bd) || (!cz)) return;
508 /* no point in adjusting size or position if it's not visible */
509 if (!bd->visible) return;
511 indsz = cz->indicator.size;
512 sftsz = cz->softkey.size;
513 if ((ind = e_illume_border_indicator_get(bd->zone)))
515 if (!ind->visible) indsz = 0;
517 if ((sft = e_illume_border_softkey_get(bd->zone)))
519 if (!sft->visible) sftsz = 0;
521 /* set some defaults */
522 ny = (bd->zone->y + indsz);
523 nh = ((bd->zone->h - indsz - sftsz) / 2);
525 /* see if there are any other home windows */
526 home = e_illume_border_home_get(bd->zone);
529 if (bd != home) ny = (home->y + nh);
532 /* make sure it's the required width & height */
533 if ((bd->w != bd->zone->w) || (bd->h != nh))
534 _policy_border_resize(bd, bd->zone->w, nh);
536 /* move to correct position (relative to zone) if needed */
537 if ((bd->x != bd->zone->x) || (bd->y != ny))
538 _policy_border_move(bd, bd->zone->x, ny);
540 /* set layer if needed */
541 if (bd->layer != POL_HOME_LAYER) e_border_layer_set(bd, POL_HOME_LAYER);
545 _policy_zone_layout_home_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz)
550 // printf("\tLayout Home Dual Custom: %s\n", bd->client.icccm.class);
552 if ((!bd) || (!cz)) return;
554 /* no point in adjusting size or position if it's not visible */
555 if (!bd->visible) return;
557 /* grab indicator position */
558 e_illume_border_indicator_pos_get(bd->zone, NULL, &iy);
560 /* set some defaults */
564 /* see if there are any other home windows */
565 home = e_illume_border_home_get(bd->zone);
566 if ((home) && (bd != home))
568 ny = (iy + cz->indicator.size);
569 nh = ((bd->zone->y + bd->zone->h) - ny - cz->softkey.size);
572 /* make sure it's the required width & height */
573 if ((bd->w != bd->zone->w) || (bd->h != nh))
574 _policy_border_resize(bd, bd->zone->w, nh);
576 /* move to correct position (relative to zone) if needed */
577 if ((bd->x != bd->zone->x) || (bd->y != ny))
578 _policy_border_move(bd, bd->zone->x, ny);
580 /* set layer if needed */
581 if (bd->layer != POL_HOME_LAYER) e_border_layer_set(bd, POL_HOME_LAYER);
585 _policy_zone_layout_home_dual_left(E_Border *bd, E_Illume_Config_Zone *cz)
590 // printf("\tLayout Home Dual Left: %s\n", bd->client.icccm.class);
592 if ((!bd) || (!cz)) return;
594 /* no point in adjusting size or position if it's not visible */
595 if (!bd->visible) return;
597 nh = (bd->zone->h - cz->indicator.size - cz->softkey.size);
599 /* set some defaults */
601 nw = (bd->zone->w / 2);
603 /* see if there are any other home windows */
604 home = e_illume_border_home_get(bd->zone);
605 if ((home) && (bd != home)) nx = (home->x + nw);
607 /* make sure it's the required width & height */
608 if ((bd->w != nw) || (bd->h != nh))
609 _policy_border_resize(bd, nw, nh);
611 /* move to correct position (relative to zone) if needed */
612 if ((bd->x != nx) || (bd->y != (bd->zone->y + cz->indicator.size)))
613 _policy_border_move(bd, nx, (bd->zone->y + cz->indicator.size));
615 /* set layer if needed */
616 if (bd->layer != POL_HOME_LAYER) e_border_layer_set(bd, POL_HOME_LAYER);
620 _policy_zone_layout_fullscreen(E_Border *bd)
624 printf("\tLayout Fullscreen: %s\n", bd->client.icccm.name);
628 /* grab keyboard safe region */
629 e_illume_keyboard_safe_app_region_get(bd->zone, NULL, NULL, NULL, &kh);
631 /* make sure it's the required width & height */
632 if ((bd->w != bd->zone->w) || (bd->h != kh))
633 _policy_border_resize(bd, bd->zone->w, kh);
635 /* set layer if needed */
636 if (bd->layer != POL_FULLSCREEN_LAYER)
637 e_border_layer_set(bd, POL_FULLSCREEN_LAYER);
641 _policy_zone_layout_app_single(E_Border *bd, E_Illume_Config_Zone *cz)
645 if ((!bd) || (!cz)) return;
646 if ((!bd->new_client) && (!bd->visible)) return;
648 // printf("\tLayout App Single: %s\n", bd->client.icccm.name);
650 /* grab keyboard safe region */
651 e_illume_keyboard_safe_app_region_get(bd->zone, NULL, &ky, NULL, &kh);
653 /* make sure it's the required width & height */
654 if (kh >= bd->zone->h)
655 nh = (kh - cz->indicator.size - cz->softkey.size);
657 nh = (kh - cz->indicator.size);
659 /* resize if needed */
660 if ((bd->w != bd->zone->w) || (bd->h != nh))
661 _policy_border_resize(bd, bd->zone->w, nh);
663 /* move to correct position (relative to zone) if needed */
664 ny = (bd->zone->y + cz->indicator.size);
665 if ((bd->x != bd->zone->x) || (bd->y != ny))
666 _policy_border_move(bd, bd->zone->x, ny);
668 /* set layer if needed */
669 if (bd->layer != POL_APP_LAYER) e_border_layer_set(bd, POL_APP_LAYER);
673 _policy_zone_layout_app_dual_top(E_Border *bd, E_Illume_Config_Zone *cz)
678 // printf("\tLayout App Dual Top: %s\n", bd->client.icccm.name);
680 if ((!bd) || (!cz)) return;
681 if ((!bd->new_client) && (!bd->visible)) return;
683 /* set a default Y position */
684 ny = (bd->zone->y + cz->indicator.size);
687 (bd->client.vkbd.state > ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF))
689 /* grab keyboard safe region */
690 e_illume_keyboard_safe_app_region_get(bd->zone, NULL, NULL, NULL, &kh);
691 nh = (kh - cz->indicator.size);
695 /* make sure it's the required width & height */
696 nh = ((bd->zone->h - cz->indicator.size - cz->softkey.size) / 2);
699 /* see if there is a border already there. if so, check placement based on
700 * virtual keyboard usage */
701 b = e_illume_border_at_xy_get(bd->zone, bd->zone->x, ny);
702 if ((b) && (b != bd))
704 /* does this border need keyboard ? */
706 (bd->client.vkbd.state > ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF))
710 /* move existing border to bottom if needed */
711 h = ((bd->zone->h - cz->indicator.size - cz->softkey.size) / 2);
712 if ((b->x != b->zone->x) || (b->y != (ny + h)))
713 _policy_border_move(b, b->zone->x, (ny + h));
715 /* resize existing border if needed */
716 if ((b->w != b->zone->w) || (b->h != h))
717 _policy_border_resize(b, b->zone->w, h);
723 /* resize if needed */
724 if ((bd->w != bd->zone->w) || (bd->h != nh))
725 _policy_border_resize(bd, bd->zone->w, nh);
727 /* move to correct position (relative to zone) if needed */
728 if ((bd->x != bd->zone->x) || (bd->y != ny))
729 _policy_border_move(bd, bd->zone->x, ny);
731 /* set layer if needed */
732 if (bd->layer != POL_APP_LAYER) e_border_layer_set(bd, POL_APP_LAYER);
736 _policy_zone_layout_app_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz)
741 // printf("\tLayout App Dual Custom: %s\n", bd->client.icccm.class);
743 if ((!bd) || (!cz)) return;
744 if ((!bd->new_client) && (!bd->visible)) return;
746 /* grab indicator position */
747 e_illume_border_indicator_pos_get(bd->zone, NULL, &iy);
749 /* set a default position */
753 app = e_illume_border_at_xy_get(bd->zone, bd->zone->x, bd->zone->y);
754 if ((app) && (bd != app))
756 ny = (iy + cz->indicator.size);
757 nh = ((bd->zone->y + bd->zone->h) - ny - cz->softkey.size);
760 /* make sure it's the required width & height */
761 if ((bd->w != bd->zone->w) || (bd->h != nh))
762 _policy_border_resize(bd, bd->zone->w, nh);
764 /* move to correct position (relative to zone) if needed */
765 if ((bd->x != bd->zone->x) || (bd->y != ny))
766 _policy_border_move(bd, bd->zone->x, ny);
768 /* set layer if needed */
769 if (bd->layer != POL_APP_LAYER) e_border_layer_set(bd, POL_APP_LAYER);
773 _policy_zone_layout_app_dual_left(E_Border *bd, E_Illume_Config_Zone *cz)
778 // printf("\tLayout App Dual Left: %s\n", bd->client.icccm.name);
780 if ((!bd) || (!cz)) return;
781 if ((!bd->new_client) && (!bd->visible)) return;
783 /* grab keyboard safe region */
784 e_illume_keyboard_safe_app_region_get(bd->zone, NULL, &ky, NULL, &kh);
786 if (kh >= bd->zone->h)
787 kh = (kh - cz->indicator.size - cz->softkey.size);
789 kh = (kh - cz->indicator.size);
791 /* set some defaults */
793 nw = (bd->zone->w / 2);
795 /* see if there is a border already there. if so, place at right */
796 b = e_illume_border_at_xy_get(bd->zone, nx, (ky + cz->indicator.size));
797 if ((b) && (bd != b)) nx = b->x + nw;
799 /* resize if needed */
800 if ((bd->w != nw) || (bd->h != kh))
801 _policy_border_resize(bd, nw, kh);
803 /* move to correct position (relative to zone) if needed */
804 if ((bd->x != nx) || (bd->y != (ky + cz->indicator.size)))
805 _policy_border_move(bd, nx, (ky + cz->indicator.size));
807 /* set layer if needed */
808 if (bd->layer != POL_APP_LAYER) e_border_layer_set(bd, POL_APP_LAYER);
812 _policy_zone_layout_dialog(E_Border *bd, E_Illume_Config_Zone *cz)
817 // printf("\tLayout Dialog: %s\n", bd->client.icccm.name);
819 /* NB: This policy ignores any ICCCM requested positions and centers the
820 * dialog on it's parent (if it exists) or on the zone */
822 if ((!bd) || (!cz)) return;
827 /* make sure it fits in this zone */
828 if (mw > bd->zone->w) mw = bd->zone->w;
829 if (mh > bd->zone->h) mh = bd->zone->h;
831 /* try to get this dialog's parent if it exists */
832 parent = e_illume_border_parent_get(bd);
834 /* if we have no parent, or we are in dual mode, then center on zone */
835 /* NB: we check dual mode because if we are in dual mode, dialogs tend to
836 * be too small to be useful when positioned on the parent, so center
837 * on zone. We could check their size first here tho */
838 if ((!parent) || (cz->mode.dual == 1))
840 /* no parent or dual mode, center on screen */
841 nx = (bd->zone->x + ((bd->zone->w - mw) / 2));
842 ny = (bd->zone->y + ((bd->zone->h - mh) / 2));
846 /* NB: there is an assumption here that the parent has already been
847 * laid out on screen. This could be bad. Needs Testing */
849 /* make sure we are not larger than the parent window */
850 if (mw > parent->w) mw = parent->w;
851 if (mh > parent->h) mh = parent->h;
853 /* center on parent */
854 nx = (parent->x + ((parent->w - mw) / 2));
855 ny = (parent->y + ((parent->h - mh) / 2));
858 /* make sure it's the required width & height */
859 if ((bd->w != mw) || (bd->h != mh))
860 _policy_border_resize(bd, mw, mh);
862 /* make sure it's in the correct position */
863 if ((bd->x != nx) || (bd->y != ny))
864 _policy_border_move(bd, nx, ny);
866 /* set layer if needed */
867 if (bd->layer != POL_DIALOG_LAYER)
868 e_border_layer_set(bd, POL_DIALOG_LAYER);
872 _policy_zone_layout_splash(E_Border *bd, E_Illume_Config_Zone *cz)
874 E_Border *parent = NULL;
877 /* NB: This code is almost exactly the same as the dialog layout code
878 * (_policy_zone_layout_dialog) except for setting a different layer */
880 // printf("\tLayout Splash: %s\n", bd->client.icccm.name);
882 /* NB: This policy ignores any ICCCM requested positions and centers the
883 * splash screen on it's parent (if it exists) or on the zone */
885 if ((!bd) || (!cz)) return;
887 /* no point in adjusting size or position if it's not visible */
888 if (!bd->visible) return;
890 /* grab minimum size */
891 e_illume_border_min_get(bd, &mw, &mh);
893 /* make sure it fits in this zone */
894 if (mw > bd->zone->w) mw = bd->zone->w;
895 if (mh > bd->zone->h) mh = bd->zone->h;
897 /* if we have no parent, or we are in dual mode, then center on zone */
898 /* NB: we check dual mode because if we are in dual mode, dialogs tend to
899 * be too small to be useful when positioned on the parent,
900 * so center on zone instead */
901 if ((!parent) || (cz->mode.dual == 1))
903 /* no parent or in dual mode, center on screen */
904 nx = (bd->zone->x + ((bd->zone->w - mw) / 2));
905 ny = (bd->zone->y + ((bd->zone->h - mh) / 2));
909 /* NB: there is an assumption here that the parent has already been
910 * laid out on screen. This could be bad. Needs Testing */
912 /* make sure we are not larger than the parent window */
913 if (mw > parent->w) mw = parent->w;
914 if (mh > parent->h) mh = parent->h;
916 /* center on parent */
917 nx = (parent->x + ((parent->w - mw) / 2));
918 ny = (parent->y + ((parent->h - mh) / 2));
921 /* make sure it's the required width & height */
922 if ((bd->w != mw) || (bd->h != mh))
923 _policy_border_resize(bd, mw, mh);
925 /* make sure it's in the correct position */
926 if ((bd->x != nx) || (bd->y != ny))
927 _policy_border_move(bd, nx, ny);
929 /* set layer if needed */
930 if (bd->layer != POL_SPLASH_LAYER) e_border_layer_set(bd, POL_SPLASH_LAYER);
934 _policy_zone_layout_conformant_single(E_Border *bd, E_Illume_Config_Zone *cz)
936 if ((!bd) || (!cz)) return;
937 if ((!bd->new_client) && (!bd->visible)) return;
939 /* make sure it's the required width & height */
940 if ((bd->w != bd->zone->w) || (bd->h != bd->zone->h))
941 _policy_border_resize(bd, bd->zone->w, bd->zone->h);
943 /* move to correct position (relative to zone) if needed */
944 if ((bd->x != bd->zone->x) || (bd->y != bd->zone->y))
945 _policy_border_move(bd, bd->zone->x, bd->zone->y);
947 /* set layer if needed */
948 if (bd->layer != POL_CONFORMANT_LAYER)
949 e_border_layer_set(bd, POL_CONFORMANT_LAYER);
953 _policy_zone_layout_conformant_dual_top(E_Border *bd, E_Illume_Config_Zone *cz)
957 /* according to the docs I have, conformant windows are always on the
958 * bottom in dual-top mode */
959 if ((!bd) || (!cz)) return;
960 if ((!bd->new_client) && (!bd->visible)) return;
962 /* set some defaults */
963 nh = ((bd->zone->h - cz->indicator.size - cz->softkey.size) / 2);
964 ny = (bd->zone->y + cz->indicator.size) + nh;
965 nh += cz->softkey.size;
967 /* make sure it's the required width & height */
968 if ((bd->w != bd->zone->w) || (bd->h != nh))
969 _policy_border_resize(bd, bd->zone->w, nh);
971 /* move to correct position (relative to zone) if needed */
972 if ((bd->x != bd->zone->x) || (bd->y != ny))
973 _policy_border_move(bd, bd->zone->x, ny);
975 /* set layer if needed */
976 if (bd->layer != POL_CONFORMANT_LAYER)
977 e_border_layer_set(bd, POL_CONFORMANT_LAYER);
981 _policy_zone_layout_conformant_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz)
985 // printf("\tLayout Conformant Dual Custom: %s\n", bd->client.icccm.class);
987 if ((!bd) || (!cz)) return;
988 if ((!bd->new_client) && (!bd->visible)) return;
990 /* grab indicator position */
991 e_illume_border_indicator_pos_get(bd->zone, NULL, &iy);
993 /* set some defaults */
994 nh = ((bd->zone->y + bd->zone->h) - iy);
996 /* make sure it's the required width & height */
997 if ((bd->w != bd->zone->w) || (bd->h != nh))
998 _policy_border_resize(bd, bd->zone->w, nh);
1000 /* move to correct position (relative to zone) if needed */
1001 if ((bd->x != bd->zone->x) || (bd->y != iy))
1002 _policy_border_move(bd, bd->zone->x, iy);
1004 /* set layer if needed */
1005 if (bd->layer != POL_CONFORMANT_LAYER)
1006 e_border_layer_set(bd, POL_CONFORMANT_LAYER);
1010 _policy_zone_layout_conformant_dual_left(E_Border *bd, E_Illume_Config_Zone *cz)
1014 /* according to the docs I have, conformant windows are always on the
1015 * left in dual-left mode */
1016 if ((!bd) || (!cz)) return;
1017 if ((!bd->new_client) && (!bd->visible)) return;
1019 /* set some defaults */
1020 nw = (bd->zone->w / 2);
1023 /* make sure it's the required width & height */
1024 if ((bd->w != nw) || (bd->h != bd->zone->h))
1025 _policy_border_resize(bd, nw, bd->zone->h);
1027 /* move to correct position (relative to zone) if needed */
1028 if ((bd->x != nx) || (bd->y != bd->zone->y))
1029 _policy_border_move(bd, nx, bd->zone->y);
1031 /* set layer if needed */
1032 if (bd->layer != POL_CONFORMANT_LAYER)
1033 e_border_layer_set(bd, POL_CONFORMANT_LAYER);
1037 /* policy functions */
1039 _policy_border_add(E_Border *bd)
1041 // printf("Border added: %s\n", bd->client.icccm.class);
1045 /* NB: this call sets an atom on the window that specifices the zone.
1046 * the logic here is that any new windows created can access the zone
1047 * window by a 'get' call. This is useful for elementary apps as they
1048 * normally would not have access to the zone window. Typical use case
1049 * is for indicator & softkey windows so that they can send messages
1050 * that apply to their respective zone only. Example: softkey sends close
1051 * messages (or back messages to cycle focus) that should pertain just
1052 * to it's current zone */
1053 ecore_x_e_illume_zone_set(bd->client.win, bd->zone->black_win);
1055 /* ignore stolen borders. These are typically quickpanel or keyboards */
1056 if (bd->stolen) return;
1058 /* if this is a fullscreen window, than we need to hide indicator window */
1059 /* NB: we could use the e_illume_border_is_fullscreen function here
1060 * but we save ourselves a function call this way */
1061 if ((bd->fullscreen) || (bd->need_fullscreen))
1063 E_Border *ind, *sft;
1065 /* try to get the Indicator on this zone */
1066 if ((ind = e_illume_border_indicator_get(bd->zone)))
1068 /* we have the indicator, hide it if needed */
1069 if (ind->visible) e_illume_border_hide(ind);
1071 /* conformant - may not need softkey */
1072 if ((sft = e_illume_border_softkey_get(bd->zone)))
1074 if (e_illume_border_is_conformant(bd))
1076 if (sft->visible) e_illume_border_hide(sft);
1080 if (!sft->visible) e_illume_border_show(sft);
1085 /* Add this border to our focus stack if it can accept or take focus */
1086 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
1087 _pol_focus_stack = eina_list_append(_pol_focus_stack, bd);
1089 if ((e_illume_border_is_softkey(bd)) || (e_illume_border_is_indicator(bd)))
1090 _policy_zone_layout_update(bd->zone);
1093 /* set focus on new border if we can */
1094 _policy_border_set_focus(bd);
1099 _policy_border_del(E_Border *bd)
1101 // printf("Border deleted: %s\n", bd->client.icccm.class);
1105 /* if this is a fullscreen window, than we need to show indicator window */
1106 /* NB: we could use the e_illume_border_is_fullscreen function here
1107 * but we save ourselves a function call this way */
1108 if ((bd->fullscreen) || (bd->need_fullscreen))
1112 /* try to get the Indicator on this zone */
1113 if ((ind = e_illume_border_indicator_get(bd->zone)))
1115 /* we have the indicator, show it if needed */
1116 if (!ind->visible) e_illume_border_show(ind);
1118 _policy_zone_layout_update(bd->zone);
1121 /* remove from our focus stack */
1122 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
1123 _pol_focus_stack = eina_list_remove(_pol_focus_stack, bd);
1125 if (e_illume_border_is_softkey(bd))
1127 E_Illume_Config_Zone *cz;
1129 /* get the config for this zone */
1130 cz = e_illume_zone_config_get(bd->zone->id);
1131 cz->softkey.size = 0;
1132 _policy_zone_layout_update(bd->zone);
1134 else if (e_illume_border_is_indicator(bd))
1136 E_Illume_Config_Zone *cz;
1138 /* get the config for this zone */
1139 cz = e_illume_zone_config_get(bd->zone->id);
1140 cz->indicator.size = 0;
1141 _policy_zone_layout_update(bd->zone);
1145 /* show the border below this one */
1146 _policy_border_show_below(bd);
1151 _policy_border_focus_in(E_Border *bd __UNUSED__)
1155 // printf("Border focus in: %s\n", bd->client.icccm.name);
1156 if ((bd->fullscreen) || (bd->need_fullscreen))
1158 /* try to get the Indicator on this zone */
1159 if ((ind = e_illume_border_indicator_get(bd->zone)))
1161 /* we have the indicator, show it if needed */
1162 if (ind->visible) e_illume_border_hide(ind);
1167 /* try to get the Indicator on this zone */
1168 if ((ind = e_illume_border_indicator_get(bd->zone)))
1170 /* we have the indicator, show it if needed */
1171 if (!ind->visible) e_illume_border_show(ind);
1174 _policy_zone_layout_update(bd->zone);
1178 _policy_border_focus_out(E_Border *bd)
1180 // printf("Border focus out: %s\n", bd->client.icccm.name);
1184 /* NB: if we got this focus_out event on a deleted border, we check if
1185 * it is a transient (child) of another window. If it is, then we
1186 * transfer focus back to the parent window */
1187 if (e_object_is_del(E_OBJECT(bd)))
1189 if (e_illume_border_is_dialog(bd))
1193 if ((parent = e_illume_border_parent_get(bd)))
1194 _policy_border_set_focus(parent);
1200 _policy_border_activate(E_Border *bd)
1204 // printf("Border Activate: %s\n", bd->client.icccm.name);
1208 /* NB: stolen borders may or may not need focus call...have to test */
1209 if (bd->stolen) return;
1211 /* conformant windows hide the softkey */
1212 if ((sft = e_illume_border_softkey_get(bd->zone)))
1214 if (e_illume_border_is_conformant(bd))
1216 if (sft->visible) e_illume_border_hide(sft);
1220 if (!sft->visible) e_illume_border_show(sft);
1224 /* NB: We cannot use our set_focus function here because it does,
1225 * occasionally fall through wrt E's focus policy, so cherry pick the good
1226 * parts and use here :) */
1228 /* if the border is iconified then uniconify if allowed */
1229 if ((bd->iconic) && (!bd->lock_user_iconify))
1230 e_border_uniconify(bd);
1232 /* set very high layer for this window as it needs attention and thus
1233 * should show above everything */
1234 e_border_layer_set(bd, POL_ACTIVATE_LAYER);
1236 /* if we can raise the border do it */
1237 if (!bd->lock_user_stacking) e_border_raise(bd);
1239 /* focus the border */
1240 e_border_focus_set(bd, 1, 1);
1242 /* NB: since we skip needless border evals when container layout
1243 * is called (to save cpu cycles), we need to
1244 * signal this border that it's focused so that the edj gets
1247 * This is potentially useless as THIS policy
1248 * makes all windows borderless anyway, but it's in here for
1250 e_border_focus_latest_set(bd);
1252 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
1253 if (bd->icon_object)
1254 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
1255 e_focus_event_focus_in(bd);
1260 _policy_border_post_fetch(E_Border *bd)
1262 // printf("Border post fetch\n");
1266 /* NB: for this policy we disable all remembers set on a border */
1267 if (bd->remember) e_remember_del(bd->remember);
1268 bd->remember = NULL;
1270 /* set this border to borderless */
1271 #ifdef DIALOG_USES_PIXEL_BORDER
1272 if ((e_illume_border_is_dialog(bd)) && (e_illume_border_parent_get(bd)))
1273 eina_stringshare_replace(&bd->bordername, "pixel");
1280 /* tell E the border has changed */
1281 bd->client.border.changed = 1;
1285 _policy_border_post_assign(E_Border *bd)
1287 // printf("Border post assign\n");
1291 bd->internal_no_remember = 1;
1293 /* do not allow client to change these properties */
1294 bd->lock_client_size = 1;
1295 bd->lock_client_shade = 1;
1296 bd->lock_client_maximize = 1;
1297 bd->lock_client_location = 1;
1298 bd->lock_client_stacking = 1;
1300 /* do not allow the user to change these properties */
1301 bd->lock_user_location = 1;
1302 bd->lock_user_size = 1;
1303 bd->lock_user_shade = 1;
1305 /* clear any centered states */
1306 /* NB: this is mainly needed for E's main config dialog */
1307 bd->client.e.state.centered = 0;
1309 /* lock the border type so user/client cannot change */
1310 bd->lock_border = 1;
1314 _policy_border_show(E_Border *bd)
1318 /* make sure we have a name so that we don't handle windows like E's root */
1319 if (!bd->client.icccm.name) return;
1321 // printf("Border Show: %s\n", bd->client.icccm.class);
1323 /* trap for special windows so we can ignore hides below them */
1324 if (e_illume_border_is_indicator(bd)) return;
1325 if (e_illume_border_is_softkey(bd)) return;
1326 if (e_illume_border_is_quickpanel(bd)) return;
1327 if (e_illume_border_is_keyboard(bd)) return;
1329 _policy_border_hide_below(bd);
1333 _policy_zone_layout(E_Zone *zone)
1335 E_Illume_Config_Zone *cz;
1341 // printf("Zone Layout: %d\n", zone->id);
1343 /* get the config for this zone */
1344 cz = e_illume_zone_config_get(zone->id);
1346 /* loop through border list and update layout */
1347 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1349 /* skip borders that are being deleted */
1350 if (e_object_is_del(E_OBJECT(bd))) continue;
1352 /* skip borders not on this zone */
1353 if (bd->zone != zone) continue;
1355 /* only update layout for this border if it really needs it */
1356 if ((!bd->new_client) && (!bd->changes.pos) && (!bd->changes.size) &&
1357 (!bd->changes.visible) && (!bd->pending_move_resize) &&
1358 (!bd->need_shape_export) && (!bd->need_shape_merge)) continue;
1360 /* are we laying out an indicator ? */
1361 if (e_illume_border_is_indicator(bd))
1362 _policy_zone_layout_indicator(bd, cz);
1364 /* are we layout out a quickpanel ? */
1365 else if (e_illume_border_is_quickpanel(bd))
1366 _policy_zone_layout_quickpanel(bd);
1368 /* are we laying out a softkey ? */
1369 else if (e_illume_border_is_softkey(bd))
1370 _policy_zone_layout_softkey(bd, cz);
1372 /* are we laying out a keyboard ? */
1373 else if (e_illume_border_is_keyboard(bd))
1374 _policy_zone_layout_keyboard(bd, cz);
1376 /* are we layout out a home window ? */
1377 else if (e_illume_border_is_home(bd))
1380 _policy_zone_layout_home_single(bd, cz);
1383 /* we are in dual-mode, check orientation */
1384 if (cz->mode.side == 0)
1388 e_illume_border_indicator_pos_get(bd->zone, NULL, &ty);
1389 if (ty <= bd->zone->y)
1390 _policy_zone_layout_home_dual_top(bd, cz);
1392 _policy_zone_layout_home_dual_custom(bd, cz);
1395 _policy_zone_layout_home_dual_left(bd, cz);
1399 /* are we laying out a fullscreen window ? */
1400 /* NB: we could use the e_illume_border_is_fullscreen function here
1401 * but we save ourselves a function call this way. */
1402 else if ((bd->fullscreen) || (bd->need_fullscreen))
1403 _policy_zone_layout_fullscreen(bd);
1405 /* are we laying out a splash screen ? */
1406 /* NB: we check splash before dialog so if a splash screen does not
1407 * register as a splash, than the dialog trap should catch it */
1408 else if (e_illume_border_is_splash(bd))
1409 _policy_zone_layout_splash(bd, cz);
1411 /* are we laying out a dialog ? */
1412 else if (e_illume_border_is_dialog(bd))
1413 _policy_zone_layout_dialog(bd, cz);
1415 /* are we layout out a conformant window ? */
1416 else if (e_illume_border_is_conformant(bd))
1419 _policy_zone_layout_conformant_single(bd, cz);
1422 /* we are in dual-mode, check orientation */
1423 if (cz->mode.side == 0)
1427 e_illume_border_indicator_pos_get(bd->zone, NULL, &ty);
1428 if (ty <= bd->zone->y)
1429 _policy_zone_layout_conformant_dual_top(bd, cz);
1431 _policy_zone_layout_conformant_dual_custom(bd, cz);
1434 _policy_zone_layout_conformant_dual_left(bd, cz);
1438 /* must be an app */
1441 /* are we in single mode ? */
1443 _policy_zone_layout_app_single(bd, cz);
1446 /* we are in dual-mode, check orientation */
1447 if (cz->mode.side == 0)
1451 /* grab the indicator position so we can tell if it
1452 * is in a custom position or not (user dragged it) */
1453 e_illume_border_indicator_pos_get(bd->zone, NULL, &ty);
1454 if (ty <= bd->zone->y)
1455 _policy_zone_layout_app_dual_top(bd, cz);
1457 _policy_zone_layout_app_dual_custom(bd, cz);
1460 _policy_zone_layout_app_dual_left(bd, cz);
1467 _policy_zone_move_resize(E_Zone *zone)
1472 // printf("Zone move resize\n");
1476 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1478 /* skip borders not on this zone */
1479 if (bd->zone != zone) continue;
1481 /* signal a changed pos here so layout gets updated */
1482 bd->changes.pos = 1;
1488 _policy_zone_mode_change(E_Zone *zone, Ecore_X_Atom mode)
1490 E_Illume_Config_Zone *cz;
1491 Eina_List *homes = NULL;
1495 // printf("Zone mode change: %d\n", zone->id);
1499 /* get the config for this zone */
1500 cz = e_illume_zone_config_get(zone->id);
1502 /* update config with new mode */
1503 if (mode == ECORE_X_ATOM_E_ILLUME_MODE_SINGLE)
1508 if (mode == ECORE_X_ATOM_E_ILLUME_MODE_DUAL_TOP)
1510 else if (mode == ECORE_X_ATOM_E_ILLUME_MODE_DUAL_LEFT)
1513 e_config_save_queue();
1515 /* lock indicator window from dragging if we need to */
1516 bd = e_illume_border_indicator_get(zone);
1519 /* only dual-top mode can drag */
1520 if ((cz->mode.dual == 1) && (cz->mode.side == 0))
1522 /* only set locked if we need to */
1523 if (bd->client.illume.drag.locked != 0)
1524 ecore_x_e_illume_drag_locked_set(bd->client.win, 0);
1528 /* only set locked if we need to */
1529 if (bd->client.illume.drag.locked != 1)
1530 ecore_x_e_illume_drag_locked_set(bd->client.win, 1);
1534 if (!(homes = e_illume_border_home_borders_get(zone))) return;
1536 count = eina_list_count(homes);
1538 /* create a new home window (if needed) for dual mode */
1539 if (cz->mode.dual == 1)
1542 ecore_x_e_illume_home_new_send(zone->black_win);
1544 else if (cz->mode.dual == 0)
1546 /* if we went to single mode, delete any extra home windows */
1551 /* try to get a home window on this zone and remove it */
1552 if ((home = e_illume_border_home_get(zone)))
1553 ecore_x_e_illume_home_del_send(home->client.win);
1557 /* Need to trigger a layout update here */
1558 _policy_zone_layout_update(zone);
1562 _policy_zone_close(E_Zone *zone)
1566 // printf("Zone close\n");
1570 /* make sure we have a focused border */
1571 if (!(bd = e_border_focused_get())) return;
1573 /* make sure focused border is on this zone */
1574 if (bd->zone != zone) return;
1576 /* close this border */
1577 e_border_act_close_begin(bd);
1581 _policy_drag_start(E_Border *bd)
1583 // printf("Drag start\n");
1587 /* ignore stolen borders */
1588 if (bd->stolen) return;
1590 /* set property on this border to say we are dragging */
1591 ecore_x_e_illume_drag_set(bd->client.win, 1);
1593 /* set property on zone window that a drag is happening */
1594 ecore_x_e_illume_drag_set(bd->zone->black_win, 1);
1598 _policy_drag_end(E_Border *bd)
1600 // printf("Drag end\n");
1604 /* ignore stolen borders */
1605 if (bd->stolen) return;
1607 /* set property on this border to say we are done dragging */
1608 ecore_x_e_illume_drag_set(bd->client.win, 0);
1610 /* set property on zone window that a drag is finished */
1611 ecore_x_e_illume_drag_set(bd->zone->black_win, 0);
1615 _policy_focus_back(E_Zone *zone)
1617 Eina_List *l, *fl = NULL;
1621 if (eina_list_count(_pol_focus_stack) < 1) return;
1623 // printf("Focus back\n");
1625 EINA_LIST_REVERSE_FOREACH(_pol_focus_stack, l, bd)
1627 if (bd->zone != zone) continue;
1628 fl = eina_list_append(fl, bd);
1631 if (!(fbd = e_border_focused_get())) return;
1632 if (fbd->parent) return;
1634 EINA_LIST_REVERSE_FOREACH(fl, l, bd)
1636 if ((fbd) && (bd == fbd))
1640 if ((l->next) && (b = l->next->data))
1642 _policy_border_set_focus(b);
1647 /* we've reached the end of the list. Set focus to first */
1648 if ((b = eina_list_nth(fl, 0)))
1650 _policy_border_set_focus(b);
1660 _policy_focus_forward(E_Zone *zone)
1662 Eina_List *l, *fl = NULL;
1666 if (eina_list_count(_pol_focus_stack) < 1) return;
1668 // printf("Focus forward\n");
1670 EINA_LIST_FOREACH(_pol_focus_stack, l, bd)
1672 if (bd->zone != zone) continue;
1673 fl = eina_list_append(fl, bd);
1676 if (!(fbd = e_border_focused_get())) return;
1677 if (fbd->parent) return;
1679 EINA_LIST_FOREACH(fl, l, bd)
1681 if ((fbd) && (bd == fbd))
1685 if ((l->next) && (b = l->next->data))
1687 _policy_border_set_focus(b);
1692 /* we've reached the end of the list. Set focus to first */
1693 if ((b = eina_list_nth(fl, 0)))
1695 _policy_border_set_focus(b);
1705 _policy_focus_home(E_Zone *zone)
1710 if (!(bd = e_illume_border_home_get(zone))) return;
1711 _policy_border_set_focus(bd);
1715 _policy_property_change(Ecore_X_Event_Window_Property *event)
1717 // printf("Property Change\n");
1719 /* we are interested in state changes here */
1720 if (event->atom == ECORE_X_ATOM_NET_WM_STATE)
1724 if (!(bd = e_border_find_by_client_window(event->win))) return;
1726 /* not interested in stolen or invisible borders */
1727 if ((bd->stolen) || (!bd->visible)) return;
1729 /* make sure the border has a name or class */
1730 /* NB: this check is here because some E borders get State Changes
1731 * but do not have a name/class associated with them. Not entirely sure
1732 * which ones they are, but I would guess Managers, Containers, or Zones.
1733 * At any rate, we're not interested in those types of borders */
1734 if ((!bd->client.icccm.name) || (!bd->client.icccm.class)) return;
1736 /* NB: If we have reached this point, then it should be a fullscreen
1737 * border that has toggled fullscreen on/off */
1739 /* try to get the Indicator on this zone */
1740 if (!(ind = e_illume_border_indicator_get(bd->zone))) return;
1742 /* if we are fullscreen, hide the indicator...else we show it */
1743 /* NB: we could use the e_illume_border_is_fullscreen function here
1744 * but we save ourselves a function call this way */
1745 if ((bd->fullscreen) || (bd->need_fullscreen))
1749 e_illume_border_hide(ind);
1750 _policy_zone_layout_update(bd->zone);
1757 e_illume_border_show(ind);
1758 _policy_zone_layout_update(bd->zone);
1762 else if (event->atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY)
1769 /* make sure this property changed on a zone */
1770 if (!(zone = e_util_zone_window_find(event->win))) return;
1772 /* get the geometry */
1773 if (!(bd = e_illume_border_indicator_get(zone))) return;
1779 /* look for conformant borders */
1780 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1782 if (bd->zone != zone) continue;
1783 if (!e_illume_border_is_conformant(bd)) continue;
1784 /* set indicator geometry on conformant window */
1785 /* NB: This is needed so that conformant apps get told about
1786 * the indicator size/position...else they have no way of
1787 * knowing that the geometry has been updated */
1788 ecore_x_e_illume_indicator_geometry_set(bd->client.win, x, y, w, h);
1791 else if (event->atom == ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY)
1798 /* make sure this property changed on a zone */
1799 if (!(zone = e_util_zone_window_find(event->win))) return;
1801 if (!(bd = e_illume_border_softkey_get(zone))) return;
1807 /* look for conformant borders */
1808 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1810 if (bd->zone != zone) continue;
1811 if (!e_illume_border_is_conformant(bd)) continue;
1812 /* set softkey geometry on conformant window */
1813 /* NB: This is needed so that conformant apps get told about
1814 * the softkey size/position...else they have no way of
1815 * knowing that the geometry has been updated */
1816 ecore_x_e_illume_softkey_geometry_set(bd->client.win, x, y, w, h);
1819 else if (event->atom == ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY)
1823 E_Illume_Keyboard *kbd;
1827 /* make sure this property changed on a zone */
1828 if (!(zone = e_util_zone_window_find(event->win))) return;
1830 /* get the keyboard */
1831 if (!(kbd = e_illume_keyboard_get())) return;
1832 if (!kbd->border) return;
1834 /* get the geometry */
1839 /* adjust Y for keyboard visibility because keyboard uses fx_offset */
1841 if (kbd->border->fx.y <= 0) y = kbd->border->y;
1843 /* look for conformant borders */
1844 EINA_LIST_FOREACH(e_border_client_list(), l, bd)
1846 if (bd->zone != zone) continue;
1847 if (!e_illume_border_is_conformant(bd)) continue;
1848 /* set keyboard geometry on conformant window */
1849 /* NB: This is needed so that conformant apps get told about
1850 * the keyboard size/position...else they have no way of
1851 * knowing that the geometry has been updated */
1852 ecore_x_e_illume_keyboard_geometry_set(bd->client.win, x, y, w, h);
1855 else if (event->atom == ATM_ENLIGHTENMENT_SCALE)
1860 EINA_LIST_FOREACH(e_manager_list(), ml, man)
1865 if (event->win != man->root) continue;
1866 EINA_LIST_FOREACH(man->containers, cl, con)
1871 EINA_LIST_FOREACH(con->zones, zl, zone)
1872 _policy_zone_layout_update(zone);