Files
zdwm/src/bar/binding.c
Zedhugh Chen dee4073996 feat(bar): 新增绑定模式指示器显示当前 binding mode
- 新增 bar/binding: 监听 binding mode 变更,显示当前模式名
- 支持点击单元循环切换绑定模式(binding_mode_cycle)
- 默认模式下按 show_default 配置决定是否隐藏单元
- 补充 binding 相关默认配置(颜色、内边距、是否显示默认模式)
2026-06-16 02:09:38 +08:00

105 lines
2.4 KiB
C

#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);
}