void swap_container(swayc_t *a, swayc_t *b) { if (!sway_assert(a&&b, "parameters must be non null") || !sway_assert(a->parent && b->parent, "containers must have parents")) { 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 if (a->is_floating) { a_parent->floating->items[a_index] = b; } else { a_parent->children->items[a_index] = b; } if (b->is_floating) { b_parent->floating->items[b_index] = a; } else { b_parent->children->items[b_index] = a; } a->parent = b_parent; b->parent = a_parent; if (a_parent->focused == a) { a_parent->focused = b; } // don't want to double switch if (b_parent->focused == b && a_parent != b_parent) { b_parent->focused = a; } }
swayc_t *replace_child(swayc_t *child, swayc_t *new_child) { swayc_t *parent = child->parent; if (parent == NULL) { return NULL; } int i = index_child(child); if (child->is_floating) { parent->floating->items[i] = new_child; } else { parent->children->items[i] = new_child; } // Set parent and focus for new_child new_child->parent = child->parent; 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; // reset geometry for child child->width = 0; child->height = 0; // deactivate child if (child->type == C_VIEW) { wlc_view_set_state(child->handle, WLC_BIT_ACTIVATED, false); } return parent; }
swayc_t *add_sibling(swayc_t *sibling, swayc_t *child) { swayc_t *parent = sibling->parent; int i = index_child(sibling); list_insert(parent->children, i+1, child); child->parent = parent; return child->parent; }
swayc_t *add_sibling(swayc_t *sibling, swayc_t *child) { swayc_t *parent = sibling->parent; int i = index_child(parent, sibling); if (i == parent->children->length) { --i; } list_insert(parent->children, i+1, child); child->parent = parent; return child->parent; }
swayc_t *add_sibling(swayc_t *fixed, swayc_t *active) { swayc_t *parent = fixed->parent; int i = index_child(fixed); if (fixed->is_floating) { list_insert(parent->floating, i + 1, active); } else { list_insert(parent->children, i + 1, active); } active->parent = parent; // focus new child parent->focused = active; return active->parent; }
swayc_t *replace_child(swayc_t *child, swayc_t *new_child) { swayc_t *parent = child->parent; if (parent == NULL) { return NULL; } int i = index_child(parent, child); parent->children->items[i] = new_child; new_child->parent = child->parent; if (child->parent->focused == child) { child->parent->focused = new_child; } child->parent = NULL; return parent; }
void move_container(swayc_t *container, enum movement_direction dir) { enum swayc_layouts layout; if (container->is_floating || (container->type != C_VIEW && container->type != C_CONTAINER)) { return; } if (dir == MOVE_UP || dir == MOVE_DOWN) { layout = L_VERT; } else if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { layout = L_HORIZ; } else { return; } swayc_t *parent = container->parent; swayc_t *child = container; bool ascended = false; while (true) { sway_log(L_DEBUG, "container:%p, parent:%p, child %p,", container,parent,child); if (parent->layout == layout || (parent->layout == L_TABBED && layout == L_HORIZ) || (parent->layout == L_STACKED && layout == L_VERT)) { int diff; // If it has ascended (parent has moved up), no container is removed // so insert it at index, or index+1. // if it has not, the moved container is removed, so it needs to be // inserted at index-1, or index+1 if (ascended) { diff = dir == MOVE_LEFT || dir == MOVE_UP ? 0 : 1; } else { diff = dir == MOVE_LEFT || dir == MOVE_UP ? -1 : 1; } int desired = index_child(child) + diff; // when it has ascended, legal insertion position is 0:len // when it has not, legal insertion position is 0:len-1 if (desired >= 0 && desired - ascended < parent->children->length) { if (!ascended) { child = parent->children->items[desired]; // Move container into sibling container if (child->type == C_CONTAINER) { parent = child; // Insert it in first/last if matching layout, otherwise // inesrt it next to focused container if (parent->layout == layout || (parent->layout == L_TABBED && layout == L_HORIZ) || (parent->layout == L_STACKED && layout == L_VERT)) { desired = (diff < 0) * parent->children->length; } else { desired = index_child(child->focused); } //reset geometry container->width = container->height = 0; } } swayc_t *old_parent = remove_child(container); insert_child(parent, container, desired); destroy_container(old_parent); sway_log(L_DEBUG,"Moving to %p %d",parent, desired); break; } } // Change parent layout if we need to if (parent->children->length == 1 && parent->layout != layout) { parent->layout = layout; continue; } if (parent->type == C_WORKSPACE) { // We simply cannot move any further. if (parent->layout == layout) { break; } // Create container around workspace to insert child into parent = new_container(parent, layout); } ascended = true; child = parent; parent = child->parent; } arrange_windows(parent->parent, -1, -1); set_focused_container_for(parent->parent, container); }