Added a policy to support such as quickpanel to rotate based Window manager. 56/9756/2
authorSeunghun Lee <shiin.lee@samsung.com>
Fri, 31 May 2013 10:24:05 +0000 (19:24 +0900)
committerMun, Gwan-gyeong <kk.moon@samsung.com>
Wed, 5 Jun 2013 07:19:39 +0000 (16:19 +0900)
Change-Id: If5d340fe94d7f6c9867b0dbc1de99fd2221671e0

illume2-tizen/src/e_illume.h
illume2-tizen/src/e_mod_policy.c
illume2-tizen/src/policies/illume/illume.c
illume2-tizen/src/policies/illume/policy.c
illume2-tizen/src/policies/illume/policy.h
move-tizen/src/e_mod_move_indicator_widget.c
move-tizen/src/e_mod_move_mini_apptray_widget.c

index eae03c6..b3d707e 100644 (file)
@@ -225,6 +225,8 @@ struct _E_Illume_Policy
         void (*idle_enterer) (void);
 
         void (*illume_win_state_change_request) (Ecore_X_Event_Client_Message *event);
+
+        void (*rotation_list_add) (E_Border *bd);
      } funcs;
 };
 
index 42a633a..ffccc32 100644 (file)
@@ -32,6 +32,7 @@ static void _e_mod_policy_cb_hook_new_border(void *data __UNUSED__, void *data2)
 #ifdef _F_BORDER_HOOK_PATCH_
 static void _e_mod_policy_cb_hook_del_border(void *data __UNUSED__, void *data2);
 #endif
+static void _e_mod_policy_cb_hook_rotation_list_add(void *data __UNUSED__, void *data2);
 
 static Eina_Bool _e_mod_policy_cb_window_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event);
 
@@ -468,6 +469,10 @@ _e_mod_policy_hooks_add(void)
                       e_border_hook_add(E_BORDER_HOOK_DEL_BORDER,
                                         _e_mod_policy_cb_hook_del_border, NULL));
 #endif
+   _policy_hooks =
+     eina_list_append(_policy_hooks,
+                      e_border_hook_add(E_BORDER_HOOK_ROTATION_LIST_ADD,
+                                        _e_mod_policy_cb_hook_rotation_list_add, NULL));
 }
 
 static void
@@ -1121,3 +1126,13 @@ _e_mod_policy_cb_idle_enterer(void *data __UNUSED__)
 
    return ECORE_CALLBACK_RENEW;
 }
+
+static void
+_e_mod_policy_cb_hook_rotation_list_add(void *data __UNUSED__, void *data2)
+{
+   E_Border *bd;
+
+   if (!(bd = data2)) return;
+   if ((_policy) && (_policy->funcs.rotation_list_add))
+     _policy->funcs.rotation_list_add(bd);
+}
index 21d33bc..e518200 100644 (file)
@@ -71,6 +71,8 @@ e_illume_policy_init(E_Illume_Policy *p)
 
    p->funcs.illume_win_state_change_request = _policy_illume_win_state_change_request;
 
+   p->funcs.rotation_list_add = _policy_border_hook_rotation_list_add;
+
    if (!_policy_init())
      return 0;
 
@@ -138,6 +140,8 @@ e_illume_policy_shutdown(E_Illume_Policy *p)
 
    p->funcs.illume_win_state_change_request = NULL;
 
+   p->funcs.rotation_list_add = NULL;
+
    _policy_fin();
    return 1;
 }
