Debugging with Clouseau

Clouseau is the EFL user interface inspection tool. It is designed to make it easy to query UI components and structure. It supports remote debugging and works with GDB. Clouseau can also provide information about different widgets along with their properties.

Installing Clouseau

Clouseau is available from the Enlightenment git repository using the following command:

git clone https://git.enlightenment.org/enlightenment/clouseau.git

Debugging with Clouseau

The following sections will demonstrate the use of Clouseau to debug a simple "Hello World" program.

A Hello World Example

Create the following program in your development environment or text editor:

#define EFL_EO_API_SUPPORT 1
#define EFL_BETA_API_SUPPORT 1
 
#include <Eina.h>
#include <Elementary.h>
#include <Efl_Ui.h>
 
static void
_quit(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
{
   // quit the mainloop
   efl_exit(0);
}
 
EAPI_MAIN void
efl_main(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
{
   Efl_Ui_Win *win;
   Efl_Ui_Box *box;
 
   // new window - new background
   win = efl_add(EFL_UI_WIN_CLASS, NULL,
                  efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC),
                  efl_text_set(efl_added, "Hello World"),
                  efl_ui_win_autodel_set(efl_added, EINA_TRUE));
 
   // when the user clicks "close" on a window there is a request to delete
   efl_event_callback_add(win, EFL_UI_WIN_EVENT_DELETE_REQUEST, _quit, NULL);
 
   // add a box object - default is vertical.
   box = efl_add(EFL_UI_BOX_CLASS, win,
                 efl_content_set(win, efl_added),
                 // make the box horizontal
                 efl_ui_direction_set(efl_added, EFL_UI_DIR_HORIZONTAL));
 
   // add a label widget, set the text and put it in the box
   efl_add(EFL_UI_TEXT_CLASS, box,
           efl_text_set(efl_added, "Hello out there world!"),
           efl_ui_text_interactive_selection_allowed_set(efl_added, EINA_FALSE),
           efl_pack(box, efl_added));
 
   // add a quit button
   efl_add(EFL_UI_BUTTON_CLASS, box,
           efl_text_set(efl_added, "Quit"),
           efl_pack(box, efl_added),
           efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED,
                                  _quit, efl_added));
}
EFL_MAIN()

Save and compile the program as "helloworld".

Debugging Hello World with Clouseau

For using Clouseau, you need to have the efl_debugd daemon running.

 efl_debugd

Also make sure that you have enabled the clouseau option in the elementary_config option.

Then, just run the "helloworld" program with the following command:

 ./helloworld

After that you can start clouseau_client, change from offline to local mode, and select your helloworld app, after that you should be ready to start your debugging session.

The following screenshot demonstrates Clouseau's output:

Clouseau

  • Yellow - The "helloworld" application
  • Red - the composition of the "helloworld" application
  • Blue - the characteristic of Efl.Ui and Efl.Canvas

Exploring Hello World

The application is composed of three main widgets : Efl.Ui.Win, Efl.Ui.Bg, and Efl.Ui.Box.

win = efl_add(EFL_UI_WIN_CLASS, NULL);
[...]
box = efl_add(EFL_UI_BOX_CLASS, win);

The efl_add(EFL_UI_WIN_CLASS, NULL) line creates the window widget, win, which is the root widget often used in an application. It also adds a standard background (Efl.Bg). Then the efl_add(EFL_UI_BOX_CLASS, win) line creates a box widget.

efl_pack(box, efl_added);

The efl_pack() functions add the label and button widgets at the end of the pack list, so that they appear inside the box widget.

The blue section of the screenshot shows certain characteristics of the object and widget: their position, size, color and so on. Some of these characteristics are dynamic and can be updated with the reload button in Clouseau.

efl_content_set(win, efl_added)

The efl_content_set() function sets the content of the window such that it will resize to take up the minimum space. You can see in the blue section that the minimum and maximum size are equal as a consequence of this function call.

Displaying All Objects

To control the objects that are displayed, click on the "Settings" button and deselect "Only show Efl.Ui widgets" as per the below screenshot:

Clouseau Settings

This will display all the program's objects, demonstrating that widgets are just gathered specific objects.

Clouseau Objects

Highlighted in yellow is the Efl.Ui.Box, which is an Efl.Canvas.Box composed of an Efl.Canvas.Rectangle, an Efl.Ui.Text and an Efl.Ui.Button.

A Button widget is an Efl.Ui.Button which is composed of four Efl.Canvas.Rectangle, one Efl.Canvas.Image and two Efl.Canvas.Text.