diff --git a/include/randr.h b/include/randr.h index 823ddea4..2c379f6f 100644 --- a/include/randr.h +++ b/include/randr.h @@ -29,13 +29,6 @@ typedef enum { */ void randr_init(int *event_base); -/** - * Disables RandR support by creating exactly one output with the size of the - * X11 screen. - * - */ -void disable_randr(xcb_connection_t *conn); - /** * Initializes a CT_OUTPUT Con (searches existing ones from inplace restart * before) to use for the given Output. @@ -120,3 +113,9 @@ Output *get_output_next(direction_t direction, Output *current, output_close_far * */ 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); diff --git a/src/randr.c b/src/randr.c index 69a866ab..23dd98d5 100644 --- a/src/randr.c +++ b/src/randr.c @@ -27,7 +27,8 @@ xcb_randr_get_output_primary_reply_t *primary; /* Stores all outputs available in your current session. */ struct outputs_head outputs = TAILQ_HEAD_INITIALIZER(outputs); -static bool randr_disabled = false; +/* This is the output covering the root window */ +static Output *root_output; /* * Get a specific output by its internal X11 id. Used by randr_query_outputs @@ -72,6 +73,21 @@ Output *get_first_output(void) { die("No usable outputs available.\n"); } +/* + * Check whether there are any active outputs (excluding the root output). + * + */ +static bool any_randr_output_active(void) { + Output *output; + + TAILQ_FOREACH(output, &outputs, outputs) { + if (output != root_output && !output->to_be_disabled && output->active) + return true; + } + + return false; +} + /* * Returns the active (!) output which contains the coordinates x, y or NULL * if there is no output which contains these coordinates. @@ -220,27 +236,22 @@ Output *get_output_next(direction_t direction, Output *current, output_close_far } /* - * Disables RandR support by creating exactly one output with the size of the - * X11 screen. + * Creates an output covering the root window. * */ -void disable_randr(xcb_connection_t *conn) { - DLOG("RandR extension unusable, disabling.\n"); +void create_root_output(xcb_connection_t *conn) { + root_output = scalloc(1, sizeof(Output)); - 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 = true; - 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"; - output_init_con(s); - init_ws_for_output(s, output_get_content(s->con)); - - TAILQ_INSERT_TAIL(&outputs, s, outputs); - - randr_disabled = true; + TAILQ_INSERT_TAIL(&outputs, root_output, outputs); } /* @@ -588,6 +599,8 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id, /* * (Re-)queries the outputs via RandR and stores them in the list of outputs. * + * If no outputs are found use the root window. + * */ void randr_query_outputs(void) { Output *output, *other, *first; @@ -602,9 +615,6 @@ void randr_query_outputs(void) { /* an output is VGA-1, LVDS-1, etc. (usually physical video outputs) */ xcb_randr_output_t *randr_outputs; - if (randr_disabled) - return; - /* Get screen resources (primary output, crtcs, outputs, modes) */ rcookie = xcb_randr_get_screen_resources_current(conn, root); pcookie = xcb_randr_get_output_primary(conn, root); @@ -613,10 +623,9 @@ void randr_query_outputs(void) { ELOG("Could not get RandR primary output\n"); else DLOG("primary output is %08x\n", primary->output); - if ((res = xcb_randr_get_screen_resources_current_reply(conn, rcookie, NULL)) == NULL) { - disable_randr(conn); + if ((res = xcb_randr_get_screen_resources_current_reply(conn, rcookie, NULL)) == NULL) return; - } + cts = res->config_timestamp; int len = xcb_randr_get_screen_resources_current_outputs_length(res); @@ -638,6 +647,16 @@ void randr_query_outputs(void) { free(output); } + /* If there's no randr output, enable the output covering the root window. */ + if (any_randr_output_active()) { + DLOG("Active RandR output found. Disabling root output.\n"); + if (root_output->active) + root_output->to_be_disabled = true; + } else { + DLOG("No active RandR output found. Enabling root output.\n"); + root_output->active = true; + } + /* Check for clones, disable the clones and reduce the mode to the * lowest common mode */ TAILQ_FOREACH(output, &outputs, outputs) { @@ -779,11 +798,6 @@ void randr_query_outputs(void) { } } - if (TAILQ_EMPTY(&outputs)) { - ELOG("No outputs found via RandR, disabling\n"); - disable_randr(conn); - } - /* Just go through each active output and assign one workspace */ TAILQ_FOREACH(output, &outputs, outputs) { if (!output->active) @@ -819,12 +833,13 @@ void randr_query_outputs(void) { void randr_init(int *event_base) { const xcb_query_extension_reply_t *extreply; + create_root_output(conn); + extreply = xcb_get_extension_data(conn, &xcb_randr_id); - if (!extreply->present) { - disable_randr(conn); + if (!extreply->present) return; - } else - randr_query_outputs(); + + randr_query_outputs(); if (event_base != NULL) *event_base = extreply->first_event; diff --git a/src/xinerama.c b/src/xinerama.c index cae71fc2..049e1bc4 100644 --- a/src/xinerama.c +++ b/src/xinerama.c @@ -94,15 +94,15 @@ 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, disabling.\n"); - disable_randr(conn); + DLOG("Xinerama extension not found, using root output.\n"); + create_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), disabling.\n"); - disable_randr(conn); + DLOG("Xinerama is not active (in your X-Server), using root output.\n"); + create_root_output(conn); } else query_screens(conn);