From 8eeeff5f3bc2361a20872050426b6aee43df18e2 Mon Sep 17 00:00:00 2001 From: Zedhugh Chen Date: Sat, 20 Dec 2025 22:47:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BB=8E=20Xresources=20?= =?UTF-8?q?=E4=B8=AD=E8=AF=BB=E5=8F=96=E9=85=8D=E7=BD=AE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 ++ src/types.h | 1 + src/wm.c | 37 +++++++++++++++++++++++++++++------ src/wm.h | 6 ++++++ src/xres.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/xres.h | 8 ++++++++ 6 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 src/xres.c create mode 100644 src/xres.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ee0ef9..799348f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ add_executable(${APP_NAME} ${SOURCE_DIR}/xkb.c ${SOURCE_DIR}/atoms.c ${SOURCE_DIR}/layout.c + ${SOURCE_DIR}/xres.c ) find_package(PkgConfig REQUIRED) @@ -57,6 +58,7 @@ pkg_check_modules(deps REQUIRED xcb-xfixes xcb-xinerama xcb-xkb + xcb-xrm xkbcommon-x11 cairo diff --git a/src/types.h b/src/types.h index a83a3ac..e45e8cf 100644 --- a/src/types.h +++ b/src/types.h @@ -91,5 +91,6 @@ typedef struct color_set_t { } color_set_t; typedef struct padding_t { + uint16_t bar_y; uint16_t tag_x; } padding_t; diff --git a/src/wm.c b/src/wm.c index 0642327..07b9928 100644 --- a/src/wm.c +++ b/src/wm.c @@ -31,6 +31,7 @@ #include "utils.h" #include "xcursor.h" #include "xkb.h" +#include "xres.h" #include "xwindow.h" static void wm_setup_signal(void); @@ -40,6 +41,7 @@ static void wm_detect_monitor(void); static void wm_scan_clients(void); static void wm_clean(void); static void wm_setup(void); +static void wm_get_xres_config(void); static void wm_init_color_set(void); static void wm_setup_keybindings(void); @@ -277,17 +279,18 @@ void wm_clean(void) { } static void wm_setup(void) { - wm.border_width = border_width; - wm.padding.tag_x = tag_x_padding; wm.layout_list = layout_list; wm.layout_count = (uint16_t)countof(layout_list); + wm_get_xres_config(); wm_init_color_set(); - int font_height = text_init_pango_layout(font_family, font_size, default_dpi); - wm.bar_height = (uint16_t)font_height + 2 * bar_y_padding; - - logger("font height: %d, bar height: %u\n", font_height, wm.bar_height); + { + int font_height = + text_init_pango_layout(wm.font_family, wm.font_size, wm.dpi); + wm.bar_height = (uint16_t)font_height + 2 * wm.padding.bar_y; + logger("font height: %d, bar height: %u\n", font_height, wm.bar_height); + } uint32_t tag_count = 0; for (monitor_t *m = wm.monitor_list; m; m = m->next) { @@ -331,6 +334,28 @@ static void wm_setup(void) { xcb_flush(wm.xcb_conn); } +static void wm_get_xres_config(void) { + xres_init_xrm_db(); + + wm.dpi = default_dpi; + wm.font_size = font_size; + xres_get_uint32("Xft.dpi", (uint32_t *)&wm.dpi); + xres_get_uint32(APP_NAME ".font_size", (uint32_t *)&wm.font_size); + xres_get_string(APP_NAME ".font_family", &wm.font_family, font_family); + + wm.border_width = border_width; + xres_get_uint32(APP_NAME ".border_width", (uint32_t *)&wm.border_width); + + wm.padding.bar_y = bar_y_padding; + wm.padding.tag_x = tag_x_padding; +#define NAME APP_NAME ".padding." + xres_get_uint32(NAME "bar_y", (uint32_t *)&wm.padding.bar_y); + xres_get_uint32(NAME "tag_x", (uint32_t *)&wm.padding.tag_x); +#undef NAME + + xres_clean(); +} + void wm_init_color_set(void) { color_parse(bar_bg, &wm.color_set.bar_bg); color_parse(tag_bg, &wm.color_set.tag_bg); diff --git a/src/wm.h b/src/wm.h index 5c0b18c..b643a69 100644 --- a/src/wm.h +++ b/src/wm.h @@ -2,6 +2,7 @@ #include #include +#include #include #include "types.h" @@ -22,8 +23,13 @@ typedef struct wm_t { monitor_t *current_monitor; const layout_t *layout_list; + char *font_family; + uint32_t font_size; + uint32_t dpi; + xcb_connection_t *xcb_conn; xcb_screen_t *screen; + xcb_xrm_database_t *xrm; xcb_key_symbols_t *key_symbols; xcb_window_t wm_check_window; int default_screen; diff --git a/src/xres.c b/src/xres.c new file mode 100644 index 0000000..d43f360 --- /dev/null +++ b/src/xres.c @@ -0,0 +1,52 @@ +#include "xres.h" + +#include +#include +#include +#include + +#include "wm.h" + +void xres_init_xrm_db(void) { + if (wm.xrm) return; + wm.xrm = xcb_xrm_database_from_default(wm.xcb_conn); +} + +void xres_clean(void) { + if (!wm.xrm) return; + + xcb_xrm_database_free(wm.xrm); + wm.xrm = nullptr; +} + +/** + * @brief 获取 Xresources 文件中配置的 long 类型配置并将其转化为 uint32_t 类型 + * @param name Xresources 文件中的配置名 + * @param value 获取到的结果存放的指针 + * @returns 配置获取是否成功,成功返回 true 失败返回 false + */ +bool xres_get_uint32(const char *name, uint32_t *value) { + if (!wm.xrm) return false; + + long temp_value = 0; + bool success = + xcb_xrm_resource_get_long(wm.xrm, name, nullptr, &temp_value) == 0; + if (success) *value = (uint32_t)temp_value; + + return success; +} + +/** + * @brief 读取 Xresources 文件中的字符串配置 + * @param name Xresources 文件中的配置名 + * @param value 存放读取到的字符串存储的指针的指针,使用完后记得使用 + * free(*value) 释放字符串对应的内存 + * @param fallback 若 Xresources 解析失败,则使用这个默认值 + */ +void xres_get_string(const char *name, char **value, const char *fallback) { + if (!wm.xrm) return; + + if (!xcb_xrm_resource_get_string(wm.xrm, name, nullptr, value)) return; + + *value = strdup(fallback); +} diff --git a/src/xres.h b/src/xres.h new file mode 100644 index 0000000..59ed263 --- /dev/null +++ b/src/xres.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +void xres_init_xrm_db(void); +void xres_clean(void); +bool xres_get_uint32(const char *name, uint32_t *value); +void xres_get_string(const char *name, char **value, const char *fallback);