From 69e54ef0d0215a5579975e7fad51bbb043e6e403 Mon Sep 17 00:00:00 2001
From: Mykyta Holubakha <hilobakho@gmail.com>
Date: Tue, 30 Apr 2019 18:50:47 +0300
Subject: [PATCH] Render transparent fullscreen containers

desktop/output: always iterate all surfaces

Assume views under fullscreen containers visible
---
 sway/desktop/output.c | 50 ++++++------------------
 sway/desktop/render.c | 88 +++++++++++++++++++++----------------------
 sway/tree/view.c      |  4 +-
 3 files changed, 56 insertions(+), 86 deletions(-)

diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 0cc08525..158669e1 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -251,51 +251,25 @@ static void output_for_each_surface(struct sway_output *output,
 	};
 
 	struct sway_workspace *workspace = output_get_active_workspace(output);
-	struct sway_container *fullscreen_con = root->fullscreen_global;
-	if (!fullscreen_con) {
-		if (!workspace) {
-			return;
-		}
-		fullscreen_con = workspace->current.fullscreen;
-	}
-	if (fullscreen_con) {
-		for_each_surface_container_iterator(fullscreen_con, &data);
-		container_for_each_child(fullscreen_con,
-			for_each_surface_container_iterator, &data);
 
-		// TODO: Show transient containers for fullscreen global
-		if (fullscreen_con == workspace->current.fullscreen) {
-			for (int i = 0; i < workspace->current.floating->length; ++i) {
-				struct sway_container *floater =
-					workspace->current.floating->items[i];
-				if (container_is_transient_for(floater, fullscreen_con)) {
-					for_each_surface_container_iterator(floater, &data);
-				}
-			}
-		}
-#if HAVE_XWAYLAND
-		output_unmanaged_for_each_surface(output, &root->xwayland_unmanaged,
-			iterator, user_data);
-#endif
-	} else {
-		output_layer_for_each_surface(output,
-			&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
-			iterator, user_data);
-		output_layer_for_each_surface(output,
-			&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
-			iterator, user_data);
+	output_layer_for_each_surface(output,
+		&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
+		iterator, user_data);
+	output_layer_for_each_surface(output,
+		&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
+		iterator, user_data);
 
+	if (workspace)
 		workspace_for_each_container(workspace,
 			for_each_surface_container_iterator, &data);
 
 #if HAVE_XWAYLAND
-		output_unmanaged_for_each_surface(output, &root->xwayland_unmanaged,
-			iterator, user_data);
+	output_unmanaged_for_each_surface(output, &root->xwayland_unmanaged,
+		iterator, user_data);
 #endif
-		output_layer_for_each_surface(output,
-			&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
-			iterator, user_data);
-	}
+	output_layer_for_each_surface(output,
+		&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
+		iterator, user_data);
 
 overlay:
 	output_layer_for_each_surface(output,
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index 6bea5656..c56e7bf4 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -32,6 +32,8 @@ struct render_data {
 	float alpha;
 };
 
+static struct sway_container *fullscreen_con;
+
 /**
  * Apply scale to a width or height.
  *
@@ -675,6 +677,10 @@ static void render_containers_linear(struct sway_output *output,
 	for (int i = 0; i < parent->children->length; ++i) {
 		struct sway_container *child = parent->children->items[i];
 
+		if (child == fullscreen_con) {
+			continue;
+		}
+
 		if (child->view) {
 			struct sway_view *view = child->view;
 			struct border_colors *colors;
@@ -878,6 +884,9 @@ static void render_container(struct sway_output *output,
 		.focused = focused,
 		.active_child = con->current.focused_inactive_child,
 	};
+	if (con == fullscreen_con) {
+		return;
+	}
 	render_containers(output, damage, &data);
 }
 
@@ -996,66 +1005,53 @@ void output_render(struct sway_output *output, struct timespec *when,
 		goto render_overlay;
 	}
 
-	struct sway_container *fullscreen_con = root->fullscreen_global;
+	fullscreen_con = root->fullscreen_global;
 	if (!fullscreen_con) {
 		fullscreen_con = workspace->current.fullscreen;
 	}
 
-	if (fullscreen_con) {
-		float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
+	float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f};
 
-		int nrects;
-		pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
-		for (int i = 0; i < nrects; ++i) {
-			scissor_output(wlr_output, &rects[i]);
-			wlr_renderer_clear(renderer, clear_color);
-		}
+	int nrects;
+	pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
+	for (int i = 0; i < nrects; ++i) {
+		scissor_output(wlr_output, &rects[i]);
+		wlr_renderer_clear(renderer, clear_color);
+	}
 
-		if (fullscreen_con->view) {
-			if (fullscreen_con->view->saved_buffer) {
-				render_saved_view(fullscreen_con->view, output, damage, 1.0f);
-			} else if (fullscreen_con->view->surface) {
-				render_view_toplevels(fullscreen_con->view,
-						output, damage, 1.0f);
+	render_layer(output, damage,
+		&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
+	render_layer(output, damage,
+		&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
+
+	render_workspace(output, damage, workspace, workspace->current.focused);
+
+	struct sway_container *fs_con = fullscreen_con;
+	fullscreen_con = NULL;
+	if (fs_con) {
+		if (fs_con->view) {
+			if (fs_con->view->saved_buffer) {
+				render_saved_view(fs_con->view, output, damage,
+					fs_con->alpha);
+			} else if (fs_con->view->surface) {
+				render_view_toplevels(fs_con->view,
+					output, damage,
+					fs_con->alpha);
 			}
 		} else {
-			render_container(output, damage, fullscreen_con,
-					fullscreen_con->current.focused);
-		}
-
-		for (int i = 0; i < workspace->current.floating->length; ++i) {
-			struct sway_container *floater =
-				workspace->current.floating->items[i];
-			if (container_is_transient_for(floater, fullscreen_con)) {
-				render_floating_container(output, damage, floater);
-			}
+			render_container(output, damage, fs_con,
+				fs_con->current.focused);
 		}
-#if HAVE_XWAYLAND
-		render_unmanaged(output, damage, &root->xwayland_unmanaged);
-#endif
-	} else {
-		float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f};
+	}
 
-		int nrects;
-		pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
-		for (int i = 0; i < nrects; ++i) {
-			scissor_output(wlr_output, &rects[i]);
-			wlr_renderer_clear(renderer, clear_color);
-		}
+	render_floating(output, damage);
 
-		render_layer(output, damage,
-			&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
-		render_layer(output, damage,
-			&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
 
-		render_workspace(output, damage, workspace, workspace->current.focused);
-		render_floating(output, damage);
 #if HAVE_XWAYLAND
-		render_unmanaged(output, damage, &root->xwayland_unmanaged);
+	render_unmanaged(output, damage, &root->xwayland_unmanaged);
 #endif
-		render_layer(output, damage,
-			&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
-	}
+	render_layer(output, damage,
+		&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
 
 	render_seatops(output, damage);
 
diff --git a/sway/tree/view.c b/sway/tree/view.c
index e8f5a299..0b103162 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -1078,12 +1078,12 @@ bool view_is_visible(struct sway_view *view) {
 		con = con->parent;
 	}
 	// Check view isn't hidden by another fullscreen view
-	struct sway_container *fs = root->fullscreen_global ?
+	/*struct sway_container *fs = root->fullscreen_global ?
 		root->fullscreen_global : workspace->fullscreen;
 	if (fs && !container_is_fullscreen_or_child(view->container) &&
 			!container_is_transient_for(view->container, fs)) {
 		return false;
-	}
+	}*/
 	return true;
 }
 
-- 
2.21.0

