summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfamfo <[email protected]>2023-12-22 06:08:09 +0000
committerGitHub <[email protected]>2023-12-22 01:08:09 -0500
commitca42d414536c167f951e23bfc50d5edabb6f9dc2 (patch)
tree989ef953da5cc98a826de4bf19dc2aad34d8f1be
parent5e866d0345449f34ac51c6590a3aac285cb2f8bf (diff)
Implement shadow_offset (#255)
-rw-r--r--README.md1
-rw-r--r--include/sway/commands.h1
-rw-r--r--include/sway/config.h1
-rw-r--r--include/sway/desktop/fx_renderer/fx_renderer.h4
-rw-r--r--sway/commands.c1
-rw-r--r--sway/commands/shadow_offset.c27
-rw-r--r--sway/config.c2
-rw-r--r--sway/desktop/fx_renderer/fx_renderer.c14
-rw-r--r--sway/desktop/output.c4
-rw-r--r--sway/desktop/render.c32
-rw-r--r--sway/meson.build1
-rw-r--r--sway/sway.5.scd3
12 files changed, 64 insertions, 27 deletions
diff --git a/README.md b/README.md
index b1750da7..0941944e 100644
--- a/README.md
+++ b/README.md
@@ -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*.