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 #define E_DESK_SMART_DATA_GET(obj, ptr) \
9 E_Desk_Smart_Data *ptr = evas_object_smart_data_get(obj);
11 #define E_DESK_SMART_DATA_GET_OR_RETURN(obj, ptr) \
12 E_DESK_SMART_DATA_GET(obj, ptr); \
15 typedef struct _E_Desk_Smart_Data E_Desk_Smart_Data;
17 struct _E_Desk_Smart_Data
19 Evas_Object_Smart_Clipped_Data base;
25 double ratio_x, ratio_y;
31 static void _e_desk_free(E_Desk *desk);
32 static void _e_desk_event_desk_show_free(void *data, void *ev);
33 static void _e_desk_event_desk_before_show_free(void *data, void *ev);
34 static void _e_desk_event_desk_after_show_free(void *data, void *ev);
35 static void _e_desk_show_begin(E_Desk *desk, int dx, int dy);
36 static void _e_desk_hide_begin(E_Desk *desk, int dx, int dy);
37 static void _e_desk_event_desk_geometry_change_free(void *data, void *ev);
38 static Eina_Bool _e_desk_cb_zone_move_resize(void *data, int type EINA_UNUSED, void *event);
40 static void _e_desk_smart_init(E_Desk *desk);
41 static void _e_desk_smart_add(Evas_Object *obj);
42 static void _e_desk_smart_del(Evas_Object *obj);
43 static void _e_desk_smart_client_add(Evas_Object *obj, E_Client *ec);
44 static void _e_desk_smart_client_del(Evas_Object *obj, E_Client *ec);
45 static void _e_desk_object_zoom(Evas_Object *obj, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy);
46 static void _e_desk_client_zoom(E_Client *ec, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy);
47 static void _e_desk_util_comp_hwc_disable_set(Eina_Bool enable);
49 EVAS_SMART_SUBCLASS_NEW(E_DESK_SMART_OBJ_TYPE, _e_desk,
50 Evas_Smart_Class, Evas_Smart_Class,
51 evas_object_smart_clipped_class_get, NULL)
53 static E_Desk_Flip_Cb _e_desk_flip_cb = NULL;
54 static void *_e_desk_flip_data = NULL;
56 E_API int E_EVENT_DESK_SHOW = 0;
57 E_API int E_EVENT_DESK_BEFORE_SHOW = 0;
58 E_API int E_EVENT_DESK_AFTER_SHOW = 0;
59 E_API int E_EVENT_DESK_DESKSHOW = 0;
60 E_API int E_EVENT_DESK_NAME_CHANGE = 0;
61 E_API int E_EVENT_DESK_WINDOW_PROFILE_CHANGE = 0;
62 E_API int E_EVENT_DESK_GEOMETRY_CHANGE = 0;
63 E_API int E_EVENT_DESK_ZOOM_SET = 0;
64 E_API int E_EVENT_DESK_ZOOM_UNSET = 0;
68 _e_desk_event_simple_free(void *d EINA_UNUSED, E_Event_Desk *event)
73 e_object_unref(E_OBJECT(ev->desk));
78 _e_desk_event_simple_add(E_Desk *desk, int type)
82 ev = E_NEW(E_Event_Desk, 1);
85 e_object_ref(E_OBJECT(desk));
87 ecore_event_add(type, ev, (Ecore_End_Cb)_e_desk_event_simple_free, NULL);
93 E_EVENT_DESK_SHOW = ecore_event_type_new();
94 E_EVENT_DESK_BEFORE_SHOW = ecore_event_type_new();
95 E_EVENT_DESK_AFTER_SHOW = ecore_event_type_new();
96 E_EVENT_DESK_DESKSHOW = ecore_event_type_new();
97 E_EVENT_DESK_NAME_CHANGE = ecore_event_type_new();
98 E_EVENT_DESK_WINDOW_PROFILE_CHANGE = ecore_event_type_new();
99 E_EVENT_DESK_GEOMETRY_CHANGE = ecore_event_type_new();
100 E_EVENT_DESK_ZOOM_SET = ecore_event_type_new();
101 E_EVENT_DESK_ZOOM_UNSET = ecore_event_type_new();
107 e_desk_shutdown(void)
113 e_desk_new(E_Zone *zone, int x, int y)
117 E_Config_Desktop_Name *cfname;
118 E_Config_Desktop_Window_Profile *cfprof;
122 E_OBJECT_CHECK_RETURN(zone, NULL);
123 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
125 desk = E_OBJECT_ALLOC(E_Desk, E_DESK_TYPE, _e_desk_free);
126 if (!desk) return NULL;
132 if (!e_config->use_desk_smart_obj)
134 /* need to set geometry of desk even if disable the smart object,
135 * because 'E_Client' can be reconfigured base on desk.geom as a member
136 * of desk. the reason why this is necessary is all of 'E_Client' is not
137 * members of the smart object so far.
139 EINA_RECTANGLE_SET(&desk->geom, zone->x, zone->y, zone->w, zone->h);
140 E_LIST_HANDLER_APPEND(desk->handlers, E_EVENT_ZONE_MOVE_RESIZE, _e_desk_cb_zone_move_resize, desk);
144 /* init smart object */
145 _e_desk_smart_init(desk);
148 /* Get current desktop's name */
149 EINA_LIST_FOREACH(e_config->desktop_names, l, cfname)
151 if ((cfname->zone >= 0) &&
152 ((int)zone->num != cfname->zone)) continue;
153 if ((cfname->desk_x != desk->x) || (cfname->desk_y != desk->y))
155 desk->name = eina_stringshare_ref(cfname->name);
162 snprintf(name, sizeof(name), _(e_config->desktop_default_name), x, y);
163 desk->name = eina_stringshare_add(name);
165 /* Get window profile name for current desktop */
167 EINA_LIST_FOREACH(e_config->desktop_window_profiles, l, cfprof)
169 if ((cfprof->zone >= 0) &&
170 ((int)zone->num != cfprof->zone)) continue;
171 if ((cfprof->desk_x != desk->x) || (cfprof->desk_y != desk->y))
173 desk->window_profile = eina_stringshare_ref(cfprof->profile);
179 desk->window_profile = eina_stringshare_ref(e_config->desktop_default_window_profile);
184 e_desk_client_top_visible_get(const E_Desk *desk)
188 E_OBJECT_CHECK_RETURN(desk, NULL);
189 E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, NULL);
191 E_CLIENT_REVERSE_FOREACH(ec)
192 if (e_client_util_desk_visible(ec, desk) && evas_object_visible_get(ec->frame)) return ec;
197 e_desk_name_set(E_Desk *desk, const char *name)
199 E_OBJECT_CHECK(desk);
200 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
202 eina_stringshare_replace(&desk->name, name);
204 _e_desk_event_simple_add(desk, E_EVENT_DESK_NAME_CHANGE);
208 e_desk_name_add(int zone, int desk_x, int desk_y, const char *name)
210 E_Config_Desktop_Name *cfname;
212 e_desk_name_del(zone, desk_x, desk_y);
214 cfname = E_NEW(E_Config_Desktop_Name, 1);
217 cfname->desk_x = desk_x;
218 cfname->desk_y = desk_y;
219 if (name) cfname->name = eina_stringshare_add(name);
220 else cfname->name = NULL;
221 e_config->desktop_names = eina_list_append(e_config->desktop_names, cfname);
225 e_desk_name_del(int zone, int desk_x, int desk_y)
228 E_Config_Desktop_Name *cfname = NULL;
230 EINA_LIST_FOREACH(e_config->desktop_names, l, cfname)
232 if ((cfname->zone == zone) &&
233 (cfname->desk_x == desk_x) && (cfname->desk_y == desk_y))
235 e_config->desktop_names =
236 eina_list_remove_list(e_config->desktop_names, l);
237 if (cfname->name) eina_stringshare_del(cfname->name);
245 e_desk_name_update(void)
247 const Eina_List *z, *l;
250 E_Config_Desktop_Name *cfname;
254 EINA_LIST_FOREACH(e_comp->zones, z, zone)
256 for (d_x = 0; d_x < zone->desk_x_count; d_x++)
258 for (d_y = 0; d_y < zone->desk_y_count; d_y++)
260 desk = zone->desks[d_x + zone->desk_x_count * d_y];
263 EINA_LIST_FOREACH(e_config->desktop_names, l, cfname)
265 if ((cfname->zone >= 0) &&
266 ((int)zone->num != cfname->zone)) continue;
267 if ((cfname->desk_x != d_x) ||
268 (cfname->desk_y != d_y)) continue;
269 e_desk_name_set(desk, cfname->name);
276 snprintf(name, sizeof(name),
277 _(e_config->desktop_default_name),
279 e_desk_name_set(desk, name);
287 e_desk_show(E_Desk *desk)
289 E_Event_Desk_Show *ev = NULL;
290 E_Event_Desk_Before_Show *eev = NULL;
291 E_Event_Desk_After_Show *eeev = NULL;
292 Edje_Message_Float_Set *msg = NULL;
293 E_Desk *desk2 = NULL;
295 Ecore_Event *eev_ecore_event = NULL;
296 Ecore_Event *ev_ecore_event = NULL;
298 E_OBJECT_CHECK(desk);
299 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
300 if (desk->visible) return;
302 desk2 = e_desk_at_xy_get(desk->zone, desk->zone->desk_x_current, desk->zone->desk_y_current);
303 if ((!starting) && (!desk2->visible)) return;
304 eev = E_NEW(E_Event_Desk_Before_Show, 1);
306 eev->desk = e_desk_current_get(desk->zone);
307 e_object_ref(E_OBJECT(eev->desk));
308 eev_ecore_event = ecore_event_add(E_EVENT_DESK_BEFORE_SHOW, eev,
309 _e_desk_event_desk_before_show_free, NULL);
316 dx = desk->x - desk2->x;
317 dy = desk->y - desk2->y;
319 _e_desk_hide_begin(desk2, dx, dy);
320 if (desk2->smart_obj)
321 evas_object_hide(desk2->smart_obj);
324 desk->zone->desk_x_prev = desk->zone->desk_x_current;
325 desk->zone->desk_y_prev = desk->zone->desk_y_current;
326 desk->zone->desk_x_current = desk->x;
327 desk->zone->desk_y_current = desk->y;
330 msg = alloca(sizeof(Edje_Message_Float_Set) + (4 * sizeof(double)));
333 msg->val[1] = desk->x;
334 msg->val[2] = desk->zone->desk_x_count;
335 msg->val[3] = desk->y;
336 msg->val[4] = desk->zone->desk_y_count;
337 if (desk->zone->bg_object)
338 edje_object_message_send(desk->zone->bg_object, EDJE_MESSAGE_FLOAT_SET, 0, msg);
340 #ifndef ENABLE_QUICK_INIT
342 if (desk->zone->bg_object) was_zone = 1;
344 _e_desk_show_begin(desk, dx, dy);
346 evas_object_show(desk->smart_obj);
348 #ifndef ENABLE_QUICK_INIT
350 e_bg_zone_update(desk->zone, E_BG_TRANSITION_DESK);
352 e_bg_zone_update(desk->zone, E_BG_TRANSITION_START);
355 ev = E_NEW(E_Event_Desk_Show, 1);
358 e_object_ref(E_OBJECT(desk));
359 ev_ecore_event = ecore_event_add(E_EVENT_DESK_SHOW, ev, _e_desk_event_desk_show_free, NULL);
361 eeev = E_NEW(E_Event_Desk_After_Show, 1);
362 if (!eeev) goto error;
363 eeev->desk = e_desk_current_get(desk->zone);
364 e_object_ref(E_OBJECT(eeev->desk));
365 ecore_event_add(E_EVENT_DESK_AFTER_SHOW, eeev,
366 _e_desk_event_desk_after_show_free, NULL);
367 e_zone_edge_flip_eval(desk->zone);
375 ecore_event_del(ev_ecore_event);
376 e_object_unref(E_OBJECT(ev->desk));
382 ecore_event_del(eev_ecore_event);
383 e_object_unref(E_OBJECT(eev->desk));
389 e_desk_deskshow(E_Zone *zone)
394 E_OBJECT_CHECK(zone);
395 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
397 desk = e_desk_current_get(zone);
398 EINA_SAFETY_ON_NULL_RETURN(desk);
400 if (desk->deskshow_toggle)
402 /* uniconify raises windows and changes stacking order
403 * go top-down to avoid skipping windows
405 E_CLIENT_REVERSE_FOREACH(ec)
407 if (e_client_util_ignored_get(ec)) continue;
408 if (ec->desk != desk) continue;
412 e_client_uniconify(ec);
419 * iconify raises, so we have to start from the bottom so we are going forward
423 if (e_client_util_ignored_get(ec)) continue;
424 if (ec->desk != desk) continue;
425 if (ec->iconic) continue;
426 if (ec->netwm.state.skip_taskbar) continue;
427 if (ec->user_skip_winlist) continue;
429 e_client_iconify(ec);
432 desk->deskshow_toggle = !desk->deskshow_toggle;
434 _e_desk_event_simple_add(desk, E_EVENT_DESK_DESKSHOW);
438 e_desk_last_focused_focus(E_Desk *desk)
441 E_Client *ec, *ecs = NULL, *focus_ec = NULL;
443 EINA_LIST_FOREACH(e_client_focus_stack_get(), l, ec)
445 if ((!ec->iconic) && (evas_object_visible_get(ec->frame) || ec->changes.visible) &&
446 ((ec->desk == desk) || ((ec->zone == desk->zone) && ec->sticky)) &&
447 (ec->icccm.accepts_focus || ec->icccm.take_focus) &&
448 (ec->netwm.type != E_WINDOW_TYPE_DOCK) &&
449 (ec->netwm.type != E_WINDOW_TYPE_TOOLBAR) &&
450 (ec->netwm.type != E_WINDOW_TYPE_MENU) &&
451 (ec->netwm.type != E_WINDOW_TYPE_SPLASH) &&
452 (ec->netwm.type != E_WINDOW_TYPE_DESKTOP))
454 /* this was the window last focused in this desktop */
455 if (!ec->lock_focus_out)
462 if (ec->changes.visible && (!evas_object_visible_get(ec->frame)))
463 ec->want_focus = ec->take_focus = 1;
465 e_client_focus_set_with_pointer(ec);
466 if (e_config->raise_on_revert_focus)
474 if (ecs->changes.visible && (!evas_object_visible_get(ecs->frame)))
475 ecs->want_focus = ecs->take_focus = 1;
477 e_client_focus_set_with_pointer(ecs);
478 if (e_config->raise_on_revert_focus)
483 focus_ec = e_client_focused_get();
486 if (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK)
488 ELOGF("FOCUS", "focus unset | last_focused_focus", focus_ec);
489 e_client_frame_focus_set(focus_ec, EINA_FALSE);
497 e_desk_row_add(E_Zone *zone)
499 e_zone_desk_count_set(zone, zone->desk_x_count, zone->desk_y_count + 1);
503 e_desk_row_remove(E_Zone *zone)
505 e_zone_desk_count_set(zone, zone->desk_x_count, zone->desk_y_count - 1);
509 e_desk_col_add(E_Zone *zone)
511 e_zone_desk_count_set(zone, zone->desk_x_count + 1, zone->desk_y_count);
515 e_desk_col_remove(E_Zone *zone)
517 e_zone_desk_count_set(zone, zone->desk_x_count - 1, zone->desk_y_count);
521 e_desk_current_get(E_Zone *zone)
523 E_OBJECT_CHECK_RETURN(zone, NULL);
524 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
526 return e_desk_at_xy_get(zone, zone->desk_x_current, zone->desk_y_current);
530 e_desk_at_xy_get(E_Zone *zone, int x, int y)
532 E_OBJECT_CHECK_RETURN(zone, NULL);
533 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
535 if ((x >= zone->desk_x_count) || (y >= zone->desk_y_count))
537 else if ((x < 0) || (y < 0))
540 if (!zone->desks) return NULL;
541 return zone->desks[x + (y * zone->desk_x_count)];
545 e_desk_at_pos_get(E_Zone *zone, int pos)
549 E_OBJECT_CHECK_RETURN(zone, NULL);
550 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
552 y = pos / zone->desk_x_count;
553 x = pos - (y * zone->desk_x_count);
555 if ((x >= zone->desk_x_count) || (y >= zone->desk_y_count))
558 return zone->desks[x + (y * zone->desk_x_count)];
562 e_desk_xy_get(E_Desk *desk, int *x, int *y)
564 E_OBJECT_CHECK(desk);
565 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
572 e_desk_next(E_Zone *zone)
576 E_OBJECT_CHECK(zone);
577 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
579 if ((zone->desk_x_count < 2) && (zone->desk_y_count < 2))
582 x = zone->desk_x_current;
583 y = zone->desk_y_current;
586 if (x >= zone->desk_x_count)
590 if (y >= zone->desk_y_count) y = 0;
593 e_desk_show(e_desk_at_xy_get(zone, x, y));
597 e_desk_prev(E_Zone *zone)
601 E_OBJECT_CHECK(zone);
602 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
604 if ((zone->desk_x_count < 2) && (zone->desk_y_count < 2))
607 x = zone->desk_x_current;
608 y = zone->desk_y_current;
613 x = zone->desk_x_count - 1;
615 if (y < 0) y = zone->desk_y_count - 1;
617 e_desk_show(e_desk_at_xy_get(zone, x, y));
621 e_desk_window_profile_set(E_Desk *desk,
624 E_OBJECT_CHECK(desk);
625 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
627 eina_stringshare_replace(&desk->window_profile, profile);
629 _e_desk_event_simple_add(desk, E_EVENT_DESK_WINDOW_PROFILE_CHANGE);
633 e_desk_window_profile_add(int zone,
638 E_Config_Desktop_Window_Profile *cfprof;
640 e_desk_window_profile_del(zone, desk_x, desk_y);
642 cfprof = E_NEW(E_Config_Desktop_Window_Profile, 1);
645 cfprof->desk_x = desk_x;
646 cfprof->desk_y = desk_y;
647 cfprof->profile = eina_stringshare_add(profile);
648 e_config->desktop_window_profiles = eina_list_append(e_config->desktop_window_profiles, cfprof);
652 e_desk_window_profile_del(int zone,
657 E_Config_Desktop_Window_Profile *cfprof = NULL;
659 EINA_LIST_FOREACH(e_config->desktop_window_profiles, l, cfprof)
661 if (!((cfprof->zone == zone) &&
662 (cfprof->desk_x == desk_x) &&
663 (cfprof->desk_y == desk_y)))
666 e_config->desktop_window_profiles =
667 eina_list_remove_list(e_config->desktop_window_profiles, l);
668 eina_stringshare_del(cfprof->profile);
675 e_desk_window_profile_update(void)
677 const Eina_List *z, *l;
680 E_Config_Desktop_Window_Profile *cfprof;
683 if (!(e_config->use_desktop_window_profile))
686 EINA_LIST_FOREACH(e_comp->zones, z, zone)
688 for (d_x = 0; d_x < zone->desk_x_count; d_x++)
690 for (d_y = 0; d_y < zone->desk_y_count; d_y++)
692 desk = zone->desks[d_x + zone->desk_x_count * d_y];
695 EINA_LIST_FOREACH(e_config->desktop_window_profiles, l, cfprof)
697 if ((cfprof->zone >= 0) &&
698 ((int)zone->num != cfprof->zone)) continue;
699 if ((cfprof->desk_x != d_x) ||
700 (cfprof->desk_y != d_y)) continue;
701 e_desk_window_profile_set(desk, cfprof->profile);
708 e_desk_window_profile_set
709 (desk, e_config->desktop_default_window_profile);
717 e_desk_flip_cb_set(E_Desk_Flip_Cb cb, const void *data)
719 _e_desk_flip_cb = cb;
720 _e_desk_flip_data = (void*)data;
724 e_desk_flip_end(E_Desk *desk)
728 _e_desk_event_simple_add(desk, E_EVENT_DESK_AFTER_SHOW);
730 if ((e_config->focus_policy == E_FOCUS_MOUSE) ||
731 (e_config->focus_policy == E_FOCUS_SLOPPY))
733 ec = e_client_focused_get();
734 /* only set focus/warp pointer if currently focused window
735 * is on same screen (user hasn't switched screens during transition)
737 if (ec && ec->desk && (ec->desk->zone != desk->zone)) return;
739 if (starting) return;
740 ec = e_desk_last_focused_focus(desk);
741 if ((e_config->focus_policy != E_FOCUS_MOUSE) && (!ec))
743 /* we didn't previously have a focused window on this desk
744 * but we should, so this is probably the first time the
745 * user has flipped to this desk. let's be helpful and
746 * focus a random window!
748 E_CLIENT_REVERSE_FOREACH(ec)
750 /* start with top and go down... */
751 if (e_client_util_ignored_get(ec)) continue;
752 if (!e_client_util_desk_visible(ec, desk)) continue;
753 if (ec->iconic) continue;
754 if (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK)
756 ELOGF("FOCUS", "focus set | desk flip end", ec);
757 e_client_frame_focus_set(ec, EINA_TRUE);
759 if (e_config->raise_on_revert_focus)
771 unsigned int count = 0;
773 EINA_LIST_FOREACH(e_comp->zones, l, zone)
777 e_zone_desk_count_get(zone, &cx, &cy);
784 e_desk_client_add(E_Desk *desk, E_Client *ec)
786 if (!e_config->use_desk_smart_obj)
789 E_OBJECT_CHECK(desk);
790 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
793 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
795 _e_desk_smart_client_add(desk->smart_obj, ec);
799 e_desk_client_del(E_Desk *desk, E_Client *ec)
801 if (!e_config->use_desk_smart_obj)
804 E_OBJECT_CHECK(desk);
805 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
808 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
810 _e_desk_smart_client_del(desk->smart_obj, ec);
814 e_desk_geometry_set(E_Desk *desk, int x, int y, int w, int h)
818 Eina_List *l = NULL, *ll = NULL;
820 E_Event_Desk_Geometry_Change *ev = NULL;
824 if (!e_config->use_desk_smart_obj)
826 DBG("Do nothing, Desk Smart Object is disabled");
830 E_OBJECT_CHECK(desk);
831 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
833 E_DESK_SMART_DATA_GET_OR_RETURN(desk->smart_obj, sd);
835 if ((desk->geom.x == x) && (desk->geom.y == y) &&
836 (desk->geom.w == w) && (desk->geom.h == h))
839 dx = x - desk->geom.x;
840 dy = y - desk->geom.y;
841 EINA_RECTANGLE_SET(&desk->geom, x, y, w, h);
843 EINA_LIST_FOREACH(sd->clients, l, ec)
845 /* even if the desktop geometry is chagned, the system partial windows such as virtual
846 * keyboard and clipboard should be placed at the bottom of the desktop. */
848 if (e_policy_client_is_keyboard(ec))
852 else if ((ec->comp_data) && (ec->comp_data->sub.data))
856 else if (ec->maximized)
859 ec->maximized = E_MAXIMIZE_NONE;
860 e_client_maximize(ec, max);
864 e_client_geometry_get(ec, &cx, &cy, NULL, NULL);
865 e_client_util_move_without_frame(ec, cx + dx, cy + dy);
869 // E Client as an member of smart object is not changed even though parent obj is changed
870 // Workaround : update max geometry if ec is a member of desk->smart_obj
871 EINA_LIST_FOREACH(evas_object_smart_members_get(desk->smart_obj), ll, m)
873 ec = evas_object_data_get(m, "E_Client");
874 if (ec && ec->maximized)
877 ec->maximized = E_MAXIMIZE_NONE;
878 e_client_maximize(ec, max);
882 // apply geometry on smart obj
883 evas_object_geometry_set(desk->smart_obj, x, y, w, h);
885 ev = E_NEW(E_Event_Desk_Geometry_Change, 1);
893 e_object_ref(E_OBJECT(desk));
894 ecore_event_add(E_EVENT_DESK_GEOMETRY_CHANGE, ev,
895 _e_desk_event_desk_geometry_change_free, NULL);
898 e_comp_render_queue();
902 e_desk_zoom_set(E_Desk *desk, double zoomx, double zoomy, int cx, int cy)
907 E_Output *eout = NULL;
909 E_OBJECT_CHECK(desk);
910 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
912 if (e_config->use_pp_zoom)
914 if (e_comp_screen_pp_support())
917 eout = e_output_find(zone->output_id);
920 ERR("e_desk_zoom_set: fail get eout");
923 if (!e_output_zoom_set(eout, zoomx, zoomy, cx, cy))
924 ERR("e_desk_zoom_set: fail zoom set");
926 DBG("e_desk_zoom_set: zoomx:%f, zoomy:%f, x:%d, y:%d", zoomx, zoomy, cx, cy);
932 if (e_config->use_desk_smart_obj)
934 E_DESK_SMART_DATA_GET_OR_RETURN(desk->smart_obj, sd);
936 if ((sd->zoom.ratio_x != zoomx) || (sd->zoom.ratio_y != zoomy) ||
937 (sd->zoom.cord_x != cx) || (sd->zoom.cord_y != cy))
939 sd->zoom.ratio_x = zoomx;
940 sd->zoom.ratio_y = zoomy;
941 sd->zoom.cord_x = cx;
942 sd->zoom.cord_y = cy;
944 _e_desk_object_zoom(desk->smart_obj, zoomx, zoomy, cx, cy);
945 EINA_LIST_FOREACH(sd->clients, l, ec)
946 _e_desk_client_zoom(ec, zoomx, zoomy, cx, cy);
949 if (!sd->zoom.enabled)
951 sd->zoom.enabled = EINA_TRUE;
954 * NOTE: evas_object_map_enable_set is called in _e_desk_client_zoom()
957 * evas_object_map_enable_set(desk->smart_obj, EINA_TRUE);
958 * EINA_LIST_FOREACH(sd->clients, l, ec)
959 * evas_object_map_enable_set(ec->frame, EINA_TRUE);
962 /* FIXME TEMP disable hwc */
963 _e_desk_util_comp_hwc_disable_set(EINA_TRUE);
968 _e_desk_event_simple_add(desk, E_EVENT_DESK_ZOOM_SET);
972 e_desk_zoom_get(E_Desk *desk, double *zoomx, double *zoomy, int *cx, int *cy)
975 E_Output *eout = NULL;
976 Eina_Bool res = EINA_FALSE;
978 E_OBJECT_CHECK_RETURN(desk, EINA_FALSE);
979 E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, EINA_FALSE);
981 if (e_config->use_pp_zoom)
983 if (e_comp_screen_pp_support())
986 eout = e_output_find(zone->output_id);
989 ERR("e_desk_zoom_set: fail get eout");
993 res = e_output_zoom_get(eout, zoomx, zoomy, cx, cy);
998 if (e_config->use_desk_smart_obj)
1000 E_DESK_SMART_DATA_GET(desk->smart_obj, sd);
1001 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EINA_FALSE);
1003 if (zoomx) *zoomx = sd->zoom.ratio_x;
1004 if (zoomy) *zoomy = sd->zoom.ratio_y;
1005 if (cx) *cx = sd->zoom.cord_x;
1006 if (cy) *cy = sd->zoom.cord_y;
1015 e_desk_zoom_get_center_coordinate(E_Desk *desk, double zoomx, double zoomy, int rectx, int recty, int *cx, int *cy)
1017 E_Zone *zone = NULL;
1018 E_Output *eout = NULL;
1022 E_OBJECT_CHECK_RETURN(desk, EINA_FALSE);
1023 E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, EINA_FALSE);
1026 eout = e_output_find(zone->output_id);
1028 e_output_size_get(eout, &w, &h);
1033 if (e_config->use_pp_zoom)
1035 if (zoomx == 1 || rectx < 0 || zoomw + rectx >= w)
1038 if (zoomy == 1 || recty < 0 || zoomh + recty >= h)
1043 if (zoomx == 1 || zoomy == 1)
1050 *cx = (int)((zoomx * (double)rectx) / (zoomx - 1.0));
1055 *cy = (int)((zoomy * (double)recty) / (zoomy - 1.0));
1061 e_desk_zoom_unset(E_Desk *desk)
1065 E_Zone *zone = NULL;
1066 E_Output *eout = NULL;
1068 E_OBJECT_CHECK(desk);
1069 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1071 if (e_config->use_pp_zoom)
1073 if (e_comp_screen_pp_support())
1076 eout = e_output_find(zone->output_id);
1079 ERR("e_desk_zoom_unset: fail get eout");
1083 e_output_zoom_unset(eout);
1084 DBG("e_desk_zoom_unset");
1090 if (e_config->use_desk_smart_obj)
1092 E_DESK_SMART_DATA_GET_OR_RETURN(desk->smart_obj, sd);
1094 if (!sd->zoom.enabled)
1097 sd->zoom.ratio_x = 1.0;
1098 sd->zoom.ratio_y = 1.0;
1099 sd->zoom.cord_x = 0;
1100 sd->zoom.cord_y = 0;
1101 sd->zoom.enabled = EINA_FALSE;
1103 _e_desk_object_zoom(desk->smart_obj, sd->zoom.ratio_x, sd->zoom.ratio_y,
1104 sd->zoom.cord_x, sd->zoom.cord_y);
1106 * NOTE: evas_object_map_enable_set is called in _e_desk_client_zoom()
1109 * evas_object_map_enable_set(desk->smart_obj, EINA_FALSE);
1111 EINA_LIST_FOREACH(sd->clients, l, ec)
1113 /* NOTE Is it really necessary?
1114 * Why isn't it enough to just call evas_object_map_enable_set(false)? */
1115 _e_desk_client_zoom(ec, sd->zoom.ratio_x, sd->zoom.ratio_y,
1116 sd->zoom.cord_x, sd->zoom.cord_y);
1117 //evas_object_map_enable_set(ec->frame, EINA_FALSE);
1120 /* FIXME TEMP enable hwc */
1121 _e_desk_util_comp_hwc_disable_set(EINA_FALSE);
1125 _e_desk_event_simple_add(desk, E_EVENT_DESK_ZOOM_UNSET);
1129 e_desk_smart_member_add(E_Desk *desk, Evas_Object *obj)
1131 if (!e_config->use_desk_smart_obj)
1134 E_OBJECT_CHECK(desk);
1135 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1137 evas_object_smart_member_add(obj, desk->smart_obj);
1141 e_desk_smart_member_del(Evas_Object *obj)
1143 if (!e_config->use_desk_smart_obj)
1146 evas_object_smart_member_del(obj);
1150 e_desk_client_zoom_apply(E_Desk *desk, E_Client *ec)
1152 if (!e_config->use_desk_smart_obj)
1155 E_OBJECT_CHECK(desk);
1156 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1159 E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
1161 E_DESK_SMART_DATA_GET_OR_RETURN(desk->smart_obj, sd);
1163 if (sd->zoom.enabled)
1165 _e_desk_client_zoom(ec,
1166 sd->zoom.ratio_x, sd->zoom.ratio_y,
1167 sd->zoom.cord_x, sd->zoom.cord_y);
1172 _e_desk_free(E_Desk *desk)
1174 E_FREE_FUNC(desk->smart_obj, evas_object_del);
1175 eina_stringshare_del(desk->name);
1177 E_FREE_LIST(desk->handlers, ecore_event_handler_del);
1182 _e_desk_event_desk_show_free(void *data EINA_UNUSED, void *event)
1184 E_Event_Desk_Show *ev;
1187 e_object_unref(E_OBJECT(ev->desk));
1192 _e_desk_event_desk_before_show_free(void *data EINA_UNUSED, void *event)
1194 E_Event_Desk_Before_Show *ev;
1197 e_object_unref(E_OBJECT(ev->desk));
1202 _e_desk_event_desk_after_show_free(void *data EINA_UNUSED, void *event)
1204 E_Event_Desk_After_Show *ev;
1207 e_object_unref(E_OBJECT(ev->desk));
1212 _e_desk_event_desk_geometry_change_free(void *data EINA_UNUSED, void *event)
1214 E_Event_Desk_Geometry_Change *ev = event;
1215 e_object_unref(E_OBJECT(ev->desk));
1220 _e_desk_cb_zone_move_resize(void *data, int type EINA_UNUSED, void *event)
1222 E_Event_Zone_Move_Resize *ev;
1226 if (!ev) return ECORE_CALLBACK_PASS_ON;
1229 if (!desk) return ECORE_CALLBACK_PASS_ON;
1231 if (ev->zone != desk->zone)
1232 return ECORE_CALLBACK_PASS_ON;
1234 EINA_RECTANGLE_SET(&desk->geom, ev->zone->x, ev->zone->y, ev->zone->w, ev->zone->h);
1236 return ECORE_CALLBACK_PASS_ON;
1240 _e_desk_transition_setup(E_Client *ec, int dx, int dy, int state)
1242 e_comp_object_effect_set(ec->frame, "none");
1248 _e_desk_show_end(void *data, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
1250 E_Client *ec = data;
1252 ec->desk->animate_count--;
1253 e_client_comp_hidden_set(ec, ec->shaded);
1254 e_comp_object_effect_unclip(ec->frame);
1256 if (!ec->visible) evas_object_show(ec->frame);
1257 if (ec->desk != e_desk_current_get(ec->zone)) return;
1258 if (!ec->desk->animate_count) e_desk_flip_end(ec->desk);
1262 _e_desk_hide_end(void *data, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
1264 E_Client *ec = data;
1266 ec->desk->animate_count--;
1268 evas_object_hide(ec->frame);
1272 _e_desk_show_begin(E_Desk *desk, int dx, int dy)
1276 if (dx < 0) dx = -1;
1278 if (dy < 0) dy = -1;
1281 desk->animate_count = 0;
1282 E_CLIENT_FOREACH(ec)
1284 if (e_client_util_ignored_get(ec) || (ec->desk->zone != desk->zone) || (ec->iconic)) continue;
1287 e_client_desk_set(ec, desk);
1288 evas_object_show(ec->frame);
1291 if ((ec->desk != desk) || (ec->sticky)) continue;
1292 if ((!starting) && (!ec->new_client) && _e_desk_transition_setup(ec, dx, dy, 1))
1294 e_comp_object_effect_stop(ec->frame, _e_desk_hide_end);
1295 e_comp_object_effect_start(ec->frame, _e_desk_show_end, ec);
1296 desk->animate_count++;
1301 e_client_comp_hidden_set(ec, ec->hidden || ec->shaded);
1302 evas_object_show(ec->frame);
1304 e_desk_flip_end(desk);
1308 _e_desk_hide_begin(E_Desk *desk, int dx, int dy)
1312 if (dx < 0) dx = -1;
1314 if (dy < 0) dy = -1;
1317 desk->animate_count = 0;
1318 E_CLIENT_FOREACH(ec)
1320 if (e_client_util_ignored_get(ec) || (ec->desk->zone != desk->zone) || (ec->iconic)) continue;
1321 if (ec->moving) continue;
1322 if ((ec->desk != desk) || (ec->sticky)) continue;
1323 if ((!starting) && (!ec->new_client) && _e_desk_transition_setup(ec, -dx, -dy, 0))
1325 e_comp_object_effect_stop(ec->frame, _e_desk_show_end);
1326 e_comp_object_effect_start(ec->frame, _e_desk_hide_end, ec);
1327 desk->animate_count++;
1332 evas_object_show(ec->frame);
1333 ec->changes.visible = 0;
1334 evas_object_hide(ec->frame);
1336 e_client_comp_hidden_set(ec, EINA_TRUE);
1341 _e_desk_smart_init(E_Desk *desk)
1347 if (!e_config->use_desk_smart_obj)
1350 desk->smart_obj = evas_object_smart_add(e_comp->evas, _e_desk_smart_class_new());
1351 e_desk_geometry_set(desk, zone->x, zone->y, zone->w, zone->h);
1353 E_DESK_SMART_DATA_GET_OR_RETURN(desk->smart_obj, sd);
1355 sd->zoom.ratio_x = 1.0;
1356 sd->zoom.ratio_y = 1.0;
1357 sd->zoom.cord_x = 0;
1358 sd->zoom.cord_y = 0;
1362 _e_desk_smart_client_cb_resize(void *data, int type, void *event)
1365 E_Desk_Smart_Data *sd;
1366 E_Client *ec = NULL;
1368 if (!data) goto end;
1369 if (!event) goto end;
1376 if (!eina_list_data_find(sd->clients, ec))
1379 if (sd->zoom.enabled)
1380 _e_desk_client_zoom(ec,
1381 sd->zoom.ratio_x, sd->zoom.ratio_y,
1382 sd->zoom.cord_x, sd->zoom.cord_y);
1384 return ECORE_CALLBACK_PASS_ON;
1388 _e_desk_smart_add(Evas_Object *obj)
1390 EVAS_SMART_DATA_ALLOC(obj, E_Desk_Smart_Data);
1392 /* to apply zoom transformation whenever the client's size is changed. */
1393 E_LIST_HANDLER_APPEND(priv->handlers, E_EVENT_CLIENT_RESIZE, _e_desk_smart_client_cb_resize, priv);
1395 /* FIXME hard coded, it will be laid upper than unpacked clients */
1396 evas_object_layer_set(obj, E_LAYER_DESK_OBJECT);
1398 _e_desk_parent_sc->add(obj);
1402 _e_desk_smart_del(Evas_Object *obj)
1404 _e_desk_parent_sc->del(obj);
1406 E_DESK_SMART_DATA_GET_OR_RETURN(obj, sd);
1408 E_FREE_LIST(sd->handlers, ecore_event_handler_del);
1409 eina_list_free(sd->clients);
1412 evas_object_smart_data_set(obj, NULL);
1416 _e_desk_smart_member_add(Evas_Object *obj, Evas_Object *child)
1420 _e_desk_parent_sc->member_add(obj, child);
1422 ec = evas_object_data_get(child, "E_Client");
1424 e_desk_client_del(ec->desk, ec);
1428 _e_desk_smart_member_del(Evas_Object *obj, Evas_Object *child)
1430 E_Client *ec = NULL;
1431 Evas_Object *parent = NULL;
1433 _e_desk_parent_sc->member_del(obj, child);
1435 // if quickpanel packed into mover smart obj, _e_desk_smart_member_del is called
1436 // but parent is still e_desk, because mover's parent is the same e_desk
1437 // than don't add ec on the sd->clists
1438 parent = evas_object_smart_parent_get(child);
1439 if (parent && (parent == obj)) return;
1441 ec = evas_object_data_get(child, "E_Client");
1443 e_desk_client_add(ec->desk, ec);
1447 _e_desk_smart_set_user(Evas_Smart_Class *sc)
1449 sc->add = _e_desk_smart_add;
1450 sc->del = _e_desk_smart_del;
1451 sc->member_add = _e_desk_smart_member_add;
1452 sc->member_del = _e_desk_smart_member_del;
1456 _e_desk_smart_client_add(Evas_Object *obj, E_Client *ec)
1458 Evas_Object *parent = NULL;
1460 E_DESK_SMART_DATA_GET_OR_RETURN(obj, sd);
1462 // if ec is a member of e_desk, don't add it in data.
1463 parent = evas_object_smart_parent_get(ec->frame);
1464 if (parent && (parent == ec->desk->smart_obj)) return;
1466 if (eina_list_data_find(sd->clients, ec))
1469 sd->clients = eina_list_append(sd->clients, ec);
1470 evas_object_smart_changed(obj);
1474 _e_desk_smart_client_del(Evas_Object *obj, E_Client *ec)
1476 E_DESK_SMART_DATA_GET_OR_RETURN(obj, sd);
1478 if (!eina_list_data_find(sd->clients, ec))
1481 if (sd->zoom.enabled)
1482 _e_desk_client_zoom(ec, 1.0, 1.0, 0, 0);
1484 sd->clients = eina_list_remove(sd->clients, ec);
1485 evas_object_smart_changed(obj);
1489 _e_desk_util_comp_hwc_disable_set(Eina_Bool disable)
1492 e_comp_hwc_end("in runtime by e_desk");
1494 e_comp_hwc_deactive_set(disable);
1498 _e_desk_object_zoom(Evas_Object *obj, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy)
1503 map = evas_map_new(4);
1504 evas_map_util_object_move_sync_set(map, EINA_TRUE);
1505 evas_map_util_points_populate_from_object(map, obj);
1506 evas_map_util_zoom(map, zoomx, zoomy, cx, cy);
1507 evas_object_map_set(obj, map);
1508 enabled = ((zoomx != 1.0) || (zoomy != 1.0));
1509 evas_object_map_enable_set(obj, enabled);
1514 _e_desk_client_zoom(E_Client *ec, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy)
1516 Eina_Bool transformed;
1518 if (e_object_is_del(E_OBJECT(ec))) return;
1519 if (ec->is_cursor) return;
1521 transformed = e_client_transform_core_enable_get(ec);
1524 e_client_transform_core_update_with_desk_zoom(ec);
1526 _e_desk_object_zoom(ec->frame, zoomx, zoomy, cx, cy);
1528 if (evas_object_visible_get(ec->frame))
1531 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
1532 e_comp_object_dirty(ec->frame);
1533 e_comp_object_render(ec->frame);