+#undef I3__FILE__
+#define I3__FILE__ "randr.c"
/*
* vim:ts=4:sw=4:expandtab
*
*
*/
Output *get_output_most(direction_t direction, Output *current) {
- Output *output, *candidate = NULL;
- int position = 0;
- TAILQ_FOREACH(output, &outputs, outputs) {
- if (!output->active)
- continue;
-
- /* Repeated calls of WIN determine the winner of the comparison */
- #define WIN(variable, condition) \
- if (variable condition) { \
- candidate = output; \
- position = variable; \
- } \
- break;
-
- if (((direction == D_UP) || (direction == D_DOWN)) &&
- (current->rect.x != output->rect.x))
- continue;
-
- if (((direction == D_LEFT) || (direction == D_RIGHT)) &&
- (current->rect.y != output->rect.y))
- continue;
-
- switch (direction) {
- case D_UP:
- WIN(output->rect.y, <= position);
- case D_DOWN:
- WIN(output->rect.y, >= position);
- case D_LEFT:
- WIN(output->rect.x, <= position);
- case D_RIGHT:
- WIN(output->rect.x, >= position);
- }
- }
-
- assert(candidate != NULL);
-
- return candidate;
+ Output *best = get_output_next(direction, current, FARTHEST_OUTPUT);
+ if (!best)
+ best = current;
+ DLOG("current = %s, best = %s\n", current->name, best->name);
+ return best;
}
/*
* Gets the output which is the next one in the given direction.
*
*/
-Output *get_output_next(direction_t direction, Output *current) {
- Output *output, *candidate = NULL;
-
+Output *get_output_next(direction_t direction, Output *current, output_close_far_t close_far) {
+ Rect *cur = &(current->rect),
+ *other;
+ Output *output,
+ *best = NULL;
TAILQ_FOREACH(output, &outputs, outputs) {
if (!output->active)
continue;
- if (((direction == D_UP) || (direction == D_DOWN)) &&
- (current->rect.x != output->rect.x))
+ other = &(output->rect);
+
+ if ((direction == D_RIGHT && other->x > cur->x) ||
+ (direction == D_LEFT && other->x < cur->x)) {
+ /* Skip the output when it doesn’t overlap the other one’s y
+ * coordinate at all. */
+ if ((other->y + other->height) <= cur->y ||
+ (cur->y + cur->height) <= other->y)
+ continue;
+ } else if ((direction == D_DOWN && other->y > cur->y) ||
+ (direction == D_UP && other->y < cur->y)) {
+ /* Skip the output when it doesn’t overlap the other one’s x
+ * coordinate at all. */
+ if ((other->x + other->width) <= cur->x ||
+ (cur->x + cur->width) <= other->x)
+ continue;
+ } else
continue;
- if (((direction == D_LEFT) || (direction == D_RIGHT)) &&
- (current->rect.y != output->rect.y))
+ /* No candidate yet? Start with this one. */
+ if (!best) {
+ best = output;
continue;
+ }
- switch (direction) {
- case D_UP:
- if (output->rect.y < current->rect.y &&
- (!candidate || output->rect.y < candidate->rect.y))
- candidate = output;
- break;
- case D_DOWN:
- if (output->rect.y > current->rect.y &&
- (!candidate || output->rect.y > candidate->rect.y))
- candidate = output;
- break;
- case D_LEFT:
- if (output->rect.x < current->rect.x &&
- (!candidate || output->rect.x > candidate->rect.x))
- candidate = output;
- break;
- case D_RIGHT:
- if (output->rect.x > current->rect.x &&
- (!candidate || output->rect.x < candidate->rect.x))
- candidate = output;
- break;
+ if (close_far == CLOSEST_OUTPUT) {
+ /* Is this output better (closer to the current output) than our
+ * current best bet? */
+ if ((direction == D_RIGHT && other->x < best->rect.x) ||
+ (direction == D_LEFT && other->x > best->rect.x) ||
+ (direction == D_DOWN && other->y < best->rect.y) ||
+ (direction == D_UP && other->y > best->rect.y)) {
+ best = output;
+ continue;
+ }
+ } else {
+ /* Is this output better (farther to the current output) than our
+ * current best bet? */
+ if ((direction == D_RIGHT && other->x > best->rect.x) ||
+ (direction == D_LEFT && other->x < best->rect.x) ||
+ (direction == D_DOWN && other->y > best->rect.y) ||
+ (direction == D_UP && other->y < best->rect.y)) {
+ best = output;
+ continue;
+ }
}
}
- return candidate;
+ DLOG("current = %s, best = %s\n", current->name, (best ? best->name : "NULL"));
+ return best;
}
/*
Con *topdock = con_new(NULL, NULL);
topdock->type = CT_DOCKAREA;
topdock->layout = L_DOCKAREA;
- topdock->orientation = VERT;
/* this container swallows dock clients */
Match *match = scalloc(sizeof(Match));
match_init(match);
DLOG("adding main content container\n");
Con *content = con_new(NULL, NULL);
content->type = CT_CON;
+ content->layout = L_SPLITH;
FREE(content->name);
content->name = sstrdup("content");
Con *bottomdock = con_new(NULL, NULL);
bottomdock->type = CT_DOCKAREA;
bottomdock->layout = L_DOCKAREA;
- bottomdock->orientation = VERT;
/* this container swallows dock clients */
match = scalloc(sizeof(Match));
match_init(match);
if (con_num_children(workspace) > 1)
continue;
- workspace->orientation = (output->rect.height > output->rect.width) ? VERT : HORIZ;
- DLOG("Setting workspace [%d,%s]'s orientation to %d.\n", workspace->num, workspace->name, workspace->orientation);
+ workspace->layout = (output->rect.height > output->rect.width) ? L_SPLITV : L_SPLITH;
+ DLOG("Setting workspace [%d,%s]'s layout to %d.\n", workspace->num, workspace->name, workspace->layout);
if ((child = TAILQ_FIRST(&(workspace->nodes_head)))) {
- child->orientation = workspace->orientation;
- DLOG("Setting child [%d,%s]'s orientation to %d.\n", child->num, child->name, child->orientation);
+ if (child->layout == L_SPLITV || child->layout == L_SPLITH)
+ child->layout = workspace->layout;
+ DLOG("Setting child [%d,%s]'s layout to %d.\n", child->num, child->name, child->layout);
}
}
}