diff options
Diffstat (limited to 'sway/layout.c')
-rw-r--r-- | sway/layout.c | 140 |
1 files changed, 85 insertions, 55 deletions
diff --git a/sway/layout.c b/sway/layout.c index 035fea34..bc12b9b1 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -20,7 +20,8 @@ void init_layout(void) { root_container.handle = -1; } -static int index_child(swayc_t *parent, swayc_t *child) { +static int index_child(swayc_t *child) { + swayc_t *parent = child->parent; int i; for (i = 0; i < parent->children->length; ++i) { if (parent->children->items[i] == child) { @@ -54,7 +55,7 @@ void add_floating(swayc_t *ws, swayc_t *child) { swayc_t *add_sibling(swayc_t *sibling, swayc_t *child) { swayc_t *parent = sibling->parent; - int i = index_child(parent, sibling); + int i = index_child(sibling); if (i == parent->children->length) { --i; } @@ -68,17 +69,65 @@ swayc_t *replace_child(swayc_t *child, swayc_t *new_child) { if (parent == NULL) { return NULL; } - int i = index_child(parent, child); + int i = index_child(child); parent->children->items[i] = new_child; new_child->parent = child->parent; + // Set parent for new child if (child->parent->focused == child) { child->parent->focused = new_child; } child->parent = NULL; + // Set geometry for new child + new_child->x = child->x; + new_child->y = child->y; + new_child->width = child->width; + new_child->height = child->height; + // set child geometry to 0 + child->x = 0; + child->y = 0; + child->width = 0; + child->height = 0; return parent; } +void swap_container(swayc_t *a, swayc_t *b) { + //TODO doesnt handle floating <-> tiling swap + if (!sway_assert(a&&b, "%s: parameters must be non null",__func__) || + !sway_assert(a->parent && b->parent, "%s: containers must have parents",__func__)) { + return; + } + size_t a_index = index_child(a); + size_t b_index = index_child(b); + swayc_t *a_parent = a->parent; + swayc_t *b_parent = b->parent; + // Swap the pointers + a_parent->children->items[a_index] = b; + b_parent->children->items[b_index] = a; + a->parent = b_parent; + b->parent = a_parent; + if (a_parent->focused == a) { + a_parent->focused = b; + } + // dont want to double switch + if (b_parent->focused == b && a_parent != b_parent) { + b_parent->focused = a; + } + // and their geometry + double x = a->x; + double y = a->y; + double w = a->width; + double h = a->height; + a->x = b->x; + a->y = b->y; + a->width = b->width; + a->height = b->height; + b->x = x; + b->y = y; + b->width = w; + b->height = h; +} + swayc_t *remove_child(swayc_t *child) { int i; swayc_t *parent = child->parent; @@ -154,6 +203,30 @@ void move_container(swayc_t *container,swayc_t* root,enum movement_direction dir } +void update_geometry(swayc_t *container) { + if (container->type != C_VIEW) { + return; + } + struct wlc_geometry geometry = { + .origin = { + .x = container->x + (container->is_floating ? 0 : container->gaps / 2), + .y = container->y + (container->is_floating ? 0 : container->gaps / 2) + }, + .size = { + .w = container->width - (container->is_floating ? 0 : container->gaps), + .h = container->height - (container->is_floating ? 0 : container->gaps) + } + }; + if (swayc_is_fullscreen(container)) { + swayc_t *parent = swayc_parent_by_type(container, C_OUTPUT); + geometry.origin.x = 0; + geometry.origin.y = 0; + geometry.size.w = parent->width; + geometry.size.h = parent->height; + } + wlc_view_set_geometry(container->handle, 0, &geometry); + return; +} void arrange_windows(swayc_t *container, double width, double height) { int i; @@ -189,31 +262,11 @@ void arrange_windows(swayc_t *container, double width, double height) { return; case C_VIEW: { - struct wlc_geometry geometry = { - .origin = { - .x = container->x + container->gaps / 2, - .y = container->y + container->gaps / 2 - }, - .size = { - .w = width - container->gaps, - .h = height - container->gaps - } - }; - if (swayc_is_fullscreen(container)) { - swayc_t *parent = swayc_parent_by_type(container, C_OUTPUT); - geometry.origin.x = 0; - geometry.origin.y = 0; - geometry.size.w = parent->width; - geometry.size.h = parent->height; - wlc_view_set_geometry(container->handle, 0, &geometry); - wlc_view_bring_to_front(container->handle); - } else { - wlc_view_set_geometry(container->handle, 0, &geometry); - container->width = width; - container->height = height; - } - sway_log(L_DEBUG, "Set view to %d x %d @ %d, %d", geometry.size.w, geometry.size.h, - geometry.origin.x, geometry.origin.y); + container->width = width; + container->height = height; + update_geometry(container); + sway_log(L_DEBUG, "Set view to %.f x %.f @ %.f, %.f", container->width, + container->height, container->x, container->y); } return; default: @@ -287,35 +340,12 @@ void arrange_windows(swayc_t *container, double width, double height) { for (i = 0; i < container->floating->length; ++i) { swayc_t *view = container->floating->items[i]; if (view->type == C_VIEW) { - // Set the geometry - struct wlc_geometry geometry = { - .origin = { - .x = view->x, - .y = view->y - }, - .size = { - .w = view->width, - .h = view->height - } - }; + update_geometry(view); if (swayc_is_fullscreen(view)) { - swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT); - geometry.origin.x = 0; - geometry.origin.y = 0; - geometry.size.w = parent->width; - geometry.size.h = parent->height; - wlc_view_set_geometry(view->handle, 0, &geometry); wlc_view_bring_to_front(view->handle); - } else { - wlc_view_set_geometry(view->handle, 0, &geometry); - // Bring the views to the front in order of the list, the list - // will be kept up to date so that more recently focused views - // have higher indexes - // This is conditional on there not being a fullscreen view in the workspace - if (!container->focused - || !swayc_is_fullscreen(container->focused)) { - wlc_view_bring_to_front(view->handle); - } + } else if (!container->focused + || !swayc_is_fullscreen(container->focused)) { + wlc_view_bring_to_front(view->handle); } } } |