Compare commits
2 Commits
a749fc3c6c
...
56f211480f
| Author | SHA1 | Date | |
|---|---|---|---|
|
56f211480f
|
|||
|
7a86eb469b
|
@@ -70,6 +70,7 @@ pkg_check_modules(deps REQUIRED
|
||||
xcb-xinerama
|
||||
xcb-xkb
|
||||
xcb-xrm
|
||||
xkbcommon
|
||||
xkbcommon-x11
|
||||
|
||||
cairo
|
||||
|
||||
30
include/zdwm/action.h
Normal file
30
include/zdwm/action.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef ZDWM_ACTION_H
|
||||
#define ZDWM_ACTION_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef union zdwm_action_arg_t {
|
||||
bool b;
|
||||
int32_t i;
|
||||
uint32_t ui;
|
||||
const char *str;
|
||||
} zdwm_action_arg_t;
|
||||
|
||||
typedef struct zdwm_action_ctx_t zdwm_action_ctx_t;
|
||||
|
||||
typedef void
|
||||
zdwm_action_fn(const zdwm_action_ctx_t *ctx, const zdwm_action_arg_t *arg);
|
||||
|
||||
struct zdwm_action_ctx_t {
|
||||
void (*spawn)(const char *command);
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZDWM_ACTION_H */
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <zdwm/action.h>
|
||||
#include <zdwm/layout.h>
|
||||
#include <zdwm/rules.h>
|
||||
#include <zdwm/types.h>
|
||||
@@ -76,6 +77,68 @@ typedef struct zdwm_api_t {
|
||||
const zdwm_rule_match_t *match,
|
||||
const zdwm_rule_action_t *action
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief 用户调用这个函数添加按键模式
|
||||
*
|
||||
* @details 按键模式名不能重复,如果添加重复的名字仅第一次成功,后续将添加失败
|
||||
*
|
||||
* @param builder 配置构建上下文
|
||||
* @param mode_name 按键模式名字,不能为 nullptr 或空字符串
|
||||
*
|
||||
* @return 添加成功返回新增模式的 id 否则返回 ZDWM_BINDING_MODE_ID_INVALID
|
||||
*/
|
||||
zdwm_binding_mode_id_t (*add_mode)(
|
||||
zdwm_config_builder_t *builder,
|
||||
const char *mode_name
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief 添加按键绑定
|
||||
*
|
||||
* @details mode_id 对应的模式不存在或 key_sequence 不合法,都会添加失败
|
||||
*
|
||||
* @param builder 配置构建上下文
|
||||
* @param bind_mode 模式 ID
|
||||
* @param key_sequence 按键序列的字符串表达
|
||||
* @param action_fn 用户行为函数
|
||||
* @param action_arg 用户行为函数所需的参数
|
||||
*
|
||||
* @return 添加成功返回 true 否则返回 false
|
||||
*/
|
||||
bool (*bind)(
|
||||
zdwm_config_builder_t *builder,
|
||||
zdwm_binding_mode_id_t bind_mode,
|
||||
const char *key_sequence,
|
||||
zdwm_action_fn action_fn,
|
||||
zdwm_action_arg_t *action_arg
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief 设置默认模式
|
||||
*
|
||||
* @param table 按键绑定表
|
||||
* @param mode_id 按键模式 ID
|
||||
*
|
||||
* @return 切换成功返回 true 否则返回 false
|
||||
*/
|
||||
bool (*set_default_mode)(
|
||||
zdwm_config_builder_t *builder,
|
||||
zdwm_binding_mode_id_t mode_id
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief 设置初始模式
|
||||
*
|
||||
* @param builder 配置构建上下文
|
||||
* @param mode_id 按键模式 ID
|
||||
*
|
||||
* @return 切换成功返回 true 否则返回 false
|
||||
*/
|
||||
bool (*set_initial_mode)(
|
||||
zdwm_config_builder_t *builder,
|
||||
zdwm_binding_mode_id_t mode_id
|
||||
);
|
||||
} zdwm_api_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,10 +10,12 @@ extern "C" {
|
||||
typedef uint32_t zdwm_layout_id_t;
|
||||
typedef uint32_t zdwm_window_id_t;
|
||||
typedef uint32_t zdwm_workspace_id_t;
|
||||
typedef uint32_t zdwm_binding_mode_id_t;
|
||||
|
||||
#define ZDWM_LAYOUT_ID_INVALID ((zdwm_layout_id_t)UINT32_MAX)
|
||||
#define ZDWM_WINDOW_ID_INVALID ((zdwm_window_id_t)0)
|
||||
#define ZDWM_WORKSPACE_ID_INVALID ((zdwm_workspace_id_t)UINT32_MAX)
|
||||
#define ZDWM_LAYOUT_ID_INVALID ((zdwm_layout_id_t)UINT32_MAX)
|
||||
#define ZDWM_WINDOW_ID_INVALID ((zdwm_window_id_t)0)
|
||||
#define ZDWM_WORKSPACE_ID_INVALID ((zdwm_workspace_id_t)UINT32_MAX)
|
||||
#define ZDWM_BINDING_MODE_ID_INVALID ((zdwm_binding_mode_id_t)UINT32_MAX)
|
||||
|
||||
typedef struct zdwm_rect_t {
|
||||
int32_t x;
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
#include "config/defaults.h"
|
||||
|
||||
#include <zdwm/action.h>
|
||||
#include <zdwm/types.h>
|
||||
|
||||
#include "base/macros.h"
|
||||
|
||||
static constexpr char launcher[] =
|
||||
"rofi -show combi -modes combi -combi-modes window,drun,run,ssh,windowcd";
|
||||
|
||||
static void spawn(const zdwm_action_ctx_t *ctx, const zdwm_action_arg_t *arg) {
|
||||
ctx->spawn(arg->str);
|
||||
}
|
||||
|
||||
bool config_defaults_build(
|
||||
const zdwm_api_t *api,
|
||||
zdwm_config_builder_t *builder,
|
||||
@@ -46,5 +56,20 @@ bool config_defaults_build(
|
||||
}
|
||||
}
|
||||
|
||||
auto default_mode = api->add_mode(builder, "default");
|
||||
|
||||
zdwm_action_arg_t launcher_arg = {.str = launcher};
|
||||
api->bind(builder, default_mode, "Mod4+r", spawn, &launcher_arg);
|
||||
|
||||
#define BIND(mode, key, fn, arg) \
|
||||
api->bind(builder, mode, key, fn, &(zdwm_action_arg_t)arg)
|
||||
|
||||
BIND(default_mode, "Mod4+r", spawn, {.str = launcher});
|
||||
|
||||
#undef BIND
|
||||
|
||||
api->set_default_mode(builder, default_mode);
|
||||
api->set_initial_mode(builder, default_mode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "base/memory.h"
|
||||
#include "config/defaults.h"
|
||||
#include "config/loader.h"
|
||||
#include "core/binding.h"
|
||||
#include "core/layout.h"
|
||||
#include "core/rules.h"
|
||||
#include "core/runtime.h"
|
||||
@@ -21,6 +22,7 @@ struct zdwm_config_builder_t {
|
||||
size_t workspace_count;
|
||||
size_t workspace_capacity;
|
||||
size_t output_count;
|
||||
binding_table_t *binding_table;
|
||||
};
|
||||
|
||||
void runtime_config_cleanup(runtime_init_desc_t *desc) {
|
||||
@@ -30,6 +32,8 @@ void runtime_config_cleanup(runtime_init_desc_t *desc) {
|
||||
desc->layouts.slot_capacity) {
|
||||
layout_registry_cleanup(&desc->layouts);
|
||||
}
|
||||
binding_table_destroy(desc->binding_table);
|
||||
desc->binding_table = nullptr;
|
||||
workspace_desc_list_cleanup(&desc->workspaces, &desc->workspace_count);
|
||||
if (desc->config_module_handle) dlclose(desc->config_module_handle);
|
||||
desc->config_module_handle = nullptr;
|
||||
@@ -45,6 +49,9 @@ static void config_builder_cleanup(zdwm_config_builder_t *builder) {
|
||||
workspace_desc_list_cleanup(&builder->workspaces, &builder->workspace_count);
|
||||
builder->workspace_capacity = 0;
|
||||
builder->output_count = 0;
|
||||
|
||||
binding_table_destroy(builder->binding_table);
|
||||
builder->binding_table = nullptr;
|
||||
}
|
||||
|
||||
static layout_id_t runtime_config_register_layout(
|
||||
@@ -144,6 +151,35 @@ static bool runtime_config_add_rule(
|
||||
return true;
|
||||
}
|
||||
|
||||
static zdwm_binding_mode_id_t
|
||||
runtime_config_add_mode(zdwm_config_builder_t *builder, const char *mode_name) {
|
||||
return binding_table_add_mode(builder->binding_table, mode_name);
|
||||
}
|
||||
|
||||
static bool runtime_config_bind(
|
||||
zdwm_config_builder_t *builder,
|
||||
zdwm_binding_mode_id_t mode,
|
||||
const char *key,
|
||||
zdwm_action_fn fn,
|
||||
zdwm_action_arg_t *arg
|
||||
) {
|
||||
return binding_table_add_bind(builder->binding_table, mode, key, fn, arg);
|
||||
}
|
||||
|
||||
static bool runtime_config_set_default_mode(
|
||||
zdwm_config_builder_t *builder,
|
||||
zdwm_binding_mode_id_t mode_id
|
||||
) {
|
||||
return binding_table_set_default_mode(builder->binding_table, mode_id);
|
||||
}
|
||||
|
||||
static bool runtime_config_set_initial_mode(
|
||||
zdwm_config_builder_t *builder,
|
||||
zdwm_binding_mode_id_t mode_id
|
||||
) {
|
||||
return binding_table_set_current_mode(builder->binding_table, mode_id);
|
||||
}
|
||||
|
||||
static bool config_builder_finish(
|
||||
zdwm_config_builder_t *builder,
|
||||
runtime_init_desc_t *out
|
||||
@@ -154,8 +190,10 @@ 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->binding_table = builder->binding_table;
|
||||
out->workspaces = builder->workspaces;
|
||||
out->workspace_count = builder->workspace_count;
|
||||
builder->binding_table = nullptr;
|
||||
builder->workspaces = nullptr;
|
||||
builder->workspace_count = 0;
|
||||
builder->workspace_capacity = 0;
|
||||
@@ -172,6 +210,7 @@ static bool runtime_config_build(
|
||||
if (!setup || !out) return false;
|
||||
zdwm_config_builder_t builder = {0};
|
||||
builder.output_count = output_count;
|
||||
builder.binding_table = binding_table_create();
|
||||
|
||||
zdwm_api_t api = {
|
||||
.abi_version = ZDWM_CONFIG_ABI_VERSION,
|
||||
@@ -183,6 +222,10 @@ static bool runtime_config_build(
|
||||
.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,
|
||||
};
|
||||
bool ok = setup(&api, &builder, outputs, output_count) &&
|
||||
config_builder_finish(&builder, out);
|
||||
|
||||
23
src/core/action.c
Normal file
23
src/core/action.c
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "core/action.h"
|
||||
|
||||
#include <paths.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "base/log.h"
|
||||
|
||||
void spawn(const char *command) {
|
||||
if (fork() == 0) {
|
||||
setsid();
|
||||
|
||||
if (fork() == 0) {
|
||||
execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command, nullptr);
|
||||
fatal("execl fail: %s", command);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
wait(0);
|
||||
}
|
||||
3
src/core/action.h
Normal file
3
src/core/action.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void spawn(const char *command);
|
||||
273
src/core/binding.c
Normal file
273
src/core/binding.c
Normal file
@@ -0,0 +1,273 @@
|
||||
#include "core/binding.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <xkbcommon/xkbcommon-keysyms.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <zdwm/action.h>
|
||||
#include <zdwm/types.h>
|
||||
|
||||
#include "base/array.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/memory.h"
|
||||
#include "core/event.h"
|
||||
|
||||
typedef struct key_binding_t {
|
||||
const char *key_str;
|
||||
modifier_mask_t modifiers;
|
||||
xkb_keysym_t keysym;
|
||||
zdwm_action_fn *fn;
|
||||
zdwm_action_arg_t *arg;
|
||||
} key_binding_t;
|
||||
|
||||
typedef struct binding_mode_t {
|
||||
zdwm_binding_mode_id_t id;
|
||||
const char *name;
|
||||
key_binding_t *items;
|
||||
size_t count;
|
||||
size_t capacity;
|
||||
} binding_mode_t;
|
||||
|
||||
typedef struct binding_table_t {
|
||||
binding_mode_t *modes;
|
||||
size_t count;
|
||||
size_t capacity;
|
||||
zdwm_binding_mode_id_t default_mode;
|
||||
zdwm_binding_mode_id_t current_mode;
|
||||
} binding_table_t;
|
||||
|
||||
zdwm_binding_mode_id_t
|
||||
binding_table_add_mode(binding_table_t *table, const char *mode_name) {
|
||||
if (!table || !mode_name || strlen(mode_name) == 0) {
|
||||
return ZDWM_BINDING_MODE_ID_INVALID;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < table->count; ++i) {
|
||||
if (strcmp(table->modes[i].name, mode_name) == 0) {
|
||||
return ZDWM_BINDING_MODE_ID_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
zdwm_binding_mode_id_t id = (zdwm_binding_mode_id_t)table->count;
|
||||
binding_mode_t *new_mode =
|
||||
array_push(table->modes, table->count, table->capacity);
|
||||
new_mode->name = mode_name;
|
||||
new_mode->id = id;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static binding_mode_t *
|
||||
binding_table_get_mode(binding_table_t *table, zdwm_binding_mode_id_t mode_id) {
|
||||
if (mode_id >= table->count) return nullptr;
|
||||
|
||||
binding_mode_t *mode = &table->modes[mode_id];
|
||||
if (mode->id == mode_id) return mode;
|
||||
|
||||
for (size_t i = 0; i < table->count; ++i) {
|
||||
mode = &table->modes[i];
|
||||
if (mode->id == mode_id) return mode;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
typedef struct mod_entry_t {
|
||||
const char *name;
|
||||
modifier_mask_t mask;
|
||||
} mod_entry_t;
|
||||
|
||||
static const mod_entry_t mod_table[] = {
|
||||
{"Shift", ZDWM_MOD_SHIFT},
|
||||
{"Control", ZDWM_MOD_CONTROL},
|
||||
{"Mod1", ZDWM_MOD_1},
|
||||
{"Mod2", ZDWM_MOD_2},
|
||||
{"Mod3", ZDWM_MOD_3},
|
||||
{"Mod4", ZDWM_MOD_4},
|
||||
{"Mod5", ZDWM_MOD_5},
|
||||
};
|
||||
|
||||
static modifier_mask_t lookup_modifier(const char *name, size_t len) {
|
||||
for (size_t i = 0; i < countof(mod_table); ++i) {
|
||||
if (strlen(mod_table[i].name) == len &&
|
||||
strncmp(name, mod_table[i].name, len) == 0) {
|
||||
return mod_table[i].mask;
|
||||
}
|
||||
}
|
||||
return ZDWM_MOD_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 解析按键序列
|
||||
*
|
||||
* @details 按键序列不合法解析失败,解析成功会设置 modifiers 与 keysym 对应的值
|
||||
*
|
||||
* @notice
|
||||
* 1. modifier 仅支持 Mod1 ~ Mod5, Control, Shift
|
||||
* 2. 必须保证一个且仅能有一个除 modifier 外的按键
|
||||
* 3. 按键序列通过 + 链接
|
||||
* 4. + 前后可以有多个空格
|
||||
* 5. 两个 + 之间必须有内容,如 "++", " + + "
|
||||
* 6. 不能以 + 开头和结尾
|
||||
* 7. 按键符号必须能被 xkbcommon 解析,否则按键序列也不合法
|
||||
*
|
||||
* @param key_sequence 按键序列
|
||||
* @param modifiers 返回修饰键的指针
|
||||
* @param keysym 返回按键符号的指针
|
||||
*
|
||||
* @return 解析成功返回 true 否则返回 false
|
||||
*/
|
||||
static bool parse_key_sequence(
|
||||
const char *key_sequence,
|
||||
modifier_mask_t *modifiers,
|
||||
xkb_keysym_t *keysym
|
||||
) {
|
||||
if (!key_sequence || !modifiers || !keysym) return false;
|
||||
|
||||
modifier_mask_t mods = ZDWM_MOD_NONE;
|
||||
xkb_keysym_t key = XKB_KEY_NoSymbol;
|
||||
|
||||
const char *p = key_sequence;
|
||||
const char *end = key_sequence + strlen(key_sequence);
|
||||
|
||||
while (p < end) {
|
||||
const char *plus = strchr(p, '+');
|
||||
const char *seg_end = plus ? plus : end;
|
||||
|
||||
const char *s = p;
|
||||
while (s < seg_end && isspace((unsigned char)*s)) ++s;
|
||||
|
||||
const char *e = seg_end;
|
||||
while (e > s && isspace((unsigned char)*(e - 1))) --e;
|
||||
|
||||
if (s == e) return false;
|
||||
|
||||
if (plus) {
|
||||
modifier_mask_t mod = lookup_modifier(s, (size_t)(e - s));
|
||||
if (mod == ZDWM_MOD_NONE) return false;
|
||||
mods |= mod;
|
||||
p = plus + 1;
|
||||
} else {
|
||||
char key_buf[64];
|
||||
size_t key_len = (size_t)(e - s);
|
||||
if (key_len >= sizeof(key_buf)) return false;
|
||||
memcpy(key_buf, s, key_len);
|
||||
key_buf[key_len] = '\0';
|
||||
|
||||
key = xkb_keysym_from_name(key_buf, XKB_KEYSYM_CASE_INSENSITIVE);
|
||||
if (key == XKB_KEY_NoSymbol) {
|
||||
return false;
|
||||
} else {
|
||||
*modifiers = mods;
|
||||
*keysym = key;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool binding_table_add_bind(
|
||||
binding_table_t *table,
|
||||
zdwm_binding_mode_id_t mode_id,
|
||||
const char *key_sequence,
|
||||
zdwm_action_fn fn,
|
||||
zdwm_action_arg_t *arg
|
||||
) {
|
||||
binding_mode_t *mode = binding_table_get_mode(table, mode_id);
|
||||
if (!mode) return false;
|
||||
|
||||
modifier_mask_t modifiers = 0;
|
||||
xkb_keysym_t keysym = XKB_KEY_NoSymbol;
|
||||
if (!parse_key_sequence(key_sequence, &modifiers, &keysym)) return false;
|
||||
|
||||
key_binding_t *item = array_push(mode->items, mode->count, mode->capacity);
|
||||
item->key_str = key_sequence;
|
||||
item->modifiers = modifiers;
|
||||
item->keysym = keysym;
|
||||
item->fn = fn;
|
||||
item->arg = arg;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void binding_table_destroy(binding_table_t *table) {
|
||||
if (!table) return;
|
||||
|
||||
for (size_t i = 0; i < table->count; ++i) {
|
||||
binding_mode_t *mode = &table->modes[i];
|
||||
p_delete(&mode->items);
|
||||
mode->count = 0;
|
||||
mode->capacity = 0;
|
||||
}
|
||||
|
||||
p_delete(&table->modes);
|
||||
table->count = 0;
|
||||
table->capacity = 0;
|
||||
table->default_mode = ZDWM_BINDING_MODE_ID_INVALID;
|
||||
|
||||
p_delete(&table);
|
||||
}
|
||||
|
||||
binding_table_t *binding_table_create(void) {
|
||||
binding_table_t *table = p_new(binding_table_t, 1);
|
||||
|
||||
/* 默认情况下,默认模式和当前模式都是第一个添加的模式 */
|
||||
table->default_mode = 0;
|
||||
table->current_mode = 0;
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
bool binding_table_set_default_mode(
|
||||
binding_table_t *table,
|
||||
zdwm_binding_mode_id_t mode_id
|
||||
) {
|
||||
if (mode_id >= table->count) return false;
|
||||
|
||||
table->default_mode = mode_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool binding_table_set_current_mode(
|
||||
binding_table_t *table,
|
||||
zdwm_binding_mode_id_t mode_id
|
||||
) {
|
||||
if (mode_id >= table->count) return false;
|
||||
|
||||
table->current_mode = mode_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool binding_table_cycle_mode(binding_table_t *table, int delta) {
|
||||
if (!table || !table->modes || table->count < 1) return false;
|
||||
|
||||
bool matched = false;
|
||||
size_t index = (size_t)table->current_mode;
|
||||
if (table->modes[index].id == table->current_mode) {
|
||||
matched = true;
|
||||
} else {
|
||||
for (size_t i = 0; i < table->count; ++i) {
|
||||
if (table->modes[i].id == table->current_mode) {
|
||||
index = i;
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!matched) return false;
|
||||
|
||||
/* 只有一个模式没必要切换 */
|
||||
if (table->count == 1) return true;
|
||||
|
||||
int64_t count = (int64_t)table->count;
|
||||
int64_t next_index = ((int64_t)index + (int64_t)delta) % count;
|
||||
if (next_index < 0) next_index += count;
|
||||
table->current_mode = table->modes[next_index].id;
|
||||
|
||||
return true;
|
||||
}
|
||||
86
src/core/binding.h
Normal file
86
src/core/binding.h
Normal file
@@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
#include <zdwm/action.h>
|
||||
#include <zdwm/types.h>
|
||||
|
||||
typedef struct binding_table_t binding_table_t;
|
||||
|
||||
/**
|
||||
* @brief 添加新的模式
|
||||
*
|
||||
* @details 按键模式名不能重复,如果添加重复的名字仅第一次成功,后续将添加失败
|
||||
*
|
||||
* @param table 按键绑定表
|
||||
* @param mode_name 按键模式名字,不能为 nullptr 或空字符串
|
||||
*
|
||||
* @return 添加成功返回新增模式的 id 否则返回 ZDWM_BINDING_MODE_ID_INVALID
|
||||
*/
|
||||
zdwm_binding_mode_id_t
|
||||
binding_table_add_mode(binding_table_t *table, const char *mode_name);
|
||||
|
||||
/**
|
||||
* @brief 添加按键绑定
|
||||
*
|
||||
* @details mode_id 对应的模式不存在或 key_sequence 不合法,都会添加失败
|
||||
*
|
||||
* @param table 按键绑定表
|
||||
* @param mode_id 模式 ID
|
||||
* @param key_sequence 按键序列的字符串表达
|
||||
* @param fn 用户行为函数
|
||||
* @param arg 用户行为函数所需的参数
|
||||
*
|
||||
* @return 添加成功返回 true 否则返回 false
|
||||
*/
|
||||
bool binding_table_add_bind(
|
||||
binding_table_t *table,
|
||||
zdwm_binding_mode_id_t mode_id,
|
||||
const char *key_sequence,
|
||||
zdwm_action_fn fn,
|
||||
zdwm_action_arg_t *arg
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief 销毁按键绑定表
|
||||
*/
|
||||
void binding_table_destroy(binding_table_t *table);
|
||||
|
||||
/**
|
||||
* @brief 创建按键绑定表
|
||||
*/
|
||||
binding_table_t *binding_table_create(void);
|
||||
|
||||
/**
|
||||
* @brief 通过模式 ID 设置默认模式
|
||||
*
|
||||
* @param table 按键绑定表
|
||||
* @param mode_id 按键模式 ID
|
||||
*
|
||||
* @return 切换成功返回 true 否则返回 false
|
||||
*/
|
||||
bool binding_table_set_default_mode(
|
||||
binding_table_t *table,
|
||||
zdwm_binding_mode_id_t mode_id
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief 通过模式 ID 设置当前模式
|
||||
*
|
||||
* @param table 按键绑定表
|
||||
* @param mode_id 按键模式 ID
|
||||
*
|
||||
* @return 切换成功返回 true 否则返回 false
|
||||
*/
|
||||
bool binding_table_set_current_mode(
|
||||
binding_table_t *table,
|
||||
zdwm_binding_mode_id_t mode_id
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief 切换按键绑定模式
|
||||
*
|
||||
* @param table 按键绑定表
|
||||
* @param delta 切换变化量
|
||||
*
|
||||
* @return 无法切换返回 false 否则返回 true
|
||||
*/
|
||||
bool binding_table_cycle_mode(binding_table_t *table, int delta);
|
||||
@@ -20,13 +20,6 @@ typedef enum event_type_t {
|
||||
ZDWM_EVENT_CONFIGURE_REQUEST,
|
||||
} event_type_t;
|
||||
|
||||
typedef enum modifier_bit_t {
|
||||
ZDWM_MOD_SHIFT = 1u << 0,
|
||||
ZDWM_MOD_CTRL = 1u << 1,
|
||||
ZDWM_MOD_ALT = 1u << 2,
|
||||
ZDWM_MOD_SUPER = 1u << 3,
|
||||
} modifier_bit_t;
|
||||
|
||||
typedef uint32_t modifier_mask_t;
|
||||
typedef uint32_t keysym_t;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <zdwm/action.h>
|
||||
#include "core/command_buffer.h"
|
||||
#include "core/event.h"
|
||||
#include "core/plan.h"
|
||||
@@ -9,6 +10,7 @@
|
||||
typedef struct policy_context_t {
|
||||
state_t *state;
|
||||
const rules_t *rules;
|
||||
const zdwm_action_ctx_t action_ctx;
|
||||
} policy_context_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "action.h"
|
||||
#include "base/memory.h"
|
||||
#include "core/backend.h"
|
||||
#include "core/binding.h"
|
||||
#include "core/command_buffer.h"
|
||||
#include "core/event.h"
|
||||
#include "core/layout.h"
|
||||
@@ -52,8 +54,10 @@ bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc) {
|
||||
layout_registry_move(&desc->layouts, &runtime->layouts);
|
||||
rules_move(&desc->rules, &runtime->rules);
|
||||
runtime->config_module_handle = desc->config_module_handle;
|
||||
runtime->binding_table = desc->binding_table;
|
||||
desc->backend = nullptr;
|
||||
desc->config_module_handle = nullptr;
|
||||
desc->binding_table = nullptr;
|
||||
|
||||
state_init(
|
||||
&runtime->state,
|
||||
@@ -73,6 +77,9 @@ bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc) {
|
||||
void runtime_init_desc_cleanup(runtime_init_desc_t *desc) {
|
||||
if (!desc) return;
|
||||
|
||||
binding_table_destroy(desc->binding_table);
|
||||
desc->binding_table = nullptr;
|
||||
|
||||
if (desc->backend) {
|
||||
backend_destroy(desc->backend);
|
||||
desc->backend = nullptr;
|
||||
@@ -97,6 +104,8 @@ void runtime_shutdown(runtime_t *runtime) {
|
||||
layout_registry_cleanup(&runtime->layouts);
|
||||
rules_cleanup(&runtime->rules);
|
||||
state_cleanup(&runtime->state);
|
||||
binding_table_destroy(runtime->binding_table);
|
||||
runtime->binding_table = nullptr;
|
||||
backend_destroy(runtime->backend);
|
||||
runtime->backend = nullptr;
|
||||
if (runtime->config_module_handle) dlclose(runtime->config_module_handle);
|
||||
@@ -111,8 +120,11 @@ void runtime_run(runtime_t *runtime) {
|
||||
plan_t *plan = &runtime->plan;
|
||||
|
||||
policy_context_t ctx = {
|
||||
.state = &runtime->state,
|
||||
.rules = &runtime->rules,
|
||||
.state = &runtime->state,
|
||||
.rules = &runtime->rules,
|
||||
.action_ctx = {
|
||||
.spawn = spawn,
|
||||
},
|
||||
};
|
||||
|
||||
while (runtime->running) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "core/backend.h"
|
||||
#include "core/binding.h"
|
||||
#include "core/command_buffer.h"
|
||||
#include "core/layout.h"
|
||||
#include "core/plan.h"
|
||||
@@ -19,6 +20,7 @@ typedef struct runtime_init_desc_t {
|
||||
workspace_desc_t *workspaces;
|
||||
size_t workspace_count;
|
||||
void *config_module_handle;
|
||||
binding_table_t *binding_table;
|
||||
} runtime_init_desc_t;
|
||||
|
||||
typedef struct runtime_t {
|
||||
@@ -32,6 +34,7 @@ typedef struct runtime_t {
|
||||
rules_t rules;
|
||||
backend_t *backend;
|
||||
void *config_module_handle;
|
||||
binding_table_t *binding_table;
|
||||
} runtime_t;
|
||||
|
||||
bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc);
|
||||
|
||||
@@ -48,3 +48,14 @@ typedef enum cross_output_policy_t {
|
||||
ZDWM_CROSS_OUTPUT_KEEP_WORKSPACE,
|
||||
ZDWM_CROSS_OUTPUT_MOVE_TO_TARGET_WORKSPACE,
|
||||
} cross_output_policy_t;
|
||||
|
||||
typedef enum modifier_bit_t {
|
||||
ZDWM_MOD_NONE = 0u,
|
||||
ZDWM_MOD_SHIFT = 1u << 0,
|
||||
ZDWM_MOD_CONTROL = 1u << 1,
|
||||
ZDWM_MOD_1 = 1u << 2,
|
||||
ZDWM_MOD_2 = 1u << 3,
|
||||
ZDWM_MOD_3 = 1u << 4,
|
||||
ZDWM_MOD_4 = 1u << 5,
|
||||
ZDWM_MOD_5 = 1u << 6,
|
||||
} modifier_bit_t;
|
||||
|
||||
@@ -41,6 +41,8 @@ add_executable(${RUNTIME_CONFIG_TEST_APP_NAME}
|
||||
${SOURCE_DIR}/config/defaults.c
|
||||
${SOURCE_DIR}/config/loader.c
|
||||
${SOURCE_DIR}/config/runtime_config.c
|
||||
${SOURCE_DIR}/core/action.c
|
||||
${SOURCE_DIR}/core/binding.c
|
||||
${SOURCE_DIR}/core/command_buffer.c
|
||||
${SOURCE_DIR}/core/event.c
|
||||
${SOURCE_DIR}/core/layer.c
|
||||
@@ -61,6 +63,7 @@ target_include_directories(${RUNTIME_CONFIG_TEST_APP_NAME}
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
target_link_libraries(${RUNTIME_CONFIG_TEST_APP_NAME}
|
||||
PRIVATE ${deps_xkbcommon_MODULE_NAME}
|
||||
PRIVATE ${CMAKE_DL_LIBS}
|
||||
)
|
||||
add_dependencies(${RUNTIME_CONFIG_TEST_APP_NAME}
|
||||
|
||||
@@ -10,6 +10,8 @@ add_executable(${TEST_APP_NAME}
|
||||
${SOURCE_DIR}/backend/x11/backend.c
|
||||
${SOURCE_DIR}/backend/x11/event.c
|
||||
${SOURCE_DIR}/backend/x11/window.c
|
||||
${SOURCE_DIR}/core/action.c
|
||||
${SOURCE_DIR}/core/binding.c
|
||||
${SOURCE_DIR}/core/command_buffer.c
|
||||
${SOURCE_DIR}/core/event.c
|
||||
${SOURCE_DIR}/core/layer.c
|
||||
|
||||
Reference in New Issue
Block a user