From 19df2e590602abe0b5e1b53bc11debdb37be3fbe Mon Sep 17 00:00:00 2001 From: Brian Ashworth Date: Wed, 6 Mar 2019 00:33:10 -0500 Subject: [PATCH] ipc: change {,deco_}rect to match i3 This fixes the `deco_rect` and `rect` properties in the IPC responses to match i3's behavior. `deco_rect` should be relative to the parent node, not the current node. This also takes tabbed and stacked decorations into account and will calculate `deco_rect` for all containers since tabbed and stacked child containers will have decorations. `rect` should exclude the window decorations. --- sway/ipc-json.c | 51 +++++++++++++++++++++++++++++++++++++-------- sway/sway-ipc.7.scd | 5 +++-- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 125df387..c008f241 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -350,6 +350,38 @@ static void ipc_json_describe_workspace(struct sway_workspace *workspace, json_object_object_add(object, "floating_nodes", floating_array); } +static void get_deco_rect(struct sway_container *c, struct wlr_box *deco_rect) { + enum sway_container_layout parent_layout = container_parent_layout(c); + if (parent_layout != L_TABBED && parent_layout != L_STACKED && + c->current.border != B_NORMAL) { + deco_rect->x = deco_rect->y = deco_rect->width = deco_rect->height = 0; + return; + } + + if (c->parent) { + deco_rect->x = c->x - c->parent->x; + deco_rect->y = c->y - c->parent->y; + } else { + deco_rect->x = c->x - c->workspace->x; + deco_rect->y = c->y - c->workspace->y; + } + deco_rect->width = c->width; + deco_rect->height = container_titlebar_height(); + + if (parent_layout == L_TABBED) { + deco_rect->width = c->parent + ? c->parent->width / c->parent->children->length + : c->workspace->width / c->workspace->tiling->length; + deco_rect->x += deco_rect->width * container_sibling_index(c); + } else if (container_parent_layout(c) == L_STACKED) { + if (!c->view) { + size_t siblings = container_get_siblings(c)->length; + deco_rect->y -= deco_rect->height * siblings; + } + deco_rect->y += deco_rect->height * container_sibling_index(c); + } +} + static void ipc_json_describe_view(struct sway_container *c, json_object *object) { json_object_object_add(object, "pid", json_object_new_int(c->view->pid)); @@ -377,15 +409,6 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object json_object_object_add(object, "window_rect", ipc_json_create_rect(&window_box)); - struct wlr_box deco_box = {0, 0, 0, 0}; - - if (c->current.border == B_NORMAL) { - deco_box.width = c->width; - deco_box.height = c->content_y - c->y; - } - - json_object_object_add(object, "deco_rect", ipc_json_create_rect(&deco_box)); - struct wlr_box geometry = {0, 0, c->view->natural_width, c->view->natural_height}; json_object_object_add(object, "geometry", ipc_json_create_rect(&geometry)); @@ -465,6 +488,10 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o json_object_new_int(c->current.border_thickness)); json_object_object_add(object, "floating_nodes", json_object_new_array()); + struct wlr_box deco_box = {0, 0, 0, 0}; + get_deco_rect(c, &deco_box); + json_object_object_add(object, "deco_rect", ipc_json_create_rect(&deco_box)); + if (c->view) { ipc_json_describe_view(c, object); } @@ -505,6 +532,12 @@ json_object *ipc_json_describe_node(struct sway_node *node) { struct wlr_box box; node_get_box(node, &box); + if (node->type == N_CONTAINER) { + struct wlr_box deco_rect = {0, 0, 0, 0}; + get_deco_rect(node->sway_container, &deco_rect); + box.y += deco_rect.height; + box.height -= deco_rect.height; + } json_object *focus = json_object_new_array(); struct focus_inactive_data data = { diff --git a/sway/sway-ipc.7.scd b/sway/sway-ipc.7.scd index d598a54f..6b400453 100644 --- a/sway/sway-ipc.7.scd +++ b/sway/sway-ipc.7.scd @@ -314,14 +314,15 @@ node and will have the following properties: and other special nodes such as the scratchpad |- rect : object -: The absolute geometry of the node +: The absolute geometry of the node. The window decorations are excluded from + this, but borders are included. |- window_rect : object : The geometry of the contents inside the node. The window decorations are excluded from this calculation, but borders are included. |- deco_rect : object -: The geometry of the decorations inside the node +: The geometry of the decorations for the node relative to the parent node |- geometry : object : The natural geometry of the contents if it were to size itself