diff --git a/protocols/dwl-ipc-unstable-v2.xml b/protocols/dwl-ipc-unstable-v2.xml index efbb64a..fb2f2c9 100644 --- a/protocols/dwl-ipc-unstable-v2.xml +++ b/protocols/dwl-ipc-unstable-v2.xml @@ -220,6 +220,13 @@ I would probably just submit raphi's patchset but I don't think that would be po + + + last map layer. + + + + diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 5eab1cd..1cfa2c8 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -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++) { diff --git a/src/ext-protocol/dwl-ipc.h b/src/ext-protocol/dwl-ipc.h index d05c72c..67f96f1 100644 --- a/src/ext-protocol/dwl-ipc.h +++ b/src/ext-protocol/dwl-ipc.h @@ -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); } diff --git a/src/maomao.c b/src/maomao.c index 775c59c..713ea49 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -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);