Skip to content

Commit

Permalink
Don't raise floating windows when focused because of focus_follows_mouse
Browse files Browse the repository at this point in the history
Fixes i3#2990.
  • Loading branch information
orestisfl committed Jan 14, 2018
1 parent 2b5b633 commit 0c2fbee
Show file tree
Hide file tree
Showing 15 changed files with 99 additions and 51 deletions.
6 changes: 6 additions & 0 deletions include/con.h
Expand Up @@ -38,6 +38,12 @@ void con_free(Con *con);
*/
void con_focus(Con *con);

/**
* Sets input focus to the given container and raises it to the top.
*
*/
void con_activate(Con *con);

/**
* Closes the given container.
*
Expand Down
4 changes: 2 additions & 2 deletions src/click.c
Expand Up @@ -241,7 +241,7 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod
* The splitv container will be focused. */
Con *focused = con->parent;
focused = TAILQ_FIRST(&(focused->focus_head));
con_focus(focused);
con_activate(focused);
/* To prevent scrolling from going outside the container (see ticket
* #557), we first check if scrolling is possible at all. */
bool scroll_prev_possible = (TAILQ_PREV(focused, nodes_head, nodes) != NULL);
Expand All @@ -256,7 +256,7 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod
}

/* 2: focus this con. */
con_focus(con);
con_activate(con);

/* 3: For floating containers, we also want to raise them on click.
* We will skip handling events on floating cons in fullscreen mode */
Expand Down
12 changes: 6 additions & 6 deletions src/commands.c
Expand Up @@ -1261,7 +1261,7 @@ static void cmd_focus_force_focus(Con *con) {
if (fullscreen_on_ws && fullscreen_on_ws != con && !con_has_parent(con, fullscreen_on_ws)) {
con_disable_fullscreen(fullscreen_on_ws);
}
con_focus(con);
con_activate(con);
}

/*
Expand Down Expand Up @@ -1379,12 +1379,12 @@ void cmd_focus(I3_CMD) {
* the target workspace, then revert focus. */
Con *currently_focused = focused;
cmd_focus_force_focus(current->con);
con_focus(currently_focused);
con_activate(currently_focused);

/* Now switch to the workspace, then focus */
workspace_show(ws);
LOG("focusing %p / %s\n", current->con, current->con->name);
con_focus(current->con);
con_activate(current->con);
count++;
}

