5 * * fix shape callbacks to be able to be safely deleted
6 * * remove duplicate bd->layer -> layers code
10 /* local subsystem functions */
11 static void _e_container_free(E_Container *con);
13 static E_Container *_e_container_find_by_event_window(Ecore_X_Window win);
15 static Eina_Bool _e_container_cb_mouse_in(void *data, int type, void *event);
16 static Eina_Bool _e_container_cb_mouse_out(void *data, int type, void *event);
17 static Eina_Bool _e_container_cb_mouse_down(void *data, int type, void *event);
18 static Eina_Bool _e_container_cb_mouse_up(void *data, int type, void *event);
19 static Eina_Bool _e_container_cb_mouse_move(void *data, int type, void *event);
20 static Eina_Bool _e_container_cb_mouse_wheel(void *data, int type, void *event);
22 static void _e_container_shape_del(E_Container_Shape *es);
23 static void _e_container_shape_free(E_Container_Shape *es);
24 static void _e_container_shape_change_call(E_Container_Shape *es, E_Container_Shape_Change ch);
25 static void _e_container_resize_handle(E_Container *con);
26 static void _e_container_event_container_resize_free(void *data, void *ev);
28 EAPI int E_EVENT_CONTAINER_RESIZE = 0;
29 static Eina_List *handlers = NULL;
31 /* externally accessible functions */
33 e_container_init(void)
35 E_EVENT_CONTAINER_RESIZE = ecore_event_type_new();
37 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_container_cb_mouse_in, NULL));
38 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_container_cb_mouse_out, NULL));
39 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_container_cb_mouse_down, NULL));
40 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_container_cb_mouse_up, NULL));
41 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_container_cb_mouse_move, NULL));
42 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _e_container_cb_mouse_wheel, NULL));
47 e_container_shutdown(void)
49 E_FREE_LIST(handlers, ecore_event_handler_del);
54 e_container_new(E_Manager *man)
59 Eina_List *l, *screens;
62 static int container_num = 0;
64 con = E_OBJECT_ALLOC(E_Container, E_CONTAINER_TYPE, _e_container_free);
65 if (!con) return NULL;
67 con->manager->containers = eina_list_append(con->manager->containers, con);
68 con->w = con->manager->w;
69 con->h = con->manager->h;
70 if (e_config->use_virtual_roots)
72 con->win = ecore_x_window_override_new(con->manager->win, con->x, con->y, con->w, con->h);
73 ecore_x_icccm_title_set(con->win, "Enlightenment Container");
74 ecore_x_netwm_name_set(con->win, "Enlightenment Container");
75 ecore_x_window_raise(con->win);
78 con->win = con->manager->win;
80 if (!e_config->null_container_win)
81 con->bg_ecore_evas = e_canvas_new(e_config->evas_engine_container, con->win,
82 0, 0, con->w, con->h, 1, 1,
85 con->bg_ecore_evas = e_canvas_new(e_config->evas_engine_container, con->win,
88 e_canvas_add(con->bg_ecore_evas);
89 con->event_win = ecore_x_window_input_new(con->win, 0, 0, con->w, con->h);
90 ecore_x_window_show(con->event_win);
91 con->bg_evas = ecore_evas_get(con->bg_ecore_evas);
92 ecore_evas_name_class_set(con->bg_ecore_evas, "E", "Background_Window");
93 ecore_evas_title_set(con->bg_ecore_evas, "Enlightenment Background");
94 if (!getenv("EVAS_RENDER_MODE"))
100 // FIXME: major hack. checking in advance for comp. eventully comp
101 // will be rolled into e17 core and this won't be needed
102 EINA_LIST_FOREACH(e_config->modules, l, em)
104 if (!strcmp(em->name, "comp"))
112 if (getenv("REDRAW_DEBUG"))
113 ecore_evas_avoid_damage_set(con->bg_ecore_evas, !atoi(getenv("REDRAW_DEBUG")));
115 ecore_evas_avoid_damage_set(con->bg_ecore_evas, ECORE_EVAS_AVOID_DAMAGE_BUILT_IN);
118 ecore_x_window_lower(con->bg_win);
120 o = evas_object_rectangle_add(con->bg_evas);
121 con->bg_blank_object = o;
122 evas_object_layer_set(o, -100);
123 evas_object_move(o, 0, 0);
124 evas_object_resize(o, con->w, con->h);
125 evas_object_color_set(o, 255, 255, 255, 255);
126 evas_object_name_set(o, "e/desktop/background");
127 evas_object_data_set(o, "e_container", con);
130 con->num = container_num;
132 snprintf(name, sizeof(name), _("Container %d"), con->num);
133 con->name = eina_stringshare_add(name);
135 /* create a scratch window for putting stuff into */
136 con->scratch_win = ecore_x_window_override_new(con->win, 0, 0, 7, 7);
139 for (i = 0; i < 7; i++)
141 con->layers[i].win = ecore_x_window_input_new(con->win, 0, 0, 1, 1);
142 ecore_x_window_lower(con->layers[i].win);
145 ecore_x_window_configure(con->layers[i].win,
146 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
147 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
149 con->layers[i - 1].win, ECORE_X_WINDOW_STACK_ABOVE);
152 /* Put init win on top */
154 ecore_x_window_configure(man->initwin,
155 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
156 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
158 con->layers[6].win, ECORE_X_WINDOW_STACK_ABOVE);
161 /* Put menu win on top */
162 mwin = e_menu_grab_window_get();
164 ecore_x_window_configure(mwin,
165 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
166 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
168 con->layers[6].win, ECORE_X_WINDOW_STACK_ABOVE);
170 /* Put background win at the bottom */
171 ecore_x_window_configure(con->bg_win,
172 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
173 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
175 con->layers[0].win, ECORE_X_WINDOW_STACK_BELOW);
177 screens = (Eina_List *)e_xinerama_screens_get();
181 EINA_LIST_FOREACH(screens, l, scr)
183 e_zone_new(con, scr->screen, scr->escreen, scr->x, scr->y, scr->w, scr->h);
187 e_zone_new(con, 0, 0, 0, 0, con->w, con->h);
192 e_container_show(E_Container *con)
195 E_OBJECT_TYPE_CHECK(con, E_CONTAINER_TYPE);
197 if (con->visible) return;
198 if (!e_config->null_container_win)
199 ecore_evas_show(con->bg_ecore_evas);
200 ecore_x_window_configure(con->bg_win,
201 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
202 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
204 con->layers[0].win, ECORE_X_WINDOW_STACK_BELOW);
205 ecore_x_window_configure(con->event_win,
206 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
207 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
209 con->layers[0].win, ECORE_X_WINDOW_STACK_BELOW);
210 if (con->win != con->manager->win)
211 ecore_x_window_show(con->win);
212 ecore_x_icccm_state_set(con->bg_win, ECORE_X_WINDOW_STATE_HINT_NORMAL);
217 e_container_hide(E_Container *con)
220 E_OBJECT_TYPE_CHECK(con, E_CONTAINER_TYPE);
222 if (!con->visible) return;
223 ecore_evas_hide(con->bg_ecore_evas);
224 if (con->win != con->manager->win)
225 ecore_x_window_hide(con->win);
230 e_container_current_get(E_Manager *man)
234 E_OBJECT_CHECK_RETURN(man, NULL);
235 E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
237 EINA_LIST_FOREACH(man->containers, l, con)
240 if (con->visible) return con;
243 /* If no one is available, return the first */
244 if (!man->containers) return NULL;
246 return (E_Container *)eina_list_data_get(l);
250 e_container_number_get(E_Manager *man, int num)
255 E_OBJECT_CHECK_RETURN(man, NULL);
256 E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
257 EINA_LIST_FOREACH(man->containers, l, con)
259 if ((int) con->num == num) return con;
265 e_container_move(E_Container *con, int x, int y)
268 E_OBJECT_TYPE_CHECK(con, E_CONTAINER_TYPE);
269 if ((x == con->x) && (y == con->y)) return;
272 if (con->win != con->manager->win)
273 ecore_x_window_move(con->win, con->x, con->y);
274 evas_object_move(con->bg_blank_object, con->x, con->y);
278 e_container_resize(E_Container *con, int w, int h)
281 E_OBJECT_TYPE_CHECK(con, E_CONTAINER_TYPE);
282 if ((w == con->w) && (h == con->h)) return;
285 if (con->win != con->manager->win)
286 ecore_x_window_resize(con->win, con->w, con->h);
287 ecore_x_window_resize(con->event_win, con->w, con->h);
288 if (!e_config->null_container_win)
289 ecore_evas_resize(con->bg_ecore_evas, con->w, con->h);
290 evas_object_resize(con->bg_blank_object, con->w, con->h);
291 _e_container_resize_handle(con);
295 e_container_move_resize(E_Container *con, int x, int y, int w, int h)
298 E_OBJECT_TYPE_CHECK(con, E_CONTAINER_TYPE);
299 if ((x == con->x) && (y == con->y) && (w == con->w) && (h == con->h)) return;
304 if (con->win != con->manager->win)
305 ecore_x_window_move_resize(con->win, con->x, con->y, con->w, con->h);
306 ecore_x_window_move_resize(con->event_win, con->x, con->y, con->w, con->h);
307 if (!e_config->null_container_win)
308 ecore_evas_resize(con->bg_ecore_evas, con->w, con->h);
309 evas_object_move(con->bg_blank_object, con->x, con->y);
310 evas_object_resize(con->bg_blank_object, con->w, con->h);
311 _e_container_resize_handle(con);
315 e_container_raise(E_Container *con __UNUSED__)
317 // E_OBJECT_CHECK(con);
318 // E_OBJECT_TYPE_CHECK(con, E_CONTAINER_TYPE);
322 e_container_lower(E_Container *con __UNUSED__)
324 // E_OBJECT_CHECK(con);
325 // E_OBJECT_TYPE_CHECK(con, E_CONTAINER_TYPE);
329 e_container_zone_at_point_get(E_Container *con, int x, int y)
334 E_OBJECT_CHECK_RETURN(con, NULL);
335 E_OBJECT_TYPE_CHECK_RETURN(con, E_CONTAINER_TYPE, NULL);
336 EINA_LIST_FOREACH(con->zones, l, zone)
338 if (E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h))
345 e_container_zone_number_get(E_Container *con, int num)
350 E_OBJECT_CHECK_RETURN(con, NULL);
351 E_OBJECT_TYPE_CHECK_RETURN(con, E_CONTAINER_TYPE, NULL);
352 EINA_LIST_FOREACH(con->zones, l, zone)
354 if ((int) zone->num == num) return zone;
360 e_container_zone_id_get(E_Container *con, int id)
365 E_OBJECT_CHECK_RETURN(con, NULL);
366 E_OBJECT_TYPE_CHECK_RETURN(con, E_CONTAINER_TYPE, NULL);
367 EINA_LIST_FOREACH(con->zones, l, zone)
369 if (zone->id == id) return zone;
374 EAPI E_Container_Shape *
375 e_container_shape_add(E_Container *con)
377 E_Container_Shape *es;
379 E_OBJECT_CHECK_RETURN(con, NULL);
380 E_OBJECT_TYPE_CHECK_RETURN(con, E_CONTAINER_TYPE, 0);
382 es = E_OBJECT_ALLOC(E_Container_Shape, E_CONTAINER_SHAPE_TYPE, _e_container_shape_free);
383 E_OBJECT_DEL_SET(es, _e_container_shape_del);
385 con->shapes = eina_list_append(con->shapes, es);
386 _e_container_shape_change_call(es, E_CONTAINER_SHAPE_ADD);
391 e_container_shape_show(E_Container_Shape *es)
394 E_OBJECT_TYPE_CHECK(es, E_CONTAINER_SHAPE_TYPE);
395 if (es->visible) return;
397 _e_container_shape_change_call(es, E_CONTAINER_SHAPE_SHOW);
401 e_container_shape_hide(E_Container_Shape *es)
404 E_OBJECT_TYPE_CHECK(es, E_CONTAINER_SHAPE_TYPE);
405 if (!es->visible) return;
407 _e_container_shape_change_call(es, E_CONTAINER_SHAPE_HIDE);
411 e_container_shape_move(E_Container_Shape *es, int x, int y)
414 E_OBJECT_TYPE_CHECK(es, E_CONTAINER_SHAPE_TYPE);
415 if ((es->x == x) && (es->y == y)) return;
418 _e_container_shape_change_call(es, E_CONTAINER_SHAPE_MOVE);
422 e_container_shape_resize(E_Container_Shape *es, int w, int h)
425 E_OBJECT_TYPE_CHECK(es, E_CONTAINER_SHAPE_TYPE);
428 if ((es->w == w) && (es->h == h)) return;
431 _e_container_shape_change_call(es, E_CONTAINER_SHAPE_RESIZE);
435 e_container_shape_list_get(E_Container *con)
437 E_OBJECT_CHECK_RETURN(con, NULL);
438 E_OBJECT_TYPE_CHECK_RETURN(con, E_CONTAINER_TYPE, NULL);
443 e_container_shape_geometry_get(E_Container_Shape *es, int *x, int *y, int *w, int *h)
446 E_OBJECT_TYPE_CHECK(es, E_CONTAINER_SHAPE_TYPE);
454 e_container_shape_container_get(E_Container_Shape *es)
456 E_OBJECT_CHECK_RETURN(es, NULL);
457 E_OBJECT_TYPE_CHECK_RETURN(es, E_CONTAINER_SHAPE_TYPE, NULL);
462 e_container_shape_change_callback_add(E_Container *con, void (*func) (void *data, E_Container_Shape *es, E_Container_Shape_Change ch), void *data)
464 E_Container_Shape_Callback *cb;
467 E_OBJECT_TYPE_CHECK(con, E_CONTAINER_TYPE);
468 cb = calloc(1, sizeof(E_Container_Shape_Callback));
472 con->shape_change_cb = eina_list_append(con->shape_change_cb, cb);
476 e_container_shape_change_callback_del(E_Container *con, void (*func) (void *data, E_Container_Shape *es, E_Container_Shape_Change ch), void *data)
479 E_Container_Shape_Callback *cb = NULL;
481 /* FIXME: if we call this from within a callback we are in trouble */
483 E_OBJECT_TYPE_CHECK(con, E_CONTAINER_TYPE);
484 EINA_LIST_FOREACH(con->shape_change_cb, l, cb)
486 if ((cb->func == func) && (cb->data == data))
488 con->shape_change_cb = eina_list_remove_list(con->shape_change_cb, l);
496 e_container_shape_rects_get(E_Container_Shape *es)
498 E_OBJECT_CHECK_RETURN(es, NULL);
499 E_OBJECT_TYPE_CHECK_RETURN(es, E_CONTAINER_SHAPE_TYPE, NULL);
504 e_container_shape_rects_set(E_Container_Shape *es, Ecore_X_Rectangle *rects, int num)
510 E_OBJECT_TYPE_CHECK(es, E_CONTAINER_SHAPE_TYPE);
513 E_FREE_LIST(es->shape, free);
516 if ((rects) && (num == 1) &&
519 ((int) rects[0].width == es->w) &&
520 ((int) rects[0].height == es->h))
526 for (i = 0; i < num; i++)
528 r = malloc(sizeof(E_Rect));
533 r->w = rects[i].width;
534 r->h = rects[i].height;
535 es->shape = eina_list_append(es->shape, r);
539 _e_container_shape_change_call(es, E_CONTAINER_SHAPE_RECTS);
543 e_container_shape_solid_rect_set(E_Container_Shape *es, int x, int y, int w, int h)
545 es->solid_rect.x = x;
546 es->solid_rect.y = y;
547 es->solid_rect.w = w;
548 es->solid_rect.h = h;
552 e_container_shape_solid_rect_get(E_Container_Shape *es, int *x, int *y, int *w, int *h)
554 if (x) *x = es->solid_rect.x;
555 if (y) *y = es->solid_rect.y;
556 if (w) *w = es->solid_rect.w;
557 if (h) *h = es->solid_rect.h;
566 * 999 = internal on top windows for E
569 e_container_borders_count(E_Container *con)
575 e_container_border_add(E_Border *bd)
579 if (!bd->zone) return;
580 if (bd->layer == 0) pos = 0;
581 else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1;
582 else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2;
583 else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3;
584 else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4;
587 bd->zone->container->clients++;
588 bd->zone->container->layers[pos].clients =
589 eina_list_append(bd->zone->container->layers[pos].clients, bd);
590 e_hints_client_list_set();
594 e_container_border_remove(E_Border *bd)
598 if (!bd->zone) return;
599 /* FIXME: Could revert to old behaviour, ->layer is consistent
601 for (i = 0; i < 7; i++)
603 bd->zone->container->layers[i].clients =
604 eina_list_remove(bd->zone->container->layers[i].clients, bd);
606 bd->zone->container->clients--;
608 e_hints_client_list_set();
612 e_container_window_raise(E_Container *con, Ecore_X_Window win, int layer)
616 if (layer <= 0) pos = 0;
617 else if ((layer > 0) && (layer <= 50)) pos = 1;
618 else if ((layer > 50) && (layer <= 100)) pos = 2;
619 else if ((layer > 100) && (layer <= 150)) pos = 3;
620 else if ((layer > 150) && (layer <= 200)) pos = 4;
623 ecore_x_window_configure(win,
624 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
625 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
627 con->layers[pos + 1].win, ECORE_X_WINDOW_STACK_BELOW);
631 e_container_window_lower(E_Container *con, Ecore_X_Window win, int layer)
635 if (layer <= 0) pos = 0;
636 else if ((layer > 0) && (layer <= 50)) pos = 1;
637 else if ((layer > 50) && (layer <= 100)) pos = 2;
638 else if ((layer > 100) && (layer <= 150)) pos = 3;
639 else if ((layer > 150) && (layer <= 200)) pos = 4;
642 ecore_x_window_configure(win,
643 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
644 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
646 con->layers[pos].win, ECORE_X_WINDOW_STACK_ABOVE);
650 e_container_border_raise(E_Border *bd)
652 E_Border *above = NULL;
656 if (!bd->zone) return NULL;
657 /* Remove from old layer */
658 for (i = 0; i < 7; i++)
660 bd->zone->container->layers[i].clients =
661 eina_list_remove(bd->zone->container->layers[i].clients, bd);
664 /* Add to new layer */
665 if (bd->layer <= 0) pos = 0;
666 else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1;
667 else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2;
668 else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3;
669 else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4;
672 ecore_x_window_configure(bd->win,
673 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
674 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
676 bd->zone->container->layers[pos + 1].win, ECORE_X_WINDOW_STACK_BELOW);
678 bd->zone->container->layers[pos].clients =
679 eina_list_append(bd->zone->container->layers[pos].clients, bd);
681 /* Find the window below this one */
682 l = eina_list_data_find_list(bd->zone->container->layers[pos].clients, bd);
683 if (eina_list_prev(l))
684 above = eina_list_data_get(eina_list_prev(l));
687 /* Need to check the layers below */
688 for (i = pos - 1; i >= 0; i--)
690 if ((bd->zone->container->layers[i].clients) &&
691 (l = eina_list_last(bd->zone->container->layers[i].clients)))
693 above = eina_list_data_get(l);
699 e_hints_client_stacking_set();
704 e_container_border_lower(E_Border *bd)
706 E_Border *below = NULL;
710 if (!bd->zone) return NULL;
711 /* Remove from old layer */
712 for (i = 0; i < 7; i++)
714 bd->zone->container->layers[i].clients =
715 eina_list_remove(bd->zone->container->layers[i].clients, bd);
718 /* Add to new layer */
719 if (bd->layer <= 0) pos = 0;
720 else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1;
721 else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2;
722 else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3;
723 else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4;
726 ecore_x_window_configure(bd->win,
727 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
728 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
730 bd->zone->container->layers[pos].win, ECORE_X_WINDOW_STACK_ABOVE);
732 bd->zone->container->layers[pos].clients =
733 eina_list_prepend(bd->zone->container->layers[pos].clients, bd);
735 /* Find the window above this one */
736 l = eina_list_data_find_list(bd->zone->container->layers[pos].clients, bd);
737 if (eina_list_next(l))
738 below = eina_list_data_get(eina_list_next(l));
741 /* Need to check the layers above */
742 for (i = pos + 1; i < 7; i++)
744 if (bd->zone->container->layers[i].clients)
746 below = eina_list_data_get(bd->zone->container->layers[i].clients);
752 e_hints_client_stacking_set();
757 e_container_border_stack_above(E_Border *bd, E_Border *above)
761 if (!bd->zone) return;
762 /* Remove from old layer */
763 for (i = 0; i < 7; i++)
765 bd->zone->container->layers[i].clients =
766 eina_list_remove(bd->zone->container->layers[i].clients, bd);
769 /* Add to new layer */
770 bd->layer = above->layer;
772 if (bd->layer <= 0) pos = 0;
773 else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1;
774 else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2;
775 else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3;
776 else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4;
779 ecore_x_window_configure(bd->win,
780 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
781 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
783 above->win, ECORE_X_WINDOW_STACK_ABOVE);
785 bd->zone->container->layers[pos].clients =
786 eina_list_append_relative(bd->zone->container->layers[pos].clients, bd, above);
790 e_container_border_stack_below(E_Border *bd, E_Border *below)
794 if (!bd->zone) return;
795 /* Remove from old layer */
796 for (i = 0; i < 7; i++)
798 bd->zone->container->layers[i].clients =
799 eina_list_remove(bd->zone->container->layers[i].clients, bd);
802 /* Add to new layer */
803 bd->layer = below->layer;
805 if (bd->layer <= 0) pos = 0;
806 else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1;
807 else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2;
808 else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3;
809 else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4;
812 ecore_x_window_configure(bd->win,
813 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
814 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
816 below->win, ECORE_X_WINDOW_STACK_BELOW);
818 bd->zone->container->layers[pos].clients =
819 eina_list_prepend_relative(bd->zone->container->layers[pos].clients, bd, below);
822 static E_Border_List *
823 _e_container_border_list_new(E_Container *con)
825 E_Border_List *list = NULL;
830 if (!(list = E_NEW(E_Border_List, 1))) return NULL;
831 list->container = con;
832 e_object_ref(E_OBJECT(list->container));
833 eina_array_step_set(&(list->client_array), sizeof(list->client_array), 256);
834 for (i = 0; i < 7; i++)
836 EINA_LIST_FOREACH(con->layers[i].clients, l, bd)
837 eina_array_push(&(list->client_array), bd);
843 _e_container_border_list_jump(E_Border_List *list, int dir)
847 if ((list->pos < 0) ||
848 (list->pos >= (int)eina_array_count_get(&(list->client_array))))
850 bd = eina_array_data_get(&(list->client_array), list->pos);
856 e_container_border_list_first(E_Container *con)
858 E_Border_List *list = NULL;
860 list = _e_container_border_list_new(con);
866 e_container_border_list_last(E_Container *con)
868 E_Border_List *list = NULL;
870 list = _e_container_border_list_new(con);
871 list->pos = eina_array_count_get(&(list->client_array)) - 1;
876 e_container_border_list_next(E_Border_List *list)
878 return _e_container_border_list_jump(list, 1);
882 e_container_border_list_prev(E_Border_List *list)
884 return _e_container_border_list_jump(list, -1);
888 e_container_border_list_free(E_Border_List *list)
890 e_object_unref(E_OBJECT(list->container));
891 eina_array_flush(&(list->client_array));
896 e_container_all_freeze(void)
902 EINA_LIST_FOREACH(e_manager_list(), l, man)
904 EINA_LIST_FOREACH(man->containers, ll, con)
906 evas_event_freeze(con->bg_evas);
912 e_container_all_thaw(void)
918 EINA_LIST_FOREACH(e_manager_list(), l, man)
920 EINA_LIST_FOREACH(man->containers, ll, con)
922 evas_event_thaw(con->bg_evas);
927 /* local subsystem functions */
929 _e_container_free(E_Container *con)
934 ecore_x_window_free(con->scratch_win);
935 ecore_x_window_free(con->event_win);
936 /* We can't use e_object_del here, because border adds a ref to itself
937 * when it is removed, and the ref is never unref'ed */
938 for (i = 0; i < 7; i++)
940 ecore_x_window_free(con->layers[i].win);
941 /* FIXME: had to disable this as it was freeing already freed items during
942 * looping (particularly remember/lock config dialogs). this is just
943 * disabled until we put in some special handling for this
945 EINA_LiST_FOREACH(con->layers[i].clients, l, tmp)
947 e_object_free(E_OBJECT(tmp));
953 E_FREE_LIST(l, e_object_del);
954 con->manager->containers = eina_list_remove(con->manager->containers, con);
955 e_canvas_del(con->bg_ecore_evas);
956 ecore_evas_free(con->bg_ecore_evas);
957 if (con->manager->win != con->win)
959 ecore_x_window_free(con->win);
961 if (con->name) eina_stringshare_del(con->name);
966 _e_container_find_by_event_window(Ecore_X_Window win)
972 EINA_LIST_FOREACH(e_manager_list(), l, man)
974 EINA_LIST_FOREACH(man->containers, ll, con)
976 if (con->event_win == win) return con;
983 _e_container_cb_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
985 Ecore_X_Event_Mouse_In *ev;
990 con = _e_container_find_by_event_window(ev->event_win);
993 bd = e_border_focused_get();
994 if (bd) e_focus_event_mouse_out(bd);
995 ecore_event_evas_modifier_lock_update(con->bg_evas, ev->modifiers);
996 evas_event_feed_mouse_in(con->bg_evas, ev->time, NULL);
998 return ECORE_CALLBACK_PASS_ON;
1002 _e_container_cb_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
1004 Ecore_X_Event_Mouse_Out *ev;
1008 con = _e_container_find_by_event_window(ev->event_win);
1011 ecore_event_evas_modifier_lock_update(con->bg_evas, ev->modifiers);
1012 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
1013 evas_event_feed_mouse_cancel(con->bg_evas, ev->time, NULL);
1014 evas_event_feed_mouse_out(con->bg_evas, ev->time, NULL);
1016 return ECORE_CALLBACK_PASS_ON;
1020 _e_container_cb_mouse_down(void *data __UNUSED__, int type __UNUSED__, void *event)
1022 Ecore_Event_Mouse_Button *ev;
1026 con = _e_container_find_by_event_window(ev->event_window);
1029 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
1031 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_CONTAINER,
1033 if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
1034 if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
1035 ecore_event_evas_modifier_lock_update(con->bg_evas, ev->modifiers);
1036 evas_event_feed_mouse_down(con->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
1038 return ECORE_CALLBACK_PASS_ON;
1042 _e_container_cb_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event)
1044 Ecore_Event_Mouse_Button *ev;
1048 con = _e_container_find_by_event_window(ev->event_window);
1051 evas_event_feed_mouse_up(con->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
1052 ecore_event_evas_modifier_lock_update(con->bg_evas, ev->modifiers);
1053 e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_CONTAINER,
1056 return ECORE_CALLBACK_PASS_ON;
1060 _e_container_cb_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
1062 Ecore_Event_Mouse_Move *ev;
1066 con = _e_container_find_by_event_window(ev->event_window);
1069 ecore_event_evas_modifier_lock_update(con->bg_evas, ev->modifiers);
1070 evas_event_feed_mouse_move(con->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
1076 _e_container_cb_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event)
1078 Ecore_Event_Mouse_Wheel *ev;
1082 con = _e_container_find_by_event_window(ev->event_window);
1085 if (!e_bindings_wheel_event_handle(E_BINDING_CONTEXT_CONTAINER,
1088 ecore_event_evas_modifier_lock_update(con->bg_evas, ev->modifiers);
1089 evas_event_feed_mouse_wheel(con->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
1092 return ECORE_CALLBACK_PASS_ON;
1096 _e_container_shape_del(E_Container_Shape *es)
1098 _e_container_shape_change_call(es, E_CONTAINER_SHAPE_DEL);
1102 _e_container_shape_free(E_Container_Shape *es)
1104 es->con->shapes = eina_list_remove(es->con->shapes, es);
1105 E_FREE_LIST(es->shape, free);
1110 _e_container_shape_change_call(E_Container_Shape *es, E_Container_Shape_Change ch)
1112 Eina_List *l = NULL;
1113 E_Container_Shape_Callback *cb = NULL;
1115 if ((!es) || (!es->con) || (!es->con->shape_change_cb)) return;
1116 EINA_LIST_FOREACH(es->con->shape_change_cb, l, cb)
1119 cb->func(cb->data, es, ch);
1124 _e_container_resize_handle(E_Container *con)
1126 E_Event_Container_Resize *ev;
1127 Eina_List *l, *screens, *zones = NULL;
1132 ev = calloc(1, sizeof(E_Event_Container_Resize));
1133 ev->container = con;
1134 e_object_ref(E_OBJECT(con));
1136 e_xinerama_update();
1137 screens = (Eina_List *)e_xinerama_screens_get();
1141 EINA_LIST_FOREACH(con->zones, l, zone)
1142 zones = eina_list_append(zones, zone);
1143 EINA_LIST_FOREACH(screens, l, scr)
1145 zone = e_container_zone_id_get(con, scr->escreen);
1148 e_zone_move_resize(zone, scr->x, scr->y, scr->w, scr->h);
1149 e_shelf_zone_move_resize_handle(zone);
1150 zones = eina_list_remove(zones, zone);
1155 E_Config_Shelf *cf_es;
1157 zone = e_zone_new(con, scr->screen, scr->escreen, scr->x, scr->y, scr->w, scr->h);
1158 /* find any shelves configured for this zone and add them in */
1159 EINA_LIST_FOREACH(e_config->shelves, ll, cf_es)
1161 if (e_util_container_zone_id_get(cf_es->container, cf_es->zone) == zone)
1162 e_shelf_config_new(zone, cf_es);
1168 E_Zone *spare_zone = NULL;
1171 EINA_LIST_FOREACH(con->zones, ll, spare_zone)
1173 if (eina_list_data_find(zones, spare_zone))
1177 EINA_LIST_FREE(zones, zone)
1179 Eina_List *shelves, *ll, *del_shelves;
1184 /* delete any shelves on this zone */
1185 shelves = e_shelf_list();
1187 EINA_LIST_FOREACH(shelves, ll, es)
1189 if (es->zone == zone)
1190 del_shelves = eina_list_append(del_shelves, es);
1192 E_FREE_LIST(del_shelves, e_object_del);
1193 bl = e_container_border_list_first(zone->container);
1194 while ((bd = e_container_border_list_next(bl)))
1196 if (bd->zone == zone)
1198 if (spare_zone) e_border_zone_set(bd, spare_zone);
1200 printf("EEEK! should not be here - but no\n"
1201 "spare zones exist to move this\n"
1202 "window to!!! help!\n");
1205 e_container_border_list_free(bl);
1206 e_object_del(E_OBJECT(zone));
1214 zone = e_container_zone_number_get(con, 0);
1215 e_zone_move_resize(zone, 0, 0, con->w, con->h);
1216 e_shelf_zone_move_resize_handle(zone);
1219 ecore_event_add(E_EVENT_CONTAINER_RESIZE, ev, _e_container_event_container_resize_free, NULL);
1221 for (i = 0; i < 7; i++)
1223 Eina_List *tmp = NULL;
1226 /* Make temporary list as e_border_res_change_geometry_restore
1227 * rearranges the order. */
1228 EINA_LIST_FOREACH(con->layers[i].clients, l, bd)
1229 tmp = eina_list_append(tmp, bd);
1231 EINA_LIST_FOREACH(tmp, l, bd)
1233 e_border_res_change_geometry_save(bd);
1234 e_border_res_change_geometry_restore(bd);
1237 eina_list_free(tmp);
1242 _e_container_event_container_resize_free(void *data __UNUSED__, void *ev)
1244 E_Event_Container_Resize *e;
1247 e_object_unref(E_OBJECT(e->container));