0e8cccc68ca580579eb4772775e6adad43d48b5b
[platform/upstream/enlightenment.git] / src / bin / e_focus_policy_history.c
1 #include "e_focus_policy_iface.h"
2 #include "e_zone_intern.h"
3 #include "e_client_intern.h"
4 #include "e_comp_object_intern.h"
5 #include "e_comp_intern.h"
6 #include "e_policy_visibility_intern.h"
7 #include "e_desk_intern.h"
8 #include "e_config_intern.h"
9
10 typedef struct _E_Focus_Policy_History_Impl E_Focus_Policy_History;
11 typedef struct _E_Focus_Policy_History_Client E_Focus_Policy_History_Client;
12
13 struct _E_Focus_Policy_History_Impl
14 {
15    E_Zone   *zone;
16    E_Client *focused_ec;
17
18    Eina_List *focus_stack;
19    Eina_List *defer_focus_stack;
20
21    struct wl_listener zone_client_add;
22    struct wl_listener zone_client_remove;
23    struct wl_listener zone_focus_clear;
24    struct wl_listener zone_focus_reset;
25 };
26
27 struct _E_Focus_Policy_History_Client
28 {
29    E_Client *ec;
30    E_Focus_Policy_History *history_policy;
31
32    struct wl_listener client_destroy;
33    struct wl_listener client_mouse_in;
34    struct wl_listener client_mouse_out;
35    struct wl_listener client_mouse_down;
36    struct wl_listener client_focus_set;
37    struct wl_listener client_focus_unset;
38    struct wl_listener client_lower;
39    struct wl_listener client_move;
40    struct wl_listener client_focus_defer_set;
41    struct wl_listener client_focus_latest_set;
42    struct wl_listener client_activate_done;
43    struct wl_listener client_eval_end;
44    struct wl_listener stack_transient_for_done;
45
46 #ifdef REFACTOR_DESK_AREA
47    struct wl_listener comp_object_lower_done;
48 #else
49    struct wl_listener comp_object_lower;
50 #endif
51    struct wl_listener comp_object_show;
52    struct wl_listener comp_object_hide;
53 };
54
55 // Trace the focus history
56 //#define FOCUS_HISTORY_TRACE
57 #ifdef FOCUS_HISTORY_TRACE
58 #define E_FOCUS_HISTORY_TRACE(history_policy, ec) \
59   do \
60     { \
61        ELOGF( \
62              "FOCUS_HISTORY", "[FOCUS][Trace][%s]:(%p, %d) focused_ec:%p focus_stack#:%d defer_stack#:%d", ec, \
63              __FUNCTION__, history_policy, history_policy->zone->id, history_policy->focused_ec, \
64              eina_list_count(history_policy->focus_stack), eina_list_count(history_policy->defer_focus_stack)\
65             ); \
66     } \
67   while (0)
68 #else
69 #define E_FOCUS_HISTORY_TRACE(history_policy, ec)
70 #endif
71
72 static void
73 _focus_policy_history_focus_stack_latest_set(E_Focus_Policy_History *history_policy, E_Client *ec)
74 {
75    history_policy->focus_stack = eina_list_remove(history_policy->focus_stack, ec);
76    history_policy->focus_stack = eina_list_prepend(history_policy->focus_stack, ec);
77
78    E_FOCUS_HISTORY_TRACE(history_policy, ec);
79 }
80
81 static void
82 _focus_policy_history_focus_stack_lower(E_Focus_Policy_History *history_policy, E_Client *ec)
83 {
84    Eina_List *l = NULL;
85    E_Client *ec2 = NULL;
86
87    history_policy->focus_stack = eina_list_remove(history_policy->focus_stack, ec);
88
89    EINA_LIST_REVERSE_FOREACH(history_policy->focus_stack, l, ec2)
90      {
91         if (ec2 == NULL) continue;
92         if (ec2->layer < ec->layer) continue;
93
94         history_policy->focus_stack = eina_list_append_relative_list(history_policy->focus_stack, ec, l);
95
96         return;
97      }
98
99    history_policy->focus_stack = eina_list_prepend(history_policy->focus_stack, ec);
100 }
101
102 static void
103 _e_focus_policy_history_focus_focus_defer_set(E_Focus_Policy_History *history_policy, E_Client *ec)
104 {
105    ELOGF("FOCUS_HISTORY", "focus defer set", ec);
106
107    history_policy->defer_focus_stack = eina_list_remove(history_policy->defer_focus_stack, ec);
108    history_policy->defer_focus_stack = eina_list_prepend(history_policy->defer_focus_stack, ec);
109
110    E_FOCUS_HISTORY_TRACE(history_policy, ec);
111 }
112
113 static void
114 _e_focus_policy_history_focus_defer_unset(E_Focus_Policy_History *history_policy, E_Client *ec)
115 {
116    ELOGF("FOCUS_HISTORY", "focus defer unset", ec);
117
118    history_policy->defer_focus_stack = eina_list_remove(history_policy->defer_focus_stack, ec);
119
120    E_FOCUS_HISTORY_TRACE(history_policy, ec);
121 }
122
123 static void
124 _e_focus_policy_history_merge_focus_stack_with_defer_focus(E_Focus_Policy_History *history_policy)
125 {
126    Eina_List *l = NULL;
127    E_Client *ec = NULL, *defer_ec = NULL;
128    Eina_Bool find_rel = EINA_FALSE;
129    Eina_Bool inserted = EINA_FALSE;
130    E_Client *focused_ec;
131
132    focused_ec = history_policy->focused_ec;
133
134    if (!history_policy->focus_stack)
135      {
136         history_policy->focus_stack = eina_list_merge(history_policy->focus_stack, history_policy->defer_focus_stack);
137         goto end;
138      }
139
140    E_CLIENT_FOREACH(defer_ec)
141      {
142         if (!eina_list_data_find(history_policy->defer_focus_stack, defer_ec)) continue;
143
144         find_rel = EINA_FALSE;
145         inserted = EINA_FALSE;
146         history_policy->focus_stack = eina_list_remove(history_policy->focus_stack, defer_ec);
147
148         EINA_LIST_FOREACH(history_policy->focus_stack, l, ec)
149           {
150              if (ec == NULL) continue;
151
152              if (!find_rel)
153                {
154                   if (ec == focused_ec)
155                     find_rel = EINA_TRUE;
156                   continue;
157                }
158
159              if (ec->layer > defer_ec->layer) continue;
160
161              history_policy->focus_stack = eina_list_prepend_relative_list(history_policy->focus_stack, defer_ec, l);
162              inserted = EINA_TRUE;
163              break;
164           }
165
166         if (!inserted)
167           history_policy->focus_stack = eina_list_append(history_policy->focus_stack, defer_ec);
168      }
169
170 end:
171    history_policy->defer_focus_stack = eina_list_free(history_policy->defer_focus_stack);
172 }
173
174 static E_Client *
175 _e_focus_policy_history_candidate_focus_get(E_Focus_Policy_History *history_policy, E_Client *reverted_focus_ec)
176 {
177    E_Client *ec, *cec;
178    E_Client *focused_ec, *defered_focus_ec = NULL;
179    Eina_List *child_list = NULL;
180    Eina_List *l = NULL;
181    Eina_Bool child_deferred;
182    E_Zone *zone;
183    E_Desk *desk;
184
185    zone = history_policy->zone;
186    focused_ec = history_policy->focused_ec;
187
188    desk = e_desk_current_get(zone);
189
190    E_CLIENT_REVERSE_FOREACH(ec)
191      {
192         if (!eina_list_data_find(history_policy->defer_focus_stack, ec)) continue;
193
194         if (e_object_is_del(E_OBJECT(ec))) continue;
195         if (e_client_util_ignored_get(ec)) continue;
196         if (!e_zone_has_ec(zone, ec)) continue;
197         if (!desk) continue;
198         if (!e_desk_has_ec(desk, ec)) continue;
199
200         if (!(ec->icccm.accepts_focus || ec->icccm.take_focus)) continue;
201         if (ec->lock_focus_in || ec->lock_focus_out) continue;
202         if (!evas_object_visible_get(ec->frame)) continue;
203         if (ec->iconic) continue;
204         if (ec->bg_state) continue;
205
206         if (!(cec = e_client_check_obscured_by_children_group(ec)) ||
207             e_client_check_really_iconified(cec))
208           {
209              if (ec->visibility.obscured != E_VISIBILITY_UNOBSCURED) continue;
210              if (e_client_check_fully_contain_by_above(ec, EINA_FALSE)) continue;
211           }
212
213         if (focused_ec && (focused_ec->layer > ec->layer)) continue;
214         else if (!focused_ec && reverted_focus_ec && (reverted_focus_ec->layer > ec->layer)) continue;
215
216         // check transient_for child defered
217         child_deferred = EINA_FALSE;
218         child_list = eina_list_clone(ec->transients);
219         EINA_LIST_FOREACH(child_list, l, cec)
220           {
221              if (e_client_transient_policy_get(cec) == E_TRANSIENT_BELOW) continue;
222              if (!(cec->icccm.accepts_focus || cec->icccm.take_focus)) continue;
223              if (eina_list_data_find(history_policy->defer_focus_stack, cec))
224                {
225                   child_deferred = EINA_TRUE;
226                   break;
227                }
228           }
229         eina_list_free(child_list);
230         if (child_deferred) continue;
231
232         defered_focus_ec = ec;
233         break;
234      }
235
236    return defered_focus_ec;
237 }
238
239 static Eina_Bool
240 _e_focus_policy_history_focus_can_take_by_vis_obscured(E_Focus_Policy_History *history_policy, E_Client *ec)
241 {
242    switch (ec->visibility.obscured)
243      {
244        case E_VISIBILITY_UNKNOWN:
245            if (e_client_check_really_iconified(ec))
246              return EINA_FALSE;
247
248            if (!evas_object_visible_get(ec->frame) &&
249                !eina_list_data_find(history_policy->defer_focus_stack, ec))
250              return EINA_FALSE;
251            break;
252
253        case E_VISIBILITY_FULLY_OBSCURED:
254            if (e_client_check_really_iconified(ec))
255              return EINA_FALSE;
256            break;
257
258        case E_VISIBILITY_UNOBSCURED:
259        case E_VISIBILITY_PARTIALLY_OBSCURED:
260        case E_VISIBILITY_PRE_UNOBSCURED:
261        default:
262            break;
263      }
264    return EINA_TRUE;
265 }
266
267 static Eina_Bool
268 _e_focus_policy_history_focus_can_take(E_Focus_Policy_History *history_policy, E_Client *ec)
269 {
270    E_Zone *zone;
271    E_Client *child_ec, *above_ec;
272    int x = 0, y = 0, w = 0, h = 0;
273
274    if (!ec) return EINA_FALSE;
275    if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
276    if (e_client_util_ignored_get(ec)) return EINA_FALSE;
277
278    if (!(ec->icccm.accepts_focus || ec->icccm.take_focus)) return EINA_FALSE;
279    if (ec->lock_focus_in || ec->lock_focus_out) return EINA_FALSE;
280
281    if (!ec->visible) return EINA_FALSE;
282    if (ec->bg_state) return EINA_FALSE;
283    if (ec->visibility.force_obscured) return EINA_FALSE;
284    if (!_e_focus_policy_history_focus_can_take_by_vis_obscured(history_policy, ec)) return EINA_FALSE;
285
286    zone = e_comp_zone_find_by_ec(ec);
287    if (zone)
288      {
289         e_client_geometry_get(ec, &x, &y, &w, &h);
290         if (!E_INTERSECTS(zone->x, zone->y, zone->w, zone->h, x, y, w, h))
291           return EINA_FALSE;
292      }
293
294    above_ec = e_client_check_fully_contain_by_above(ec, EINA_FALSE);
295    if (above_ec)
296      {
297         child_ec = e_client_check_obscured_by_children_group(ec);
298         if (!child_ec) return EINA_FALSE;
299         if (above_ec != child_ec) return EINA_FALSE;
300
301         if (_e_focus_policy_history_focus_can_take(history_policy, child_ec))
302           return EINA_FALSE;
303         else if (e_client_check_fully_contain_by_above(child_ec, EINA_FALSE))
304           return EINA_FALSE;
305      }
306
307    return EINA_TRUE;
308 }
309
310 static E_Client *
311 _focus_policy_history_find_next_focusable_ec(E_Focus_Policy_History *history_policy, E_Client *ec)
312 {
313    Eina_List *l = NULL;
314    E_Client *temp_ec = NULL;
315
316    // call the intercept hook of the revert focus
317    if (e_client_intercept_hook_focus_revert_call(ec))
318      return NULL;
319
320    EINA_LIST_FOREACH(history_policy->focus_stack, l, temp_ec)
321      {
322         if (_e_focus_policy_history_focus_can_take(history_policy, temp_ec))
323           return temp_ec;
324      }
325
326    return NULL;
327 }
328
329 static E_Client *
330 _focus_policy_history_focusable_get(E_Focus_Policy_History *history_policy, E_Client *ec)
331 {
332    E_Client *pec = NULL, *focusable_ec = NULL;
333    E_Zone *zone;
334    E_Desk *desk = NULL;
335
336    if (stopping) return NULL;
337
338    if (!ec)
339      return _focus_policy_history_find_next_focusable_ec(history_policy, NULL);
340
341    zone = history_policy->zone;
342
343    desk = e_desk_current_get(zone);
344    if (!desk) return NULL;
345    if (!e_comp_client_zone_is_displaying(ec)) return NULL;
346
347    if (e_config->focus_policy == E_FOCUS_MOUSE)
348      {
349         // set mouse over focus
350         pec = e_client_under_pointer_get(desk, ec);
351         if (pec)
352           focusable_ec = pec;
353         /* no autoraise/revert here because it's probably annoying */
354      }
355    else
356      focusable_ec = _focus_policy_history_find_next_focusable_ec(history_policy, ec);
357
358    return focusable_ec;
359 }
360
361 static void
362 _focus_policy_history_next_focus_set(E_Focus_Policy_History *history_policy, E_Client *ec)
363 {
364    E_Client *focusable_ec;
365
366    focusable_ec = _focus_policy_history_focusable_get(history_policy, ec);
367    if (!focusable_ec) return;
368
369    if (focusable_ec != ec)
370      {
371         _e_focus_policy_history_focus_defer_unset(history_policy, ec);
372         ELOGF("FOCUS_HISTORY", "focus unset | revert_focus", ec);
373         e_client_frame_focus_set(ec, EINA_FALSE);
374      }
375
376    if (!focusable_ec->iconic || focusable_ec->exp_iconify.buffer_flush)
377      {
378         ELOGF("FOCUS_HISTORY", "focus set   | revert_focus", focusable_ec);
379         e_client_frame_focus_set(focusable_ec, EINA_TRUE);
380      }
381 }
382
383 static void
384 _focus_policy_history_cb_client_destroy(struct wl_listener *listener, void *data)
385 {
386    E_Focus_Policy_History_Client *history_client;
387    E_Focus_Policy_History *history_policy;
388    E_Client *ec;
389
390    history_client = wl_container_of(listener, history_client, client_destroy);
391
392    history_policy = history_client->history_policy;
393    EINA_SAFETY_ON_NULL_RETURN(history_policy);
394
395    ec = history_client->ec;
396    EINA_SAFETY_ON_NULL_RETURN(ec);
397
398    E_FOCUS_HISTORY_TRACE(history_policy, ec);
399
400    wl_list_remove(&history_client->comp_object_hide.link);
401    wl_list_remove(&history_client->comp_object_show.link);
402 #ifdef REFACTOR_DESK_AREA
403    wl_list_remove(&history_client->comp_object_lower_done.link);
404 #else
405    wl_list_remove(&history_client->comp_object_lower.link);
406 #endif
407
408    wl_list_remove(&history_client->stack_transient_for_done.link);
409    wl_list_remove(&history_client->client_eval_end.link);
410    wl_list_remove(&history_client->client_activate_done.link);
411    wl_list_remove(&history_client->client_focus_latest_set.link);
412    wl_list_remove(&history_client->client_focus_defer_set.link);
413    wl_list_remove(&history_client->client_lower.link);
414    wl_list_remove(&history_client->client_move.link);
415    wl_list_remove(&history_client->client_focus_unset.link);
416    wl_list_remove(&history_client->client_focus_set.link);
417    wl_list_remove(&history_client->client_mouse_down.link);
418    wl_list_remove(&history_client->client_mouse_out.link);
419    wl_list_remove(&history_client->client_mouse_in.link);
420    wl_list_remove(&history_client->client_destroy.link);
421
422    E_FREE(history_client);
423 }
424
425 static void
426 _focus_policy_history_cb_client_mouse_in(struct wl_listener *listener, void *data)
427 {
428    E_Focus_Policy_History_Client *history_client;
429    E_Focus_Policy_History *history_policy;
430    E_Client *ec;
431
432    history_client = wl_container_of(listener, history_client, client_mouse_in);
433
434    history_policy = history_client->history_policy;
435    EINA_SAFETY_ON_NULL_RETURN(history_policy);
436
437    ec = history_client->ec;
438    EINA_SAFETY_ON_NULL_RETURN(ec);
439
440    E_FOCUS_HISTORY_TRACE(history_policy, ec);
441
442    if ((!ec->iconic) && (!e_client_util_ignored_get(ec)))
443      {
444         if ((e_config->focus_policy == E_FOCUS_MOUSE) ||
445             (e_config->focus_policy == E_FOCUS_SLOPPY))
446           {
447              ELOGF("FOCUS_HISTORY", "focus set   | mouse in", ec);
448              e_client_frame_focus_set(ec, EINA_TRUE);
449           }
450
451         if (e_config->use_auto_raise)
452           {
453              if (!ec->lock_user_stacking)
454                e_client_raise(ec);
455           }
456      }
457 }
458
459 static void
460 _focus_policy_history_cb_client_mouse_out(struct wl_listener *listener, void *data)
461 {
462    E_Focus_Policy_History_Client *history_client;
463    E_Focus_Policy_History *history_policy;
464    E_Client *ec;
465
466    history_client = wl_container_of(listener, history_client, client_mouse_out);
467
468    history_policy = history_client->history_policy;
469    EINA_SAFETY_ON_NULL_RETURN(history_policy);
470
471    ec = history_client->ec;
472    EINA_SAFETY_ON_NULL_RETURN(ec);
473
474    E_FOCUS_HISTORY_TRACE(history_policy, ec);
475
476    if ((!ec->iconic) && (!e_client_util_ignored_get(ec)))
477      {
478         if (e_config->focus_policy == E_FOCUS_MOUSE)
479           {
480              if (!ec->lock_focus_in)
481                {
482                   if (ec->focused)
483                     {
484                        ELOGF("FOCUS_HISTORY", "focus unset | mouse out", ec);
485                        e_client_frame_focus_set(ec, EINA_FALSE);
486                     }
487                }
488           }
489      }
490 }
491
492 static void
493 _focus_policy_history_cb_client_mouse_down(struct wl_listener *listener, void *data)
494 {
495    E_Focus_Policy_History_Client *history_client;
496    E_Focus_Policy_History *history_policy;
497    E_Client *ec;
498    E_Client *focused_ec;
499
500    history_client = wl_container_of(listener, history_client, client_mouse_down);
501
502    history_policy = history_client->history_policy;
503    EINA_SAFETY_ON_NULL_RETURN(history_policy);
504
505    ec = history_client->ec;
506    EINA_SAFETY_ON_NULL_RETURN(ec);
507
508    E_FOCUS_HISTORY_TRACE(history_policy, ec);
509
510    focused_ec = history_policy->focused_ec;
511    if ((focused_ec) && (ec != focused_ec))
512      {
513         if (e_client_focus_policy_click(ec) ||
514             e_config->always_click_to_focus)
515           {
516              ELOGF("FOCUS_HISTORY", "focus set   | mouse down", ec);
517              e_client_frame_focus_set(ec, EINA_TRUE);
518
519              if (ec->floating)
520                e_client_raise(ec);
521           }
522
523         if (e_config->always_click_to_raise)
524           {
525              if (!ec->lock_user_stacking)
526                {
527                   e_client_raise(ec);
528                   _e_focus_policy_history_focus_focus_defer_set(history_policy, ec);
529                }
530
531              if (ec->parent && e_client_is_belong_to_parent(ec))
532                {
533                   if (!ec->parent->lock_user_stacking)
534                     e_client_raise(ec->parent);
535                }
536           }
537      }
538 }
539
540 static void set_focused_ec(E_Focus_Policy_History *history_policy, E_Client *ec)
541 {
542    atomic_store(&history_policy->focused_ec, ec);
543 }
544
545 static void
546 _focus_policy_history_cb_client_focus_set(struct wl_listener *listener, void *data)
547 {
548    E_Focus_Policy_History_Client *history_client;
549    E_Focus_Policy_History *history_policy;
550 #ifdef REFACTOR_DESK_AREA
551    E_Client *focused_ec, *ec;
552 #else
553    E_Client *focused_ec, *ec, *ec2;
554    E_Zone *zone;
555    Eina_List *l, *ll;
556 #endif
557
558    history_client = wl_container_of(listener, history_client, client_focus_set);
559
560    history_policy = history_client->history_policy;
561    EINA_SAFETY_ON_NULL_RETURN(history_policy);
562
563    ec = history_client->ec;
564    EINA_SAFETY_ON_NULL_RETURN(ec);
565
566    E_FOCUS_HISTORY_TRACE(history_policy, ec);
567
568    focused_ec = history_policy->focused_ec;
569    if (ec == focused_ec) return;
570
571 #ifdef REFACTOR_DESK_AREA
572 #else
573    zone = history_policy->zone;
574 #endif
575
576    ec->focused = 1;
577
578 #ifdef REFACTOR_DESK_AREA
579 #else
580    // TODO: This is not for focus policy, but for fullscreen(Window State) policy.
581    //       Move this code to the better place.
582    int x, total = zone->desk_x_count * zone->desk_y_count;
583    for (x = 0; x < total; x++)
584      {
585         E_Desk *desk = zone->desks[x];
586         /* if there's any fullscreen non-parents on this desk, unfullscreen them */
587         EINA_LIST_FOREACH_SAFE(desk->fullscreen_clients, l, ll, ec2)
588           {
589              if (ec2 == ec) continue;
590              if (e_object_is_del(E_OBJECT(ec2))) continue;
591              /* but only if it's the same desk or one of the clients is sticky */
592              if (e_desk_has_ec(desk, ec) || (ec->sticky || ec2->sticky))
593                {
594                   if (!eina_list_data_find(ec->transients, ec2))
595                      e_client_unfullscreen(ec2);
596                }
597           }
598      }
599 #endif
600
601    _focus_policy_history_focus_stack_latest_set(history_policy, ec);
602
603    // assign the focused_ec
604    set_focused_ec(history_policy, ec);
605
606    ELOGF("FOCUS_HISTORY", "focus_set | focused_ec SET", ec);
607 }
608
609 static void
610 _focus_policy_history_cb_client_focus_unset(struct wl_listener *listener, void *data)
611 {
612    E_Focus_Policy_History_Client *history_client;
613    E_Focus_Policy_History *history_policy;
614    E_Client *ec, *ec2;
615    E_Zone *zone;
616    Eina_List *l;
617
618    history_client = wl_container_of(listener, history_client, client_focus_unset);
619
620    history_policy = history_client->history_policy;
621    EINA_SAFETY_ON_NULL_RETURN(history_policy);
622
623    ec = history_client->ec;
624    EINA_SAFETY_ON_NULL_RETURN(ec);
625
626    E_FOCUS_HISTORY_TRACE(history_policy, ec);
627
628    zone = history_policy->zone;
629
630    ec->want_focus = ec->focused = 0;
631    if (ec->mouse.in && ec && (!e_client_util_is_popup(ec)) &&
632       (e_config->focus_policy != E_FOCUS_CLICK))
633       e_client_mouse_out(ec, ec->x - 1, ec->y - 1);
634
635    /* if there unfocus client is fullscreen and visible */
636    if ((ec->fullscreen) && (!ec->iconic) && (!ec->hidden) &&
637       (zone == e_zone_current_get()) &&
638       (e_desk_has_ec(e_desk_current_get(zone), ec) || (ec->sticky)))
639       {
640          Eina_Bool have_vis_child = EINA_FALSE;
641          E_Desk *desk, *desk2;
642          desk = e_zone_desk_find_by_ec(zone, ec);
643          /* if any of its children are visible */
644          EINA_LIST_FOREACH(ec->transients, l, ec2)
645          {
646             desk2 = e_zone_desk_find_by_ec(zone, ec2);
647             if (((desk2 == desk) ||
648                  (ec2->sticky) || (ec->sticky)))
649                {
650                   have_vis_child = EINA_TRUE;
651                   break;
652                }
653          }
654          /* if no children are visible, unfullscreen */
655          if ((!e_object_is_del(E_OBJECT(ec))) && (!have_vis_child))
656          e_client_unfullscreen(ec);
657       }
658
659    _e_focus_policy_history_focus_defer_unset(history_policy, ec);
660
661    // assign the focused_ec
662    set_focused_ec(history_policy, NULL);
663
664    ELOGF("FOCUS_HISTORY", "focus_set | focused_ec UNSET", ec);
665 }
666
667 static void
668 _focus_policy_history_cb_client_lower(struct wl_listener *listener, void *data)
669 {
670    E_Focus_Policy_History_Client *history_client;
671    E_Focus_Policy_History *history_policy;
672    E_Client *ec;
673
674    history_client = wl_container_of(listener, history_client, client_lower);
675
676    history_policy = history_client->history_policy;
677    EINA_SAFETY_ON_NULL_RETURN(history_policy);
678
679    ec = history_client->ec;
680    EINA_SAFETY_ON_NULL_RETURN(ec);
681
682    E_FOCUS_HISTORY_TRACE(history_policy, ec);
683
684    // no need to change the focused ec when ec is not focused.
685    if (!ec->focused) return;
686
687    // no need to change the focused ec when calc_vis_without_effect is not set.
688    if (e_config->calc_vis_without_effect) return;
689
690    // find the next focus and set it
691    _focus_policy_history_next_focus_set(history_policy, ec);
692 }
693
694 static void
695 _focus_policy_history_cb_client_move(struct wl_listener *listener, void *data)
696 {
697    E_Focus_Policy_History_Client *history_client;
698    E_Focus_Policy_History *history_policy;
699    E_Client *ec;
700    E_Zone *zone;
701
702    history_client = wl_container_of(listener, history_client, client_move);
703
704    history_policy = history_client->history_policy;
705    EINA_SAFETY_ON_NULL_RETURN(history_policy);
706
707    ec = history_client->ec;
708    EINA_SAFETY_ON_NULL_RETURN(ec);
709
710    E_FOCUS_HISTORY_TRACE(history_policy, ec);
711
712    zone = e_comp_zone_find_by_ec(ec);
713    if (!zone) return;
714
715    // no need to change the focused ec when ec is not focused.
716    if (!ec->focused) return;
717
718    // no need to change the focused ec when ec is in the area of a zone.
719    if (!E_INTERSECTS(ec->x, ec->y, ec->w, ec->h,
720                     zone->x, zone->y, zone->w, zone->h))
721      {
722         // find the next focus and set it
723         _focus_policy_history_next_focus_set(history_policy, ec);
724      }
725 }
726
727 static void
728 _focus_policy_history_cb_client_focus_defer_set(struct wl_listener *listener, void *data)
729 {
730    E_Focus_Policy_History_Client *history_client;
731    E_Focus_Policy_History *history_policy;
732    E_Client *ec;
733
734    history_client = wl_container_of(listener, history_client, client_focus_defer_set);
735
736    history_policy = history_client->history_policy;
737    EINA_SAFETY_ON_NULL_RETURN(history_policy);
738
739    ec = history_client->ec;
740    EINA_SAFETY_ON_NULL_RETURN(ec);
741
742    E_FOCUS_HISTORY_TRACE(history_policy, ec);
743
744    ELOGF("FOCUS_HISTORY", "focus defer set callback. e_client_focus_defer_set is called.", ec);
745
746    _e_focus_policy_history_focus_focus_defer_set(history_policy, ec);
747 }
748
749 static void
750 _focus_policy_history_cb_client_focus_latest_set(struct wl_listener *listener, void *data)
751 {
752    E_Focus_Policy_History_Client *history_client;
753    E_Focus_Policy_History *history_policy;
754    E_Client *ec;
755
756    history_client = wl_container_of(listener, history_client, client_focus_latest_set);
757
758    history_policy = history_client->history_policy;
759    EINA_SAFETY_ON_NULL_RETURN(history_policy);
760
761    ec = history_client->ec;
762    EINA_SAFETY_ON_NULL_RETURN(ec);
763
764    E_FOCUS_HISTORY_TRACE(history_policy, ec);
765
766    //ELOGF("FOCUS_HISTORY", "focus latest set", ec);
767
768    _focus_policy_history_focus_stack_latest_set(history_policy, ec);
769 }
770
771 static void
772 _focus_policy_history_cb_client_activate_done(struct wl_listener *listener, void *data)
773 {
774    E_Focus_Policy_History_Client *history_client;
775    E_Focus_Policy_History *history_policy;
776    E_Client *ec;
777    E_Client *focus_ec = NULL;
778    E_Client *obscured_above = NULL;
779
780    history_client = wl_container_of(listener, history_client, client_activate_done);
781
782    history_policy = history_client->history_policy;
783    EINA_SAFETY_ON_NULL_RETURN(history_policy);
784
785    ec = history_client->ec;
786    EINA_SAFETY_ON_NULL_RETURN(ec);
787
788    E_FOCUS_HISTORY_TRACE(history_policy, ec);
789
790    if (ec->lock_focus_out) return;
791
792    if (ec->transients)
793      focus_ec = e_client_transient_child_top_get(ec, EINA_TRUE);
794
795    if (!focus_ec)
796      focus_ec = ec;
797    else
798      {
799         _focus_policy_history_focus_stack_latest_set(history_policy, ec);
800         _focus_policy_history_focus_stack_latest_set(history_policy, focus_ec);
801         _e_focus_policy_history_focus_defer_unset(history_policy, ec);
802      }
803
804     obscured_above = e_client_check_fully_contain_by_above(focus_ec, EINA_FALSE);
805     if (!obscured_above)
806       {
807          if (!e_policy_visibility_client_is_uniconic(ec) ||
808              (ec->visibility.obscured == E_VISIBILITY_FULLY_OBSCURED))
809            {
810               _e_focus_policy_history_focus_focus_defer_set(history_policy, focus_ec);
811               _focus_policy_history_focus_stack_latest_set(history_policy, focus_ec);
812            }
813          else
814            {
815               ELOGF("FOCUS_HISTORY", "focus set   | client activate", focus_ec);
816               e_client_frame_focus_set(focus_ec, EINA_TRUE);
817            }
818       }
819     else
820       {
821          _e_focus_policy_history_focus_focus_defer_set(history_policy, focus_ec);
822          _focus_policy_history_focus_stack_latest_set(history_policy, focus_ec);
823       }
824 }
825
826 static void
827 _focus_policy_history_cb_client_eval_end(struct wl_listener *listener, void *data)
828 {
829    E_Focus_Policy_History_Client *history_client;
830    E_Focus_Policy_History *history_policy;
831    E_Client *focused_ec, *ec;
832    E_Zone *zone;
833
834    history_client = wl_container_of(listener, history_client, client_eval_end);
835
836    history_policy = history_client->history_policy;
837    EINA_SAFETY_ON_NULL_RETURN(history_policy);
838
839    ec = history_client->ec;
840    EINA_SAFETY_ON_NULL_RETURN(ec);
841
842    E_FOCUS_HISTORY_TRACE(history_policy, ec);
843
844    zone = history_policy->zone;
845    focused_ec = history_policy->focused_ec;
846
847    if ((!ec->input_only) && (!ec->iconic) &&
848        (e_desk_has_ec(e_desk_current_get(zone), ec)) &&
849        ((ec->take_focus) || (ec->want_focus)))
850      {
851         ec->take_focus = 0;
852         if (ec->want_focus)
853           {
854              ec->want_focus = 0;
855           }
856         else
857           {
858              /* focus window by default when it is the only one on desk */
859              E_Client *ec2 = NULL;
860              Eina_List *l;
861              E_Desk *desk;
862              desk = e_zone_desk_find_by_ec(zone, ec);
863              EINA_LIST_FOREACH(history_policy->focus_stack, l, ec2)
864                {
865                   if (ec == ec2) continue;
866                   if ((!ec2->iconic) && (ec2->visible) &&
867                       ((e_desk_has_ec(desk, ec2)) || ec2->sticky))
868                     break;
869                }
870
871              if (!ec2)
872                {
873                   if ((!ec->icccm.accepts_focus) &&
874                       (!ec->icccm.take_focus))
875                     return;
876                   if (ec->lock_focus_out) return;
877                   if (ec == focused_ec) return;
878
879                   ELOGF("FOCUS_HISTORY", "focus set   | focus with pointer", ec);
880                    e_client_frame_focus_set(ec, EINA_TRUE);
881                }
882           }
883      }
884    else
885      ec->take_focus = ec->want_focus = 0;
886 }
887
888 static void
889 _focus_policy_history_cb_stack_transient_for_done(struct wl_listener *listener, void *data)
890 {
891    E_Focus_Policy_History_Client *history_client;
892    E_Focus_Policy_History *history_policy;
893    E_Client *new_focus, *ec;
894
895    history_client = wl_container_of(listener, history_client, stack_transient_for_done);
896
897    history_policy = history_client->history_policy;
898    EINA_SAFETY_ON_NULL_RETURN(history_policy);
899
900    ec = history_client->ec;
901    EINA_SAFETY_ON_NULL_RETURN(ec);
902
903    E_FOCUS_HISTORY_TRACE(history_policy, ec);
904
905    if (!ec->parent) return;
906    if (ec->parent != history_policy->focused_ec) return;
907
908    new_focus = e_client_transient_child_top_get(ec->parent, EINA_TRUE);
909    if (!new_focus) return;
910
911    ELOGF("FOCUS_HISTORY", "focus set   | tranient_for fetch", new_focus);
912
913    e_client_frame_focus_set(new_focus, EINA_TRUE);
914 }
915
916 #ifdef REFACTOR_DESK_AREA
917 static void
918 _focus_policy_history_cb_comp_object_lower_done(struct wl_listener *listener, void *data)
919 #else
920 static void
921 _focus_policy_history_cb_comp_object_lower(struct wl_listener *listener, void *data)
922 #endif
923 {
924    E_Focus_Policy_History_Client *history_client;
925    E_Focus_Policy_History *history_policy;
926    E_Client *ec;
927
928 #ifdef REFACTOR_DESK_AREA
929    history_client = wl_container_of(listener, history_client, comp_object_lower_done);
930 #else
931    history_client = wl_container_of(listener, history_client, comp_object_lower);
932 #endif
933
934    history_policy = history_client->history_policy;
935    EINA_SAFETY_ON_NULL_RETURN(history_policy);
936
937    ec = history_client->ec;
938    EINA_SAFETY_ON_NULL_RETURN(ec);
939
940    E_FOCUS_HISTORY_TRACE(history_policy, ec);
941
942    // return if post_lower of ec is set
943    if (ec->post_lower) return;
944
945    _focus_policy_history_focus_stack_lower(history_policy, ec);
946 }
947
948 static void
949 _e_focus_policy_history_focus_stack_append_current_focused(E_Focus_Policy_History *history_policy, E_Client *ec)
950 {
951    Eina_List *l = NULL;
952    E_Client *focused_ec, *temp_ec = NULL;
953
954    focused_ec = history_policy->focused_ec;
955    history_policy->focus_stack = eina_list_remove(history_policy->focus_stack, ec);
956
957    EINA_LIST_FOREACH(history_policy->focus_stack, l, temp_ec)
958      {
959         if (temp_ec != focused_ec) continue;
960
961         history_policy->focus_stack = eina_list_append_relative_list(history_policy->focus_stack, ec, l);
962         return;
963      }
964
965    history_policy->focus_stack = eina_list_prepend(history_policy->focus_stack, ec);
966 }
967
968 static void
969 _focus_policy_history_cb_comp_object_show(struct wl_listener *listener, void *data)
970 {
971    E_Focus_Policy_History_Client *history_client;
972    E_Focus_Policy_History *history_policy;
973    E_Client *ec;
974
975    history_client = wl_container_of(listener, history_client, comp_object_show);
976
977    history_policy = history_client->history_policy;
978    EINA_SAFETY_ON_NULL_RETURN(history_policy);
979
980    ec = history_client->ec;
981    EINA_SAFETY_ON_NULL_RETURN(ec);
982
983    E_FOCUS_HISTORY_TRACE(history_policy, ec);
984
985    if (!e_client_is_iconified_by_client(ec)||
986        e_policy_visibility_client_is_uniconic(ec))
987     {
988        if (!ec->iconic ||
989            e_policy_visibility_client_is_uniconic(ec))
990          {
991             if (ec->exp_iconify.not_raise &&
992                 e_client_check_above_focused(ec))
993               _e_focus_policy_history_focus_stack_append_current_focused(history_policy, ec);
994             else
995               _e_focus_policy_history_focus_focus_defer_set(history_policy, ec);
996          }
997     }
998 }
999
1000 static void
1001 _focus_policy_history_cb_comp_object_hide(struct wl_listener *listener, void *data)
1002 {
1003    E_Focus_Policy_History_Client *history_client;
1004    E_Focus_Policy_History *history_policy;
1005    E_Client *ec;
1006
1007    history_client = wl_container_of(listener, history_client, comp_object_hide);
1008
1009    history_policy = history_client->history_policy;
1010    EINA_SAFETY_ON_NULL_RETURN(history_policy);
1011
1012    ec = history_client->ec;
1013    EINA_SAFETY_ON_NULL_RETURN(ec);
1014
1015    E_FOCUS_HISTORY_TRACE(history_policy, ec);
1016
1017    if (ec->focused)
1018      {
1019         /* ensure focus-out */
1020         ELOGF("FOCUS_HISTORY", "focus unset | comp_object_hide ", ec);
1021         e_client_frame_focus_set(ec, EINA_FALSE);
1022         _e_focus_policy_history_focus_defer_unset(history_policy, ec);
1023      }
1024 }
1025
1026 static void
1027 _focus_policy_history_cb_zone_client_add(struct wl_listener *listener, void *data)
1028 {
1029    E_Focus_Policy_History *history_policy;
1030    E_Focus_Policy_History_Client *history_client;
1031    E_Client *ec;
1032    Evas_Object *obj;
1033
1034    history_policy = wl_container_of(listener, history_policy, zone_client_add);
1035
1036    ec = (E_Client *)data;
1037    EINA_SAFETY_ON_NULL_RETURN(ec);
1038
1039    E_FOCUS_HISTORY_TRACE(history_policy, ec);
1040
1041    obj = ec->frame;
1042    EINA_SAFETY_ON_NULL_RETURN(obj);
1043
1044    history_client = E_NEW(E_Focus_Policy_History_Client, 1);
1045    EINA_SAFETY_ON_NULL_RETURN(history_client);
1046
1047    history_client->ec = ec;
1048    history_client->history_policy = history_policy;
1049
1050    // e_client listeners
1051    history_client->client_destroy.notify = _focus_policy_history_cb_client_destroy;
1052    e_client_destroy_listener_add(ec, &history_client->client_destroy);
1053    history_client->client_mouse_in.notify = _focus_policy_history_cb_client_mouse_in;
1054    e_client_mouse_in_listener_add(ec, &history_client->client_mouse_in);
1055    history_client->client_mouse_out.notify = _focus_policy_history_cb_client_mouse_out;
1056    e_client_mouse_out_listener_add(ec, &history_client->client_mouse_out);
1057    history_client->client_mouse_down.notify = _focus_policy_history_cb_client_mouse_down;
1058    e_client_mouse_down_listener_add(ec, &history_client->client_mouse_down);
1059    history_client->client_focus_set.notify = _focus_policy_history_cb_client_focus_set;
1060    e_client_focus_set_listener_add(ec, &history_client->client_focus_set);
1061    history_client->client_focus_unset.notify = _focus_policy_history_cb_client_focus_unset;
1062    e_client_focus_unset_listener_add(ec, &history_client->client_focus_unset);
1063    history_client->client_lower.notify = _focus_policy_history_cb_client_lower;
1064    e_client_lower_listener_add(ec, &history_client->client_lower);
1065    history_client->client_move.notify = _focus_policy_history_cb_client_move;
1066    e_client_move_listener_add(ec, &history_client->client_move);
1067    history_client->client_focus_defer_set.notify = _focus_policy_history_cb_client_focus_defer_set;
1068    e_client_focus_defer_set_listener_add(ec, &history_client->client_focus_defer_set);
1069    history_client->client_focus_latest_set.notify = _focus_policy_history_cb_client_focus_latest_set;
1070    e_client_focus_latest_set_listener_add(ec, &history_client->client_focus_latest_set);
1071    history_client->client_activate_done.notify = _focus_policy_history_cb_client_activate_done;
1072    e_client_activate_done_listener_add(ec, &history_client->client_activate_done);
1073    history_client->client_eval_end.notify = _focus_policy_history_cb_client_eval_end;
1074    e_client_eval_end_listener_add(ec, &history_client->client_eval_end);
1075    history_client->stack_transient_for_done.notify = _focus_policy_history_cb_stack_transient_for_done;
1076    e_client_stack_transient_for_done_listener_add(ec, &history_client->stack_transient_for_done);
1077
1078    // e_comp_object listeners
1079 #ifdef REFACTOR_DESK_AREA
1080    history_client->comp_object_lower_done.notify = _focus_policy_history_cb_comp_object_lower_done;
1081    e_comp_object_lower_done_listener_add(obj, &history_client->comp_object_lower_done);
1082 #else
1083    history_client->comp_object_lower.notify = _focus_policy_history_cb_comp_object_lower;
1084    e_comp_object_lower_listener_add(obj, &history_client->comp_object_lower);
1085 #endif
1086    history_client->comp_object_show.notify = _focus_policy_history_cb_comp_object_show;
1087    e_comp_object_show_listener_add(obj, &history_client->comp_object_show);
1088    history_client->comp_object_hide.notify = _focus_policy_history_cb_comp_object_hide;
1089    e_comp_object_hide_listener_add(obj, &history_client->comp_object_hide);
1090
1091    ELOGF("FOCUS_HISTORY", "zone_client_add | ", ec);
1092 }
1093
1094 static void
1095 _focus_policy_history_cb_zone_client_remove(struct wl_listener *listener, void *data)
1096 {
1097    E_Focus_Policy_History *history_policy;
1098    E_Client *ec;
1099
1100    history_policy = wl_container_of(listener, history_policy, zone_client_remove);
1101
1102    ec = (E_Client *)data;
1103    EINA_SAFETY_ON_NULL_RETURN(ec);
1104
1105    E_FOCUS_HISTORY_TRACE(history_policy, ec);
1106
1107    ELOGF("FOCUS_HISTORY", "zone_client_remove | ", ec);
1108
1109    // remove ec from focus stack and defer_focus_stack
1110    history_policy->focus_stack = eina_list_remove(history_policy->focus_stack, ec);
1111    _e_focus_policy_history_focus_defer_unset(history_policy, ec);
1112
1113    // find the next focus and set it when ec is focused.
1114    if (ec->focused)
1115      {
1116         _focus_policy_history_next_focus_set(history_policy, ec);
1117
1118         // check the critical case
1119         if (history_policy->focused_ec == ec)
1120           {
1121              ELOGF("FOCUS_HISTORY", "CRITICAL. focused is deleted ec.", ec);
1122              ELOGF("FOCUS_HISTORY", "CLIENT FOCUS_SET", NULL);
1123              set_focused_ec(history_policy, NULL);
1124          }
1125      }
1126 }
1127
1128 static void
1129 _focus_policy_history_cb_zone_focus_clear(struct wl_listener *listener, void *data)
1130 {
1131    E_Focus_Policy_History *history_policy;
1132    E_Zone *zone;
1133
1134    history_policy = wl_container_of(listener, history_policy, zone_focus_clear);
1135
1136    E_FOCUS_HISTORY_TRACE(history_policy, NULL);
1137
1138    zone = history_policy->zone;
1139    EINA_SAFETY_ON_NULL_RETURN(zone);
1140
1141    // make focused_ec be NULL
1142    set_focused_ec(history_policy, NULL);
1143
1144    ELOGF("FOCUS_HISTORY", "focus_clear | focused_ec UNSET", NULL);
1145 }
1146
1147 static void
1148 _focus_policy_history_cb_zone_focus_reset(struct wl_listener *listener, void *data)
1149 {
1150    E_Focus_Policy_History *history_policy;
1151    E_Zone *zone;
1152    E_Desk *desk;
1153    E_Client *ec;
1154    const Eina_List *l;
1155
1156    history_policy = wl_container_of(listener, history_policy, zone_focus_reset);
1157
1158    E_FOCUS_HISTORY_TRACE(history_policy, NULL);
1159
1160    zone = history_policy->zone;
1161    EINA_SAFETY_ON_NULL_RETURN(zone);
1162
1163   if (e_config->focus_policy == E_FOCUS_MOUSE) return;
1164
1165    EINA_LIST_FOREACH(history_policy->focus_stack, l, ec)
1166      {
1167         desk = e_zone_desk_find_by_ec(zone, ec);
1168         if (!desk) continue;
1169         if (desk->visible && (!ec->iconic))
1170           {
1171              if (e_comp->input_key_grabs || e_comp->input_mouse_grabs)
1172                {
1173                   break;
1174                }
1175
1176              ELOGF("FOCUS_HISTORY", "focus set   | refocus", ec);
1177              e_client_frame_focus_set(ec, EINA_TRUE);
1178              break;
1179           }
1180      }
1181 }
1182
1183 static void
1184 _focus_policy_history_del(E_Focus_Policy_Impl *impl)
1185 {
1186    E_Focus_Policy_History *history_policy = (E_Focus_Policy_History *)impl;
1187
1188    if (!history_policy) return;
1189
1190    E_FOCUS_HISTORY_TRACE(history_policy, NULL);
1191
1192    ELOGF("FOCUS_HISTORY", "delete history focus policy.", NULL);
1193
1194    if (history_policy->defer_focus_stack)
1195      history_policy->defer_focus_stack = eina_list_free(history_policy->defer_focus_stack);
1196
1197    wl_list_remove(&history_policy->zone_focus_reset.link);
1198    wl_list_remove(&history_policy->zone_focus_clear.link);
1199    wl_list_remove(&history_policy->zone_client_remove.link);
1200    wl_list_remove(&history_policy->zone_client_add.link);
1201
1202    E_FREE(history_policy);
1203 }
1204
1205 static E_Client *
1206 _focus_policy_history_focused_ec_get(E_Focus_Policy_Impl *impl)
1207 {
1208    E_Focus_Policy_History *history_policy;
1209    E_Client *focused_ec = NULL;
1210
1211    history_policy = (E_Focus_Policy_History *)impl;
1212    EINA_SAFETY_ON_NULL_RETURN_VAL(history_policy, NULL);
1213
1214    //E_FOCUS_HISTORY_TRACE(history_policy, NULL);
1215    focused_ec = atomic_load(&history_policy->focused_ec);
1216
1217    return focused_ec;
1218 }
1219
1220 static Eina_Bool
1221 _focus_policy_history_update(E_Focus_Policy_Impl *impl)
1222 {
1223    E_Focus_Policy_History *history_policy;
1224    E_Zone *zone;
1225    E_Client *defered_focus_ec, *reverted_focus_ec = NULL;
1226    E_Client *focused_ec, *old_focused_ec = NULL;
1227
1228    history_policy = (E_Focus_Policy_History *)impl;
1229    EINA_SAFETY_ON_NULL_RETURN_VAL(history_policy, EINA_FALSE);
1230
1231    zone = history_policy->zone;
1232    EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
1233
1234    //E_FOCUS_HISTORY_TRACE(history_policy, NULL);
1235
1236    // no need to update the focused ec when zone is not displaying
1237    if (!e_zone_is_displaying(zone)) return EINA_FALSE;
1238
1239    // current focused ec
1240    focused_ec = history_policy->focused_ec;
1241
1242    if ((!focused_ec) ||
1243        (focused_ec != eina_list_data_get(history_policy->focus_stack)) ||
1244        (!_e_focus_policy_history_focus_can_take(history_policy, focused_ec)))
1245      {
1246         reverted_focus_ec = _focus_policy_history_focusable_get(history_policy, focused_ec);
1247         if (!reverted_focus_ec && focused_ec)
1248           {
1249              _e_focus_policy_history_focus_defer_unset(history_policy, focused_ec);
1250              old_focused_ec = focused_ec;
1251           }
1252      }
1253
1254    defered_focus_ec = _e_focus_policy_history_candidate_focus_get(history_policy, reverted_focus_ec);
1255
1256    if (defered_focus_ec)
1257      {
1258         if (defered_focus_ec != focused_ec)
1259           {
1260              ELOGF("FOCUS_HISTORY", "focus set   | focus calculate (defer_focus) Zone(%d)", defered_focus_ec, zone->id);
1261              if (focused_ec)
1262                _e_focus_policy_history_focus_defer_unset(history_policy, focused_ec);
1263              e_client_frame_focus_set(defered_focus_ec, EINA_TRUE);
1264           }
1265
1266         _e_focus_policy_history_focus_defer_unset(history_policy, defered_focus_ec);
1267
1268         _e_focus_policy_history_merge_focus_stack_with_defer_focus(history_policy);
1269      }
1270    else if(reverted_focus_ec)
1271      {
1272         if (reverted_focus_ec != focused_ec)
1273           {
1274              ELOGF("FOCUS_HISTORY", "focus set   | focus calculate (revert_focus) Zone(%d)", reverted_focus_ec, zone->id);
1275              if (focused_ec)
1276                _e_focus_policy_history_focus_defer_unset(history_policy, focused_ec);
1277              e_client_frame_focus_set(reverted_focus_ec, EINA_TRUE);
1278           }
1279      }
1280    else if (old_focused_ec)
1281      {
1282         ELOGF("FOCUS_HISTORY", "focus unset | focus calculate Zone(%d)", old_focused_ec, zone->id);
1283         e_client_frame_focus_set(old_focused_ec, EINA_FALSE);
1284      }
1285
1286    return EINA_TRUE;
1287 }
1288
1289 EINTERN E_Focus_Policy_Iface *
1290 e_focus_policy_iface_history_new(E_Zone* zone)
1291 {
1292    E_Focus_Policy_Iface *policy_iface;
1293    E_Focus_Policy_History *history_policy;
1294
1295    EINA_SAFETY_ON_NULL_RETURN_VAL(zone, NULL);
1296
1297    policy_iface = E_NEW(E_Focus_Policy_Iface, 1);
1298    EINA_SAFETY_ON_NULL_RETURN_VAL(policy_iface, NULL);
1299
1300    history_policy = E_NEW(E_Focus_Policy_History, 1);
1301    EINA_SAFETY_ON_NULL_GOTO(history_policy, fail);
1302
1303    history_policy->zone = zone;
1304
1305    E_FOCUS_HISTORY_TRACE(history_policy, NULL);
1306
1307    policy_iface->impl = (E_Focus_Policy_Impl *)history_policy;
1308    policy_iface->del = _focus_policy_history_del;
1309    policy_iface->focused_ec_get = _focus_policy_history_focused_ec_get;
1310    policy_iface->update = _focus_policy_history_update;
1311
1312    // zone listeners
1313    history_policy->zone_client_add.notify = _focus_policy_history_cb_zone_client_add;
1314    e_zone_client_add_listener_add(zone, &history_policy->zone_client_add);
1315    history_policy->zone_client_remove.notify = _focus_policy_history_cb_zone_client_remove;
1316    e_zone_client_remove_listener_add(zone, &history_policy->zone_client_remove);
1317    history_policy->zone_focus_clear.notify = _focus_policy_history_cb_zone_focus_clear;
1318    e_zone_focus_clear_listener_add(zone, &history_policy->zone_focus_clear);
1319    history_policy->zone_focus_reset.notify = _focus_policy_history_cb_zone_focus_reset;
1320    e_zone_focus_reset_listener_add(zone, &history_policy->zone_focus_reset);
1321
1322    return policy_iface;
1323
1324 fail:
1325    _focus_policy_history_del(history_policy);
1326
1327    E_FREE(policy_iface);
1328
1329    return NULL;
1330 }
1331