diff options
| -rw-r--r-- | include/sway/container.h | 2 | ||||
| -rw-r--r-- | include/sway/layout.h | 1 | ||||
| -rw-r--r-- | include/sway/view.h | 2 | ||||
| -rw-r--r-- | sway/desktop/xdg_shell_v6.c | 15 | ||||
| -rw-r--r-- | sway/tree/container.c | 42 | ||||
| -rw-r--r-- | sway/tree/layout.c | 13 | 
6 files changed, 73 insertions, 2 deletions
diff --git a/include/sway/container.h b/include/sway/container.h index 1a173f3e..08a98ed9 100644 --- a/include/sway/container.h +++ b/include/sway/container.h @@ -132,6 +132,8 @@ swayc_t *new_output(struct sway_output *sway_output);  swayc_t *new_workspace(swayc_t *output, const char *name);  swayc_t *new_view(swayc_t *sibling, struct sway_view *sway_view); +swayc_t *destroy_view(swayc_t *view); +  swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type);  #endif diff --git a/include/sway/layout.h b/include/sway/layout.h index 505036a0..f3b62b05 100644 --- a/include/sway/layout.h +++ b/include/sway/layout.h @@ -5,6 +5,7 @@ struct sway_container;  void init_layout(void);  void add_child(struct sway_container *parent, struct sway_container *child); +struct sway_container *remove_child(struct sway_container *child);  enum swayc_layouts default_layout(struct sway_container *output);  void sort_workspaces(struct sway_container *output);  void arrange_windows(struct sway_container *container, double width, double height); diff --git a/include/sway/view.h b/include/sway/view.h index fca444b7..2707ca78 100644 --- a/include/sway/view.h +++ b/include/sway/view.h @@ -14,6 +14,7 @@ struct sway_xdg_surface_v6 {  	struct wl_listener request_move;  	struct wl_listener request_resize;  	struct wl_listener request_maximize; +	struct wl_listener destroy;  	int pending_width, pending_height;  }; @@ -38,7 +39,6 @@ enum sway_view_prop {   * tree (shell surfaces).   */  struct sway_view { -	struct wl_listener destroy;  	enum sway_view_type type;  	struct sway_container *swayc;  	struct wlr_surface *surface; diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 94682fcd..45e443fc 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -44,11 +44,22 @@ static void handle_commit(struct wl_listener *listener, void *data) {  	sway_log(L_DEBUG, "xdg surface commit %dx%d",  			sway_surface->pending_width, sway_surface->pending_height);  	// NOTE: We intentionally discard the view's desired width here -	// TODO: Don't do that for floating views +	// TODO: Let floating views do whatever  	view->width = sway_surface->pending_width;  	view->height = sway_surface->pending_height;  } +static void handle_destroy(struct wl_listener *listener, void *data) { +	struct sway_xdg_surface_v6 *sway_xdg_surface = +		wl_container_of(listener, sway_xdg_surface, destroy); +	wl_list_remove(&sway_xdg_surface->commit.link); +	wl_list_remove(&sway_xdg_surface->destroy.link); +	swayc_t *parent = destroy_view(sway_xdg_surface->view->swayc); +	free(sway_xdg_surface->view); +	free(sway_xdg_surface); +	arrange_windows(parent, -1, -1); +} +  void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) {  	struct sway_server *server = wl_container_of(  			listener, server, xdg_shell_v6_surface); @@ -90,6 +101,8 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) {  	sway_surface->commit.notify = handle_commit;  	wl_signal_add(&xdg_surface->events.commit, &sway_surface->commit); +	sway_surface->destroy.notify = handle_destroy; +	wl_signal_add(&xdg_surface->events.destroy, &sway_surface->destroy);  	// TODO: actual focus semantics  	swayc_t *parent = root_container.children->items[0]; diff --git a/sway/tree/container.c b/sway/tree/container.c index a83c0f6b..c7bce38a 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -109,6 +109,48 @@ swayc_t *new_view(swayc_t *sibling, struct sway_view *sway_view) {  	return swayc;  } +static void free_swayc(swayc_t *cont) { +	if (!sway_assert(cont, "free_swayc passed NULL")) { +		return; +	} +	if (cont->children) { +		// remove children until there are no more, free_swayc calls +		// remove_child, which removes child from this container +		while (cont->children->length) { +			free_swayc(cont->children->items[0]); +		} +		list_free(cont->children); +	} +	if (cont->marks) { +		list_foreach(cont->marks, free); +		list_free(cont->marks); +	} +	if (cont->parent) { +		remove_child(cont); +	} +	if (cont->name) { +		free(cont->name); +	} +	free(cont); +} + +swayc_t *destroy_view(swayc_t *view) { +	if (!sway_assert(view, "null view passed to destroy_view")) { +		return NULL; +	} +	sway_log(L_DEBUG, "Destroying view '%s'", view->name); +	swayc_t *parent = view->parent; +	free_swayc(view); + +	// TODO WLR: Destroy empty containers +	/* +	if (parent && parent->type == C_CONTAINER) { +		return destroy_container(parent); +	} +	*/ +	return parent; +} +  swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) {  	if (!sway_assert(container, "container is NULL")) {  		return NULL; diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 6e2586a7..ea7bb8bb 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -40,6 +40,19 @@ void add_child(swayc_t *parent, swayc_t *child) {  	*/  } +swayc_t *remove_child(swayc_t *child) { +	int i; +	swayc_t *parent = child->parent; +	for (i = 0; i < parent->children->length; ++i) { +		if (parent->children->items[i] == child) { +			list_del(parent->children, i); +			break; +		} +	} +	child->parent = NULL; +	return parent; +} +  enum swayc_layouts default_layout(swayc_t *output) {  	/* TODO WLR  	if (config->default_layout != L_NONE) {  | 
