Implement shadow_offset (#255)
This commit is contained in:
parent
5e866d0345
commit
ca42d41453
|
@ -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>`
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 },
|
||||
|
|
27
sway/commands/shadow_offset.c
Normal file
27
sway/commands/shadow_offset.c
Normal file
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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*.
|
||||
|
|
Loading…
Reference in a new issue