diff --git a/include/ipc-json.h b/include/ipc-json.h new file mode 100644 index 000000000..f90d801e4 --- /dev/null +++ b/include/ipc-json.h @@ -0,0 +1,13 @@ +#ifndef _SWAY_IPC_JSON_H +#define _SWAY_IPC_JSON_H + +#include +#include "config.h" +#include "container.h" + +json_object *ipc_json_get_version(); +json_object *ipc_json_describe_bar_config(struct bar_config *bar); +json_object *ipc_json_describe_container(swayc_t *c); +json_object *ipc_json_describe_container_recursive(swayc_t *c); + +#endif diff --git a/sway/CMakeLists.txt b/sway/CMakeLists.txt index 73df3b1bc..be63c9440 100644 --- a/sway/CMakeLists.txt +++ b/sway/CMakeLists.txt @@ -21,6 +21,7 @@ add_executable(sway handlers.c input.c input_state.c + ipc-json.c ipc-server.c layout.c main.c diff --git a/sway/container.c b/sway/container.c index 21538ab44..a7e465716 100644 --- a/sway/container.c +++ b/sway/container.c @@ -75,6 +75,30 @@ static void free_swayc(swayc_t *cont) { free(cont); } +static void update_root_geometry() { + int width = 0; + int height = 0; + swayc_t *child; + int child_width; + int child_height; + + for (int i = 0; i < root_container.children->length; ++i) { + child = root_container.children->items[i]; + child_width = child->width + child->x; + child_height = child->height + child->y; + if (child_width > width) { + width = child_width; + } + + if (child_height > height) { + height = child_height; + } + } + + root_container.width = width; + root_container.height = height; +} + // New containers swayc_t *new_output(wlc_handle handle) { @@ -167,6 +191,7 @@ swayc_t *new_output(wlc_handle handle) { } free(ws_name); + update_root_geometry(); return output; } @@ -361,7 +386,7 @@ void floating_view_sane_size(swayc_t *view) { view->desired_width = config->floating_maximum_width; } - sway_log(L_DEBUG, "Sane values for view to %d x %d @ %.f, %.f", + sway_log(L_DEBUG, "Sane values for view to %d x %d @ %.f, %.f", view->desired_width, view->desired_height, view->x, view->y); return; @@ -393,6 +418,7 @@ swayc_t *destroy_output(swayc_t *output) { } sway_log(L_DEBUG, "OUTPUT: Destroying output '%" PRIuPTR "'", output->handle); free_swayc(output); + update_root_geometry(); return &root_container; } diff --git a/sway/ipc-json.c b/sway/ipc-json.c new file mode 100644 index 000000000..46caad9ce --- /dev/null +++ b/sway/ipc-json.c @@ -0,0 +1,326 @@ +#include +#include +#include +#include "container.h" +#include "util.h" +#include "ipc-json.h" + +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 const char *ipc_json_border_description(swayc_t *c) { + const char *border; + + switch (c->border_type) { + case B_PIXEL: + border = "1pixel"; + break; + + case B_NORMAL: + border = "normal"; + break; + + case B_NONE: // fallthrough + default: + border = "none"; + break; + } + + return border; +} + +static const char *ipc_json_layout_description(swayc_t *c) { + const char *layout; + + switch (c->layout) { + case L_VERT: + layout = "splitv"; + break; + + case L_HORIZ: + layout = "splith"; + break; + + case L_TABBED: + layout = "tabbed"; + break; + + case L_STACKED: + layout = "stacked"; + break; + + case L_FLOATING: + layout = "floating"; + break; + + case L_NONE: // fallthrough + case L_LAYOUTS: // fallthrough; this should never happen, I'm just trying to silence compiler warnings + default: + layout = "null"; + break; + } + + return layout; +} + +static float ipc_json_child_percentage(swayc_t *c) { + float percent = 0; + swayc_t *parent = c->parent; + + if (parent) { + switch (parent->layout) { + case L_VERT: + percent = c->height / parent->height; + break; + + case L_HORIZ: + percent = c->width / parent->width; + break; + + case L_STACKED: // fallthrough + case L_TABBED: // fallthrough + percent = 1.0; + break; + + default: + break; + } + } + + return percent; +} + +static void ipc_json_describe_output(swayc_t *output, json_object *object) { + json_object_object_add(object, "active", json_object_new_boolean(true)); + json_object_object_add(object, "primary", json_object_new_boolean(false)); + json_object_object_add(object, "layout", json_object_new_string("output")); + 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; + bool focused = root_container.focused == workspace->parent && workspace->parent->focused == workspace; + + json_object_object_add(object, "num", json_object_new_int(num)); + json_object_object_add(object, "visible", json_object_new_boolean(workspace->visible)); + json_object_object_add(object, "focused", json_object_new_boolean(focused)); + json_object_object_add(object, "output", json_object_new_string((workspace->parent) ? workspace->parent->name : "null")); + json_object_object_add(object, "urgent", json_object_new_boolean(false)); + json_object_object_add(object, "type", json_object_new_string("workspace")); + json_object_object_add(object, "layout", json_object_new_string(ipc_json_layout_description(workspace))); +} + +static void ipc_json_describe_view(swayc_t *view, json_object *object) { + float percent = ipc_json_child_percentage(view); + + json_object_object_add(object, "border", json_object_new_string(ipc_json_border_description(view))); + json_object_object_add(object, "current_border_width", json_object_new_int(view->border_thickness)); + json_object_object_add(object, "percent", (percent > 0) ? json_object_new_double(percent) : json_object_new_string("null")); + // TODO: make urgency actually work once Sway supports it + json_object_object_add(object, "urgent", json_object_new_boolean(false)); + json_object_object_add(object, "focused", json_object_new_boolean(view->is_focused)); + json_object_object_add(object, "type", json_object_new_string((view->is_floating) ? "floating_con" : "con")); + json_object_object_add(object, "layout", json_object_new_string(ipc_json_layout_description(view))); + + if (view->class) { + json_object_object_add(object, "class", json_object_new_string(view->class)); + } + + if (view->app_id) { + json_object_object_add(object, "app_id", json_object_new_string(view->app_id)); + } +} + +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((int64_t)&c)); + json_object_object_add(object, "name", json_object_new_string(c->name)); + json_object_object_add(object, "rect", ipc_json_create_rect(c)); + + switch (c->type) { + case C_ROOT: + json_object_object_add(object, "type", json_object_new_string("root")); + break; + + case C_OUTPUT: + ipc_json_describe_output(c, object); + break; + + case C_CONTAINER: // fallthrough + case C_VIEW: + ipc_json_describe_view(c, object); + break; + + case C_WORKSPACE: + ipc_json_describe_workspace(c, object); + break; + + case C_TYPES: // fallthrough; this should never happen, I'm just trying to silence compiler warnings + default: + break; + } + + return object; +} + +json_object *ipc_json_get_version() { + json_object *version = json_object_new_object(); + +#if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE + char *full_version = calloc(strlen(SWAY_GIT_VERSION) + strlen(SWAY_GIT_BRANCH) + strlen(SWAY_VERSION_DATE) + 20, 1); + strcat(full_version, SWAY_GIT_VERSION); + strcat(full_version, " ("); + strcat(full_version, SWAY_VERSION_DATE); + strcat(full_version, ", branch \""); + strcat(full_version, SWAY_GIT_BRANCH); + strcat(full_version, "\")"); + + json_object_object_add(version, "human_readable", json_object_new_string(full_version)); + json_object_object_add(version, "variant", json_object_new_string("sway")); + // Todo once we actually release a version + json_object_object_add(version, "major", json_object_new_int(0)); + json_object_object_add(version, "minor", json_object_new_int(0)); + json_object_object_add(version, "patch", json_object_new_int(1)); +#else + json_object_object_add(version, "human_readable", json_object_new_string("version not found")); + json_object_object_add(version, "major", json_object_new_int(0)); + json_object_object_add(version, "minor", json_object_new_int(0)); + json_object_object_add(version, "patch", json_object_new_int(0)); +#endif + + return version; +} + +json_object *ipc_json_describe_bar_config(struct bar_config *bar) { + if (!sway_assert(bar, "Bar must not be NULL")) { + return NULL; + } + + json_object *json = json_object_new_object(); + json_object_object_add(json, "id", json_object_new_string(bar->id)); + json_object_object_add(json, "tray_output", NULL); + json_object_object_add(json, "mode", json_object_new_string(bar->mode)); + json_object_object_add(json, "hidden_state", json_object_new_string(bar->hidden_state)); + json_object_object_add(json, "modifier", json_object_new_string(get_modifier_name_by_mask(bar->modifier))); + switch (bar->position) { + case DESKTOP_SHELL_PANEL_POSITION_TOP: + json_object_object_add(json, "position", json_object_new_string("top")); + break; + case DESKTOP_SHELL_PANEL_POSITION_BOTTOM: + json_object_object_add(json, "position", json_object_new_string("bottom")); + break; + case DESKTOP_SHELL_PANEL_POSITION_LEFT: + json_object_object_add(json, "position", json_object_new_string("left")); + break; + case DESKTOP_SHELL_PANEL_POSITION_RIGHT: + json_object_object_add(json, "position", json_object_new_string("right")); + break; + } + json_object_object_add(json, "status_command", json_object_new_string(bar->status_command)); + json_object_object_add(json, "font", json_object_new_string((bar->font) ? bar->font : config->font)); + if (bar->separator_symbol) { + json_object_object_add(json, "separator_symbol", json_object_new_string(bar->separator_symbol)); + } + json_object_object_add(json, "bar_height", json_object_new_int(bar->height)); + json_object_object_add(json, "workspace_buttons", json_object_new_boolean(bar->workspace_buttons)); + json_object_object_add(json, "strip_workspace_numbers", json_object_new_boolean(bar->strip_workspace_numbers)); + json_object_object_add(json, "binding_mode_indicator", json_object_new_boolean(bar->binding_mode_indicator)); + json_object_object_add(json, "verbose", json_object_new_boolean(bar->verbose)); + json_object_object_add(json, "pango_markup", json_object_new_boolean(bar->pango_markup)); + + json_object *colors = json_object_new_object(); + json_object_object_add(colors, "background", json_object_new_string(bar->colors.background)); + json_object_object_add(colors, "statusline", json_object_new_string(bar->colors.statusline)); + json_object_object_add(colors, "separator", json_object_new_string(bar->colors.separator)); + + json_object_object_add(colors, "focused_workspace_border", json_object_new_string(bar->colors.focused_workspace_border)); + json_object_object_add(colors, "focused_workspace_bg", json_object_new_string(bar->colors.focused_workspace_bg)); + json_object_object_add(colors, "focused_workspace_text", json_object_new_string(bar->colors.focused_workspace_text)); + + json_object_object_add(colors, "inactive_workspace_border", json_object_new_string(bar->colors.inactive_workspace_border)); + json_object_object_add(colors, "inactive_workspace_bg", json_object_new_string(bar->colors.inactive_workspace_bg)); + json_object_object_add(colors, "inactive_workspace_text", json_object_new_string(bar->colors.inactive_workspace_text)); + + json_object_object_add(colors, "active_workspace_border", json_object_new_string(bar->colors.active_workspace_border)); + json_object_object_add(colors, "active_workspace_bg", json_object_new_string(bar->colors.active_workspace_bg)); + json_object_object_add(colors, "active_workspace_text", json_object_new_string(bar->colors.active_workspace_text)); + + json_object_object_add(colors, "urgent_workspace_border", json_object_new_string(bar->colors.urgent_workspace_border)); + json_object_object_add(colors, "urgent_workspace_bg", json_object_new_string(bar->colors.urgent_workspace_bg)); + json_object_object_add(colors, "urgent_workspace_text", json_object_new_string(bar->colors.urgent_workspace_text)); + + json_object_object_add(colors, "binding_mode_border", json_object_new_string(bar->colors.binding_mode_border)); + json_object_object_add(colors, "binding_mode_bg", json_object_new_string(bar->colors.binding_mode_bg)); + json_object_object_add(colors, "binding_mode_text", json_object_new_string(bar->colors.binding_mode_text)); + + json_object_object_add(json, "colors", colors); + + // Add outputs if defined + if (bar->outputs && bar->outputs->length > 0) { + json_object *outputs = json_object_new_array(); + int i; + for (i = 0; i < bar->outputs->length; ++i) { + const char *name = bar->outputs->items[i]; + json_object_array_add(outputs, json_object_new_string(name)); + } + json_object_object_add(json, "outputs", outputs); + } + + return json; +} + +json_object *ipc_json_describe_container_recursive(swayc_t *c) { + json_object *object = ipc_json_describe_container(c); + int i; + + json_object *floating = json_object_new_array(); + if (c->floating && c->floating->length > 0) { + for (i = 0; i < c->floating->length; ++i) { + json_object_array_add(floating, ipc_json_describe_container_recursive(c->floating->items[i])); + } + } + json_object_object_add(object, "floating_nodes", floating); + + json_object *children = json_object_new_array(); + if (c->children && c->children->length > 0) { + 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); + + json_object *unmanaged = json_object_new_array(); + if (c->unmanaged && c->unmanaged->length > 0) { + for (i = 0; i < c->unmanaged->length; ++i) { + json_object_array_add(unmanaged, ipc_json_describe_container_recursive(c->unmanaged->items[i])); + } + } + json_object_object_add(object, "unmanaged_nodes", unmanaged); + + if (c->type == C_ROOT) { + json_object *scratchpad_json = json_object_new_array(); + if (scratchpad->length > 0) { + for (i = 0; i < scratchpad->length; ++i) { + json_object_array_add(scratchpad_json, ipc_json_describe_container_recursive(scratchpad->items[i])); + } + } + json_object_object_add(object, "scratchpad", unmanaged); + } + + return object; +} diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 484d7e516..0729bfd50 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c @@ -10,10 +10,10 @@ #include #include #include -#include #include #include #include +#include "ipc-json.h" #include "ipc-server.h" #include "log.h" #include "config.h" @@ -53,7 +53,6 @@ void ipc_client_handle_command(struct ipc_client *client); bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length); void ipc_get_workspaces_callback(swayc_t *workspace, void *data); void ipc_get_outputs_callback(swayc_t *container, void *data); -json_object *ipc_json_describe_bar_config(struct bar_config *bar); void ipc_init(void) { ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); @@ -399,33 +398,21 @@ 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: { -#if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE - char *full_version = calloc(strlen(SWAY_GIT_VERSION) + strlen(SWAY_GIT_BRANCH) + strlen(SWAY_VERSION_DATE) + 20, 1); - strcat(full_version, SWAY_GIT_VERSION); - strcat(full_version, " ("); - strcat(full_version, SWAY_VERSION_DATE); - strcat(full_version, ", branch \""); - strcat(full_version, SWAY_GIT_BRANCH); - strcat(full_version, "\")"); - json_object *json = json_object_new_object(); - json_object_object_add(json, "human_readable", json_object_new_string(full_version)); - json_object_object_add(json, "variant", json_object_new_string("sway")); - // Todo once we actually release a version - json_object_object_add(json, "major", json_object_new_int(0)); - json_object_object_add(json, "minor", json_object_new_int(0)); - json_object_object_add(json, "patch", json_object_new_int(1)); -#else - json_object_object_add(json, "human_readable", json_object_new_string("version not found")); - json_object_object_add(json, "major", json_object_new_int(0)); - json_object_object_add(json, "minor", json_object_new_int(0)); - json_object_object_add(json, "patch", json_object_new_int(0)); -#endif - const char *json_string = json_object_to_json_string(json); + json_object *version = ipc_json_get_version(); + const char *json_string = json_object_to_json_string(version); ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); - json_object_put(json); // free - free(full_version); + json_object_put(version); // free goto exit_cleanup; } @@ -518,139 +505,18 @@ bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t pay return true; } -json_object *ipc_json_describe_workspace(swayc_t *workspace) { - if (!sway_assert(workspace, "Workspace must not be NULL")) { - return NULL; - } - - int num = isdigit(workspace->name[0]) ? atoi(workspace->name) : -1; - json_object *object = json_object_new_object(); - json_object *rect = json_object_new_object(); - json_object_object_add(rect, "x", json_object_new_int((int32_t) workspace->x)); - json_object_object_add(rect, "y", json_object_new_int((int32_t) workspace->y)); - json_object_object_add(rect, "width", json_object_new_int((int32_t) workspace->width)); - json_object_object_add(rect, "height", json_object_new_int((int32_t) workspace->height)); - - json_object_object_add(object, "num", json_object_new_int(num)); - json_object_object_add(object, "name", json_object_new_string(workspace->name)); - json_object_object_add(object, "visible", json_object_new_boolean(workspace->visible)); - bool focused = root_container.focused == workspace->parent && workspace->parent->focused == workspace; - json_object_object_add(object, "focused", json_object_new_boolean(focused)); - json_object_object_add(object, "rect", rect); - json_object_object_add(object, "output", json_object_new_string(workspace->parent ? workspace->parent->name : "null")); - json_object_object_add(object, "urgent", json_object_new_boolean(false)); - - return object; -} - void ipc_get_workspaces_callback(swayc_t *workspace, void *data) { if (workspace->type == C_WORKSPACE) { - json_object_array_add((json_object *)data, ipc_json_describe_workspace(workspace)); + json_object_array_add((json_object *)data, ipc_json_describe_container(workspace)); } } -json_object *ipc_json_describe_output(swayc_t *output) { - json_object *object = json_object_new_object(); - json_object *rect = json_object_new_object(); - json_object_object_add(rect, "x", json_object_new_int((int32_t) output->x)); - json_object_object_add(rect, "y", json_object_new_int((int32_t) output->y)); - json_object_object_add(rect, "width", json_object_new_int((int32_t) output->width)); - json_object_object_add(rect, "height", json_object_new_int((int32_t) output->height)); - - json_object_object_add(object, "name", json_object_new_string(output->name)); - json_object_object_add(object, "active", json_object_new_boolean(true)); - json_object_object_add(object, "primary", json_object_new_boolean(false)); - json_object_object_add(object, "rect", rect); - json_object_object_add(object, "current_workspace", - output->focused ? json_object_new_string(output->focused->name) : NULL); - - return object; -} - void ipc_get_outputs_callback(swayc_t *container, void *data) { if (container->type == C_OUTPUT) { - json_object_array_add((json_object *)data, ipc_json_describe_output(container)); + json_object_array_add((json_object *)data, ipc_json_describe_container(container)); } } -json_object *ipc_json_describe_bar_config(struct bar_config *bar) { - if (!sway_assert(bar, "Bar must not be NULL")) { - return NULL; - } - - json_object *json = json_object_new_object(); - json_object_object_add(json, "id", json_object_new_string(bar->id)); - json_object_object_add(json, "tray_output", NULL); - json_object_object_add(json, "mode", json_object_new_string(bar->mode)); - json_object_object_add(json, "hidden_state", json_object_new_string(bar->hidden_state)); - json_object_object_add(json, "modifier", json_object_new_string(get_modifier_name_by_mask(bar->modifier))); - switch (bar->position) { - case DESKTOP_SHELL_PANEL_POSITION_TOP: - json_object_object_add(json, "position", json_object_new_string("top")); - break; - case DESKTOP_SHELL_PANEL_POSITION_BOTTOM: - json_object_object_add(json, "position", json_object_new_string("bottom")); - break; - case DESKTOP_SHELL_PANEL_POSITION_LEFT: - json_object_object_add(json, "position", json_object_new_string("left")); - break; - case DESKTOP_SHELL_PANEL_POSITION_RIGHT: - json_object_object_add(json, "position", json_object_new_string("right")); - break; - } - json_object_object_add(json, "status_command", json_object_new_string(bar->status_command)); - json_object_object_add(json, "font", json_object_new_string(bar->font ? bar->font : config->font)); - if (bar->separator_symbol) { - json_object_object_add(json, "separator_symbol", json_object_new_string(bar->separator_symbol)); - } - json_object_object_add(json, "bar_height", json_object_new_int(bar->height)); - json_object_object_add(json, "workspace_buttons", json_object_new_boolean(bar->workspace_buttons)); - json_object_object_add(json, "strip_workspace_numbers", json_object_new_boolean(bar->strip_workspace_numbers)); - json_object_object_add(json, "binding_mode_indicator", json_object_new_boolean(bar->binding_mode_indicator)); - json_object_object_add(json, "verbose", json_object_new_boolean(bar->verbose)); - json_object_object_add(json, "pango_markup", json_object_new_boolean(bar->pango_markup)); - - json_object *colors = json_object_new_object(); - json_object_object_add(colors, "background", json_object_new_string(bar->colors.background)); - json_object_object_add(colors, "statusline", json_object_new_string(bar->colors.statusline)); - json_object_object_add(colors, "separator", json_object_new_string(bar->colors.separator)); - - json_object_object_add(colors, "focused_workspace_border", json_object_new_string(bar->colors.focused_workspace_border)); - json_object_object_add(colors, "focused_workspace_bg", json_object_new_string(bar->colors.focused_workspace_bg)); - json_object_object_add(colors, "focused_workspace_text", json_object_new_string(bar->colors.focused_workspace_text)); - - json_object_object_add(colors, "inactive_workspace_border", json_object_new_string(bar->colors.inactive_workspace_border)); - json_object_object_add(colors, "inactive_workspace_bg", json_object_new_string(bar->colors.inactive_workspace_bg)); - json_object_object_add(colors, "inactive_workspace_text", json_object_new_string(bar->colors.inactive_workspace_text)); - - json_object_object_add(colors, "active_workspace_border", json_object_new_string(bar->colors.active_workspace_border)); - json_object_object_add(colors, "active_workspace_bg", json_object_new_string(bar->colors.active_workspace_bg)); - json_object_object_add(colors, "active_workspace_text", json_object_new_string(bar->colors.active_workspace_text)); - - json_object_object_add(colors, "urgent_workspace_border", json_object_new_string(bar->colors.urgent_workspace_border)); - json_object_object_add(colors, "urgent_workspace_bg", json_object_new_string(bar->colors.urgent_workspace_bg)); - json_object_object_add(colors, "urgent_workspace_text", json_object_new_string(bar->colors.urgent_workspace_text)); - - json_object_object_add(colors, "binding_mode_border", json_object_new_string(bar->colors.binding_mode_border)); - json_object_object_add(colors, "binding_mode_bg", json_object_new_string(bar->colors.binding_mode_bg)); - json_object_object_add(colors, "binding_mode_text", json_object_new_string(bar->colors.binding_mode_text)); - - json_object_object_add(json, "colors", colors); - - // Add outputs if defined - if (bar->outputs && bar->outputs->length > 0) { - json_object *outputs = json_object_new_array(); - int i; - for (i = 0; i < bar->outputs->length; ++i) { - const char *name = bar->outputs->items[i]; - json_object_array_add(outputs, json_object_new_string(name)); - } - json_object_object_add(json, "outputs", outputs); - } - - return json; -} - void ipc_send_event(const char *json_string, enum ipc_command_type event) { int i; struct ipc_client *client; @@ -672,14 +538,14 @@ void ipc_event_workspace(swayc_t *old, swayc_t *new, const char *change) { json_object_object_add(obj, "change", json_object_new_string(change)); if (strcmp("focus", change) == 0) { if (old) { - json_object_object_add(obj, "old", ipc_json_describe_workspace(old)); + json_object_object_add(obj, "old", ipc_json_describe_container(old)); } else { json_object_object_add(obj, "old", NULL); } } if (new) { - json_object_object_add(obj, "current", ipc_json_describe_workspace(new)); + json_object_object_add(obj, "current", ipc_json_describe_container(new)); } else { json_object_object_add(obj, "current", NULL); } diff --git a/sway/layout.c b/sway/layout.c index 952bcf1c1..27760f35c 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -23,6 +23,7 @@ int min_sane_w = 100; void init_layout(void) { root_container.type = C_ROOT; root_container.layout = L_NONE; + root_container.name = strdup("root"); root_container.children = create_list(); root_container.handle = -1; root_container.visible = true;