Bugfix: Fix clone mode with new RandR code (Thanks Merovius)
This commit is contained in:
parent
d73f1748db
commit
718d62a3cd
|
@ -513,6 +513,11 @@ struct xoutput {
|
|||
* mode) */
|
||||
bool active;
|
||||
|
||||
/** Internal flags, necessary for querying RandR screens (happens in
|
||||
* two stages) */
|
||||
bool changed;
|
||||
bool to_be_disabled;
|
||||
|
||||
/** Current workspace selected on this virtual screen */
|
||||
Workspace *current_workspace;
|
||||
|
||||
|
|
77
src/randr.c
77
src/randr.c
|
@ -270,14 +270,14 @@ static void output_change_mode(xcb_connection_t *conn, Output *output) {
|
|||
/*
|
||||
* Gets called by randr_query_screens() for each output. The function adds new
|
||||
* outputs to the list of outputs, checks if the mode of existing outputs has
|
||||
* been changed or if an existing output has been disabled.
|
||||
* been changed or if an existing output has been disabled. It will then change
|
||||
* either the "changed" or the "to_be_deleted" flag of the output, if
|
||||
* appropriate.
|
||||
*
|
||||
*/
|
||||
static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
|
||||
xcb_randr_get_output_info_reply_t *output,
|
||||
xcb_timestamp_t cts, resources_reply *res) {
|
||||
Workspace *ws;
|
||||
|
||||
/* each CRT controller has a position in which we are interested in */
|
||||
crtc_info *crtc;
|
||||
|
||||
|
@ -303,15 +303,7 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
|
|||
if (!existing)
|
||||
TAILQ_INSERT_TAIL(&outputs, new, outputs);
|
||||
else if (new->active) {
|
||||
new->active = false;
|
||||
new->current_workspace = NULL;
|
||||
DLOG("Output %s disabled (no CRTC)\n", new->name);
|
||||
TAILQ_FOREACH(ws, workspaces, workspaces) {
|
||||
if (ws->output != new)
|
||||
continue;
|
||||
|
||||
workspace_assign_to(ws, get_first_output());
|
||||
}
|
||||
new->to_be_disabled = true;
|
||||
|
||||
}
|
||||
free(output);
|
||||
|
@ -348,7 +340,7 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
|
|||
return;
|
||||
}
|
||||
|
||||
output_change_mode(conn, new);
|
||||
new->changed = true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -356,6 +348,7 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
|
|||
*
|
||||
*/
|
||||
void randr_query_screens(xcb_connection_t *conn) {
|
||||
Workspace *ws;
|
||||
xcb_randr_get_screen_resources_current_cookie_t rcookie;
|
||||
resources_reply *res;
|
||||
/* timestamp of the configuration so that we get consistent replies to all
|
||||
|
@ -380,8 +373,9 @@ void randr_query_screens(xcb_connection_t *conn) {
|
|||
ocookie[i] = xcb_randr_get_output_info(conn, randr_outputs[i], cts);
|
||||
|
||||
/* Loop through all outputs available for this X11 screen */
|
||||
xcb_randr_get_output_info_reply_t *output;
|
||||
for (int i = 0; i < len; i++) {
|
||||
xcb_randr_get_output_info_reply_t *output;
|
||||
|
||||
if ((output = xcb_randr_get_output_info_reply(conn, ocookie[i], NULL)) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -392,13 +386,15 @@ void randr_query_screens(xcb_connection_t *conn) {
|
|||
Output *screen, *oscreen;
|
||||
/* Check for clones and reduce the mode to the lowest common mode */
|
||||
TAILQ_FOREACH(screen, &outputs, outputs) {
|
||||
if (!screen->active)
|
||||
if (!screen->active || screen->to_be_disabled)
|
||||
continue;
|
||||
DLOG("screen %p, position (%d, %d), checking for clones\n",
|
||||
screen, screen->rect.x, screen->rect.y);
|
||||
|
||||
TAILQ_FOREACH(oscreen, &outputs, outputs) {
|
||||
if (oscreen == screen || !oscreen->active)
|
||||
for (oscreen = screen;
|
||||
oscreen != TAILQ_END(&outputs);
|
||||
oscreen = TAILQ_NEXT(oscreen, outputs)) {
|
||||
if (oscreen == screen || !oscreen->active || oscreen->to_be_disabled)
|
||||
continue;
|
||||
|
||||
if (oscreen->rect.x != screen->rect.x ||
|
||||
|
@ -412,12 +408,13 @@ void randr_query_screens(xcb_connection_t *conn) {
|
|||
|
||||
if (update_if_necessary(&(screen->rect.width), width) |
|
||||
update_if_necessary(&(screen->rect.height), height))
|
||||
output_change_mode(conn, screen);
|
||||
screen->changed = true;
|
||||
|
||||
if (update_if_necessary(&(oscreen->rect.width), width) |
|
||||
update_if_necessary(&(oscreen->rect.height), height))
|
||||
output_change_mode(conn, oscreen);
|
||||
update_if_necessary(&(oscreen->rect.width), width);
|
||||
update_if_necessary(&(oscreen->rect.height), height);
|
||||
|
||||
DLOG("disabling screen %p (%s)\n", oscreen, oscreen->name);
|
||||
oscreen->to_be_disabled = true;
|
||||
|
||||
DLOG("new screen mode %d x %d, oscreen mode %d x %d\n",
|
||||
screen->rect.width, screen->rect.height,
|
||||
|
@ -425,13 +422,49 @@ void randr_query_screens(xcb_connection_t *conn) {
|
|||
}
|
||||
}
|
||||
|
||||
Output *output, *first;
|
||||
TAILQ_FOREACH(output, &outputs, outputs) {
|
||||
if (output->to_be_disabled) {
|
||||
output->active = false;
|
||||
DLOG("Output %s disabled, re-assigning workspaces/docks\n", output->name);
|
||||
|
||||
if ((first = get_first_output()) == NULL)
|
||||
die("No usable outputs available\n");
|
||||
|
||||
bool needs_init = (first->current_workspace == NULL);
|
||||
|
||||
TAILQ_FOREACH(ws, workspaces, workspaces) {
|
||||
if (ws->output != output)
|
||||
continue;
|
||||
|
||||
workspace_assign_to(ws, first);
|
||||
if (!needs_init)
|
||||
continue;
|
||||
initialize_output(conn, first, ws);
|
||||
needs_init = false;
|
||||
}
|
||||
|
||||
Client *dock;
|
||||
while (!SLIST_EMPTY(&(output->dock_clients))) {
|
||||
dock = SLIST_FIRST(&(output->dock_clients));
|
||||
SLIST_INSERT_HEAD(&(first->dock_clients), dock, dock_clients);
|
||||
SLIST_REMOVE_HEAD(&(output->dock_clients), dock_clients);
|
||||
}
|
||||
output->current_workspace = NULL;
|
||||
output->to_be_disabled = false;
|
||||
} else if (output->changed) {
|
||||
output_change_mode(conn, output);
|
||||
output->changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
ewmh_update_workarea();
|
||||
|
||||
/* Just go through each active output and associate one workspace */
|
||||
TAILQ_FOREACH(screen, &outputs, outputs) {
|
||||
if (!screen->active || screen->current_workspace != NULL)
|
||||
continue;
|
||||
Workspace *ws = get_first_workspace_for_screen(screen);
|
||||
ws = get_first_workspace_for_screen(screen);
|
||||
initialize_output(conn, screen, ws);
|
||||
}
|
||||
|
||||
|
|
|
@ -207,6 +207,7 @@ void workspace_show(xcb_connection_t *conn, int workspace) {
|
|||
void workspace_assign_to(Workspace *ws, Output *output) {
|
||||
Client *client;
|
||||
bool empty = true;
|
||||
bool visible = workspace_is_visible(ws);
|
||||
|
||||
ws->output = output;
|
||||
|
||||
|
@ -228,14 +229,14 @@ void workspace_assign_to(Workspace *ws, Output *output) {
|
|||
render_workspace(global_conn, output, ws);
|
||||
|
||||
/* …unless we want to see them at the moment, we should hide that workspace */
|
||||
if (workspace_is_visible(ws))
|
||||
if (visible)
|
||||
return;
|
||||
|
||||
workspace_unmap_clients(global_conn, ws);
|
||||
|
||||
if (c_ws == ws) {
|
||||
DLOG("Need to adjust c_ws...\n");
|
||||
c_ws = output->current_workspace;
|
||||
DLOG("Need to adjust output->current_workspace...\n");
|
||||
output->current_workspace = c_ws;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue