|  |  |  | @ -16,6 +16,7 @@ | 
			
		
	
		
			
				
					|  |  |  |  | #include "sway/input/input-manager.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "sway/input/seat.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "sway/ipc-server.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "sway/scene_descriptor.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "sway/output.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "sway/server.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "sway/surface.h" | 
			
		
	
	
		
			
				
					|  |  |  | @ -94,6 +95,11 @@ struct sway_container *container_create(struct sway_view *view) { | 
			
		
	
		
			
				
					|  |  |  |  | 		c->border.right = alloc_rect_node(c->border.tree, &failed); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!failed && !scene_descriptor_assign(&c->scene_tree->node, | 
			
		
	
		
			
				
					|  |  |  |  | 			SWAY_SCENE_DESC_CONTAINER, c)) { | 
			
		
	
		
			
				
					|  |  |  |  | 		failed = true; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (failed) { | 
			
		
	
		
			
				
					|  |  |  |  | 		wlr_scene_node_destroy(&c->scene_tree->node); | 
			
		
	
		
			
				
					|  |  |  |  | 		free(c); | 
			
		
	
	
		
			
				
					|  |  |  | @ -239,265 +245,6 @@ struct sway_container *container_find_child(struct sway_container *container, | 
			
		
	
		
			
				
					|  |  |  |  | 	return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static struct sway_container *surface_at_view(struct sway_container *con, double lx, double ly, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_surface **surface, double *sx, double *sy) { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!sway_assert(con->view, "Expected a view")) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_view *view = con->view; | 
			
		
	
		
			
				
					|  |  |  |  | 	double view_sx = lx - con->surface_x + view->geometry.x; | 
			
		
	
		
			
				
					|  |  |  |  | 	double view_sy = ly - con->surface_y + view->geometry.y; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	double _sx, _sy; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_surface *_surface = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	switch (view->type) { | 
			
		
	
		
			
				
					|  |  |  |  | #if HAVE_XWAYLAND | 
			
		
	
		
			
				
					|  |  |  |  | 	case SWAY_VIEW_XWAYLAND: | 
			
		
	
		
			
				
					|  |  |  |  | 		_surface = wlr_surface_surface_at(view->surface, | 
			
		
	
		
			
				
					|  |  |  |  | 				view_sx, view_sy, &_sx, &_sy); | 
			
		
	
		
			
				
					|  |  |  |  | 		break; | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  | 	case SWAY_VIEW_XDG_SHELL: | 
			
		
	
		
			
				
					|  |  |  |  | 		_surface = wlr_xdg_surface_surface_at( | 
			
		
	
		
			
				
					|  |  |  |  | 				view->wlr_xdg_toplevel->base, | 
			
		
	
		
			
				
					|  |  |  |  | 				view_sx, view_sy, &_sx, &_sy); | 
			
		
	
		
			
				
					|  |  |  |  | 		break; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	if (_surface) { | 
			
		
	
		
			
				
					|  |  |  |  | 		*sx = _sx; | 
			
		
	
		
			
				
					|  |  |  |  | 		*sy = _sy; | 
			
		
	
		
			
				
					|  |  |  |  | 		*surface = _surface; | 
			
		
	
		
			
				
					|  |  |  |  | 		return con; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /**
 | 
			
		
	
		
			
				
					|  |  |  |  |  * container_at for a container with layout L_TABBED. | 
			
		
	
		
			
				
					|  |  |  |  |  */ | 
			
		
	
		
			
				
					|  |  |  |  | static struct sway_container *container_at_tabbed(struct sway_node *parent, | 
			
		
	
		
			
				
					|  |  |  |  | 		double lx, double ly, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_surface **surface, double *sx, double *sy) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_box box; | 
			
		
	
		
			
				
					|  |  |  |  | 	node_get_box(parent, &box); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (lx < box.x || lx > box.x + box.width || | 
			
		
	
		
			
				
					|  |  |  |  | 			ly < box.y || ly > box.y + box.height) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_seat *seat = input_manager_current_seat(); | 
			
		
	
		
			
				
					|  |  |  |  | 	list_t *children = node_get_children(parent); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!children->length) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// Tab titles
 | 
			
		
	
		
			
				
					|  |  |  |  | 	int title_height = container_titlebar_height(); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (ly < box.y + title_height) { | 
			
		
	
		
			
				
					|  |  |  |  | 		int tab_width = box.width / children->length; | 
			
		
	
		
			
				
					|  |  |  |  | 		int child_index = (lx - box.x) / tab_width; | 
			
		
	
		
			
				
					|  |  |  |  | 		if (child_index >= children->length) { | 
			
		
	
		
			
				
					|  |  |  |  | 			child_index = children->length - 1; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		struct sway_container *child = children->items[child_index]; | 
			
		
	
		
			
				
					|  |  |  |  | 		return child; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// Surfaces
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_node *current = seat_get_active_tiling_child(seat, parent); | 
			
		
	
		
			
				
					|  |  |  |  | 	return current ? tiling_container_at(current, lx, ly, surface, sx, sy) : NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /**
 | 
			
		
	
		
			
				
					|  |  |  |  |  * container_at for a container with layout L_STACKED. | 
			
		
	
		
			
				
					|  |  |  |  |  */ | 
			
		
	
		
			
				
					|  |  |  |  | static struct sway_container *container_at_stacked(struct sway_node *parent, | 
			
		
	
		
			
				
					|  |  |  |  | 		double lx, double ly, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_surface **surface, double *sx, double *sy) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_box box; | 
			
		
	
		
			
				
					|  |  |  |  | 	node_get_box(parent, &box); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (lx < box.x || lx > box.x + box.width || | 
			
		
	
		
			
				
					|  |  |  |  | 			ly < box.y || ly > box.y + box.height) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_seat *seat = input_manager_current_seat(); | 
			
		
	
		
			
				
					|  |  |  |  | 	list_t *children = node_get_children(parent); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// Title bars
 | 
			
		
	
		
			
				
					|  |  |  |  | 	int title_height = container_titlebar_height(); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (title_height > 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 		int child_index = (ly - box.y) / title_height; | 
			
		
	
		
			
				
					|  |  |  |  | 		if (child_index < children->length) { | 
			
		
	
		
			
				
					|  |  |  |  | 			struct sway_container *child = children->items[child_index]; | 
			
		
	
		
			
				
					|  |  |  |  | 			return child; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// Surfaces
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_node *current = seat_get_active_tiling_child(seat, parent); | 
			
		
	
		
			
				
					|  |  |  |  | 	return current ? tiling_container_at(current, lx, ly, surface, sx, sy) : NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /**
 | 
			
		
	
		
			
				
					|  |  |  |  |  * container_at for a container with layout L_HORIZ or L_VERT. | 
			
		
	
		
			
				
					|  |  |  |  |  */ | 
			
		
	
		
			
				
					|  |  |  |  | static struct sway_container *container_at_linear(struct sway_node *parent, | 
			
		
	
		
			
				
					|  |  |  |  | 		double lx, double ly, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_surface **surface, double *sx, double *sy) { | 
			
		
	
		
			
				
					|  |  |  |  | 	list_t *children = node_get_children(parent); | 
			
		
	
		
			
				
					|  |  |  |  | 	for (int i = 0; i < children->length; ++i) { | 
			
		
	
		
			
				
					|  |  |  |  | 		struct sway_container *child = children->items[i]; | 
			
		
	
		
			
				
					|  |  |  |  | 		struct sway_container *container = | 
			
		
	
		
			
				
					|  |  |  |  | 			tiling_container_at(&child->node, lx, ly, surface, sx, sy); | 
			
		
	
		
			
				
					|  |  |  |  | 		if (container) { | 
			
		
	
		
			
				
					|  |  |  |  | 			return container; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static struct sway_container *floating_container_at(double lx, double ly, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_surface **surface, double *sx, double *sy) { | 
			
		
	
		
			
				
					|  |  |  |  | 	// For outputs with floating containers that overhang the output bounds,
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// those at the end of the output list appear on top of floating
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// containers from other outputs, so iterate the list in reverse.
 | 
			
		
	
		
			
				
					|  |  |  |  | 	for (int i = root->outputs->length - 1; i >= 0; --i) { | 
			
		
	
		
			
				
					|  |  |  |  | 		struct sway_output *output = root->outputs->items[i]; | 
			
		
	
		
			
				
					|  |  |  |  | 		for (int j = 0; j < output->workspaces->length; ++j) { | 
			
		
	
		
			
				
					|  |  |  |  | 			struct sway_workspace *ws = output->workspaces->items[j]; | 
			
		
	
		
			
				
					|  |  |  |  | 			if (!workspace_is_visible(ws)) { | 
			
		
	
		
			
				
					|  |  |  |  | 				continue; | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 			// Items at the end of the list are on top, so iterate the list in
 | 
			
		
	
		
			
				
					|  |  |  |  | 			// reverse.
 | 
			
		
	
		
			
				
					|  |  |  |  | 			for (int k = ws->floating->length - 1; k >= 0; --k) { | 
			
		
	
		
			
				
					|  |  |  |  | 				struct sway_container *floater = ws->floating->items[k]; | 
			
		
	
		
			
				
					|  |  |  |  | 				struct sway_container *container = | 
			
		
	
		
			
				
					|  |  |  |  | 					tiling_container_at(&floater->node, lx, ly, surface, sx, sy); | 
			
		
	
		
			
				
					|  |  |  |  | 				if (container) { | 
			
		
	
		
			
				
					|  |  |  |  | 					return container; | 
			
		
	
		
			
				
					|  |  |  |  | 				} | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static struct sway_container *view_container_content_at(struct sway_node *parent, | 
			
		
	
		
			
				
					|  |  |  |  | 		double lx, double ly, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_surface **surface, double *sx, double *sy) { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!sway_assert(node_is_view(parent), "Expected a view")) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_container *container = parent->sway_container; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_box box = { | 
			
		
	
		
			
				
					|  |  |  |  | 		.x = container->pending.content_x, | 
			
		
	
		
			
				
					|  |  |  |  | 		.y = container->pending.content_y, | 
			
		
	
		
			
				
					|  |  |  |  | 		.width = container->pending.content_width, | 
			
		
	
		
			
				
					|  |  |  |  | 		.height = container->pending.content_height, | 
			
		
	
		
			
				
					|  |  |  |  | 	}; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (wlr_box_contains_point(&box, lx, ly)) { | 
			
		
	
		
			
				
					|  |  |  |  | 		surface_at_view(parent->sway_container, lx, ly, surface, sx, sy); | 
			
		
	
		
			
				
					|  |  |  |  | 		return container; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static struct sway_container *view_container_at(struct sway_node *parent, | 
			
		
	
		
			
				
					|  |  |  |  | 		double lx, double ly, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_surface **surface, double *sx, double *sy) { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!sway_assert(node_is_view(parent), "Expected a view")) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_container *container = parent->sway_container; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_box box = { | 
			
		
	
		
			
				
					|  |  |  |  | 		.x = container->pending.x, | 
			
		
	
		
			
				
					|  |  |  |  | 		.y = container->pending.y, | 
			
		
	
		
			
				
					|  |  |  |  | 		.width = container->pending.width, | 
			
		
	
		
			
				
					|  |  |  |  | 		.height = container->pending.height, | 
			
		
	
		
			
				
					|  |  |  |  | 	}; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (wlr_box_contains_point(&box, lx, ly)) { | 
			
		
	
		
			
				
					|  |  |  |  | 		surface_at_view(parent->sway_container, lx, ly, surface, sx, sy); | 
			
		
	
		
			
				
					|  |  |  |  | 		return container; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | struct sway_container *tiling_container_at(struct sway_node *parent, | 
			
		
	
		
			
				
					|  |  |  |  | 		double lx, double ly, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_surface **surface, double *sx, double *sy) { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (node_is_view(parent)) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return view_container_at(parent, lx, ly, surface, sx, sy); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!node_get_children(parent)) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	switch (node_get_layout(parent)) { | 
			
		
	
		
			
				
					|  |  |  |  | 	case L_HORIZ: | 
			
		
	
		
			
				
					|  |  |  |  | 	case L_VERT: | 
			
		
	
		
			
				
					|  |  |  |  | 		return container_at_linear(parent, lx, ly, surface, sx, sy); | 
			
		
	
		
			
				
					|  |  |  |  | 	case L_TABBED: | 
			
		
	
		
			
				
					|  |  |  |  | 		return container_at_tabbed(parent, lx, ly, surface, sx, sy); | 
			
		
	
		
			
				
					|  |  |  |  | 	case L_STACKED: | 
			
		
	
		
			
				
					|  |  |  |  | 		return container_at_stacked(parent, lx, ly, surface, sx, sy); | 
			
		
	
		
			
				
					|  |  |  |  | 	case L_NONE: | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static bool surface_is_popup(struct wlr_surface *surface) { | 
			
		
	
		
			
				
					|  |  |  |  | 	while (wlr_xdg_surface_try_from_wlr_surface(surface) == NULL) { | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_subsurface *subsurface = | 
			
		
	
		
			
				
					|  |  |  |  | 			wlr_subsurface_try_from_wlr_surface(surface); | 
			
		
	
		
			
				
					|  |  |  |  | 		if (subsurface == NULL) { | 
			
		
	
		
			
				
					|  |  |  |  | 			return false; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		surface = subsurface->parent; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_xdg_surface *xdg_surface = | 
			
		
	
		
			
				
					|  |  |  |  | 		wlr_xdg_surface_try_from_wlr_surface(surface); | 
			
		
	
		
			
				
					|  |  |  |  | 	return xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP && xdg_surface->popup != NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | struct sway_container *container_at(struct sway_workspace *workspace, | 
			
		
	
		
			
				
					|  |  |  |  | 		double lx, double ly, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_surface **surface, double *sx, double *sy) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_container *c; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_seat *seat = input_manager_current_seat(); | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_container *focus = seat_get_focused_container(seat); | 
			
		
	
		
			
				
					|  |  |  |  | 	bool is_floating = focus && container_is_floating_or_child(focus); | 
			
		
	
		
			
				
					|  |  |  |  | 	// Focused view's popups
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (focus && focus->view) { | 
			
		
	
		
			
				
					|  |  |  |  | 		c = surface_at_view(focus, lx, ly, surface, sx, sy); | 
			
		
	
		
			
				
					|  |  |  |  | 		if (c && surface_is_popup(*surface)) { | 
			
		
	
		
			
				
					|  |  |  |  | 			return c; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		*surface = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	// Floating
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if ((c = floating_container_at(lx, ly, surface ,sx ,sy))) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return c; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	// Tiling (focused)
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (focus && focus->view && !is_floating) { | 
			
		
	
		
			
				
					|  |  |  |  | 		if ((c = view_container_content_at(&focus->node, lx, ly, surface, sx, sy))) { | 
			
		
	
		
			
				
					|  |  |  |  | 			return c; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	// Tiling (non-focused)
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if ((c = tiling_container_at(&workspace->node, lx, ly, surface, sx, sy))) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return c; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void container_for_each_child(struct sway_container *container, | 
			
		
	
		
			
				
					|  |  |  |  | 		void (*f)(struct sway_container *container, void *data), | 
			
		
	
		
			
				
					|  |  |  |  | 		void *data) { | 
			
		
	
	
		
			
				
					|  |  |  | 
 |