diff options
Diffstat (limited to 'sway/debug-tree.c')
-rw-r--r-- | sway/debug-tree.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/sway/debug-tree.c b/sway/debug-tree.c new file mode 100644 index 00000000..ae0a1869 --- /dev/null +++ b/sway/debug-tree.c | |||
@@ -0,0 +1,119 @@ | |||
1 | #include <pango/pangocairo.h> | ||
2 | #include <wlr/backend.h> | ||
3 | #include <wlr/render/wlr_texture.h> | ||
4 | #include <wlr/util/log.h> | ||
5 | #include "config.h" | ||
6 | #include "sway/input/input-manager.h" | ||
7 | #include "sway/input/seat.h" | ||
8 | #include "sway/server.h" | ||
9 | #include "sway/tree/container.h" | ||
10 | #include "sway/tree/layout.h" | ||
11 | #include "cairo.h" | ||
12 | #include "config.h" | ||
13 | #include "pango.h" | ||
14 | |||
15 | static const char *layout_to_str(enum sway_container_layout layout) { | ||
16 | switch (layout) { | ||
17 | case L_HORIZ: | ||
18 | return "L_HORIZ"; | ||
19 | case L_VERT: | ||
20 | return "L_VERT"; | ||
21 | case L_STACKED: | ||
22 | return "L_STACKED"; | ||
23 | case L_TABBED: | ||
24 | return "L_TABBED"; | ||
25 | case L_FLOATING: | ||
26 | return "L_FLOATING"; | ||
27 | case L_NONE: | ||
28 | default: | ||
29 | return "L_NONE"; | ||
30 | } | ||
31 | } | ||
32 | |||
33 | static int draw_container(cairo_t *cairo, struct sway_container *container, | ||
34 | struct sway_container *focus, int x, int y) { | ||
35 | int text_width, text_height; | ||
36 | get_text_size(cairo, "monospace", &text_width, &text_height, | ||
37 | 1, false, "%s id:%zd '%s' %s %.fx%.f@%.f,%.f", | ||
38 | container_type_to_str(container->type), container->id, container->name, | ||
39 | layout_to_str(container->layout), | ||
40 | container->width, container->height, container->x, container->y); | ||
41 | cairo_save(cairo); | ||
42 | cairo_rectangle(cairo, x + 2, y, text_width - 2, text_height); | ||
43 | cairo_set_source_u32(cairo, 0xFFFFFFE0); | ||
44 | cairo_fill(cairo); | ||
45 | int height = text_height; | ||
46 | if (container->children) { | ||
47 | for (int i = 0; i < container->children->length; ++i) { | ||
48 | struct sway_container *child = container->children->items[i]; | ||
49 | if (child->parent == container) { | ||
50 | cairo_set_source_u32(cairo, 0x000000FF); | ||
51 | } else { | ||
52 | cairo_set_source_u32(cairo, 0xFF0000FF); | ||
53 | } | ||
54 | height += draw_container(cairo, child, focus, x + 10, y + height); | ||
55 | } | ||
56 | } | ||
57 | cairo_set_source_u32(cairo, 0xFFFFFFE0); | ||
58 | cairo_rectangle(cairo, x, y, 2, height); | ||
59 | cairo_fill(cairo); | ||
60 | cairo_restore(cairo); | ||
61 | cairo_move_to(cairo, x, y); | ||
62 | if (focus == container) { | ||
63 | cairo_set_source_u32(cairo, 0x0000FFFF); | ||
64 | } | ||
65 | pango_printf(cairo, "monospace", 1, false, "%s id:%zd '%s' %s %.fx%.f@%.f,%.f", | ||
66 | container_type_to_str(container->type), container->id, container->name, | ||
67 | layout_to_str(container->layout), | ||
68 | container->width, container->height, container->x, container->y); | ||
69 | return height; | ||
70 | } | ||
71 | |||
72 | bool enable_debug_tree = false; | ||
73 | |||
74 | void update_debug_tree() { | ||
75 | if (!enable_debug_tree) { | ||
76 | return; | ||
77 | } | ||
78 | |||
79 | int width = 640, height = 480; | ||
80 | for (int i = 0; i < root_container.children->length; ++i) { | ||
81 | struct sway_container *container = root_container.children->items[i]; | ||
82 | if (container->width > width) { | ||
83 | width = container->width; | ||
84 | } | ||
85 | if (container->height > height) { | ||
86 | height = container->height; | ||
87 | } | ||
88 | } | ||
89 | cairo_surface_t *surface = | ||
90 | cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); | ||
91 | cairo_t *cairo = cairo_create(surface); | ||
92 | PangoContext *pango = pango_cairo_create_context(cairo); | ||
93 | |||
94 | struct sway_seat *seat = NULL; | ||
95 | wl_list_for_each(seat, &input_manager->seats, link) { | ||
96 | break; | ||
97 | } | ||
98 | |||
99 | struct sway_container *focus = NULL; | ||
100 | if (seat != NULL) { | ||
101 | focus = seat_get_focus(seat); | ||
102 | } | ||
103 | cairo_set_source_u32(cairo, 0x000000FF); | ||
104 | draw_container(cairo, &root_container, focus, 0, 0); | ||
105 | |||
106 | cairo_surface_flush(surface); | ||
107 | struct wlr_renderer *renderer = wlr_backend_get_renderer(server.backend); | ||
108 | if (root_container.sway_root->debug_tree) { | ||
109 | wlr_texture_destroy(root_container.sway_root->debug_tree); | ||
110 | } | ||
111 | unsigned char *data = cairo_image_surface_get_data(surface); | ||
112 | int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); | ||
113 | struct wlr_texture *texture = wlr_texture_from_pixels(renderer, | ||
114 | WL_SHM_FORMAT_ARGB8888, stride, width, height, data); | ||
115 | root_container.sway_root->debug_tree = texture; | ||
116 | cairo_surface_destroy(surface); | ||
117 | g_object_unref(pango); | ||
118 | cairo_destroy(cairo); | ||
119 | } | ||