2 * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
4 * This file is a modified version of BSD licensed file and
5 * licensed under the Flora License, Version 1.0 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://floralicense.org/license/
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an AS IS BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * Please, see the COPYING file for the original copyright owner and
22 /* E_Zone is a child object of E_Container. There is one zone per screen
23 * in a xinerama setup. Each zone has one or more desktops.
26 static void _e_zone_free(E_Zone *zone);
27 static void _e_zone_cb_bg_mouse_down(void *data,
31 static void _e_zone_cb_bg_mouse_up(void *data,
35 static void _e_zone_event_zone_desk_count_set_free(void *data,
37 static Eina_Bool _e_zone_cb_mouse_in(void *data,
40 static Eina_Bool _e_zone_cb_mouse_out(void *data,
43 static Eina_Bool _e_zone_cb_mouse_down(void *data,
46 static Eina_Bool _e_zone_cb_mouse_up(void *data,
49 static Eina_Bool _e_zone_cb_mouse_move(void *data,
52 static Eina_Bool _e_zone_cb_desk_after_show(void *data,
55 static Eina_Bool _e_zone_cb_edge_timer(void *data);
56 static void _e_zone_event_move_resize_free(void *data,
58 static void _e_zone_event_add_free(void *data,
60 static void _e_zone_event_del_free(void *data,
62 static void _e_zone_object_del_attach(void *o);
63 static E_Zone_Edge _e_zone_detect_edge(E_Zone *zone,
65 static void _e_zone_edge_move_resize(E_Zone *zone);
66 static void _e_zone_border_geometry_update(E_Zone *zone);
67 #ifdef _F_ZONE_WINDOW_ROTATION_
68 static void _e_zone_event_rotation_change_free(void *data,
72 EAPI int E_EVENT_ZONE_DESK_COUNT_SET = 0;
73 EAPI int E_EVENT_POINTER_WARP = 0;
74 EAPI int E_EVENT_ZONE_MOVE_RESIZE = 0;
75 EAPI int E_EVENT_ZONE_ADD = 0;
76 EAPI int E_EVENT_ZONE_DEL = 0;
77 EAPI int E_EVENT_ZONE_EDGE_IN = 0;
78 EAPI int E_EVENT_ZONE_EDGE_OUT = 0;
79 EAPI int E_EVENT_ZONE_EDGE_MOVE = 0;
80 #ifdef _F_ZONE_WINDOW_ROTATION_
81 EAPI int E_EVENT_ZONE_ROTATION_CHANGE = 0;
84 #define E_ZONE_FLIP_LEFT(zone) (((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1)) || ((zone)->desk_x_current > 0)) && (zone)->edge.left)
85 #define E_ZONE_FLIP_RIGHT(zone) (((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1)) || (((zone)->desk_x_current + 1) < (zone)->desk_x_count)) && (zone)->edge.right)
86 #define E_ZONE_FLIP_UP(zone) (((e_config->desk_flip_wrap && ((zone)->desk_y_count > 1)) || ((zone)->desk_y_current > 0)) && (zone)->edge.top)
87 #define E_ZONE_FLIP_DOWN(zone) (((e_config->desk_flip_wrap && ((zone)->desk_y_count > 1)) || (((zone)->desk_y_current + 1) < (zone)->desk_y_count)) && (zone)->edge.bottom)
89 #define E_ZONE_CORNER_RATIO 0.025;
94 E_EVENT_ZONE_DESK_COUNT_SET = ecore_event_type_new();
95 E_EVENT_POINTER_WARP = ecore_event_type_new();
96 E_EVENT_ZONE_MOVE_RESIZE = ecore_event_type_new();
97 E_EVENT_ZONE_ADD = ecore_event_type_new();
98 E_EVENT_ZONE_DEL = ecore_event_type_new();
99 E_EVENT_ZONE_EDGE_IN = ecore_event_type_new();
100 E_EVENT_ZONE_EDGE_OUT = ecore_event_type_new();
101 E_EVENT_ZONE_EDGE_MOVE = ecore_event_type_new();
102 #ifdef _F_ZONE_WINDOW_ROTATION_
103 E_EVENT_ZONE_ROTATION_CHANGE = ecore_event_type_new();
109 e_zone_shutdown(void)
115 e_zone_all_edge_flip_eval(void)
117 Eina_List *l, *ll, *lll;
122 EINA_LIST_FOREACH(e_manager_list(), l, man)
124 EINA_LIST_FOREACH(man->containers, ll, con)
126 EINA_LIST_FOREACH(con->zones, lll, zone)
128 e_zone_edge_flip_eval(zone);
135 _e_zone_black_new(E_Zone *zone)
140 if (zone->black_ecore_evas) return;
141 zone->black_ecore_evas = e_canvas_new(zone->container->win,
142 zone->x, zone->y, 1, 1, 1, 1,
144 e_canvas_add(zone->black_ecore_evas);
145 ecore_evas_layer_set(zone->black_ecore_evas, 6);
146 zone->black_evas = ecore_evas_get(zone->black_ecore_evas);
148 o = evas_object_rectangle_add(zone->black_evas);
149 evas_object_move(o, 0, 0);
150 evas_object_resize(o, zone->w, zone->h);
151 evas_object_color_set(o, 0, 0, 0, 255);
154 ecore_evas_name_class_set(zone->black_ecore_evas, "E", "Black_Window");
155 snprintf(name, sizeof(name), "Enlightenment Black Zone (%d)", zone->num);
156 ecore_evas_title_set(zone->black_ecore_evas, name);
160 _e_zone_black_free(E_Zone *zone)
162 if (!zone->black_ecore_evas) return;
163 e_canvas_del(zone->black_ecore_evas);
164 ecore_evas_free(zone->black_ecore_evas);
165 zone->black_ecore_evas = NULL;
170 _e_zone_black_get(E_Zone *zone)
173 if (!zone->black_ecore_evas) return;
174 if (zone->black_need == 1)
176 ecore_evas_move(zone->black_ecore_evas, zone->x, zone->y);
177 ecore_evas_resize(zone->black_ecore_evas, zone->w, zone->h);
182 _e_zone_black_unget(E_Zone *zone)
185 if (!zone->black_ecore_evas) return;
186 if (zone->black_need == 0)
188 ecore_evas_move(zone->black_ecore_evas, zone->x, zone->y);
189 ecore_evas_resize(zone->black_ecore_evas, 1, 1);
194 e_zone_new(E_Container *con,
204 E_Event_Zone_Add *ev;
207 zone = E_OBJECT_ALLOC(E_Zone, E_ZONE_TYPE, _e_zone_free);
208 if (!zone) return NULL;
210 zone->container = con;
218 e_zone_useful_geometry_dirty(zone);
220 //printf("@@@@@@@@@@ e_zone_new: %i %i | %i %i %ix%i = %p\n", num, id, x, y, w, h, zone);
223 eina_list_append(zone->handlers,
224 ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN,
225 _e_zone_cb_mouse_in, zone));
227 eina_list_append(zone->handlers,
228 ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT,
229 _e_zone_cb_mouse_out, zone));
231 eina_list_append(zone->handlers,
232 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
233 _e_zone_cb_mouse_down, zone));
235 eina_list_append(zone->handlers,
236 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
237 _e_zone_cb_mouse_up, zone));
239 eina_list_append(zone->handlers,
240 ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
241 _e_zone_cb_mouse_move, zone));
243 eina_list_append(zone->handlers,
244 ecore_event_handler_add(E_EVENT_DESK_AFTER_SHOW,
245 _e_zone_cb_desk_after_show, zone));
247 snprintf(name, sizeof(name), "Zone %d", zone->num);
248 zone->name = eina_stringshare_add(name);
250 con->zones = eina_list_append(con->zones, zone);
252 o = evas_object_rectangle_add(con->bg_evas);
253 zone->bg_clip_object = o;
254 evas_object_move(o, x, y);
255 evas_object_resize(o, w, h);
256 evas_object_color_set(o, 255, 255, 255, 255);
259 o = evas_object_rectangle_add(con->bg_evas);
260 zone->bg_event_object = o;
261 evas_object_clip_set(o, zone->bg_clip_object);
262 evas_object_move(o, x, y);
263 evas_object_resize(o, w, h);
264 evas_object_color_set(o, 0, 0, 0, 0);
265 evas_object_repeat_events_set(o, 1);
267 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _e_zone_cb_bg_mouse_down, zone);
268 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _e_zone_cb_bg_mouse_up, zone);
270 /* TODO: config the ecore_evas type. */
272 zone->desk_x_count = 0;
273 zone->desk_y_count = 0;
274 zone->desk_x_current = 0;
275 zone->desk_y_current = 0;
276 e_zone_desk_count_set(zone, e_config->zone_desks_x_count,
277 e_config->zone_desks_y_count);
279 e_object_del_attach_func_set(E_OBJECT(zone), _e_zone_object_del_attach);
281 _e_zone_black_new(zone);
283 ev = E_NEW(E_Event_Zone_Add, 1);
285 e_object_ref(E_OBJECT(ev->zone));
286 ecore_event_add(E_EVENT_ZONE_ADD, ev, _e_zone_event_add_free, NULL);
288 e_zone_all_edge_flip_eval();
293 e_zone_name_set(E_Zone *zone,
296 E_OBJECT_CHECK(zone);
297 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
299 if (zone->name) eina_stringshare_del(zone->name);
300 zone->name = eina_stringshare_add(name);
304 e_zone_move(E_Zone *zone,
308 E_Event_Zone_Move_Resize *ev;
310 E_OBJECT_CHECK(zone);
311 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
313 if ((x == zone->x) && (y == zone->y)) return;
316 evas_object_move(zone->bg_object, x, y);
317 evas_object_move(zone->bg_event_object, x, y);
318 evas_object_move(zone->bg_clip_object, x, y);
320 ev = E_NEW(E_Event_Zone_Move_Resize, 1);
322 e_object_ref(E_OBJECT(ev->zone));
323 ecore_event_add(E_EVENT_ZONE_MOVE_RESIZE, ev, _e_zone_event_move_resize_free, NULL);
325 _e_zone_edge_move_resize(zone);
326 e_zone_bg_reconfigure(zone);
327 if (zone->black_need > 0)
329 ecore_evas_move(zone->black_ecore_evas, zone->x, zone->y);
330 ecore_evas_resize(zone->black_ecore_evas, zone->w, zone->h);
332 _e_zone_border_geometry_update(zone);
336 e_zone_resize(E_Zone *zone,
340 E_Event_Zone_Move_Resize *ev;
342 E_OBJECT_CHECK(zone);
343 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
345 if ((w == zone->w) && (h == zone->h)) return;
348 evas_object_resize(zone->bg_object, w, h);
349 evas_object_resize(zone->bg_event_object, w, h);
350 evas_object_resize(zone->bg_clip_object, w, h);
352 ev = E_NEW(E_Event_Zone_Move_Resize, 1);
354 e_object_ref(E_OBJECT(ev->zone));
355 ecore_event_add(E_EVENT_ZONE_MOVE_RESIZE, ev,
356 _e_zone_event_move_resize_free, NULL);
358 _e_zone_edge_move_resize(zone);
359 e_zone_bg_reconfigure(zone);
360 if (zone->black_need > 0)
362 ecore_evas_move(zone->black_ecore_evas, zone->x, zone->y);
363 ecore_evas_resize(zone->black_ecore_evas, zone->w, zone->h);
365 _e_zone_border_geometry_update(zone);
369 e_zone_move_resize(E_Zone *zone,
375 E_Event_Zone_Move_Resize *ev;
377 E_OBJECT_CHECK(zone);
378 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
380 if ((x == zone->x) && (y == zone->y) && (w == zone->w) && (h == zone->h))
388 evas_object_move(zone->bg_object, x, y);
389 evas_object_move(zone->bg_event_object, x, y);
390 evas_object_move(zone->bg_clip_object, x, y);
391 evas_object_resize(zone->bg_object, w, h);
392 evas_object_resize(zone->bg_event_object, w, h);
393 evas_object_resize(zone->bg_clip_object, w, h);
395 ev = E_NEW(E_Event_Zone_Move_Resize, 1);
397 e_object_ref(E_OBJECT(ev->zone));
398 ecore_event_add(E_EVENT_ZONE_MOVE_RESIZE, ev,
399 _e_zone_event_move_resize_free, NULL);
401 _e_zone_edge_move_resize(zone);
403 e_zone_bg_reconfigure(zone);
404 if (zone->black_need > 0)
406 ecore_evas_move(zone->black_ecore_evas, zone->x, zone->y);
407 ecore_evas_resize(zone->black_ecore_evas, zone->w, zone->h);
409 _e_zone_border_geometry_update(zone);
413 e_zone_fullscreen_set(E_Zone *zone,
416 E_OBJECT_CHECK(zone);
417 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
419 if ((!zone->fullscreen) && (on))
421 _e_zone_black_get(zone);
422 ecore_evas_show(zone->black_ecore_evas);
423 e_container_window_raise(zone->container, zone->black_win, 150);
424 zone->fullscreen = 1;
426 else if ((zone->fullscreen) && (!on))
428 ecore_evas_hide(zone->black_ecore_evas);
429 zone->fullscreen = 0;
430 _e_zone_black_unget(zone);
435 e_zone_current_get(E_Container *con)
440 E_OBJECT_CHECK_RETURN(con, NULL);
441 E_OBJECT_TYPE_CHECK_RETURN(con, E_CONTAINER_TYPE, NULL);
446 ecore_x_pointer_xy_get(con->win, &x, &y);
447 EINA_LIST_FOREACH(con->zones, l, zone)
449 if (E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h))
453 if (!con->zones) return NULL;
454 return (E_Zone *)eina_list_data_get(con->zones);
458 e_zone_bg_reconfigure(E_Zone *zone)
460 E_OBJECT_CHECK(zone);
461 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
463 e_bg_zone_update(zone, E_BG_TRANSITION_CHANGE);
467 e_zone_flip_coords_handle(E_Zone *zone,
471 E_Event_Zone_Edge *zev;
472 E_Binding_Edge *binding;
480 E_OBJECT_CHECK(zone);
481 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
483 if (!e_config->edge_flip_dragging || zone->flip.switching) return;
484 /* if we have only 1 row we can flip up/down even if we have xinerama */
485 if (eina_list_count(zone->container->zones) > 1)
491 zones = zone->container->zones;
492 next_zone = (E_Zone *)eina_list_data_get(zones);
495 zones = eina_list_next(zones);
496 EINA_LIST_FOREACH(eina_list_next(zones), zones, next_zone)
498 if (next_zone->x != cx) one_col = 0;
499 if (next_zone->y != cy) one_row = 0;
502 if (eina_list_count(zone->container->manager->containers) > 1)
504 if (!E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h))
506 if ((one_row) && (y == 0))
507 edge = E_ZONE_EDGE_TOP;
508 else if ((one_col) && (x == (zone->w - 1)))
509 edge = E_ZONE_EDGE_RIGHT;
510 else if ((one_row) && (y == (zone->h - 1)))
511 edge = E_ZONE_EDGE_BOTTOM;
512 else if ((one_col) && (x == 0))
513 edge = E_ZONE_EDGE_LEFT;
518 e_shelf_toggle(zone->flip.es, 0);
519 zone->flip.es = NULL;
522 EINA_LIST_FOREACH(e_shelf_list(), l, es)
524 if (es->zone != zone) continue;
525 switch (es->gadcon->orient)
527 case E_GADCON_ORIENT_TOP:
528 case E_GADCON_ORIENT_CORNER_TL:
529 case E_GADCON_ORIENT_CORNER_TR:
530 if (edge == E_ZONE_EDGE_TOP) ok = 1;
533 case E_GADCON_ORIENT_BOTTOM:
534 case E_GADCON_ORIENT_CORNER_BL:
535 case E_GADCON_ORIENT_CORNER_BR:
536 if (edge == E_ZONE_EDGE_BOTTOM) ok = 1;
539 case E_GADCON_ORIENT_LEFT:
540 case E_GADCON_ORIENT_CORNER_LT:
541 case E_GADCON_ORIENT_CORNER_LB:
542 if (edge == E_ZONE_EDGE_LEFT) ok = 1;
545 case E_GADCON_ORIENT_RIGHT:
546 case E_GADCON_ORIENT_CORNER_RT:
547 case E_GADCON_ORIENT_CORNER_RB:
548 if (edge == E_ZONE_EDGE_RIGHT) ok = 1;
557 if (!E_INSIDE(x, y, es->x, es->y, es->w, es->h))
561 e_shelf_toggle(zone->flip.es, 0);
564 e_shelf_toggle(es, 1);
568 case E_ZONE_EDGE_LEFT:
569 if (E_ZONE_FLIP_LEFT(zone)) ok = 1;
572 case E_ZONE_EDGE_TOP:
573 if (E_ZONE_FLIP_UP(zone)) ok = 1;
576 case E_ZONE_EDGE_RIGHT:
577 if (E_ZONE_FLIP_RIGHT(zone)) ok = 1;
580 case E_ZONE_EDGE_BOTTOM:
581 if (E_ZONE_FLIP_DOWN(zone)) ok = 1;
589 binding = e_bindings_edge_get("desk_flip_in_direction", edge, 0);
590 if (!binding) binding = e_bindings_edge_get("desk_flip_by", edge, 0);
591 if (binding && (!binding->timer))
593 zev = E_NEW(E_Event_Zone_Edge, 1);
599 zone->flip.bind = binding;
600 zone->flip.switching = 1;
601 binding->timer = ecore_timer_add(((double)binding->delay), _e_zone_cb_edge_timer, zone);
606 e_zone_desk_count_set(E_Zone *zone,
611 E_Desk *desk, *new_desk;
613 E_Event_Zone_Desk_Count_Set *ev;
615 int x, y, xx, yy, moved, nx, ny;
617 E_OBJECT_CHECK(zone);
618 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
625 /* Orphaned window catcher; in case desk count gets reset */
627 if (zone->desk_x_current >= xx) moved = 1;
628 if (zone->desk_y_current >= yy) moved = 1;
631 nx = zone->desk_x_current;
632 ny = zone->desk_y_current;
633 if (zone->desk_x_current >= xx) nx = xx - 1;
634 if (zone->desk_y_current >= yy) ny = yy - 1;
635 e_desk_show(e_desk_at_xy_get(zone, nx, ny));
638 new_desks = malloc(xx * yy * sizeof(E_Desk *));
639 for (x = 0; x < xx; x++)
641 for (y = 0; y < yy; y++)
643 if ((x < zone->desk_x_count) && (y < zone->desk_y_count))
644 desk = zone->desks[x + (y * zone->desk_x_count)];
646 desk = e_desk_new(zone, x, y);
647 new_desks[x + (y * xx)] = desk;
651 /* catch windoes that have fallen off the end if we got smaller */
652 if (xx < zone->desk_x_count)
654 for (y = 0; y < zone->desk_y_count; y++)
656 new_desk = zone->desks[xx - 1 + (y * zone->desk_x_count)];
657 for (x = xx; x < zone->desk_x_count; x++)
659 desk = zone->desks[x + (y * zone->desk_x_count)];
661 bl = e_container_border_list_first(zone->container);
662 while ((bd = e_container_border_list_next(bl)))
664 if (bd->desk == desk)
665 e_border_desk_set(bd, new_desk);
667 e_container_border_list_free(bl);
668 e_object_del(E_OBJECT(desk));
672 if (yy < zone->desk_y_count)
674 for (x = 0; x < zone->desk_x_count; x++)
676 new_desk = zone->desks[x + ((yy - 1) * zone->desk_x_count)];
677 for (y = yy; y < zone->desk_y_count; y++)
679 desk = zone->desks[x + (y * zone->desk_x_count)];
681 bl = e_container_border_list_first(zone->container);
682 while ((bd = e_container_border_list_next(bl)))
684 if (bd->desk == desk)
685 e_border_desk_set(bd, new_desk);
687 e_container_border_list_free(bl);
688 e_object_del(E_OBJECT(desk));
692 if (zone->desks) free(zone->desks);
693 zone->desks = new_desks;
695 zone->desk_x_count = xx;
696 zone->desk_y_count = yy;
697 e_config->zone_desks_x_count = xx;
698 e_config->zone_desks_y_count = yy;
699 e_config_save_queue();
701 /* Cannot call desk_current_get until the zone desk counts have been set
702 * or else we end up with a "white background" because desk_current_get will
705 desk = e_desk_current_get(zone);
712 e_zone_edge_flip_eval(zone);
714 ev = E_NEW(E_Event_Zone_Desk_Count_Set, 1);
717 e_object_ref(E_OBJECT(ev->zone));
718 ecore_event_add(E_EVENT_ZONE_DESK_COUNT_SET, ev,
719 _e_zone_event_zone_desk_count_set_free, NULL);
723 e_zone_desk_count_get(E_Zone *zone,
727 E_OBJECT_CHECK(zone);
728 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
730 if (x_count) *x_count = zone->desk_x_count;
731 if (y_count) *y_count = zone->desk_y_count;
735 e_zone_desk_flip_by(E_Zone *zone,
739 E_OBJECT_CHECK(zone);
740 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
742 dx = zone->desk_x_current + dx;
743 dy = zone->desk_y_current + dy;
744 e_zone_desk_flip_to(zone, dx, dy);
745 e_zone_edge_flip_eval(zone);
749 e_zone_desk_flip_to(E_Zone *zone,
755 E_OBJECT_CHECK(zone);
756 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
758 if (e_config->desk_flip_wrap)
760 x = x % zone->desk_x_count;
761 y = y % zone->desk_y_count;
762 if (x < 0) x += zone->desk_x_count;
763 if (y < 0) y += zone->desk_y_count;
768 else if (x >= zone->desk_x_count)
769 x = zone->desk_x_count - 1;
771 else if (y >= zone->desk_y_count)
772 y = zone->desk_y_count - 1;
774 desk = e_desk_at_xy_get(zone, x, y);
775 if (desk) e_desk_show(desk);
776 e_zone_edge_flip_eval(zone);
780 e_zone_desk_linear_flip_by(E_Zone *zone,
783 E_OBJECT_CHECK(zone);
784 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
786 dx = zone->desk_x_current +
787 (zone->desk_y_current * zone->desk_x_count) + dx;
788 dx = dx % (zone->desk_x_count * zone->desk_y_count);
790 dx += (zone->desk_x_count * zone->desk_y_count);
791 e_zone_desk_linear_flip_to(zone, dx);
792 e_zone_edge_flip_eval(zone);
796 e_zone_desk_linear_flip_to(E_Zone *zone,
801 E_OBJECT_CHECK(zone);
802 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
804 y = x / zone->desk_x_count;
805 x = x - (y * zone->desk_x_count);
806 e_zone_desk_flip_to(zone, x, y);
807 e_zone_edge_flip_eval(zone);
811 e_zone_edge_enable(void)
813 Eina_List *l, *ll, *lll;
818 EINA_LIST_FOREACH(e_manager_list(), l, man)
820 EINA_LIST_FOREACH(man->containers, ll, con)
822 EINA_LIST_FOREACH(con->zones, lll, zone)
824 if (zone->edge.left) ecore_x_window_show(zone->edge.left);
825 if (zone->edge.right) ecore_x_window_show(zone->edge.right);
826 if (zone->edge.top) ecore_x_window_show(zone->edge.top);
827 if (zone->edge.bottom) ecore_x_window_show(zone->edge.bottom);
828 if (zone->corner.left_top) ecore_x_window_show(zone->corner.left_top);
829 if (zone->corner.top_left) ecore_x_window_show(zone->corner.top_left);
830 if (zone->corner.top_right) ecore_x_window_show(zone->corner.top_right);
831 if (zone->corner.right_top) ecore_x_window_show(zone->corner.right_top);
832 if (zone->corner.right_bottom) ecore_x_window_show(zone->corner.right_bottom);
833 if (zone->corner.bottom_right) ecore_x_window_show(zone->corner.bottom_right);
834 if (zone->corner.bottom_left) ecore_x_window_show(zone->corner.bottom_left);
835 if (zone->corner.left_bottom) ecore_x_window_show(zone->corner.left_bottom);
836 e_zone_edge_flip_eval(zone);
843 e_zone_edge_disable(void)
845 Eina_List *l, *ll, *lll;
850 EINA_LIST_FOREACH(e_manager_list(), l, man)
852 EINA_LIST_FOREACH(man->containers, ll, con)
854 EINA_LIST_FOREACH(con->zones, lll, zone)
856 if (zone->edge.left) ecore_x_window_hide(zone->edge.left);
857 if (zone->edge.right) ecore_x_window_hide(zone->edge.right);
858 if (zone->edge.top) ecore_x_window_hide(zone->edge.top);
859 if (zone->edge.bottom) ecore_x_window_hide(zone->edge.bottom);
860 if (zone->corner.left_top) ecore_x_window_hide(zone->corner.left_top);
861 if (zone->corner.top_left) ecore_x_window_hide(zone->corner.top_left);
862 if (zone->corner.top_right) ecore_x_window_hide(zone->corner.top_right);
863 if (zone->corner.right_top) ecore_x_window_hide(zone->corner.right_top);
864 if (zone->corner.right_bottom) ecore_x_window_hide(zone->corner.right_bottom);
865 if (zone->corner.bottom_right) ecore_x_window_hide(zone->corner.bottom_right);
866 if (zone->corner.bottom_left) ecore_x_window_hide(zone->corner.bottom_left);
867 if (zone->corner.left_bottom) ecore_x_window_hide(zone->corner.left_bottom);
874 e_zone_edges_desk_flip_capable(E_Zone *zone, Eina_Bool l, Eina_Bool r, Eina_Bool t, Eina_Bool b)
876 #define NEED_FLIP_EDGE(x) \
877 (e_bindings_edge_flippable_get(x) || e_bindings_edge_non_flippable_get(x))
878 #define NEED_EDGE(x) \
879 (e_bindings_edge_non_flippable_get(x))
880 #define CHECK_EDGE(v, ed, win) \
883 if (NEED_FLIP_EDGE(ed)) { if (zone->edge.win) ecore_x_window_show(zone->edge.win); } \
884 else if (zone->edge.win) ecore_x_window_hide(zone->edge.win); \
887 if (NEED_EDGE(ed)) { if (zone->edge.win) ecore_x_window_show(zone->edge.win); } \
888 else if (zone->edge.win) ecore_x_window_hide(zone->edge.win); \
892 CHECK_EDGE(l, E_ZONE_EDGE_LEFT, left);
893 CHECK_EDGE(r, E_ZONE_EDGE_RIGHT, right);
894 CHECK_EDGE(t, E_ZONE_EDGE_TOP, top);
895 CHECK_EDGE(b, E_ZONE_EDGE_BOTTOM, bottom);
897 #define CHECK_CORNER(v1, v2, ed, win1, win2) \
898 if ((!v1) && (!v2)) { \
899 if (NEED_EDGE(ed)) { \
900 if (zone->corner.win1) ecore_x_window_show(zone->corner.win1); \
901 if (zone->corner.win2) ecore_x_window_show(zone->corner.win2); \
904 if (zone->corner.win1) ecore_x_window_hide(zone->corner.win1); \
905 if (zone->corner.win2) ecore_x_window_hide(zone->corner.win2); \
909 if (NEED_FLIP_EDGE(ed)) { \
910 if (zone->corner.win1) ecore_x_window_show(zone->corner.win1); \
911 if (zone->corner.win2) ecore_x_window_show(zone->corner.win2); \
914 if (zone->corner.win1) ecore_x_window_hide(zone->corner.win1); \
915 if (zone->corner.win2) ecore_x_window_hide(zone->corner.win2); \
919 CHECK_CORNER(l, t, E_ZONE_EDGE_TOP_LEFT, left_top, top_left);
920 CHECK_CORNER(r, t, E_ZONE_EDGE_TOP_RIGHT, right_top, top_right);
921 CHECK_CORNER(l, b, E_ZONE_EDGE_BOTTOM_LEFT, left_bottom, bottom_left);
922 CHECK_CORNER(r, b, E_ZONE_EDGE_BOTTOM_RIGHT, right_bottom, bottom_right);
926 e_zone_exists_direction(E_Zone *zone, E_Zone_Edge edge)
931 EINA_LIST_FOREACH(zone->container->zones, l, z2)
933 if (zone == z2) continue;
937 case E_ZONE_EDGE_TOP_LEFT:
938 if (((E_SPANS_COMMON(0, zone->x + zone->w, z2->x, z2->w)) &&
939 (z2->y < zone->y)) ||
940 ((E_SPANS_COMMON(0, zone->y + zone->h, z2->y, z2->h)) &&
944 case E_ZONE_EDGE_TOP:
945 if ((E_SPANS_COMMON(zone->x, zone->w, z2->x, z2->w)) &&
949 case E_ZONE_EDGE_TOP_RIGHT:
950 if (((E_SPANS_COMMON(zone->x, 99999, z2->x, z2->w)) &&
951 (z2->y < zone->y)) ||
952 ((E_SPANS_COMMON(0, zone->y + zone->h, z2->y, z2->h)) &&
953 (z2->x >= (zone->x + zone->w))))
957 case E_ZONE_EDGE_LEFT:
958 if ((E_SPANS_COMMON(zone->y, zone->h, z2->y, z2->h)) &&
963 case E_ZONE_EDGE_RIGHT:
964 if ((E_SPANS_COMMON(zone->y, zone->h, z2->y, z2->h)) &&
965 (z2->x >= (zone->x + zone->w)))
969 case E_ZONE_EDGE_BOTTOM_LEFT:
970 if (((E_SPANS_COMMON(0, zone->x + zone->w, z2->x, z2->w)) &&
971 (z2->y >= (zone->y + zone->h))) ||
972 ((E_SPANS_COMMON(zone->y, 99999, z2->y, z2->h)) &&
976 case E_ZONE_EDGE_BOTTOM:
977 if ((E_SPANS_COMMON(zone->x, zone->w, z2->x, z2->w)) &&
978 (z2->y >= (zone->y + zone->h)))
981 case E_ZONE_EDGE_BOTTOM_RIGHT:
982 if (((E_SPANS_COMMON(zone->x, 99999, z2->x, z2->w)) &&
983 (z2->y >= (zone->y + zone->h))) ||
984 ((E_SPANS_COMMON(zone->y, 99999, z2->y, z2->h)) &&
999 e_zone_edge_flip_eval(E_Zone *zone)
1001 Eina_Bool lf, rf, tf, bf;
1003 lf = rf = tf = bf = EINA_TRUE;
1004 if (zone->desk_x_count <= 1) lf = rf = EINA_FALSE;
1005 else if (!e_config->desk_flip_wrap)
1007 if (zone->desk_x_current == 0) lf = EINA_FALSE;
1008 if (zone->desk_x_current == (zone->desk_x_count - 1)) rf = EINA_FALSE;
1010 if (zone->desk_y_count <= 1) tf = bf = EINA_FALSE;
1011 else if (!e_config->desk_flip_wrap)
1013 if (zone->desk_y_current == 0) tf = EINA_FALSE;
1014 if (zone->desk_y_current == (zone->desk_y_count - 1)) bf = EINA_FALSE;
1016 e_zone_edges_desk_flip_capable(zone, lf, rf, tf, bf);
1020 e_zone_edge_new(E_Zone_Edge edge)
1022 Eina_List *l, *ll, *lll;
1028 // configurably disallow edge bindings when we have more than 1 root
1029 // window (ie pure old multihead) since we don't know which direction
1030 // other root windows are in
1031 if ((!e_config->multiscreen_flip) && (eina_list_count(e_manager_list()) > 1)) return;
1032 EINA_LIST_FOREACH(e_manager_list(), l, man)
1034 EINA_LIST_FOREACH(man->containers, ll, con)
1036 EINA_LIST_FOREACH(con->zones, lll, zone)
1038 // don't allow bindings on edges that are on the boundary
1040 if (e_zone_exists_direction(zone, edge)) continue;
1041 cw = zone->w * E_ZONE_CORNER_RATIO;
1042 ch = zone->h * E_ZONE_CORNER_RATIO;
1045 case E_ZONE_EDGE_NONE:
1049 case E_ZONE_EDGE_LEFT:
1050 if (!zone->edge.left)
1052 zone->edge.left = ecore_x_window_input_new(con->win,
1053 zone->x, zone->y + ch, 1,
1055 ecore_x_window_show(zone->edge.left);
1059 case E_ZONE_EDGE_RIGHT:
1060 if (!zone->edge.right)
1062 zone->edge.right = ecore_x_window_input_new(con->win,
1063 zone->x + zone->w - 1,
1064 zone->y + ch, 1, zone->h - 2 * ch);
1065 ecore_x_window_show(zone->edge.right);
1069 case E_ZONE_EDGE_TOP:
1070 if (!zone->edge.top)
1072 zone->edge.top = ecore_x_window_input_new(con->win,
1073 zone->x + 1 + cw, zone->y,
1074 zone->w - 2 * cw - 2, 1);
1075 ecore_x_window_show(zone->edge.top);
1079 case E_ZONE_EDGE_BOTTOM:
1080 if (!zone->edge.bottom)
1082 zone->edge.bottom = ecore_x_window_input_new(con->win,
1083 zone->x + 1 + cw, zone->y + zone->h - 1,
1084 zone->w - 2 - 2 * cw, 1);
1085 ecore_x_window_show(zone->edge.bottom);
1089 case E_ZONE_EDGE_TOP_LEFT:
1090 if (!zone->corner.left_top)
1092 zone->corner.left_top = ecore_x_window_input_new(con->win,
1093 zone->x, zone->y, 1, ch);
1094 ecore_x_window_show(zone->corner.left_top);
1096 if (!zone->corner.top_left)
1098 zone->corner.top_left = ecore_x_window_input_new(con->win,
1099 zone->x + 1, zone->y, cw, 1);
1100 ecore_x_window_show(zone->corner.top_left);
1104 case E_ZONE_EDGE_TOP_RIGHT:
1105 if (!zone->corner.top_right)
1107 zone->corner.top_right = ecore_x_window_input_new(con->win,
1108 zone->x + zone->w - cw - 2,
1110 ecore_x_window_show(zone->corner.top_right);
1112 if (!zone->corner.right_top)
1114 zone->corner.right_top = ecore_x_window_input_new(con->win,
1115 zone->x + zone->w - 1,
1117 ecore_x_window_show(zone->corner.right_top);
1121 case E_ZONE_EDGE_BOTTOM_RIGHT:
1122 if (!zone->corner.right_bottom)
1124 zone->corner.right_bottom = ecore_x_window_input_new(con->win,
1125 zone->x + zone->w - 1,
1126 zone->y + zone->h - ch, 1, ch);
1127 ecore_x_window_show(zone->corner.right_bottom);
1129 if (!zone->corner.bottom_right)
1131 zone->corner.bottom_right = ecore_x_window_input_new(con->win,
1132 zone->x + zone->w - cw - 2,
1133 zone->y + zone->h - 1, cw, 1);
1135 ecore_x_window_show(zone->corner.bottom_right);
1139 case E_ZONE_EDGE_BOTTOM_LEFT:
1140 if (!zone->corner.bottom_left)
1142 zone->corner.bottom_left = ecore_x_window_input_new(con->win,
1144 zone->y + zone->h - 1, cw, 1);
1145 ecore_x_window_show(zone->corner.bottom_left);
1147 if (!zone->corner.left_bottom)
1149 zone->corner.left_bottom = ecore_x_window_input_new(con->win,
1150 zone->x, zone->y + zone->h - ch,
1152 ecore_x_window_show(zone->corner.left_bottom);
1156 if (e_config->fullscreen_flip)
1157 e_zone_edge_win_layer_set(zone, 250);
1159 e_zone_edge_win_layer_set(zone, 200);
1166 e_zone_edge_free(E_Zone_Edge edge)
1168 Eina_List *l, *ll, *lll;
1173 EINA_LIST_FOREACH(e_manager_list(), l, man)
1175 EINA_LIST_FOREACH(man->containers, ll, con)
1177 EINA_LIST_FOREACH(con->zones, lll, zone)
1181 case E_ZONE_EDGE_NONE:
1185 case E_ZONE_EDGE_LEFT:
1186 if (zone->edge.left) ecore_x_window_free(zone->edge.left);
1187 zone->edge.left = 0;
1190 case E_ZONE_EDGE_RIGHT:
1191 if (zone->edge.right) ecore_x_window_free(zone->edge.right);
1192 zone->edge.right = 0;
1195 case E_ZONE_EDGE_TOP:
1196 if (zone->edge.top) ecore_x_window_free(zone->edge.top);
1200 case E_ZONE_EDGE_BOTTOM:
1201 if (zone->edge.bottom) ecore_x_window_free(zone->edge.bottom);
1202 zone->edge.bottom = 0;
1205 case E_ZONE_EDGE_TOP_LEFT:
1206 if (zone->corner.left_top) ecore_x_window_free(zone->corner.left_top);
1207 if (zone->corner.top_left) ecore_x_window_free(zone->corner.top_left);
1208 zone->corner.left_top = 0;
1209 zone->corner.top_left = 0;
1212 case E_ZONE_EDGE_TOP_RIGHT:
1213 if (zone->corner.top_right) ecore_x_window_free(zone->corner.top_right);
1214 if (zone->corner.right_top) ecore_x_window_free(zone->corner.right_top);
1215 zone->corner.top_right = 0;
1216 zone->corner.right_top = 0;
1219 case E_ZONE_EDGE_BOTTOM_RIGHT:
1220 if (zone->corner.right_bottom) ecore_x_window_free(zone->corner.right_bottom);
1221 if (zone->corner.bottom_right) ecore_x_window_free(zone->corner.bottom_right);
1222 zone->corner.right_bottom = 0;
1223 zone->corner.bottom_right = 0;
1226 case E_ZONE_EDGE_BOTTOM_LEFT:
1227 if (zone->corner.bottom_left) ecore_x_window_free(zone->corner.bottom_left);
1228 if (zone->corner.left_bottom) ecore_x_window_free(zone->corner.left_bottom);
1229 zone->corner.bottom_left = 0;
1230 zone->corner.left_bottom = 0;
1239 e_zone_edge_win_layer_set(E_Zone *zone,
1242 if (zone->corner.left_bottom) e_container_window_raise(zone->container, zone->corner.left_bottom, layer);
1243 if (zone->corner.left_top) e_container_window_raise(zone->container, zone->corner.left_top, layer);
1244 if (zone->corner.top_left) e_container_window_raise(zone->container, zone->corner.top_left, layer);
1245 if (zone->corner.top_right) e_container_window_raise(zone->container, zone->corner.top_right, layer);
1246 if (zone->corner.right_top) e_container_window_raise(zone->container, zone->corner.right_top, layer);
1247 if (zone->corner.right_bottom) e_container_window_raise(zone->container, zone->corner.right_bottom, layer);
1248 if (zone->corner.bottom_right) e_container_window_raise(zone->container, zone->corner.bottom_right, layer);
1249 if (zone->corner.bottom_left) e_container_window_raise(zone->container, zone->corner.bottom_left, layer);
1251 if (zone->edge.left) e_container_window_raise(zone->container, zone->edge.left, layer);
1252 if (zone->edge.right) e_container_window_raise(zone->container, zone->edge.right, layer);
1253 if (zone->edge.top) e_container_window_raise(zone->container, zone->edge.top, layer);
1254 if (zone->edge.bottom) e_container_window_raise(zone->container, zone->edge.bottom, layer);
1258 _e_zone_useful_geometry_calc(E_Zone *zone)
1260 const E_Shelf *shelf;
1262 int x0, x1, yy0, yy1;
1268 shelves = e_shelf_list_all();
1269 EINA_LIST_FREE(shelves, shelf)
1271 E_Config_Shelf_Desk *sd;
1272 E_Gadcon_Orient orient;
1276 if (shelf->zone != zone)
1281 if (shelf->cfg->overlap)
1284 if (shelf->cfg->autohide)
1286 orient = shelf->cfg->orient;
1288 if (shelf->cfg->desk_show_mode)
1291 EINA_LIST_FOREACH(shelf->cfg->desk_list, ll, sd)
1294 if ((sd->x == zone->desk_x_current) && (sd->y == zone->desk_y_current))
1305 orient = shelf->gadcon->orient;
1309 /* these are non-edje orientations */
1310 case E_GADCON_ORIENT_FLOAT:
1311 case E_GADCON_ORIENT_HORIZ:
1312 case E_GADCON_ORIENT_VERT:
1315 case E_GADCON_ORIENT_TOP:
1316 case E_GADCON_ORIENT_CORNER_TL:
1317 case E_GADCON_ORIENT_CORNER_TR:
1322 case E_GADCON_ORIENT_BOTTOM:
1323 case E_GADCON_ORIENT_CORNER_BL:
1324 case E_GADCON_ORIENT_CORNER_BR:
1325 if (yy1 > zone->h - shelf->h)
1326 yy1 = zone->h - shelf->h;
1330 case E_GADCON_ORIENT_LEFT:
1331 case E_GADCON_ORIENT_CORNER_LT:
1332 case E_GADCON_ORIENT_CORNER_LB:
1337 case E_GADCON_ORIENT_RIGHT:
1338 case E_GADCON_ORIENT_CORNER_RT:
1339 case E_GADCON_ORIENT_CORNER_RB:
1340 if (x1 > zone->w - shelf->w)
1341 x1 = zone->w - shelf->w;
1348 zone->useful_geometry.x = zone->x + x0;
1349 zone->useful_geometry.y = zone->y + yy0;
1350 zone->useful_geometry.w = x1 - x0;
1351 zone->useful_geometry.h = yy1 - yy0;
1352 zone->useful_geometry.dirty = 0;
1356 * Get (or calculate) the useful (or free, without any shelves) area.
1359 e_zone_useful_geometry_get(E_Zone *zone,
1368 E_OBJECT_CHECK(zone);
1369 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1371 if (!zone->useful_geometry.dirty)
1373 EINA_LIST_FOREACH(e_shelf_list(), l, shelf)
1375 if (!shelf->cfg) continue;
1376 if (shelf->cfg->desk_show_mode)
1378 _e_zone_useful_geometry_calc(zone);
1384 _e_zone_useful_geometry_calc(zone);
1386 if (x) *x = zone->useful_geometry.x;
1387 if (y) *y = zone->useful_geometry.y;
1388 if (w) *w = zone->useful_geometry.w;
1389 if (h) *h = zone->useful_geometry.h;
1393 * Mark as dirty so e_zone_useful_geometry_get() will need to recalculate.
1395 * Call this function when shelves are added or important properties changed.
1398 e_zone_useful_geometry_dirty(E_Zone *zone)
1400 E_Event_Zone_Move_Resize *ev;
1402 E_OBJECT_CHECK(zone);
1403 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1405 ev = E_NEW(E_Event_Zone_Move_Resize, 1);
1407 e_object_ref(E_OBJECT(ev->zone));
1408 ecore_event_add(E_EVENT_ZONE_MOVE_RESIZE, ev, _e_zone_event_move_resize_free, NULL);
1410 zone->useful_geometry.dirty = 1;
1411 zone->useful_geometry.x = -1;
1412 zone->useful_geometry.y = -1;
1413 zone->useful_geometry.w = -1;
1414 zone->useful_geometry.h = -1;
1417 #ifdef _F_ZONE_WINDOW_ROTATION_
1419 e_zone_rotation_set(E_Zone *zone,
1422 E_Event_Zone_Rotation_Change *ev;
1424 E_OBJECT_CHECK(zone);
1425 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1426 if (!e_config->wm_win_rotation) return;
1428 ELBF(ELBT_ROT, 0, zone->num, "SET ROT a%d", rot);
1430 if ((zone->rot.wait_for_done) ||
1431 (zone->rot.block_count > 0))
1433 zone->rot.next = rot;
1434 zone->rot.pending = EINA_TRUE;
1437 if (zone->rot.curr == rot) return;
1439 zone->rot.prev = zone->rot.curr;
1440 zone->rot.curr = rot;
1441 zone->rot.wait_for_done = EINA_TRUE;
1443 ev = E_NEW(E_Event_Zone_Rotation_Change, 1);
1445 e_object_ref(E_OBJECT(ev->zone));
1446 ecore_event_add(E_EVENT_ZONE_ROTATION_CHANGE, ev, _e_zone_event_rotation_change_free, NULL);
1448 ELBF(ELBT_ROT, 0, zone->num, "CHANGE ROT a%d", zone->rot.curr);
1452 e_zone_rotation_get(E_Zone *zone)
1454 E_OBJECT_CHECK(zone);
1455 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1456 return zone->rot.curr;
1460 e_zone_rotation_block_set(E_Zone *zone, const char *name_hint, Eina_Bool set)
1462 E_Event_Zone_Rotation_Change *ev;
1464 E_OBJECT_CHECK_RETURN(zone, EINA_FALSE);
1465 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, EINA_FALSE);
1467 if (set) zone->rot.block_count++;
1468 else zone->rot.block_count--;
1470 ELBF(ELBT_ROT, 0, zone->num, "[%s ROT] count: %d, from %s",
1471 set ? "PAUSE" : "RESUME", zone->rot.block_count, name_hint);
1473 if (zone->rot.block_count <= 0)
1475 zone->rot.block_count = 0;
1476 if (zone->rot.pending)
1478 zone->rot.prev = zone->rot.curr;
1479 zone->rot.curr = zone->rot.next;
1480 zone->rot.pending = EINA_FALSE;
1482 ev = E_NEW(E_Event_Zone_Rotation_Change, 1);
1484 e_object_ref(E_OBJECT(ev->zone));
1485 ecore_event_add(E_EVENT_ZONE_ROTATION_CHANGE, ev, _e_zone_event_rotation_change_free, NULL);
1487 ELBF(ELBT_ROT, 0, zone->num, "CHANGE ROT(pending) a%d", zone->rot.curr);
1495 e_zone_rotation_update_done(E_Zone *zone)
1497 E_Event_Zone_Rotation_Change *ev;
1499 E_OBJECT_CHECK(zone);
1500 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1501 if (!e_config->wm_win_rotation) return;
1503 ELBF(ELBT_ROT, 0, zone->num, "DONE ROT a%d", zone->rot.curr);
1505 zone->rot.wait_for_done = EINA_FALSE;
1506 if ((zone->rot.pending) &&
1507 (zone->rot.block_count == 0))
1509 zone->rot.prev = zone->rot.curr;
1510 zone->rot.curr = zone->rot.next;
1511 zone->rot.pending = EINA_FALSE;
1513 ev = E_NEW(E_Event_Zone_Rotation_Change, 1);
1515 e_object_ref(E_OBJECT(ev->zone));
1516 ecore_event_add(E_EVENT_ZONE_ROTATION_CHANGE, ev, _e_zone_event_rotation_change_free, NULL);
1518 ELBF(ELBT_ROT, 0, zone->num, "CHANGE ROT(pending) a%d", zone->rot.curr);
1523 e_zone_rotation_update_cancel(E_Zone *zone)
1525 E_OBJECT_CHECK(zone);
1526 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1527 if (!e_config->wm_win_rotation) return;
1529 zone->rot.wait_for_done = EINA_FALSE;
1530 if (zone->rot.pending)
1532 zone->rot.prev = zone->rot.curr;
1533 zone->rot.curr = zone->rot.next;
1534 zone->rot.pending = EINA_FALSE;
1537 ELBF(ELBT_ROT, 0, zone->num, "CANCEL ROT a%d", zone->rot.curr);
1541 /* local subsystem functions */
1543 _e_zone_free(E_Zone *zone)
1548 //printf("@@@@@@@@@@ e_zone_free: %i %i | %i %i %ix%i = %p\n", zone->num, zone->id, zone->x, zone->y, zone->w, zone->h, zone);
1549 /* Delete the edge windows if they exist */
1550 if (zone->edge.top) ecore_x_window_free(zone->edge.top);
1551 if (zone->edge.bottom) ecore_x_window_free(zone->edge.bottom);
1552 if (zone->edge.left) ecore_x_window_free(zone->edge.left);
1553 if (zone->edge.right) ecore_x_window_free(zone->edge.right);
1554 if (zone->corner.left_bottom) ecore_x_window_free(zone->corner.left_bottom);
1555 if (zone->corner.left_top) ecore_x_window_free(zone->corner.left_top);
1556 if (zone->corner.top_left) ecore_x_window_free(zone->corner.top_left);
1557 if (zone->corner.top_right) ecore_x_window_free(zone->corner.top_right);
1558 if (zone->corner.right_top) ecore_x_window_free(zone->corner.right_top);
1559 if (zone->corner.right_bottom) ecore_x_window_free(zone->corner.right_bottom);
1560 if (zone->corner.bottom_right) ecore_x_window_free(zone->corner.bottom_right);
1561 if (zone->corner.bottom_left) ecore_x_window_free(zone->corner.bottom_left);
1563 /* Delete the object event callbacks */
1564 evas_object_event_callback_del(zone->bg_event_object,
1565 EVAS_CALLBACK_MOUSE_DOWN,
1566 _e_zone_cb_bg_mouse_down);
1567 evas_object_event_callback_del(zone->bg_event_object,
1568 EVAS_CALLBACK_MOUSE_UP,
1569 _e_zone_cb_bg_mouse_up);
1571 if (zone->black_ecore_evas)
1573 e_canvas_del(zone->black_ecore_evas);
1574 ecore_evas_free(zone->black_ecore_evas);
1575 zone->black_ecore_evas = NULL;
1577 if (zone->cur_mouse_action)
1579 e_object_unref(E_OBJECT(zone->cur_mouse_action));
1580 zone->cur_mouse_action = NULL;
1583 /* remove handlers */
1584 E_FREE_LIST(zone->handlers, ecore_event_handler_del);
1586 con = zone->container;
1587 if (zone->name) eina_stringshare_del(zone->name);
1588 con->zones = eina_list_remove(con->zones, zone);
1589 evas_object_del(zone->bg_event_object);
1590 evas_object_del(zone->bg_clip_object);
1591 evas_object_del(zone->bg_object);
1592 if (zone->prev_bg_object) evas_object_del(zone->prev_bg_object);
1593 if (zone->transition_object) evas_object_del(zone->transition_object);
1596 for (x = 0; x < zone->desk_x_count; x++)
1598 for (y = 0; y < zone->desk_y_count; y++)
1599 e_object_del(E_OBJECT(zone->desks[x + (y * zone->desk_x_count)]));
1603 _e_zone_black_free(zone);
1609 _e_zone_cb_bg_mouse_down(void *data,
1610 Evas *evas __UNUSED__,
1611 Evas_Object *obj __UNUSED__,
1612 void *event_info __UNUSED__)
1617 if (e_menu_grab_window_get()) return;
1619 if (!zone->cur_mouse_action)
1621 if (ecore_event_current_type_get() == ECORE_EVENT_MOUSE_BUTTON_DOWN)
1623 Ecore_Event_Mouse_Button *ev2;
1625 ev2 = ecore_event_current_event_get();
1626 zone->cur_mouse_action =
1627 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_ZONE,
1628 E_OBJECT(zone), ev2);
1629 if (zone->cur_mouse_action)
1631 if ((!zone->cur_mouse_action->func.end_mouse) &&
1632 (!zone->cur_mouse_action->func.end))
1633 zone->cur_mouse_action = NULL;
1634 if (zone->cur_mouse_action)
1635 e_object_ref(E_OBJECT(zone->cur_mouse_action));
1642 _e_zone_cb_bg_mouse_up(void *data,
1643 Evas *evas __UNUSED__,
1644 Evas_Object *obj __UNUSED__,
1645 void *event_info __UNUSED__)
1650 if (zone->cur_mouse_action)
1652 if (ecore_event_current_type_get() == ECORE_EVENT_MOUSE_BUTTON_UP)
1654 Ecore_Event_Mouse_Button *ev2;
1656 ev2 = ecore_event_current_event_get();
1657 if (zone->cur_mouse_action->func.end_mouse)
1658 zone->cur_mouse_action->func.end_mouse(E_OBJECT(zone), "", ev2);
1659 else if (zone->cur_mouse_action->func.end)
1660 zone->cur_mouse_action->func.end(E_OBJECT(zone), "");
1662 e_object_unref(E_OBJECT(zone->cur_mouse_action));
1663 zone->cur_mouse_action = NULL;
1667 if (ecore_event_current_type_get() == ECORE_EVENT_MOUSE_BUTTON_UP)
1669 Ecore_Event_Mouse_Button *ev2;
1671 ev2 = ecore_event_current_event_get();
1672 e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_ZONE,
1673 E_OBJECT(zone), ev2);
1679 _e_zone_event_zone_desk_count_set_free(void *data __UNUSED__,
1682 E_Event_Zone_Desk_Count_Set *e;
1685 e_object_unref(E_OBJECT(e->zone));
1690 _e_zone_cb_mouse_in(void *data,
1691 int type __UNUSED__,
1694 Ecore_X_Event_Mouse_In *ev;
1695 E_Event_Zone_Edge *zev;
1702 edge = _e_zone_detect_edge(zone, ev->win);
1703 if (edge == E_ZONE_EDGE_NONE) return ECORE_CALLBACK_PASS_ON;
1705 zev = E_NEW(E_Event_Zone_Edge, 1);
1708 zev->x = ev->root.x;
1709 zev->y = ev->root.y;
1710 zev->modifiers = ev->modifiers;
1711 ecore_event_add(E_EVENT_ZONE_EDGE_IN, zev, NULL, NULL);
1712 e_bindings_edge_in_event_handle(E_BINDING_CONTEXT_ZONE, E_OBJECT(zone), zev);
1714 return ECORE_CALLBACK_PASS_ON;
1718 _e_zone_cb_mouse_out(void *data,
1719 int type __UNUSED__,
1722 Ecore_X_Event_Mouse_Out *ev;
1723 E_Event_Zone_Edge *zev;
1730 edge = _e_zone_detect_edge(zone, ev->win);
1731 if (edge == E_ZONE_EDGE_NONE) return ECORE_CALLBACK_PASS_ON;
1733 zev = E_NEW(E_Event_Zone_Edge, 1);
1736 zev->x = ev->root.x;
1737 zev->y = ev->root.y;
1738 zev->modifiers = ev->modifiers;
1739 ecore_event_add(E_EVENT_ZONE_EDGE_OUT, zev, NULL, NULL);
1740 e_bindings_edge_out_event_handle(E_BINDING_CONTEXT_ZONE, E_OBJECT(zone), zev);
1741 return ECORE_CALLBACK_PASS_ON;
1745 _e_zone_cb_mouse_down(void *data,
1746 int type __UNUSED__,
1749 Ecore_Event_Mouse_Button *ev;
1750 E_Event_Zone_Edge *zev;
1757 edge = _e_zone_detect_edge(zone, ev->window);
1758 if (edge == E_ZONE_EDGE_NONE) return ECORE_CALLBACK_PASS_ON;
1760 zev = E_NEW(E_Event_Zone_Edge, 1);
1763 zev->x = ev->root.x;
1764 zev->y = ev->root.y;
1765 zev->button = ev->buttons;
1766 zev->modifiers = ev->modifiers;
1767 ecore_event_add(E_EVENT_ZONE_EDGE_OUT, zev, NULL, NULL);
1768 e_bindings_edge_down_event_handle(E_BINDING_CONTEXT_ZONE, E_OBJECT(zone), zev);
1769 return ECORE_CALLBACK_PASS_ON;
1773 _e_zone_cb_mouse_up(void *data,
1774 int type __UNUSED__,
1777 Ecore_Event_Mouse_Button *ev;
1778 E_Event_Zone_Edge *zev;
1785 edge = _e_zone_detect_edge(zone, ev->window);
1786 if (edge == E_ZONE_EDGE_NONE) return ECORE_CALLBACK_PASS_ON;
1788 zev = E_NEW(E_Event_Zone_Edge, 1);
1791 zev->x = ev->root.x;
1792 zev->y = ev->root.y;
1793 zev->button = ev->buttons;
1794 zev->modifiers = ev->modifiers;
1795 ecore_event_add(E_EVENT_ZONE_EDGE_OUT, zev, NULL, NULL);
1796 e_bindings_edge_up_event_handle(E_BINDING_CONTEXT_ZONE, E_OBJECT(zone), zev);
1797 return ECORE_CALLBACK_PASS_ON;
1801 _e_zone_cb_mouse_move(void *data,
1802 int type __UNUSED__,
1805 Ecore_Event_Mouse_Move *ev;
1806 E_Event_Zone_Edge *zev;
1813 edge = _e_zone_detect_edge(zone, ev->window);
1814 if (edge == E_ZONE_EDGE_NONE) return ECORE_CALLBACK_PASS_ON;
1816 zev = E_NEW(E_Event_Zone_Edge, 1);
1819 zev->x = ev->root.x;
1820 zev->y = ev->root.y;
1821 zev->modifiers = ev->modifiers;
1822 ecore_event_add(E_EVENT_ZONE_EDGE_MOVE, zev, NULL, NULL);
1823 return ECORE_CALLBACK_PASS_ON;
1827 _e_zone_cb_desk_after_show(void *data,
1828 int type __UNUSED__,
1831 E_Event_Desk_Show *ev;
1836 if (ev->desk->zone != zone) return ECORE_CALLBACK_PASS_ON;
1838 zone->flip.switching = 0;
1839 return ECORE_CALLBACK_PASS_ON;
1843 _e_zone_cb_edge_timer(void *data)
1849 act = e_action_find(zone->flip.bind->action);
1852 E_FREE(zone->flip.ev);
1853 return ECORE_CALLBACK_CANCEL;
1856 if (act->func.go_edge)
1857 act->func.go_edge(E_OBJECT(zone), zone->flip.bind->params, zone->flip.ev);
1858 else if (act->func.go)
1859 act->func.go(E_OBJECT(zone), zone->flip.bind->params);
1861 zone->flip.bind->timer = NULL;
1863 E_FREE(zone->flip.ev);
1864 return ECORE_CALLBACK_CANCEL;
1868 _e_zone_event_move_resize_free(void *data __UNUSED__,
1871 E_Event_Zone_Move_Resize *e;
1874 e_object_unref(E_OBJECT(e->zone));
1879 _e_zone_event_add_free(void *data __UNUSED__,
1882 E_Event_Zone_Add *e;
1885 e_object_unref(E_OBJECT(e->zone));
1890 _e_zone_event_del_free(void *data __UNUSED__,
1893 E_Event_Zone_Del *e;
1896 e_object_unref(E_OBJECT(e->zone));
1901 _e_zone_object_del_attach(void *o)
1904 E_Event_Zone_Del *ev;
1907 ev = E_NEW(E_Event_Zone_Del, 1);
1909 e_object_ref(E_OBJECT(ev->zone));
1910 ecore_event_add(E_EVENT_ZONE_DEL, ev, _e_zone_event_del_free, NULL);
1914 _e_zone_detect_edge(E_Zone *zone,
1917 E_Zone_Edge edge = E_ZONE_EDGE_NONE;
1919 if (win == zone->edge.left)
1920 edge = E_ZONE_EDGE_LEFT;
1921 else if (win == zone->edge.top)
1922 edge = E_ZONE_EDGE_TOP;
1923 else if (win == zone->edge.right)
1924 edge = E_ZONE_EDGE_RIGHT;
1925 else if (win == zone->edge.bottom)
1926 edge = E_ZONE_EDGE_BOTTOM;
1927 else if ((win == zone->corner.left_top) ||
1928 (win == zone->corner.top_left))
1929 edge = E_ZONE_EDGE_TOP_LEFT;
1930 else if ((win == zone->corner.right_top) ||
1931 (win == zone->corner.top_right))
1932 edge = E_ZONE_EDGE_TOP_RIGHT;
1933 else if ((win == zone->corner.right_bottom) ||
1934 (win == zone->corner.bottom_right))
1935 edge = E_ZONE_EDGE_BOTTOM_RIGHT;
1936 else if ((win == zone->corner.left_bottom) ||
1937 (win == zone->corner.bottom_left))
1938 edge = E_ZONE_EDGE_BOTTOM_LEFT;
1943 _e_zone_edge_move_resize(E_Zone *zone)
1948 cw = zone->w * E_ZONE_CORNER_RATIO;
1949 ch = zone->h * E_ZONE_CORNER_RATIO;
1951 if (zone->corner.left_bottom)
1952 ecore_x_window_move_resize(zone->corner.left_bottom,
1953 zone->x, zone->y + zone->h - ch, 1, ch);
1954 if (zone->edge.left)
1955 ecore_x_window_move_resize(zone->edge.left,
1956 zone->x, zone->y + ch, 1, zone->h - 2 * ch);
1957 if (zone->corner.left_top)
1958 ecore_x_window_move_resize(zone->corner.left_top,
1959 zone->x, zone->y, 1, ch);
1961 if (zone->corner.top_left)
1962 ecore_x_window_move_resize(zone->corner.top_left,
1963 zone->x + 1, zone->y, cw, 1);
1965 ecore_x_window_move_resize(zone->edge.top,
1966 zone->x + 1 + cw, zone->y, zone->w - 2 * cw - 2, 1);
1967 if (zone->corner.top_right)
1968 ecore_x_window_move_resize(zone->corner.top_right,
1969 zone->x + zone->w - cw - 2, zone->y, cw, 1);
1971 if (zone->corner.right_top)
1972 ecore_x_window_move_resize(zone->corner.right_top,
1973 zone->x + zone->w - 1, zone->y, 1, ch);
1974 if (zone->edge.right)
1975 ecore_x_window_move_resize(zone->edge.right,
1976 zone->x + zone->w - 1, zone->y + ch, 1, zone->h - 2 * ch);
1977 if (zone->corner.right_bottom)
1978 ecore_x_window_move_resize(zone->corner.right_bottom,
1979 zone->x + zone->w - 1, zone->y + zone->h - ch, 1, ch);
1981 if (zone->corner.bottom_right)
1982 ecore_x_window_move_resize(zone->corner.bottom_right,
1983 zone->x + 1, zone->y + zone->h - 1, cw, 1);
1984 if (zone->edge.bottom)
1985 ecore_x_window_move_resize(zone->edge.bottom,
1986 zone->x + 1 + cw, zone->y + zone->h - 1, zone->w - 2 - 2 * cw, 1);
1987 if (zone->corner.bottom_left)
1988 ecore_x_window_move_resize(zone->corner.bottom_left,
1989 zone->x + zone->w - cw - 2, zone->y + zone->h - 1, cw, 1);
1993 _e_zone_border_geometry_update(E_Zone *zone)
1995 Eina_List *borders, *l;
1997 unsigned int zgeom[4];
2003 borders = e_border_client_list();
2004 EINA_LIST_FOREACH(borders, l, bd)
2006 if (bd->zone == zone)
2007 ecore_x_window_prop_card32_set(bd->client.win,
2008 E_ATOM_ZONE_GEOMETRY,
2013 #ifdef _F_ZONE_WINDOW_ROTATION_
2015 _e_zone_event_rotation_change_free(void *data __UNUSED__,
2018 E_Event_Zone_Rotation_Change *e = ev;
2019 e_object_unref(E_OBJECT(e->zone));