mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Merge pull request #2483 from RyanDwyer/floating-emit-reparent
Send enter/leave events for floating views
This commit is contained in:
		
						commit
						08a69f267a
					
				
					 7 changed files with 107 additions and 98 deletions
				
			
		| 
						 | 
					@ -138,6 +138,9 @@ struct sway_container {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct sway_container *parent;
 | 
						struct sway_container *parent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Outputs currently being intersected
 | 
				
			||||||
 | 
						list_t *outputs; // struct sway_output
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Indicates that the container is a scratchpad container.
 | 
						// Indicates that the container is a scratchpad container.
 | 
				
			||||||
	// Both hidden and visible scratchpad containers have scratchpad=true.
 | 
						// Both hidden and visible scratchpad containers have scratchpad=true.
 | 
				
			||||||
	// Hidden scratchpad containers have a NULL parent.
 | 
						// Hidden scratchpad containers have a NULL parent.
 | 
				
			||||||
| 
						 | 
					@ -166,12 +169,7 @@ struct sway_container {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		struct wl_signal destroy;
 | 
							struct wl_signal destroy;
 | 
				
			||||||
		// Raised after the tree updates, but before arrange_windows
 | 
					 | 
				
			||||||
		// Passed the previous parent
 | 
					 | 
				
			||||||
		struct wl_signal reparent;
 | 
					 | 
				
			||||||
	} events;
 | 
						} events;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct wl_listener reparent;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sway_container *container_create(enum sway_container_type type);
 | 
					struct sway_container *container_create(enum sway_container_type type);
 | 
				
			||||||