index 75cf22d..929d41b 100644 (file)
@@ -94,6 +94,8 @@ static void _policy_property_notification_level_change (Ecore_X_Event_Window_Pro
 static void _policy_property_overlay_win_change (Ecore_X_Event_Window_Property *event);
 static void _policy_property_window_opaque_change (Ecore_X_Event_Window_Property *event);
 static void _policy_property_illume_window_state_change(Ecore_X_Event_Window_Property *event);
+static void _policy_property_indicator_cmd_win_change(Ecore_X_Event_Window_Property *event);
+static void _policy_property_active_indicator_win_change(Ecore_X_Event_Window_Property *event);
 
 static void _policy_border_illume_window_state_change(E_Border *bd, unsigned int state);
 
@@ -136,6 +138,8 @@ static void _policy_zone_layout_app_single_monitor(E_Illume_Border_Info *bd_info
 /* for controling indicator */
 static void _policy_border_indicator_control(E_Border *indi_bd);
 static Eina_Bool _policy_border_indicator_state_change(E_Border *indi_bd, E_Border *bd);
+static Ecore_X_Window _policy_indicator_cmd_win_get(Ecore_X_Window win);
+static Ecore_X_Window _policy_active_indicator_win_get(Ecore_X_Window win);
 
 static void _policy_resize_start(E_Illume_Border_Info *bd_info);
 static void _policy_resize_end(E_Illume_Border_Info *bd_info);
@@ -157,6 +161,10 @@ static E_Border* _policy_border_find_below(E_Border *bd);
 static void _policy_border_uniconify_below_borders(E_Border *bd);
 static void _policy_border_uniconify_top_border(E_Border *bd);
 
+/* for supporting rotation */
+static void       _policy_border_dependent_rotation(E_Border *bd);
+static Eina_List* _policy_dependent_rotation_list_make(E_Border *bd);
+
 /*******************/
 /* local variables */
 /*******************/
@@ -197,6 +205,10 @@ static Ecore_X_Window g_indi_control_win;
 static Ecore_X_Atom E_ILLUME_ATOM_COMP_MODULE_ENABLED;
 #endif
 
+/* for supporting rotation */
+static Ecore_X_Atom E_INDICATOR_CMD_WIN;
+static Ecore_X_Atom E_ACTIVE_INDICATOR_WIN;
+
 #if 1 // for visibility
 static Eina_Hash* _e_illume_xwin_info_hash = NULL;
 static Eina_Inlist* _e_illume_xwin_info_list = NULL;
@@ -210,6 +222,31 @@ static E_Msg_Handler *_e_illume_msg_handler = NULL;
 static Eina_Bool _e_use_comp = EINA_FALSE;
 static Eina_Bool _g_visibility_changed = EINA_FALSE;
 
+/* for supporing rotation */
+typedef struct _E_Policy_Rotation_Dependent  E_Policy_Rotation_Dependent;
+
+struct _E_Policy_Rotation_Dependent
+{
+   Eina_List *list;
+   Ecore_X_Window root;
+
+   struct
+     {
+        Ecore_X_Window cmd_win;
+        Ecore_X_Window active_win;
+     } refer;
+
+   int ang;
+};
+
+static E_Policy_Rotation_Dependent dep_rot =
+{
+   NULL,
+   NULL,
+   {NULL, NULL},
+   -1
+};
+
 /* local functions */
 static void
 _policy_border_set_focus(E_Border *bd)
@@ -877,6 +914,11 @@ _policy_border_del(E_Border *bd)
              e_illume_util_mem_trim();
           }
      }
+
+   // for supporting rotation such as quickpanel
+   if (e_illume_border_is_quickpanel(bd) ||
+       e_illume_border_is_miniapp_tray(bd))
+     dep_rot.list = eina_list_remove(dep_rot.list, bd);
 }
 
 void
@@ -973,6 +1015,17 @@ _policy_border_post_fetch(E_Border *bd)
      }
 #endif
 
+   // for supporting rotation such as quickpanel
+   if (e_illume_border_is_quickpanel(bd) ||
+       e_illume_border_is_miniapp_tray(bd))
+     {
+        bd->client.e.state.rot.type = E_BORDER_ROTATION_TYPE_DEPENDENT;
+        if (eina_list_data_find(dep_rot.list, bd) != bd)
+          {
+             dep_rot.list = eina_list_append(dep_rot.list, bd);
+          }
+     }
+
    /* tell E the border has changed */
    bd->client.border.changed = 1;
 }
@@ -2873,6 +2926,14 @@ _policy_property_change(Ecore_X_Event_Window_Property *event)
         _policy_property_composite_module_change (event);
      }
 #endif
+   else if (event->atom == E_INDICATOR_CMD_WIN)
+     {
+        _policy_property_indicator_cmd_win_change(event);
+     }
+   else if (event->atom == E_ACTIVE_INDICATOR_WIN)
+     {
+        _policy_property_active_indicator_win_change(event);
+     }
 }
 
 
