diff --git a/include/sway/ipc-json.h b/include/sway/ipc-json.h index 5bfddcba9..9986c399f 100644 --- a/include/sway/ipc-json.h +++ b/include/sway/ipc-json.h @@ -1,7 +1,10 @@ #ifndef _SWAY_IPC_JSON_H #define _SWAY_IPC_JSON_H #include +#include "sway/container.h" json_object *ipc_json_get_version(); +json_object *ipc_json_describe_container_recursive(swayc_t *c); + #endif diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 6fcb91fa4..2e774a964 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -1,6 +1,11 @@ #include #include +#include +#include "log.h" #include "sway/ipc-json.h" +#include "sway/container.h" +#include +#include json_object *ipc_json_get_version() { int major = 0, minor = 0, patch = 0; @@ -16,3 +21,89 @@ json_object *ipc_json_get_version() { return version; } + +static json_object *ipc_json_create_rect(swayc_t *c) { + json_object *rect = json_object_new_object(); + + json_object_object_add(rect, "x", json_object_new_int((int32_t)c->x)); + json_object_object_add(rect, "y", json_object_new_int((int32_t)c->y)); + json_object_object_add(rect, "width", json_object_new_int((int32_t)c->width)); + json_object_object_add(rect, "height", json_object_new_int((int32_t)c->height)); + + return rect; +} + +static void ipc_json_describe_root(swayc_t *root, json_object *object) { + json_object_object_add(object, "type", json_object_new_string("root")); + json_object_object_add(object, "layout", json_object_new_string("splith")); +} + +static void ipc_json_describe_output(swayc_t *output, json_object *object) { + json_object_object_add(object, "type", json_object_new_string("output")); + json_object_object_add(object, "current_workspace", + (output->focused) ? json_object_new_string(output->focused->name) : NULL); +} + +static void ipc_json_describe_workspace(swayc_t *workspace, json_object *object) { + int num = (isdigit(workspace->name[0])) ? atoi(workspace->name) : -1; + + json_object_object_add(object, "num", json_object_new_int(num)); + json_object_object_add(object, "output", (workspace->parent) ? json_object_new_string(workspace->parent->name) : NULL); + json_object_object_add(object, "type", json_object_new_string("workspace")); +} + +static void ipc_json_describe_view(swayc_t *c, json_object *object) { + json_object_object_add(object, "name", (c->name) ? json_object_new_string(c->name) : NULL); +} + +json_object *ipc_json_describe_container(swayc_t *c) { + if (!(sway_assert(c, "Container must not be null."))) { + return NULL; + } + + json_object *object = json_object_new_object(); + + json_object_object_add(object, "id", json_object_new_int((int)c->id)); + json_object_object_add(object, "name", (c->name) ? json_object_new_string(c->name) : NULL); + json_object_object_add(object, "rect", ipc_json_create_rect(c)); + + switch (c->type) { + case C_ROOT: + ipc_json_describe_root(c, object); + break; + + case C_OUTPUT: + ipc_json_describe_output(c, object); + break; + + case C_CONTAINER: + case C_VIEW: + ipc_json_describe_view(c, object); + break; + + case C_WORKSPACE: + ipc_json_describe_workspace(c, object); + break; + + case C_TYPES: + default: + break; + } + + return object; +} + +json_object *ipc_json_describe_container_recursive(swayc_t *c) { + json_object *object = ipc_json_describe_container(c); + int i; + + json_object *children = json_object_new_array(); + if (c->type != C_VIEW && c->children) { + for (i = 0; i < c->children->length; ++i) { + json_object_array_add(children, ipc_json_describe_container_recursive(c->children->items[i])); + } + } + json_object_object_add(object, "nodes", children); + + return object; +} diff --git a/sway/ipc-server.c b/sway/ipc-server.c index f3a6469ba..71f8dddd6 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c @@ -343,6 +343,16 @@ void ipc_client_handle_command(struct ipc_client *client) { goto exit_cleanup; } + case IPC_GET_TREE: + { + json_object *tree = + ipc_json_describe_container_recursive(&root_container); + const char *json_string = json_object_to_json_string(tree); + ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); + json_object_put(tree); + goto exit_cleanup; + } + case IPC_GET_VERSION: { json_object *version = ipc_json_get_version();