Expand Down Expand Up @@ -1496,7 +1496,7 @@ void cmd_move_direction(I3_CMD, const char *direction, long move_px) {

/* the move command should not disturb focus */
if (focused != initially_focused)
con_focus(initially_focused);
con_activate(initially_focused);

// XXX: default reply for now, make this a better reply
ysuccess(true);
Expand Down Expand Up @@ -1621,7 +1621,7 @@ void cmd_open(I3_CMD) {
LOG("opening new container\n");
Con *con = tree_open_con(NULL, NULL);
con->layout = L_SPLITH;
con_focus(con);
con_activate(con);

y(map_open);
ystr("success");
Expand Down Expand Up @@ -2010,7 +2010,7 @@ void cmd_rename_workspace(I3_CMD, const char *old_name, const char *new_name) {
}

/* Restore the previous focus since con_attach messes with the focus. */
con_focus(previously_focused);
con_activate(previously_focused);

cmd_output->needs_tree_render = true;
ysuccess(true);
Expand Down
46 changes: 30 additions & 16 deletions src/con.c
Expand Up @@ -243,15 +243,29 @@ void con_focus(Con *con) {
workspace_update_urgent_flag(con_get_workspace(con));
ipc_send_window_event("urgent", con);
}
}

/* Focusing a container with a floating parent should raise it to the top. Since
* con_focus is called recursively for each parent we don't need to use
* con_inside_floating(). */
if (con->type == CT_FLOATING_CON) {
floating_raise_con(con);
/*
* Raise container to the top if it is floating or inside some floating
* container.
*
*/
static void con_raise(Con *con) {
Con *floating = con_inside_floating(con);
if (floating) {
floating_raise_con(floating);
}
}

/*
* Sets input focus to the given container and raises it to the top.
*
*/
void con_activate(Con *con) {
con_focus(con);
con_raise(con);
}

/*
* Closes the given container.
*
Expand Down Expand Up @@ -994,9 +1008,9 @@ void con_enable_fullscreen(Con *con, fullscreen_mode_t fullscreen_mode) {
Con *old_focused = focused;
if (fullscreen_mode == CF_GLOBAL && cur_ws != con_ws)
workspace_show(con_ws);
con_focus(con);
con_activate(con);
if (fullscreen_mode != CF_GLOBAL && cur_ws != con_ws)
con_focus(old_focused);
con_activate(old_focused);

con_set_fullscreen_mode(con, fullscreen_mode);
}
Expand Down Expand Up @@ -1148,11 +1162,11 @@ static bool _con_move_to_con(Con *con, Con *target, bool behind_focused, bool fi
* new workspace is hidden and it's necessary to immediately switch
* back to the originally-focused workspace. */
Con *old_focus = TAILQ_FIRST(&(output_get_content(dest_output)->focus_head));
con_focus(con_descend_focused(con));
con_activate(con_descend_focused(con));

/* Restore focus if the output's focused workspace has changed. */
if (con_get_workspace(focused) != old_focus)
con_focus(old_focus);
con_activate(old_focus);
}

/* 7: when moving to another workspace, we leave the focus on the current
Expand All @@ -1172,7 +1186,7 @@ static bool _con_move_to_con(Con *con, Con *target, bool behind_focused, bool fi
/* Set focus only if con was on current workspace before moving.
* Otherwise we would give focus to some window on different workspace. */
if (!ignore_focus && source_ws == current_ws)
con_focus(con_descend_focused(focus_next));
con_activate(con_descend_focused(focus_next));

/* 8. If anything within the container is associated with a startup sequence,
* delete it so child windows won't be created on the old workspace. */
Expand Down Expand Up @@ -1791,7 +1805,7 @@ void con_set_layout(Con *con, layout_t layout) {
con_attach(new, con, false);

if (old_focused)
con_focus(old_focused);
con_activate(old_focused);

tree_flatten(croot);
}
Expand Down Expand Up @@ -2358,7 +2372,7 @@ bool con_swap(Con *first, Con *second) {
* We don't need to check this for the second container because we've only
* moved the first one at this point.*/
if (first_ws != second_ws && focused_within_first) {
con_focus(con_descend_focused(current_ws));
con_activate(con_descend_focused(current_ws));
}

/* Move second to where first has been originally. */
Expand Down Expand Up @@ -2401,15 +2415,15 @@ bool con_swap(Con *first, Con *second) {
*/
if (focused_within_first) {
if (first_ws == second_ws) {
con_focus(old_focus);
con_activate(old_focus);
} else {
con_focus(con_descend_focused(second));
con_activate(con_descend_focused(second));
}
} else if (focused_within_second) {
if (first_ws == second_ws) {
con_focus(old_focus);
con_activate(old_focus);
} else {
con_focus(con_descend_focused(first));
con_activate(con_descend_focused(first));
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/floating.c
Expand Up @@ -318,7 +318,7 @@ void floating_enable(Con *con, bool automatic) {
render_con(con, false);

if (set_focus)
con_focus(con);
con_activate(con);

/* Check if we need to re-assign it to a different workspace because of its
* coordinates and exit if that was done successfully. */
Expand Down Expand Up @@ -382,7 +382,7 @@ void floating_disable(Con *con, bool automatic) {
con_fix_percent(con->parent);

if (set_focus)
con_focus(con);
con_activate(con);

floating_set_hint_atom(con, false);
ipc_send_window_event("floating", con);
Expand Down Expand Up @@ -450,7 +450,7 @@ bool floating_maybe_reassign_ws(Con *con) {
DLOG("Moving con %p / %s to workspace %p / %s\n", con, con->name, ws, ws->name);
con_move_to_workspace(con, ws, false, true, false);
workspace_show(ws);
con_focus(con_descend_focused(con));
con_activate(con_descend_focused(con));
return true;
}

Expand Down
8 changes: 4 additions & 4 deletions src/handlers.c
Expand Up @@ -433,7 +433,7 @@ static void handle_configure_request(xcb_configure_request_event_t *event) {
if (config.focus_on_window_activation == FOWA_FOCUS || (config.focus_on_window_activation == FOWA_SMART && workspace_is_visible(ws))) {
DLOG("Focusing con = %p\n", con);
workspace_show(ws);
con_focus(con);
con_activate(con);
tree_render();
} else if (config.focus_on_window_activation == FOWA_URGENT || (config.focus_on_window_activation == FOWA_SMART && !workspace_is_visible(ws))) {
DLOG("Marking con = %p urgent\n", con);
Expand Down Expand Up @@ -776,7 +776,7 @@ static void handle_client_message(xcb_client_message_event_t *event) {
workspace_show(ws);
/* Re-set focus, even if unchanged from i3’s perspective. */
focused_id = XCB_NONE;
con_focus(con);
con_activate(con);
}
} else {
/* Request is from an application. */
Expand All @@ -788,7 +788,7 @@ static void handle_client_message(xcb_client_message_event_t *event) {
if (config.focus_on_window_activation == FOWA_FOCUS || (config.focus_on_window_activation == FOWA_SMART && workspace_is_visible(ws))) {
DLOG("Focusing con = %p\n", con);
workspace_show(ws);
con_focus(con);
con_activate(con);
} else if (config.focus_on_window_activation == FOWA_URGENT || (config.focus_on_window_activation == FOWA_SMART && !workspace_is_visible(ws))) {
DLOG("Marking con = %p urgent\n", con);
con_set_urgency(con, true);
Expand Down Expand Up @@ -1245,7 +1245,7 @@ static void handle_focus_in(xcb_focus_in_event_t *event) {
if (ws != con_get_workspace(focused))
workspace_show(ws);

con_focus(con);
con_activate(con);
/* We update focused_id because we don’t need to set focus again */
focused_id = event->event;
tree_render();
Expand Down
2 changes: 1 addition & 1 deletion src/load_layout.c
Expand Up @@ -654,6 +654,6 @@ void tree_append_json(Con *con, const char *buf, const size_t len, char **errorm
yajl_free(hand);

if (to_focus) {
con_focus(to_focus);
con_activate(to_focus);
}
}
2 changes: 1 addition & 1 deletion src/main.c
Expand Up @@ -766,7 +766,7 @@ int main(int argc, char *argv[]) {
output = get_first_output();
}

con_focus(con_descend_focused(output_get_content(output->con)));
con_activate(con_descend_focused(output_get_content(output->con)));
free(pointerreply);
}

Expand Down
2 changes: 1 addition & 1 deletion src/manage.c
Expand Up @@ -646,7 +646,7 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
* proper window event sequence. */
if (set_focus && nc->mapped) {
DLOG("Now setting focus.\n");
con_focus(nc);
con_activate(nc);
}

tree_render();
Expand Down
2 changes: 1 addition & 1 deletion src/move.c
Expand Up @@ -118,7 +118,7 @@ static void move_to_output_directed(Con *con, direction_t direction) {
attach_to_workspace(con, ws, direction);

/* fix the focus stack */
con_focus(con);
con_activate(con);

/* force re-painting the indicators */
FREE(con->deco_render_params);
Expand Down
6 changes: 3 additions & 3 deletions src/randr.c
Expand Up @@ -496,7 +496,7 @@ void init_ws_for_output(Output *output, Con *content) {
Con *ws = create_workspace_on_output(output, content);

/* TODO: Set focus in main.c */
con_focus(ws);
con_activate(ws);
}

/*
Expand Down Expand Up @@ -924,7 +924,7 @@ void randr_query_outputs(void) {
continue;

DLOG("Focusing primary output %s\n", output_primary_name(output));
con_focus(con_descend_focused(output->con));
con_activate(con_descend_focused(output->con));
}

/* render_layout flushes */
Expand Down Expand Up @@ -987,7 +987,7 @@ void randr_disable_output(Output *output) {

if (next) {
DLOG("now focusing next = %p\n", next);
con_focus(next);
con_activate(next);
workspace_show(con_get_workspace(next));
}

Expand Down
4 changes: 2 additions & 2 deletions src/scratchpad.c
Expand Up @@ -123,7 +123,7 @@ void scratchpad_show(Con *con) {
/* use con_descend_tiling_focused to get the last focused
* window inside this scratch container in order to
* keep the focus the same within this container */
con_focus(con_descend_tiling_focused(walk_con));
con_activate(con_descend_tiling_focused(walk_con));
return;
}
}
Expand Down Expand Up @@ -205,7 +205,7 @@ void scratchpad_show(Con *con) {
workspace_show(active);
}

con_focus(con_descend_focused(con));
con_activate(con_descend_focused(con));
}

/*
Expand Down

0 comments on commit 0c2fbee

Please sign in to comment.