swayfx/sway/movement.c
2015-08-16 14:47:08 -04:00

71 lines
1.7 KiB
C

#include <stdlib.h>
#include <stdbool.h>
#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;
}
}
}
}