3 /* E_Desk is a child object of E_Zone. A desk is essentially a background
4 * and an associated set of client windows. Each zone can have an arbitrary
8 static void _e_desk_free(E_Desk *desk);
9 static void _e_desk_event_desk_show_free(void *data, void *ev);
10 static void _e_desk_event_desk_before_show_free(void *data, void *ev);
11 static void _e_desk_event_desk_after_show_free(void *data, void *ev);
12 static void _e_desk_event_desk_deskshow_free(void *data, void *ev);
13 static void _e_desk_event_desk_name_change_free(void *data, void *ev);
14 static void _e_desk_show_begin(E_Desk *desk, int mode, int dx, int dy);
15 static void _e_desk_show_end(E_Desk *desk);
16 static Eina_Bool _e_desk_show_animator(void *data);
17 static void _e_desk_hide_begin(E_Desk *desk, int mode, int dx, int dy);
18 static void _e_desk_hide_end(E_Desk *desk);
19 static Eina_Bool _e_desk_hide_animator(void *data);
21 EAPI int E_EVENT_DESK_SHOW = 0;
22 EAPI int E_EVENT_DESK_BEFORE_SHOW = 0;
23 EAPI int E_EVENT_DESK_AFTER_SHOW = 0;
24 EAPI int E_EVENT_DESK_DESKSHOW = 0;
25 EAPI int E_EVENT_DESK_NAME_CHANGE = 0;
30 E_EVENT_DESK_SHOW = ecore_event_type_new();
31 E_EVENT_DESK_BEFORE_SHOW = ecore_event_type_new();
32 E_EVENT_DESK_AFTER_SHOW = ecore_event_type_new();
33 E_EVENT_DESK_DESKSHOW = ecore_event_type_new();
34 E_EVENT_DESK_NAME_CHANGE = ecore_event_type_new();
45 e_desk_new(E_Zone *zone, int x, int y)
49 E_Config_Desktop_Name *cfname;
53 E_OBJECT_CHECK_RETURN(zone, NULL);
54 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
56 desk = E_OBJECT_ALLOC(E_Desk, E_DESK_TYPE, _e_desk_free);
57 if (!desk) return NULL;
63 /* Get current desktop's name */
65 EINA_LIST_FOREACH(e_config->desktop_names, l, cfname)
67 if ((cfname->container >= 0) &&
68 ((int) zone->container->num != cfname->container)) continue;
69 if ((cfname->zone >= 0) &&
70 ((int) zone->num != cfname->zone)) continue;
71 if ((cfname->desk_x != desk->x) || (cfname->desk_y != desk->y))
73 desk->name = eina_stringshare_add(cfname->name);
80 snprintf(name, sizeof(name), _(e_config->desktop_default_name), x, y);
81 desk->name = eina_stringshare_add(name);
88 e_desk_name_set(E_Desk *desk, const char *name)
90 E_Event_Desk_Name_Change *ev;
93 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
94 if (desk->name) eina_stringshare_del(desk->name);
95 desk->name = eina_stringshare_add(name);
97 ev = E_NEW(E_Event_Desk_Name_Change, 1);
99 e_object_ref(E_OBJECT(desk));
100 ecore_event_add(E_EVENT_DESK_NAME_CHANGE, ev,
101 _e_desk_event_desk_name_change_free, NULL);
105 e_desk_name_add(int container, int zone, int desk_x, int desk_y, const char *name)
107 E_Config_Desktop_Name *cfname;
109 e_desk_name_del(container, zone, desk_x, desk_y);
110 cfname = E_NEW(E_Config_Desktop_Name, 1);
111 cfname->container = container;
113 cfname->desk_x = desk_x;
114 cfname->desk_y = desk_y;
115 if (name) cfname->name = eina_stringshare_add(name);
116 e_config->desktop_names = eina_list_append(e_config->desktop_names, cfname);
120 e_desk_name_del(int container, int zone, int desk_x, int desk_y)
123 E_Config_Desktop_Name *cfname = NULL;
125 EINA_LIST_FOREACH(e_config->desktop_names, l, cfname)
127 if ((cfname->container == container) && (cfname->zone == zone) &&
128 (cfname->desk_x == desk_x) && (cfname->desk_y == desk_y))
130 e_config->desktop_names =
131 eina_list_remove_list(e_config->desktop_names, l);
132 if (cfname->name) eina_stringshare_del(cfname->name);
140 e_desk_name_update(void)
142 Eina_List *m, *c, *z, *l;
147 E_Config_Desktop_Name *cfname;
151 EINA_LIST_FOREACH(e_manager_list(), m, man)
153 EINA_LIST_FOREACH(man->containers, c, con)
155 EINA_LIST_FOREACH(con->zones, z, zone)
157 for (d_x = 0; d_x < zone->desk_x_count; d_x++)
159 for (d_y = 0; d_y < zone->desk_y_count; d_y++)
161 desk = zone->desks[d_x + zone->desk_x_count * d_y];
164 EINA_LIST_FOREACH(e_config->desktop_names, l, cfname)
166 if ((cfname->container >= 0) &&
167 ((int) con->num != cfname->container)) continue;
168 if ((cfname->zone >= 0) &&
169 ((int) zone->num != cfname->zone)) continue;
170 if ((cfname->desk_x != d_x) ||
171 (cfname->desk_y != d_y)) continue;
172 e_desk_name_set(desk,cfname->name);
179 snprintf(name, sizeof(name),
180 _(e_config->desktop_default_name),
182 e_desk_name_set(desk,name);
192 e_desk_show(E_Desk *desk)
196 E_Event_Desk_Show *ev;
197 E_Event_Desk_Before_Show *eev;
198 E_Event_Desk_After_Show *eeev;
201 int was_zone = 0, x, y, dx = 0, dy = 0, prev_x = 0, prev_y = 0;
203 E_OBJECT_CHECK(desk);
204 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
205 if (desk->visible) return;
207 eev = E_NEW(E_Event_Desk_Before_Show, 1);
208 eev->desk = e_desk_current_get(desk->zone);
209 e_object_ref(E_OBJECT(eev->desk));
210 ecore_event_add(E_EVENT_DESK_BEFORE_SHOW, eev,
211 _e_desk_event_desk_before_show_free, NULL);
213 ecore_x_window_shadow_tree_flush();
214 for (x = 0; x < desk->zone->desk_x_count; x++)
216 for (y = 0; y < desk->zone->desk_y_count; y++)
220 desk2 = e_desk_at_xy_get(desk->zone, x, y);
226 dx = desk->x - desk2->x;
227 dy = desk->y - desk2->y;
228 if (e_config->desk_flip_animate_mode > 0)
229 _e_desk_hide_begin(desk2, e_config->desk_flip_animate_mode,
236 desk->zone->desk_x_current = desk->x;
237 desk->zone->desk_y_current = desk->y;
240 if (desk->zone->bg_object) was_zone = 1;
241 if (e_config->desk_flip_animate_mode == 0)
243 bl = e_container_border_list_first(desk->zone->container);
244 while ((bd = e_container_border_list_next(bl)))
246 if ((bd->desk->zone == desk->zone) && (!bd->iconic))
248 if ((bd->desk == desk) || (bd->sticky))
251 e_border_desk_set(bd, desk);
253 e_border_hide(bd, 2);
256 e_container_border_list_free(bl);
259 if (e_config->desk_flip_animate_mode > 0)
260 _e_desk_show_begin(desk, e_config->desk_flip_animate_mode, dx, dy);
262 if (e_config->focus_last_focused_per_desktop)
263 e_desk_last_focused_focus(desk);
267 if (e_config->desk_flip_pan_bg)
268 e_bg_zone_slide(desk->zone, prev_x, prev_y);
270 e_bg_zone_update(desk->zone, E_BG_TRANSITION_DESK);
273 e_bg_zone_update(desk->zone, E_BG_TRANSITION_START);
275 ev = E_NEW(E_Event_Desk_Show, 1);
277 e_object_ref(E_OBJECT(desk));
278 ecore_event_add(E_EVENT_DESK_SHOW, ev, _e_desk_event_desk_show_free, NULL);
280 EINA_LIST_FOREACH(e_shelf_list(), l, es)
283 E_Config_Shelf *cf_es;
285 E_Config_Shelf_Desk *sd;
289 if (!es->cfg->desk_show_mode) continue;
291 if (!cf_es) continue;
293 zone = e_util_zone_current_get(e_manager_current_get());
294 if (cf_es->zone != (int) zone->num) continue;
296 EINA_LIST_FOREACH(es->cfg->desk_list, ll, sd)
299 if ((desk->x == sd->x) && (desk->y == sd->y))
311 if (e_config->desk_flip_animate_mode == 0)
313 eeev = E_NEW(E_Event_Desk_After_Show, 1);
314 eeev->desk = e_desk_current_get(desk->zone);
315 e_object_ref(E_OBJECT(eeev->desk));
316 ecore_event_add(E_EVENT_DESK_AFTER_SHOW, eeev,
317 _e_desk_event_desk_after_show_free, NULL);
323 e_desk_deskshow(E_Zone *zone)
328 E_Event_Desk_Show *ev;
330 E_OBJECT_CHECK(zone);
331 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
333 desk = e_desk_current_get(zone);
334 bl = e_container_border_list_first(zone->container);
335 ecore_x_window_shadow_tree_flush();
336 while ((bd = e_container_border_list_next(bl)))
338 if (bd->desk == desk)
340 if (desk->deskshow_toggle)
342 if (bd->deskshow) e_border_uniconify(bd);
347 if (bd->iconic) continue;
348 if (bd->client.netwm.state.skip_taskbar) continue;
349 if (bd->user_skip_winlist) continue;
350 e_border_iconify(bd);
355 desk->deskshow_toggle = desk->deskshow_toggle ? 0 : 1;
356 e_container_border_list_free(bl);
357 ev = E_NEW(E_Event_Desk_Show, 1);
359 e_object_ref(E_OBJECT(desk));
360 ecore_event_add(E_EVENT_DESK_DESKSHOW, ev,
361 _e_desk_event_desk_deskshow_free, NULL);
365 e_desk_last_focused_focus(E_Desk *desk)
370 EINA_LIST_FOREACH(e_border_focus_stack_get(), l, bd)
372 if ((!bd->iconic) && (bd->visible) &&
373 ((bd->desk == desk) || ((bd->zone == desk->zone) && bd->sticky)) &&
374 (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus) &&
375 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
376 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
377 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
378 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
379 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
381 /* this was the window last focused in this desktop */
382 if (!bd->lock_focus_out)
384 e_border_focus_set(bd, 1, 1);
392 e_desk_row_add(E_Zone *zone)
394 e_zone_desk_count_set(zone, zone->desk_x_count, zone->desk_y_count + 1);
398 e_desk_row_remove(E_Zone *zone)
400 e_zone_desk_count_set(zone, zone->desk_x_count, zone->desk_y_count - 1);
404 e_desk_col_add(E_Zone *zone)
406 e_zone_desk_count_set(zone, zone->desk_x_count + 1, zone->desk_y_count);
410 e_desk_col_remove(E_Zone *zone)
412 e_zone_desk_count_set(zone, zone->desk_x_count - 1, zone->desk_y_count);
416 e_desk_current_get(E_Zone *zone)
418 E_OBJECT_CHECK_RETURN(zone, NULL);
419 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
421 return e_desk_at_xy_get(zone, zone->desk_x_current, zone->desk_y_current);
425 e_desk_at_xy_get(E_Zone *zone, int x, int y)
427 E_OBJECT_CHECK_RETURN(zone, NULL);
428 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
430 if ((x >= zone->desk_x_count) || (y >= zone->desk_y_count))
432 else if ((x < 0) || (y < 0))
435 return zone->desks[x + (y * zone->desk_x_count)];
439 e_desk_at_pos_get(E_Zone *zone, int pos)
443 E_OBJECT_CHECK_RETURN(zone, NULL);
444 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
446 y = pos / zone->desk_x_count;
447 x = pos - (y * zone->desk_x_count);
449 if ((x >= zone->desk_x_count) || (y >= zone->desk_y_count))
452 return zone->desks[x + (y * zone->desk_x_count)];
456 e_desk_xy_get(E_Desk *desk, int *x, int *y)
458 E_OBJECT_CHECK(desk);
459 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
466 e_desk_next(E_Zone *zone)
470 E_OBJECT_CHECK(zone);
471 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
473 if ((zone->desk_x_count < 2) && (zone->desk_y_count < 2))
476 x = zone->desk_x_current;
477 y = zone->desk_y_current;
480 if (x >= zone->desk_x_count)
484 if (y >= zone->desk_y_count) y = 0;
487 e_desk_show(e_desk_at_xy_get(zone, x, y));
491 e_desk_prev(E_Zone *zone)
495 E_OBJECT_CHECK(zone);
496 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
498 if ((zone->desk_x_count < 2) && (zone->desk_y_count < 2))
501 x = zone->desk_x_current;
502 y = zone->desk_y_current;
507 x = zone->desk_x_count - 1;
509 if (y < 0) y = zone->desk_y_count - 1;
511 e_desk_show(e_desk_at_xy_get(zone, x, y));
515 _e_desk_free(E_Desk *desk)
517 if (desk->name) eina_stringshare_del(desk->name);
518 if (desk->animator) ecore_animator_del(desk->animator);
523 _e_desk_event_desk_show_free(void *data __UNUSED__, void *event)
525 E_Event_Desk_Show *ev;
528 e_object_unref(E_OBJECT(ev->desk));
533 _e_desk_event_desk_before_show_free(void *data __UNUSED__, void *event)
535 E_Event_Desk_Before_Show *ev;
538 e_object_unref(E_OBJECT(ev->desk));
543 _e_desk_event_desk_after_show_free(void *data __UNUSED__, void *event)
545 E_Event_Desk_After_Show *ev;
548 e_object_unref(E_OBJECT(ev->desk));
553 _e_desk_event_desk_deskshow_free(void *data __UNUSED__, void *event)
555 E_Event_Desk_Show *ev;
558 e_object_unref(E_OBJECT(ev->desk));
563 _e_desk_event_desk_name_change_free(void *data __UNUSED__, void *event)
565 E_Event_Desk_Name_Change *ev;
568 e_object_unref(E_OBJECT(ev->desk));
573 _e_desk_show_begin(E_Desk *desk, int mode, int dx, int dy)
584 t = ecore_loop_time_get();
585 bl = e_container_border_list_first(desk->zone->container);
586 while ((bd = e_container_border_list_next(bl)))
588 if ((bd->desk->zone == desk->zone) && (!bd->iconic))
595 e_border_desk_set(bd, desk);
598 else if ((bd->desk == desk) && (!bd->sticky))
603 bd->fx.start.x = bd->zone->w * (dx * 1.5);
604 bd->fx.start.y = bd->zone->h * (dy * 1.5);
609 double fx, fy, ang, rad, len, lmax;
611 mx = bd->zone->x + (bd->zone->w / 2);
612 my = bd->zone->y + (bd->zone->h / 2);
614 bx = bd->x + (bd->w / 2) - mx;
615 by = bd->y + (bd->h / 2) - my;
618 fx = (double)bx / (double)(bd->zone->w / 2);
619 fy = (double)by / (double)(bd->zone->h / 2);
623 len = sqrt((bx * bx) + (by * by));
624 lmax = sqrt(((bd->zone->w / 2) * (bd->zone->w / 2)) +
625 ((bd->zone->h / 2) * (bd->zone->h / 2)));
626 rad = sqrt((bd->w * bd->w) + (bd->h * bd->h)) / 2.0;
627 bx = cos(ang) * (lmax - len + rad);
628 by = sin(ang) * (lmax - len + rad);
632 if (bd->fx.start.x < 0)
633 bd->fx.start.x -= bd->zone->x;
635 bd->fx.start.x += bd->zone->container->w - (bd->zone->x + bd->zone->w);
636 if (bd->fx.start.y < 0)
637 bd->fx.start.y -= bd->zone->y;
639 bd->fx.start.y += bd->zone->container->h - (bd->zone->y + bd->zone->h);
640 e_border_fx_offset(bd, bd->fx.start.x, bd->fx.start.y);
641 e_border_comp_hidden_set(bd, EINA_TRUE);
645 e_container_border_list_free(bl);
646 if (desk->animator) ecore_animator_del(desk->animator);
647 desk->animator = ecore_animator_add(_e_desk_show_animator, desk);
648 desk->animating = EINA_TRUE;
652 _e_desk_show_end(E_Desk *desk)
654 E_Event_Desk_After_Show *ev;
658 bl = e_container_border_list_first(desk->zone->container);
659 while ((bd = e_container_border_list_next(bl)))
661 if ((bd->desk->zone == desk->zone) && (!bd->iconic))
664 e_border_fx_offset(bd, 0, 0);
665 else if ((bd->desk == desk) && (!bd->sticky))
667 e_border_fx_offset(bd, 0, 0);
668 e_border_comp_hidden_set(bd, EINA_FALSE);
676 if (e_config->focus_last_focused_per_desktop)
677 e_desk_last_focused_focus(desk);
679 e_container_border_list_free(bl);
680 ecore_x_window_shadow_tree_flush();
681 ev = E_NEW(E_Event_Desk_After_Show, 1);
682 ev->desk = e_desk_current_get(desk->zone);
683 e_object_ref(E_OBJECT(ev->desk));
684 ecore_event_add(E_EVENT_DESK_AFTER_SHOW, ev,
685 _e_desk_event_desk_after_show_free, NULL);
689 _e_desk_show_animator(void *data)
698 if (!desk->animating)
700 _e_desk_show_end(desk);
701 desk->animator = NULL;
702 return ECORE_CALLBACK_CANCEL;
705 t = ecore_loop_time_get();
707 spd = e_config->desk_flip_animate_time;
708 bl = e_container_border_list_first(desk->zone->container);
709 while ((bd = e_container_border_list_next(bl)))
711 if ((bd->desk->zone == desk->zone) && (!bd->iconic))
716 else if ((bd->desk == desk) && (!bd->sticky))
721 dt = (t - bd->fx.start.t) / spd;
722 if (dt > 1.0) dt = 1.0;
724 dt *= dt; /* decelerate - could be a better hack */
725 e_border_fx_offset(bd,
726 ((double)bd->fx.start.x * dt),
727 ((double)bd->fx.start.y * dt));
731 e_container_border_list_free(bl);
733 desk->animating = EINA_FALSE;
735 return ECORE_CALLBACK_RENEW;
739 _e_desk_hide_begin(E_Desk *desk, int mode, int dx, int dy)
750 t = ecore_loop_time_get();
751 bl = e_container_border_list_first(desk->zone->container);
752 while ((bd = e_container_border_list_next(bl)))
754 if ((bd->desk->zone == desk->zone) && (!bd->iconic))
762 else if ((bd->desk == desk) && (!bd->sticky))
767 bd->fx.start.x = bd->zone->w * (-dx * 1.5);
768 bd->fx.start.y = bd->zone->h * (-dy * 1.5);
773 double fx, fy, ang, rad, len, lmax;
775 mx = bd->zone->x + (bd->zone->w / 2);
776 my = bd->zone->y + (bd->zone->h / 2);
778 bx = bd->x + (bd->w / 2) - mx;
779 by = bd->y + (bd->h / 2) - my;
782 fx = (double)bx / (double)(bd->zone->w / 2);
783 fy = (double)by / (double)(bd->zone->h / 2);
787 len = sqrt((bx * bx) + (by * by));
788 lmax = sqrt(((bd->zone->w / 2) * (bd->zone->w / 2)) +
789 ((bd->zone->h / 2) * (bd->zone->h / 2)));
790 rad = sqrt((bd->w * bd->w) + (bd->h * bd->h)) / 2.0;
791 bx = cos(ang) * (lmax - len + rad);
792 by = sin(ang) * (lmax - len + rad);
796 if (bd->fx.start.x < 0)
797 bd->fx.start.x -= bd->zone->x;
799 bd->fx.start.x += bd->zone->container->w - (bd->zone->x + bd->zone->w);
800 if (bd->fx.start.y < 0)
801 bd->fx.start.y -= bd->zone->y;
803 bd->fx.start.y += bd->zone->container->h - (bd->zone->y + bd->zone->h);
804 e_border_fx_offset(bd, 0, 0);
805 e_border_comp_hidden_set(bd, EINA_TRUE);
809 e_container_border_list_free(bl);
810 if (desk->animator) ecore_animator_del(desk->animator);
811 desk->animator = ecore_animator_add(_e_desk_hide_animator, desk);
812 desk->animating = EINA_TRUE;
816 _e_desk_hide_end(E_Desk *desk)
821 bl = e_container_border_list_first(desk->zone->container);
822 while ((bd = e_container_border_list_next(bl)))
824 if ((bd->desk->zone == desk->zone) && (!bd->iconic))
827 e_border_fx_offset(bd, 0, 0);
828 else if ((bd->desk == desk) && (!bd->sticky))
830 e_border_fx_offset(bd, 0, 0);
831 e_border_comp_hidden_set(bd, EINA_FALSE);
832 e_border_hide(bd, 2);
836 e_container_border_list_free(bl);
837 ecore_x_window_shadow_tree_flush();
841 _e_desk_hide_animator(void *data)
850 if (!desk->animating)
852 _e_desk_hide_end(desk);
853 desk->animator = NULL;
854 return ECORE_CALLBACK_CANCEL;
857 t = ecore_loop_time_get();
859 spd = e_config->desk_flip_animate_time;
860 bl = e_container_border_list_first(desk->zone->container);
861 while ((bd = e_container_border_list_next(bl)))
863 if ((bd->desk->zone == desk->zone) && (!bd->iconic))
868 else if ((bd->desk == desk) && (!bd->sticky))
870 dt = (t - bd->fx.start.t) / spd;
871 if (dt > 1.0) dt = 1.0;
872 dt *= dt; /* decelerate - could be a better hack */
873 e_border_fx_offset(bd,
874 ((double)bd->fx.start.x * dt),
875 ((double)bd->fx.start.y * dt));
879 e_container_border_list_free(bl);
881 if ((dt < 0.0) || (dt >= 1.0))
882 desk->animating = EINA_FALSE;
884 return ECORE_CALLBACK_RENEW;