]> git.sur5r.net Git - i3/i3/commitdiff
Change workspace assignments to use the RandR output name instead of <screen>
authorMichael Stapelberg <michael@stapelberg.de>
Tue, 2 Mar 2010 12:35:43 +0000 (13:35 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Tue, 2 Mar 2010 12:35:43 +0000 (13:35 +0100)
docs/userguide
include/data.h
include/randr.h
src/cfgparse.l
src/cfgparse.y
src/randr.c
src/workspace.c

index 63f8e8acaa83560c21edbfdcc811c8b8d8a3c73e..7f47acce23956665953698d522a94a0394a6a7ea 100644 (file)
@@ -1,7 +1,7 @@
 i3 User’s Guide
 ===============
 Michael Stapelberg <michael+i3@stapelberg.de>
-August 2009
+March 2010
 
 This document contains all information you need to configuring and using the i3
 window manager. If it does not, please contact me on IRC, Jabber or E-Mail and
@@ -367,25 +367,17 @@ default it will use 1 for the first screen, 2 for the second screen and so on).
 
 *Syntax*:
 ----------------------------------
-workspace <number> screen <screen>
+workspace <number> output <output>
 ----------------------------------
 
-Screen can be either a number (starting at 0 for the first screen) or a
-position. When using numbers, it is not guaranteed that your screens always
-get the same number. Though, unless you upgrade your X server or drivers, the
-order usually stays the same. When using positions, you have to specify the
-exact pixel where the screen *starts*, not a pixel which is contained by the
-screen. Thus, if your first screen has the dimensions 1280x800, you can match
-the second screen right of it by specifying 1280. You cannot use 1281.
+The output is the name of the RandR output you attach your screen to. On a
+laptop, you might have VGA1 and LVDS1 as output names. You can see the
+available outputs by running +xrandr --current+.
 
 *Examples*:
 ---------------------------
-workspace 1 screen 0
-workspace 5 screen 1
-
-workspace 1 screen 1280
-workspace 2 screen x800
-workspace 3 screen 1280x800
+workspace 1 output LVDS1
+workspace 5 output VGA1
 ---------------------------
 
 === Named workspaces
@@ -396,10 +388,10 @@ them names (of course UTF-8 is supported):
 *Syntax*:
 ---------------------------------------
 workspace <number> <name>
-workspace <number> screen <screen> name
+workspace <number> output <output> name
 ---------------------------------------
 
-For more details about the screen-part of this command, see above.
+For more details about the output-part of this command, see above.
 
 *Examples*:
 --------------------------
