Added support for shadows
This commit is contained in:
		
							parent
							
								
									d4e8038082
								
							
						
					
					
						commit
						1030f08b06
					
				
					 7 changed files with 116 additions and 64 deletions
				
			
		|  | @ -32,7 +32,7 @@ Sway is an incredible window manager, and certainly one of the most well establi | ||||||
|     - `blur_passes <integer value 0 - 10>` |     - `blur_passes <integer value 0 - 10>` | ||||||
|     - `blur_radius <integer value 0 - 10>` |     - `blur_radius <integer value 0 - 10>` | ||||||
| + LayerShell effects: *ONLY ON SWAYFX-GIT, NOT YET RELEASED* | + LayerShell effects: *ONLY ON SWAYFX-GIT, NOT YET RELEASED* | ||||||
|     - `layer_effects <layer namespace, eg: "waybar"> blur corner_radius` |     - `layer_effects <layer namespace, eg: "waybar"> blur shadow corner_radius` | ||||||
| + Dim unfocused windows: | + Dim unfocused windows: | ||||||
|     - `default_dim_inactive <float value 0.0 - 1.0>` |     - `default_dim_inactive <float value 0.0 - 1.0>` | ||||||
|     - `for_window [CRITERIA_HERE] dim_inactive <float value 0.0 - 1.0>` |     - `for_window [CRITERIA_HERE] dim_inactive <float value 0.0 - 1.0>` | ||||||
|  |  | ||||||
|  | @ -478,6 +478,7 @@ struct blur_parameters { | ||||||
| struct layer_effects { | struct layer_effects { | ||||||
| 	char *namespace; | 	char *namespace; | ||||||
| 	bool blur; | 	bool blur; | ||||||
|  | 	bool shadow; | ||||||
| 	bool corner_radius; | 	bool corner_radius; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -30,6 +30,7 @@ struct decoration_data { | ||||||
| 	float *dim_color; | 	float *dim_color; | ||||||
| 	bool has_titlebar; | 	bool has_titlebar; | ||||||
| 	bool blur; | 	bool blur; | ||||||
|  | 	bool shadow; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct fx_render_data { | struct fx_render_data { | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ struct cmd_results *cmd_layer_effects(int argc, char **argv) { | ||||||
| 	effect->namespace = malloc(len + 1); | 	effect->namespace = malloc(len + 1); | ||||||
| 	memcpy(effect->namespace, argv[0], len); | 	memcpy(effect->namespace, argv[0], len); | ||||||
| 	effect->blur = false; | 	effect->blur = false; | ||||||
|  | 	effect->shadow = false; | ||||||
| 	effect->corner_radius = false; | 	effect->corner_radius = false; | ||||||
| 
 | 
 | ||||||
| 	// Parse the commands
 | 	// Parse the commands
 | ||||||
|  | @ -22,6 +23,9 @@ struct cmd_results *cmd_layer_effects(int argc, char **argv) { | ||||||
| 		if (strcmp(arg, "blur") == 0) { | 		if (strcmp(arg, "blur") == 0) { | ||||||
| 			effect->blur = true; | 			effect->blur = true; | ||||||
| 			continue; | 			continue; | ||||||
|  | 		} else if (strcmp(arg, "shadow") == 0) { | ||||||
|  | 			effect->shadow = true; | ||||||
|  | 			continue; | ||||||
| 		} else if (strcmp(arg, "corner_rounding") == 0) { | 		} else if (strcmp(arg, "corner_rounding") == 0) { | ||||||
| 			effect->corner_radius = true; | 			effect->corner_radius = true; | ||||||
| 			continue; | 			continue; | ||||||
|  | @ -29,7 +33,7 @@ struct cmd_results *cmd_layer_effects(int argc, char **argv) { | ||||||
| 		return cmd_results_new(CMD_INVALID, "Invalid layer_effects effect! Got \"%s\"", arg); | 		return cmd_results_new(CMD_INVALID, "Invalid layer_effects effect! Got \"%s\"", arg); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!effect->blur && !effect->corner_radius) { | 	if (!effect->blur && !effect->shadow && !effect->corner_radius) { | ||||||
| 		return cmd_results_new(CMD_SUCCESS, NULL); | 		return cmd_results_new(CMD_SUCCESS, NULL); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -202,9 +202,9 @@ void output_layer_for_each_toplevel_surface(struct sway_output *output, | ||||||
| 		struct fx_render_data *data = user_data; | 		struct fx_render_data *data = user_data; | ||||||
| 		struct layer_effects *effects = layer_surface->effects; | 		struct layer_effects *effects = layer_surface->effects; | ||||||
| 		if (effects) { | 		if (effects) { | ||||||
| 			data->deco_data.blur = effects->blur; | 			data->deco_data.blur = effects->blur && config->blur_enabled; | ||||||
| 			data->deco_data.corner_radius = | 			data->deco_data.shadow = effects->shadow && config->shadow_enabled; | ||||||
| 				effects->corner_radius? config->corner_radius: 0; | 			data->deco_data.corner_radius = effects->corner_radius? config->corner_radius: 0; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		output_surface_for_each_surface(output, wlr_layer_surface_v1->surface, | 		output_surface_for_each_surface(output, wlr_layer_surface_v1->surface, | ||||||
|  |  | ||||||
|  | @ -48,6 +48,7 @@ struct decoration_data get_undecorated_decoration_data() { | ||||||
| 		.saturation = 1.0f, | 		.saturation = 1.0f, | ||||||
| 		.has_titlebar = false, | 		.has_titlebar = false, | ||||||
| 		.blur = false, | 		.blur = false, | ||||||
|  | 		.shadow = false, | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -59,6 +60,10 @@ bool should_parameters_blur() { | ||||||
| 	return config->blur_params.radius > 0 && config->blur_params.num_passes > 0; | 	return config->blur_params.radius > 0 && config->blur_params.num_passes > 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool should_parameters_shadow() { | ||||||
|  | 	return config->shadow_blur_sigma > 0 && config->shadow_color[3] > 0.0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Apply scale to a width or height. |  * Apply scale to a width or height. | ||||||
|  * |  * | ||||||
|  | @ -323,6 +328,51 @@ damage_finish: | ||||||
| 	pixman_region32_fini(&inverse_opaque); | 	pixman_region32_fini(&inverse_opaque); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // _box.x and .y are expected to be layout-local
 | ||||||
|  | // _box.width and .height are expected to be output-buffer-local
 | ||||||
|  | void render_box_shadow(struct sway_output *output, pixman_region32_t *output_damage, | ||||||
|  | 		const struct wlr_box *_box, const float color[static 4], | ||||||
|  | 		float blur_sigma, float corner_radius) { | ||||||
|  | 	struct wlr_output *wlr_output = output->wlr_output; | ||||||
|  | 	struct fx_renderer *renderer = output->renderer; | ||||||
|  | 
 | ||||||
|  | 	struct wlr_box box; | ||||||
|  | 	memcpy(&box, _box, sizeof(struct wlr_box)); | ||||||
|  | 	box.x -= output->lx * wlr_output->scale + blur_sigma; | ||||||
|  | 	box.y -= output->ly * wlr_output->scale + blur_sigma; | ||||||
|  | 	box.width += 2 * blur_sigma; | ||||||
|  | 	box.height += 2 * blur_sigma; | ||||||
|  | 
 | ||||||
|  | 	pixman_region32_t damage = create_damage(box, output_damage); | ||||||
|  | 
 | ||||||
|  | 	// don't damage area behind window since we dont render it anyway
 | ||||||
|  | 	struct wlr_box inner_box; | ||||||
|  | 	memcpy(&inner_box, _box, sizeof(struct wlr_box)); | ||||||
|  | 	inner_box.x += corner_radius; | ||||||
|  | 	inner_box.y += corner_radius; | ||||||
|  | 	inner_box.width -= 2 * corner_radius; | ||||||
|  | 	inner_box.height -= 2 * corner_radius; | ||||||
|  | 	pixman_region32_t inner_damage = create_damage(inner_box, output_damage); | ||||||
|  | 	pixman_region32_subtract(&damage, &damage, &inner_damage); | ||||||
|  | 
 | ||||||
|  | 	bool damaged = pixman_region32_not_empty(&damage); | ||||||
|  | 	if (!damaged) { | ||||||
|  | 		goto damage_finish; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	int nrects; | ||||||
|  | 	pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); | ||||||
|  | 	for (int i = 0; i < nrects; ++i) { | ||||||
|  | 		scissor_output(wlr_output, &rects[i]); | ||||||
|  | 
 | ||||||
|  | 		fx_render_box_shadow(renderer, &box, color, | ||||||
|  | 				wlr_output->transform_matrix, corner_radius, blur_sigma); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | damage_finish: | ||||||
|  | 	pixman_region32_fini(&damage); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| static void render_surface_iterator(struct sway_output *output, | static void render_surface_iterator(struct sway_output *output, | ||||||
| 		struct sway_view *view, struct wlr_surface *surface, | 		struct sway_view *view, struct wlr_surface *surface, | ||||||
|  | @ -391,6 +441,7 @@ static void render_surface_iterator(struct sway_output *output, | ||||||
| 		pixman_region32_fini(&opaque_region); | 		pixman_region32_fini(&opaque_region); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// Render surface texture
 | ||||||
| 	struct wlr_fbox src_box; | 	struct wlr_fbox src_box; | ||||||
| 	wlr_surface_get_buffer_source_box(surface, &src_box); | 	wlr_surface_get_buffer_source_box(surface, &src_box); | ||||||
| 	struct fx_texture fx_texture = fx_texture_from_wlr_texture(texture); | 	struct fx_texture fx_texture = fx_texture_from_wlr_texture(texture); | ||||||
|  | @ -399,6 +450,34 @@ static void render_surface_iterator(struct sway_output *output, | ||||||
| 
 | 
 | ||||||
| 	wlr_presentation_surface_sampled_on_output(server.presentation, surface, | 	wlr_presentation_surface_sampled_on_output(server.presentation, surface, | ||||||
| 		wlr_output); | 		wlr_output); | ||||||
|  | 
 | ||||||
|  | 	// render shadow (view->surface == surface excludes shadow on subsurfaces)
 | ||||||
|  | 	if (deco_data.shadow && should_parameters_shadow() && !is_subsurface) { | ||||||
|  | 		enum sway_container_border border = B_NONE; | ||||||
|  | 		int corner_radius = deco_data.corner_radius; | ||||||
|  | 		struct wlr_box box; | ||||||
|  | 		if (data->is_toplevel_surface) { | ||||||
|  | 			memcpy(&box, &dst_box, sizeof(struct wlr_box)); | ||||||
|  | 		} else if (view) { | ||||||
|  | 			struct sway_container *con = view->container; | ||||||
|  | 			struct sway_container_state *state = &con->current; | ||||||
|  | 
 | ||||||
|  | 			border = view->container->current.border; | ||||||
|  | 			corner_radius = (con->corner_radius + state->border_thickness) * wlr_output->scale; | ||||||
|  | 
 | ||||||
|  | 			box.x = floor(state->x); | ||||||
|  | 			box.y = floor(state->y); | ||||||
|  | 			box.width = state->width; | ||||||
|  | 			box.height = state->height; | ||||||
|  | 		} | ||||||
|  | 		// Only draw shadows on CSD windows if shadows_on_csd is enabled
 | ||||||
|  | 		if (border == B_CSD && !config->shadows_on_csd_enabled) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 		scale_box(&box, wlr_output->scale); | ||||||
|  | 		render_box_shadow(output, output_damage, &box, config->shadow_color, | ||||||
|  | 				config->shadow_blur_sigma, corner_radius); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void render_layer_toplevel(struct sway_output *output, | static void render_layer_toplevel(struct sway_output *output, | ||||||
|  | @ -597,51 +676,6 @@ damage_finish: | ||||||
| 	pixman_region32_fini(&damage); | 	pixman_region32_fini(&damage); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // _box.x and .y are expected to be layout-local
 |  | ||||||
| // _box.width and .height are expected to be output-buffer-local
 |  | ||||||
| void render_box_shadow(struct sway_output *output, pixman_region32_t *output_damage, |  | ||||||
| 		const struct wlr_box *_box, const float color[static 4], |  | ||||||
| 		float blur_sigma, float corner_radius) { |  | ||||||
| 	struct wlr_output *wlr_output = output->wlr_output; |  | ||||||
| 	struct fx_renderer *renderer = output->renderer; |  | ||||||
| 
 |  | ||||||
| 	struct wlr_box box; |  | ||||||
| 	memcpy(&box, _box, sizeof(struct wlr_box)); |  | ||||||
| 	box.x -= output->lx * wlr_output->scale + blur_sigma; |  | ||||||
| 	box.y -= output->ly * wlr_output->scale + blur_sigma; |  | ||||||
| 	box.width += 2 * blur_sigma; |  | ||||||
| 	box.height += 2 * blur_sigma; |  | ||||||
| 
 |  | ||||||
| 	pixman_region32_t damage = create_damage(box, output_damage); |  | ||||||
| 
 |  | ||||||
| 	// don't damage area behind window since we dont render it anyway
 |  | ||||||
| 	struct wlr_box inner_box; |  | ||||||
| 	memcpy(&inner_box, _box, sizeof(struct wlr_box)); |  | ||||||
| 	inner_box.x += corner_radius; |  | ||||||
| 	inner_box.y += corner_radius; |  | ||||||
| 	inner_box.width -= 2 * corner_radius; |  | ||||||
| 	inner_box.height -= 2 * corner_radius; |  | ||||||
| 	pixman_region32_t inner_damage = create_damage(inner_box, output_damage); |  | ||||||
| 	pixman_region32_subtract(&damage, &damage, &inner_damage); |  | ||||||
| 
 |  | ||||||
| 	bool damaged = pixman_region32_not_empty(&damage); |  | ||||||
| 	if (!damaged) { |  | ||||||
| 		goto damage_finish; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	int nrects; |  | ||||||
| 	pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); |  | ||||||
| 	for (int i = 0; i < nrects; ++i) { |  | ||||||
| 		scissor_output(wlr_output, &rects[i]); |  | ||||||
| 
 |  | ||||||
| 		fx_render_box_shadow(renderer, &box, color, |  | ||||||
| 				wlr_output->transform_matrix, corner_radius, blur_sigma); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| damage_finish: |  | ||||||
| 	pixman_region32_fini(&damage); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void premultiply_alpha(float color[4], float opacity) { | void premultiply_alpha(float color[4], float opacity) { | ||||||
| 	color[3] *= opacity; | 	color[3] *= opacity; | ||||||
| 	color[0] *= color[3]; | 	color[0] *= color[3]; | ||||||
|  | @ -724,7 +758,8 @@ static void render_saved_view(struct sway_view *view, struct sway_output *output | ||||||
| 		enum wl_output_transform transform = wlr_output_transform_invert(saved_buf->transform); | 		enum wl_output_transform transform = wlr_output_transform_invert(saved_buf->transform); | ||||||
| 		wlr_matrix_project_box(matrix, &proj_box, transform, 0, wlr_output->transform_matrix); | 		wlr_matrix_project_box(matrix, &proj_box, transform, 0, wlr_output->transform_matrix); | ||||||
| 
 | 
 | ||||||
| 		struct sway_container_state state = view->container->current; | 		struct sway_container *con = view->container; | ||||||
|  | 		struct sway_container_state state = con->current; | ||||||
| 		dst_box.x = state.x - output->lx; | 		dst_box.x = state.x - output->lx; | ||||||
| 		dst_box.y = state.y - output->ly; | 		dst_box.y = state.y - output->ly; | ||||||
| 		dst_box.width = state.width; | 		dst_box.width = state.width; | ||||||
|  | @ -752,7 +787,7 @@ static void render_saved_view(struct sway_view *view, struct sway_output *output | ||||||
| 				struct wlr_box monitor_box = get_monitor_box(wlr_output); | 				struct wlr_box monitor_box = get_monitor_box(wlr_output); | ||||||
| 				// TODO: contribute wlroots function to allow creating an fbox from a box?
 | 				// TODO: contribute wlroots function to allow creating an fbox from a box?
 | ||||||
| 				struct wlr_fbox src_box = { monitor_box.x, monitor_box.y, monitor_box.width, monitor_box.height }; | 				struct wlr_fbox src_box = { monitor_box.x, monitor_box.y, monitor_box.width, monitor_box.height }; | ||||||
| 				bool is_floating = container_is_floating(view->container); | 				bool is_floating = container_is_floating(con); | ||||||
| 				render_blur(!is_floating, output, damage, &src_box, &dst_box, &opaque_region, | 				render_blur(!is_floating, output, damage, &src_box, &dst_box, &opaque_region, | ||||||
| 						saved_buf->width, saved_buf->height, 1, deco_data.corner_radius); | 						saved_buf->width, saved_buf->height, 1, deco_data.corner_radius); | ||||||
| 
 | 
 | ||||||
|  | @ -760,9 +795,26 @@ static void render_saved_view(struct sway_view *view, struct sway_output *output | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		// Render saved surface texture
 | ||||||
| 		struct fx_texture fx_texture = fx_texture_from_wlr_texture(saved_buf->buffer->texture); | 		struct fx_texture fx_texture = fx_texture_from_wlr_texture(saved_buf->buffer->texture); | ||||||
| 		render_texture(wlr_output, damage, &fx_texture, | 		render_texture(wlr_output, damage, &fx_texture, | ||||||
| 				&saved_buf->source_box, &dst_box, matrix, deco_data); | 				&saved_buf->source_box, &dst_box, matrix, deco_data); | ||||||
|  | 
 | ||||||
|  | 		// render shadow
 | ||||||
|  | 		if (deco_data.shadow && should_parameters_shadow() | ||||||
|  | 				// Only draw shadows on CSD windows if shadows_on_csd is enabled
 | ||||||
|  | 				&& !(con->current.border == B_CSD && !config->shadows_on_csd_enabled)) { | ||||||
|  | 			struct wlr_box box = { | ||||||
|  | 				.x = floor(state.x), | ||||||
|  | 				.y = floor(state.y), | ||||||
|  | 				.width = state.width, | ||||||
|  | 				.height = state.height, | ||||||
|  | 			}; | ||||||
|  | 			int corner_radius = (con->corner_radius + state.border_thickness) * wlr_output->scale; | ||||||
|  | 			scale_box(&box, wlr_output->scale); | ||||||
|  | 			render_box_shadow(output, damage, &box, config->shadow_color, | ||||||
|  | 					config->shadow_blur_sigma, corner_radius); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// FIXME: we should set the surface that this saved buffer originates from
 | 	// FIXME: we should set the surface that this saved buffer originates from
 | ||||||
|  | @ -794,18 +846,6 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage, | ||||||
| 	float output_scale = output->wlr_output->scale; | 	float output_scale = output->wlr_output->scale; | ||||||
| 	struct wlr_box box; | 	struct wlr_box box; | ||||||
| 
 | 
 | ||||||
| 	// render shadow
 |  | ||||||
| 	if (con->shadow_enabled && config->shadow_blur_sigma > 0 && config->shadow_color[3] > 0.0) { |  | ||||||
| 		box.x = floor(state->x); |  | ||||||
| 		box.y = floor(state->y); |  | ||||||
| 		box.width = state->width; |  | ||||||
| 		box.height = state->height; |  | ||||||
| 		scale_box(&box, output_scale); |  | ||||||
| 		int scaled_corner_radius = (con->corner_radius + state->border_thickness) * output_scale; |  | ||||||
| 		render_box_shadow(output, damage, &box, config->shadow_color, config->shadow_blur_sigma, |  | ||||||
| 				scaled_corner_radius); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (state->border == B_NONE || state->border == B_CSD) { | 	if (state->border == B_NONE || state->border == B_CSD) { | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  | @ -1357,6 +1397,7 @@ static void render_containers_linear(struct sway_output *output, | ||||||
| 				.saturation = child->saturation, | 				.saturation = child->saturation, | ||||||
| 				.has_titlebar = has_titlebar, | 				.has_titlebar = has_titlebar, | ||||||
| 				.blur = child->blur_enabled, | 				.blur = child->blur_enabled, | ||||||
|  | 				.shadow = child->shadow_enabled, | ||||||
| 			}; | 			}; | ||||||
| 			render_view(output, damage, child, colors, deco_data); | 			render_view(output, damage, child, colors, deco_data); | ||||||
| 			if (has_titlebar) { | 			if (has_titlebar) { | ||||||
|  | @ -1465,6 +1506,7 @@ static void render_containers_tabbed(struct sway_output *output, | ||||||
| 			.saturation = current->saturation, | 			.saturation = current->saturation, | ||||||
| 			.has_titlebar = true, | 			.has_titlebar = true, | ||||||
| 			.blur = current->blur_enabled, | 			.blur = current->blur_enabled, | ||||||
|  | 			.shadow = current->shadow_enabled, | ||||||
| 		}; | 		}; | ||||||
| 		render_view(output, damage, current, current_colors, deco_data); | 		render_view(output, damage, current, current_colors, deco_data); | ||||||
| 	} else { | 	} else { | ||||||
|  | @ -1540,6 +1582,7 @@ static void render_containers_stacked(struct sway_output *output, | ||||||
| 			.corner_radius = current->corner_radius, | 			.corner_radius = current->corner_radius, | ||||||
| 			.has_titlebar = true, | 			.has_titlebar = true, | ||||||
| 			.blur = current->blur_enabled, | 			.blur = current->blur_enabled, | ||||||
|  | 			.shadow = current->shadow_enabled, | ||||||
| 		}; | 		}; | ||||||
| 		render_view(output, damage, current, current_colors, deco_data); | 		render_view(output, damage, current, current_colors, deco_data); | ||||||
| 	} else { | 	} else { | ||||||
|  | @ -1641,6 +1684,7 @@ static void render_floating_container(struct sway_output *soutput, | ||||||
| 			.corner_radius = con->corner_radius, | 			.corner_radius = con->corner_radius, | ||||||
| 			.has_titlebar = has_titlebar, | 			.has_titlebar = has_titlebar, | ||||||
| 			.blur = con->blur_enabled, | 			.blur = con->blur_enabled, | ||||||
|  | 			.shadow = con->shadow_enabled, | ||||||
| 		}; | 		}; | ||||||
| 		render_view(soutput, damage, con, colors, deco_data); | 		render_view(soutput, damage, con, colors, deco_data); | ||||||
| 		if (has_titlebar) { | 		if (has_titlebar) { | ||||||
|  | @ -1944,6 +1988,7 @@ void output_render(struct sway_output *output, struct timespec *when, | ||||||
| 			.saturation = focus->saturation, | 			.saturation = focus->saturation, | ||||||
| 			.has_titlebar = false, | 			.has_titlebar = false, | ||||||
| 			.blur = false, | 			.blur = false, | ||||||
|  | 			.shadow = false, | ||||||
| 		}; | 		}; | ||||||
| 		render_view_popups(focus->view, output, damage, deco_data); | 		render_view_popups(focus->view, output, damage, deco_data); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -77,6 +77,7 @@ The following commands may only be used in the configuration file. | ||||||
| 
 | 
 | ||||||
| 	Effects: | 	Effects: | ||||||
| 	- *blur* | 	- *blur* | ||||||
|  | 	- *shadow* | ||||||
| 	- *corner_rounding* | 	- *corner_rounding* | ||||||
| 
 | 
 | ||||||
| *scratchpad_minimize* enable|disable | *scratchpad_minimize* enable|disable | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue