feat: add layerrule to match noblur layer

This commit is contained in:
DreamMaoMao 2025-06-26 20:36:25 +08:00
parent fbf9c8e487
commit 063d5b27f5
4 changed files with 110 additions and 8 deletions

View file

@ -220,6 +220,13 @@ I would probably just submit raphi's patchset but I don't think that would be po
<arg name="height" type="int" summary="height of the selected client"/>
</event>
<event name="last_layer" since="2">
<description summary="last map layer.">
last map layer.
</description>
<arg name="last_layer" type="string" summary="last map layer."/>
</event>
</interface>
</protocol>

View file

@ -122,6 +122,11 @@ typedef struct {
int no_render_border;
} ConfigTagRule;
typedef struct {
char *layer_name; // 布局名称
int noblur;
} ConfigLayerRule;
typedef struct {
int animations;
char animation_type_open[10];
@ -229,6 +234,9 @@ typedef struct {
ConfigTagRule *tag_rules; // 动态数组
int tag_rules_count; // 数量
ConfigLayerRule *layer_rules; // 动态数组
int layer_rules_count; // 数量
ConfigWinRule *window_rules;
int window_rules_count;
@ -1270,6 +1278,49 @@ void parse_config_line(Config *config, const char *line) {
}
config->tag_rules_count++;
} else if (strcmp(key, "layerrule") == 0) {
config->layer_rules =
realloc(config->layer_rules,
(config->layer_rules_count + 1) * sizeof(ConfigLayerRule));
if (!config->layer_rules) {
fprintf(stderr,
"Error: Failed to allocate memory for layer rules\n");
return;
}
ConfigLayerRule *rule = &config->layer_rules[config->layer_rules_count];
memset(rule, 0, sizeof(ConfigLayerRule));
// 设置默认值
rule->layer_name = NULL;
rule->noblur = 0;
char *token = strtok(value, ",");
while (token != NULL) {
char *colon = strchr(token, ':');
if (colon != NULL) {
*colon = '\0';
char *key = token;
char *val = colon + 1;
trim_whitespace(key);
trim_whitespace(val);
if (strcmp(key, "layer_name") == 0) {
rule->layer_name = strdup(val);
} else if (strcmp(key, "noblur") == 0) {
rule->noblur = CLAMP_INT(atoi(val), 0, 1);
}
}
token = strtok(NULL, ",");
}
// 如果没有指定布局名称,则使用默认值
if (rule->layer_name == NULL) {
rule->layer_name = strdup("default");
}
config->layer_rules_count++;
} else if (strcmp(key, "windowrule") == 0) {
config->window_rules =
realloc(config->window_rules,
@ -1950,6 +2001,16 @@ void free_config(void) {
config.tag_rules_count = 0;
}
// 释放 layer_rules
if (config.layer_rules) {
for (int i = 0; i < config.layer_rules_count; i++) {
free((void *)config.layer_rules[i].layer_name);
}
free(config.layer_rules);
config.layer_rules = NULL;
config.layer_rules_count = 0;
}
// 释放 exec
if (config.exec) {
for (i = 0; i < config.exec_count; i++) {

View file

@ -156,25 +156,30 @@ void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) {
focused ? focused->isfloating : 0);
}
if (wl_resource_get_version(ipc_output->resource) >=
ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) {
ZDWL_IPC_OUTPUT_V2_X_SINCE_VERSION) {
zdwl_ipc_output_v2_send_x(ipc_output->resource,
focused ? focused->geom.x : 0);
}
if (wl_resource_get_version(ipc_output->resource) >=
ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) {
ZDWL_IPC_OUTPUT_V2_Y_SINCE_VERSION) {
zdwl_ipc_output_v2_send_y(ipc_output->resource,
focused ? focused->geom.y : 0);
}
if (wl_resource_get_version(ipc_output->resource) >=
ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) {
ZDWL_IPC_OUTPUT_V2_WIDTH_SINCE_VERSION) {
zdwl_ipc_output_v2_send_width(ipc_output->resource,
focused ? focused->geom.width : 0);
}
if (wl_resource_get_version(ipc_output->resource) >=
ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) {
ZDWL_IPC_OUTPUT_V2_HEIGHT_SINCE_VERSION) {
zdwl_ipc_output_v2_send_height(ipc_output->resource,
focused ? focused->geom.height : 0);
}
if (wl_resource_get_version(ipc_output->resource) >=
ZDWL_IPC_OUTPUT_V2_LAST_LAYER_SINCE_VERSION) {
zdwl_ipc_output_v2_send_last_layer(ipc_output->resource,
monitor->last_surface_ws_name);
}
zdwl_ipc_output_v2_send_frame(ipc_output->resource);
}

View file

@ -397,6 +397,7 @@ struct Monitor {
int asleep;
unsigned int visible_clients;
struct wlr_scene_optimized_blur *blur;
char last_surface_ws_name[256];
};
typedef struct {
@ -471,6 +472,7 @@ static void cleanupmon(struct wl_listener *listener, void *data); // 退出清
static void closemon(Monitor *m);
static void cleanuplisteners(void);
static void toggle_hotarea(int x_root, int y_root); // 触发热区
static void maplayersurfacenotify(struct wl_listener *listener, void *data);
static void commitlayersurfacenotify(struct wl_listener *listener, void *data);
static void commitnotify(struct wl_listener *listener, void *data);
static void createdecoration(struct wl_listener *listener, void *data);
@ -3045,6 +3047,16 @@ static void iter_layer_scene_buffers(struct wlr_scene_buffer *buffer, int sx,
}
}
void maplayersurfacenotify(struct wl_listener *listener, void *data) {
LayerSurface *l = wl_container_of(listener, l, map);
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] =
'\0'; // 确保字符串以null结尾
}
void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
LayerSurface *l = wl_container_of(listener, l, surface_commit);
struct wlr_layer_surface_v1 *layer_surface = l->layer_surface;
@ -3052,6 +3064,8 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
layers[layermap[layer_surface->current.layer]];
struct wlr_layer_surface_v1_state old_state;
struct wlr_layer_surface_v1 *wlr_layer_surface = l->layer_surface;
int ji;
bool exclude_blur = false;
if (l->layer_surface->initial_commit) {
client_set_scale(layer_surface->surface, l->mon->wlr_output->scale);
@ -3067,10 +3081,23 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
if (blur && blur_layer) {
// 设置非背景layer模糊
if (wlr_layer_surface->current.layer !=
for (ji = 0; ji < config.layer_rules_count; ji++) {
if (config.layer_rules_count < 1)
break;
if (strcmp(config.layer_rules[ji].layer_name,
l->layer_surface->namespace) == 0) {
exclude_blur = true;
break;
}
}
if (!exclude_blur &&
wlr_layer_surface->current.layer !=
ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM &&
wlr_layer_surface->current.layer !=
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND) {
wlr_log(WLR_ERROR, "st");
wlr_scene_node_for_each_buffer(&l->scene->node,
iter_layer_scene_buffers, l);
}
@ -3079,10 +3106,10 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
if (blur) {
// 如果背景层发生变化,标记优化的模糊背景缓存需要更新
if (wlr_layer_surface->current.layer ==
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND ||
wlr_layer_surface->current.layer ==
ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) {
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND) {
if (l->mon) {
wlr_log(WLR_ERROR, "dirty");
wlr_scene_optimized_blur_mark_dirty(l->mon->blur);
}
}
@ -3359,6 +3386,7 @@ void createlayersurface(struct wl_listener *listener, void *data) {
l = layer_surface->data = ecalloc(1, sizeof(*l));
l->type = LayerShell;
LISTEN(&surface->events.map, &l->map, maplayersurfacenotify);
LISTEN(&surface->events.commit, &l->surface_commit,
commitlayersurfacenotify);
LISTEN(&surface->events.unmap, &l->unmap, unmaplayersurfacenotify);
@ -3682,6 +3710,7 @@ void destroylayersurfacenotify(struct wl_listener *listener, void *data) {
wl_list_remove(&l->link);
wl_list_remove(&l->destroy.link);
wl_list_remove(&l->map.link);
wl_list_remove(&l->unmap.link);
wl_list_remove(&l->surface_commit.link);
wlr_scene_node_destroy(&l->scene->node);