1 #include "e.h"
2
3 /* E_Zone is a child object of E_Comp. There is one zone per screen
4 * in a xinerama setup. Each zone has one or more desktops.
5 */
6
7 static void _e_zone_free(E_Zone *zone);
8 static void _e_zone_cb_bg_mouse_down(void *data,
9 Evas *evas,
10 Evas_Object *obj,
11 void *event_info);
12 static void _e_zone_cb_bg_mouse_up(void *data,
13 Evas *evas,
14 Evas_Object *obj,
15 void *event_info);
16 static Eina_Bool _e_zone_cb_edge_timer(void *data);
17 static void _e_zone_event_generic_free(void *data, void *ev);
18 static void _e_zone_object_del_attach(void *o);
19 static E_Zone_Edge _e_zone_detect_edge(E_Zone *zone, Evas_Object *obj);
20 static void _e_zone_edge_move_resize(E_Zone *zone);
21 static void _e_zone_obstacle_free(E_Zone_Obstacle *obs);
22
23 E_API int E_EVENT_ZONE_DESK_COUNT_SET = 0;
24 E_API int E_EVENT_POINTER_WARP = 0;
25 E_API int E_EVENT_ZONE_USEFUL_GEOMETRY_CHANGED = 0;
26 E_API int E_EVENT_ZONE_MOVE_RESIZE = 0;
27 E_API int E_EVENT_ZONE_ADD = 0;
28 E_API int E_EVENT_ZONE_DEL = 0;
29 E_API int E_EVENT_ZONE_EDGE_IN = 0;
30 E_API int E_EVENT_ZONE_EDGE_OUT = 0;
31 E_API int E_EVENT_ZONE_EDGE_MOVE = 0;
32 E_API int E_EVENT_ZONE_STOW = 0;
33 E_API int E_EVENT_ZONE_UNSTOW = 0;
34
35 #define E_ZONE_FLIP_LEFT(zone) (((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1)) || ((zone)->desk_x_current > 0)) && (zone)->edge.left)
36 #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)
37 #define E_ZONE_FLIP_UP(zone) (((e_config->desk_flip_wrap && ((zone)->desk_y_count > 1)) || ((zone)->desk_y_current > 0)) && (zone)->edge.top)
38 #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)
39
40 #define E_ZONE_CORNER_RATIO 0.025;
41
42 EINTERN int
e_zone_init(void)43 e_zone_init(void)
44 {
45 E_EVENT_ZONE_DESK_COUNT_SET = ecore_event_type_new();
46 E_EVENT_POINTER_WARP = ecore_event_type_new();
47 E_EVENT_ZONE_MOVE_RESIZE = ecore_event_type_new();
48 E_EVENT_ZONE_USEFUL_GEOMETRY_CHANGED = ecore_event_type_new();
49 E_EVENT_ZONE_ADD = ecore_event_type_new();
50 E_EVENT_ZONE_DEL = ecore_event_type_new();
51 E_EVENT_ZONE_EDGE_IN = ecore_event_type_new();
52 E_EVENT_ZONE_EDGE_OUT = ecore_event_type_new();
53 E_EVENT_ZONE_EDGE_MOVE = ecore_event_type_new();
54 E_EVENT_ZONE_STOW = ecore_event_type_new();
55 E_EVENT_ZONE_UNSTOW = ecore_event_type_new();
56 return 1;
57 }
58
59 EINTERN int
e_zone_shutdown(void)60 e_zone_shutdown(void)
61 {
62 return 1;
63 }
64
65 E_API void
e_zone_all_edge_flip_eval(void)66 e_zone_all_edge_flip_eval(void)
67 {
68 const Eina_List *l;
69 E_Zone *zone;
70
71 EINA_LIST_FOREACH(e_comp->zones, l, zone)
72 e_zone_edge_flip_eval(zone);
73 }
74
75 static void
_e_zone_cb_mouse_in(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info)76 _e_zone_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
77 {
78 Evas_Event_Mouse_In *ev = event_info;
79 E_Event_Zone_Edge *zev;
80 E_Zone_Edge edge;
81 E_Zone *zone = data;
82
83 if (!ev->timestamp) return;
84 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
85 edge = _e_zone_detect_edge(zone, obj);
86 if (edge == E_ZONE_EDGE_NONE) return;
87
88 zev = E_NEW(E_Event_Zone_Edge, 1);
89 zev->zone = zone;
90 zev->edge = edge;
91 zev->x = ev->output.x;
92 zev->y = ev->output.y;
93 zev->modifiers = e_bindings_evas_modifiers_convert(ev->modifiers);
94 zev->drag = !!evas_pointer_button_down_mask_get(e_comp->evas);
95
96 ecore_event_add(E_EVENT_ZONE_EDGE_IN, zev, NULL, NULL);
97 if (e_bindings_edge_in_event_handle(E_BINDING_CONTEXT_ZONE, E_OBJECT(zone), zev))
98 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
99 }
100
101 static void
_e_zone_cb_mouse_out(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info)102 _e_zone_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
103 {
104 Evas_Event_Mouse_Out *ev = event_info;
105 E_Event_Zone_Edge *zev;
106 E_Zone_Edge edge;
107 E_Zone *zone = data;
108
109 if (!ev->timestamp) return;
110 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
111 edge = _e_zone_detect_edge(zone, obj);
112 if (edge == E_ZONE_EDGE_NONE) return;
113
114 zev = E_NEW(E_Event_Zone_Edge, 1);
115 zev->zone = zone;
116 zev->edge = edge;
117 zev->x = ev->output.x;
118 zev->y = ev->output.y;
119 zev->modifiers = e_bindings_evas_modifiers_convert(ev->modifiers);
120 zev->drag = !!evas_pointer_button_down_mask_get(e_comp->evas);
121
122 ecore_event_add(E_EVENT_ZONE_EDGE_OUT, zev, NULL, NULL);
123 if (e_bindings_edge_out_event_handle(E_BINDING_CONTEXT_ZONE, E_OBJECT(zone), zev))
124 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
125 }
126
127 static void
_e_zone_cb_mouse_down(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info)128 _e_zone_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
129 {
130 Evas_Event_Mouse_Down *ev = event_info;
131 E_Event_Zone_Edge *zev;
132 E_Zone_Edge edge;
133 E_Zone *zone = data;
134
135 if (!ev->timestamp) return;
136 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
137 edge = _e_zone_detect_edge(zone, obj);
138 if (edge == E_ZONE_EDGE_NONE) return;
139
140 zev = E_NEW(E_Event_Zone_Edge, 1);
141 zev->zone = zone;
142 zev->edge = edge;
143 zev->x = ev->output.x;
144 zev->y = ev->output.y;
145 zev->button = ev->button;
146 zev->modifiers = e_bindings_evas_modifiers_convert(ev->modifiers);
147 ecore_event_add(E_EVENT_ZONE_EDGE_OUT, zev, NULL, NULL);
148 if (e_bindings_edge_down_event_handle(E_BINDING_CONTEXT_ZONE, E_OBJECT(zone), zev))
149 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
150 }
151
152 static void
_e_zone_cb_mouse_up(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info)153 _e_zone_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
154 {
155 Evas_Event_Mouse_Up *ev = event_info;
156 E_Event_Zone_Edge *zev;
157 E_Zone_Edge edge;
158 E_Zone *zone = data;
159
160 if (!ev->timestamp) return;
161 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
162 edge = _e_zone_detect_edge(zone, obj);
163 if (edge == E_ZONE_EDGE_NONE) return;
164
165 zev = E_NEW(E_Event_Zone_Edge, 1);
166 zev->zone = zone;
167 zev->edge = edge;
168 zev->x = ev->output.x;
169 zev->y = ev->output.y;
170 zev->button = ev->button;
171 zev->modifiers = e_bindings_evas_modifiers_convert(ev->modifiers);
172 ecore_event_add(E_EVENT_ZONE_EDGE_OUT, zev, NULL, NULL);
173 if (e_bindings_edge_up_event_handle(E_BINDING_CONTEXT_ZONE, E_OBJECT(zone), zev))
174 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
175 }
176
177 static void
_e_zone_cb_mouse_move(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info)178 _e_zone_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
179 {
180 Evas_Event_Mouse_Move *ev = event_info;
181 E_Event_Zone_Edge *zev;
182 E_Zone_Edge edge;
183 E_Zone *zone = data;
184
185 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
186 edge = _e_zone_detect_edge(zone, obj);
187 if (edge == E_ZONE_EDGE_NONE) return;
188
189 zev = E_NEW(E_Event_Zone_Edge, 1);
190 zev->zone = zone;
191 zev->edge = edge;
192 zev->x = ev->cur.output.x;
193 zev->y = ev->cur.output.y;
194 zev->modifiers = e_bindings_evas_modifiers_convert(ev->modifiers);
195 ecore_event_add(E_EVENT_ZONE_EDGE_MOVE, zev, NULL, NULL);
196 }
197
198 E_API E_Zone *
e_zone_new(int num,int id,int x,int y,int w,int h)199 e_zone_new(int num, int id, int x, int y, int w, int h)
200 {
201 E_Zone *zone;
202 Evas_Object *o;
203 E_Event_Zone_Add *ev;
204 char name[40];
205
206 zone = E_OBJECT_ALLOC(E_Zone, E_ZONE_TYPE, _e_zone_free);
207 if (!zone) return NULL;
208
209 zone->x = x;
210 zone->y = y;
211 zone->w = w;
212 zone->h = h;
213 zone->num = num;
214 zone->id = id;
215
216 zone->useful_geometry_dirty = 1;
217 zone->useful_geometry[0].x = zone->useful_geometry[0].y =
218 zone->useful_geometry[0].w = zone->useful_geometry[0].h = -1;
219 zone->useful_geometry[1].x = zone->useful_geometry[1].y =
220 zone->useful_geometry[1].w = zone->useful_geometry[1].h = -1;
221
222 //printf("@@@@@@@@@@ e_zone_new: %i %i | %i %i %ix%i = %p\n", num, id, x, y, w, h, zone);
223
224 snprintf(name, sizeof(name), "Zone %d", zone->num);
225 zone->name = eina_stringshare_add(name);
226
227 e_comp->zones = eina_list_append(e_comp->zones, zone);
228
229 o = evas_object_rectangle_add(e_comp->evas);
230 zone->bg_clip_object = o;
231 evas_object_repeat_events_set(o, 1);
232 evas_object_layer_set(o, E_LAYER_BG);
233 evas_object_name_set(o, "zone->bg_clip_object");
234 evas_object_move(o, x, y);
235 evas_object_resize(o, w, h);
236 evas_object_color_set(o, 255, 255, 255, 255);
237 evas_object_show(o);
238
239 o = evas_object_rectangle_add(e_comp->evas);
240 zone->bg_event_object = o;
241 evas_object_name_set(o, "zone->bg_event_object");
242 evas_object_clip_set(o, zone->bg_clip_object);
243 evas_object_layer_set(o, E_LAYER_BG);
244 evas_object_repeat_events_set(o, 1);
245 evas_object_move(o, x, y);
246 evas_object_resize(o, w, h);
247 evas_object_color_set(o, 0, 0, 0, 0);
248 evas_object_repeat_events_set(o, 1);
249 evas_object_show(o);
250 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _e_zone_cb_bg_mouse_down, zone);
251 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _e_zone_cb_bg_mouse_up, zone);
252
253 /* TODO: config the ecore_evas type. */
254
255 zone->desk_x_count = 0;
256 zone->desk_y_count = 0;
257 zone->desk_x_current = 0;
258 zone->desk_y_current = 0;
259 e_zone_desk_count_set(zone, e_config->zone_desks_x_count,
260 e_config->zone_desks_y_count);
261
262 e_object_del_attach_func_set(E_OBJECT(zone), _e_zone_object_del_attach);
263
264 e_zone_all_edge_flip_eval();
265
266 if (starting) return zone;
267
268 ev = E_NEW(E_Event_Zone_Add, 1);
269 ev->zone = zone;
270 e_object_ref(E_OBJECT(ev->zone));
271 ecore_event_add(E_EVENT_ZONE_ADD, ev, _e_zone_event_generic_free, NULL);
272
273 return zone;
274 }
275
276 E_API void
e_zone_name_set(E_Zone * zone,const char * name)277 e_zone_name_set(E_Zone *zone,
278 const char *name)
279 {
280 E_OBJECT_CHECK(zone);
281 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
282
283 if (zone->name) eina_stringshare_del(zone->name);
284 zone->name = eina_stringshare_add(name);
285 }
286
287 static void
e_zone_reconfigure_clients(E_Zone * zone,int dx,int dy)288 e_zone_reconfigure_clients(E_Zone *zone, int dx, int dy)
289 {
290 E_Client *ec;
291
292 E_CLIENT_FOREACH(ec)
293 {
294 if (ec->zone != zone) continue;
295
296 if ((dx != 0) || (dy != 0))
297 evas_object_move(ec->frame, ec->x + dx, ec->y + dy);
298 }
299 }
300
301 E_API void
e_zone_move(E_Zone * zone,int x,int y)302 e_zone_move(E_Zone *zone,
303 int x,
304 int y)
305 {
306 E_OBJECT_CHECK(zone);
307 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
308 e_zone_move_resize(zone, x, y, zone->w, zone->h);
309 }
310
311 E_API void
e_zone_resize(E_Zone * zone,int w,int h)312 e_zone_resize(E_Zone *zone,
313 int w,
314 int h)
315 {
316 E_OBJECT_CHECK(zone);
317 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
318 e_zone_move_resize(zone, zone->x, zone->y, w, h);
319 }
320
321 E_API Eina_Bool
e_zone_move_resize(E_Zone * zone,int x,int y,int w,int h)322 e_zone_move_resize(E_Zone *zone,
323 int x,
324 int y,
325 int w,
326 int h)
327 {
328 E_Event_Zone_Move_Resize *ev;
329 int dx, dy;
330
331 E_OBJECT_CHECK_RETURN(zone, EINA_FALSE);
332 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, EINA_FALSE);
333
334 if ((x == zone->x) && (y == zone->y) && (w == zone->w) && (h == zone->h))
335 return EINA_FALSE;
336
337 dx = x - zone->x;
338 dy = y - zone->y;
339 zone->x = x;
340 zone->y = y;
341 zone->w = w;
342 zone->h = h;
343
344 evas_object_move(zone->bg_object, x, y);
345 evas_object_move(zone->bg_event_object, x, y);
346 evas_object_move(zone->bg_clip_object, x, y);
347 evas_object_resize(zone->bg_object, w, h);
348 evas_object_resize(zone->bg_event_object, w, h);
349 evas_object_resize(zone->bg_clip_object, w, h);
350
351 ev = E_NEW(E_Event_Zone_Move_Resize, 1);
352 ev->zone = zone;
353 e_object_ref(E_OBJECT(ev->zone));
354 ecore_event_add(E_EVENT_ZONE_MOVE_RESIZE, ev,
355 _e_zone_event_generic_free, NULL);
356
357 _e_zone_edge_move_resize(zone);
358 e_zone_bg_reconfigure(zone);
359 e_zone_reconfigure_clients(zone, dx, dy);
360 e_zone_useful_geometry_dirty(zone);
361 return EINA_TRUE;
362 }
363
364 E_API E_Zone *
e_zone_current_get(void)365 e_zone_current_get(void)
366 {
367 Eina_List *l = NULL;
368 E_Zone *zone;
369
370 if (!e_comp) return NULL;
371 if (!starting)
372 {
373 int x, y;
374
375 ecore_evas_pointer_xy_get(e_comp->ee, &x, &y);
376 EINA_LIST_FOREACH(e_comp->zones, l, zone)
377 {
378 if (E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h))
379 return zone;
380 }
381 }
382 if (!e_comp->zones) return NULL;
383 return eina_list_data_get(e_comp->zones);
384 }
385
386 E_API void
e_zone_bg_reconfigure(E_Zone * zone)387 e_zone_bg_reconfigure(E_Zone *zone)
388 {
389 E_OBJECT_CHECK(zone);
390 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
391
392 e_bg_zone_update(zone, E_BG_TRANSITION_CHANGE);
393 }
394
395 E_API void
e_zone_flip_coords_handle(E_Zone * zone,int x,int y)396 e_zone_flip_coords_handle(E_Zone *zone,
397 int x,
398 int y)
399 {
400 E_Event_Zone_Edge *zev;
401 E_Binding_Edge *binding;
402 E_Zone_Edge edge;
403 Eina_List *l;
404 E_Shelf *es;
405 int ok = 0;
406 int one_row = 1;
407 int one_col = 1;
408
409 E_OBJECT_CHECK(zone);
410 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
411
412 if (zone->flip.switching)
413 {
414 int cx, cy, w, h;
415
416 switch (zone->flip.switching)
417 {
418 case E_ZONE_EDGE_LEFT:
419 evas_object_geometry_get(zone->edge.left, &cx, &cy, &w, &h);
420 if (!E_INSIDE(x, y, cx, cy, w, h))
421 zone->flip.switching = E_ZONE_EDGE_NONE;
422 break;
423 case E_ZONE_EDGE_RIGHT:
424 evas_object_geometry_get(zone->edge.right, &cx, &cy, &w, &h);
425 if (!E_INSIDE(x, y, cx, cy, w, h))
426 zone->flip.switching = E_ZONE_EDGE_NONE;
427 break;
428 case E_ZONE_EDGE_TOP:
429 evas_object_geometry_get(zone->edge.top, &cx, &cy, &w, &h);
430 if (!E_INSIDE(x, y, cx, cy, w, h))
431 zone->flip.switching = E_ZONE_EDGE_NONE;
432 break;
433 case E_ZONE_EDGE_BOTTOM:
434 evas_object_geometry_get(zone->edge.bottom, &cx, &cy, &w, &h);
435 if (!E_INSIDE(x, y, cx, cy, w, h))
436 zone->flip.switching = E_ZONE_EDGE_NONE;
437 break;
438
439 case E_ZONE_EDGE_TOP_LEFT:
440 evas_object_geometry_get(zone->corner.left_top, &cx, &cy, &w, &h);
441 if (!E_INSIDE(x, y, cx, cy, w, h))
442 {
443 evas_object_geometry_get(zone->corner.top_left, &cx, &cy, &w, &h);
444 if (!E_INSIDE(x, y, cx, cy, w, h))
445 zone->flip.switching = E_ZONE_EDGE_NONE;
446 }
447 break;
448 case E_ZONE_EDGE_TOP_RIGHT:
449 evas_object_geometry_get(zone->corner.right_top, &cx, &cy, &w, &h);
450 if (!E_INSIDE(x, y, cx, cy, w, h))
451 {
452 evas_object_geometry_get(zone->corner.top_right, &cx, &cy, &w, &h);
453 if (!E_INSIDE(x, y, cx, cy, w, h))
454 zone->flip.switching = E_ZONE_EDGE_NONE;
455 }
456 break;
457 case E_ZONE_EDGE_BOTTOM_RIGHT:
458 evas_object_geometry_get(zone->corner.right_bottom, &cx, &cy, &w, &h);
459 if (!E_INSIDE(x, y, cx, cy, w, h))
460 {
461 evas_object_geometry_get(zone->corner.bottom_right, &cx, &cy, &w, &h);
462 if (!E_INSIDE(x, y, cx, cy, w, h))
463 zone->flip.switching = E_ZONE_EDGE_NONE;
464 }
465 break;
466 case E_ZONE_EDGE_BOTTOM_LEFT:
467 evas_object_geometry_get(zone->corner.left_bottom, &cx, &cy, &w, &h);
468 if (!E_INSIDE(x, y, cx, cy, w, h))
469 {
470 evas_object_geometry_get(zone->corner.bottom_left, &cx, &cy, &w, &h);
471 if (!E_INSIDE(x, y, cx, cy, w, h))
472 zone->flip.switching = E_ZONE_EDGE_NONE;
473 }
474 break;
475 default: break;
476 }
477 if (zone->flip.switching) return;
478 }
479
480 if (!e_config->edge_flip_dragging) return;
481 /* if we have only 1 row we can flip up/down even if we have xinerama */
482 if (eina_list_count(e_comp->zones) > 1)
483 {
484 Eina_List *zones;
485 E_Zone *next_zone;
486 int cx, cy;
487
488 zones = e_comp->zones;
489 next_zone = (E_Zone *)eina_list_data_get(zones);
490 cx = next_zone->x;
491 cy = next_zone->y;
492 zones = eina_list_next(zones);
493 EINA_LIST_FOREACH(eina_list_next(zones), zones, next_zone)
494 {
495 if (next_zone->x != cx) one_col = 0;
496 if (next_zone->y != cy) one_row = 0;
497 }
498 }
499 if (!E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h))
500 goto noflip;
501 if ((one_row) && (y == 0))
502 edge = E_ZONE_EDGE_TOP;
503 else if ((one_col) && (x == (zone->w - 1)))
504 edge = E_ZONE_EDGE_RIGHT;
505 else if ((one_row) && (y == (zone->h - 1)))
506 edge = E_ZONE_EDGE_BOTTOM;
507 else if ((one_col) && (x == 0))
508 edge = E_ZONE_EDGE_LEFT;
509 else
510 {
511 noflip:
512 if (zone->flip.es)
513 e_shelf_toggle(zone->flip.es, 0);
514 zone->flip.es = NULL;
515 return;
516 }
517 EINA_LIST_FOREACH(e_shelf_list(), l, es)
518 {
519 if (es->zone != zone) continue;
520 switch (es->gadcon->orient)
521 {
522 case E_GADCON_ORIENT_TOP:
523 case E_GADCON_ORIENT_CORNER_TL:
524 case E_GADCON_ORIENT_CORNER_TR:
525 if (edge == E_ZONE_EDGE_TOP) ok = 1;
526 break;
527
528 case E_GADCON_ORIENT_BOTTOM:
529 case E_GADCON_ORIENT_CORNER_BL:
530 case E_GADCON_ORIENT_CORNER_BR:
531 if (edge == E_ZONE_EDGE_BOTTOM) ok = 1;
532 break;
533
534 case E_GADCON_ORIENT_LEFT:
535 case E_GADCON_ORIENT_CORNER_LT:
536 case E_GADCON_ORIENT_CORNER_LB:
537 if (edge == E_ZONE_EDGE_LEFT) ok = 1;
538 break;
539
540 case E_GADCON_ORIENT_RIGHT:
541 case E_GADCON_ORIENT_CORNER_RT:
542 case E_GADCON_ORIENT_CORNER_RB:
543 if (edge == E_ZONE_EDGE_RIGHT) ok = 1;
544 break;
545
546 default:
547 ok = 0;
548 break;
549 }
550
551 if (!ok) continue;
552 if (!E_INSIDE(x, y, es->x, es->y, es->w, es->h))
553 continue;
554
555 if (zone->flip.es)
556 e_shelf_toggle(zone->flip.es, 0);
557
558 zone->flip.es = es;
559 e_shelf_toggle(es, 1);
560 }
561 ok = 0;
562 switch (edge)
563 {
564 case E_ZONE_EDGE_LEFT:
565 if (E_ZONE_FLIP_LEFT(zone)) ok = 1;
566 break;
567
568 case E_ZONE_EDGE_TOP:
569 if (E_ZONE_FLIP_UP(zone)) ok = 1;
570 break;
571
572 case E_ZONE_EDGE_RIGHT:
573 if (E_ZONE_FLIP_RIGHT(zone)) ok = 1;
574 break;
575
576 case E_ZONE_EDGE_BOTTOM:
577 if (E_ZONE_FLIP_DOWN(zone)) ok = 1;
578 break;
579
580 default:
581 ok = 0;
582 break;
583 }
584 if (!ok) return;
585 binding = e_bindings_edge_get("desk_flip_in_direction", edge, 0);
586 if (!binding) binding = e_bindings_edge_get("desk_flip_by", edge, 0);
587 if (binding && (!binding->timer))
588 {
589 zev = E_NEW(E_Event_Zone_Edge, 1);
590 zev->zone = zone;
591 zev->x = x;
592 zev->y = y;
593 zev->edge = edge;
594 zone->flip.ev = zev;
595 zone->flip.bind = binding;
596 zone->flip.switching = edge;
597 binding->timer = ecore_timer_loop_add(((double)binding->delay), _e_zone_cb_edge_timer, zone);
598 }
599 }
600
601 E_API void
e_zone_desk_count_set(E_Zone * zone,int x_count,int y_count)602 e_zone_desk_count_set(E_Zone *zone,
603 int x_count,
604 int y_count)
605 {
606 E_Desk **new_desks;
607 E_Desk *desk, *new_desk;
608 E_Client *ec;
609 E_Event_Zone_Desk_Count_Set *ev;
610 int x, y, xx, yy, moved, nx, ny;
611
612 E_OBJECT_CHECK(zone);
613 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
614
615 xx = x_count;
616 if (xx < 1) xx = 1;
617 yy = y_count;
618 if (yy < 1) yy = 1;
619
620 /* Orphaned window catcher; in case desk count gets reset */
621 moved = 0;
622 if (zone->desk_x_current >= xx) moved = 1;
623 if (zone->desk_y_current >= yy) moved = 1;
624 if (moved)
625 {
626 nx = zone->desk_x_current;
627 ny = zone->desk_y_current;
628 if (zone->desk_x_current >= xx) nx = xx - 1;
629 if (zone->desk_y_current >= yy) ny = yy - 1;
630 e_desk_show(e_desk_at_xy_get(zone, nx, ny));
631 }
632
633 new_desks = malloc(xx * yy * sizeof(E_Desk *));
634 for (x = 0; x < xx; x++)
635 {
636 for (y = 0; y < yy; y++)
637 {
638 if ((x < zone->desk_x_count) && (y < zone->desk_y_count))
639 desk = zone->desks[x + (y * zone->desk_x_count)];
640 else
641 desk = e_desk_new(zone, x, y);
642 new_desks[x + (y * xx)] = desk;
643 }
644 }
645
646 /* catch windows that have fallen off the end if we got smaller */
647 if (xx < zone->desk_x_count)
648 {
649 for (y = 0; y < zone->desk_y_count; y++)
650 {
651 new_desk = zone->desks[xx - 1 + (y * zone->desk_x_count)];
652 for (x = xx; x < zone->desk_x_count; x++)
653 {
654 desk = zone->desks[x + (y * zone->desk_x_count)];
655
656 E_CLIENT_FOREACH(ec)
657 {
658 if (ec->desk == desk)
659 e_client_desk_set(ec, new_desk);
660 }
661 e_object_del(E_OBJECT(desk));
662 }
663 }
664 }
665 if (yy < zone->desk_y_count)
666 {
667 for (x = 0; x < zone->desk_x_count; x++)
668 {
669 new_desk = zone->desks[x + ((yy - 1) * zone->desk_x_count)];
670 for (y = yy; y < zone->desk_y_count; y++)
671 {
672 desk = zone->desks[x + (y * zone->desk_x_count)];
673
674 E_CLIENT_FOREACH(ec)
675 {
676 if (ec->desk == desk)
677 e_client_desk_set(ec, new_desk);
678 }
679 e_object_del(E_OBJECT(desk));
680 }
681 }
682 }
683 free(zone->desks);
684 zone->desks = new_desks;
685
686 zone->desk_x_count = xx;
687 zone->desk_y_count = yy;
688 e_config->zone_desks_x_count = xx;
689 e_config->zone_desks_y_count = yy;
690 e_config_save_queue();
691
692 /* Cannot call desk_current_get until the zone desk counts have been set
693 * or else we end up with a "white background" because desk_current_get will
694 * return NULL.
695 */
696 desk = e_desk_current_get(zone);
697 if (desk)
698 {
699 /* need to simulate "startup" conditions to force desk show to reevaluate here */
700 int s = starting;
701 desk->visible = 0;
702 starting = 1;
703 e_desk_show(desk);
704 starting = s;
705 }
706
707 e_zone_edge_flip_eval(zone);
708
709 ev = E_NEW(E_Event_Zone_Desk_Count_Set, 1);
710 if (!ev) return;
711 ev->zone = zone;
712 e_object_ref(E_OBJECT(ev->zone));
713 ecore_event_add(E_EVENT_ZONE_DESK_COUNT_SET, ev,
714 _e_zone_event_generic_free, NULL);
715 }
716
717 E_API void
e_zone_desk_count_get(E_Zone * zone,int * x_count,int * y_count)718 e_zone_desk_count_get(E_Zone *zone,
719 int *x_count,
720 int *y_count)
721 {
722 E_OBJECT_CHECK(zone);
723 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
724
725 if (x_count) *x_count = zone->desk_x_count;
726 if (y_count) *y_count = zone->desk_y_count;
727 }
728
729 E_API void
e_zone_desk_flip_by(E_Zone * zone,int dx,int dy)730 e_zone_desk_flip_by(E_Zone *zone,
731 int dx,
732 int dy)
733 {
734 E_OBJECT_CHECK(zone);
735 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
736
737 dx = zone->desk_x_current + dx;
738 dy = zone->desk_y_current + dy;
739 e_zone_desk_flip_to(zone, dx, dy);
740 e_zone_edge_flip_eval(zone);
741 }
742
743 E_API void
e_zone_desk_flip_to(E_Zone * zone,int x,int y)744 e_zone_desk_flip_to(E_Zone *zone,
745 int x,
746 int y)
747 {
748 E_Desk *desk;
749
750 E_OBJECT_CHECK(zone);
751 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
752
753 if (e_config->desk_flip_wrap)
754 {
755 x = x % zone->desk_x_count;
756 y = y % zone->desk_y_count;
757 if (x < 0) x += zone->desk_x_count;
758 if (y < 0) y += zone->desk_y_count;
759 }
760 else
761 {
762 if (x < 0) x = 0;
763 else if (x >= zone->desk_x_count)
764 x = zone->desk_x_count - 1;
765 if (y < 0) y = 0;
766 else if (y >= zone->desk_y_count)
767 y = zone->desk_y_count - 1;
768 }
769 desk = e_desk_at_xy_get(zone, x, y);
770 if (!desk) return;
771 e_desk_show(desk);
772 e_zone_edge_flip_eval(zone);
773 }
774
775 E_API void
e_zone_desk_linear_flip_by(E_Zone * zone,int dx)776 e_zone_desk_linear_flip_by(E_Zone *zone,
777 int dx)
778 {
779 E_OBJECT_CHECK(zone);
780 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
781
782 dx = zone->desk_x_current +
783 (zone->desk_y_current * zone->desk_x_count) + dx;
784 if ((!e_config->desk_flip_wrap) &&
785 ((dx < 0) || (dx >= zone->desk_x_count * zone->desk_y_count))) return;
786 dx = dx % (zone->desk_x_count * zone->desk_y_count);
787 while (dx < 0)
788 dx += (zone->desk_x_count * zone->desk_y_count);
789 e_zone_desk_linear_flip_to(zone, dx);
790 }
791
792 E_API void
e_zone_desk_linear_flip_to(E_Zone * zone,int x)793 e_zone_desk_linear_flip_to(E_Zone *zone,
794 int x)
795 {
796 int y;
797
798 E_OBJECT_CHECK(zone);
799 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
800
801 y = x / zone->desk_x_count;
802 x = x - (y * zone->desk_x_count);
803 e_zone_desk_flip_to(zone, x, y);
804 }
805
806 E_API void
e_zone_edge_enable(void)807 e_zone_edge_enable(void)
808 {
809 const Eina_List *l;
810 E_Zone *zone;
811
812 EINA_LIST_FOREACH(e_comp->zones, l, zone)
813 {
814 if (zone->edge.left) evas_object_show(zone->edge.left);
815 if (zone->edge.right) evas_object_show(zone->edge.right);
816 if (zone->edge.top) evas_object_show(zone->edge.top);
817 if (zone->edge.bottom) evas_object_show(zone->edge.bottom);
818 if (zone->corner.left_top) evas_object_show(zone->corner.left_top);
819 if (zone->corner.top_left) evas_object_show(zone->corner.top_left);
820 if (zone->corner.top_right) evas_object_show(zone->corner.top_right);
821 if (zone->corner.right_top) evas_object_show(zone->corner.right_top);
822 if (zone->corner.right_bottom) evas_object_show(zone->corner.right_bottom);
823 if (zone->corner.bottom_right) evas_object_show(zone->corner.bottom_right);
824 if (zone->corner.bottom_left) evas_object_show(zone->corner.bottom_left);
825 if (zone->corner.left_bottom) evas_object_show(zone->corner.left_bottom);
826 e_zone_edge_flip_eval(zone);
827 }
828 }
829
830 E_API void
e_zone_edge_disable(void)831 e_zone_edge_disable(void)
832 {
833 const Eina_List *l;
834 E_Zone *zone;
835
836 EINA_LIST_FOREACH(e_comp->zones, l, zone)
837 {
838 zone->flip.switching = E_ZONE_EDGE_NONE;
839 if (zone->edge.left) evas_object_hide(zone->edge.left);
840 if (zone->edge.right) evas_object_hide(zone->edge.right);
841 if (zone->edge.top) evas_object_hide(zone->edge.top);
842 if (zone->edge.bottom) evas_object_hide(zone->edge.bottom);
843 if (zone->corner.left_top) evas_object_hide(zone->corner.left_top);
844 if (zone->corner.top_left) evas_object_hide(zone->corner.top_left);
845 if (zone->corner.top_right) evas_object_hide(zone->corner.top_right);
846 if (zone->corner.right_top) evas_object_hide(zone->corner.right_top);
847 if (zone->corner.right_bottom) evas_object_hide(zone->corner.right_bottom);
848 if (zone->corner.bottom_right) evas_object_hide(zone->corner.bottom_right);
849 if (zone->corner.bottom_left) evas_object_hide(zone->corner.bottom_left);
850 if (zone->corner.left_bottom) evas_object_hide(zone->corner.left_bottom);
851 }
852 }
853
854 E_API void
e_zone_edges_desk_flip_capable(E_Zone * zone,Eina_Bool l,Eina_Bool r,Eina_Bool t,Eina_Bool b)855 e_zone_edges_desk_flip_capable(E_Zone *zone, Eina_Bool l, Eina_Bool r, Eina_Bool t, Eina_Bool b)
856 {
857 #define NEED_FLIP_EDGE(x) \
858 (e_bindings_edge_flippable_get(x) || e_bindings_edge_non_flippable_get(x))
859 #define NEED_EDGE(x) \
860 (e_bindings_edge_non_flippable_get(x))
861 #define CHECK_EDGE(v, ed, obj) \
862 do { \
863 if (v) { \
864 if (NEED_FLIP_EDGE(ed)) { if (zone->edge.obj) evas_object_show(zone->edge.obj); } \
865 else if (zone->edge.obj) \
866 evas_object_hide(zone->edge.obj); \
867 } \
868 else { \
869 if (NEED_EDGE(ed)) { if (zone->edge.obj) evas_object_show(zone->edge.obj); } \
870 else if (zone->edge.obj) \
871 evas_object_hide(zone->edge.obj); \
872 } \
873 } while (0)
874
875 CHECK_EDGE(l, E_ZONE_EDGE_LEFT, left);
876 CHECK_EDGE(r, E_ZONE_EDGE_RIGHT, right);
877 CHECK_EDGE(t, E_ZONE_EDGE_TOP, top);
878 CHECK_EDGE(b, E_ZONE_EDGE_BOTTOM, bottom);
879
880 #define CHECK_CORNER(v1, v2, ed, obj1, obj2) \
881 if ((!v1) && (!v2)) { \
882 if (NEED_EDGE(ed)) { \
883 if (zone->corner.obj1) evas_object_show(zone->corner.obj1); \
884 if (zone->corner.obj2) evas_object_show(zone->corner.obj2); \
885 } \
886 else { \
887 if (zone->corner.obj1) evas_object_hide(zone->corner.obj1); \
888 if (zone->corner.obj2) evas_object_hide(zone->corner.obj2); \
889 } \
890 } \
891 else { \
892 if (NEED_FLIP_EDGE(ed)) { \
893 if (zone->corner.obj1) evas_object_show(zone->corner.obj1); \
894 if (zone->corner.obj2) evas_object_show(zone->corner.obj2); \
895 } \
896 else { \
897 if (zone->corner.obj1) evas_object_hide(zone->corner.obj1); \
898 if (zone->corner.obj2) evas_object_hide(zone->corner.obj2); \
899 } \
900 }
901
902 CHECK_CORNER(l, t, E_ZONE_EDGE_TOP_LEFT, left_top, top_left);
903 CHECK_CORNER(r, t, E_ZONE_EDGE_TOP_RIGHT, right_top, top_right);
904 CHECK_CORNER(l, b, E_ZONE_EDGE_BOTTOM_LEFT, left_bottom, bottom_left);
905 CHECK_CORNER(r, b, E_ZONE_EDGE_BOTTOM_RIGHT, right_bottom, bottom_right);
906 }
907
908 E_API Eina_Bool
e_zone_exists_direction(E_Zone * zone,E_Zone_Edge edge)909 e_zone_exists_direction(E_Zone *zone, E_Zone_Edge edge)
910 {
911 Eina_List *l;
912 E_Zone *z2;
913
914 EINA_LIST_FOREACH(e_comp->zones, l, z2)
915 {
916 if (zone == z2) continue;
917
918 switch (edge)
919 {
920 case E_ZONE_EDGE_TOP_LEFT:
921 if (((E_SPANS_COMMON(0, zone->x + zone->w, z2->x, z2->w)) &&
922 (z2->y < zone->y)) ||
923 ((E_SPANS_COMMON(0, zone->y + zone->h, z2->y, z2->h)) &&
924 (z2->x < zone->x)))
925 return EINA_TRUE;
926 break;
927
928 case E_ZONE_EDGE_TOP:
929 if ((E_SPANS_COMMON(zone->x, zone->w, z2->x, z2->w)) &&
930 (z2->y < zone->y))
931 return EINA_TRUE;
932 break;
933
934 case E_ZONE_EDGE_TOP_RIGHT:
935 if (((E_SPANS_COMMON(zone->x, 99999, z2->x, z2->w)) &&
936 (z2->y < zone->y)) ||
937 ((E_SPANS_COMMON(0, zone->y + zone->h, z2->y, z2->h)) &&
938 (z2->x >= (zone->x + zone->w))))
939 return EINA_TRUE;
940 break;
941
942 case E_ZONE_EDGE_LEFT:
943 if ((E_SPANS_COMMON(zone->y, zone->h, z2->y, z2->h)) &&
944 (z2->x < zone->x))
945 return EINA_TRUE;
946 break;
947
948 case E_ZONE_EDGE_RIGHT:
949 if ((E_SPANS_COMMON(zone->y, zone->h, z2->y, z2->h)) &&
950 (z2->x >= (zone->x + zone->w)))
951 return EINA_TRUE;
952 break;
953
954 case E_ZONE_EDGE_BOTTOM_LEFT:
955 if (((E_SPANS_COMMON(0, zone->x + zone->w, z2->x, z2->w)) &&
956 (z2->y >= (zone->y + zone->h))) ||
957 ((E_SPANS_COMMON(zone->y, 99999, z2->y, z2->h)) &&
958 (z2->x < zone->x)))
959 return EINA_TRUE;
960 break;
961
962 case E_ZONE_EDGE_BOTTOM:
963 if ((E_SPANS_COMMON(zone->x, zone->w, z2->x, z2->w)) &&
964 (z2->y >= (zone->y + zone->h)))
965 return EINA_TRUE;
966 break;
967
968 case E_ZONE_EDGE_BOTTOM_RIGHT:
969 if (((E_SPANS_COMMON(zone->x, 99999, z2->x, z2->w)) &&
970 (z2->y >= (zone->y + zone->h))) ||
971 ((E_SPANS_COMMON(zone->y, 99999, z2->y, z2->h)) &&
972 (z2->x < zone->x)))
973 return EINA_TRUE;
974 break;
975
976 default:
977 break;
978 }
979 }
980
981 return EINA_FALSE;
982 }
983
984 E_API void
e_zone_edge_flip_eval(E_Zone * zone)985 e_zone_edge_flip_eval(E_Zone *zone)
986 {
987 Eina_Bool lf, rf, tf, bf;
988
989 lf = rf = tf = bf = EINA_TRUE;
990 if (zone->desk_x_count <= 1) lf = rf = EINA_FALSE;
991 else if (!e_config->desk_flip_wrap)
992 {
993 if (zone->desk_x_current == 0) lf = EINA_FALSE;
994 if (zone->desk_x_current == (zone->desk_x_count - 1)) rf = EINA_FALSE;
995 }
996 if (zone->desk_y_count <= 1) tf = bf = EINA_FALSE;
997 else if (!e_config->desk_flip_wrap)
998 {
999 if (zone->desk_y_current == 0) tf = EINA_FALSE;
1000 if (zone->desk_y_current == (zone->desk_y_count - 1)) bf = EINA_FALSE;
1001 }
1002 e_zone_edges_desk_flip_capable(zone, lf, rf, tf, bf);
1003 }
1004
1005 E_API void
e_zone_edge_new(E_Zone_Edge edge)1006 e_zone_edge_new(E_Zone_Edge edge)
1007 {
1008 const Eina_List *l;
1009 E_Zone *zone;
1010 int cw, ch;
1011
1012 if (edge == E_ZONE_EDGE_NONE) return;
1013
1014 EINA_LIST_FOREACH(e_comp->zones, l, zone)
1015 {
1016 // don't allow bindings on edges that are on the boundary
1017 // between zones
1018 if (e_zone_exists_direction(zone, edge)) continue;
1019 cw = zone->w * E_ZONE_CORNER_RATIO;
1020 ch = zone->h * E_ZONE_CORNER_RATIO;
1021 switch (edge)
1022 {
1023 #define EDGE_NEW(MEMBER, X, Y, W, H) do { \
1024 if (!zone->MEMBER) \
1025 { \
1026 zone->MEMBER = evas_object_rectangle_add(e_comp->evas); \
1027 evas_object_name_set(zone->MEMBER, #MEMBER); \
1028 evas_object_move(zone->MEMBER, (X), (Y)); \
1029 evas_object_resize(zone->MEMBER, (W), (H)); \
1030 evas_object_repeat_events_set(zone->MEMBER, 1); \
1031 evas_object_data_set(zone->MEMBER, "comp_repeat", (void*)1); \
1032 evas_object_color_set(zone->MEMBER, 0, 0, 0, 0); \
1033 evas_object_event_callback_add(zone->MEMBER, EVAS_CALLBACK_MOUSE_MOVE, _e_zone_cb_mouse_move, zone); \
1034 evas_object_event_callback_add(zone->MEMBER, EVAS_CALLBACK_MOUSE_IN, _e_zone_cb_mouse_in, zone); \
1035 evas_object_event_callback_add(zone->MEMBER, EVAS_CALLBACK_MOUSE_OUT, _e_zone_cb_mouse_out, zone); \
1036 evas_object_event_callback_add(zone->MEMBER, EVAS_CALLBACK_MOUSE_DOWN, _e_zone_cb_mouse_down, zone); \
1037 evas_object_event_callback_add(zone->MEMBER, EVAS_CALLBACK_MOUSE_UP, _e_zone_cb_mouse_up, zone); \
1038 evas_object_show(zone->MEMBER); \
1039 } \
1040 } while (0)
1041
1042 case E_ZONE_EDGE_LEFT:
1043 EDGE_NEW(edge.left, zone->x, zone->y + ch, 1, zone->h - 2 * ch);
1044 break;
1045 case E_ZONE_EDGE_RIGHT:
1046 EDGE_NEW(edge.right, zone->x + zone->w - 1, zone->y + ch, 1, zone->h - 2 * ch);
1047 break;
1048 case E_ZONE_EDGE_TOP:
1049 EDGE_NEW(edge.top, zone->x + 1 + cw, zone->y, zone->w - 2 * cw - 2, 1);
1050 break;
1051 case E_ZONE_EDGE_BOTTOM:
1052 EDGE_NEW(edge.bottom, zone->x + 1 + cw, zone->y + zone->h - 1, zone->w - 2 - 2 * cw, 1);
1053 break;
1054 case E_ZONE_EDGE_TOP_LEFT:
1055 EDGE_NEW(corner.left_top, zone->x, zone->y, 1, ch);
1056 EDGE_NEW(corner.top_left, zone->x + 1, zone->y, cw, 1);
1057 break;
1058 case E_ZONE_EDGE_TOP_RIGHT:
1059 EDGE_NEW(corner.top_right, zone->x + zone->w - cw - 2, zone->y, cw, 1);
1060 EDGE_NEW(corner.right_top, zone->x + zone->w - 1, zone->y, 1, ch);
1061 break;
1062 case E_ZONE_EDGE_BOTTOM_RIGHT:
1063 EDGE_NEW(corner.right_bottom, zone->x + zone->w - 1, zone->y + zone->h - ch, 1, ch);
1064 EDGE_NEW(corner.bottom_right, zone->x + zone->w - cw - 2, zone->y + zone->h - 1, cw, 1);
1065 break;
1066 case E_ZONE_EDGE_BOTTOM_LEFT:
1067 EDGE_NEW(corner.bottom_left, zone->x + 1, zone->y + zone->h - 1, cw, 1);
1068 EDGE_NEW(corner.left_bottom, zone->x, zone->y + zone->h - ch, 1, ch);
1069 break;
1070 default: continue;
1071 }
1072 if (e_config->fullscreen_flip)
1073 e_zone_edge_win_layer_set(zone, E_LAYER_CLIENT_EDGE_FULLSCREEN);
1074 else
1075 e_zone_edge_win_layer_set(zone, E_LAYER_CLIENT_EDGE);
1076 }
1077 }
1078
1079 E_API void
e_zone_edge_free(E_Zone_Edge edge)1080 e_zone_edge_free(E_Zone_Edge edge)
1081 {
1082 const Eina_List *l;
1083 E_Zone *zone;
1084
1085 if (edge == E_ZONE_EDGE_NONE) return;
1086 EINA_LIST_FOREACH(e_comp->zones, l, zone)
1087 {
1088 if (zone->flip.switching == edge)
1089 zone->flip.switching = E_ZONE_EDGE_NONE;
1090 switch (edge)
1091 {
1092 case E_ZONE_EDGE_NONE:
1093 /* noop */
1094 break;
1095
1096 case E_ZONE_EDGE_LEFT:
1097 E_FREE_FUNC(zone->edge.left, evas_object_del);
1098 break;
1099
1100 case E_ZONE_EDGE_RIGHT:
1101 E_FREE_FUNC(zone->edge.right, evas_object_del);
1102 break;
1103
1104 case E_ZONE_EDGE_TOP:
1105 E_FREE_FUNC(zone->edge.top, evas_object_del);
1106 break;
1107
1108 case E_ZONE_EDGE_BOTTOM:
1109 E_FREE_FUNC(zone->edge.bottom, evas_object_del);
1110 break;
1111
1112 case E_ZONE_EDGE_TOP_LEFT:
1113 E_FREE_FUNC(zone->corner.left_top, evas_object_del);
1114 E_FREE_FUNC(zone->corner.top_left, evas_object_del);
1115 break;
1116
1117 case E_ZONE_EDGE_TOP_RIGHT:
1118 E_FREE_FUNC(zone->corner.top_right, evas_object_del);
1119 E_FREE_FUNC(zone->corner.right_top, evas_object_del);
1120 break;
1121
1122 case E_ZONE_EDGE_BOTTOM_RIGHT:
1123 E_FREE_FUNC(zone->corner.right_bottom, evas_object_del);
1124 E_FREE_FUNC(zone->corner.bottom_right, evas_object_del);
1125 break;
1126
1127 case E_ZONE_EDGE_BOTTOM_LEFT:
1128 E_FREE_FUNC(zone->corner.bottom_left, evas_object_del);
1129 E_FREE_FUNC(zone->corner.left_bottom, evas_object_del);
1130 break;
1131 }
1132 }
1133 }
1134
1135 E_API void
e_zone_edge_win_layer_set(E_Zone * zone,E_Layer layer)1136 e_zone_edge_win_layer_set(E_Zone *zone, E_Layer layer)
1137 {
1138 #define EDGE_STACK(EDGE) do { \
1139 if (zone->EDGE) \
1140 { \
1141 evas_object_layer_set(zone->EDGE, layer); \
1142 evas_object_stack_below(zone->EDGE, e_comp->layers[e_comp_canvas_layer_map(layer)].obj); \
1143 } \
1144 } while (0)
1145
1146 EDGE_STACK(corner.left_bottom);
1147 EDGE_STACK(corner.left_top);
1148 EDGE_STACK(corner.top_left);
1149 EDGE_STACK(corner.top_right);
1150 EDGE_STACK(corner.right_top);
1151 EDGE_STACK(corner.right_bottom);
1152 EDGE_STACK(corner.bottom_right);
1153 EDGE_STACK(corner.bottom_left);
1154
1155 EDGE_STACK(edge.left);
1156 EDGE_STACK(edge.right);
1157 EDGE_STACK(edge.top);
1158 EDGE_STACK(edge.bottom);
1159 }
1160
1161 E_API void
e_zone_fade_handle(E_Zone * zone,int out,double tim)1162 e_zone_fade_handle(E_Zone *zone, int out, double tim)
1163 {
1164 EINA_SAFETY_ON_NULL_RETURN(zone);
1165 if (out == 1)
1166 {
1167 if ((e_backlight_exists()) && (!e_comp_config_get()->nofade))
1168 {
1169 e_backlight_update();
1170 zone->bloff = EINA_TRUE;
1171 zone->bl = e_backlight_level_get(zone);
1172 e_backlight_level_set(zone, 0.0, tim);
1173 }
1174 }
1175 else
1176 {
1177 if ((e_backlight_exists()) && (!e_comp_config_get()->nofade))
1178 {
1179 zone->bloff = EINA_FALSE;
1180 e_backlight_update();
1181 if (e_backlight_mode_get(zone) != E_BACKLIGHT_MODE_NORMAL)
1182 e_backlight_mode_set(zone, E_BACKLIGHT_MODE_NORMAL);
1183 else
1184 e_backlight_level_set(zone, e_config->backlight.normal, tim);
1185 }
1186 }
1187 }
1188
1189 static void
_e_zone_useful_geometry_calc(const E_Zone * zone,int dx,int dy,int * x,int * y,int * w,int * h)1190 _e_zone_useful_geometry_calc(const E_Zone *zone, int dx, int dy, int *x, int *y, int *w, int *h)
1191 {
1192 E_Desk *desk;
1193 E_Zone_Obstacle *obs;
1194 Eina_Tiler *tiler;
1195 int zx, zy, zw, zh;
1196 Eina_Iterator *it;
1197 Eina_Rectangle geom = { 0 } , *rect;
1198 int size = 0;
1199
1200 zx = zone->x;
1201 zy = zone->y;
1202 zw = zone->w;
1203 zh = zone->h;
1204 tiler = eina_tiler_new(zw, zh);
1205 eina_tiler_tile_size_set(tiler, 1, 1);
1206 eina_tiler_rect_add(tiler, &(Eina_Rectangle){0, 0, zw, zh});
1207 EINA_INLIST_FOREACH(zone->obstacles, obs)
1208 {
1209 if (!E_INTERSECTS(obs->x, obs->y, obs->w, obs->h, zx, zy, zw, zh)) continue;
1210 if (obs->vertical)
1211 eina_tiler_rect_del(tiler, &(Eina_Rectangle){obs->x - zx, 0, obs->w, zh});
1212 else
1213 eina_tiler_rect_del(tiler, &(Eina_Rectangle){0, obs->y - zy, zw, obs->h});
1214 }
1215 desk = e_desk_at_xy_get(zone, dx, dy);
1216 if (desk)
1217 {
1218 EINA_INLIST_FOREACH(desk->obstacles, obs)
1219 {
1220 if (!E_INTERSECTS(obs->x, obs->y, obs->w, obs->h, zx, zy, zw, zh)) continue;
1221 if (obs->vertical)
1222 eina_tiler_rect_del(tiler, &(Eina_Rectangle){obs->x - zx, 0, obs->w, zh});
1223 else
1224 eina_tiler_rect_del(tiler, &(Eina_Rectangle){0, obs->y - zy, zw, obs->h});
1225 }
1226 }
1227 it = eina_tiler_iterator_new(tiler);
1228 EINA_ITERATOR_FOREACH(it, rect)
1229 {
1230 if (rect->w * rect->h < size) continue;
1231 size = rect->w * rect->h;
1232 geom = *rect;
1233 }
1234 eina_iterator_free(it);
1235 eina_tiler_free(tiler);
1236
1237 if (x) *x = geom.x + zx;
1238 if (y) *y = geom.y + zy;
1239 if (w) *w = geom.w;
1240 if (h) *h = geom.h;
1241 }
1242
1243 /**
1244 * Get (or calculate) the useful (or free, without any shelves) area.
1245 */
1246 E_API Eina_Bool
e_zone_useful_geometry_get(E_Zone * zone,int * x,int * y,int * w,int * h)1247 e_zone_useful_geometry_get(E_Zone *zone,
1248 int *x,
1249 int *y,
1250 int *w,
1251 int *h)
1252 {
1253 int zx, zy, zw, zh;
1254
1255 E_OBJECT_CHECK_RETURN(zone, EINA_FALSE);
1256 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, EINA_FALSE);
1257
1258 if (zone->useful_geometry_dirty)
1259 {
1260 _e_zone_useful_geometry_calc(zone, zone->desk_x_current, zone->desk_y_current, &zx, &zy, &zw, &zh);
1261 memcpy(&zone->useful_geometry[0], &zone->useful_geometry[1], sizeof(Eina_Rectangle));
1262 zone->useful_geometry[1].x = zx;
1263 zone->useful_geometry[1].y = zy;
1264 zone->useful_geometry[1].w = zw;
1265 zone->useful_geometry[1].h = zh;
1266 zone->useful_geometry_changed =
1267 !!memcmp(&zone->useful_geometry[0], &zone->useful_geometry[1], sizeof(Eina_Rectangle));
1268
1269 }
1270 zone->useful_geometry_dirty = 0;
1271
1272 if (x) *x = zone->useful_geometry[1].x;
1273 if (y) *y = zone->useful_geometry[1].y;
1274 if (w) *w = zone->useful_geometry[1].w;
1275 if (h) *h = zone->useful_geometry[1].h;
1276 return zone->useful_geometry_changed;
1277 }
1278
1279 E_API void
e_zone_desk_useful_geometry_get(const E_Zone * zone,const E_Desk * desk,int * x,int * y,int * w,int * h)1280 e_zone_desk_useful_geometry_get(const E_Zone *zone, const E_Desk *desk, int *x, int *y, int *w, int *h)
1281 {
1282 E_OBJECT_CHECK(zone);
1283 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1284 E_OBJECT_CHECK(desk);
1285 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1286
1287 if (desk->zone != zone) CRI("zone/desk mismatch!");
1288
1289 _e_zone_useful_geometry_calc(zone, desk->x, desk->y, x, y, w, h);
1290 }
1291
1292 /**
1293 * Mark as dirty so e_zone_useful_geometry_get() will need to recalculate.
1294 *
1295 * Call this function when shelves are added or important properties changed.
1296 */
1297 E_API void
e_zone_useful_geometry_dirty(E_Zone * zone)1298 e_zone_useful_geometry_dirty(E_Zone *zone)
1299 {
1300 E_Event_Zone_Move_Resize *ev;
1301
1302 E_OBJECT_CHECK(zone);
1303 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1304
1305 /* ignore if pending event already exists */
1306 if (zone->useful_geometry_dirty) return;
1307
1308 zone->useful_geometry_dirty = 1;
1309 if (!e_zone_useful_geometry_get(zone, NULL, NULL, NULL, NULL)) return;
1310 ev = E_NEW(E_Event_Zone_Move_Resize, 1);
1311 ev->zone = zone;
1312 e_object_ref(E_OBJECT(ev->zone));
1313 ecore_event_add(E_EVENT_ZONE_USEFUL_GEOMETRY_CHANGED, ev, _e_zone_event_generic_free, NULL);
1314
1315 if (!stopping)
1316 e_comp_clients_rescale();
1317 }
1318
1319 E_API E_Zone_Obstacle *
e_zone_obstacle_add(E_Zone * zone,E_Desk * desk,Eina_Rectangle * geom,Eina_Bool vertical)1320 e_zone_obstacle_add(E_Zone *zone, E_Desk *desk, Eina_Rectangle *geom, Eina_Bool vertical)
1321 {
1322 E_Zone_Obstacle *obs;
1323
1324 E_OBJECT_CHECK_RETURN(zone, NULL);
1325 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
1326 if (desk)
1327 {
1328 E_OBJECT_CHECK_RETURN(desk, NULL);
1329 E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, NULL);
1330 if (desk->zone != zone)
1331 {
1332 ERR("zone != desk->zone");
1333 return NULL;
1334 }
1335 }
1336 obs = E_OBJECT_ALLOC(E_Zone_Obstacle, E_ZONE_OBSTACLE_TYPE, _e_zone_obstacle_free);
1337 obs->x = geom->x, obs->y = geom->y;
1338 obs->w = geom->w, obs->h = geom->h;
1339 obs->owner = E_OBJECT(desk) ?: E_OBJECT(zone);
1340 obs->vertical = !!vertical;
1341 if (desk)
1342 {
1343 desk->obstacles = eina_inlist_append(desk->obstacles, EINA_INLIST_GET(obs));
1344 if (desk->visible)
1345 e_zone_useful_geometry_dirty(desk->zone);
1346 }
1347 else
1348 {
1349 zone->obstacles = eina_inlist_append(zone->obstacles, EINA_INLIST_GET(obs));
1350 e_zone_useful_geometry_dirty(zone);
1351 }
1352 return obs;
1353 }
1354
1355 E_API void
e_zone_obstacle_modify(E_Zone_Obstacle * obs,Eina_Rectangle * geom,Eina_Bool vertical)1356 e_zone_obstacle_modify(E_Zone_Obstacle *obs, Eina_Rectangle *geom, Eina_Bool vertical)
1357 {
1358 E_Zone *zone;
1359 E_Desk *desk;
1360
1361 E_OBJECT_CHECK(obs);
1362 E_OBJECT_TYPE_CHECK(obs, E_ZONE_OBSTACLE_TYPE);
1363 EINA_SAFETY_ON_NULL_RETURN(geom);
1364 if ((obs->x == geom->x) && (obs->y == geom->y) && (obs->w == geom->w) && (obs->h == geom->h))
1365 return;
1366 obs->x = geom->x, obs->y = geom->y;
1367 obs->w = geom->w, obs->h = geom->h;
1368 obs->vertical = !!vertical;
1369
1370 if (obs->owner->type == E_DESK_TYPE)
1371 {
1372 desk = (void *)obs->owner;
1373 if (desk->visible)
1374 e_zone_useful_geometry_dirty(desk->zone);
1375 }
1376 else
1377 {
1378 zone = (void *)obs->owner;
1379 e_zone_useful_geometry_dirty(zone);
1380 }
1381 }
1382
1383 E_API void
e_zone_stow(E_Zone * zone)1384 e_zone_stow(E_Zone *zone)
1385 {
1386 E_Event_Zone_Stow *ev;
1387
1388 E_OBJECT_CHECK(zone);
1389 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1390 if (zone->stowed) return;
1391 ev = E_NEW(E_Event_Zone_Stow, 1);
1392 ev->zone = zone;
1393 e_object_ref(E_OBJECT(ev->zone));
1394 ecore_event_add(E_EVENT_ZONE_STOW, ev, _e_zone_event_generic_free, NULL);
1395
1396 zone->stowed = EINA_TRUE;
1397 }
1398
1399 E_API void
e_zone_unstow(E_Zone * zone)1400 e_zone_unstow(E_Zone *zone)
1401 {
1402 E_Event_Zone_Unstow *ev;
1403
1404 E_OBJECT_CHECK(zone);
1405 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1406 if (!zone->stowed) return;
1407 ev = E_NEW(E_Event_Zone_Unstow, 1);
1408 ev->zone = zone;
1409 e_object_ref(E_OBJECT(ev->zone));
1410 ecore_event_add(E_EVENT_ZONE_UNSTOW, ev, _e_zone_event_generic_free, NULL);
1411
1412 zone->stowed = EINA_FALSE;
1413 }
1414
1415 /* local subsystem functions */
1416 static void
_e_zone_free(E_Zone * zone)1417 _e_zone_free(E_Zone *zone)
1418 {
1419 int x, y;
1420
1421 //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);
1422 /* Delete the edge windows if they exist */
1423 E_FREE_FUNC(zone->edge.top, evas_object_del);
1424 E_FREE_FUNC(zone->edge.bottom, evas_object_del);
1425 E_FREE_FUNC(zone->edge.left, evas_object_del);
1426 E_FREE_FUNC(zone->edge.right, evas_object_del);
1427 E_FREE_FUNC(zone->corner.left_bottom, evas_object_del);
1428 E_FREE_FUNC(zone->corner.left_top, evas_object_del);
1429 E_FREE_FUNC(zone->corner.top_left, evas_object_del);
1430 E_FREE_FUNC(zone->corner.top_right, evas_object_del);
1431 E_FREE_FUNC(zone->corner.right_top, evas_object_del);
1432 E_FREE_FUNC(zone->corner.right_bottom, evas_object_del);
1433 E_FREE_FUNC(zone->corner.bottom_right, evas_object_del);
1434 E_FREE_FUNC(zone->corner.bottom_left, evas_object_del);
1435
1436 /* Delete the object event callbacks */
1437 evas_object_event_callback_del(zone->bg_event_object,
1438 EVAS_CALLBACK_MOUSE_DOWN,
1439 _e_zone_cb_bg_mouse_down);
1440 evas_object_event_callback_del(zone->bg_event_object,
1441 EVAS_CALLBACK_MOUSE_UP,
1442 _e_zone_cb_bg_mouse_up);
1443
1444 E_FREE_FUNC(zone->cur_mouse_action, e_object_unref);
1445
1446 /* remove handlers */
1447 E_FREE_LIST(zone->handlers, ecore_event_handler_del);
1448
1449 if (zone->name) eina_stringshare_del(zone->name);
1450 e_comp->zones = eina_list_remove(e_comp->zones, zone);
1451 evas_object_del(zone->bg_event_object);
1452 evas_object_del(zone->bg_clip_object);
1453 evas_object_del(zone->bg_object);
1454 if (zone->prev_bg_object) evas_object_del(zone->prev_bg_object);
1455 if (zone->transition_object) evas_object_del(zone->transition_object);
1456
1457 evas_object_del(zone->base);
1458 evas_object_del(zone->over);
1459 if ((!stopping) && (!e_comp_config_get()->nofade))
1460 {
1461 if (zone->bloff)
1462 {
1463 if (e_backlight_mode_get(zone) != E_BACKLIGHT_MODE_NORMAL)
1464 e_backlight_mode_set(zone, E_BACKLIGHT_MODE_NORMAL);
1465 e_backlight_level_set(zone, e_config->backlight.normal, 0.0);
1466 }
1467 }
1468
1469 /* free desks */
1470 for (x = 0; x < zone->desk_x_count; x++)
1471 {
1472 for (y = 0; y < zone->desk_y_count; y++)
1473 e_object_del(E_OBJECT(zone->desks[x + (y * zone->desk_x_count)]));
1474 }
1475 while (zone->obstacles)
1476 {
1477 E_Object *obs = (void*)EINA_INLIST_CONTAINER_GET(zone->obstacles, E_Zone_Obstacle);
1478 e_object_del(obs);
1479 }
1480 free(zone->desks);
1481 free(zone->randr2_id);
1482 free(zone);
1483 }
1484
1485 static void
_e_zone_cb_bg_mouse_down(void * data,Evas * evas EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1486 _e_zone_cb_bg_mouse_down(void *data,
1487 Evas *evas EINA_UNUSED,
1488 Evas_Object *obj EINA_UNUSED,
1489 void *event_info)
1490 {
1491 E_Zone *zone = data;
1492 Evas_Event_Mouse_Down *ev = event_info;
1493
1494 if (e_comp_util_mouse_grabbed()) return;
1495 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1496
1497 if (!zone->cur_mouse_action)
1498 {
1499 zone->cur_mouse_action =
1500 e_bindings_mouse_down_evas_event_handle(E_BINDING_CONTEXT_ZONE,
1501 E_OBJECT(zone), event_info);
1502 if (zone->cur_mouse_action)
1503 {
1504 if ((!zone->cur_mouse_action->func.end_mouse) &&
1505 (!zone->cur_mouse_action->func.end))
1506 zone->cur_mouse_action = NULL;
1507 if (zone->cur_mouse_action)
1508 e_object_ref(E_OBJECT(zone->cur_mouse_action));
1509 }
1510 }
1511 }
1512
1513 static void
_e_zone_cb_bg_mouse_up(void * data,Evas * evas EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1514 _e_zone_cb_bg_mouse_up(void *data,
1515 Evas *evas EINA_UNUSED,
1516 Evas_Object *obj EINA_UNUSED,
1517 void *event_info)
1518 {
1519 E_Zone *zone = data;
1520 Evas_Event_Mouse_Up *ev = event_info;
1521
1522 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1523 if (zone->cur_mouse_action)
1524 {
1525 E_Binding_Event_Mouse_Button event;
1526
1527 e_bindings_evas_event_mouse_button_convert(event_info, &event);
1528 if (zone->cur_mouse_action->func.end_mouse)
1529 zone->cur_mouse_action->func.end_mouse(E_OBJECT(zone), "", &event);
1530 else if (zone->cur_mouse_action->func.end)
1531 zone->cur_mouse_action->func.end(E_OBJECT(zone), "");
1532
1533 e_object_unref(E_OBJECT(zone->cur_mouse_action));
1534 zone->cur_mouse_action = NULL;
1535 }
1536 else
1537 {
1538 E_Binding_Event_Mouse_Button event;
1539
1540 e_bindings_ecore_event_mouse_button_convert(event_info, &event);
1541 e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_ZONE,
1542 E_OBJECT(zone), &event);
1543 }
1544 }
1545
1546 static Eina_Bool
_e_zone_cb_edge_timer(void * data)1547 _e_zone_cb_edge_timer(void *data)
1548 {
1549 E_Zone *zone;
1550 E_Action *act;
1551
1552 zone = data;
1553 act = e_action_find(zone->flip.bind->action);
1554 if (!act)
1555 {
1556 E_FREE(zone->flip.ev);
1557 return ECORE_CALLBACK_CANCEL;
1558 }
1559
1560 if (act->func.go_edge)
1561 act->func.go_edge(E_OBJECT(zone), zone->flip.bind->params, zone->flip.ev);
1562 else if (act->func.go)
1563 act->func.go(E_OBJECT(zone), zone->flip.bind->params);
1564
1565 zone->flip.bind->timer = NULL;
1566
1567 E_FREE(zone->flip.ev);
1568 return ECORE_CALLBACK_CANCEL;
1569 }
1570
1571 static void
_e_zone_event_generic_free(void * data EINA_UNUSED,void * ev)1572 _e_zone_event_generic_free(void *data EINA_UNUSED, void *ev)
1573 {
1574 struct _E_Event_Zone_Generic *e;
1575 // also handes E_Event_Zone_Add, E_Event_Zone_Del, E_Event_Zone_Stow,
1576 // E_Event_Zone_Unstow, E_Event_Zone_Desk_Count_Set due to them all
1577 // having the same content
1578
1579 e = ev;
1580 e_object_unref(E_OBJECT(e->zone));
1581 free(e);
1582 }
1583
1584 static void
_e_zone_object_del_attach(void * o)1585 _e_zone_object_del_attach(void *o)
1586 {
1587 E_Zone *zone;
1588 E_Event_Zone_Del *ev;
1589
1590 zone = o;
1591 if (stopping) return;
1592 ev = E_NEW(E_Event_Zone_Del, 1);
1593 ev->zone = zone;
1594 e_object_ref(E_OBJECT(ev->zone));
1595 ecore_event_add(E_EVENT_ZONE_DEL, ev, _e_zone_event_generic_free, NULL);
1596 }
1597
1598 static E_Zone_Edge
_e_zone_detect_edge(E_Zone * zone,Evas_Object * obj)1599 _e_zone_detect_edge(E_Zone *zone, Evas_Object *obj)
1600 {
1601 E_Zone_Edge edge = E_ZONE_EDGE_NONE;
1602
1603 if (obj == zone->edge.left)
1604 edge = E_ZONE_EDGE_LEFT;
1605 else if (obj == zone->edge.top)
1606 edge = E_ZONE_EDGE_TOP;
1607 else if (obj == zone->edge.right)
1608 edge = E_ZONE_EDGE_RIGHT;
1609 else if (obj == zone->edge.bottom)
1610 edge = E_ZONE_EDGE_BOTTOM;
1611 else if ((obj == zone->corner.left_top) ||
1612 (obj == zone->corner.top_left))
1613 edge = E_ZONE_EDGE_TOP_LEFT;
1614 else if ((obj == zone->corner.right_top) ||
1615 (obj == zone->corner.top_right))
1616 edge = E_ZONE_EDGE_TOP_RIGHT;
1617 else if ((obj == zone->corner.right_bottom) ||
1618 (obj == zone->corner.bottom_right))
1619 edge = E_ZONE_EDGE_BOTTOM_RIGHT;
1620 else if ((obj == zone->corner.left_bottom) ||
1621 (obj == zone->corner.bottom_left))
1622 edge = E_ZONE_EDGE_BOTTOM_LEFT;
1623 return edge;
1624 }
1625
1626 static void
_e_zone_edge_move_resize(E_Zone * zone)1627 _e_zone_edge_move_resize(E_Zone *zone)
1628 {
1629 int cw;
1630 int ch;
1631
1632 cw = zone->w * E_ZONE_CORNER_RATIO;
1633 ch = zone->h * E_ZONE_CORNER_RATIO;
1634
1635 evas_object_geometry_set(zone->corner.left_bottom,
1636 zone->x, zone->y + zone->h - ch, 1, ch);
1637 evas_object_geometry_set(zone->edge.left,
1638 zone->x, zone->y + ch, 1, zone->h - 2 * ch);
1639 evas_object_geometry_set(zone->corner.left_top,
1640 zone->x, zone->y, 1, ch);
1641
1642 evas_object_geometry_set(zone->corner.top_left,
1643 zone->x + 1, zone->y, cw, 1);
1644 evas_object_geometry_set(zone->edge.top,
1645 zone->x + 1 + cw, zone->y, zone->w - 2 * cw - 2, 1);
1646 evas_object_geometry_set(zone->corner.top_right,
1647 zone->x + zone->w - cw - 2, zone->y, cw, 1);
1648
1649 evas_object_geometry_set(zone->corner.right_top,
1650 zone->x + zone->w - 1, zone->y, 1, ch);
1651 evas_object_geometry_set(zone->edge.right,
1652 zone->x + zone->w - 1, zone->y + ch, 1, zone->h - 2 * ch);
1653 evas_object_geometry_set(zone->corner.right_bottom,
1654 zone->x + zone->w - 1, zone->y + zone->h - ch, 1, ch);
1655
1656 evas_object_geometry_set(zone->corner.bottom_right,
1657 zone->x + 1, zone->y + zone->h - 1, cw, 1);
1658 evas_object_geometry_set(zone->edge.bottom,
1659 zone->x + 1 + cw, zone->y + zone->h - 1, zone->w - 2 - 2 * cw, 1);
1660 evas_object_geometry_set(zone->corner.bottom_left,
1661 zone->x + zone->w - cw - 2, zone->y + zone->h - 1, cw, 1);
1662 }
1663
1664 static void
_e_zone_obstacle_free(E_Zone_Obstacle * obs)1665 _e_zone_obstacle_free(E_Zone_Obstacle *obs)
1666 {
1667 E_Zone *zone;
1668 E_Desk *desk;
1669
1670 if (obs->owner->type == E_DESK_TYPE)
1671 {
1672 desk = (void *)obs->owner;
1673 desk->obstacles = eina_inlist_remove(desk->obstacles, EINA_INLIST_GET(obs));
1674 if (desk->visible)
1675 e_zone_useful_geometry_dirty(desk->zone);
1676 }
1677 else
1678 {
1679 zone = (void *)obs->owner;
1680 zone->obstacles = eina_inlist_remove(zone->obstacles, EINA_INLIST_GET(obs));
1681 e_zone_useful_geometry_dirty(zone);
1682 }
1683 free(obs);
1684 }
1685
1686 E_API E_Zone *
e_zone_for_id_get(const char * id)1687 e_zone_for_id_get(const char *id)
1688 {
1689 Eina_List *l = NULL;
1690 E_Zone *zone;
1691
1692 if (!e_comp) return NULL;
1693
1694 EINA_LIST_FOREACH(e_comp->zones, l, zone)
1695 {
1696 if (eina_streq(zone->randr2_id, id))
1697 return zone;
1698 }
1699
1700 return NULL;
1701 }
1702