From f14efe85d14553569376d8c416944eeac9379275 Mon Sep 17 00:00:00 2001 From: Nils Schneider Date: Mon, 21 Sep 2015 11:44:39 +0200 Subject: [PATCH] Don't create empty workspaces on restart This fixes a bug I introduced in #1921. When restarting i3 in place a stray workspace was created on the root_output during restart. On first start, this workspace would have been moved to the first real and empty output. However, this does not produce the desired result during restarts when workspaces are alread present on all real outputs. The stray workspace would still be added to the first real output which already contains some workspaces. Thus, adding a new empty workspace to it. Fix this by delaying creation of the root output's workspace until it is known whether the output is active or not. Fixes #1940 --- include/randr.h | 2 +- src/randr.c | 31 ++++++++++++++++++------------- src/xinerama.c | 17 +++++++++++++++-- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/include/randr.h b/include/randr.h index 2c379f6f..998f0d59 100644 --- a/include/randr.h +++ b/include/randr.h @@ -118,4 +118,4 @@ Output *get_output_next_wrap(direction_t direction, Output *current); * Creates an output covering the root window. * */ -void create_root_output(xcb_connection_t *conn); +Output *create_root_output(xcb_connection_t *conn); diff --git a/src/randr.c b/src/randr.c index 23dd98d5..e4522c4d 100644 --- a/src/randr.c +++ b/src/randr.c @@ -239,19 +239,17 @@ Output *get_output_next(direction_t direction, Output *current, output_close_far * Creates an output covering the root window. * */ -void create_root_output(xcb_connection_t *conn) { - root_output = scalloc(1, sizeof(Output)); +Output *create_root_output(xcb_connection_t *conn) { + Output *s = scalloc(1, sizeof(Output)); - root_output->active = true; - root_output->rect.x = 0; - root_output->rect.y = 0; - root_output->rect.width = root_screen->width_in_pixels; - root_output->rect.height = root_screen->height_in_pixels; - root_output->name = "xroot-0"; - output_init_con(root_output); - init_ws_for_output(root_output, output_get_content(root_output->con)); + s->active = false; + s->rect.x = 0; + s->rect.y = 0; + s->rect.width = root_screen->width_in_pixels; + s->rect.height = root_screen->height_in_pixels; + s->name = "xroot-0"; - TAILQ_INSERT_TAIL(&outputs, root_output, outputs); + return s; } /* @@ -833,11 +831,18 @@ void randr_query_outputs(void) { void randr_init(int *event_base) { const xcb_query_extension_reply_t *extreply; - create_root_output(conn); + root_output = create_root_output(conn); + TAILQ_INSERT_TAIL(&outputs, root_output, outputs); extreply = xcb_get_extension_data(conn, &xcb_randr_id); - if (!extreply->present) + if (!extreply->present) { + DLOG("RandR is not present, activating root output.\n"); + root_output->active = true; + output_init_con(root_output); + init_ws_for_output(root_output, output_get_content(root_output->con)); + return; + } randr_query_outputs(); diff --git a/src/xinerama.c b/src/xinerama.c index 049e1bc4..fb3b8603 100644 --- a/src/xinerama.c +++ b/src/xinerama.c @@ -87,6 +87,19 @@ static void query_screens(xcb_connection_t *conn) { } } +/* + * This creates the root_output (borrowed from randr.c) and uses it + * as the sole output for this session. + * + */ +static void use_root_output(xcb_connection_t *conn) { + Output *s = create_root_output(conn); + s->active = true; + TAILQ_INSERT_TAIL(&outputs, s, outputs); + output_init_con(s); + init_ws_for_output(s, output_get_content(s->con)); +} + /* * We have just established a connection to the X server and need the initial Xinerama * information to setup workspaces for each screen. @@ -95,14 +108,14 @@ static void query_screens(xcb_connection_t *conn) { void xinerama_init(void) { if (!xcb_get_extension_data(conn, &xcb_xinerama_id)->present) { DLOG("Xinerama extension not found, using root output.\n"); - create_root_output(conn); + use_root_output(conn); } else { xcb_xinerama_is_active_reply_t *reply; reply = xcb_xinerama_is_active_reply(conn, xcb_xinerama_is_active(conn), NULL); if (reply == NULL || !reply->state) { DLOG("Xinerama is not active (in your X-Server), using root output.\n"); - create_root_output(conn); + use_root_output(conn); } else query_screens(conn);