RandR: respect primary output

This commit is contained in:
Michael Stapelberg 2011-01-27 15:40:02 +01:00
parent 432563d6e7
commit fe851b85f0
2 changed files with 43 additions and 9 deletions

View File

@ -198,6 +198,7 @@ struct xoutput {
* two stages) */ * two stages) */
bool changed; bool changed;
bool to_be_disabled; bool to_be_disabled;
bool primary;
/** x, y, width, height */ /** x, y, width, height */
Rect rect; Rect rect;

View File

@ -24,6 +24,9 @@ typedef xcb_randr_get_crtc_info_reply_t crtc_info;
typedef xcb_randr_mode_info_t mode_info; typedef xcb_randr_mode_info_t mode_info;
typedef xcb_randr_get_screen_resources_current_reply_t resources_reply; typedef xcb_randr_get_screen_resources_current_reply_t resources_reply;
/* Pointer to the result of the query for primary output */
xcb_randr_get_output_primary_reply_t *primary;
/* Stores all outputs available in your current session. */ /* Stores all outputs available in your current session. */
struct outputs_head outputs = TAILQ_HEAD_INITIALIZER(outputs); struct outputs_head outputs = TAILQ_HEAD_INITIALIZER(outputs);
@ -386,6 +389,7 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
if (!existing) if (!existing)
new = scalloc(sizeof(Output)); new = scalloc(sizeof(Output));
new->id = id; new->id = id;
new->primary = (primary && primary->output == id);
FREE(new->name); FREE(new->name);
asprintf(&new->name, "%.*s", asprintf(&new->name, "%.*s",
xcb_randr_get_output_info_name_length(output), xcb_randr_get_output_info_name_length(output),
@ -397,9 +401,11 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
* we do not need to change the list ever again (we only update the * we do not need to change the list ever again (we only update the
* position/size) */ * position/size) */
if (output->crtc == XCB_NONE) { if (output->crtc == XCB_NONE) {
if (!existing) if (!existing) {
TAILQ_INSERT_TAIL(&outputs, new, outputs); if (new->primary)
else if (new->active) TAILQ_INSERT_HEAD(&outputs, new, outputs);
else TAILQ_INSERT_TAIL(&outputs, new, outputs);
} else if (new->active)
new->to_be_disabled = true; new->to_be_disabled = true;
return; return;
} }
@ -431,8 +437,11 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
* does not exist in the first place, the case is simple: we either * does not exist in the first place, the case is simple: we either
* need to insert the new output or we are done. */ * need to insert the new output or we are done. */
if (!updated || !existing) { if (!updated || !existing) {
if (!existing) if (!existing) {
TAILQ_INSERT_TAIL(&outputs, new, outputs); if (new->primary)
TAILQ_INSERT_HEAD(&outputs, new, outputs);
else TAILQ_INSERT_TAIL(&outputs, new, outputs);
}
return; return;
} }
@ -445,8 +454,10 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
*/ */
void randr_query_outputs() { void randr_query_outputs() {
Output *output, *other, *first; Output *output, *other, *first;
xcb_randr_get_output_primary_cookie_t pcookie;
xcb_randr_get_screen_resources_current_cookie_t rcookie; xcb_randr_get_screen_resources_current_cookie_t rcookie;
resources_reply *res; resources_reply *res;
/* timestamp of the configuration so that we get consistent replies to all /* timestamp of the configuration so that we get consistent replies to all
* requests (if the configuration changes between our different calls) */ * requests (if the configuration changes between our different calls) */
xcb_timestamp_t cts; xcb_timestamp_t cts;
@ -457,8 +468,13 @@ void randr_query_outputs() {
if (randr_disabled) if (randr_disabled)
return; return;
/* Get screen resources (crtcs, outputs, modes) */ /* Get screen resources (primary output, crtcs, outputs, modes) */
rcookie = xcb_randr_get_screen_resources_current(conn, root); rcookie = xcb_randr_get_screen_resources_current(conn, root);
pcookie = xcb_randr_get_output_primary(conn, root);
if ((primary = xcb_randr_get_output_primary_reply(conn, pcookie, NULL)) == NULL)
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) { if ((res = xcb_randr_get_screen_resources_current_reply(conn, rcookie, NULL)) == NULL) {
disable_randr(conn); disable_randr(conn);
return; return;
@ -484,14 +500,13 @@ void randr_query_outputs() {
free(output); free(output);
} }
free(res);
/* Check for clones, disable the clones and reduce the mode to the /* Check for clones, disable the clones and reduce the mode to the
* lowest common mode */ * lowest common mode */
TAILQ_FOREACH(output, &outputs, outputs) { TAILQ_FOREACH(output, &outputs, outputs) {
if (!output->active || output->to_be_disabled) if (!output->active || output->to_be_disabled)
continue; continue;
DLOG("output %p, position (%d, %d), checking for clones\n", DLOG("output %p / %s, position (%d, %d), checking for clones\n",
output, output->rect.x, output->rect.y); output, output->name, output->rect.x, output->rect.y);
for (other = output; for (other = output;
other != TAILQ_END(&outputs); other != TAILQ_END(&outputs);
@ -568,6 +583,7 @@ void randr_query_outputs() {
} }
output->to_be_disabled = false; output->to_be_disabled = false;
output->changed = false;
} }
if (output->active && output->con == NULL) { if (output->active && output->con == NULL) {
@ -599,8 +615,25 @@ void randr_query_outputs() {
} }
#endif #endif
/* Focus the primary screen, if possible */
TAILQ_FOREACH(output, &outputs, outputs) {
if (!output->primary || !output->con)
continue;
DLOG("Focusing primary output %s\n", output->name);
Con *next = output->con;
while (!TAILQ_EMPTY(&(next->focus_head)))
next = TAILQ_FIRST(&(next->focus_head));
DLOG("focusing %p\n", next);
con_focus(next);
}
/* render_layout flushes */ /* render_layout flushes */
tree_render(); tree_render();
FREE(res);
FREE(primary);
} }
/* /*