diff --git a/src/animation/layer.h b/src/animation/layer.h index 476cba63..59d8833e 100644 --- a/src/animation/layer.h +++ b/src/animation/layer.h @@ -1,13 +1,11 @@ void layer_actual_size(LayerSurface *l, int32_t *width, int32_t *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; + *width = l->geom.width; + *height = l->geom.height; } } @@ -151,6 +149,34 @@ void set_layer_dir_animaiton(LayerSurface *l, struct wlr_box *geo) { } } +void layer_draw_shield(LayerSurface *l) { + int32_t width, height; + + if (!l->mapped) + return; + + if (active_capture_count > 0 && l->shield_when_capture) { + + layer_actual_size(l, &width, &height); + + if (width <= 0 || height <= 0) { + wlr_scene_node_set_enabled(&l->shield->node, false); + return; + } + + wlr_scene_node_raise_to_top(&l->shield->node); + wlr_scene_node_set_position(&l->shield->node, 0, 0); + wlr_scene_rect_set_size(l->shield, width, height); + wlr_scene_node_set_enabled(&l->shield->node, true); + } else { + if (l->shield->node.enabled) { + wlr_scene_node_lower_to_bottom(&l->shield->node); + wlr_scene_node_set_position(&l->shield->node, 0, 0); + wlr_scene_node_set_enabled(&l->shield->node, false); + } + } +} + void layer_scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int32_t sx, int32_t sy, void *data) { BufferData *buffer_data = (BufferData *)data; @@ -522,6 +548,7 @@ bool layer_draw_frame(LayerSurface *l) { !l->noanim) { layer_animation_next_tick(l); } else { + layer_draw_shield(l); l->need_output_flush = false; } return true; diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 07035118..e2b3793c 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -185,6 +185,7 @@ typedef struct { char *layer_name; // 布局名称 char *animation_type_open; char *animation_type_close; + int32_t shield_when_capture; int32_t noanim; } ConfigLayerRule; @@ -2241,6 +2242,7 @@ bool parse_option(Config *config, char *key, char *value) { rule->layer_name = NULL; rule->animation_type_open = NULL; rule->animation_type_close = NULL; + rule->shield_when_capture = 0; rule->noanim = 0; bool parse_error = false; @@ -2261,6 +2263,8 @@ bool parse_option(Config *config, char *key, char *value) { rule->animation_type_open = strdup(val); } else if (strcmp(key, "animation_type_close") == 0) { rule->animation_type_close = strdup(val); + } else if (strcmp(key, "shield_when_capture") == 0) { + rule->shield_when_capture = CLAMP_INT(atoi(val), 0, 1); } else if (strcmp(key, "noanim") == 0) { rule->noanim = CLAMP_INT(atoi(val), 0, 1); } diff --git a/src/fetch/common.h b/src/fetch/common.h index d017dff3..285120d5 100644 --- a/src/fetch/common.h +++ b/src/fetch/common.h @@ -160,9 +160,13 @@ void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc, } if (node->type == WLR_SCENE_NODE_RECT) { - if (c) { + if (c && (c->type == XDGShell || c->type == X11)) { surface = client_surface(c); } + + if (l && l->type == LayerShell) { + surface = l->layer_surface->surface; + } } break; diff --git a/src/mango.c b/src/mango.c index b9b9ee9b..7202ba75 100644 --- a/src/mango.c +++ b/src/mango.c @@ -515,6 +515,7 @@ typedef struct { Monitor *mon; struct wlr_scene_tree *scene; struct wlr_scene_tree *popups; + struct wlr_scene_rect *shield; struct wlr_scene_layer_surface_v1 *scene_layer; struct wl_list link; struct wl_list fadeout_link; @@ -531,6 +532,7 @@ typedef struct { int32_t noanim; char *animation_type_open; char *animation_type_close; + bool shield_when_capture; bool need_output_flush; bool being_unmapped; } LayerSurface; @@ -2763,6 +2765,7 @@ void maplayersurfacenotify(struct wl_listener *listener, void *data) { l->noanim = 0; l->dirty = false; + l->shield_when_capture = false; l->need_output_flush = true; // 应用layer规则 @@ -2773,17 +2776,28 @@ void maplayersurfacenotify(struct wl_listener *listener, void *data) { l->layer_surface->namespace)) { r = &config.layer_rules[ji]; + APPLY_INT_PROP(l, r, shield_when_capture); APPLY_INT_PROP(l, r, noanim); APPLY_STRING_PROP(l, r, animation_type_open); APPLY_STRING_PROP(l, r, animation_type_close); } } + // 初始化屏蔽 + l->shield = + wlr_scene_rect_create(l->scene, 0, 0, (float[4]){0, 0, 0, 0xff}); + l->shield->node.data = l; + wlr_scene_node_lower_to_bottom(&l->shield->node); + wlr_scene_node_set_enabled(&l->shield->node, false); + // 初始化动画 if (config.animations && config.layer_animations && !l->noanim) { l->animation.duration = config.animation_duration_open; l->animation.action = OPEN; layer_set_pending_state(l); + } else { + l->animainit_geom = l->animation.current = l->current = l->pending = + l->geom; } // 刷新布局,让窗口能感应到exclude_zone变化以及设置独占表面 arrangelayers(l->mon); @@ -2827,20 +2841,26 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) { get_layer_target_geometry(l, &box); - if (config.animations && config.layer_animations && !l->noanim && - l->mapped && - layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM && - layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND && - !wlr_box_equal(&box, &l->geom)) { - + if (!wlr_box_equal(&box, &l->geom)) { 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->animation.duration = config.animation_duration_move; - l->need_output_flush = true; - layer_set_pending_state(l); + + if (config.animations && config.layer_animations && !l->noanim && + l->mapped && + layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM && + layer_surface->current.layer != + ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND) { + l->animation.action = MOVE; + l->animation.duration = config.animation_duration_move; + l->need_output_flush = true; + layer_set_pending_state(l); + } else { + l->animainit_geom = l->animation.current = l->current = l->pending = + l->geom; + l->need_output_flush = true; + } } if (layer_surface->current.committed == 0 &&