diff options
Diffstat (limited to 'sway/tree/layout.c')
| -rw-r--r-- | sway/tree/layout.c | 116 | 
1 files changed, 93 insertions, 23 deletions
diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 0b637822..7ffc2484 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -82,6 +82,37 @@ static int index_child(const struct sway_container *child) {  	return i;  } +static void container_handle_fullscreen_reparent(struct sway_container *viewcon, +		struct sway_container *old_parent) { +	if (viewcon->type != C_VIEW || !viewcon->sway_view->is_fullscreen) { +		return; +	} +	struct sway_view *view = viewcon->sway_view; +	struct sway_container *old_workspace = old_parent; +	if (old_workspace && old_workspace->type != C_WORKSPACE) { +		old_workspace = container_parent(old_workspace, C_WORKSPACE); +	} +	struct sway_container *new_workspace = container_parent(view->swayc, +			C_WORKSPACE); +	if (old_workspace == new_workspace) { +		return; +	} +	// Unmark the old workspace as fullscreen +	if (old_workspace) { +		old_workspace->sway_workspace->fullscreen = NULL; +	} + +	// Mark the new workspace as fullscreen +	if (new_workspace->sway_workspace->fullscreen) { +		view_set_fullscreen(new_workspace->sway_workspace->fullscreen, false); +	} +	new_workspace->sway_workspace->fullscreen = view; +	// Resize view to new output dimensions +	struct sway_output *output = new_workspace->parent->sway_output; +	view_configure(view, 0, 0, +			output->wlr_output->width, output->wlr_output->height); +} +  void container_insert_child(struct sway_container *parent,  		struct sway_container *child, int i) {  	struct sway_container *old_parent = child->parent; @@ -91,6 +122,7 @@ void container_insert_child(struct sway_container *parent,  	wlr_log(L_DEBUG, "Inserting id:%zd at index %d", child->id, i);  	list_insert(parent->children, i, child);  	child->parent = parent; +	container_handle_fullscreen_reparent(child, old_parent);  	wl_signal_emit(&child->events.reparent, old_parent);  } @@ -106,6 +138,7 @@ struct sway_container *container_add_sibling(struct sway_container *fixed,  	int i = index_child(fixed);  	list_insert(parent->children, i + 1, active);  	active->parent = parent; +	container_handle_fullscreen_reparent(active, old_parent);  	wl_signal_emit(&active->events.reparent, old_parent);  	return active->parent;  } @@ -115,11 +148,18 @@ void container_add_child(struct sway_container *parent,  	wlr_log(L_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)",  			child, child->type, child->width, child->height,  			parent, parent->type, parent->width, parent->height); +	struct sway_container *old_parent = child->parent;  	list_add(parent->children, child); +	container_handle_fullscreen_reparent(child, old_parent);  	child->parent = parent;  }  struct sway_container *container_remove_child(struct sway_container *child) { +	if (child->type == C_VIEW && child->sway_view->is_fullscreen) { +		struct sway_container *workspace = container_parent(child, C_WORKSPACE); +		workspace->sway_workspace->fullscreen = NULL; +	} +  	struct sway_container *parent = child->parent;  	for (int i = 0; i < parent->children->length; ++i) {  		if (parent->children->items[i] == child) { @@ -164,6 +204,26 @@ void container_move_to(struct sway_container *container,  		arrange_windows(old_parent, -1, -1);  	}  	arrange_windows(new_parent, -1, -1); +	// If view was moved to a fullscreen workspace, refocus the fullscreen view +	struct sway_container *new_workspace = container; +	if (new_workspace->type != C_WORKSPACE) { +		new_workspace = container_parent(new_workspace, C_WORKSPACE); +	} +	if (new_workspace->sway_workspace->fullscreen) { +		struct sway_seat *seat; +		struct sway_container *focus, *focus_ws; +		wl_list_for_each(seat, &input_manager->seats, link) { +			focus = seat_get_focus(seat); +			focus_ws = focus; +			if (focus_ws->type != C_WORKSPACE) { +				focus_ws = container_parent(focus_ws, C_WORKSPACE); +			} +			seat_set_focus(seat, new_workspace->sway_workspace->fullscreen->swayc); +			if (focus_ws != new_workspace) { +				seat_set_focus(seat, focus); +			} +		} +	}  }  static bool sway_dir_to_wlr(enum movement_direction dir, @@ -268,6 +328,11 @@ void container_move(struct sway_container *container,  	struct sway_container *current = container;  	struct sway_container *parent = current->parent; +	// If moving a fullscreen view, only consider outputs +	if (container->type == C_VIEW && container->sway_view->is_fullscreen) { +		current = container_parent(container, C_OUTPUT); +	} +  	if (parent != container_flatten(parent)) {  		// Special case: we were the last one in this container, so flatten it  		// and leave @@ -568,6 +633,11 @@ void arrange_windows(struct sway_container *container,  			container->y = y = area->y;  			wlr_log(L_DEBUG, "Arranging workspace '%s' at %f, %f",  					container->name, container->x, container->y); +			if (container->sway_workspace->fullscreen) { +				view_configure(container->sway_workspace->fullscreen, 0, 0, +						output->width, output->height); +				return; +			}  		}  		// children are properly handled below  		break; @@ -816,34 +886,26 @@ static struct sway_container *sway_output_from_wlr(struct wlr_output *output) {  struct sway_container *container_get_in_direction(  		struct sway_container *container, struct sway_seat *seat,  		enum movement_direction dir) { -	if (dir == MOVE_CHILD) { -		return seat_get_focus_inactive(seat, container); -	} -  	struct sway_container *parent = container->parent; -	if (dir == MOVE_PARENT) { -		if (parent->type == C_OUTPUT) { + +	if (container->type == C_VIEW && container->sway_view->is_fullscreen) { +		if (dir == MOVE_PARENT || dir == MOVE_CHILD) {  			return NULL; -		} else { -			return parent;  		} -	} - -	// TODO WLR fullscreen -	/* -	if (container->type == C_VIEW && swayc_is_fullscreen(container)) { -		wlr_log(L_DEBUG, "Moving from fullscreen view, skipping to output");  		container = container_parent(container, C_OUTPUT); -		get_layout_center_position(container, &abs_pos); -		struct sway_container *output = -		swayc_adjacent_output(container, dir, &abs_pos, true); -		return get_swayc_in_output_direction(output, dir); -	} -	if (container->type == C_WORKSPACE && container->fullscreen) { -		sway_log(L_DEBUG, "Moving to fullscreen view"); -		return container->fullscreen; +		parent = container->parent; +	} else { +		if (dir == MOVE_CHILD) { +			return seat_get_focus_inactive(seat, container); +		} +		if (dir == MOVE_PARENT) { +			if (parent->type == C_OUTPUT) { +				return NULL; +			} else { +				return parent; +			} +		}  	} -	*/  	struct sway_container *wrap_candidate = NULL;  	while (true) { @@ -874,6 +936,14 @@ struct sway_container *container_get_in_direction(  			if (next == NULL) {  				return NULL;  			} +			struct sway_container *next_workspace = next; +			if (next_workspace->type != C_WORKSPACE) { +				next_workspace = container_parent(next_workspace, C_WORKSPACE); +			} +			sway_assert(next_workspace, "Next container has no workspace"); +			if (next_workspace->sway_workspace->fullscreen) { +				return next_workspace->sway_workspace->fullscreen->swayc; +			}  			if (next->children && next->children->length) {  				// TODO consider floating children as well  				return seat_get_focus_inactive_view(seat, next);  | 
