|  |  |  | @ -27,6 +27,24 @@ | 
			
		
	
		
			
				
					|  |  |  |  | #include "log.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "stringop.h" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static struct wlr_scene_rect *alloc_rect_node(struct wlr_scene_tree *parent, | 
			
		
	
		
			
				
					|  |  |  |  | 		bool *failed) { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (*failed) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// just pass in random values. These will be overwritten when
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// they need to be used.
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_scene_rect *rect = wlr_scene_rect_create( | 
			
		
	
		
			
				
					|  |  |  |  | 		parent, 0, 0, (float[4]){0.f, 0.f, 0.f, 1.f}); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!rect) { | 
			
		
	
		
			
				
					|  |  |  |  | 		sway_log(SWAY_ERROR, "Failed to allocate a wlr_scene_rect"); | 
			
		
	
		
			
				
					|  |  |  |  | 		*failed = true; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	return rect; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | struct sway_container *container_create(struct sway_view *view) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_container *c = calloc(1, sizeof(struct sway_container)); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!c) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -34,14 +52,62 @@ struct sway_container *container_create(struct sway_view *view) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	node_init(&c->node, N_CONTAINER, c); | 
			
		
	
		
			
				
					|  |  |  |  | 	c->pending.layout = L_NONE; | 
			
		
	
		
			
				
					|  |  |  |  | 	c->view = view; | 
			
		
	
		
			
				
					|  |  |  |  | 	c->alpha = 1.0f; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// Container tree structure
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// - scene tree
 | 
			
		
	
		
			
				
					|  |  |  |  | 	//   - title bar
 | 
			
		
	
		
			
				
					|  |  |  |  | 	//     - border
 | 
			
		
	
		
			
				
					|  |  |  |  | 	//     - background
 | 
			
		
	
		
			
				
					|  |  |  |  | 	//     - title text
 | 
			
		
	
		
			
				
					|  |  |  |  | 	//     - marks text
 | 
			
		
	
		
			
				
					|  |  |  |  | 	//   - border
 | 
			
		
	
		
			
				
					|  |  |  |  | 	//     - border top/bottom/left/right
 | 
			
		
	
		
			
				
					|  |  |  |  | 	//     - content_tree (we put the content node here so when we disable the
 | 
			
		
	
		
			
				
					|  |  |  |  | 	//       border everything gets disabled. We only render the content iff there
 | 
			
		
	
		
			
				
					|  |  |  |  | 	//       is a border as well)
 | 
			
		
	
		
			
				
					|  |  |  |  | 	bool failed = false; | 
			
		
	
		
			
				
					|  |  |  |  | 	c->scene_tree = alloc_scene_tree(root->staging, &failed); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	c->title_bar.tree = alloc_scene_tree(c->scene_tree, &failed); | 
			
		
	
		
			
				
					|  |  |  |  | 	c->title_bar.border = alloc_scene_tree(c->title_bar.tree, &failed); | 
			
		
	
		
			
				
					|  |  |  |  | 	c->title_bar.background = alloc_scene_tree(c->title_bar.tree, &failed); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// for opacity purposes we need to carfully create the scene such that
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// none of our rect nodes as well as text buffers don't overlap. To do
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// this we have to create rects such that they go around text buffers
 | 
			
		
	
		
			
				
					|  |  |  |  | 	for (int i = 0; i < 4; i++) { | 
			
		
	
		
			
				
					|  |  |  |  | 		alloc_rect_node(c->title_bar.border, &failed); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	for (int i = 0; i < 5; i++) { | 
			
		
	
		
			
				
					|  |  |  |  | 		alloc_rect_node(c->title_bar.background, &failed); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	c->border.tree = alloc_scene_tree(c->scene_tree, &failed); | 
			
		
	
		
			
				
					|  |  |  |  | 	c->content_tree = alloc_scene_tree(c->border.tree, &failed); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (view) { | 
			
		
	
		
			
				
					|  |  |  |  | 		// only containers with views can have borders
 | 
			
		
	
		
			
				
					|  |  |  |  | 		c->border.top = alloc_rect_node(c->border.tree, &failed); | 
			
		
	
		
			
				
					|  |  |  |  | 		c->border.bottom = alloc_rect_node(c->border.tree, &failed); | 
			
		
	
		
			
				
					|  |  |  |  | 		c->border.left = alloc_rect_node(c->border.tree, &failed); | 
			
		
	
		
			
				
					|  |  |  |  | 		c->border.right = alloc_rect_node(c->border.tree, &failed); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (failed) { | 
			
		
	
		
			
				
					|  |  |  |  | 		wlr_scene_node_destroy(&c->scene_tree->node); | 
			
		
	
		
			
				
					|  |  |  |  | 		free(c); | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!view) { | 
			
		
	
		
			
				
					|  |  |  |  | 		c->pending.children = create_list(); | 
			
		
	
		
			
				
					|  |  |  |  | 		c->current.children = create_list(); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	c->pending.layout = L_NONE; | 
			
		
	
		
			
				
					|  |  |  |  | 	c->view = view; | 
			
		
	
		
			
				
					|  |  |  |  | 	c->alpha = 1.0f; | 
			
		
	
		
			
				
					|  |  |  |  | 	c->marks = create_list(); | 
			
		
	
		
			
				
					|  |  |  |  | 	c->outputs = create_list(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -85,6 +151,8 @@ void container_destroy(struct sway_container *con) { | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	scene_node_disown_children(con->content_tree); | 
			
		
	
		
			
				
					|  |  |  |  | 	wlr_scene_node_destroy(&con->scene_tree->node); | 
			
		
	
		
			
				
					|  |  |  |  | 	free(con); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | 
 |