]> git.sur5r.net Git - i3/i3/commitdiff
Bugfix: Repeatedly try to find screens if none are available (Thanks mxf)
authorMichael Stapelberg <michael@stapelberg.de>
Tue, 21 Jul 2009 13:59:11 +0000 (15:59 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Tue, 21 Jul 2009 13:59:11 +0000 (15:59 +0200)
When rotating your screens (xrandr --output LVDS1 --rotate right), sometimes
the X server returned no screens which lead to an exit(1) of i3. Now, i3
tries to find screens for up to 5 seconds and only quits afterwards.

src/xinerama.c

index f1becf8c423c0677e133bd060e0433ea901ff565..2bb8b2986900ee027bfea6e2a9efe65e1bcf9c32 100644 (file)
@@ -13,6 +13,7 @@
 #include <string.h>
 #include <stdbool.h>
 #include <assert.h>
+#include <time.h>
 
 #include <xcb/xcb.h>
 #include <xcb/xinerama.h>
@@ -156,46 +157,55 @@ static void disable_xinerama(xcb_connection_t *conn) {
 static void query_screens(xcb_connection_t *conn, struct screens_head *screenlist) {
         xcb_xinerama_query_screens_reply_t *reply;
         xcb_xinerama_screen_info_t *screen_info;
+        time_t before_trying = time(NULL);
+
+        /* Try repeatedly to find screens (there might be short timeframes in
+         * which the X server does not return any screens, such as when rotating
+         * screens), but not longer than 5 seconds (strictly speaking, only four
+         * seconds of trying are guaranteed due to the 1-second-resolution) */
+        while ((time(NULL) - before_trying) < 5) {
+                reply = xcb_xinerama_query_screens_reply(conn, xcb_xinerama_query_screens_unchecked(conn), NULL);
+                if (!reply) {
+                        LOG("Couldn't get Xinerama screens\n");
+                        return;
+                }
+                screen_info = xcb_xinerama_query_screens_screen_info(reply);
+                int screens = xcb_xinerama_query_screens_screen_info_length(reply);
+                num_screens = 0;
+
+                for (int screen = 0; screen < screens; screen++) {
+                        i3Screen *s = get_screen_at(screen_info[screen].x_org, screen_info[screen].y_org, screenlist);
+                        if (s!= NULL) {
+                                /* This screen already exists. We use the littlest screen so that the user
+                                   can always see the complete workspace */
+                                s->rect.width = min(s->rect.width, screen_info[screen].width);
+                                s->rect.height = min(s->rect.height, screen_info[screen].height);
+                        } else {
+                                s = calloc(sizeof(i3Screen), 1);
+                                s->rect.x = screen_info[screen].x_org;
+                                s->rect.y = screen_info[screen].y_org;
+                                s->rect.width = screen_info[screen].width;
+                                s->rect.height = screen_info[screen].height;
+                                /* We always treat the screen at 0x0 as the primary screen */
+                                if (s->rect.x == 0 && s->rect.y == 0)
+                                        TAILQ_INSERT_HEAD(screenlist, s, screens);
+                                else TAILQ_INSERT_TAIL(screenlist, s, screens);
+                                num_screens++;
+                        }
 
-        reply = xcb_xinerama_query_screens_reply(conn, xcb_xinerama_query_screens_unchecked(conn), NULL);
-        if (!reply) {
-                LOG("Couldn't get Xinerama screens\n");
-                return;
-        }
-        screen_info = xcb_xinerama_query_screens_screen_info(reply);
-        int screens = xcb_xinerama_query_screens_screen_info_length(reply);
-        num_screens = 0;
-
-        for (int screen = 0; screen < screens; screen++) {
-                i3Screen *s = get_screen_at(screen_info[screen].x_org, screen_info[screen].y_org, screenlist);
-                if (s!= NULL) {
-                        /* This screen already exists. We use the littlest screen so that the user
-                           can always see the complete workspace */
-                        s->rect.width = min(s->rect.width, screen_info[screen].width);
-                        s->rect.height = min(s->rect.height, screen_info[screen].height);
-                } else {
-                        s = calloc(sizeof(i3Screen), 1);
-                        s->rect.x = screen_info[screen].x_org;
-                        s->rect.y = screen_info[screen].y_org;
-                        s->rect.width = screen_info[screen].width;
-                        s->rect.height = screen_info[screen].height;
-                        /* We always treat the screen at 0x0 as the primary screen */
-                        if (s->rect.x == 0 && s->rect.y == 0)
-                                TAILQ_INSERT_HEAD(screenlist, s, screens);
-                        else TAILQ_INSERT_TAIL(screenlist, s, screens);
-                        num_screens++;
+                        LOG("found Xinerama screen: %d x %d at %d x %d\n",
+                                        screen_info[screen].width, screen_info[screen].height,
+                                        screen_info[screen].x_org, screen_info[screen].y_org);
                 }
 
-                LOG("found Xinerama screen: %d x %d at %d x %d\n",
-                                screen_info[screen].width, screen_info[screen].height,
-                                screen_info[screen].x_org, screen_info[screen].y_org);
-        }
+                free(reply);
 
-        free(reply);
+                if (num_screens == 0) {
+                        LOG("No screens found. This is weird. Trying again...\n");
+                        continue;
+                }
 
-        if (num_screens == 0) {
-                LOG("No screens found. This is weird.\n");
-                exit(1);
+                break;
         }
 }