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
This commit is contained in:
Nils Schneider 2015-09-21 11:44:39 +02:00
parent 78decb565a
commit f14efe85d1
3 changed files with 34 additions and 16 deletions

View File

@ -118,4 +118,4 @@ Output *get_output_next_wrap(direction_t direction, Output *current);
* Creates an output covering the root window. * Creates an output covering the root window.
* *
*/ */
void create_root_output(xcb_connection_t *conn); Output *create_root_output(xcb_connection_t *conn);

View File

@ -239,19 +239,17 @@ Output *get_output_next(direction_t direction, Output *current, output_close_far
* Creates an output covering the root window. * Creates an output covering the root window.
* *
*/ */
void create_root_output(xcb_connection_t *conn) { Output *create_root_output(xcb_connection_t *conn) {
root_output = scalloc(1, sizeof(Output)); Output *s = scalloc(1, sizeof(Output));
root_output->active = true; s->active = false;
root_output->rect.x = 0; s->rect.x = 0;
root_output->rect.y = 0; s->rect.y = 0;
root_output->rect.width = root_screen->width_in_pixels; s->rect.width = root_screen->width_in_pixels;
root_output->rect.height = root_screen->height_in_pixels; s->rect.height = root_screen->height_in_pixels;
root_output->name = "xroot-0"; s->name = "xroot-0";
output_init_con(root_output);
init_ws_for_output(root_output, output_get_content(root_output->con));
TAILQ_INSERT_TAIL(&outputs, root_output, outputs); return s;
} }
/* /*
@ -833,11 +831,18 @@ void randr_query_outputs(void) {
void randr_init(int *event_base) { void randr_init(int *event_base) {
const xcb_query_extension_reply_t *extreply; 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); 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; return;
}
randr_query_outputs(); randr_query_outputs();

View File

@ -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 * We have just established a connection to the X server and need the initial Xinerama
* information to setup workspaces for each screen. * information to setup workspaces for each screen.
@ -95,14 +108,14 @@ static void query_screens(xcb_connection_t *conn) {
void xinerama_init(void) { void xinerama_init(void) {
if (!xcb_get_extension_data(conn, &xcb_xinerama_id)->present) { if (!xcb_get_extension_data(conn, &xcb_xinerama_id)->present) {
DLOG("Xinerama extension not found, using root output.\n"); DLOG("Xinerama extension not found, using root output.\n");
create_root_output(conn); use_root_output(conn);
} else { } else {
xcb_xinerama_is_active_reply_t *reply; xcb_xinerama_is_active_reply_t *reply;
reply = xcb_xinerama_is_active_reply(conn, xcb_xinerama_is_active(conn), NULL); reply = xcb_xinerama_is_active_reply(conn, xcb_xinerama_is_active(conn), NULL);
if (reply == NULL || !reply->state) { if (reply == NULL || !reply->state) {
DLOG("Xinerama is not active (in your X-Server), using root output.\n"); DLOG("Xinerama is not active (in your X-Server), using root output.\n");
create_root_output(conn); use_root_output(conn);
} else } else
query_screens(conn); query_screens(conn);