]> git.sur5r.net Git - i3/i3/blobdiff - src/randr.c
implement 'move' command in the new parser
[i3/i3] / src / randr.c
index 7531ecf2cd9facebcd4b3d1a189ba819cbf06e9d..6c63069f84572d89722539499253081002f51ae1 100644 (file)
  * (take your time to read it completely, it answers all questions).
  *
  */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <assert.h>
 #include <time.h>
-#include <unistd.h>
 
-#include <xcb/xcb.h>
 #include <xcb/randr.h>
 
-#include "queue.h"
-#include "i3.h"
-#include "data.h"
-#include "table.h"
-#include "util.h"
-#include "layout.h"
-#include "xcb.h"
-#include "config.h"
-#include "workspace.h"
-#include "log.h"
-#include "ewmh.h"
+#include "all.h"
 
 /* While a clean namespace is usually a pretty good thing, we really need
  * to use shorter names than the whole xcb_randr_* default names. */
@@ -157,6 +140,7 @@ Output *get_output_most(direction_t direction, Output *current) {
         return candidate;
 }
 
+#if 0
 /*
  * Initializes the specified output, assigning the specified workspace to it.
  *
@@ -188,9 +172,24 @@ void initialize_output(xcb_connection_t *conn, Output *output, Workspace *worksp
 
         SLIST_INIT(&(output->dock_clients));
 
+        ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"init\"}");
         DLOG("initialized output at (%d, %d) with %d x %d\n",
                         output->rect.x, output->rect.y, output->rect.width, output->rect.height);
+
+        DLOG("assigning configured workspaces to this output...\n");
+        Workspace *ws;
+        TAILQ_FOREACH(ws, workspaces, workspaces) {
+                if (ws == workspace)
+                        continue;
+                if (ws->preferred_output == NULL ||
+                    get_output_by_name(ws->preferred_output) != output)
+                        continue;
+
+                DLOG("assigning ws %d\n", ws->num + 1);
+                workspace_assign_to(ws, output, true);
+        }
 }
+#endif
 
 /*
  * Disables RandR support by creating exactly one output with the size of the
@@ -229,8 +228,6 @@ void disable_randr(xcb_connection_t *conn) {
  */
 static void output_change_mode(xcb_connection_t *conn, Output *output) {
         i3Font *font = load_font(conn, config.font);
-        Workspace *ws;
-        Client *client;
 
         DLOG("Output mode changed, reconfiguring bar, updating workspaces\n");
         Rect bar_rect = {output->rect.x,
@@ -240,17 +237,29 @@ static void output_change_mode(xcb_connection_t *conn, Output *output) {
 
         xcb_set_window_rect(conn, output->bar, bar_rect);
 
+#if 0
         /* go through all workspaces and set force_reconfigure */
         TAILQ_FOREACH(ws, workspaces, workspaces) {
                 if (ws->output != output)
                         continue;
 
+                SLIST_FOREACH(client, &(ws->focus_stack), focus_clients) {
+                        client->force_reconfigure = true;
+                        if (!client_is_floating(client))
+                                continue;
+                        /* For floating clients we need to translate the
+                         * coordinates (old workspace to new workspace) */
+                        DLOG("old: (%x, %x)\n", client->rect.x, client->rect.y);
+                        client->rect.x -= ws->rect.x;
+                        client->rect.y -= ws->rect.y;
+                        client->rect.x += ws->output->rect.x;
+                        client->rect.y += ws->output->rect.y;
+                        DLOG("new: (%x, %x)\n", client->rect.x, client->rect.y);
+                }
+
                 /* Update dimensions from output */
                 memcpy(&(ws->rect), &(ws->output->rect), sizeof(Rect));
 
-                SLIST_FOREACH(client, &(ws->focus_stack), focus_clients)
-                        client->force_reconfigure = true;
-
                 /* Update the dimensions of a fullscreen client, if any */
                 if (ws->fullscreen_client != NULL) {
                         DLOG("Updating fullscreen client size\n");
@@ -263,6 +272,7 @@ static void output_change_mode(xcb_connection_t *conn, Output *output) {
                         xcb_set_window_rect(conn, client->child, r);
                 }
         }
+#endif
 }
 
 /*
@@ -284,6 +294,7 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
         if (!existing)
                 new = scalloc(sizeof(Output));
         new->id = id;
+        FREE(new->name);
         asprintf(&new->name, "%.*s",
                         xcb_randr_get_output_info_name_length(output),
                         xcb_randr_get_output_info_name(output));
@@ -296,11 +307,8 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
         if (output->crtc == XCB_NONE) {
                 if (!existing)
                         TAILQ_INSERT_TAIL(&outputs, new, outputs);
-                else if (new->active) {
+                else if (new->active)
                         new->to_be_disabled = true;
-
-                }
-                free(output);
                 return;
         }
 
@@ -310,15 +318,19 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
                 DLOG("Skipping output %s: could not get CRTC (%p)\n",
                      new->name, crtc);
                 free(new);
-                free(output);
                 return;
         }
 
-        new->active = true;
         bool updated = update_if_necessary(&(new->rect.x), crtc->x) |
                        update_if_necessary(&(new->rect.y), crtc->y) |
                        update_if_necessary(&(new->rect.width), crtc->width) |
                        update_if_necessary(&(new->rect.height), crtc->height);
+        free(crtc);
+        new->active = (new->rect.width != 0 && new->rect.height != 0);
+        if (!new->active) {
+                DLOG("width/height 0/0, disabling output\n");
+                return;
+        }
 
         DLOG("mode: %dx%d+%d+%d\n", new->rect.width, new->rect.height,
                                     new->rect.x, new->rect.y);
@@ -329,7 +341,6 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
         if (!updated || !existing) {
                 if (!existing)
                         TAILQ_INSERT_TAIL(&outputs, new, outputs);
-                free(output);
                 return;
         }
 
@@ -340,8 +351,7 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
  * (Re-)queries the outputs via RandR and stores them in the list of outputs.
  *
  */
-void randr_query_outputs(xcb_connection_t *conn) {
-        Workspace *ws;
+void randr_query_outputs() {
         Output *output, *other, *first;
         xcb_randr_get_screen_resources_current_cookie_t rcookie;
         resources_reply *res;
@@ -379,6 +389,7 @@ void randr_query_outputs(xcb_connection_t *conn) {
                         continue;
 
                 handle_output(conn, randr_outputs[i], output, cts, res);
+                free(output);
         }
 
         free(res);
@@ -431,8 +442,9 @@ void randr_query_outputs(xcb_connection_t *conn) {
                         if ((first = get_first_output()) == NULL)
                                 die("No usable outputs available\n");
 
-                        bool needs_init = (first->current_workspace == NULL);
+                        //bool needs_init = (first->current_workspace == NULL);
 
+#if 0
                         TAILQ_FOREACH(ws, workspaces, workspaces) {
                                 if (ws->output != output)
                                         continue;
@@ -440,17 +452,19 @@ void randr_query_outputs(xcb_connection_t *conn) {
                                 workspace_assign_to(ws, first, true);
                                 if (!needs_init)
                                         continue;
-                                initialize_output(conn, first, ws);
+                                //initialize_output(conn, first, ws);
                                 needs_init = false;
                         }
 
                         Client *dock;
                         while (!SLIST_EMPTY(&(output->dock_clients))) {
                                 dock = SLIST_FIRST(&(output->dock_clients));
-                                SLIST_INSERT_HEAD(&(first->dock_clients), dock, dock_clients);
                                 SLIST_REMOVE_HEAD(&(output->dock_clients), dock_clients);
+                                SLIST_INSERT_HEAD(&(first->dock_clients), dock, dock_clients);
                         }
-                        output->current_workspace = NULL;
+
+#endif
+                        //output->current_workspace = NULL;
                         output->to_be_disabled = false;
                 } else if (output->changed) {
                         output_change_mode(conn, output);
@@ -458,8 +472,14 @@ void randr_query_outputs(xcb_connection_t *conn) {
                 }
         }
 
-        ewmh_update_workarea();
+        if (TAILQ_EMPTY(&outputs)) {
+                ELOG("No outputs found via RandR, disabling\n");
+                disable_randr(conn);
+        }
+
+        //ewmh_update_workarea();
 
+#if 0
         /* Just go through each active output and associate one workspace */
         TAILQ_FOREACH(output, &outputs, outputs) {
                 if (!output->active || output->current_workspace != NULL)
@@ -467,9 +487,10 @@ void randr_query_outputs(xcb_connection_t *conn) {
                 ws = get_first_workspace_for_output(output);
                 initialize_output(conn, output, ws);
         }
+#endif
 
         /* render_layout flushes */
-        render_layout(conn);
+        tree_render();
 }
 
 /*
@@ -477,7 +498,7 @@ void randr_query_outputs(xcb_connection_t *conn) {
  * XRandR information to setup workspaces for each screen.
  *
  */
-void initialize_randr(xcb_connection_t *conn, int *event_base) {
+void randr_init(int *event_base) {
         const xcb_query_extension_reply_t *extreply;
 
         extreply = xcb_get_extension_data(conn, &xcb_randr_id);