| 
						 | 
					@ -353,4 +351,12 @@ bool container_is_floating_or_child(struct sway_container *container);
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool container_is_fullscreen_or_child(struct sway_container *container);
 | 
					bool container_is_fullscreen_or_child(struct sway_container *container);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Return the output which will be used for scale purposes.
 | 
				
			||||||
 | 
					 * This is the most recently entered output.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct sway_output *container_get_effective_output(struct sway_container *con);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void container_discover_outputs(struct sway_container *con);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -120,7 +120,6 @@ struct sway_view {
 | 
				
			||||||
	} events;
 | 
						} events;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_listener surface_new_subsurface;
 | 
						struct wl_listener surface_new_subsurface;
 | 
				
			||||||
	struct wl_listener container_reparent;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sway_xdg_shell_v6_view {
 | 
					struct sway_xdg_shell_v6_view {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -236,7 +236,6 @@ static void workspace_move_to_output(struct sway_container *workspace,
 | 
				
			||||||
		seat_get_focus_inactive(seat, output);
 | 
							seat_get_focus_inactive(seat, output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	container_add_child(output, workspace);
 | 
						container_add_child(output, workspace);
 | 
				
			||||||
	wl_signal_emit(&workspace->events.reparent, old_output);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// If moving the last workspace from the old output, create a new workspace
 | 
						// If moving the last workspace from the old output, create a new workspace
 | 
				
			||||||
	// on the old output
 | 
						// on the old output
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -195,6 +195,9 @@ static void transaction_apply(struct sway_transaction *transaction) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		container->instruction = NULL;
 | 
							container->instruction = NULL;
 | 
				
			||||||
 | 
							if (container->type == C_CONTAINER || container->type == C_VIEW) {
 | 
				
			||||||
 | 
								container_discover_outputs(container);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -76,31 +76,6 @@ void container_update_textures_recursive(struct sway_container *con) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_reparent(struct wl_listener *listener,
 | 
					 | 
				
			||||||
		void *data) {
 | 
					 | 
				
			||||||
	struct sway_container *container =
 | 
					 | 
				
			||||||
		wl_container_of(listener, container, reparent);
 | 
					 | 
				
			||||||
	struct sway_container *old_parent = data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct sway_container *old_output = old_parent;
 | 
					 | 
				
			||||||
	if (old_output != NULL && old_output->type != C_OUTPUT) {
 | 
					 | 
				
			||||||
		old_output = container_parent(old_output, C_OUTPUT);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct sway_container *new_output = container->parent;
 | 
					 | 
				
			||||||
	if (new_output != NULL && new_output->type != C_OUTPUT) {
 | 
					 | 
				
			||||||
		new_output = container_parent(new_output, C_OUTPUT);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (old_output && new_output) {
 | 
					 | 
				
			||||||
		float old_scale = old_output->sway_output->wlr_output->scale;
 | 
					 | 
				
			||||||
		float new_scale = new_output->sway_output->wlr_output->scale;
 | 
					 | 
				
			||||||
		if (old_scale != new_scale) {
 | 
					 | 
				
			||||||
			container_update_textures_recursive(container);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct sway_container *container_create(enum sway_container_type type) {
 | 
					struct sway_container *container_create(enum sway_container_type type) {
 | 
				
			||||||
	// next id starts at 1 because 0 is assigned to root_container in layout.c
 | 
						// next id starts at 1 because 0 is assigned to root_container in layout.c
 | 
				
			||||||
	static size_t next_id = 1;
 | 
						static size_t next_id = 1;
 | 
				
			||||||
| 
						 | 
					@ -117,12 +92,9 @@ struct sway_container *container_create(enum sway_container_type type) {
 | 
				
			||||||
		c->children = create_list();
 | 
							c->children = create_list();
 | 
				
			||||||
		c->current.children = create_list();
 | 
							c->current.children = create_list();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						c->outputs = create_list();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_signal_init(&c->events.destroy);
 | 
						wl_signal_init(&c->events.destroy);
 | 
				
			||||||
	wl_signal_init(&c->events.reparent);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wl_signal_add(&c->events.reparent, &c->reparent);
 | 
					 | 
				
			||||||
	c->reparent.notify = handle_reparent;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c->has_gaps = false;
 | 
						c->has_gaps = false;
 | 
				
			||||||
	c->gaps_inner = 0;
 | 
						c->gaps_inner = 0;
 | 
				
			||||||
| 
						 | 
					@ -156,6 +128,7 @@ void container_free(struct sway_container *cont) {
 | 
				
			||||||
	wlr_texture_destroy(cont->title_urgent);
 | 
						wlr_texture_destroy(cont->title_urgent);
 | 
				
			||||||
	list_free(cont->children);
 | 
						list_free(cont->children);
 | 
				
			||||||
	list_free(cont->current.children);
 | 
						list_free(cont->current.children);
 | 
				
			||||||
 | 
						list_free(cont->outputs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (cont->type) {
 | 
						switch (cont->type) {
 | 
				
			||||||
	case C_ROOT:
 | 
						case C_ROOT:
 | 
				
			||||||
| 
						 | 
					@ -238,6 +211,14 @@ static struct sway_container *container_workspace_destroy(
 | 
				
			||||||
	return output;
 | 
						return output;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void untrack_output(struct sway_container *con, void *data) {
 | 
				
			||||||
 | 
						struct sway_output *output = data;
 | 
				
			||||||
 | 
						int index = list_find(con->outputs, output);
 | 
				
			||||||
 | 
						if (index != -1) {
 | 
				
			||||||
 | 
							list_del(con->outputs, index);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct sway_container *container_output_destroy(
 | 
					static struct sway_container *container_output_destroy(
 | 
				
			||||||
		struct sway_container *output) {
 | 
							struct sway_container *output) {
 | 
				
			||||||
	if (!sway_assert(output, "cannot destroy null output")) {
 | 
						if (!sway_assert(output, "cannot destroy null output")) {
 | 
				
			||||||
| 
						 | 
					@ -279,6 +260,8 @@ static struct sway_container *container_output_destroy(
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						root_for_each_container(untrack_output, output->sway_output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_remove(&output->sway_output->mode.link);
 | 
						wl_list_remove(&output->sway_output->mode.link);
 | 
				
			||||||
	wl_list_remove(&output->sway_output->transform.link);
 | 
						wl_list_remove(&output->sway_output->transform.link);
 | 
				
			||||||
	wl_list_remove(&output->sway_output->scale.link);
 | 
						wl_list_remove(&output->sway_output->scale.link);
 | 
				
			||||||
| 
						 | 
					@ -777,13 +760,24 @@ void container_damage_whole(struct sway_container *container) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Return the output which will be used for scale purposes.
 | 
				
			||||||
 | 
					 * This is the most recently entered output.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct sway_output *container_get_effective_output(struct sway_container *con) {
 | 
				
			||||||
 | 
						if (con->outputs->length == 0) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return con->outputs->items[con->outputs->length - 1];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void update_title_texture(struct sway_container *con,
 | 
					static void update_title_texture(struct sway_container *con,
 | 
				
			||||||
		struct wlr_texture **texture, struct border_colors *class) {
 | 
							struct wlr_texture **texture, struct border_colors *class) {
 | 
				
			||||||
	if (!sway_assert(con->type == C_CONTAINER || con->type == C_VIEW,
 | 
						if (!sway_assert(con->type == C_CONTAINER || con->type == C_VIEW,
 | 
				
			||||||
			"Unexpected type %s", container_type_to_str(con->type))) {
 | 
								"Unexpected type %s", container_type_to_str(con->type))) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	struct sway_container *output = container_parent(con, C_OUTPUT);
 | 
						struct sway_output *output = container_get_effective_output(con);
 | 
				
			||||||
	if (!output) {
 | 
						if (!output) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -795,7 +789,7 @@ static void update_title_texture(struct sway_container *con,
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	double scale = output->sway_output->wlr_output->scale;
 | 
						double scale = output->wlr_output->scale;
 | 
				
			||||||
	int width = 0;
 | 
						int width = 0;
 | 
				
			||||||
	int height = con->title_height * scale;
 | 
						int height = con->title_height * scale;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -823,7 +817,7 @@ static void update_title_texture(struct sway_container *con,
 | 
				
			||||||
	unsigned char *data = cairo_image_surface_get_data(surface);
 | 
						unsigned char *data = cairo_image_surface_get_data(surface);
 | 
				
			||||||
	int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
 | 
						int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
 | 
				
			||||||
	struct wlr_renderer *renderer = wlr_backend_get_renderer(
 | 
						struct wlr_renderer *renderer = wlr_backend_get_renderer(
 | 
				
			||||||
			output->sway_output->wlr_output->backend);
 | 
								output->wlr_output->backend);
 | 
				
			||||||
	*texture = wlr_texture_from_pixels(
 | 
						*texture = wlr_texture_from_pixels(
 | 
				
			||||||
			renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data);
 | 
								renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data);
 | 
				
			||||||
	cairo_surface_destroy(surface);
 | 
						cairo_surface_destroy(surface);
 | 
				
			||||||
| 
						 | 
					@ -1272,3 +1266,67 @@ bool container_is_fullscreen_or_child(struct sway_container *container) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void surface_send_enter_iterator(struct wlr_surface *surface,
 | 
				
			||||||
 | 
							int x, int y, void *data) {
 | 
				
			||||||
 | 
						struct wlr_output *wlr_output = data;
 | 
				
			||||||
 | 
						wlr_surface_send_enter(surface, wlr_output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void surface_send_leave_iterator(struct wlr_surface *surface,
 | 
				
			||||||
 | 
							int x, int y, void *data) {
 | 
				
			||||||
 | 
						struct wlr_output *wlr_output = data;
 | 
				
			||||||
 | 
						wlr_surface_send_leave(surface, wlr_output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void container_discover_outputs(struct sway_container *con) {
 | 
				
			||||||
 | 
						if (!sway_assert(con->type == C_CONTAINER || con->type == C_VIEW,
 | 
				
			||||||
 | 
									"Expected a container or view")) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						struct wlr_box con_box = {
 | 
				
			||||||
 | 
							.x = con->current.swayc_x,
 | 
				
			||||||
 | 
							.y = con->current.swayc_y,
 | 
				
			||||||
 | 
							.width = con->current.swayc_width,
 | 
				
			||||||
 | 
							.height = con->current.swayc_height,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						struct sway_output *old_output = container_get_effective_output(con);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (int i = 0; i < root_container.children->length; ++i) {
 | 
				
			||||||
 | 
							struct sway_container *output = root_container.children->items[i];
 | 
				
			||||||
 | 
							struct sway_output *sway_output = output->sway_output;
 | 
				
			||||||
 | 
							struct wlr_box output_box;
 | 
				
			||||||
 | 
							container_get_box(output, &output_box);
 | 
				
			||||||
 | 
							struct wlr_box intersection;
 | 
				
			||||||
 | 
							bool intersects =
 | 
				
			||||||
 | 
								wlr_box_intersection(&con_box, &output_box, &intersection);
 | 
				
			||||||
 | 
							int index = list_find(con->outputs, sway_output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (intersects && index == -1) {
 | 
				
			||||||
 | 
								// Send enter
 | 
				
			||||||
 | 
								wlr_log(WLR_DEBUG, "Con %p entered output %p", con, sway_output);
 | 
				
			||||||
 | 
								if (con->type == C_VIEW) {
 | 
				
			||||||
 | 
									view_for_each_surface(con->sway_view,
 | 
				
			||||||
 | 
											surface_send_enter_iterator, sway_output->wlr_output);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								list_add(con->outputs, sway_output);
 | 
				
			||||||
 | 
							} else if (!intersects && index != -1) {
 | 
				
			||||||
 | 
								// Send leave
 | 
				
			||||||
 | 
								wlr_log(WLR_DEBUG, "Con %p left output %p", con, sway_output);
 | 
				
			||||||
 | 
								if (con->type == C_VIEW) {
 | 
				
			||||||
 | 
									view_for_each_surface(con->sway_view,
 | 
				
			||||||
 | 
										surface_send_leave_iterator, sway_output->wlr_output);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								list_del(con->outputs, index);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						struct sway_output *new_output = container_get_effective_output(con);
 | 
				
			||||||
 | 
						double old_scale = old_output ? old_output->wlr_output->scale : -1;
 | 
				
			||||||
 | 
						double new_scale = new_output ? new_output->wlr_output->scale : -1;
 | 
				
			||||||
 | 
						if (old_scale != new_scale) {
 | 
				
			||||||
 | 
							container_update_title_textures(con);
 | 
				
			||||||
 | 
							if (con->type == C_VIEW) {
 | 
				
			||||||
 | 
								view_update_marks_textures(con->sway_view);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,7 +75,6 @@ void container_insert_child(struct sway_container *parent,
 | 
				
			||||||
	list_insert(parent->children, i, child);
 | 
						list_insert(parent->children, i, child);
 | 
				
			||||||
	child->parent = parent;
 | 
						child->parent = parent;
 | 
				
			||||||
	container_handle_fullscreen_reparent(child, old_parent);
 | 
						container_handle_fullscreen_reparent(child, old_parent);
 | 
				
			||||||
	wl_signal_emit(&child->events.reparent, old_parent);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sway_container *container_add_sibling(struct sway_container *fixed,
 | 
					struct sway_container *container_add_sibling(struct sway_container *fixed,
 | 
				
			||||||
| 
						 | 
					@ -91,7 +90,6 @@ struct sway_container *container_add_sibling(struct sway_container *fixed,
 | 
				
			||||||
	list_insert(parent->children, i + 1, active);
 | 
						list_insert(parent->children, i + 1, active);
 | 
				
			||||||
	active->parent = parent;
 | 
						active->parent = parent;
 | 
				
			||||||
	container_handle_fullscreen_reparent(active, old_parent);
 | 
						container_handle_fullscreen_reparent(active, old_parent);
 | 
				
			||||||
	wl_signal_emit(&active->events.reparent, old_parent);
 | 
					 | 
				
			||||||
	return active->parent;
 | 
						return active->parent;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -181,8 +179,6 @@ void container_move_to(struct sway_container *container,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_signal_emit(&container->events.reparent, old_parent);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (container->type == C_VIEW) {
 | 
						if (container->type == C_VIEW) {
 | 
				
			||||||
		ipc_event_window(container, "move");
 | 
							ipc_event_window(container, "move");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -307,7 +303,6 @@ static void workspace_rejigger(struct sway_container *ws,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	container_flatten(ws);
 | 
						container_flatten(ws);
 | 
				
			||||||
	container_reap_empty_recursive(original_parent);
 | 
						container_reap_empty_recursive(original_parent);
 | 
				
			||||||
	wl_signal_emit(&child->events.reparent, original_parent);
 | 
					 | 
				
			||||||
	container_create_notify(new_parent);
 | 
						container_create_notify(new_parent);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -859,7 +854,6 @@ struct sway_container *container_split(struct sway_container *child,
 | 
				
			||||||
			struct sway_container *ws_child = workspace->children->items[0];
 | 
								struct sway_container *ws_child = workspace->children->items[0];
 | 
				
			||||||
			container_remove_child(ws_child);
 | 
								container_remove_child(ws_child);
 | 
				
			||||||
			container_add_child(cont, ws_child);
 | 
								container_add_child(cont, ws_child);
 | 
				
			||||||
			wl_signal_emit(&ws_child->events.reparent, workspace);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		container_add_child(workspace, cont);
 | 
							container_add_child(workspace, cont);
 | 
				
			||||||
| 
						 | 
					@ -867,11 +861,9 @@ struct sway_container *container_split(struct sway_container *child,
 | 
				
			||||||
		workspace->layout = layout;
 | 
							workspace->layout = layout;
 | 
				
			||||||
		cont->layout = old_layout;
 | 
							cont->layout = old_layout;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		struct sway_container *old_parent = child->parent;
 | 
					 | 
				
			||||||
		cont->layout = layout;
 | 
							cont->layout = layout;
 | 
				
			||||||
		container_replace_child(child, cont);
 | 
							container_replace_child(child, cont);
 | 
				
			||||||
		container_add_child(cont, child);
 | 
							container_add_child(cont, child);
 | 
				
			||||||
		wl_signal_emit(&child->events.reparent, old_parent);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (set_focus) {
 | 
						if (set_focus) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -364,48 +364,6 @@ static void view_handle_surface_new_subsurface(struct wl_listener *listener,
 | 
				
			||||||
	view_subsurface_create(view, subsurface);
 | 
						view_subsurface_create(view, subsurface);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void surface_send_enter_iterator(struct wlr_surface *surface,
 | 
					 | 
				
			||||||
		int x, int y, void *data) {
 | 
					 | 
				
			||||||
	struct wlr_output *wlr_output = data;
 | 
					 | 
				
			||||||
	wlr_surface_send_enter(surface, wlr_output);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void surface_send_leave_iterator(struct wlr_surface *surface,
 | 
					 | 
				
			||||||
		int x, int y, void *data) {
 | 
					 | 
				
			||||||
	struct wlr_output *wlr_output = data;
 | 
					 | 
				
			||||||
	wlr_surface_send_leave(surface, wlr_output);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void view_handle_container_reparent(struct wl_listener *listener,
 | 
					 | 
				
			||||||
		void *data) {
 | 
					 | 
				
			||||||
	struct sway_view *view =
 | 
					 | 
				
			||||||
		wl_container_of(listener, view, container_reparent);
 | 
					 | 
				
			||||||
	struct sway_container *old_parent = data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct sway_container *old_output = old_parent;
 | 
					 | 
				
			||||||
	if (old_output != NULL && old_output->type != C_OUTPUT) {
 | 
					 | 
				
			||||||
		old_output = container_parent(old_output, C_OUTPUT);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct sway_container *new_output = view->swayc->parent;
 | 
					 | 
				
			||||||
	if (new_output != NULL && new_output->type != C_OUTPUT) {
 | 
					 | 
				
			||||||
		new_output = container_parent(new_output, C_OUTPUT);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (old_output == new_output) {
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (old_output != NULL) {
 | 
					 | 
				
			||||||
		view_for_each_surface(view, surface_send_leave_iterator,
 | 
					 | 
				
			||||||
			old_output->sway_output->wlr_output);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (new_output != NULL) {
 | 
					 | 
				
			||||||
		view_for_each_surface(view, surface_send_enter_iterator,
 | 
					 | 
				
			||||||
			new_output->sway_output->wlr_output);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool view_has_executed_criteria(struct sway_view *view,
 | 
					static bool view_has_executed_criteria(struct sway_view *view,
 | 
				
			||||||
		struct criteria *criteria) {
 | 
							struct criteria *criteria) {
 | 
				
			||||||
	for (int i = 0; i < view->executed_criteria->length; ++i) {
 | 
						for (int i = 0; i < view->executed_criteria->length; ++i) {
 | 
				
			||||||
| 
						 | 
					@ -567,9 +525,6 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
 | 
				
			||||||
		&view->surface_new_subsurface);
 | 
							&view->surface_new_subsurface);
 | 
				
			||||||
	view->surface_new_subsurface.notify = view_handle_surface_new_subsurface;
 | 
						view->surface_new_subsurface.notify = view_handle_surface_new_subsurface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_signal_add(&view->swayc->events.reparent, &view->container_reparent);
 | 
					 | 
				
			||||||
	view->container_reparent.notify = view_handle_container_reparent;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (view->impl->wants_floating && view->impl->wants_floating(view)) {
 | 
						if (view->impl->wants_floating && view->impl->wants_floating(view)) {
 | 
				
			||||||
		view->border = config->floating_border;
 | 
							view->border = config->floating_border;
 | 
				
			||||||
		view->border_thickness = config->floating_border_thickness;
 | 
							view->border_thickness = config->floating_border_thickness;
 | 
				
			||||||
| 
						 | 
					@ -587,15 +542,12 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
 | 
				
			||||||
	view_update_title(view, false);
 | 
						view_update_title(view, false);
 | 
				
			||||||
	container_notify_subtree_changed(view->swayc->parent);
 | 
						container_notify_subtree_changed(view->swayc->parent);
 | 
				
			||||||
	view_execute_criteria(view);
 | 
						view_execute_criteria(view);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	view_handle_container_reparent(&view->container_reparent, NULL);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void view_unmap(struct sway_view *view) {
 | 
					void view_unmap(struct sway_view *view) {
 | 
				
			||||||
	wl_signal_emit(&view->events.unmap, view);
 | 
						wl_signal_emit(&view->events.unmap, view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_remove(&view->surface_new_subsurface.link);
 | 
						wl_list_remove(&view->surface_new_subsurface.link);
 | 
				
			||||||
	wl_list_remove(&view->container_reparent.link);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (view->urgent_timer) {
 | 
						if (view->urgent_timer) {
 | 
				
			||||||
		wl_event_source_remove(view->urgent_timer);
 | 
							wl_event_source_remove(view->urgent_timer);
 | 
				
			||||||
| 
						 | 
					@ -937,7 +889,7 @@ void view_add_mark(struct sway_view *view, char *mark) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void update_marks_texture(struct sway_view *view,
 | 
					static void update_marks_texture(struct sway_view *view,
 | 
				
			||||||
		struct wlr_texture **texture, struct border_colors *class) {
 | 
							struct wlr_texture **texture, struct border_colors *class) {
 | 
				
			||||||
	struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
 | 
						struct sway_output *output = container_get_effective_output(view->swayc);
 | 
				
			||||||
	if (!output) {
 | 
						if (!output) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -973,7 +925,7 @@ static void update_marks_texture(struct sway_view *view,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	free(part);
 | 
						free(part);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	double scale = output->sway_output->wlr_output->scale;
 | 
						double scale = output->wlr_output->scale;
 | 
				
			||||||
	int width = 0;
 | 
						int width = 0;
 | 
				
			||||||
	int height = view->swayc->title_height * scale;
 | 
						int height = view->swayc->title_height * scale;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -999,7 +951,7 @@ static void update_marks_texture(struct sway_view *view,
 | 
				
			||||||
	unsigned char *data = cairo_image_surface_get_data(surface);
 | 
						unsigned char *data = cairo_image_surface_get_data(surface);
 | 
				
			||||||
	int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
 | 
						int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
 | 
				
			||||||
	struct wlr_renderer *renderer = wlr_backend_get_renderer(
 | 
						struct wlr_renderer *renderer = wlr_backend_get_renderer(
 | 
				
			||||||
			output->sway_output->wlr_output->backend);
 | 
								output->wlr_output->backend);
 | 
				
			||||||
	*texture = wlr_texture_from_pixels(
 | 
						*texture = wlr_texture_from_pixels(
 | 
				
			||||||
			renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data);
 | 
								renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data);
 | 
				
			||||||
	cairo_surface_destroy(surface);
 | 
						cairo_surface_destroy(surface);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue