clouseau: introduce focus inspector
This for now shows the nodes that are registered in a manager, in the hirarchy that is used. Redirects are displayed red, logicals gray and normals in a e-style blue. If something is part of the focus history its green.
This commit is contained in:
parent
4ae284bd0b
commit
65d89b92c2
|
@ -3,13 +3,20 @@ add_custom_command (
|
|||
COMMAND edje_cc -id ${CMAKE_CURRENT_SOURCE_DIR}/images ${CMAKE_CURRENT_SOURCE_DIR}/evlog.edc clouseau_evlog.edj
|
||||
DEPENDS evlog.edc
|
||||
)
|
||||
add_custom_command (
|
||||
OUTPUT clouseau_focus_inspector.edj
|
||||
COMMAND edje_cc -id ${CMAKE_CURRENT_SOURCE_DIR}/images ${CMAKE_CURRENT_SOURCE_DIR}/focus_inspector.edc clouseau_focus_inspector.edj
|
||||
DEPENDS focus_inspector.edc
|
||||
)
|
||||
|
||||
add_custom_target (
|
||||
clouseau_evlog_edj
|
||||
DEPENDS clouseau_evlog.edj evlog.edc
|
||||
)
|
||||
|
||||
add_custom_target(focus_inspector_theme DEPENDS clouseau_focus_inspector.edj)
|
||||
|
||||
install (
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/clouseau_evlog.edj images/show-screenshot.png images/take-screenshot.png
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/clouseau_focus_inspector.edj ${CMAKE_CURRENT_BINARY_DIR}/clouseau_evlog.edj images/show-screenshot.png images/take-screenshot.png
|
||||
DESTINATION share/${PROJECT_NAME_LOWER}
|
||||
)
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
collections {
|
||||
images {
|
||||
image: "focus_inspector_history.svg" COMP;
|
||||
image: "focus_inspector_logical.svg" COMP;
|
||||
image: "focus_inspector_regular.svg" COMP;
|
||||
image: "focus_inspector_redirect.svg" COMP;
|
||||
}
|
||||
group { "focus_inspector/regular";
|
||||
parts {
|
||||
image { "indicator";
|
||||
desc { "default";
|
||||
rel1.to: "widget_name";
|
||||
rel1.offset: -3px -3px;
|
||||
rel2.to: "widget_name";
|
||||
rel2.offset: 3px 3px;
|
||||
|
||||
image {
|
||||
border: 1 1 1 1;
|
||||
normal: "focus_inspector_regular.svg";
|
||||
}
|
||||
}
|
||||
}
|
||||
text { "widget_name";
|
||||
desc { "default";
|
||||
text {
|
||||
font: Sans;
|
||||
text: "<widget-name>";
|
||||
size: 8;
|
||||
min: 1 1;
|
||||
max: 1 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
group { "focus_inspector/logical";
|
||||
inherit: "focus_inspector/regular";
|
||||
parts {
|
||||
image { "indicator";
|
||||
desc { "default";
|
||||
rel1.to: "widget_name";
|
||||
rel1.offset: -3px -3px;
|
||||
rel2.to: "widget_name";
|
||||
rel2.offset: 3px 3px;
|
||||
|
||||
image {
|
||||
border: 1 1 1 1;
|
||||
normal: "focus_inspector_logical.svg";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
group { "focus_inspector/history";
|
||||
inherit: "focus_inspector/regular";
|
||||
parts {
|
||||
image { "indicator";
|
||||
desc { "default";
|
||||
rel1.to: "widget_name";
|
||||
rel1.offset: -3px -3px;
|
||||
rel2.to: "widget_name";
|
||||
rel2.offset: 3px 3px;
|
||||
|
||||
image {
|
||||
border: 1 1 1 1;
|
||||
normal: "focus_inspector_history.svg";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
group { "focus_inspector/redirect";
|
||||
inherit: "focus_inspector/regular";
|
||||
parts {
|
||||
image { "indicator";
|
||||
desc { "default";
|
||||
rel1.to: "widget_name";
|
||||
rel1.offset: -3px -3px;
|
||||
rel2.to: "widget_name";
|
||||
rel2.offset: 3px 3px;
|
||||
|
||||
image {
|
||||
border: 1 1 1 1;
|
||||
normal: "focus_inspector_redirect.svg";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="99.855179mm"
|
||||
height="28.76149mm"
|
||||
viewBox="0 0 99.855179 28.76149"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
|
||||
sodipodi:docname="focus_inspector_history.svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98994949"
|
||||
inkscape:cx="-3.7169149"
|
||||
inkscape:cy="-166.01003"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1057"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-0.58634746,-0.38263321)">
|
||||
<rect
|
||||
style="fill:#484e4d;fill-opacity:1;fill-rule:nonzero;stroke:#259700;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect4504"
|
||||
width="98.355179"
|
||||
height="27.26149"
|
||||
x="1.3363475"
|
||||
y="1.1326332"
|
||||
ry="8.5526237"
|
||||
rx="0" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="99.855179mm"
|
||||
height="28.76149mm"
|
||||
viewBox="0 0 99.855179 28.76149"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
|
||||
sodipodi:docname="focus_inspector_logical.svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98994949"
|
||||
inkscape:cx="-3.7169149"
|
||||
inkscape:cy="-166.01003"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1057"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-0.58634746,-0.38263321)">
|
||||
<rect
|
||||
style="fill:#484e4d;fill-opacity:1;fill-rule:nonzero;stroke:#787878;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect4504"
|
||||
width="98.355179"
|
||||
height="27.26149"
|
||||
x="1.3363475"
|
||||
y="1.1326332"
|
||||
ry="8.5526237"
|
||||
rx="0" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="99.855179mm"
|
||||
height="28.76149mm"
|
||||
viewBox="0 0 99.855179 28.76149"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
|
||||
sodipodi:docname="focus_inspector_redirect.svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98994949"
|
||||
inkscape:cx="-3.7169149"
|
||||
inkscape:cy="-166.01003"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1057"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-0.58634746,-0.38263321)">
|
||||
<rect
|
||||
style="fill:#484e4d;fill-opacity:1;fill-rule:nonzero;stroke:#c0392b;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect4504"
|
||||
width="98.355179"
|
||||
height="27.26149"
|
||||
x="1.3363475"
|
||||
y="1.1326332"
|
||||
ry="8.5526237"
|
||||
rx="0" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="99.855179mm"
|
||||
height="28.76149mm"
|
||||
viewBox="0 0 99.855179 28.76149"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
|
||||
sodipodi:docname="focus_inspector_regular.svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98994949"
|
||||
inkscape:cx="-3.7169149"
|
||||
inkscape:cy="-166.01003"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1057"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-0.58634746,-0.38263321)">
|
||||
<rect
|
||||
style="fill:#484e4d;fill-opacity:1;fill-rule:nonzero;stroke:#2288ee;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect4504"
|
||||
width="98.355179"
|
||||
height="27.26149"
|
||||
x="1.3363475"
|
||||
y="1.1326332"
|
||||
ry="8.5526237"
|
||||
rx="0" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <Eo.h>
|
||||
#include <Eolian.h>
|
||||
#include <Elementary.h>
|
||||
|
||||
typedef void (*Eo_Debug_Class_Extract_Cb)(void *data, uint64_t kl, char *kl_name);
|
||||
|
||||
|
@ -107,6 +108,19 @@ typedef struct
|
|||
int tm_hour;
|
||||
} Evas_Debug_Screenshot;
|
||||
|
||||
typedef struct {
|
||||
Eo *redirect_manager;
|
||||
Eo *focused;
|
||||
const char *class_name;
|
||||
Eina_List *relations;
|
||||
} Clouseau_Focus_Manager_Data;
|
||||
|
||||
typedef struct {
|
||||
Efl_Ui_Focus_Relations relation;
|
||||
const char *class_name;
|
||||
} Clouseau_Focus_Relation;
|
||||
|
||||
|
||||
EAPI void *eo_debug_eoids_request_prepare(int *size, ...);
|
||||
|
||||
EAPI void eo_debug_klids_extract(void *buffer, int size, Eo_Debug_Class_Extract_Cb cb, void *data);
|
||||
|
|
|
@ -71,6 +71,11 @@ static int _eoids_get_op = EINA_DEBUG_OPCODE_INVALID;
|
|||
static int _obj_info_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
static int _obj_highlight_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
static int _win_screenshot_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
static int _focus_manager_list_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
static int _focus_manager_detail_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
|
||||
static Eet_Data_Descriptor *managers = NULL, *manager_details = NULL;
|
||||
#include "clouseau_focus_serialization.x"
|
||||
|
||||
enum {
|
||||
HIGHLIGHT_R = 255,
|
||||
|
@ -915,6 +920,142 @@ _main_loop_win_screenshot_cb(Eina_Debug_Session *session, int srcid, void *buffe
|
|||
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_win_screenshot_cb)
|
||||
|
||||
static Eina_Bool
|
||||
_only_manager(const void *container, void *data, void *fdata)
|
||||
{
|
||||
return efl_isa(data, EFL_UI_FOCUS_MANAGER_INTERFACE);
|
||||
}
|
||||
|
||||
static void
|
||||
_main_loop_focus_manager_list_cb(Eina_Debug_Session *session, int srcid, void *buffer, int size)
|
||||
{
|
||||
Eina_Iterator *obj_iterator, *manager_iterator;
|
||||
Eina_Array *array;
|
||||
Eo *obj;
|
||||
|
||||
array = eina_array_new(10);
|
||||
obj_iterator = eo_objects_iterator_new();
|
||||
manager_iterator = eina_iterator_filter_new(obj_iterator, _only_manager, NULL, NULL);
|
||||
|
||||
EINA_ITERATOR_FOREACH(manager_iterator, obj)
|
||||
{
|
||||
eina_array_push(array, obj);
|
||||
}
|
||||
|
||||
eina_debug_session_send(session, srcid, _focus_manager_list_op, array->data, array->count * sizeof(void*));
|
||||
}
|
||||
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_focus_manager_list_cb)
|
||||
|
||||
EAPI Efl_Dbg_Info*
|
||||
clouseau_eo_info_find(Efl_Dbg_Info *root, const char *name)
|
||||
{
|
||||
Eina_Value_List eo_list;
|
||||
Eina_List *n;
|
||||
Efl_Dbg_Info *info;
|
||||
|
||||
if (!root) return NULL;
|
||||
|
||||
eina_value_pget(&(root->value), &eo_list);
|
||||
|
||||
EINA_LIST_FOREACH(eo_list.list, n, info)
|
||||
{
|
||||
if (!strcmp(info->name, name))
|
||||
{
|
||||
return info;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Eina_List*
|
||||
_fetch_children(Efl_Ui_Focus_Manager *m)
|
||||
{
|
||||
Efl_Dbg_Info *manager_data, *children_data, *root;
|
||||
Eina_List *lst = NULL, *n;
|
||||
Eina_Value_List result;
|
||||
Efl_Dbg_Info *elem;
|
||||
|
||||
root = EFL_DBG_INFO_LIST_APPEND(NULL, "Root");
|
||||
|
||||
efl_dbg_info_get(m, root);
|
||||
|
||||
manager_data = clouseau_eo_info_find(root, "Efl.Ui.Focus.Manager");
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(manager_data, NULL);
|
||||
|
||||
children_data = clouseau_eo_info_find(manager_data, "children");
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(children_data, NULL);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_get(&children_data->value) == EINA_VALUE_TYPE_LIST, NULL);
|
||||
|
||||
eina_value_pget(&children_data->value, &result);
|
||||
|
||||
EINA_LIST_FOREACH(result.list, n, elem)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_get(&elem->value) == EINA_VALUE_TYPE_UINT64, NULL);
|
||||
eina_value_get(&elem->value, &ptr);
|
||||
|
||||
lst = eina_list_append(lst, ptr);
|
||||
}
|
||||
|
||||
efl_dbg_info_free(root);
|
||||
|
||||
return lst;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_main_loop_focus_manager_detail_cb(Eina_Debug_Session *session, int srcid, void *buffer, int size)
|
||||
{
|
||||
Clouseau_Focus_Manager_Data *res;
|
||||
uint64_t ptr64;
|
||||
Eo *elem, *manager;
|
||||
|
||||
if (!manager_details) _init_data_descriptors();
|
||||
|
||||
memcpy(&ptr64, buffer, sizeof(ptr64));
|
||||
manager = (Eo *)SWAP_64(ptr64);
|
||||
if (!efl_isa(manager, EFL_UI_FOCUS_MANAGER_INTERFACE)) return EINA_TRUE;
|
||||
|
||||
Eina_List *children = _fetch_children(manager);
|
||||
|
||||
res = alloca(sizeof(Clouseau_Focus_Manager_Data));
|
||||
res->class_name = efl_class_name_get(manager);
|
||||
res->relations = NULL;
|
||||
res->focused = efl_ui_focus_manager_focus_get(manager);
|
||||
res->redirect_manager = efl_ui_focus_manager_redirect_get(manager);
|
||||
|
||||
EINA_LIST_FREE(children, elem)
|
||||
{
|
||||
Clouseau_Focus_Relation *crel = calloc(1, sizeof(Clouseau_Focus_Relation));
|
||||
Efl_Ui_Focus_Relations *rel;
|
||||
|
||||
rel = efl_ui_focus_manager_fetch(manager, elem);
|
||||
memcpy(&crel->relation, rel, sizeof(Efl_Ui_Focus_Relations));
|
||||
|
||||
crel->class_name = efl_class_name_get(elem);
|
||||
|
||||
res->relations = eina_list_append(res->relations, crel);
|
||||
|
||||
free(rel);
|
||||
}
|
||||
|
||||
int blob_size;
|
||||
void *blob = eet_data_descriptor_encode(manager_details, res, &blob_size);
|
||||
|
||||
Clouseau_Focus_Manager_Data *aaah = eet_data_descriptor_decode(manager_details, blob, blob_size);
|
||||
|
||||
if (eina_list_count(aaah->relations) != eina_list_count(res->relations)) abort();
|
||||
|
||||
eina_debug_session_send(session, srcid, _focus_manager_detail_op, blob, blob_size);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_focus_manager_detail_cb)
|
||||
|
||||
EINA_DEBUG_OPCODES_ARRAY_DEFINE(_debug_ops,
|
||||
{"Clouseau/Object_Introspection/snapshot_start", &_snapshot_start_op, &_snapshot_start_cb},
|
||||
{"Clouseau/Object_Introspection/snapshot_done", &_snapshot_done_op, NULL},
|
||||
|
@ -923,6 +1064,8 @@ EINA_DEBUG_OPCODES_ARRAY_DEFINE(_debug_ops,
|
|||
{"Clouseau/Eolian/object/info_get", &_obj_info_op, &_obj_info_req_cb},
|
||||
{"Clouseau/Evas/object/highlight", &_obj_highlight_op, &_obj_highlight_cb},
|
||||
{"Clouseau/Evas/window/screenshot", &_win_screenshot_op, &_win_screenshot_cb},
|
||||
{"Clouseau/Elementary_Focus/list", &_focus_manager_list_op, &_focus_manager_list_cb},
|
||||
{"Clouseau/Elementary_Focus/detail", &_focus_manager_detail_op, &_focus_manager_detail_cb},
|
||||
{NULL, NULL, NULL}
|
||||
);
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
static void
|
||||
_init_data_descriptors(void)
|
||||
{
|
||||
Eet_Data_Descriptor_Class klass;
|
||||
Eet_Data_Descriptor *relations_eed;
|
||||
|
||||
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&klass, Clouseau_Focus_Relation);
|
||||
relations_eed = eet_data_descriptor_file_new(&klass);
|
||||
#define BASIC(field, type) EET_DATA_DESCRIPTOR_ADD_BASIC(relations_eed, Clouseau_Focus_Relation, #field , field, type)
|
||||
|
||||
BASIC(class_name, EET_T_STRING);
|
||||
BASIC(relation.next, EET_T_UINT);
|
||||
BASIC(relation.prev, EET_T_UINT);
|
||||
BASIC(relation.logical, EET_T_CHAR);
|
||||
BASIC(relation.parent, EET_T_UINT);
|
||||
BASIC(relation.redirect, EET_T_UINT);
|
||||
BASIC(relation.node, EET_T_UINT);
|
||||
BASIC(relation.position_in_history, EET_T_INT);
|
||||
|
||||
#undef BASIC
|
||||
#define LIST(field, type) EET_DATA_DESCRIPTOR_ADD_LIST(relations_eed, Clouseau_Focus_Relation, #field , field, type)
|
||||
|
||||
/*LIST(relation.right, EET_T_UINT);
|
||||
LIST(relation.left, EET_T_UINT);
|
||||
LIST(relation.top, EET_T_UINT);
|
||||
LIST(relation.down, EET_T_UINT);*/
|
||||
|
||||
#undef LIST
|
||||
|
||||
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&klass, Clouseau_Focus_Manager_Data);
|
||||
manager_details = eet_data_descriptor_file_new(&klass);
|
||||
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(manager_details, Clouseau_Focus_Manager_Data, "redirect_manager", redirect_manager, EET_T_UINT);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(manager_details, Clouseau_Focus_Manager_Data, "focused", focused, EET_T_UINT);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(manager_details, Clouseau_Focus_Manager_Data, "class_name", class_name, EET_T_STRING);
|
||||
EET_DATA_DESCRIPTOR_ADD_LIST(manager_details, Clouseau_Focus_Manager_Data, "relations", relations, relations_eed);
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
add_subdirectory(objects_introspection)
|
||||
add_subdirectory(evlog)
|
||||
add_subdirectory(focus_inspector)
|
||||
|
||||
if (${EFL_PROFILER_FOUND})
|
||||
add_subdirectory(profiling_viewer)
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
set(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
STRING(REGEX REPLACE "\n" "" EOLIAN_EO_DIR ${EOLIAN_EO_DIR})
|
||||
STRING(REGEX REPLACE " " "" EOLIAN_EO_DIR ${EOLIAN_EO_DIR})
|
||||
add_definitions(${CLI_COMMON_DEFINITIONS} -DEFL_EO_API_SUPPORT
|
||||
-DEOLIAN_EO_DIR="${EOLIAN_EO_DIR}" -DFOCUS_EDJ="${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME_LOWER}/clouseau_focus_inspector.edj")
|
||||
|
||||
add_definitions(-DEFL_EO_API_SUPPORT -DGUI_IMAGES_PATH="${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME_LOWER}")
|
||||
|
||||
set(EOLIAN_INCLUDE_FLAG -I \"${EOLIAN_EO_DIR}/eo-1\" -I${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${ELEMENTARY_INCLUDE_DIRS}
|
||||
${EVAS_INCLUDE_DIRS}
|
||||
${EO_INCLUDE_DIRS}
|
||||
${EINA_INCLUDE_DIRS}
|
||||
${EET_INCLUDE_DIRS}
|
||||
${EOLIAN_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
link_directories (${PC_LIBELEMENTARY_LIBRARY_DIRS})
|
||||
|
||||
add_library(focus_inspector SHARED main.c gui.c tree_view.c)
|
||||
|
||||
target_link_libraries(focus_inspector
|
||||
${ELEMENTARY_LIBRARIES}
|
||||
${EVAS_LIBRARIES}
|
||||
${EO_LIBRARIES}
|
||||
${EINA_LIBRARIES}
|
||||
${EET_LIBRARIES}
|
||||
${EOLIAN_LIBRARIES}
|
||||
clouseau_debug
|
||||
)
|
||||
|
||||
add_dependencies(focus_inspector focus_inspector_theme)
|
||||
|
||||
INSTALL(TARGETS focus_inspector LIBRARY DESTINATION lib)
|
|
@ -0,0 +1,118 @@
|
|||
#include <Elementary.h>
|
||||
#include "../../Clouseau_Debug.h"
|
||||
#include "gui.h"
|
||||
|
||||
static Evas_Object *table, *managers, *redirect, *history, *scroller;
|
||||
static Elm_Genlist_Item_Class *itc;
|
||||
|
||||
static char*
|
||||
_text_get(void *data, Elm_Genlist *list, const char *part)
|
||||
{
|
||||
Efl_Ui_Focus_Manager *manager = data;
|
||||
Eina_Strbuf *res = eina_strbuf_new();
|
||||
|
||||
eina_strbuf_append_printf(res, "%p", manager);
|
||||
return eina_strbuf_release(res);
|
||||
}
|
||||
|
||||
EAPI Evas_Object*
|
||||
ui_create(Instance *inst, Evas_Object *obj)
|
||||
{
|
||||
Evas_Object *o;
|
||||
|
||||
o = table = elm_table_add(obj);
|
||||
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
evas_object_show(o);
|
||||
|
||||
o = managers = elm_combobox_add(obj);
|
||||
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
elm_object_part_text_set(o, "guide", "Manager to inspect");
|
||||
evas_object_show(o);
|
||||
elm_table_pack(table, o, 0, 0, 1, 1);
|
||||
itc = elm_genlist_item_class_new();
|
||||
itc->func.text_get = _text_get;
|
||||
|
||||
o = elm_label_add(obj);
|
||||
elm_object_text_set(o, "Redirect:");
|
||||
evas_object_show(o);
|
||||
elm_table_pack(table, o, 1, 0, 1, 1);
|
||||
|
||||
o = redirect = elm_label_add(obj);
|
||||
evas_object_show(o);
|
||||
elm_table_pack(table, o, 2, 0, 1, 1);
|
||||
|
||||
o = history = elm_hoversel_add(obj);
|
||||
elm_object_text_set(o, "History");
|
||||
evas_object_show(o);
|
||||
elm_table_pack(table, o, 3, 0, 1, 1);
|
||||
|
||||
o = scroller = elm_scroller_add(table);
|
||||
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
evas_object_show(o);
|
||||
elm_table_pack(table, o, 0, 1, 4, 1);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
static void
|
||||
_sel(void *data, Evas_Object *obj, void *event_info)
|
||||
{
|
||||
com_defailt_manager(data, elm_object_item_data_get(event_info));
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ui_managers_add(Instance *inst, Efl_Ui_Focus_Manager **manager, int size)
|
||||
{
|
||||
elm_genlist_clear(managers);
|
||||
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
elm_genlist_item_append(managers, itc, manager[i], NULL, 0, _sel, inst);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_sort(const void *a_raw, const void *b_raw)
|
||||
{
|
||||
const Clouseau_Focus_Relation *a = a_raw;
|
||||
const Clouseau_Focus_Relation *b = b_raw;
|
||||
|
||||
int val_a, val_b;
|
||||
|
||||
if (a) val_a = a->relation.position_in_history;
|
||||
if (b) val_b = b->relation.position_in_history;
|
||||
|
||||
return val_a - val_b;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ui_manager_data_arrived(Instance *inst, Clouseau_Focus_Manager_Data *data)
|
||||
{
|
||||
Clouseau_Focus_Relation *rel;
|
||||
Evas_Object *box, *o;
|
||||
Eina_List *n, *sorted = NULL;
|
||||
|
||||
EINA_LIST_FREE(inst->realized.objects, o)
|
||||
evas_object_del(o);
|
||||
|
||||
inst->realized.data = data;
|
||||
|
||||
elm_hoversel_clear(history);
|
||||
|
||||
EINA_LIST_FOREACH(data->relations, n, rel)
|
||||
{
|
||||
if (rel->relation.position_in_history != -1)
|
||||
sorted = eina_list_sorted_insert(sorted, _sort, rel);
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(sorted, n, rel)
|
||||
{
|
||||
elm_hoversel_item_add(history, rel->class_name, NULL, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
tree_view_update(inst, scroller);
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef GUI_H
|
||||
#define GUI_H
|
||||
|
||||
#include "../../Clouseau.h"
|
||||
#include "../../Clouseau_Debug.h"
|
||||
|
||||
typedef struct {
|
||||
Clouseau_Extension *ext;
|
||||
struct {
|
||||
Eina_List *objects;
|
||||
Clouseau_Focus_Manager_Data *data;
|
||||
} realized;
|
||||
} Instance;
|
||||
|
||||
#define PUSH_CLEANUP(inst, o) inst->realized.objects = eina_list_append(inst->realized.objects, o)
|
||||
|
||||
EAPI void tree_view_update(Instance *inst, Evas_Object *scroller);
|
||||
|
||||
EAPI void ui_managers_add(Instance *inst, Efl_Ui_Focus_Manager **manager, int size);
|
||||
EAPI void ui_manager_data_arrived(Instance *inst, Clouseau_Focus_Manager_Data *data);
|
||||
EAPI Evas_Object* ui_create(Instance *inst, Evas_Object *obj);
|
||||
|
||||
EAPI void com_refresh_managers(Instance *inst);
|
||||
EAPI void com_defailt_manager(Instance *inst, Efl_Ui_Focus_Manager *manager);
|
||||
#endif
|
|
@ -0,0 +1,119 @@
|
|||
#include <Eina.h>
|
||||
#include <Elementary.h>
|
||||
#include "../../Clouseau.h"
|
||||
#include "../../Clouseau_Debug.h"
|
||||
#include "gui.h"
|
||||
|
||||
static Instance inst;
|
||||
|
||||
static int _focus_manager_list_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
static int _focus_manager_detail_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
|
||||
static Eet_Data_Descriptor *managers = NULL, *manager_details = NULL;
|
||||
#include "../../clouseau_focus_serialization.x"
|
||||
|
||||
static Eina_Bool
|
||||
_main_loop_focus_manager_list_cb(Eina_Debug_Session *session, int src, void *buffer, int size)
|
||||
{
|
||||
int managers = size / sizeof(Efl_Ui_Focus_Manager*);
|
||||
Efl_Ui_Focus_Manager *manager_arr[managers];
|
||||
Clouseau_Extension *ext = eina_debug_session_data_get(session);
|
||||
|
||||
memcpy(manager_arr, buffer, size);
|
||||
|
||||
ui_managers_add(ext->data, manager_arr, managers);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_focus_manager_list_cb)
|
||||
|
||||
static Eina_Bool
|
||||
_main_loop_focus_manager_detail_cb(Eina_Debug_Session *session, int src, void *buffer, int size)
|
||||
{
|
||||
Clouseau_Extension *ext = eina_debug_session_data_get(session);
|
||||
Clouseau_Focus_Manager_Data *pd;
|
||||
if (!manager_details) _init_data_descriptors();
|
||||
|
||||
pd = eet_data_descriptor_decode(manager_details, buffer, size);
|
||||
|
||||
ui_manager_data_arrived(ext->data, pd);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_focus_manager_detail_cb)
|
||||
|
||||
EINA_DEBUG_OPCODES_ARRAY_DEFINE(_ops,
|
||||
{"Clouseau/Elementary_Focus/list", &_focus_manager_list_op, &_focus_manager_list_cb},
|
||||
{"Clouseau/Elementary_Focus/detail", &_focus_manager_detail_op, &_focus_manager_detail_cb},
|
||||
{NULL, NULL, NULL}
|
||||
);
|
||||
|
||||
static void
|
||||
_session_changed(Clouseau_Extension *ext)
|
||||
{
|
||||
int i = 0;
|
||||
Instance *inst = ext->data;
|
||||
Eina_Debug_Opcode *ops = _ops();
|
||||
|
||||
while (ops[i].opcode_name)
|
||||
{
|
||||
if (ops[i].opcode_id) *(ops[i].opcode_id) = EINA_DEBUG_OPCODE_INVALID;
|
||||
i++;
|
||||
}
|
||||
if (ext->session)
|
||||
{
|
||||
eina_debug_session_data_set(ext->session, ext);
|
||||
eina_debug_opcodes_register(ext->session, ops, NULL, ext);
|
||||
}
|
||||
}
|
||||
static void
|
||||
_app_changed(Clouseau_Extension *ext)
|
||||
{
|
||||
com_refresh_managers(ext->data);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
com_refresh_managers(Instance *inst)
|
||||
{
|
||||
int i = eina_debug_session_send(inst->ext->session, inst->ext->app_id, _focus_manager_list_op, NULL, 0);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
com_defailt_manager(Instance *inst, Efl_Ui_Focus_Manager *manager)
|
||||
{
|
||||
void *tmp[1];
|
||||
tmp[0] = manager;
|
||||
|
||||
int i = eina_debug_session_send(inst->ext->session, inst->ext->app_id, _focus_manager_detail_op, tmp, sizeof(void*));
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
extension_name_get()
|
||||
{
|
||||
return "Focus Inspector";
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
extension_start(Clouseau_Extension *ext, Eo *parent)
|
||||
{
|
||||
eina_init();
|
||||
|
||||
inst.ext = ext;
|
||||
ext->data = &inst;
|
||||
ext->ui_object = ui_create(ext->data, parent);
|
||||
ext->session_changed_cb = _session_changed;
|
||||
ext->app_changed_cb = _app_changed;
|
||||
|
||||
return !!ext->ui_object;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
extension_stop(Clouseau_Extension *ext)
|
||||
{
|
||||
efl_del(ext->ui_object);
|
||||
|
||||
eina_shutdown();
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
#include <Elementary.h>
|
||||
#include "../../Clouseau_Debug.h"
|
||||
#include "gui.h"
|
||||
|
||||
static void
|
||||
find(Instance *pd, void *parent, void (*found)(void *data, Instance *pd, Clouseau_Focus_Relation *relation), void *data)
|
||||
{
|
||||
for (int i = 0; pd->realized.data->relations && i < eina_list_count(pd->realized.data->relations); ++i)
|
||||
{
|
||||
Clouseau_Focus_Relation *rel;
|
||||
rel = eina_list_nth(pd->realized.data->relations, i);
|
||||
if (rel->relation.parent == parent)
|
||||
found(data, pd, rel);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tree_level(void *data, Instance *inst, Clouseau_Focus_Relation *relation)
|
||||
{
|
||||
Evas_Object *box, *childbox, *vis;
|
||||
int maxw, maxh, minw, minh;
|
||||
Eina_Strbuf *buf;
|
||||
char group[PATH_MAX];
|
||||
|
||||
box = evas_object_box_add(evas_object_evas_get(data));
|
||||
evas_object_box_padding_set(box, 20, 20);
|
||||
evas_object_show(box);
|
||||
|
||||
PUSH_CLEANUP(inst, box);
|
||||
|
||||
buf = eina_strbuf_new();
|
||||
eina_strbuf_append_printf(buf, "%p", relation->relation.node);
|
||||
|
||||
vis = edje_object_add(evas_object_evas_get(data));
|
||||
evas_object_size_hint_weight_set(vis, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(vis, 0.0, EVAS_HINT_FILL);
|
||||
|
||||
if (relation->relation.position_in_history != -1 )
|
||||
snprintf(group, sizeof(group), "focus_inspector/history");
|
||||
else if (relation->relation.redirect)
|
||||
snprintf(group, sizeof(group), "focus_inspector/redirect");
|
||||
else if (relation->relation.logical)
|
||||
snprintf(group, sizeof(group), "focus_inspector/logical");
|
||||
else
|
||||
snprintf(group, sizeof(group), "focus_inspector/regular");
|
||||
|
||||
edje_object_file_set(vis, FOCUS_EDJ, group);
|
||||
edje_object_part_text_set(vis, "widget_name", relation->class_name);
|
||||
evas_object_show(vis);
|
||||
evas_object_box_append(box, vis);
|
||||
|
||||
edje_object_size_max_get(vis, &maxw, &maxh);
|
||||
edje_object_size_min_get(vis, &minw, &minh);
|
||||
if ((minw <= 0) && (minh <= 0))
|
||||
edje_object_size_min_calc(vis, &minw, &minh);
|
||||
|
||||
evas_object_size_hint_max_set(vis, maxw, maxh);
|
||||
evas_object_size_hint_min_set(vis, minw, minh);
|
||||
|
||||
PUSH_CLEANUP(inst, vis);
|
||||
|
||||
childbox = evas_object_box_add(evas_object_evas_get(data));
|
||||
evas_object_box_padding_set(childbox, 20, 20);
|
||||
evas_object_box_layout_set(childbox, evas_object_box_layout_vertical, NULL, NULL);
|
||||
evas_object_box_append(box, childbox);
|
||||
evas_object_show(childbox);
|
||||
|
||||
PUSH_CLEANUP(inst, childbox);
|
||||
|
||||
find(inst, relation->relation.node, tree_level, childbox);
|
||||
|
||||
evas_object_box_append(data, box);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
tree_view_update(Instance *inst, Evas_Object *scroller)
|
||||
{
|
||||
Evas_Object *box;
|
||||
|
||||
box = evas_object_box_add(evas_object_evas_get(scroller));
|
||||
evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
evas_object_box_layout_set(box, evas_object_box_layout_vertical, NULL, NULL);
|
||||
evas_object_show(box);
|
||||
PUSH_CLEANUP(inst, box);
|
||||
|
||||
if (inst->realized.data)
|
||||
find(inst, NULL, tree_level, box);
|
||||
|
||||
elm_object_content_set(scroller, box);
|
||||
}
|
Loading…
Reference in New Issue