feat(config): 添加配置窗口边框 API

This commit is contained in:
2026-05-01 19:07:21 +08:00
parent 3a830e864a
commit 1cfa2c4505
10 changed files with 179 additions and 15 deletions

107
src/base/color.c Normal file
View File

@@ -0,0 +1,107 @@
#include "color.h"
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "base/log.h"
/**
* @brief 将 16 进制的颜色配置转换成 uint32 格式的 rgba数据
*
* @param hex 16 进制的颜色表示,支持的格式有
* RGB/RGBA/RRGGBB/RRGGBBAA/#RGB/#RGBA/#RRGGBB/#RRGGBBAA
* @param rgba 返回数据的指针,解析结果会放到这个指针指向的内存中
* @return 如果 hex 是一个能正常解析的颜色,返回 true ,否则返回 false
*/
static bool hex_color_to_rgba(const char *hex, uint32_t *rgba);
/**
* @brief 将 rgba 通道顺序的颜色转换成 argb 顺序
* @description xcb 库用到的颜色需要是 argb 通道顺序
*/
static uint32_t rgba_to_argb(uint32_t rgba);
/**
* @brief 提取颜色中的各个颜色通道数值
* @param rgba uint32 表示的颜色
* @param red red channel, range 0~1
* @param green green channel, range 0~1
* @param blue blue channel, range 0~1
* @param alpha alpha channel, range 0~1
*/
static void extract_color_channel(
const uint32_t rgba,
double *red,
double *green,
double *blue,
double *alpha
);
void color_parse(const char *hex, color_t *const color) {
bool success = hex_color_to_rgba(hex, &color->rgba);
if (!success) fatal("invalid hex color: %s", hex);
color->argb = rgba_to_argb(color->rgba);
extract_color_channel(
color->rgba,
&color->red,
&color->green,
&color->blue,
&color->alpha
);
}
bool hex_color_to_rgba(const char *hex, uint32_t *rgba) {
if (hex[0] == '#') hex++;
size_t len = strlen(hex);
char extended[9] = {0};
uint32_t color = 0x00000000;
if (len == 3 || len == 4) {
extended[0] = extended[1] = hex[0];
extended[2] = extended[3] = hex[1];
extended[4] = extended[5] = hex[2];
if (len == 3) {
extended[6] = extended[7] = 'F';
} else {
extended[6] = extended[7] = hex[3];
}
} else if (len == 6) {
strncpy(extended, hex, len);
extended[6] = extended[7] = 'F';
} else if (len == 8) {
strncpy(extended, hex, len);
} else {
return false;
}
color = strtoul(extended, nullptr, 16) & 0xffffffff;
*rgba = color;
return true;
}
#define EXTRACE_COLOR_BIT(C, R) (((C) >> (R)) & 0xff)
uint32_t rgba_to_argb(uint32_t rgba) {
uint32_t r = EXTRACE_COLOR_BIT(rgba, 24);
uint32_t g = EXTRACE_COLOR_BIT(rgba, 16);
uint32_t b = EXTRACE_COLOR_BIT(rgba, 8);
uint32_t a = EXTRACE_COLOR_BIT(rgba, 0);
uint32_t argb = (a << 24) | (r << 16) | (g << 8) | b;
return argb;
}
#define COLOR_SPLIT(C, R) (EXTRACE_COLOR_BIT((C), (R)) / (double)0xff)
void extract_color_channel(
const uint32_t rgba,
double *red,
double *green,
double *blue,
double *alpha
) {
*red = COLOR_SPLIT(rgba, 24);
*green = COLOR_SPLIT(rgba, 16);
*blue = COLOR_SPLIT(rgba, 8);
*alpha = COLOR_SPLIT(rgba, 0);
}

20
src/base/color.h Normal file
View File

@@ -0,0 +1,20 @@
#pragma once
#include <stdint.h>
typedef struct color_t {
uint32_t rgba;
uint32_t argb;
/* RGBA color channels for Cairo, each channel in the range [0, 1] */
double red, green, blue, alpha;
} color_t;
/**
* @brief 解析 16 进制表示的颜色
*
* @param hex 颜色的 16 进制表示,支持的格式有
* RGB/RGBA/RRGGBB/RRGGBBAA/#RGB/#RGBA/#RRGGBB/#RRGGBBAA
* @param color 存储颜色值的结构体指针,不能为 nullptr
*/
void color_parse(const char *hex, color_t *const color);

