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 x, 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 */
64 EINA_LIST_FOREACH(e_config->desktop_names, l, cfname)
66 if ((cfname->container >= 0) &&
67 ((int) zone->container->num != cfname->container)) continue;
68 if ((cfname->zone >= 0) &&
69 ((int) zone->num != cfname->zone)) continue;
70 if ((cfname->desk_x != desk->x) || (cfname->desk_y != desk->y))
72 desk->name = eina_stringshare_add(cfname->name);
79 snprintf(name, sizeof(name), _(e_config->desktop_default_name), x, y);
80 desk->name = eina_stringshare_add(name);
87 e_desk_name_set(E_Desk *desk, const char *name)
89 E_Event_Desk_Name_Change *ev;
92 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
94 eina_stringshare_replace(&desk->name, name);
96 ev = E_NEW(E_Event_Desk_Name_Change, 1);
98 e_object_ref(E_OBJECT(desk));
99 ecore_event_add(E_EVENT_DESK_NAME_CHANGE, ev,
100 _e_desk_event_desk_name_change_free, NULL);
104 e_desk_name_add(int container, int zone, int desk_x, int desk_y, const char *name)
106 E_Config_Desktop_Name *cfname;
108 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 else cfname->name = NULL;
117 e_config->desktop_names = eina_list_append(e_config->desktop_names, cfname);
121 e_desk_name_del(int container, int zone, int desk_x, int desk_y)
124 E_Config_Desktop_Name *cfname = NULL;
126 EINA_LIST_FOREACH(e_config->desktop_names, l, cfname)
128 if ((cfname->container == container) && (cfname->zone == zone) &&
129 (cfname->desk_x == desk_x) && (cfname->desk_y == desk_y))
131 e_config->desktop_names =
132 eina_list_remove_list(e_config->desktop_names, l);
133 if (cfname->name) eina_stringshare_del(cfname->name);
141 e_desk_name_update(void)
143 Eina_List *m, *c, *z, *l;
148 E_Config_Desktop_Name *cfname;
152 EINA_LIST_FOREACH(e_manager_list(), m, man)
154 EINA_LIST_FOREACH(man->containers, c, con)
156 EINA_LIST_FOREACH(con->zones, z, zone)
158 for (d_x = 0; d_x < zone->desk_x_count; d_x++)
160 for (d_y = 0; d_y < zone->desk_y_count; d_y++)
162 desk = zone->desks[d_x + zone->desk_x_count * d_y];
165 EINA_LIST_FOREACH(e_config->desktop_names, l, cfname)
167 if ((cfname->container >= 0) &&
168 ((int) con->num != cfname->container)) continue;
169 if ((cfname->zone >= 0) &&
170 ((int) zone->num != cfname->zone)) continue;
171 if ((cfname->desk_x != d_x) ||
172 (cfname->desk_y != d_y)) continue;
173 e_desk_name_set(desk, cfname->name);
180 snprintf(name, sizeof(name),
181 _(e_config->desktop_default_name),
183 e_desk_name_set(desk, name);
193 e_desk_show(E_Desk *desk)
197 E_Event_Desk_Show *ev;
198 E_Event_Desk_Before_Show *eev;
199 E_Event_Desk_After_Show *eeev;
200 Edje_Message_Float_Set *msg;
203 int was_zone = 0, x, y, dx = 0, dy = 0;
205 E_OBJECT_CHECK(desk);
206 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
207 if (desk->visible) return;
209 eev = E_NEW(E_Event_Desk_Before_Show, 1);
210 eev->desk = e_desk_current_get(desk->zone);
211 e_object_ref(E_OBJECT(eev->desk));
212 ecore_event_add(E_EVENT_DESK_BEFORE_SHOW, eev,
213 _e_desk_event_desk_before_show_free, NULL);
215 ecore_x_window_shadow_tree_flush();
216 for (x = 0; x < desk->zone->desk_x_count; x++)
218 for (y = 0; y < desk->zone->desk_y_count; y++)
222 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 msg = alloca(sizeof(Edje_Message_Float_Set) + (4 * sizeof(double)));
242 msg->val[0] = e_config->desk_flip_animate_time;
243 msg->val[1] = (double) desk->x;
244 msg->val[2] = (double) desk->zone->desk_x_count;
245 msg->val[3] = (double) desk->y;
246 msg->val[4] = (double) desk->zone->desk_y_count;
247 edje_object_message_send(desk->zone->bg_object, EDJE_MESSAGE_FLOAT_SET, 0, msg);
249 if (desk->zone->bg_object) was_zone = 1;
250 if (e_config->desk_flip_animate_mode == 0)
252 bl = e_container_border_list_first(desk->zone->container);
253 while ((bd = e_container_border_list_next(bl)))
255 if ((bd->desk->zone == desk->zone) && (!bd->iconic))
257 if ((bd->desk == desk) || (bd->sticky))
260 e_border_desk_set(bd, desk);
262 e_border_hide(bd, 2);
265 e_container_border_list_free(bl);
268 if (e_config->desk_flip_animate_mode > 0)
269 _e_desk_show_begin(desk, e_config->desk_flip_animate_mode, dx, dy);
272 if (e_config->focus_last_focused_per_desktop)
273 e_desk_last_focused_focus(desk);
277 e_bg_zone_update(desk->zone, E_BG_TRANSITION_DESK);
279 e_bg_zone_update(desk->zone, E_BG_TRANSITION_START);
281 ev = E_NEW(E_Event_Desk_Show, 1);
283 e_object_ref(E_OBJECT(desk));
284 ecore_event_add(E_EVENT_DESK_SHOW, ev, _e_desk_event_desk_show_free, NULL);
286 EINA_LIST_FOREACH(e_shelf_list(), l, es)
289 E_Config_Shelf *cf_es;
291 E_Config_Shelf_Desk *sd;
295 if (!es->cfg->desk_show_mode) continue;
297 if (!cf_es) continue;
299 zone = e_util_zone_current_get(e_manager_current_get());
300 if (cf_es->zone != (int) zone->num) continue;
302 EINA_LIST_FOREACH(es->cfg->desk_list, ll, sd)
305 if ((desk->x == sd->x) && (desk->y == sd->y))
317 if (e_config->desk_flip_animate_mode == 0)
319 eeev = E_NEW(E_Event_Desk_After_Show, 1);
320 eeev->desk = e_desk_current_get(desk->zone);
321 e_object_ref(E_OBJECT(eeev->desk));
322 ecore_event_add(E_EVENT_DESK_AFTER_SHOW, eeev,
323 _e_desk_event_desk_after_show_free, NULL);
325 e_zone_edge_flip_eval(desk->zone);
329 e_desk_deskshow(E_Zone *zone)
334 E_Event_Desk_Show *ev;
336 E_OBJECT_CHECK(zone);
337 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
339 desk = e_desk_current_get(zone);
340 bl = e_container_border_list_first(zone->container);
341 ecore_x_window_shadow_tree_flush();
342 while ((bd = e_container_border_list_next(bl)))
344 if (bd->desk == desk)
346 if (desk->deskshow_toggle)
348 if (bd->deskshow) e_border_uniconify(bd);
353 if (bd->iconic) continue;
354 if (bd->client.netwm.state.skip_taskbar) continue;
355 if (bd->user_skip_winlist) continue;
356 e_border_iconify(bd);
361 desk->deskshow_toggle = desk->deskshow_toggle ? 0 : 1;
362 e_container_border_list_free(bl);
363 ev = E_NEW(E_Event_Desk_Show, 1);
365 e_object_ref(E_OBJECT(desk));
366 ecore_event_add(E_EVENT_DESK_DESKSHOW, ev,
367 _e_desk_event_desk_deskshow_free, NULL);
371 e_desk_last_focused_focus(E_Desk *desk)
376 EINA_LIST_FOREACH(e_border_focus_stack_get(), l, bd)
378 if ((!bd->iconic) && (bd->visible) &&
379 ((bd->desk == desk) || ((bd->zone == desk->zone) && bd->sticky)) &&
380 (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus) &&
381 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
382 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
383 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
384 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
385 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
387 /* this was the window last focused in this desktop */
388 if (!bd->lock_focus_out)
390 e_border_focus_set(bd, 1, 1);
398 e_desk_row_add(E_Zone *zone)
400 e_zone_desk_count_set(zone, zone->desk_x_count, zone->desk_y_count + 1);
404 e_desk_row_remove(E_Zone *zone)
406 e_zone_desk_count_set(zone, zone->desk_x_count, zone->desk_y_count - 1);
410 e_desk_col_add(E_Zone *zone)
412 e_zone_desk_count_set(zone, zone->desk_x_count + 1, zone->desk_y_count);
416 e_desk_col_remove(E_Zone *zone)
418 e_zone_desk_count_set(zone, zone->desk_x_count - 1, zone->desk_y_count);
422 e_desk_current_get(E_Zone *zone)
424 E_OBJECT_CHECK_RETURN(zone, NULL);
425 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
427 return e_desk_at_xy_get(zone, zone->desk_x_current, zone->desk_y_current);
431 e_desk_at_xy_get(E_Zone *zone, int x, int y)
433 E_OBJECT_CHECK_RETURN(zone, NULL);
434 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
436 if ((x >= zone->desk_x_count) || (y >= zone->desk_y_count))
438 else if ((x < 0) || (y < 0))
441 return zone->desks[x + (y * zone->desk_x_count)];
445 e_desk_at_pos_get(E_Zone *zone, int pos)
449 E_OBJECT_CHECK_RETURN(zone, NULL);
450 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
452 y = pos / zone->desk_x_count;
453 x = pos - (y * zone->desk_x_count);
455 if ((x >= zone->desk_x_count) || (y >= zone->desk_y_count))
458 return zone->desks[x + (y * zone->desk_x_count)];
462 e_desk_xy_get(E_Desk *desk, int *x, int *y)
464 E_OBJECT_CHECK(desk);
465 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
472 e_desk_next(E_Zone *zone)
476 E_OBJECT_CHECK(zone);
477 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
479 if ((zone->desk_x_count < 2) && (zone->desk_y_count < 2))
482 x = zone->desk_x_current;
483 y = zone->desk_y_current;
486 if (x >= zone->desk_x_count)
490 if (y >= zone->desk_y_count) y = 0;
493 e_desk_show(e_desk_at_xy_get(zone, x, y));
497 e_desk_prev(E_Zone *zone)
501 E_OBJECT_CHECK(zone);
502 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
504 if ((zone->desk_x_count < 2) && (zone->desk_y_count < 2))
507 x = zone->desk_x_current;
508 y = zone->desk_y_current;
513 x = zone->desk_x_count - 1;
515 if (y < 0) y = zone->desk_y_count - 1;
517 e_desk_show(e_desk_at_xy_get(zone, x, y));
521 _e_desk_free(E_Desk *desk)
523 if (desk->name) eina_stringshare_del(desk->name);
525 if (desk->animator) ecore_animator_del(desk->animator);
526 desk->animator = NULL;
531 _e_desk_event_desk_show_free(void *data __UNUSED__, void *event)
533 E_Event_Desk_Show *ev;
536 e_object_unref(E_OBJECT(ev->desk));
541 _e_desk_event_desk_before_show_free(void *data __UNUSED__, void *event)
543 E_Event_Desk_Before_Show *ev;
546 e_object_unref(E_OBJECT(ev->desk));
551 _e_desk_event_desk_after_show_free(void *data __UNUSED__, void *event)
553 E_Event_Desk_After_Show *ev;
556 e_object_unref(E_OBJECT(ev->desk));
561 _e_desk_event_desk_deskshow_free(void *data __UNUSED__, void *event)
563 E_Event_Desk_Show *ev;
566 e_object_unref(E_OBJECT(ev->desk));
571 _e_desk_event_desk_name_change_free(void *data __UNUSED__, void *event)
573 E_Event_Desk_Name_Change *ev;
576 e_object_unref(E_OBJECT(ev->desk));
581 _e_desk_show_begin(E_Desk *desk, int mode, int dx, int dy)
592 t = ecore_loop_time_get();
593 bl = e_container_border_list_first(desk->zone->container);
594 while ((bd = e_container_border_list_next(bl)))
596 if ((bd->desk->zone == desk->zone) && (!bd->iconic))
603 e_border_desk_set(bd, desk);
606 else if ((bd->desk == desk) && (!bd->sticky))
608 e_border_tmp_input_hidden_push(bd);
612 bd->fx.start.x = bd->zone->w * (dx * 1.5);
613 bd->fx.start.y = bd->zone->h * (dy * 1.5);
618 double fx, fy, ang, rad, len, lmax;
620 mx = bd->zone->x + (bd->zone->w / 2);
621 my = bd->zone->y + (bd->zone->h / 2);
623 bx = bd->x + (bd->w / 2) - mx;
624 by = bd->y + (bd->h / 2) - my;
627 fx = (double)bx / (double)(bd->zone->w / 2);
628 fy = (double)by / (double)(bd->zone->h / 2);
632 len = sqrt((bx * bx) + (by * by));
633 lmax = sqrt(((bd->zone->w / 2) * (bd->zone->w / 2)) +
634 ((bd->zone->h / 2) * (bd->zone->h / 2)));
635 rad = sqrt((bd->w * bd->w) + (bd->h * bd->h)) / 2.0;
636 bx = cos(ang) * (lmax - len + rad);
637 by = sin(ang) * (lmax - len + rad);
641 if (bd->fx.start.x < 0)
642 bd->fx.start.x -= bd->zone->x;
644 bd->fx.start.x += bd->zone->container->w - (bd->zone->x + bd->zone->w);
645 if (bd->fx.start.y < 0)
646 bd->fx.start.y -= bd->zone->y;
648 bd->fx.start.y += bd->zone->container->h - (bd->zone->y + bd->zone->h);
649 e_border_fx_offset(bd, bd->fx.start.x, bd->fx.start.y);
650 e_border_comp_hidden_set(bd, EINA_TRUE);
654 e_container_border_list_free(bl);
655 if (desk->animator) ecore_animator_del(desk->animator);
656 desk->animator = ecore_animator_add(_e_desk_show_animator, desk);
657 desk->animating = EINA_TRUE;
661 _e_desk_show_end(E_Desk *desk)
663 E_Event_Desk_After_Show *ev;
667 bl = e_container_border_list_first(desk->zone->container);
668 while ((bd = e_container_border_list_next(bl)))
670 if ((bd->desk->zone == desk->zone) && (!bd->iconic))
673 e_border_fx_offset(bd, 0, 0);
674 else if ((bd->desk == desk) && (!bd->sticky))
676 e_border_fx_offset(bd, 0, 0);
677 e_border_comp_hidden_set(bd, EINA_FALSE);
682 e_border_tmp_input_hidden_pop(bd);
686 if ((e_config->focus_policy == E_FOCUS_MOUSE) ||
687 (e_config->focus_policy == E_FOCUS_SLOPPY))
689 if (e_config->focus_last_focused_per_desktop)
691 if (!e_border_under_pointer_get(desk, NULL))
692 e_desk_last_focused_focus(desk);
697 if (e_config->focus_last_focused_per_desktop)
698 e_desk_last_focused_focus(desk);
701 e_container_border_list_free(bl);
702 ecore_x_window_shadow_tree_flush();
703 ev = E_NEW(E_Event_Desk_After_Show, 1);
704 ev->desk = e_desk_current_get(desk->zone);
705 e_object_ref(E_OBJECT(ev->desk));
706 ecore_event_add(E_EVENT_DESK_AFTER_SHOW, ev,
707 _e_desk_event_desk_after_show_free, NULL);
711 _e_desk_show_animator(void *data)
720 if (!desk->animating)
722 _e_desk_show_end(desk);
723 desk->animator = NULL;
724 return ECORE_CALLBACK_CANCEL;
727 t = ecore_loop_time_get();
729 spd = e_config->desk_flip_animate_time;
730 bl = e_container_border_list_first(desk->zone->container);
731 while ((bd = e_container_border_list_next(bl)))
733 if ((bd->desk->zone == desk->zone) && (!bd->iconic))
738 else if ((bd->desk == desk) && (!bd->sticky))
743 dt = (t - bd->fx.start.t) / spd;
744 if (dt > 1.0) dt = 1.0;
746 dt *= dt; /* decelerate - could be a better hack */
747 e_border_fx_offset(bd,
748 ((double)bd->fx.start.x * dt),
749 ((double)bd->fx.start.y * dt));
753 e_container_border_list_free(bl);
755 desk->animating = EINA_FALSE;
757 return ECORE_CALLBACK_RENEW;
761 _e_desk_hide_begin(E_Desk *desk, int mode, int dx, int dy)
772 t = ecore_loop_time_get();
773 bl = e_container_border_list_first(desk->zone->container);
774 while ((bd = e_container_border_list_next(bl)))
776 if ((bd->desk->zone == desk->zone) && (!bd->iconic))
784 else if ((bd->desk == desk) && (!bd->sticky))
789 bd->fx.start.x = bd->zone->w * (-dx * 1.5);
790 bd->fx.start.y = bd->zone->h * (-dy * 1.5);
795 double fx, fy, ang, rad, len, lmax;
797 mx = bd->zone->x + (bd->zone->w / 2);
798 my = bd->zone->y + (bd->zone->h / 2);
800 bx = bd->x + (bd->w / 2) - mx;
801 by = bd->y + (bd->h / 2) - my;
804 fx = (double)bx / (double)(bd->zone->w / 2);
805 fy = (double)by / (double)(bd->zone->h / 2);
809 len = sqrt((bx * bx) + (by * by));
810 lmax = sqrt(((bd->zone->w / 2) * (bd->zone->w / 2)) +
811 ((bd->zone->h / 2) * (bd->zone->h / 2)));
812 rad = sqrt((bd->w * bd->w) + (bd->h * bd->h)) / 2.0;
813 bx = cos(ang) * (lmax - len + rad);
814 by = sin(ang) * (lmax - len + rad);
818 if (bd->fx.start.x < 0)
819 bd->fx.start.x -= bd->zone->x;
821 bd->fx.start.x += bd->zone->container->w - (bd->zone->x + bd->zone->w);
822 if (bd->fx.start.y < 0)
823 bd->fx.start.y -= bd->zone->y;
825 bd->fx.start.y += bd->zone->container->h - (bd->zone->y + bd->zone->h);
826 e_border_fx_offset(bd, 0, 0);
827 e_border_comp_hidden_set(bd, EINA_TRUE);
831 e_container_border_list_free(bl);
832 if (desk->animator) ecore_animator_del(desk->animator);
833 desk->animator = ecore_animator_add(_e_desk_hide_animator, desk);
834 desk->animating = EINA_TRUE;
838 _e_desk_hide_end(E_Desk *desk)
843 bl = e_container_border_list_first(desk->zone->container);
844 while ((bd = e_container_border_list_next(bl)))
846 if ((bd->desk->zone == desk->zone) && (!bd->iconic))
849 e_border_fx_offset(bd, 0, 0);
850 else if ((bd->desk == desk) && (!bd->sticky))
852 e_border_fx_offset(bd, 0, 0);
853 e_border_comp_hidden_set(bd, EINA_FALSE);
854 e_border_hide(bd, 2);
858 e_container_border_list_free(bl);
859 ecore_x_window_shadow_tree_flush();
863 _e_desk_hide_animator(void *data)
872 if (!desk->animating)
874 _e_desk_hide_end(desk);
875 desk->animator = NULL;
876 return ECORE_CALLBACK_CANCEL;
879 t = ecore_loop_time_get();
881 spd = e_config->desk_flip_animate_time;
882 bl = e_container_border_list_first(desk->zone->container);
883 while ((bd = e_container_border_list_next(bl)))
885 if ((bd->desk->zone == desk->zone) && (!bd->iconic))
890 else if ((bd->desk == desk) && (!bd->sticky))
892 dt = (t - bd->fx.start.t) / spd;
893 if (dt > 1.0) dt = 1.0;
894 dt *= dt; /* decelerate - could be a better hack */
895 e_border_fx_offset(bd,
896 ((double)bd->fx.start.x * dt),
897 ((double)bd->fx.start.y * dt));
901 e_container_border_list_free(bl);
903 if ((dt < 0.0) || (dt >= 1.0))
904 desk->animating = EINA_FALSE;
906 return ECORE_CALLBACK_RENEW;