Bugfix: Correctly hide/show workspaces when enabling new outputs, correctly handle focus (Thanks Merovius)
This commit is contained in:
parent
718d62a3cd
commit
8b192ac7ed
|
@ -53,7 +53,7 @@ void workspace_show(xcb_connection_t *conn, int workspace);
|
||||||
* screen 1 and you just plugged in screen 1).
|
* screen 1 and you just plugged in screen 1).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void workspace_assign_to(Workspace *ws, Output *screen);
|
void workspace_assign_to(Workspace *ws, Output *screen, bool hide_it);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the given workspace if it is not already initialized. The given
|
* Initializes the given workspace if it is not already initialized. The given
|
||||||
|
|
|
@ -179,6 +179,24 @@ static void check_crossing_screen_boundary(uint32_t x, uint32_t y) {
|
||||||
current_row = c_ws->current_row;
|
current_row = c_ws->current_row;
|
||||||
current_col = c_ws->current_col;
|
current_col = c_ws->current_col;
|
||||||
DLOG("We're now on output %p\n", output);
|
DLOG("We're now on output %p\n", output);
|
||||||
|
|
||||||
|
/* While usually this function is only called when the user switches
|
||||||
|
* to a different output using his mouse (and thus the output is
|
||||||
|
* empty), it may be that the following race condition occurs:
|
||||||
|
* 1) the user actives a new output (say VGA1).
|
||||||
|
* 2) the cursor is sent to the first pixel of the new VGA1, thus
|
||||||
|
* generating an enter_notify for the screen (the enter_notify
|
||||||
|
* is not yet received by i3).
|
||||||
|
* 3) i3 requeries screen configuration and maps a workspace onto the
|
||||||
|
* new output.
|
||||||
|
* 4) the enter_notify event arrives and c_ws is set to the new
|
||||||
|
* workspace but the existing windows on the new workspace are not
|
||||||
|
* focused.
|
||||||
|
*
|
||||||
|
* Therefore, we re-set the focus here to be sure it’s correct. */
|
||||||
|
Client *first_client = SLIST_FIRST(&(c_ws->focus_stack));
|
||||||
|
if (first_client != NULL)
|
||||||
|
set_focus(global_conn, first_client, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -162,6 +162,12 @@ static void initialize_output(xcb_connection_t *conn, Output *output,
|
||||||
workspace->output = output;
|
workspace->output = output;
|
||||||
output->current_workspace = workspace;
|
output->current_workspace = workspace;
|
||||||
|
|
||||||
|
/* Copy rect for the workspace */
|
||||||
|
memcpy(&(workspace->rect), &(output->rect), sizeof(Rect));
|
||||||
|
|
||||||
|
/* Map clients on the workspace, if any */
|
||||||
|
workspace_map_clients(conn, workspace);
|
||||||
|
|
||||||
/* Create a xoutput for each output */
|
/* Create a xoutput for each output */
|
||||||
Rect bar_rect = {output->rect.x,
|
Rect bar_rect = {output->rect.x,
|
||||||
output->rect.y + output->rect.height - (font->height + 6),
|
output->rect.y + output->rect.height - (font->height + 6),
|
||||||
|
@ -437,7 +443,7 @@ void randr_query_screens(xcb_connection_t *conn) {
|
||||||
if (ws->output != output)
|
if (ws->output != output)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
workspace_assign_to(ws, first);
|
workspace_assign_to(ws, first, true);
|
||||||
if (!needs_init)
|
if (!needs_init)
|
||||||
continue;
|
continue;
|
||||||
initialize_output(conn, first, ws);
|
initialize_output(conn, first, ws);
|
||||||
|
|
|
@ -204,7 +204,7 @@ void workspace_show(xcb_connection_t *conn, int workspace) {
|
||||||
* output 1 and you just plugged in output 1).
|
* output 1 and you just plugged in output 1).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void workspace_assign_to(Workspace *ws, Output *output) {
|
void workspace_assign_to(Workspace *ws, Output *output, bool hide_it) {
|
||||||
Client *client;
|
Client *client;
|
||||||
bool empty = true;
|
bool empty = true;
|
||||||
bool visible = workspace_is_visible(ws);
|
bool visible = workspace_is_visible(ws);
|
||||||
|
@ -229,7 +229,7 @@ void workspace_assign_to(Workspace *ws, Output *output) {
|
||||||
render_workspace(global_conn, output, ws);
|
render_workspace(global_conn, output, ws);
|
||||||
|
|
||||||
/* …unless we want to see them at the moment, we should hide that workspace */
|
/* …unless we want to see them at the moment, we should hide that workspace */
|
||||||
if (visible)
|
if (visible && !hide_it)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
workspace_unmap_clients(global_conn, ws);
|
workspace_unmap_clients(global_conn, ws);
|
||||||
|
@ -269,7 +269,7 @@ void workspace_initialize(Workspace *ws, Output *output, bool recheck) {
|
||||||
if (old_output != NULL && ws->output == old_output)
|
if (old_output != NULL && ws->output == old_output)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
workspace_assign_to(ws, ws->output);
|
workspace_assign_to(ws, ws->output, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue