e_info: Add debug method to print view tree 81/322781/1
authorJunseok Kim <juns.kim@samsung.com>
Fri, 28 Mar 2025 04:40:09 +0000 (13:40 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Wed, 16 Apr 2025 00:18:49 +0000 (09:18 +0900)
Change-Id: Id3b8cf27dd887c9d8a0504609c99d21f05c606ef

src/bin/core/e_view.c
src/bin/core/e_view_intern.h
src/bin/debug/e_info_client.c
src/bin/debug/e_info_server.c
src/bin/windowmgr/e_policy_desk.c
src/bin/windowmgr/e_policy_desk_area.c
src/bin/windowmgr/e_policy_desk_area_intern.h
src/bin/windowmgr/e_policy_desk_intern.h
src/bin/windowmgr/e_policy_zone.c
src/bin/windowmgr/e_policy_zone_intern.h

index 2b798e7c9ab414f2d0f18f64e7eac1dd99d1fcb5..2d1220fc2c556a7d76bec8cc953d39d6a9f50caf 100644 (file)
@@ -35,6 +35,33 @@ _view_for_each_view(E_View *view, int lx, int ly, E_View_Iterator_Cb iterator, v
      }
 }
 
+static void
+_view_for_each_view_tree(E_View *view, int lx, int ly, E_View_Iterator_Cb iterator, void *user_data, bool reverse)
+{
+   E_View_Tree *tree;
+   E_View *child;
+
+   lx += view->x;
+   ly += view->y;
+
+   iterator(view, lx, ly, user_data);
+
+   if (view->type == E_VIEW_TYPE_TREE)
+     {
+        tree = e_view_tree_from_view(view);
+        if (!reverse)
+          {
+             wl_list_for_each(child, &tree->children, link)
+                _view_for_each_view_tree(child, lx, ly, iterator, user_data, false);
+          }
+        else
+          {
+             wl_list_for_each_reverse(child, &tree->children, link)
+                _view_for_each_view_tree(child, lx, ly, iterator, user_data, true);
+          }
+     }
+}
+
 static void
 _view_destroy(E_View *view)
 {
@@ -259,6 +286,18 @@ e_view_for_each_view_reverse(E_View *view, E_View_Iterator_Cb iterator, void *us
    _view_for_each_view(view, 0, 0, iterator, user_data, true);
 }
 
+EINTERN void
+e_view_for_each_view_tree(E_View *view, E_View_Iterator_Cb iterator, void *user_data)
+{
+   _view_for_each_view_tree(view, 0, 0, iterator, user_data, false);
+}
+
+EINTERN void
+e_view_for_each_view_tree_reverse(E_View *view, E_View_Iterator_Cb iterator, void *user_data)
+{
+   _view_for_each_view_tree(view, 0, 0, iterator, user_data, true);
+}
+
 E_API E_View *
 e_view_above_get(E_View *view)
 {
index 0811d9f6933f58f42869355644a326de4f2b9a7a..80f331cb9fdca8e941afd9a0713b7d61b5339104 100644 (file)
@@ -87,6 +87,22 @@ E_View *e_view_tree_bottom_get(E_View_Tree *tree);
 
 void e_view_destroy_listener_add(E_View *view, struct wl_listener *listener);
 
+void e_view_for_each_view_tree(E_View *view, E_View_Iterator_Cb iterator, void *user_data);
+void e_view_for_each_view_tree_reverse(E_View *view, E_View_Iterator_Cb iterator, void *user_data);
+
+inline const char *e_view_util_type_to_str(E_View_Type type)
+{
+   switch (type)
+   {
+      case E_VIEW_TYPE_TREE: return "E_VIEW_TYPE_TREE";
+      case E_VIEW_TYPE_RECT: return "E_VIEW_TYPE_RECT";
+      case E_VIEW_TYPE_IMAGE: return "E_VIEW_TYPE_IMAGE";
+      case E_VIEW_TYPE_CLIENT: return "E_VIEW_TYPE_CLIENT";
+      case E_VIEW_TYPE_EDJE: return "E_VIEW_TYPE_EDJE";
+      default: return "UNDEFINED TYPE";
+   }
+}
+
 #ifdef E_VIEW_TEST
 extern Evas_Object_Event_Cb e_view_event_callback_get(E_View_Event_Type type);
 
index e515bbeaf8a7761a38af82c5221ff0399020300d..c7b9352351e0aff15a589476f6bddaf23bc1eaf9 100644 (file)
@@ -104,6 +104,14 @@ typedef struct _E_Win_Info
    Eina_Bool    is_apply_layout;
 } E_Win_Info;
 
+typedef struct _E_View_Info
+{
+   uintptr_t ptr;
+   uintptr_t parent_ptr;
+   Eina_Stringshare *type;
+   Eina_Stringshare *impl_name;
+} E_View_Info;
+
 typedef struct output_mode_info
 {
    unsigned int hdisplay, hsync_start, hsync_end, htotal;
@@ -139,6 +147,9 @@ typedef struct _E_Fps_Info
 #define VALUE_TYPE_REQUEST_FOR_WININFO_TREE "ti"
 #define VALUE_TYPE_REPLY_WININFO_TREE "tsia(tsiiiiiiii)"
 
+#define VALUE_TYPE_REPLY_VIEW_TREE_NODE "ttss"
+#define VALUE_TYPE_REPLY_VIEW_TREE "ta("VALUE_TYPE_REPLY_VIEW_TREE_NODE")"
+
 #define PRINT_ALL_ECS -1,-1,-1
 
 static E_Info_Client e_info_client;
@@ -7235,6 +7246,114 @@ err:
    printf("%s %s\n", argv[0], argv[1]);
 }
 
+static void
+_e_info_view_tree_array_del(Eina_List *views)
+{
+   E_View_Info *view_info;
+
+   EINA_LIST_FREE(views, view_info)
+     {
+        if (view_info->type) eina_stringshare_del(view_info->type);
+        if (view_info->impl_name) eina_stringshare_del(view_info->impl_name);
+        E_FREE(view_info);
+     }
+}
+
+static Eina_List *
+_e_info_view_tree_array(Eldbus_Message_Iter *nodes)
+{
+   Eldbus_Message_Iter *node;
+   E_View_Info *view_info;
+   Eina_List *views = NULL;
+   Eina_Bool res;
+
+   while (eldbus_message_iter_get_and_next(nodes, 'r', &node))
+     {
+        uint64_t ptr, parent_ptr;
+        const char *type;
+        const char *impl_name;
+
+        view_info = E_NEW(E_View_Info, 1);
+        if (!view_info)
+          {
+             printf("Failed to alloc view info\n");
+             break;
+          }
+
+        res = eldbus_message_iter_arguments_get(node,
+                                                VALUE_TYPE_REPLY_VIEW_TREE_NODE,
+                                                &ptr,
+                                                &parent_ptr,
+                                                &type,
+                                                &impl_name);
+        if (!res)
+          {
+             printf("Failed to get view info\n");
+             E_FREE(view_info);
+             continue;
+          }
+          view_info->ptr = (uintptr_t) ptr;
+          view_info->parent_ptr = (uintptr_t) parent_ptr;
+          view_info->type = eina_stringshare_add(type);
+          view_info->impl_name = eina_stringshare_add(impl_name);
+          views = eina_list_append(views, view_info);
+     }
+
+   return views;
+}
+
+static void
+_e_info_client_cb_view_tree_info(const Eldbus_Message *msg)
+{
+   const char *errname = NULL, *errtext = NULL;
+   Eldbus_Message_Iter *nodes;
+   Eina_Bool res;
+   uintptr_t root_ptr;
+   E_View_Info *view_info;
+   Eina_List *views, *l;
+
+   EINA_SAFETY_ON_TRUE_GOTO(eldbus_message_error_get(msg, &errname, &errtext), err);
+
+   res = eldbus_message_arguments_get(msg, VALUE_TYPE_REPLY_VIEW_TREE,
+                                      &root_ptr,
+                                      &nodes);
+   EINA_SAFETY_ON_FALSE_GOTO(res, err);
+
+   views = _e_info_view_tree_array(nodes);
+
+   printf("view root:%p\n", (void *)root_ptr);
+   EINA_LIST_FOREACH(views, l, view_info)
+     printf("\tview[%s]:%p parent:%p, impl_name:%s\n", view_info->type, (void *)view_info->ptr, (void *)view_info->parent_ptr, view_info->impl_name);
+
+   _e_info_view_tree_array_del(views);
+
+   return;
+
+err:
+   if (errname || errtext)
+     printf("errname : %s, errmsg : %s\n", errname, errtext);
+   else
+     printf("Error occurred in %s\n", __func__);
+}
+
+static void
+_e_info_client_proc_view_tree_info(int argc, char **argv)
+{
+   Eina_Bool res;
+
+   if (argc != 2)
+     goto err;
+
+   res = _e_info_client_eldbus_message("get_view_tree", _e_info_client_cb_view_tree_info);
+   EINA_SAFETY_ON_FALSE_RETURN(res);
+
+   return;
+
+err:
+   printf("get_view_tree: error: invalid argument\n\n");
+   printf("%s %s\n", argv[0], argv[1]);
+}
+
 typedef struct _ProcInfo
 {
    const char *option;
@@ -7667,6 +7786,12 @@ static ProcInfo procs_to_execute[] =
       "Retrieve default zone ID",
       _e_info_client_proc_default_zone_get,
    },
+   {
+      "view_tree_info",
+      NULL,
+      "Get all of view tree information and print it",
+      _e_info_client_proc_view_tree_info,
+   },
 };
 
 ProcInfo procs_to_input[] =