@@ -3314,6 +3375,20 @@ int _policy_atom_init (void)
      }
 #endif
 
+   E_INDICATOR_CMD_WIN = ecore_x_atom_get("_E_INDICATOR_CMD_WIN");
+   if (!E_INDICATOR_CMD_WIN)
+     {
+        fprintf (stderr, "[ILLUME2] Critical Error!!! Cannot create _E_INDICATOR_CMD_WIN Atom...\n");
+        return 0;
+     }
+
+   E_ACTIVE_INDICATOR_WIN = ecore_x_atom_get("_E_ACTIVE_INDICATOR_WIN");
+   if (!E_ACTIVE_INDICATOR_WIN)
+     {
+        fprintf (stderr, "[ILLUME2] Critical Error!!! Cannot create _E_ACTIVE_INDICATOR_WIN Atom...\n");
+        return 0;
+     }
+
    return 1;
 }
 
@@ -3328,6 +3403,11 @@ int _policy_init (void)
    EINA_LIST_FOREACH(e_manager_list(), ml, man)
      {
         _policy_manage_xwins (man);
+
+        dep_rot.root = man->root;
+        dep_rot.refer.cmd_win = _policy_indicator_cmd_win_get(dep_rot.root);
+        if (dep_rot.refer.cmd_win)
+          dep_rot.refer.active_win = _policy_active_indicator_win_get(dep_rot.refer.cmd_win);
      }
 
    // initialize atom
@@ -6102,6 +6182,134 @@ fin:
    return;
 }
 