index 10242f2067e18b1127050413faea436cb328a1e4..84ea1cd2b0efb564ffcf8216659115ed52cca5ad 100644 (file)
@@ -206,9 +206,8 @@ struct Workspace {
         /** Are the floating clients on this workspace currently hidden? */
         bool floating_hidden;
 
-        /** A <screen> specifier on which this workspace would like to be (if
-         * the screen is available). screen := <number> | <position> */
-        char *preferred_screen;
+        /** The name of the RandR output this screen should be on */
+        char *preferred_output;
 
         /** Temporary flag needed for re-querying xinerama screens */
         bool reassigned;
index 50e19938eb14c4a371bc1fcbf45b3a08928543ff..627afdbe9f8239f2db245ec61902567daf67e293 100644 (file)
 TAILQ_HEAD(outputs_head, xoutput);
 extern struct outputs_head outputs;
 
-/**
- * Returns true if both screen objects describe the same screen (checks their
- * size and position).
- *
- */
-bool screens_are_equal(Output *screen1, Output *screen2);
-
 /**
  * We have just established a connection to the X server and need the initial
  * XRandR information to setup workspaces for each screen.
@@ -43,6 +36,12 @@ void randr_query_screens(xcb_connection_t *conn);
  */
 Output *get_first_output();
 
+/**
+ * Returns the output with the given name if it is active (!) or NULL.
+ *
+ */
+Output *get_output_by_name(const char *name);
+
 /**
  * Looks in virtual_screens for the i3Screen which contains coordinates x, y
  *
index 1982452d790c29bb33579e5eabaaec99dceba7b4..67a41300d28c8f6cc4a8fd90a8814994a4e832f1 100644 (file)
@@ -39,8 +39,8 @@ EOL   (\r?\n)
 %s BIND_A2WS_COND
 %s ASSIGN_COND
 %s COLOR_COND
-%s SCREEN_COND
-%s SCREEN_AWS_COND
+%s OUTPUT_COND
+%s OUTPUT_AWS_COND
 %x BUFFER_LINE
 
 %%
@@ -67,6 +67,7 @@ EOL   (\r?\n)
 
 
 <BIND_A2WS_COND>[^\n]+          { BEGIN(INITIAL); yylval.string = strdup(yytext); return STR; }
+<OUTPUT_AWS_COND>[a-zA-Z0-9_-]+ { BEGIN(BIND_A2WS_COND); yylval.string = strdup(yytext); return OUTPUT; }
 ^[ \t]*#[^\n]*                  { return TOKCOMMENT; }
 <COLOR_COND>[0-9a-fA-F]+        { yylval.string = strdup(yytext); return HEX; }
 [0-9]+                          { yylval.number = atoi(yytext); return NUMBER; }
@@ -75,7 +76,14 @@ bind                            { BEGIN(BIND_COND); return TOKBIND; }
 bindsym                         { BEGIN(BINDSYM_COND); return TOKBINDSYM; }
 floating_modifier               { BEGIN(INITIAL); return TOKFLOATING_MODIFIER; }
 workspace                       { BEGIN(INITIAL); return TOKWORKSPACE; }
-screen                          { BEGIN(SCREEN_COND); return TOKSCREEN; }
+output                          { BEGIN(OUTPUT_COND); return TOKOUTPUT; }
+screen                          {
+                                  /* for compatibility until v3.φ */
+                                  ELOG("Assignments to screens are DEPRECATED and will not work. " \
+                                       "Please replace them with assignments to outputs.\n");
+                                  BEGIN(OUTPUT_COND);
+                                  return TOKOUTPUT;
+                                }
 terminal                        { BEGIN(BIND_AWS_COND); return TOKTERMINAL; }
 font                            { BEGIN(BIND_AWS_COND); return TOKFONT; }
 assign                          { BEGIN(ASSIGN_COND); return TOKASSIGN; }
@@ -112,15 +120,15 @@ shift                           { return TOKSHIFT; }
 {EOL}                           {
                                   FREE(context->line_copy);
                                   context->line_number++;
+                                  BEGIN(INITIAL);
                                   yy_push_state(BUFFER_LINE);
                                 }
-<SCREEN_AWS_COND>x              { return (int)yytext[0]; }
 <BIND_COND>[ \t]+               { BEGIN(BIND_AWS_COND); return WHITESPACE; }
 <BINDSYM_COND>[ \t]+            { BEGIN(BINDSYM_AWS_COND); return WHITESPACE; }
 <BIND_AWS_COND>[ \t]+           { BEGIN(BIND_A2WS_COND); return WHITESPACE; }
 <BINDSYM_AWS_COND>[ \t]+        { BEGIN(BIND_A2WS_COND); return WHITESPACE; }
-<SCREEN_COND>[ \t]+             { BEGIN(SCREEN_AWS_COND); return WHITESPACE; }
-<SCREEN_AWS_COND>[ \t]+         { BEGIN(BIND_A2WS_COND); return WHITESPACE; }
+<OUTPUT_COND>[ \t]+             { BEGIN(OUTPUT_AWS_COND); return WHITESPACE; }
+<OUTPUT_AWS_COND>[ \t]+         { BEGIN(BIND_A2WS_COND); return WHITESPACE; }
 [ \t]+                          { return WHITESPACE; }
 \"[^\"]+\"                      {
                                   /* if ASSIGN_COND then */
