diff options
Diffstat (limited to 'sway')
| -rw-r--r-- | sway/commands/focus.c | 7 | ||||
| -rw-r--r-- | sway/input/seat.c | 126 | 
2 files changed, 78 insertions, 55 deletions
| diff --git a/sway/commands/focus.c b/sway/commands/focus.c index 76d3f1dc..135a2908 100644 --- a/sway/commands/focus.c +++ b/sway/commands/focus.c @@ -46,14 +46,13 @@ static struct cmd_results *focus_mode(struct sway_container *con,  	struct sway_container *new_focus = NULL;  	if (floating) { -		new_focus = seat_get_focus_inactive(seat, ws->sway_workspace->floating); +		new_focus = seat_get_focus_inactive_floating(seat, ws);  	} else {  		new_focus = seat_get_focus_inactive_tiling(seat, ws);  	} -	if (!new_focus) { -		new_focus = ws; +	if (new_focus) { +		seat_set_focus(seat, new_focus);  	} -	seat_set_focus(seat, new_focus);  	return cmd_results_new(CMD_SUCCESS, NULL, NULL);  } diff --git a/sway/input/seat.c b/sway/input/seat.c index 57cc65f6..fa41904a 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -124,42 +124,6 @@ static void seat_send_focus(struct sway_container *con,  	}  } -static struct sway_container *seat_get_focus_by_type(struct sway_seat *seat, -		struct sway_container *container, enum sway_container_type type, -		bool only_tiling) { -	if (container->type == C_VIEW) { -		return container; -	} - -	struct sway_container *floating = -		container->type == C_WORKSPACE && !only_tiling ? -		container->sway_workspace->floating : NULL; -	if (container->children->length == 0 && -			(!floating || floating->children->length == 0)) { -		return container; -	} - -	struct sway_seat_container *current = NULL; -	wl_list_for_each(current, &seat->focus_stack, link) { -		if (current->container->type != type && type != C_TYPES) { -			continue; -		} - -		if (container_has_ancestor(current->container, container)) { -			if (only_tiling && -					container_is_floating_or_child(current->container)) { -				continue; -			} -			return current->container; -		} -		if (floating && container_has_ancestor(current->container, floating)) { -			return current->container; -		} -	} - -	return NULL; -} -  void seat_focus_inactive_children_for_each(struct sway_seat *seat,  		struct sway_container *container,  		void (*f)(struct sway_container *container, void *data), void *data) { @@ -175,8 +139,18 @@ void seat_focus_inactive_children_for_each(struct sway_seat *seat,  }  struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, -		struct sway_container *container) { -	return seat_get_focus_by_type(seat, container, C_VIEW, false); +		struct sway_container *ancestor) { +	if (ancestor->type == C_VIEW) { +		return ancestor; +	} +	struct sway_seat_container *current; +	wl_list_for_each(current, &seat->focus_stack, link) { +		struct sway_container *con = current->container; +		if (con->type == C_VIEW && container_has_ancestor(con, ancestor)) { +			return con; +		} +	} +	return NULL;  }  static void handle_seat_container_destroy(struct wl_listener *listener, @@ -198,7 +172,7 @@ static void handle_seat_container_destroy(struct wl_listener *listener,  	if (set_focus) {  		struct sway_container *next_focus = NULL;  		while (next_focus == NULL) { -			next_focus = seat_get_focus_by_type(seat, parent, C_VIEW, false); +			next_focus = seat_get_focus_inactive_view(seat, parent);  			if (next_focus == NULL && parent->type == C_WORKSPACE) {  				next_focus = parent; @@ -653,8 +627,7 @@ void seat_set_focus_warp(struct sway_seat *seat,  	// find new output's old workspace, which might have to be removed if empty  	struct sway_container *new_output_last_ws = NULL;  	if (last_output && new_output && last_output != new_output) { -		new_output_last_ws = -			seat_get_focus_by_type(seat, new_output, C_WORKSPACE, false); +		new_output_last_ws = seat_get_active_child(seat, new_output);  	}  	if (container && container->parent) { @@ -877,22 +850,71 @@ void seat_set_exclusive_client(struct sway_seat *seat,  }  struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, -		struct sway_container *container) { -	return seat_get_focus_by_type(seat, container, C_TYPES, false); +		struct sway_container *con) { +	if (con->type == C_WORKSPACE && !con->children->length && +			!con->sway_workspace->floating->children->length) { +		return con; +	} +	if (con->type == C_VIEW) { +		return con; +	} +	struct sway_seat_container *current; +	wl_list_for_each(current, &seat->focus_stack, link) { +		if (container_has_ancestor(current->container, con)) { +			return current->container; +		} +	} +	return NULL;  }  struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat, -		struct sway_container *container) { -	return seat_get_focus_by_type(seat, container, C_TYPES, true); +		struct sway_container *ancestor) { +	if (ancestor->type == C_WORKSPACE && !ancestor->children->length) { +		return ancestor; +	} +	struct sway_seat_container *current; +	wl_list_for_each(current, &seat->focus_stack, link) { +		struct sway_container *con = current->container; +		if (con->layout != L_FLOATING && !container_is_floating_or_child(con) && +				container_has_ancestor(current->container, ancestor)) { +			return con; +		} +	} +	return NULL; +} + +struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat, +		struct sway_container *ancestor) { +	if (ancestor->type == C_WORKSPACE && +			!ancestor->sway_workspace->floating->children->length) { +		return NULL; +	} +	struct sway_seat_container *current; +	wl_list_for_each(current, &seat->focus_stack, link) { +		struct sway_container *con = current->container; +		if (con->layout != L_FLOATING && container_is_floating_or_child(con) && +				container_has_ancestor(current->container, ancestor)) { +			return con; +		} +	} +	return NULL; +} + +static bool impl_focus_active_child(struct sway_container *con, void *data) { +	struct sway_container *parent = data; +	return con->parent == parent && con->layout != L_FLOATING;  }  struct sway_container *seat_get_active_child(struct sway_seat *seat, -		struct sway_container *container) { -	struct sway_seat_container *current = NULL; +		struct sway_container *parent) { +	if (parent->type == C_VIEW) { +		return parent; +	} +	struct sway_seat_container *current;  	wl_list_for_each(current, &seat->focus_stack, link) { -		if (current->container->parent == container && -				current->container->layout != L_FLOATING) { -			return current->container; +		struct sway_container *con = current->container; +		if (con->parent == parent && con->layout != L_FLOATING) { +			return con;  		}  	}  	return NULL; @@ -902,7 +924,9 @@ struct sway_container *seat_get_focus(struct sway_seat *seat) {  	if (!seat->has_focus) {  		return NULL;  	} -	return seat_get_focus_inactive(seat, &root_container); +	struct sway_seat_container *current = +		wl_container_of(seat->focus_stack.next, current, link); +	return current->container;  }  void seat_apply_config(struct sway_seat *seat, | 
