i3Screen *screen;
int destination_y = (direction == D_UP ? (container->y - 1) : (container->y + container->height + 1));
if ((screen = get_screen_containing(container->x, destination_y)) == NULL) {
- LOG("Not possible, no screen found.\n");
- return;
+ LOG("Wrapping screen around vertically\n");
+ /* No screen found? Then wrap */
+ screen = get_screen_most((direction == D_UP ? D_DOWN : D_UP));
}
t_ws = &(workspaces[screen->current_workspace]);
new_row = (direction == D_UP ? (t_ws->rows - 1) : 0);
- /* Bounds checking */
- if (new_col >= t_ws->cols)
- new_col = (t_ws->cols - 1);
- if (new_row >= t_ws->rows)
- new_row = (t_ws->rows - 1);
}
} else if (direction == D_LEFT || direction == D_RIGHT) {
if (direction == D_RIGHT && cell_exists(current_col+1, current_row))
i3Screen *screen;
int destination_x = (direction == D_LEFT ? (container->x - 1) : (container->x + container->width + 1));
if ((screen = get_screen_containing(destination_x, container->y)) == NULL) {
- LOG("Not possible, no screen found.\n");
- return;
+ LOG("Wrapping screen around horizontally\n");
+ screen = get_screen_most((direction == D_LEFT ? D_RIGHT : D_LEFT));
}
t_ws = &(workspaces[screen->current_workspace]);
new_col = (direction == D_LEFT ? (t_ws->cols - 1) : 0);
- /* Bounds checking */
- if (new_col >= t_ws->cols)
- new_col = (t_ws->cols - 1);
- if (new_row >= t_ws->rows)
- new_row = (t_ws->rows - 1);
}
} else {
LOG("direction unhandled\n");
return;
}
+ /* Bounds checking */
+ if (new_col >= t_ws->cols)
+ new_col = (t_ws->cols - 1);
+ if (new_row >= t_ws->rows)
+ new_row = (t_ws->rows - 1);
+
if (t_ws->table[new_col][new_row]->currently_focused != NULL)
set_focus(conn, t_ws->table[new_col][new_row]->currently_focused);
}
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
+#include <assert.h>
#include <xcb/xcb.h>
#include <xcb/xinerama.h>
return NULL;
}
+/*
+ * Gets the screen which is the last one in the given direction, for example the screen
+ * on the most bottom when direction == D_DOWN, the screen most right when direction == D_RIGHT
+ * and so on.
+ *
+ * This function always returns a screen.
+ *
+ */
+i3Screen *get_screen_most(direction_t direction) {
+ i3Screen *screen, *candidate = NULL;
+ int position = 0;
+ TAILQ_FOREACH(screen, virtual_screens, screens) {
+ /* Repeated calls of WIN determine the winner of the comparison */
+ #define WIN(variable, condition) \
+ if (variable condition) { \
+ candidate = screen; \
+ position = variable; \
+ } \
+ break;
+
+ switch (direction) {
+ case D_UP:
+ WIN(screen->rect.y, <= position);
+ case D_DOWN:
+ WIN(screen->rect.y, >= position);
+ case D_LEFT:
+ WIN(screen->rect.x, <= position);
+ case D_RIGHT:
+ WIN(screen->rect.x, >= position);
+ }
+ }
+
+ assert(candidate != NULL);
+
+ return candidate;
+}
+
/*
* Fills virtual_screens with exactly one screen with width/height of the whole X server.
*