diff options
| author | famfo <[email protected]> | 2023-12-22 06:08:09 +0000 | 
|---|---|---|
| committer | GitHub <[email protected]> | 2023-12-22 01:08:09 -0500 | 
| commit | ca42d414536c167f951e23bfc50d5edabb6f9dc2 (patch) | |
| tree | 989ef953da5cc98a826de4bf19dc2aad34d8f1be | |
| parent | 5e866d0345449f34ac51c6590a3aac285cb2f8bf (diff) | |
Implement shadow_offset (#255)
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | include/sway/commands.h | 1 | ||||
| -rw-r--r-- | include/sway/config.h | 1 | ||||
| -rw-r--r-- | include/sway/desktop/fx_renderer/fx_renderer.h | 4 | ||||
| -rw-r--r-- | sway/commands.c | 1 | ||||
| -rw-r--r-- | sway/commands/shadow_offset.c | 27 | ||||
| -rw-r--r-- | sway/config.c | 2 | ||||
| -rw-r--r-- | sway/desktop/fx_renderer/fx_renderer.c | 14 | ||||
| -rw-r--r-- | sway/desktop/output.c | 4 | ||||
| -rw-r--r-- | sway/desktop/render.c | 32 | ||||
| -rw-r--r-- | sway/meson.build | 1 | ||||
| -rw-r--r-- | sway/sway.5.scd | 3 | 
12 files changed, 64 insertions, 27 deletions
| @@ -36,6 +36,7 @@ Sway is an incredible window manager, and certainly one of the most well establi      - `shadows_on_csd enable|disable` (**Note**: The shadow might not fit some windows)      - `shadow_blur_radius <integer value 0 - 100>`      - `shadow_color <hex color with alpha> ex, #0000007F` +    - `shadow_offset <x offset> <y offset>`      - `shadow_inactive_color <hex color with alpha> ex, #0000007F`  + LayerShell effects (to blur panels / notifications etc):      - `layer_effects <layer namespace> <effects>` diff --git a/include/sway/commands.h b/include/sway/commands.h index b4166284..c29d4ff4 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -192,6 +192,7 @@ sway_cmd cmd_set;  sway_cmd cmd_shortcuts_inhibitor;  sway_cmd cmd_shadow_blur_radius;  sway_cmd cmd_shadow_color; +sway_cmd cmd_shadow_offset;  sway_cmd cmd_shadow_inactive_color;  sway_cmd cmd_shadows;  sway_cmd cmd_shadows_on_csd; diff --git a/include/sway/config.h b/include/sway/config.h index 9f23bacf..81213dbc 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -493,6 +493,7 @@ struct sway_config {  	int shadow_blur_sigma;  	float shadow_color[4];  	float shadow_inactive_color[4]; +	float shadow_offset_x, shadow_offset_y;  	bool blur_enabled;  	bool blur_xray; diff --git a/include/sway/desktop/fx_renderer/fx_renderer.h b/include/sway/desktop/fx_renderer/fx_renderer.h index 410e3d94..bfae7b72 100644 --- a/include/sway/desktop/fx_renderer/fx_renderer.h +++ b/include/sway/desktop/fx_renderer/fx_renderer.h @@ -207,8 +207,8 @@ void fx_render_border_corner(struct fx_renderer *renderer, const struct wlr_box  		enum corner_location corner_location, int radius, int border_thickness);  void fx_render_box_shadow(struct fx_renderer *renderer, const struct wlr_box *box, -		const float color[static 4], const float matrix[static 9], int radius, -		float blur_sigma); +		const struct wlr_box *inner_box, const float color[static 4], +		const float matrix[static 9], int corner_radius, float blur_sigma);  void fx_render_blur(struct fx_renderer *renderer, const float matrix[static 9],  		struct fx_framebuffer **buffer, struct blur_shader *shader, const struct wlr_box *box, diff --git a/sway/commands.c b/sway/commands.c index 3927fb2f..75c6c1e5 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -96,6 +96,7 @@ static const struct cmd_handler handlers[] = {  	{ "set", cmd_set },  	{ "shadow_blur_radius", cmd_shadow_blur_radius },  	{ "shadow_color", cmd_shadow_color }, +	{ "shadow_offset", cmd_shadow_offset },  	{ "shadow_inactive_color", cmd_shadow_inactive_color },  	{ "shadows", cmd_shadows },  	{ "shadows_on_csd", cmd_shadows_on_csd }, diff --git a/sway/commands/shadow_offset.c b/sway/commands/shadow_offset.c new file mode 100644 index 00000000..a73b54c9 --- /dev/null +++ b/sway/commands/shadow_offset.c @@ -0,0 +1,27 @@ +#include <string.h> +#include "log.h" +#include "sway/commands.h" +#include "sway/config.h" + +struct cmd_results *cmd_shadow_offset(int argc, char **argv) { +	struct cmd_results *error = NULL; +	if ((error = checkarg(argc, "shadow_offset", EXPECTED_AT_LEAST, 2))) { +		return error; +	} + +	char *err; +	float offset_x = strtof(argv[0], &err); +	float offset_y = strtof(argv[1], &err); +	if (*err || offset_x < -99.9f || offset_x > 99.9f) { +		return cmd_results_new(CMD_INVALID, "x offset float invalid"); +	} +	if (*err || offset_y < -99.9f || offset_y > 99.9f) { +		return cmd_results_new(CMD_INVALID, "y offset float invalid"); +	} + +	config->shadow_offset_x = offset_x; +	config->shadow_offset_y = offset_y; + +	return cmd_results_new(CMD_SUCCESS, NULL); +} + diff --git a/sway/config.c b/sway/config.c index 7cb84496..a0168ad0 100644 --- a/sway/config.c +++ b/sway/config.c @@ -351,6 +351,8 @@ static void config_defaults(struct sway_config *config) {  	config->shadow_enabled = false;  	config->shadows_on_csd_enabled = false;  	config->shadow_blur_sigma = 20.0f; +	config->shadow_offset_x = 0.0f; +	config->shadow_offset_y = 0.0f;  	color_to_rgba(config->shadow_color, 0x0000007F);  	color_to_rgba(config->shadow_inactive_color, 0x0000007F); diff --git a/sway/desktop/fx_renderer/fx_renderer.c b/sway/desktop/fx_renderer/fx_renderer.c index 07758325..7196bb0e 100644 --- a/sway/desktop/fx_renderer/fx_renderer.c +++ b/sway/desktop/fx_renderer/fx_renderer.c @@ -799,8 +799,8 @@ void fx_render_stencil_mask(struct fx_renderer *renderer, const struct wlr_box *  // TODO: alpha input arg?  void fx_render_box_shadow(struct fx_renderer *renderer, const struct wlr_box *box, -		const float color[static 4], const float matrix[static 9], int corner_radius, -		float blur_sigma) { +		const struct wlr_box *inner_box, const float color[static 4],  +		const float matrix[static 9], int corner_radius, float blur_sigma) {  	if (box->width == 0 || box->height == 0) {  		return;  	} @@ -821,17 +821,9 @@ void fx_render_box_shadow(struct fx_renderer *renderer, const struct wlr_box *bo  	wlr_matrix_transpose(gl_matrix, gl_matrix); -	// Init stencil work -	struct wlr_box inner_box; -	memcpy(&inner_box, box, sizeof(struct wlr_box)); -	inner_box.x += blur_sigma; -	inner_box.y += blur_sigma; -	inner_box.width -= blur_sigma * 2; -	inner_box.height -= blur_sigma * 2; -  	fx_renderer_stencil_mask_init();  	// Draw the rounded rect as a mask -	fx_render_stencil_mask(renderer, &inner_box, matrix, corner_radius); +	fx_render_stencil_mask(renderer, inner_box, matrix, corner_radius);  	fx_renderer_stencil_mask_close(false);  	// blending will practically always be needed (unless we have a madman diff --git a/sway/desktop/output.c b/sway/desktop/output.c index c41088ac..ca883144 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -758,8 +758,8 @@ void output_damage_whole_container(struct sway_output *output,  	// Pad the box by 1px, because the width is a double and might be a fraction  	struct wlr_box box = { -		.x = con->current.x - output->lx - 1 - shadow_sigma, -		.y = con->current.y - output->ly - 1 - shadow_sigma, +		.x = con->current.x - output->lx - 1 - shadow_sigma + config->shadow_offset_x, +		.y = con->current.y - output->ly - 1 - shadow_sigma + config->shadow_offset_y,  		.width = con->current.width + 2 + shadow_sigma * 2,  		.height = con->current.height + 2 + shadow_sigma * 2,  	}; diff --git a/sway/desktop/render.c b/sway/desktop/render.c index fba13b37..c054b3a5 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -342,15 +342,15 @@ damage_finish:  // _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) { +		const struct wlr_box *_box, const float color[static 4], float blur_sigma,  +		float corner_radius, float offset_x, float offset_y) {  	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 -= blur_sigma; -	box.y -= blur_sigma; +	box.x -= blur_sigma - offset_x; +	box.y -= blur_sigma - offset_y;  	box.width += 2 * blur_sigma;  	box.height += 2 * blur_sigma; @@ -365,6 +365,7 @@ void render_box_shadow(struct sway_output *output, pixman_region32_t *output_dam  	inner_box.height -= 2 * corner_radius;  	pixman_region32_t inner_damage = create_damage(inner_box, output_damage);  	pixman_region32_subtract(&damage, &damage, &inner_damage); +	pixman_region32_fini(&inner_damage);  	bool damaged = pixman_region32_not_empty(&damage);  	if (!damaged) { @@ -375,20 +376,23 @@ void render_box_shadow(struct sway_output *output, pixman_region32_t *output_dam  	wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0,  			wlr_output->transform_matrix); -	// ensure the box is updated as per the output orientation -	struct wlr_box transformed_box;  	int width, height;  	wlr_output_transformed_resolution(wlr_output, &width, &height); -	wlr_box_transform(&transformed_box, &box, -			wlr_output_transform_invert(wlr_output->transform), width, height); +	enum wl_output_transform transform = wlr_output_transform_invert(wlr_output->transform); +	// ensure the shadow_box is updated as per the output orientation +	struct wlr_box transformed_shadow_box; +	wlr_box_transform(&transformed_shadow_box, &box, transform, width, height); +	// ensure the box is updated as per the output orientation +	struct wlr_box transformed_box; +	wlr_box_transform(&transformed_box, _box, transform, width, height);  	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, &transformed_box, color, matrix, -				corner_radius, blur_sigma); +		fx_render_box_shadow(renderer, &transformed_shadow_box, &transformed_box,  +				color, matrix, corner_radius, blur_sigma);  	}  damage_finish: @@ -488,9 +492,11 @@ static void render_layer_iterator(struct sway_output *output,  	// render shadow  	if (deco_data.shadow && config_should_parameters_shadow()) {  		int corner_radius = deco_data.corner_radius *= output->wlr_output->scale; +		int offset_x = config->shadow_offset_x * output->wlr_output->scale; +		int offset_y = config->shadow_offset_y * output->wlr_output->scale;  		scale_box(_box, output->wlr_output->scale);  		render_box_shadow(output, data->damage, _box, config->shadow_color, -				config->shadow_blur_sigma, corner_radius); +				config->shadow_blur_sigma, corner_radius, offset_x, offset_y);  	}  } @@ -886,8 +892,10 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage,  				0 : (deco_data.corner_radius + state->border_thickness) * output_scale;  		float* shadow_color = view_is_urgent(view) || state->focused ?  				config->shadow_color : config->shadow_inactive_color; +		int offset_x = config->shadow_offset_x * output->wlr_output->scale; +		int offset_y = config->shadow_offset_y * output->wlr_output->scale;  		render_box_shadow(output, damage, &box, shadow_color, config->shadow_blur_sigma, -				scaled_corner_radius); +				scaled_corner_radius, offset_x, offset_y);  	}  	if (state->border == B_NONE || state->border == B_CSD) { diff --git a/sway/meson.build b/sway/meson.build index 1bc0c19c..099f2b52 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -123,6 +123,7 @@ sway_sources = files(  	'commands/set.c',  	'commands/shadow_blur_radius.c',  	'commands/shadow_color.c', +    'commands/shadow_offset.c',  	'commands/shadow_inactive_color.c',  	'commands/shadows.c',  	'commands/shadows_on_csd.c', diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 0352b403..08c1a7cb 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -689,6 +689,9 @@ The default colors are:  *shadow_inactive_color* <hex color with alpha>  	The shadow color for inactive windows. Default value: *shadow_color* +*shadow_offset* <x offset> <y offset> +	Offset all box shadows by the given value. +  *blur* enable|disable  	Sets whether blur should be drawn. Can also be set per window with  	*for_window*. | 
