1 #include "e.h"
2
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
5 * number of desktops.
6 */
7
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 dx, int dy);
15 static void _e_desk_hide_begin(E_Desk *desk, int dx, int dy);
16 static void _e_desk_event_desk_window_profile_change_free(void *data, void *ev);
17 static void _e_desk_window_profile_change_protocol_set(void);
18
19 static E_Desk_Flip_Cb _e_desk_flip_cb = NULL;
20 static void *_e_desk_flip_data = NULL;
21
22 E_API int E_EVENT_DESK_SHOW = 0;
23 E_API int E_EVENT_DESK_BEFORE_SHOW = 0;
24 E_API int E_EVENT_DESK_AFTER_SHOW = 0;
25 E_API int E_EVENT_DESK_DESKSHOW = 0;
26 E_API int E_EVENT_DESK_NAME_CHANGE = 0;
27 E_API int E_EVENT_DESK_WINDOW_PROFILE_CHANGE = 0;
28
29 EINTERN int
e_desk_init(void)30 e_desk_init(void)
31 {
32 E_EVENT_DESK_SHOW = ecore_event_type_new();
33 E_EVENT_DESK_BEFORE_SHOW = ecore_event_type_new();
34 E_EVENT_DESK_AFTER_SHOW = ecore_event_type_new();
35 E_EVENT_DESK_DESKSHOW = ecore_event_type_new();
36 E_EVENT_DESK_NAME_CHANGE = ecore_event_type_new();
37 E_EVENT_DESK_WINDOW_PROFILE_CHANGE = ecore_event_type_new();
38 return 1;
39 }
40
41 EINTERN int
e_desk_shutdown(void)42 e_desk_shutdown(void)
43 {
44 return 1;
45 }
46
47 static void
_do_profile(E_Desk * desk,E_Randr2_Screen * sc)48 _do_profile(E_Desk *desk, E_Randr2_Screen *sc)
49 {
50 int scale = 100;
51 char buf[PATH_MAX], buf2[PATH_MAX + 256];
52
53 eina_stringshare_del(desk->window_profile);
54 desk->window_profile = NULL;
55
56 if (sc->config.scale_multiplier > 0.0)
57 {
58 scale = (int)(sc->config.scale_multiplier * 100.0);
59 }
60 else if (e_config->scale.use_dpi)
61 {
62 double dpi = e_randr2_screen_dpi_get(sc);
63
64 if ((dpi > 0.0) && (e_config->scale.base_dpi > 0))
65 scale = (int)((100.0 * dpi) / (double)e_config->scale.base_dpi);
66 }
67
68 if (scale == 100)
69 snprintf(buf, sizeof(buf), "%s", sc->config.profile);
70 else
71 {
72 snprintf(buf, sizeof(buf), ".scale-%04i-%s",
73 scale, sc->config.profile);
74 if (!elm_config_profile_exists(buf))
75 {
76 snprintf(buf2, sizeof(buf2),
77 "%s/enlightenment/utils/enlightenment_elm_cfgtool "
78 "set %s %s 'scale-mul %i'",
79 e_prefix_lib_get(), sc->config.profile, buf, scale);
80 if (system(buf2) != 0)
81 ERR("Error code from trying to run \"%s\"", buf2);
82 }
83 }
84 desk->window_profile = eina_stringshare_add(buf);
85 }
86
87 E_API E_Desk *
e_desk_new(E_Zone * zone,int x,int y)88 e_desk_new(E_Zone *zone, int x, int y)
89 {
90 E_Desk *desk;
91 Eina_List *l;
92 E_Config_Desktop_Name *cfname;
93 int ok = 0;
94
95 E_OBJECT_CHECK_RETURN(zone, NULL);
96 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
97
98 desk = E_OBJECT_ALLOC(E_Desk, E_DESK_TYPE, _e_desk_free);
99 if (!desk) return NULL;
100
101 _e_desk_window_profile_change_protocol_set();
102
103 desk->zone = zone;
104 desk->x = x;
105 desk->y = y;
106
107 /* Get current desktop's name */
108 EINA_LIST_FOREACH(e_config->desktop_names, l, cfname)
109 {
110 if ((cfname->zone >= 0) &&
111 ((int)zone->num != cfname->zone)) continue;
112 if ((cfname->desk_x != desk->x) || (cfname->desk_y != desk->y))
113 continue;
114 desk->name = eina_stringshare_ref(cfname->name);
115 ok = 1;
116 break;
117 }
118
119 if (!ok) desk->name = eina_stringshare_add("");
120
121 /* Get window profile name for current desktop */
122 if (zone->randr2_id)
123 {
124 E_Randr2_Screen *sc = e_randr2_screen_id_find(zone->randr2_id);
125
126 if ((sc) && (sc->config.profile)) _do_profile(desk, sc);
127 }
128
129 return desk;
130 }
131
132 E_API E_Client *
e_desk_client_top_visible_get(const E_Desk * desk)133 e_desk_client_top_visible_get(const E_Desk *desk)
134 {
135 E_Client *ec;
136
137 E_OBJECT_CHECK_RETURN(desk, NULL);
138 E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, NULL);
139
140 E_CLIENT_REVERSE_FOREACH(ec)
141 if (e_client_util_desk_visible(ec, desk) && evas_object_visible_get(ec->frame)) return ec;
142 return NULL;
143 }
144
145 E_API void
e_desk_name_set(E_Desk * desk,const char * name)146 e_desk_name_set(E_Desk *desk, const char *name)
147 {
148 E_Event_Desk_Name_Change *ev;
149
150 E_OBJECT_CHECK(desk);
151 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
152
153 eina_stringshare_replace(&desk->name, name);
154
155 ev = E_NEW(E_Event_Desk_Name_Change, 1);
156 ev->desk = desk;
157 e_object_ref(E_OBJECT(desk));
158 ecore_event_add(E_EVENT_DESK_NAME_CHANGE, ev,
159 _e_desk_event_desk_name_change_free, NULL);
160 }
161
162 E_API void
e_desk_name_add(int zone,int desk_x,int desk_y,const char * name)163 e_desk_name_add(int zone, int desk_x, int desk_y, const char *name)
164 {
165 E_Config_Desktop_Name *cfname;
166
167 e_desk_name_del(zone, desk_x, desk_y);
168
169 cfname = E_NEW(E_Config_Desktop_Name, 1);
170 cfname->zone = zone;
171 cfname->desk_x = desk_x;
172 cfname->desk_y = desk_y;
173 if (name) cfname->name = eina_stringshare_add(name);
174 else cfname->name = NULL;
175 e_config->desktop_names = eina_list_append(e_config->desktop_names, cfname);
176 }
177
178 E_API void
e_desk_name_del(int zone,int desk_x,int desk_y)179 e_desk_name_del(int zone, int desk_x, int desk_y)
180 {
181 Eina_List *l = NULL;
182 E_Config_Desktop_Name *cfname = NULL;
183
184 EINA_LIST_FOREACH(e_config->desktop_names, l, cfname)
185 {
186 if ((cfname->zone == zone) &&
187 (cfname->desk_x == desk_x) && (cfname->desk_y == desk_y))
188 {
189 e_config->desktop_names =
190 eina_list_remove_list(e_config->desktop_names, l);
191 if (cfname->name) eina_stringshare_del(cfname->name);
192 E_FREE(cfname);
193 break;
194 }
195 }
196 }
197
198 E_API void
e_desk_name_update(void)199 e_desk_name_update(void)
200 {
201 const Eina_List *z, *l;
202 E_Zone *zone;
203 E_Desk *desk;
204 E_Config_Desktop_Name *cfname;
205 int d_x, d_y, ok;
206
207 EINA_LIST_FOREACH(e_comp->zones, z, zone)
208 {
209 for (d_x = 0; d_x < zone->desk_x_count; d_x++)
210 {
211 for (d_y = 0; d_y < zone->desk_y_count; d_y++)
212 {
213 desk = zone->desks[d_x + zone->desk_x_count * d_y];
214 ok = 0;
215
216 EINA_LIST_FOREACH(e_config->desktop_names, l, cfname)
217 {
218 if ((cfname->zone >= 0) &&
219 ((int)zone->num != cfname->zone)) continue;
220 if ((cfname->desk_x != d_x) ||
221 (cfname->desk_y != d_y)) continue;
222 e_desk_name_set(desk, cfname->name);
223 ok = 1;
224 break;
225 }
226
227 if (!ok) e_desk_name_set(desk, "");
228 }
229 }
230 }
231 }
232
233 E_API void
e_desk_show(E_Desk * desk)234 e_desk_show(E_Desk *desk)
235 {
236 E_Event_Desk_Show *ev;
237 E_Event_Desk_Before_Show *eev;
238 E_Event_Desk_After_Show *eeev;
239 Edje_Message_Float_Set *msg;
240 Eina_List *l;
241 E_Shelf *es;
242 E_Desk *desk2;
243 int was_zone = 0, dx = 0, dy = 0;
244
245 E_OBJECT_CHECK(desk);
246 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
247 if (desk->visible) return;
248 if (e_client_action_get() && e_client_util_resizing_get(e_client_action_get())) return;
249
250 desk2 = e_desk_at_xy_get(desk->zone, desk->zone->desk_x_current, desk->zone->desk_y_current);
251 if ((!starting) && (!desk2->visible)) return;
252 eev = E_NEW(E_Event_Desk_Before_Show, 1);
253 eev->desk = e_desk_current_get(desk->zone);
254 e_object_ref(E_OBJECT(eev->desk));
255 ecore_event_add(E_EVENT_DESK_BEFORE_SHOW, eev,
256 _e_desk_event_desk_before_show_free, NULL);
257
258 if (desk2->visible)
259 {
260 desk2->visible = 0;
261 if (e_config->desk_flip_wrap)
262 {
263 /* current desk (desk2) is last desk, switching to first desk (desk) */
264 if ((!desk->x) && (!desk->y) && (desk2->x + 1 == desk->zone->desk_x_count) && (desk2->y + 1 == desk->zone->desk_y_count))
265 {
266 dx = (desk->x != desk2->x) ? 1 : 0;
267 dy = (desk->y != desk2->y) ? 1 : 0;
268 }
269 /* current desk (desk2) is first desk, switching to last desk (desk) */
270 else if ((!desk2->x) && (!desk2->y) && (desk->x + 1 == desk->zone->desk_x_count) && (desk->y + 1 == desk->zone->desk_y_count))
271 {
272 dx = (desk->x != desk2->x) ? -1 : 0;
273 dy = (desk->y != desk2->y) ? -1 : 0;
274 }
275 }
276 if ((!dx) && (!dy))
277 {
278 dx = desk->x - desk2->x;
279 dy = desk->y - desk2->y;
280 }
281 _e_desk_hide_begin(desk2, dx, dy);
282 if (desk2->obstacles || desk->obstacles)
283 e_zone_useful_geometry_dirty(desk->zone);
284 }
285
286 desk->zone->desk_x_prev = desk->zone->desk_x_current;
287 desk->zone->desk_y_prev = desk->zone->desk_y_current;
288 desk->zone->desk_x_current = desk->x;
289 desk->zone->desk_y_current = desk->y;
290 desk->visible = 1;
291
292 msg = alloca(sizeof(Edje_Message_Float_Set) + (4 * sizeof(double)));
293 msg->count = 5;
294 msg->val[0] = 0.2 * (!!e_config->desk_flip_animate_mode);//e_config->desk_flip_animate_time;
295 msg->val[1] = desk->x;
296 msg->val[2] = desk->zone->desk_x_count;
297 msg->val[3] = desk->y;
298 msg->val[4] = desk->zone->desk_y_count;
299 if (desk->zone->bg_object)
300 edje_object_message_send(desk->zone->bg_object, EDJE_MESSAGE_FLOAT_SET, 0, msg);
301
302 if (desk->zone->bg_object) was_zone = 1;
303 _e_desk_show_begin(desk, dx, dy);
304
305 if (was_zone)
306 e_bg_zone_update(desk->zone, E_BG_TRANSITION_DESK);
307 else
308 e_bg_zone_update(desk->zone, E_BG_TRANSITION_START);
309
310 ev = E_NEW(E_Event_Desk_Show, 1);
311 ev->desk = desk;
312 e_object_ref(E_OBJECT(desk));
313 ecore_event_add(E_EVENT_DESK_SHOW, ev, _e_desk_event_desk_show_free, NULL);
314
315 EINA_LIST_FOREACH(e_shelf_list(), l, es)
316 {
317 if (es->zone != desk->zone) continue;
318 if (e_shelf_desk_visible(es, desk))
319 e_shelf_show(es);
320 else
321 e_shelf_hide(es);
322 }
323
324 if (e_config->desk_flip_animate_mode == 0)
325 {
326 eeev = E_NEW(E_Event_Desk_After_Show, 1);
327 eeev->desk = e_desk_current_get(desk->zone);
328 e_object_ref(E_OBJECT(eeev->desk));
329 ecore_event_add(E_EVENT_DESK_AFTER_SHOW, eeev,
330 _e_desk_event_desk_after_show_free, NULL);
331 }
332 e_zone_edge_flip_eval(desk->zone);
333 }
334
335 E_API void
e_desk_deskshow(E_Zone * zone)336 e_desk_deskshow(E_Zone *zone)
337 {
338 E_Client *ec;
339 E_Desk *desk;
340 E_Event_Desk_Show *ev;
341
342 E_OBJECT_CHECK(zone);
343 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
344
345 desk = e_desk_current_get(zone);
346 if (desk->deskshow_toggle)
347 {
348 /* uniconify raises windows and changes stacking order
349 * go top-down to avoid skipping windows
350 */
351 E_CLIENT_REVERSE_FOREACH(ec)
352 {
353 if (e_client_util_ignored_get(ec)) continue;
354 if (ec->desk != desk) continue;
355 if (ec->deskshow)
356 {
357 ec->deskshow = 0;
358 e_client_uniconify(ec);
359 }
360 }
361 }
362 else
363 {
364 /*
365 * iconify raises, so we have to start from the bottom so we are going forward
366 */
367 E_CLIENT_FOREACH(ec)
368 {
369 if (e_client_util_ignored_get(ec)) continue;
370 if (ec->desk != desk) continue;
371 if (ec->iconic) continue;
372 if (ec->netwm.state.skip_taskbar) continue;
373 if (ec->user_skip_winlist) continue;
374 ec->deskshow = 1;
375 e_client_iconify(ec);
376 }
377 }
378 desk->deskshow_toggle = !desk->deskshow_toggle;
379 ev = E_NEW(E_Event_Desk_Show, 1);
380 ev->desk = desk;
381 e_object_ref(E_OBJECT(desk));
382 ecore_event_add(E_EVENT_DESK_DESKSHOW, ev,
383 _e_desk_event_desk_deskshow_free, NULL);
384 }
385
386 E_API E_Client *
e_desk_last_focused_focus(E_Desk * desk)387 e_desk_last_focused_focus(E_Desk *desk)
388 {
389 Eina_List *l = NULL;
390 E_Client *ec, *ecs = NULL;
391
392 EINA_LIST_FOREACH(e_client_focus_stack_get(), l, ec)
393 {
394 if ((!ec->iconic) && (evas_object_visible_get(ec->frame) || ec->changes.visible) &&
395 ((desk &&
396 ((ec->desk == desk) || ((ec->zone == desk->zone) && ec->sticky))) ||
397 ((!desk) && ec->desk->visible)) &&
398 (ec->icccm.accepts_focus || ec->icccm.take_focus) &&
399 (ec->netwm.type != E_WINDOW_TYPE_DOCK) &&
400 (ec->netwm.type != E_WINDOW_TYPE_TOOLBAR) &&
401 (ec->netwm.type != E_WINDOW_TYPE_MENU) &&
402 (ec->netwm.type != E_WINDOW_TYPE_SPLASH) &&
403 (ec->netwm.type != E_WINDOW_TYPE_DESKTOP) &&
404 (!e_object_is_del(E_OBJECT(ec))))
405 {
406 /* this was the window last focused in this desktop */
407 if (!ec->lock_focus_out)
408 {
409 if (ec->sticky && (!e_config->focus_revert_allow_sticky))
410 {
411 ecs = ec;
412 continue;
413 }
414 if (ec->changes.visible && (!evas_object_visible_get(ec->frame)))
415 ec->want_focus = ec->take_focus = 1;
416 else
417 e_client_focus_set_with_pointer(ec);
418 if (e_config->raise_on_revert_focus)
419 evas_object_raise(ec->frame);
420 return ec;
421 }
422 }
423 }
424 if (ecs)
425 {
426 if (ecs->changes.visible && (!evas_object_visible_get(ecs->frame)))
427 ecs->want_focus = ecs->take_focus = 1;
428 else
429 e_client_focus_set_with_pointer(ecs);
430 if (e_config->raise_on_revert_focus)
431 evas_object_raise(ecs->frame);
432 return ecs;
433 }
434 if (e_client_focused_get())
435 evas_object_focus_set(e_client_focused_get()->frame, 0);
436 return NULL;
437 }
438
439 E_API void
e_desk_row_add(E_Zone * zone)440 e_desk_row_add(E_Zone *zone)
441 {
442 e_zone_desk_count_set(zone, zone->desk_x_count, zone->desk_y_count + 1);
443 }
444
445 E_API void
e_desk_row_remove(E_Zone * zone)446 e_desk_row_remove(E_Zone *zone)
447 {
448 e_zone_desk_count_set(zone, zone->desk_x_count, zone->desk_y_count - 1);
449 }
450
451 E_API void
e_desk_col_add(E_Zone * zone)452 e_desk_col_add(E_Zone *zone)
453 {
454 e_zone_desk_count_set(zone, zone->desk_x_count + 1, zone->desk_y_count);
455 }
456
457 E_API void
e_desk_col_remove(E_Zone * zone)458 e_desk_col_remove(E_Zone *zone)
459 {
460 e_zone_desk_count_set(zone, zone->desk_x_count - 1, zone->desk_y_count);
461 }
462
463 E_API E_Desk *
e_desk_current_get(E_Zone * zone)464 e_desk_current_get(E_Zone *zone)
465 {
466 E_OBJECT_CHECK_RETURN(zone, NULL);
467 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
468
469 return e_desk_at_xy_get(zone, zone->desk_x_current, zone->desk_y_current);
470 }
471
472 E_API E_Desk *
e_desk_at_xy_get(const E_Zone * zone,int x,int y)473 e_desk_at_xy_get(const E_Zone *zone, int x, int y)
474 {
475 E_OBJECT_CHECK_RETURN(zone, NULL);
476 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
477
478 if ((x >= zone->desk_x_count) || (y >= zone->desk_y_count))
479 return NULL;
480 else if ((x < 0) || (y < 0))
481 return NULL;
482
483 if (!zone->desks) return NULL;
484 return zone->desks[x + (y * zone->desk_x_count)];
485 }
486
487 E_API E_Desk *
e_desk_at_pos_get(E_Zone * zone,int pos)488 e_desk_at_pos_get(E_Zone *zone, int pos)
489 {
490 int x, y;
491
492 E_OBJECT_CHECK_RETURN(zone, NULL);
493 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
494
495 y = pos / zone->desk_x_count;
496 x = pos - (y * zone->desk_x_count);
497
498 if ((x >= zone->desk_x_count) || (y >= zone->desk_y_count))
499 return NULL;
500
501 return zone->desks[x + (y * zone->desk_x_count)];
502 }
503
504 E_API void
e_desk_xy_get(E_Desk * desk,int * x,int * y)505 e_desk_xy_get(E_Desk *desk, int *x, int *y)
506 {
507 E_OBJECT_CHECK(desk);
508 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
509
510 if (x) *x = desk->x;
511 if (y) *y = desk->y;
512 }
513
514 E_API void
e_desk_next(E_Zone * zone)515 e_desk_next(E_Zone *zone)
516 {
517 int x, y;
518
519 E_OBJECT_CHECK(zone);
520 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
521
522 if ((zone->desk_x_count < 2) && (zone->desk_y_count < 2))
523 return;
524
525 x = zone->desk_x_current;
526 y = zone->desk_y_current;
527
528 x++;
529 if (x >= zone->desk_x_count)
530 {
531 x = 0;
532 y++;
533 if (y >= zone->desk_y_count) y = 0;
534 }
535
536 e_desk_show(e_desk_at_xy_get(zone, x, y));
537 }
538
539 E_API void
e_desk_prev(E_Zone * zone)540 e_desk_prev(E_Zone *zone)
541 {
542 int x, y;
543
544 E_OBJECT_CHECK(zone);
545 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
546
547 if ((zone->desk_x_count < 2) && (zone->desk_y_count < 2))
548 return;
549
550 x = zone->desk_x_current;
551 y = zone->desk_y_current;
552
553 x--;
554 if (x < 0)
555 {
556 x = zone->desk_x_count - 1;
557 y--;
558 if (y < 0) y = zone->desk_y_count - 1;
559 }
560 e_desk_show(e_desk_at_xy_get(zone, x, y));
561 }
562
563 E_API void
e_desk_window_profile_set(E_Desk * desk,const char * profile)564 e_desk_window_profile_set(E_Desk *desk,
565 const char *profile)
566 {
567 E_Event_Desk_Window_Profile_Change *ev;
568
569 E_OBJECT_CHECK(desk);
570 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
571
572 eina_stringshare_replace(&desk->window_profile, profile);
573
574 ev = E_NEW(E_Event_Desk_Window_Profile_Change, 1);
575 ev->desk = desk;
576 e_object_ref(E_OBJECT(desk));
577 ecore_event_add(E_EVENT_DESK_WINDOW_PROFILE_CHANGE, ev,
578 _e_desk_event_desk_window_profile_change_free, NULL);
579 }
580
581 E_API void
e_desk_window_profile_update(E_Zone * zone)582 e_desk_window_profile_update(E_Zone *zone)
583 {
584 if (zone->randr2_id)
585 {
586 E_Randr2_Screen *sc = e_randr2_screen_id_find(zone->randr2_id);
587
588 if ((sc) && (sc->config.profile))
589 {
590 int x, y;
591
592 for (y = 0; y < zone->desk_y_count; y++)
593 {
594 for (x = 0; x < zone->desk_x_count; x++)
595 _do_profile(zone->desks[x + (y * zone->desk_x_count)], sc);
596 }
597 }
598 }
599 }
600
601 E_API void
e_desk_flip_cb_set(E_Desk_Flip_Cb cb,const void * data)602 e_desk_flip_cb_set(E_Desk_Flip_Cb cb, const void *data)
603 {
604 _e_desk_flip_cb = cb;
605 _e_desk_flip_data = (void*)data;
606 }
607
608 E_API void
e_desk_flip_end(E_Desk * desk)609 e_desk_flip_end(E_Desk *desk)
610 {
611 E_Event_Desk_After_Show *ev;
612 E_Client *ec;
613 Eina_Bool do_global_focus = EINA_FALSE;
614
615 ev = E_NEW(E_Event_Desk_After_Show, 1);
616 ev->desk = desk;
617 e_object_ref(E_OBJECT(ev->desk));
618 ecore_event_add(E_EVENT_DESK_AFTER_SHOW, ev,
619 _e_desk_event_desk_after_show_free, NULL);
620
621 e_comp_shape_queue();
622 if (desk->zone->desk_flip_sync)
623 {
624 Eina_List *l;
625 E_Zone *zone;
626 Eina_Bool sync = EINA_FALSE;
627
628 EINA_LIST_FOREACH(e_comp->zones, l, zone)
629 {
630 if (zone != desk->zone)
631 sync |= zone->desk_flip_sync;
632 }
633 do_global_focus = !sync;
634 desk->zone->desk_flip_sync = 0;
635 if (!do_global_focus) return;
636 }
637 if (!e_config->focus_last_focused_per_desktop) return;
638 if ((e_config->focus_policy == E_FOCUS_MOUSE) ||
639 (e_config->focus_policy == E_FOCUS_SLOPPY))
640 {
641 ec = e_client_focused_get();
642 /* only set focus/warp pointer if currently focused window
643 * is on same screen (user hasn't switched screens during transition)
644 */
645 if (do_global_focus)
646 {
647 if (ec && e_client_util_desk_visible(ec, ec->desk)) return;
648 }
649 else
650 {
651 if (ec && ec->desk && (ec->desk->zone != desk->zone)) return;
652 }
653 }
654 if (starting) return;
655 ec = e_desk_last_focused_focus(do_global_focus ? NULL : desk);
656 if ((e_config->focus_policy != E_FOCUS_MOUSE) && (!ec))
657 {
658 /* we didn't previously have a focused window on this desk
659 * but we should, so this is probably the first time the
660 * user has flipped to this desk. let's be helpful and
661 * focus a random window!
662 */
663 E_CLIENT_REVERSE_FOREACH(ec)
664 {
665 /* start with top and go down... */
666 if (e_client_util_ignored_get(ec)) continue;
667 if (!evas_object_visible_get(ec->frame)) continue;
668 if (ec->iconic) continue;
669 evas_object_focus_set(ec->frame, 1);
670 if (e_config->raise_on_revert_focus)
671 evas_object_raise(ec->frame);
672 return;
673 }
674 }
675 }
676
677 E_API unsigned int
e_desks_count(void)678 e_desks_count(void)
679 {
680 Eina_List *l;
681 E_Zone *zone;
682 unsigned int count = 0;
683
684 EINA_LIST_FOREACH(e_comp->zones, l, zone)
685 {
686 int cx = 0, cy = 0;
687
688 e_zone_desk_count_get(zone, &cx, &cy);
689 count += cx * cy;
690 }
691 return count;
692 }
693
694 static void
_e_desk_free(E_Desk * desk)695 _e_desk_free(E_Desk *desk)
696 {
697 while (desk->obstacles)
698 {
699 E_Object *obs = (void*)EINA_INLIST_CONTAINER_GET(desk->obstacles, E_Zone_Obstacle);
700 e_object_del(obs);
701 }
702 eina_stringshare_del(desk->name);
703 desk->name = NULL;
704 free(desk);
705 }
706
707 static void
_e_desk_event_desk_show_free(void * data EINA_UNUSED,void * event)708 _e_desk_event_desk_show_free(void *data EINA_UNUSED, void *event)
709 {
710 E_Event_Desk_Show *ev;
711
712 ev = event;
713 e_object_unref(E_OBJECT(ev->desk));
714 free(ev);
715 }
716
717 static void
_e_desk_event_desk_before_show_free(void * data EINA_UNUSED,void * event)718 _e_desk_event_desk_before_show_free(void *data EINA_UNUSED, void *event)
719 {
720 E_Event_Desk_Before_Show *ev;
721
722 ev = event;
723 e_object_unref(E_OBJECT(ev->desk));
724 free(ev);
725 }
726
727 static void
_e_desk_event_desk_after_show_free(void * data EINA_UNUSED,void * event)728 _e_desk_event_desk_after_show_free(void *data EINA_UNUSED, void *event)
729 {
730 E_Event_Desk_After_Show *ev;
731
732 ev = event;
733 e_object_unref(E_OBJECT(ev->desk));
734 free(ev);
735 }
736
737 static void
_e_desk_event_desk_deskshow_free(void * data EINA_UNUSED,void * event)738 _e_desk_event_desk_deskshow_free(void *data EINA_UNUSED, void *event)
739 {
740 E_Event_Desk_Show *ev;
741
742 ev = event;
743 e_object_unref(E_OBJECT(ev->desk));
744 free(ev);
745 }
746
747 static void
_e_desk_event_desk_name_change_free(void * data EINA_UNUSED,void * event)748 _e_desk_event_desk_name_change_free(void *data EINA_UNUSED, void *event)
749 {
750 E_Event_Desk_Name_Change *ev = event;
751 e_object_unref(E_OBJECT(ev->desk));
752 free(ev);
753 }
754
755 static void
_e_desk_event_desk_window_profile_change_free(void * data EINA_UNUSED,void * event)756 _e_desk_event_desk_window_profile_change_free(void *data EINA_UNUSED, void *event)
757 {
758 E_Event_Desk_Window_Profile_Change *ev = event;
759 e_object_unref(E_OBJECT(ev->desk));
760 E_FREE(ev);
761 }
762
763 static Eina_Bool
_e_desk_transition_setup(E_Client * ec,int dx,int dy,int state)764 _e_desk_transition_setup(E_Client *ec, int dx, int dy, int state)
765 {
766 e_comp_object_effect_set(ec->frame, e_config->desk_flip_animate_type ?: "none");
767 if (e_config->desk_flip_animate_type)
768 {
769 /* set geoms */
770 e_comp_object_effect_params_set(ec->frame, 1, (int[]){ec->x - ec->zone->x, ec->y - ec->zone->y, ec->w, ec->h, ec->zone->w, ec->zone->h, dx, dy}, 8);
771 e_comp_object_effect_params_set(ec->frame, 0, (int[]){state}, 1);
772 }
773
774 return !!e_config->desk_flip_animate_type;
775 }
776
777 static void
_e_desk_show_end(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)778 _e_desk_show_end(void *data, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
779 {
780 E_Client *ec = data;
781
782 ec->desk->animate_count--;
783 e_client_comp_hidden_set(ec, ec->shaded);
784 e_comp_object_effect_unclip(ec->frame);
785 ec->hidden = 0;
786 if (!ec->visible) evas_object_show(ec->frame);
787 if (ec->desk != e_desk_current_get(ec->zone)) return;
788 if (!ec->desk->animate_count) e_desk_flip_end(ec->desk);
789 }
790
791 static void
_e_desk_hide_end(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)792 _e_desk_hide_end(void *data, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
793 {
794 E_Client *ec = data;
795
796 ec->desk->animate_count--;
797 ec->hidden = 1;
798 evas_object_hide(ec->frame);
799 }
800
801 static void
_e_desk_show_begin(E_Desk * desk,int dx,int dy)802 _e_desk_show_begin(E_Desk *desk, int dx, int dy)
803 {
804 E_Client *ec;
805
806 if (dx < 0) dx = -1;
807 if (dx > 0) dx = 1;
808 if (dy < 0) dy = -1;
809 if (dy > 0) dy = 1;
810
811 desk->animate_count = 0;
812 if (_e_desk_flip_cb && e_config->desk_flip_animate_type)
813 {
814 _e_desk_flip_cb(_e_desk_flip_data, desk, dx, dy, 1);
815 return;
816 }
817 E_CLIENT_FOREACH(ec)
818 {
819 if (e_client_util_ignored_get(ec) || (ec->desk->zone != desk->zone) || (ec->iconic)) continue;
820 if (ec->moving)
821 {
822 e_client_desk_set(ec, desk);
823 evas_object_show(ec->frame);
824 continue;
825 }
826 if ((ec->desk != desk) || (ec->sticky)) continue;
827 if ((!starting) && (!ec->new_client) && _e_desk_transition_setup(ec, dx, dy, 1))
828 {
829 e_comp_object_effect_stop(ec->frame, _e_desk_hide_end);
830 e_comp_object_effect_start(ec->frame, _e_desk_show_end, ec);
831 desk->animate_count++;
832 }
833 else
834 ec->hidden = 0;
835
836 e_client_comp_hidden_set(ec, ec->hidden || ec->shaded);
837 evas_object_show(ec->frame);
838 }
839 if ((!e_config->desk_flip_animate_type) || (!desk->animate_count))
840 e_desk_flip_end(desk);
841 }
842
843 static void
_e_desk_hide_begin(E_Desk * desk,int dx,int dy)844 _e_desk_hide_begin(E_Desk *desk, int dx, int dy)
845 {
846 E_Client *ec;
847
848 if (dx < 0) dx = -1;
849 if (dx > 0) dx = 1;
850 if (dy < 0) dy = -1;
851 if (dy > 0) dy = 1;
852
853 desk->animate_count = 0;
854 if (_e_desk_flip_cb && e_config->desk_flip_animate_type)
855 {
856 _e_desk_flip_cb(_e_desk_flip_data, desk, dx, dy, 0);
857 return;
858 }
859 E_CLIENT_FOREACH(ec)
860 {
861 if (e_client_util_ignored_get(ec) || (ec->desk->zone != desk->zone) || (ec->iconic)) continue;
862 if (ec->moving) continue;
863 if ((ec->desk != desk) || (ec->sticky)) continue;
864 if ((!starting) && (!ec->new_client) && _e_desk_transition_setup(ec, -dx, -dy, 0))
865 {
866 e_comp_object_effect_stop(ec->frame, _e_desk_show_end);
867 e_comp_object_effect_start(ec->frame, _e_desk_hide_end, ec);
868 desk->animate_count++;
869 }
870 else
871 {
872 ec->hidden = 1;
873 evas_object_show(ec->frame);
874 ec->changes.visible = 0;
875 evas_object_hide(ec->frame);
876 }
877 e_client_comp_hidden_set(ec, EINA_TRUE);
878 }
879 }
880
881 static void
_e_desk_window_profile_change_protocol_set(void)882 _e_desk_window_profile_change_protocol_set(void)
883 {
884 #ifndef HAVE_WAYLAND_ONLY
885 static Eina_Bool is_set = EINA_FALSE;
886
887 if (!is_set)
888 {
889 if (e_comp->root)
890 {
891 is_set = EINA_TRUE;
892 ecore_x_e_window_profile_supported_set(e_comp->root, EINA_TRUE);
893 }
894 }
895 #endif
896 }
897