labwc/src/debug.c

193 lines
4.5 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0-only
#include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_scene.h>
#include "common/scene-helpers.h"
#include "labwc.h"
#include "node.h"
2022-11-26 16:13:09 -05:00
#include "ssd.h"
#include "view.h"
2022-02-22 19:29:14 +01:00
#define HEADER_CHARS "------------------------------"
2022-02-22 19:29:14 +01:00
#define INDENT_SIZE 3
#define IGNORE_SSD true
#define IGNORE_MENU true
#define LEFT_COL_SPACE 35
static struct view *last_view;
2022-02-22 19:29:14 +01:00
static const char *
get_node_type(struct wlr_scene_node *node)
{
switch (node->type) {
case WLR_SCENE_NODE_TREE:
if (!node->parent) {
return "root";
}
return "tree";
case WLR_SCENE_NODE_RECT:
return "rect";
case WLR_SCENE_NODE_BUFFER:
if (lab_wlr_surface_from_node(node)) {
return "surface";
}
return "buffer";
}
return "error";
}
2022-02-22 19:29:14 +01:00
static const char *
get_layer_name(uint32_t layer)
{
switch (layer) {
case ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND:
2022-02-22 19:29:14 +01:00
return "layer-background";
case ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM:
2022-02-22 19:29:14 +01:00
return "layer-bottom";
case ZWLR_LAYER_SHELL_V1_LAYER_TOP:
2022-02-22 19:29:14 +01:00
return "layer-top";
case ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY:
2022-02-22 19:29:14 +01:00
return "layer-overlay";
default:
abort();
}
}
2022-02-22 19:29:14 +01:00
static const char *
get_view_part(struct view *view, struct wlr_scene_node *node)
{
2022-02-22 19:29:14 +01:00
if (view && node == &view->scene_tree->node) {
return "view";
}
if (view && node == view->scene_node) {
return "view->scene_node";
}
2022-11-26 16:13:09 -05:00
if (view) {
return ssd_debug_get_node_name(view->ssd, node);
2022-02-22 19:29:14 +01:00
}
return NULL;
}
2022-02-22 19:29:14 +01:00
static const char *
get_special(struct server *server, struct wlr_scene_node *node)
2022-02-22 19:29:14 +01:00
{
if (node == &server->scene->tree.node) {
2022-02-22 19:29:14 +01:00
return "server->scene";
}
if (node == &server->menu_tree->node) {
return "server->menu_tree";
}
2022-06-17 02:53:08 +02:00
if (node == &server->view_tree->node) {
return "server->view_tree";
}
if (node == &server->view_tree_always_on_top->node) {
return "server->view_tree_always_on_top";
}
if (node->parent == server->view_tree) {
/* Add node_descriptor just to get the name here? */
return "workspace";
}
if (node->parent == &server->scene->tree) {
2022-02-22 19:29:14 +01:00
struct output *output;
wl_list_for_each(output, &server->outputs, link) {
if (node == &output->osd_tree->node) {
return "output->osd_tree";
}
if (node == &output->layer_popup_tree->node) {
return "output->popup_tree";
}
2022-02-22 19:29:14 +01:00
for (int i = 0; i < 4; i++) {
if (node == &output->layer_tree[i]->node) {
return get_layer_name(i);
}
}
}
}
2022-02-22 19:29:14 +01:00
#if HAVE_XWAYLAND
if (node == &server->unmanaged_tree->node) {
return "server->unmanaged_tree";
}
#endif
2022-06-17 02:53:08 +02:00
struct wlr_scene_tree *grand_parent =
node->parent ? node->parent->node.parent : NULL;
if (grand_parent == server->view_tree && node->data) {
last_view = node_view_from_node(node);
2022-04-09 01:16:09 +02:00
}
if (node->parent == server->view_tree_always_on_top && node->data) {
last_view = node_view_from_node(node);
2022-02-22 19:29:14 +01:00
}
const char *view_part = get_view_part(last_view, node);
2022-02-22 19:29:14 +01:00
if (view_part) {
return view_part;
}
return get_node_type(node);
2022-02-22 19:29:14 +01:00
}
2022-02-19 02:05:38 +01:00
2022-02-22 19:29:14 +01:00
struct pad {
uint8_t left;
uint8_t right;
};
2022-02-19 02:05:38 +01:00
2022-02-22 19:29:14 +01:00
static struct pad
get_center_padding(const char *text, uint8_t max_width)
{
struct pad pad;
size_t text_len = strlen(text);
pad.left = (double)(max_width - text_len) / 2 + 0.5f;
pad.right = max_width - pad.left - text_len;
return pad;
}
static void
dump_tree(struct server *server, struct wlr_scene_node *node,
int pos, int x, int y)
{
const char *type = get_special(server, node);
2022-02-22 19:29:14 +01:00
if (pos) {
printf("%*c+-- ", pos, ' ');
} else {
struct pad node_pad = get_center_padding("Node", 16);
printf(" %*c %4s %4s %*c%s\n", LEFT_COL_SPACE + 4, ' ',
"X", "Y", node_pad.left, ' ', "Node");
printf(" %*c %.4s %.4s %.16s\n", LEFT_COL_SPACE + 4, ' ',
HEADER_CHARS, HEADER_CHARS, HEADER_CHARS);
printf(" ");
}
int padding = LEFT_COL_SPACE - pos - strlen(type);
if (!pos) {
padding += 3;
}
printf("%s %*c %4d %4d [%p]\n", type, padding, ' ', x, y, node);
if ((IGNORE_MENU && node == &server->menu_tree->node)
|| (IGNORE_SSD && last_view
&& ssd_debug_is_root_node(last_view->ssd, node))) {
2022-02-22 19:29:14 +01:00
printf("%*c%s\n", pos + 4 + INDENT_SIZE, ' ', "<skipping children>");
return;
}
if (node->type == WLR_SCENE_NODE_TREE) {
struct wlr_scene_node *child;
struct wlr_scene_tree *tree = lab_scene_tree_from_node(node);
wl_list_for_each(child, &tree->children, link) {
dump_tree(server, child, pos + INDENT_SIZE,
x + child->x, y + child->y);
}
2022-02-22 19:29:14 +01:00
}
}
void
debug_dump_scene(struct server *server)
{
printf("\n");
dump_tree(server, &server->scene->tree.node, 0, 0, 0);
2022-02-22 19:29:14 +01:00
printf("\n");
/*
* Reset last_view so we don't access a
* potentially free'd pointer on the next call
*/
last_view = NULL;
}