index cc0e77cb11fc2c78beb7680b1637c24933defd01..9ed17ea1dd7314d68968ac80e8d3a572dc814c89 100644 (file)
@@ -197,6 +197,7 @@ void parse_file(const char *f) {
 %token <string>STR "<string>"
 %token <string>STR_NG "<string (non-greedy)>"
 %token <string>HEX "<hex>"
+%token <string>OUTPUT "<RandR output>"
 %token TOKBIND
 %token TOKTERMINAL
 %token TOKCOMMENT "<comment>"
@@ -209,7 +210,7 @@ void parse_file(const char *f) {
 %token TOKFLOATING_MODIFIER "floating_modifier"
 %token QUOTEDSTRING "<quoted string>"
 %token TOKWORKSPACE "workspace"
-%token TOKSCREEN "screen"
+%token TOKOUTPUT "output"
 %token TOKASSIGN "assign"
 %token TOKSET
 %token TOKIPCSOCKET "ipc_socket"
@@ -429,14 +430,14 @@ focus_follows_mouse:
         ;
 
 workspace:
-        TOKWORKSPACE WHITESPACE NUMBER WHITESPACE TOKSCREEN WHITESPACE screen optional_workspace_name
+        TOKWORKSPACE WHITESPACE NUMBER WHITESPACE TOKOUTPUT WHITESPACE OUTPUT optional_workspace_name
         {
                 int ws_num = $<number>3;
                 if (ws_num < 1) {
                         DLOG("Invalid workspace assignment, workspace number %d out of range\n", ws_num);
                 } else {
                         Workspace *ws = workspace_get(ws_num - 1);
-                        ws->preferred_screen = sstrdup($<string>7);
+                        ws->preferred_output = sstrdup($<string>7);
                         if ($<string>8 != NULL)
                                 workspace_set_name(ws, $<string>8);
                 }
@@ -447,6 +448,7 @@ workspace:
                 if (ws_num < 1) {
                         DLOG("Invalid workspace assignment, workspace number %d out of range\n", ws_num);
                 } else {
+                        DLOG("workspace name to: %s\n", $<string>5);
                         if ($<string>5 != NULL)
                                 workspace_set_name(workspace_get(ws_num - 1), $<string>5);
                 }
@@ -464,13 +466,6 @@ workspace_name:
         | WORD               { $<string>$ = $<string>1; }
         ;
 
-screen:
-        NUMBER              { asprintf(&$<string>$, "%d", $<number>1); }
-        | NUMBER 'x'        { asprintf(&$<string>$, "%d", $<number>1); }
-        | NUMBER 'x' NUMBER { asprintf(&$<string>$, "%dx%d", $<number>1, $<number>3); }
-        | 'x' NUMBER        { asprintf(&$<string>$, "x%d", $<number>2); }
-        ;
-
 assign:
         TOKASSIGN WHITESPACE window_class WHITESPACE optional_arrow assign_target
         {
index f63b2f0cc30a931cf12b50e918742bd52298669f..d56f01f09ae97c3b6d1bb35b9d741780ee01cce7 100644 (file)
@@ -45,35 +45,30 @@ typedef xcb_randr_get_screen_resources_current_reply_t resources_reply;
 struct outputs_head outputs = TAILQ_HEAD_INITIALIZER(outputs);
 
 /*
- * Returns true if both screen objects describe the same screen (checks their
- * size and position).
+ * Get a specific output by its internal X11 id. Used by randr_query_screens
+ * to check if the output is new (only in the first scan) or if we are
+ * re-scanning.
  *
  */
-bool screens_are_equal(Output *screen1, Output *screen2) {
-        /* If one of both objects (or both) are NULL, we cannot compare them */
-        if (screen1 == NULL || screen2 == NULL)
-                return false;
-
-        /* If the pointers are equal, take the short-circuit */
-        if (screen1 == screen2)
-                return true;
-
-        /* Compare their size and position - other properties are not relevant
-         * to determine if a screen is equal to another one */
-        return (memcmp(&(screen1->rect), &(screen2->rect), sizeof(Rect)) == 0);
+static Output *get_output_by_id(xcb_randr_output_t id) {
+        Output *output;
+        TAILQ_FOREACH(output, &outputs, outputs)
+                if (output->id == id)
+                        return output;
+
+        return NULL;
 }
 
 /*
- * Get a specific output by its internal X11 id. Used by randr_query_screens
- * to check if the output is new (only in the first scan) or if we are
- * re-scanning.
+ * Returns the output with the given name if it is active (!) or NULL.
  *
  */
-static Output *get_output_by_id(xcb_randr_output_t id) {
-        Output *screen;
-        TAILQ_FOREACH(screen, &outputs, outputs)
-                if (screen->id == id)
-                        return screen;
+Output *get_output_by_name(const char *name) {
+        Output *output;
+        TAILQ_FOREACH(output, &outputs, outputs)
+                if (output->active &&
+                    strcasecmp(output->name, name) == 0)
+                        return output;
 
         return NULL;
 }
index 5a4902ca2034cdb46df350126580ac03e35bd656..a579bf1d16790a7995a5c3fa0ecee3ad34ca2b37 100644 (file)
@@ -195,58 +195,6 @@ void workspace_show(xcb_connection_t *conn, int workspace) {
         }
 }
 
-
-/*
- * Parses the preferred_screen property of a workspace. You can either specify
- * the screen number (it is not given that the screen numbering always stays
- * the same) or the screen coordinates (exact coordinates, e.g. 1280 will match
- * the screen starting at x=1280, but 1281 will not). For coordinates, you can
- * either specify an x coordinate ("1280") or an y coordinate ("x800") or both
- * ("1280x800").
- *
- */
-static Output *get_screen_from_preference(char *preference) {
-        Output *screen;
-        char *rest;
-        int preferred_screen = strtol(preference, &rest, 10);
-
-        DLOG("Getting screen for preference \"%s\" (%d)\n", preference, preferred_screen);
-
-        if ((rest == preference) || (preferred_screen >= num_screens)) {
-                int x = INT_MAX, y = INT_MAX;
-                if (strchr(preference, 'x') != NULL) {
-                        /* Check if only the y coordinate was specified */
-                        if (*preference == 'x')
-                                y = atoi(preference+1);
-                        else {
-                                x = atoi(preference);
-                                y = atoi(strchr(preference, 'x') + 1);
-                        }
-                } else {
-                        x = atoi(preference);
-                }
-
-                DLOG("Looking for screen at %d x %d\n", x, y);
-
-                TAILQ_FOREACH(screen, &outputs, outputs)
-                        if ((x == INT_MAX || screen->rect.x == x) &&
-                            (y == INT_MAX || screen->rect.y == y)) {
-                                DLOG("found %p\n", screen);
-                                return screen;
-                        }
-
-                DLOG("none found\n");
-                return NULL;
-        } else {
-                int c = 0;
-                TAILQ_FOREACH(screen, &outputs, outputs)
-                        if (c++ == preferred_screen)
-                                return screen;
-        }
-
-        return NULL;
-}
-
 /*
  * Assigns the given workspace to the given output by correctly updating its
  * state and reconfiguring all the clients on this workspace.
@@ -311,8 +259,8 @@ void workspace_initialize(Workspace *ws, Output *output, bool recheck) {
         /* If this workspace has no preferred output or if the output it wants
          * to be on is not available at the moment, we initialize it with
          * the output which was given */
-        if (ws->preferred_screen == NULL ||
-            (ws->output = get_screen_from_preference(ws->preferred_screen)) == NULL)
+        if (ws->preferred_output == NULL ||
+            (ws->output = get_output_by_name(ws->preferred_output)) == NULL)
                 ws->output = output;
 
         DLOG("old_output = %p, ws->output = %p\n", old_output, ws->output);
@@ -325,7 +273,7 @@ void workspace_initialize(Workspace *ws, Output *output, bool recheck) {
 
 /*
  * Gets the first unused workspace for the given screen, taking into account
- * the preferred_screen setting of every workspace (workspace assignments).
+ * the preferred_output setting of every workspace (workspace assignments).
  *
  */
 Workspace *get_first_workspace_for_screen(Output *output) {
@@ -333,8 +281,8 @@ Workspace *get_first_workspace_for_screen(Output *output) {
 
         Workspace *ws;
         TAILQ_FOREACH(ws, workspaces, workspaces) {
-                if (ws->preferred_screen == NULL ||
-                    !screens_are_equal(get_screen_from_preference(ws->preferred_screen), output))
+                if (ws->preferred_output == NULL ||
+                    get_output_by_name(ws->preferred_output) != output)
                         continue;
 
                 result = ws;