+/* for supporting rotation */
+void
+_policy_border_hook_rotation_list_add(E_Border *bd)
+{
+   Eina_List *list = NULL;
+   int prev_ang = dep_rot.ang;
+
+   if (!bd) return;
+
+   list = _policy_dependent_rotation_list_make(bd);
+   if (list)
+     {
+        dep_rot.ang = bd->client.e.state.rot.curr;
+        ELBF(ELBT_ROT, 0, bd->client.win,
+             "ADD ROT_LIST(dependent) curr:%d != prev:%d", dep_rot.ang, prev_ang);
+        e_border_rotation_list_add(list);
+        eina_list_free(list);
+     }
+}
+
+static void
+_policy_border_dependent_rotation(E_Border *bd)
+{
+   Eina_List *list = NULL;
+   E_Zone *zone = bd->zone;
+   int prev_ang = dep_rot.ang;
+
+   list = _policy_dependent_rotation_list_make(bd);
+   if (list)
+     {
+        dep_rot.ang = bd->client.e.state.rot.curr;
+        ELBF(ELBT_ROT, 0, bd->client.win,
+             "ADD & REQUEST ROT(dependent) curr:%d != prev:%d", dep_rot.ang, prev_ang);
+        e_border_rotation_list_add_change_req(zone, list);
+        eina_list_free(list);
+     }
+}
+
+static Eina_List*
+_policy_dependent_rotation_list_make(E_Border *bd)
+{
+   Eina_List *nl = NULL, *l;
+   E_Border *dep_bd = NULL;
+   int ang;
+
+   if (!bd) return NULL;
+   if (dep_rot.refer.active_win != bd->client.win) return NULL;
+   if (dep_rot.ang == bd->client.e.state.rot.curr) return NULL;
+   if (eina_list_data_find(dep_rot.list, bd) == bd) return NULL;
+
+   ang = bd->client.e.state.rot.curr;
+   EINA_LIST_FOREACH(dep_rot.list, l, dep_bd)
+     {
+        dep_bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
+        dep_bd->client.e.state.rot.curr = ang;
+        dep_bd->client.e.state.rot.wait_for_done = 1;
+        nl = eina_list_append(nl, dep_bd);
+     }
+
+   return nl;
+}
+
+static void
+_policy_property_indicator_cmd_win_change(Ecore_X_Event_Window_Property *event)
+{
+   Ecore_X_Window cmd_win;
+
+   cmd_win = _policy_indicator_cmd_win_get(event->win);
+   if (dep_rot.refer.cmd_win != cmd_win)
+     dep_rot.refer.cmd_win = cmd_win;
+}
+
+static void
+_policy_property_active_indicator_win_change(Ecore_X_Event_Window_Property *event)
+{
+   Ecore_X_Window active_win;
+   E_Border *bd;
+
+   active_win = _policy_active_indicator_win_get(event->win);
+   if (dep_rot.refer.active_win != active_win)
+     {
+        dep_rot.refer.active_win = active_win;
+
+        bd = e_border_find_by_client_window(active_win);
+        _policy_border_dependent_rotation(bd);
+     }
+}
+
+static Ecore_X_Window
+_policy_indicator_cmd_win_get(Ecore_X_Window win)
+{
+   Ecore_X_Window cmd_win = NULL;
+   unsigned char* prop_data = NULL;
+   int ret = 0, count = 0;
+
+   if (win != dep_rot.root) return NULL;
+
+   ret = ecore_x_window_prop_property_get(win, E_INDICATOR_CMD_WIN,
+                                          ECORE_X_ATOM_WINDOW, 32,
+                                          &prop_data, &count);
+   if (ret)
+     memcpy (&cmd_win, prop_data, sizeof(ECORE_X_ATOM_WINDOW));
+
+   if (prop_data) free(prop_data);
+
+   return cmd_win;
+}
+
+static Ecore_X_Window
+_policy_active_indicator_win_get(Ecore_X_Window win)
+{
+   Ecore_X_Window active_win = NULL;
+   unsigned char* prop_data = NULL;
+   int ret = 0, count = 0;
+
+   if (win != dep_rot.refer.cmd_win) return NULL;
+
+   ret = ecore_x_window_prop_property_get(win, E_ACTIVE_INDICATOR_WIN,
+                                          ECORE_X_ATOM_WINDOW, 32,
+                                          &prop_data, &count);
+   if (ret)
+     memcpy (&active_win, prop_data, sizeof(ECORE_X_ATOM_WINDOW));
+
+   if (prop_data) free(prop_data);
+
+   return active_win;
+}
+
 void
 _policy_idle_enterer(void)
 {
index 2ebab83..de73c06 100644 (file)
@@ -161,4 +161,6 @@ void _policy_module_update(E_Event_Module_Update *event);
 void _policy_idle_enterer(void);
 
 void _policy_illume_win_state_change_request(Ecore_X_Event_Client_Message *event);
+
+void _policy_border_hook_rotation_list_add(E_Border *bd);
 #endif
index 87f32e8..84ce70f 100644 (file)
@@ -107,6 +107,14 @@ _e_mod_move_indicator_widget_cb_motion_start_internal_quickpanel_check(E_Move_Bo
    E_CHECK_RETURN(e_mod_move_util_compositor_object_visible_get(qp_mb),
                   EINA_FALSE);
 
+   // Quickpanel is under rotation state.
+   // I think there is another exception case.
+   // It's posible that WM doesn't send rotation change request yet.
+   // In this case the value of wait_for_done is zero,
+   // it means quickpanel isn't rotating for now, but going to be rotated.
+   if (qp_mb->bd)
+     if (qp_mb->bd->client.e.state.rot.wait_for_done) return EINA_FALSE;
+
    if (e_mod_move_quickpanel_objs_animation_state_get(qp_mb)) return EINA_FALSE;
 
    if (!(qp_mb->m->qp_scroll_with_clipping))
index f6f7acf..b6804aa 100644 (file)
@@ -47,6 +47,14 @@ _e_mod_move_mini_apptray_widget_cb_motion_start_internal_mini_apptray_check(E_Mo
                   EINA_FALSE);
    if (e_mod_move_mini_apptray_objs_animation_state_get(mini_apptray_mb)) return EINA_FALSE;
 
+   // Mini app-tray is under rotation state.
+   // I think there is another exception case.
+   // It's posible that WM doesn't send rotation change request yet.
+   // In this case the value of wait_for_done is zero,
+   // it means quickpanel isn't rotating for now, but going to be rotated.
+   if (mini_apptray_mb->bd)
+     if (mini_apptray_mb->bd->client.e.state.rot.wait_for_done) return EINA_FALSE;
+
    // check if notification window is on-screen.
    EINA_INLIST_REVERSE_FOREACH(m->borders, find_mb)
      {