index d549ffe4196b5459c691f6fd80375f400ec3212c..b2184447df355557637861c0d1f50474686e2043 100644 (file)
@@ -49,6 +49,9 @@
 #include "e_blur_video_capture_intern.h"
 #include "e_compositor_intern.h"
 #include "e_surface_fps_tracker_intern.h"
+#include "e_policy_zone_intern.h"
+#include "e_policy_desk_intern.h"
+#include "e_policy_desk_area_intern.h"
 
 #include <tbm_bufmgr.h>
 #include <tbm_debug.h>
@@ -60,6 +63,7 @@
 #include <mcheck.h>
 
 #include "e_comp_canvas_intern.h"
+#include "e_canvas_intern.h"
 
 #define EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT
 #include <Edje_Edit.h>
@@ -149,6 +153,9 @@ static Eina_List *module_hook = NULL;
 #define VALUE_TYPE_REQUEST_FOR_WININFO_TREE "ti"
 #define VALUE_TYPE_REPLY_WININFO_TREE "tsia(tsiiiiiiii)"
 
+#define VALUE_TYPE_REPLY_VIEW_TREE_NODE "ttss"
+#define VALUE_TYPE_REPLY_VIEW_TREE "ta("VALUE_TYPE_REPLY_VIEW_TREE_NODE")"
+
 enum
 {
    E_INFO_SERVER_SIGNAL_WIN_UNDER_TOUCH = 0
@@ -7783,6 +7790,81 @@ finish:
    return reply;
 }
 
