mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2025-10-29 05:40:21 -04:00
feat: layer shadow support
This commit is contained in:
parent
5a8d666101
commit
71bcc9dc6a
4 changed files with 102 additions and 3 deletions
|
|
@ -12,6 +12,7 @@ blur_params_contrast = 0.9
|
|||
blur_params_saturation = 1.2
|
||||
|
||||
shadows = 0
|
||||
layer_shadows = 0
|
||||
shadows_size = 10
|
||||
shadows_blur = 15
|
||||
shadows_position_x = 0
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ typedef struct {
|
|||
char *layer_name; // 布局名称
|
||||
int noblur;
|
||||
int noanim;
|
||||
int noshadow;
|
||||
} ConfigLayerRule;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -216,6 +217,7 @@ typedef struct {
|
|||
int border_radius;
|
||||
struct blur_data blur_params;
|
||||
int shadows;
|
||||
int layer_shadows;
|
||||
unsigned int shadows_size;
|
||||
float shadows_blur;
|
||||
int shadows_position_x;
|
||||
|
|
@ -936,6 +938,8 @@ void parse_config_line(Config *config, const char *line) {
|
|||
config->blur_params.saturation = atof(value);
|
||||
} else if (strcmp(key, "shadows") == 0) {
|
||||
config->shadows = atoi(value);
|
||||
} else if (strcmp(key, "layer_shadows") == 0) {
|
||||
config->layer_shadows = atoi(value);
|
||||
} else if (strcmp(key, "shadows_size") == 0) {
|
||||
config->shadows_size = atoi(value);
|
||||
} else if (strcmp(key, "shadows_blur") == 0) {
|
||||
|
|
@ -1322,6 +1326,7 @@ void parse_config_line(Config *config, const char *line) {
|
|||
rule->layer_name = NULL;
|
||||
rule->noblur = 0;
|
||||
rule->noanim = 0;
|
||||
rule->noshadow = 0;
|
||||
|
||||
char *token = strtok(value, ",");
|
||||
while (token != NULL) {
|
||||
|
|
@ -1340,6 +1345,8 @@ void parse_config_line(Config *config, const char *line) {
|
|||
rule->noblur = CLAMP_INT(atoi(val), 0, 1);
|
||||
} else if (strcmp(key, "noanim") == 0) {
|
||||
rule->noanim = CLAMP_INT(atoi(val), 0, 1);
|
||||
} else if (strcmp(key, "noshadow") == 0) {
|
||||
rule->noshadow = CLAMP_INT(atoi(val), 0, 1);
|
||||
}
|
||||
}
|
||||
token = strtok(NULL, ",");
|
||||
|
|
@ -2201,6 +2208,7 @@ void override_config(void) {
|
|||
blur_params.contrast = CLAMP_FLOAT(config.blur_params.contrast, 0, 1);
|
||||
blur_params.saturation = CLAMP_FLOAT(config.blur_params.saturation, 0, 1);
|
||||
shadows = CLAMP_INT(config.shadows, 0, 1);
|
||||
layer_shadows = CLAMP_INT(config.layer_shadows, 0, 1);
|
||||
shadows_size = CLAMP_INT(config.shadows_size, 0, 100);
|
||||
shadows_blur = CLAMP_INT(config.shadows_blur, 0, 100);
|
||||
shadows_position_x = CLAMP_INT(config.shadows_position_x, -1000, 1000);
|
||||
|
|
@ -2338,6 +2346,7 @@ void set_value_default() {
|
|||
config.blur_params.contrast = blur_params_contrast;
|
||||
config.blur_params.saturation = blur_params_saturation;
|
||||
config.shadows = shadows;
|
||||
config.layer_shadows = layer_shadows;
|
||||
config.shadows_size = shadows_size;
|
||||
config.shadows_blur = shadows_blur;
|
||||
config.shadows_position_x = shadows_position_x;
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ float blur_params_contrast = 0.9;
|
|||
float blur_params_saturation = 1.2;
|
||||
|
||||
int shadows = 0;
|
||||
int layer_shadows = 0;
|
||||
unsigned int shadows_size = 10;
|
||||
double shadows_blur = 15;
|
||||
int shadows_position_x = 0;
|
||||
|
|
|
|||
94
src/maomao.c
94
src/maomao.c
|
|
@ -348,6 +348,7 @@ typedef struct {
|
|||
Monitor *mon;
|
||||
struct wlr_scene_tree *scene;
|
||||
struct wlr_scene_tree *popups;
|
||||
struct wlr_scene_shadow *shadow;
|
||||
struct wlr_scene_layer_surface_v1 *scene_layer;
|
||||
struct wl_list link;
|
||||
struct wl_list fadeout_link;
|
||||
|
|
@ -363,6 +364,7 @@ typedef struct {
|
|||
bool dirty;
|
||||
int noblur;
|
||||
int noanim;
|
||||
int noshadow;
|
||||
bool need_output_flush;
|
||||
} LayerSurface;
|
||||
|
||||
|
|
@ -635,6 +637,10 @@ static void client_update_oldmonname_record(Client *c, Monitor *m);
|
|||
static void pending_kill_client(Client *c);
|
||||
static void set_layer_open_animaiton(LayerSurface *l, struct wlr_box geo);
|
||||
static void init_fadeout_layers(LayerSurface *l);
|
||||
static void layer_actual_size(LayerSurface *l, unsigned int *width,
|
||||
unsigned int *height);
|
||||
static void get_layer_target_geometry(LayerSurface *l,
|
||||
struct wlr_box *target_box);
|
||||
|
||||
#include "data/static_keymap.h"
|
||||
#include "dispatch/dispatch.h"
|
||||
|
|
@ -1102,6 +1108,20 @@ void client_animation_next_tick(Client *c) {
|
|||
}
|
||||
}
|
||||
|
||||
void layer_actual_size(LayerSurface *l, unsigned int *width,
|
||||
unsigned int *height) {
|
||||
struct wlr_box box;
|
||||
|
||||
if (l->animation.running) {
|
||||
*width = l->animation.current.width;
|
||||
*height = l->animation.current.height;
|
||||
} else {
|
||||
get_layer_target_geometry(l, &box);
|
||||
*width = box.width;
|
||||
*height = box.height;
|
||||
}
|
||||
}
|
||||
|
||||
void client_actual_size(Client *c, unsigned int *width, unsigned int *height) {
|
||||
*width = c->animation.current.width - c->bw;
|
||||
|
||||
|
|
@ -1140,6 +1160,55 @@ bool check_hit_no_border(Client *c) {
|
|||
return hit_no_border;
|
||||
}
|
||||
|
||||
void layer_draw_shadow(LayerSurface *l) {
|
||||
|
||||
if (!l->mapped || !l->shadow)
|
||||
return;
|
||||
|
||||
if (!shadows || !layer_shadows || l->noshadow) {
|
||||
wlr_scene_shadow_set_size(l->shadow, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t width, height;
|
||||
layer_actual_size(l, &width, &height);
|
||||
|
||||
uint32_t delta = shadows_size;
|
||||
|
||||
/* we calculate where to clip the shadow */
|
||||
struct wlr_box layer_box = {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
|
||||
struct wlr_box shadow_box = {
|
||||
.x = shadows_position_x,
|
||||
.y = shadows_position_y,
|
||||
.width = width + 2 * delta,
|
||||
.height = height + 2 * delta,
|
||||
};
|
||||
|
||||
struct wlr_box intersection_box;
|
||||
wlr_box_intersection(&intersection_box, &layer_box, &shadow_box);
|
||||
/* clipped region takes shadow relative coords, so we translate everything
|
||||
* by its position */
|
||||
intersection_box.x -= shadows_position_x;
|
||||
intersection_box.y -= shadows_position_y;
|
||||
|
||||
struct clipped_region clipped_region = {
|
||||
.area = intersection_box,
|
||||
.corner_radius = border_radius,
|
||||
.corners = border_radius_location_default,
|
||||
};
|
||||
|
||||
wlr_scene_node_set_position(&l->shadow->node, shadow_box.x, shadow_box.y);
|
||||
|
||||
wlr_scene_shadow_set_size(l->shadow, shadow_box.width, shadow_box.height);
|
||||
wlr_scene_shadow_set_clipped_region(l->shadow, clipped_region);
|
||||
}
|
||||
|
||||
void client_draw_shadow(Client *c) {
|
||||
|
||||
if (c->iskilling || !client_surface(c)->mapped)
|
||||
|
|
@ -1486,7 +1555,9 @@ bool layer_draw_frame(LayerSurface *l) {
|
|||
|
||||
if (animations && layer_animations && l->animation.running && !l->noanim) {
|
||||
layer_animation_next_tick(l);
|
||||
layer_draw_shadow(l);
|
||||
} else {
|
||||
layer_draw_shadow(l);
|
||||
l->need_output_flush = false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -3263,11 +3334,12 @@ void maplayersurfacenotify(struct wl_listener *listener, void *data) {
|
|||
int ji;
|
||||
|
||||
LayerSurface *l = wl_container_of(listener, l, map);
|
||||
struct wlr_layer_surface_v1 *layer_surface = l->layer_surface;
|
||||
|
||||
l->mapped = 1;
|
||||
|
||||
if (!l->mon)
|
||||
return;
|
||||
struct wlr_layer_surface_v1 *layer_surface = l->layer_surface;
|
||||
strncpy(l->mon->last_surface_ws_name, layer_surface->namespace,
|
||||
sizeof(l->mon->last_surface_ws_name) - 1); // 最多拷贝255个字符
|
||||
l->mon->last_surface_ws_name[sizeof(l->mon->last_surface_ws_name) - 1] =
|
||||
|
|
@ -3280,6 +3352,8 @@ void maplayersurfacenotify(struct wl_listener *listener, void *data) {
|
|||
l->noanim = 0;
|
||||
l->dirty = false;
|
||||
l->noblur = 0;
|
||||
l->shadow = NULL;
|
||||
l->need_output_flush = true;
|
||||
|
||||
// 应用layer规则
|
||||
for (ji = 0; ji < config.layer_rules_count; ji++) {
|
||||
|
|
@ -3293,11 +3367,22 @@ void maplayersurfacenotify(struct wl_listener *listener, void *data) {
|
|||
if (config.layer_rules[ji].noanim > 0) {
|
||||
l->noanim = 1;
|
||||
}
|
||||
if (config.layer_rules[ji].noshadow > 0) {
|
||||
l->noshadow = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (layer_surface->current.exclusive_zone == 0 &&
|
||||
layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM &&
|
||||
layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND) {
|
||||
l->shadow = wlr_scene_shadow_create(l->scene, 0, 0, border_radius,
|
||||
shadows_blur, shadowscolor);
|
||||
wlr_scene_node_lower_to_bottom(&l->shadow->node);
|
||||
wlr_scene_node_set_enabled(&l->shadow->node, true);
|
||||
}
|
||||
|
||||
if (animations && layer_animations && !l->noanim) {
|
||||
l->need_output_flush = true;
|
||||
l->animation.action = OPEN;
|
||||
l->geom.x = box.x;
|
||||
l->geom.y = box.y;
|
||||
|
|
@ -3348,7 +3433,10 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
|||
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND &&
|
||||
!wlr_box_equal(&box, &l->geom)) {
|
||||
|
||||
l->geom = box;
|
||||
l->geom.x = box.x;
|
||||
l->geom.y = box.y;
|
||||
l->geom.width = box.width;
|
||||
l->geom.height = box.height;
|
||||
l->animation.action = MOVE;
|
||||
l->need_output_flush = true;
|
||||
layer_set_pending_state(l);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue