#include #include #include "list.h" #include "log.h" #include "layout.h" #include "movement.h" bool move_focus(enum movement_direction direction) { swayc_t *current = get_focused_container(&root_container); swayc_t *parent = current->parent; if (direction == MOVE_PARENT) { if (parent->type == C_OUTPUT) { sway_log(L_DEBUG, "Focus cannot move to parent"); return false; } else { sway_log(L_DEBUG, "Moving focus away from %p to %p", current, parent); unfocus_all(parent->parent); focus_view(parent); return true; } } while (true) { sway_log(L_DEBUG, "Moving focus away from %p", current); // Test if we can even make a difference here bool can_move = false; int diff = 0; if (direction == MOVE_LEFT || direction == MOVE_RIGHT) { if (parent->layout == L_HORIZ || parent->type == C_ROOT) { can_move = true; diff = direction == MOVE_LEFT ? -1 : 1; } } else { if (parent->layout == L_VERT) { can_move = true; diff = direction == MOVE_UP ? -1 : 1; } } sway_log(L_DEBUG, "Can move? %s", can_move ? "yes" : "no"); if (can_move) { int i; for (i = 0; i < parent->children->length; ++i) { swayc_t *child = parent->children->items[i]; if (child == current) { break; } } int desired = i + diff; sway_log(L_DEBUG, "Moving from %d to %d", i, desired); if (desired < 0 || desired >= parent->children->length) { can_move = false; } else { unfocus_all(&root_container); focus_view(parent->children->items[desired]); return true; } } if (!can_move) { sway_log(L_DEBUG, "Can't move at current level, moving up tree"); current = parent; parent = parent->parent; if (!parent) { // Nothing we can do return false; } } } }