]> git.sur5r.net Git - i3/i3/blobdiff - src/randr.c
make i3bar use libi3’s root_atom_contents()
[i3/i3] / src / randr.c
index a73a94c92450ad9c9052481694aa7f1e6b032f48..1aef9c9c620c59af800c4a1e972f6dd6cbb0aecb 100644 (file)
@@ -69,7 +69,7 @@ Output *get_first_output(void) {
         if (output->active)
             return output;
 
-    return NULL;
+    die("No usable outputs available.\n");
 }
 
 /*
@@ -93,15 +93,55 @@ Output *get_output_containing(int x, int y) {
 }
 
 /*
- * Gets the output which is the last one in the given direction, for example
- * the output on the most bottom when direction == D_DOWN, the output most
- * right when direction == D_RIGHT and so on.
+ * In contained_by_output, we check if any active output contains part of the container.
+ * We do this by checking if the output rect is intersected by the Rect.
+ * This is the 2-dimensional counterpart of get_output_containing.
+ * Since we don't actually need the outputs intersected by the given Rect (There could
+ * be many), we just return true or false for convenience.
+ *
+ */
+bool contained_by_output(Rect rect){
+    Output *output;
+    int lx = rect.x, uy = rect.y;
+    int rx = rect.x + rect.width, by = rect.y + rect.height;
+    TAILQ_FOREACH(output, &outputs, outputs) {
+        if (!output->active)
+            continue;
+        DLOG("comparing x=%d y=%d with x=%d and y=%d width %d height %d\n",
+                        rect.x, rect.y, output->rect.x, output->rect.y, output->rect.width, output->rect.height);
+        if (rx >= (int)output->rect.x && lx <= (int)(output->rect.x + output->rect.width) &&
+            by >= (int)output->rect.y && uy <= (int)(output->rect.y + output->rect.height))
+            return true;
+    }
+    return false;
+
+}
+
+/*
+ * Like get_output_next with close_far == CLOSEST_OUTPUT, but wraps.
+ *
+ * For example if get_output_next(D_DOWN, x, FARTHEST_OUTPUT) = NULL, then
+ * get_output_next_wrap(D_DOWN, x) will return the topmost output.
  *
- * This function always returns a output.
+ * This function always returns a output: if no active outputs can be found,
+ * current itself is returned.
  *
  */
-Output *get_output_most(direction_t direction, Output *current) {
-    Output *best = get_output_next(direction, current, FARTHEST_OUTPUT);
+Output *get_output_next_wrap(direction_t direction, Output *current) {
+    Output *best = get_output_next(direction, current, CLOSEST_OUTPUT);
+    /* If no output can be found, wrap */
+    if (!best) {
+        direction_t opposite;
+        if (direction == D_RIGHT)
+            opposite = D_LEFT;
+        else if (direction == D_LEFT)
+            opposite = D_RIGHT;
+        else if (direction == D_DOWN)
+            opposite = D_UP;
+        else
+            opposite = D_DOWN;
+        best = get_output_next(opposite, current, FARTHEST_OUTPUT);
+    }
     if (!best)
         best = current;
     DLOG("current = %s, best = %s\n", current->name, best->name);
@@ -111,6 +151,13 @@ Output *get_output_most(direction_t direction, Output *current) {
 /*
  * Gets the output which is the next one in the given direction.
  *
+ * If close_far == CLOSEST_OUTPUT, then the output next to the current one will
+ * selected. If close_far == FARTHEST_OUTPUT, the output which is the last one
+ * in the given direction will be selected.
+ *
+ * NULL will be returned when no active outputs are present in the direction
+ * specified (note that “current” counts as such an output).
+ *
  */
 Output *get_output_next(direction_t direction, Output *current, output_close_far_t close_far) {
     Rect *cur = &(current->rect),
@@ -647,8 +694,7 @@ void randr_query_outputs(void) {
             output->active = false;
             DLOG("Output %s disabled, re-assigning workspaces/docks\n", output->name);
 
-            if ((first = get_first_output()) == NULL)
-                die("No usable outputs available\n");
+            first = get_first_output();
 
             /* TODO: refactor the following code into a nice function. maybe
              * use an on_destroy callback which is implement differently for
@@ -736,6 +782,9 @@ void randr_query_outputs(void) {
         disable_randr(conn);
     }
 
+    /* Verifies that there is at least one active output as a side-effect. */
+    get_first_output();
+
     /* Just go through each active output and assign one workspace */
     TAILQ_FOREACH(output, &outputs, outputs) {
         if (!output->active)