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