View File

@@ -5,6 +5,7 @@
#include <zdwm/config.h>
#include "base/array.h"
#include "base/color.h"
#include "base/memory.h"
#include "config/defaults.h"
#include "config/loader.h"
@@ -25,6 +26,7 @@ struct zdwm_config_builder_t {
size_t workspace_count;
size_t workspace_capacity;
size_t output_count;
border_config_t border;
binding_table_t *binding_table;
};
@@ -183,6 +185,17 @@ static bool runtime_config_set_initial_mode(
return binding_table_set_current_mode(builder->binding_table, mode_id);
}
static void runtime_config_set_border_config(
zdwm_config_builder_t *builder,
uint32_t width,
const char *normal,
const char *focused
) {
builder->border.width = width;
color_parse(normal, &builder->border.normal_color);
color_parse(focused, &builder->border.focused_color);
}
static bool config_builder_finish(
zdwm_config_builder_t *builder,
runtime_init_desc_t *out
@@ -193,6 +206,7 @@ static bool config_builder_finish(
if (!layout_registry_move(&builder->layouts, &out->layouts)) return false;
if (!rules_move(&builder->rules, &out->rules)) return false;
out->border = builder->border;
out->binding_table = builder->binding_table;
out->workspaces = builder->workspaces;
out->workspace_count = builder->workspace_count;
@@ -223,13 +237,14 @@ static bool runtime_config_build(
.fullscreen = fullscreen,
.maximize = maximize,
},
.register_layout = runtime_config_register_layout,
.define_workspace = runtime_config_define_workspace,
.add_rule = runtime_config_add_rule,
.add_mode = runtime_config_add_mode,
.bind = runtime_config_bind,
.set_default_mode = runtime_config_set_default_mode,
.set_initial_mode = runtime_config_set_initial_mode,
.register_layout = runtime_config_register_layout,
.define_workspace = runtime_config_define_workspace,
.add_rule = runtime_config_add_rule,
.add_mode = runtime_config_add_mode,
.bind = runtime_config_bind,
.set_default_mode = runtime_config_set_default_mode,
.set_initial_mode = runtime_config_set_initial_mode,
.set_border_config = runtime_config_set_border_config,
};
bool ok = setup(&api, &builder, outputs, output_count) &&
config_builder_finish(&builder, out);

View File

@@ -3,6 +3,7 @@
#include <stddef.h>
#include <stdint.h>
#include "base/color.h"
#include "core/types.h"
typedef enum effect_type_t {

View File

@@ -59,6 +59,7 @@ bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc) {
runtime->backend = desc->backend;
layout_registry_move(&desc->layouts, &runtime->layouts);
rules_move(&desc->rules, &runtime->rules);
runtime->border = desc->border;
runtime->config_module_handle = desc->config_module_handle;
runtime->binding_table = desc->binding_table;
desc->backend = nullptr;

View File

@@ -1,7 +1,9 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#include "base/color.h"
#include "core/backend.h"
#include "core/binding.h"
#include "core/command_buffer.h"
@@ -9,6 +11,13 @@
#include "core/plan.h"
#include "core/rules.h"
#include "core/state.h"
#include "core/types.h"
typedef struct border_config_t {
uint32_t width;
color_t normal_color;
color_t focused_color;
} border_config_t;
typedef struct runtime_init_desc_t {
backend_t *backend;
@@ -17,6 +26,7 @@ typedef struct runtime_init_desc_t {
layout_registry_t layouts;
rules_t rules;
border_config_t border;
workspace_desc_t *workspaces;
size_t workspace_count;
void *config_module_handle;
@@ -33,6 +43,7 @@ typedef struct runtime_t {
layout_result_t layout_result;
layout_registry_t layouts;
rules_t rules;
border_config_t border;
backend_t *backend;
void *config_module_handle;
binding_table_t *binding_table;

View File

@@ -27,14 +27,6 @@ typedef struct point_t {
int32_t y;
} point_t;
typedef struct color_t {
uint32_t rgba;
uint32_t argb;
/* RGBA color channels for Cairo, each channel in the range [0, 1] */
double red, green, blue, alpha;
} color_t;
typedef enum window_geometry_mode_t {
ZDWM_GEOMETRY_NORMAL,
ZDWM_GEOMETRY_MAXIMIZED,