feat(bar): 新增绑定模式指示器显示当前 binding mode

- 新增 bar/binding: 监听 binding mode 变更,显示当前模式名
- 支持点击单元循环切换绑定模式(binding_mode_cycle)
- 默认模式下按 show_default 配置决定是否隐藏单元
- 补充 binding 相关默认配置(颜色、内边距、是否显示默认模式)
This commit is contained in:
2026-06-16 02:09:38 +08:00
parent e8b59e914c
commit dee4073996
6 changed files with 155 additions and 0 deletions

View File

@@ -30,6 +30,7 @@ add_executable(${APP_NAME}
${SOURCE_DIR}/backend/x11/window.c
${SOURCE_DIR}/bar/bar.c
${SOURCE_DIR}/bar/binding.c
${SOURCE_DIR}/bar/cell.c
${SOURCE_DIR}/bar/text.c
${SOURCE_DIR}/bar/workspaces.c

View File

@@ -33,8 +33,12 @@ typedef struct zdwm_bar_config_t {
const char *layout_bg;
const char *layout_fg;
bool binding_show_default;
uint32_t binding_padding_x;
const char *binding_mode_bg;
const char *binding_mode_fg;
const char *window_bg;
const char *window_fg;
const char *window_focused_bg;

View File

@@ -8,6 +8,7 @@
#include <zdwm/bar.h>
#include <zdwm/types.h>
#include "bar/binding.h"
#include "bar/cell.h"
#include "bar/text.h"
#include "bar/types.h"
@@ -78,6 +79,28 @@ void bar_output_add_workspace(
bar_workspace_add_listeners(listeners, item->state);
}
static void bar_output_add_binding(
bar_output_t *bar_output,
zdwm_bar_config_t *config,
listeners_t *listeners
) {
bar_binding_config_t binding_config = {
.show_default = config->binding_show_default,
.cell_padding = VALUE(config->binding_padding_x, config->padding_x),
.bg = VALUE(config->binding_mode_bg, config->bg),
.fg = VALUE(config->binding_mode_fg, config->fg),
};
auto item = bar_add_item(
bar_output->output_id,
&bar_output->left,
bar_binding,
&binding_config
);
item->cell_padding = binding_config.cell_padding;
bar_binding_add_listeners(listeners, item->state);
}
void bar_init(bar_t *bar, listeners_t *listeners) {
auto c = &bar->config;
bar->ctx = text_context_create(c->font_family, c->font_size, c->dpi);
@@ -87,6 +110,7 @@ void bar_init(bar_t *bar, listeners_t *listeners) {
bar_output->height = bar->config.height;
bar_output_add_workspace(bar_output, &bar->config, listeners);
bar_output_add_binding(bar_output, &bar->config, listeners);
}
bar->timerfd = time_create_monotonic_timerfd_by_fps(bar->config.fps);

104
src/bar/binding.c Normal file
View File

@@ -0,0 +1,104 @@
#include "bar/binding.h"
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <zdwm/action.h>
#include <zdwm/bar.h>
#include <zdwm/listeners.h>
#include <zdwm/types.h>
#include "base/memory.h"
#include "core/listeners.h"
typedef struct bar_binding_state_t {
zdwm_binding_mode_notify_t mode;
bar_binding_config_t config;
bool inited;
bool dirty;
} bar_binding_state_t;
static void *
bar_binding_create_state(zdwm_output_id_t output_id, void *config) {
const bar_binding_config_t *bar_config = config;
assert(bar_config);
auto state = p_new(bar_binding_state_t, 1);
state->config = *bar_config;
return state;
}
static void bar_binding_update(
zdwm_bar_item_t *item,
const zdwm_bar_cell_api_t *cells,
void *state
) {
auto data = (bar_binding_state_t *)state;
if (!data->inited || !data->dirty) return;
auto config = &data->config;
auto mode = &data->mode;
if (!config->show_default && mode->is_default_mode) {
cells->set_cell_count(item, 0);
} else {
constexpr auto index = 0;
cells->set_cell_count(item, 1);
cells->cell_set_text(item, index, mode->name);
cells->cell_set_bg(item, index, config->bg);
cells->cell_set_fg(item, index, config->fg);
}
data->dirty = false;
}
static zdwm_action_t bar_binding_on_click(
zdwm_bar_item_t *item,
size_t cell_index,
int32_t x,
void *state
) {
return (zdwm_action_t){
.type = ZDWM_ACTION_BINDING_MODE_CYCLE,
.as.binding_mode_cycle = {.delta = 1},
};
}
static void bar_binding_destroy_state(void *state) {
if (!state) return;
auto data = (bar_binding_state_t *)state;
p_delete(&data);
}
zdwm_bar_item_type_t bar_binding = {
.create_state = bar_binding_create_state,
.update = bar_binding_update,
.on_click = bar_binding_on_click,
.destroy_state = bar_binding_destroy_state,
.update_interval_ms = 0,
};
static void
bar_binding_mode_notify(zdwm_binding_mode_notify_t mode, void *user_data) {
auto state = (bar_binding_state_t *)user_data;
if (!state->inited) {
state->mode = mode;
state->inited = true;
state->dirty = true;
return;
}
if (state->mode.id == mode.id) return;
state->mode = mode;
state->dirty = true;
}
void bar_binding_add_listeners(listeners_t *listeners, void *state) {
listeners_add_binding_mode_notify(listeners, bar_binding_mode_notify, state);
}

17
src/bar/binding.h Normal file
View File

@@ -0,0 +1,17 @@
#pragma once
#include <stdint.h>
#include <zdwm/bar.h>
#include "core/listeners.h"
typedef struct bar_binding_config_t {
bool show_default;
uint32_t cell_padding;
const char *bg;
const char *fg;
} bar_binding_config_t;
extern zdwm_bar_item_type_t bar_binding;
void bar_binding_add_listeners(listeners_t *listeners, void *state);

View File

@@ -189,6 +189,11 @@ bool config_defaults_build(
.tag_urgent_fg = "#ff0000",
.layout_bg = "#222222",
.layout_fg = "#bbbbbb",
.binding_show_default = true,
.binding_padding_x = 2,
.binding_mode_bg = "#900000",
.binding_mode_fg = "#ffffff",
};
api->set_bar_config(builder, bar_config);