feat(bar): 新增绑定模式指示器显示当前 binding mode
- 新增 bar/binding: 监听 binding mode 变更,显示当前模式名 - 支持点击单元循环切换绑定模式(binding_mode_cycle) - 默认模式下按 show_default 配置决定是否隐藏单元 - 补充 binding 相关默认配置(颜色、内边距、是否显示默认模式)
This commit is contained in:
104
src/bar/binding.c
Normal file
104
src/bar/binding.c
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user