+static const char *
+_view_tree_impl_name_map(const E_View_Tree_Impl *impl)
+{
+   if (impl == &zone_tree_impl) return "zone_tree";
+   if (impl == &desk_tree_impl) return "desk_tree";
+   if (impl == &desk_area_tree_impl) return "desk_area_tree";
+   return "tree";
+}
+
+static void
+_info_print_view_tree(E_View *view, int sx, int sy, void *user_data)
+{
+   Eldbus_Message_Iter *tree_nodes = (Eldbus_Message_Iter *) user_data;
+   Eldbus_Message_Iter *node;
+   uintptr_t tree_ptr;
+   uintptr_t parent_ptr;
+   const char *type = "", *name = "";
+
+   eldbus_message_iter_arguments_append(tree_nodes, "("VALUE_TYPE_REPLY_VIEW_TREE_NODE")", &node);
+
+   tree_ptr = (uintptr_t) view;
+   parent_ptr = (uintptr_t) view->parent;
+   type = e_view_util_type_to_str(view->type);
+
+   if (view->type == E_VIEW_TYPE_TREE)
+     {
+       E_View_Tree *view_tree = e_view_tree_try_from_view(view);
+       if (view_tree) name = _view_tree_impl_name_map(view_tree->impl);
+     }
+   else if (view->type == E_VIEW_TYPE_CLIENT)
+     {
+        E_Client *ec = e_view_data_get(view, "E_Client");
+        name = e_client_icccm_title_get(ec);
+     }
+   else
+     {
+        name = evas_object_name_get(view->eo);
+     }
+
+     eldbus_message_iter_arguments_append(node, VALUE_TYPE_REPLY_VIEW_TREE_NODE,
+                                          (uint64_t) tree_ptr,
+                                          (uint64_t) parent_ptr,
+                                          type,
+                                          name?:"No_name");
+
+     eldbus_message_iter_container_close(tree_nodes, node);
+}
+
+static Eldbus_Message *
+_e_info_server_cb_get_view_tree(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
+{
+   Eldbus_Message *reply = eldbus_message_method_return_new(msg);
+   Eldbus_Message_Iter *iter;
+   Eldbus_Message_Iter *tree_nodes;
+   E_Canvas *canvas;
+
+   canvas = e_comp_canvas_get();
+
+   if (!canvas)
+     {
+        ELOGF("E_INFO", "failed to get comp_canvas", NULL);
+        goto finish;
+     }
+
+   iter = eldbus_message_iter_get(reply);
+   eldbus_message_iter_basic_append(iter, 't', (uintptr_t) e_canvas_root_view_tree_get(canvas));
+   eldbus_message_iter_arguments_append(iter, "a("VALUE_TYPE_REPLY_VIEW_TREE_NODE")", &tree_nodes);
+   e_view_for_each_view_tree_reverse(e_view_tree_view_get(e_canvas_root_view_tree_get(canvas)), _info_print_view_tree, tree_nodes);
+   eldbus_message_iter_container_close(iter, tree_nodes);
+
+finish:
+   return reply;
+}
+
+
 //{ "method_name", arguments_from_client, return_values_to_client, _method_cb, ELDBUS_METHOD_FLAG },
 static const Eldbus_Method methods[] = {
    { "get_window_info", NULL, ELDBUS_ARGS({"isiiia("VALUE_TYPE_FOR_TOPVWINS")", "array of ec"}), _e_info_server_cb_window_info_get, 0 },
@@ -7894,6 +7976,7 @@ static const Eldbus_Method methods[] = {
    { "default_zone_set", ELDBUS_ARGS({"i", "Zone ID to set default zone"}), ELDBUS_ARGS({"b", "result"}), _e_info_server_cb_default_zone_set, 0 },
    { "default_zone_get", NULL, ELDBUS_ARGS({"i", "Zone ID to set default zone"}), _e_info_server_cb_default_zone_get, 0 },
    { "input_use_ecore_event", ELDBUS_ARGS({"i", "set input_use_ecore_event"}), NULL, _e_info_server_cb_input_use_ecore_event, 0 },
+   { "get_view_tree", NULL, ELDBUS_ARGS({VALUE_TYPE_REPLY_VIEW_TREE, "View tree info"}), _e_info_server_cb_get_view_tree, 0 },
    { NULL, NULL, NULL, NULL, 0 }
 };
 
index 77c45a015a378a2b05ae86859dc10098b89ba396..6d6223d03fead2b6bca4fb3fba4cd25dd605ec02 100644 (file)
@@ -1887,7 +1887,7 @@ _e_policy_desk_tree_child_remove(E_View_Tree *tree, E_View *child)
    // doing something
 }
 
-E_View_Tree_Impl desk_tree_impl = {
+EINTERN E_View_Tree_Impl desk_tree_impl = {
    .destroy = _e_policy_desk_tree_destroy,
    .child_add = _e_policy_desk_tree_child_add,
    .child_remove = _e_policy_desk_tree_child_remove,
index b7bc76e99162765ebb2defddf20db7ed4c0bbc42..e8cec46e697b0f12f820eb0eae457fcbbb15792b 100644 (file)
@@ -3004,7 +3004,7 @@ _e_policy_desk_area_tree_child_remove(E_View_Tree *tree, E_View *child)
    // doing something
 }
 
-E_View_Tree_Impl desk_area_tree_impl = {
+EINTERN E_View_Tree_Impl desk_area_tree_impl = {
    .destroy = _e_policy_desk_area_tree_destroy,
    .child_add = _e_policy_desk_area_tree_child_add,
    .child_remove = _e_policy_desk_area_tree_child_remove,
index a56bf616ea7da401ee22a2398a2d07c13e93b8de..a18e23c5ee5f29197657a1e5427206c5a2fde8eb 100644 (file)
@@ -3,9 +3,12 @@
 
 #include "e_intern.h"
 #include "e_desk_area_intern.h"
+#include "e_view_intern.h"
 
 typedef struct _E_Policy_Desk_Area E_Policy_Desk_Area;
 
+extern EINTERN E_View_Tree_Impl desk_area_tree_impl;
+
 EINTERN Eina_Bool            e_policy_desk_area_hook_call(E_Desk_Area *eda, E_Desk_Area_Hook_Point hookpoint, void *data);
 EINTERN E_Policy_Desk_Area * e_policy_desk_area_new(E_Desk_Area *eda);
 EINTERN void                 e_policy_desk_area_del(E_Policy_Desk_Area *pda);
index df509681baf1d570fc2f4dd7c3bb57407300d0b9..479684f7d88cd9ae757ee738551f34fa9c02f2e3 100644 (file)
@@ -3,11 +3,13 @@
 
 #include "e_intern.h"
 #include "e_desk_intern.h"
+#include "e_view_intern.h"
 
 #define E_POLICY_DESK_SMART_OBJ_TYPE "E_Desk_Smart_Object"
 
 typedef struct _E_Policy_Desk E_Policy_Desk;
 
+extern EINTERN E_View_Tree_Impl desk_tree_impl;
 
 EINTERN void           e_policy_desk_add(E_Desk *desk);
 EINTERN void           e_policy_desk_del(E_Policy_Desk *pd);
index 76c4f9ab7008a459870c0fd377c58096353dc03c..f137a3c81ecacbb354b6d9d29eb3c03ea3e0e485 100644 (file)
@@ -1835,7 +1835,7 @@ _e_policy_zone_tree_child_remove(E_View_Tree *tree, E_View *child)
    // doing something
 }
 
-E_View_Tree_Impl zone_tree_impl = {
+EINTERN E_View_Tree_Impl zone_tree_impl = {
    .destroy = _e_policy_zone_tree_destroy,
    .child_add = _e_policy_zone_tree_child_add,
    .child_remove = _e_policy_zone_tree_child_remove,
index 86d85aeb00b72dcfdaa9be760db5924426e2d29a..5941a15a99ab1533feef368ae1d35b3e3e137028 100644 (file)
@@ -3,9 +3,12 @@
 
 #include "e_intern.h"
 #include "e_zone_intern.h"
+#include "e_view_intern.h"
 
 typedef struct _E_Policy_Zone E_Policy_Zone;
 
+extern EINTERN E_View_Tree_Impl zone_tree_impl;
+
 EINTERN Eina_Bool e_policy_zone_visibility_calculate(E_Policy_Zone *policy_zone);
 EINTERN void      e_policy_zone_evaluate(E_Policy_Zone *policy_zone, Eina_Bool *check_focus);