diff --git a/include/zdwm/action.h b/include/zdwm/action.h index 6ee1438..692a57f 100644 --- a/include/zdwm/action.h +++ b/include/zdwm/action.h @@ -8,50 +8,65 @@ extern "C" { #endif -typedef union zdwm_action_arg_t { - bool b; - int32_t i; - uint32_t ui; - const char *str; - const void *ptr; -} zdwm_action_arg_t; +typedef enum zdwm_action_type_t { + ZDWM_ACTION_SPAWN, + ZDWM_ACTION_QUIT, + ZDWM_ACTION_RAISE_OR_RUN, -typedef struct zdwm_runtime_t zdwm_runtime_t; + ZDWM_ACTION_OUTPUT_CYCLE, + ZDWM_ACTION_WORKSPACE_SWITCH_SAME_OUTPUT_BY_INDEX, + ZDWM_ACTION_LAYOUT_CYCLE, + ZDWM_ACTION_BINDING_MODE_CYCLE, -typedef struct zdwm_action_api_t { - void (*spawn)(const char *command); - void (*quit)(zdwm_runtime_t *runtime, bool restart); - void (*raise_or_run)( - zdwm_runtime_t *runtime, - const char *class_name, - const char *command - ); - void (*toggle_fullscreen)(zdwm_runtime_t *runtime); - void (*toggle_maximize)(zdwm_runtime_t *runtime); - void (*toggle_floating)(zdwm_runtime_t *runtime); - void (*toggle_sticky)(zdwm_runtime_t *runtime); - void (*switch_workspace)( - zdwm_runtime_t *runtime, - zdwm_workspace_id_t workspace_id - ); - void (*switch_workspace_in_current_output)( - zdwm_runtime_t *runtime, - zdwm_workspace_id_t workspace_id - ); - void (*switch_workspace_by_index_in_current_output)( - zdwm_runtime_t *runtime, - uint32_t index - ); - void (*cycle_layout)(zdwm_runtime_t *runtime, int32_t delta); - void (*cycle_current_output)(zdwm_runtime_t *runtime, int32_t delta); - void (*focus_window)(zdwm_runtime_t *runtime, int32_t delta); -} zdwm_action_api_t; + ZDWM_ACTION_WINDOW_TOGGLE_FULLSCREEN, + ZDWM_ACTION_WINDOW_TOGGLE_MAXIMIZE, + ZDWM_ACTION_WINDOW_TOGGLE_MINIMIZE, + ZDWM_ACTION_WINDOW_TOGGLE_FLOATING, + ZDWM_ACTION_WINDOW_TOGGLE_STICKY, -typedef void zdwm_action_fn( - zdwm_runtime_t *runtime, - const zdwm_action_api_t *ctx, - const zdwm_action_arg_t *arg -); + ZDWM_ACTION_WINDOW_FOCUS_CYCLE, + ZDWM_ACTION_WINDOW_KILL, + + ZDWM_ACTION_WINDOW_SEND_TO_WORKSPACE_SAME_OUTPUT_BY_INDEX, + ZDWM_ACTION_WINDOW_CYCLE_OUTPUT, +} zdwm_action_type_t; + +typedef struct zdwm_action_data_spawn_t { + const char *command; +} zdwm_action_data_spawn_t; + +typedef struct zdwm_action_data_quit_t { + bool restart; +} zdwm_action_data_quit_t; + +typedef struct zdwm_action_data_raise_or_run_t { + const char *class_name; + const char *command; +} zdwm_action_data_raise_or_run_t; + +typedef struct zdwm_action_data_delta_only_t { + int32_t delta; +} zdwm_action_data_delta_only_t; + +typedef struct zdwm_action_data_index_only_t { + uint32_t index; +} zdwm_action_data_index_only_t; + +typedef struct zdwm_action_t { + zdwm_action_type_t type; + union { + zdwm_action_data_spawn_t spawn; + zdwm_action_data_quit_t quit; + zdwm_action_data_raise_or_run_t raise_or_run; + zdwm_action_data_delta_only_t output_cycle; + zdwm_action_data_index_only_t workspace_switch_same_output_by_index; + zdwm_action_data_delta_only_t layout_cycle; + zdwm_action_data_delta_only_t binding_mode_cycle; + zdwm_action_data_delta_only_t window_focus_cycle; + zdwm_action_data_index_only_t window_send_to_workspace_same_output_by_index; + zdwm_action_data_delta_only_t window_cycle_output; + } as; +} zdwm_action_t; #if defined(__cplusplus) } diff --git a/include/zdwm/config.h b/include/zdwm/config.h index 075ec64..d6e49e2 100644 --- a/include/zdwm/config.h +++ b/include/zdwm/config.h @@ -112,8 +112,7 @@ typedef struct zdwm_api_t { 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 + zdwm_action_t action ); /** diff --git a/src/config/defaults.c b/src/config/defaults.c index 16f510d..4274f82 100644 --- a/src/config/defaults.c +++ b/src/config/defaults.c @@ -13,80 +13,12 @@ static constexpr char launcher[] = "rofi -show combi -modes combi -combi-modes window,drun,run,ssh,windowcd"; -typedef struct raise_or_run_arg_t { - const char *class_name; - const char *command; -} raise_or_run_arg_t; +typedef struct zdwm_action_data_raise_or_run_t raise_or_run_data_t; -static raise_or_run_arg_t terminal = {"XTerm", "xterm"}; -static raise_or_run_arg_t editor = {"Emacs", "emacsclient -a '' -r -n"}; -static raise_or_run_arg_t browser = {"firefox", "firefox-bin"}; -static raise_or_run_arg_t chrome = {"Google-chrome", "google-chrome-stable"}; - -static void spawn( - zdwm_runtime_t *runtime, - const zdwm_action_api_t *api, - const zdwm_action_arg_t *arg -) { - api->spawn(arg->str); -} - -static void quit( - zdwm_runtime_t *runtime, - const zdwm_action_api_t *api, - const zdwm_action_arg_t *arg -) { - api->quit(runtime, arg->b); -} - -static void raise_or_run( - zdwm_runtime_t *runtime, - const zdwm_action_api_t *api, - const zdwm_action_arg_t *arg -) { - auto args = (raise_or_run_arg_t *)arg->ptr; - api->raise_or_run(runtime, args->class_name, args->command); -} - -static void toggle_fullscreen( - zdwm_runtime_t *runtime, - const zdwm_action_api_t *api, - const zdwm_action_arg_t *arg -) { - api->toggle_fullscreen(runtime); -} - -static void toggle_maximize( - zdwm_runtime_t *runtime, - const zdwm_action_api_t *api, - const zdwm_action_arg_t *arg -) { - api->toggle_maximize(runtime); -} - -static void toggle_floating( - zdwm_runtime_t *runtime, - const zdwm_action_api_t *api, - const zdwm_action_arg_t *arg -) { - api->toggle_floating(runtime); -} - -static void switch_workspace( - zdwm_runtime_t *runtime, - const zdwm_action_api_t *api, - const zdwm_action_arg_t *arg -) { - api->switch_workspace_by_index_in_current_output(runtime, arg->ui); -} - -static void focus_window( - zdwm_runtime_t *runtime, - const zdwm_action_api_t *api, - const zdwm_action_arg_t *arg -) { - api->focus_window(runtime, arg->i); -} +static raise_or_run_data_t terminal = {"XTerm", "xterm"}; +static raise_or_run_data_t editor = {"Emacs", "emacsclient -a '' -r -n"}; +static raise_or_run_data_t browser = {"firefox", "firefox-bin"}; +static raise_or_run_data_t chrome = {"Google-chrome", "google-chrome-stable"}; bool config_defaults_build( const zdwm_api_t *api, @@ -156,32 +88,63 @@ bool config_defaults_build( auto default_mode = api->add_mode(builder, "default"); -#define Alt "Mod1" -#define Super "Mod4" -#define BIND(MODE, KEY, FN, ARG) \ - api->bind(builder, MODE, KEY, FN, (zdwm_action_arg_t)ARG) +#define Alt_Key "Mod1" +#define Super_key "Mod4" +#define Alt(K) Alt_Key "+" K +#define Super(K) Super_key "+" K - BIND(default_mode, Super "+r", spawn, {.str = launcher}); - BIND(default_mode, Super "+Shift+q", quit, {.b = false}); - BIND(default_mode, Super "+Control+r", quit, {.b = true}); +#define BIND(MODE, KEY, ...) \ + api->bind(builder, MODE, KEY, (zdwm_action_t)__VA_ARGS__) +#define SPAWN(MODE, KEY, COMMAND) \ + BIND(MODE, KEY, {.type = ZDWM_ACTION_SPAWN, .as.spawn.command = (COMMAND)}) +#define QUIT(MODE, KEY, RESTART) \ + BIND(MODE, KEY, {.type = ZDWM_ACTION_QUIT, .as.quit.restart = (RESTART)}) +#define RAISE_OR_RUN(MODE, KEY, ...) \ + BIND( \ + MODE, \ + KEY, \ + { \ + .type = ZDWM_ACTION_RAISE_OR_RUN, \ + .as.raise_or_run = (zdwm_action_data_raise_or_run_t)__VA_ARGS__, \ + } \ + ) +#define BIND_DEFAULT(KEY, ...) BIND(default_mode, KEY, __VA_ARGS__) - BIND(default_mode, Super "+Return", spawn, {.str = terminal.command}); - BIND(default_mode, Alt "+Control+r", raise_or_run, {.ptr = &terminal}); - BIND(default_mode, Super "+e", raise_or_run, {.ptr = &editor}); - BIND(default_mode, Super "+q", raise_or_run, {.ptr = &browser}); - BIND(default_mode, Super "+a", raise_or_run, {.ptr = &chrome}); - BIND(default_mode, Super "+f", toggle_fullscreen, {0}); - BIND(default_mode, Super "+m", toggle_maximize, {0}); - BIND(default_mode, Super "+Control+space", toggle_floating, {0}); - BIND(default_mode, Alt "+j", focus_window, {.i = 1}); - BIND(default_mode, Alt "+k", focus_window, {.i = -1}); + SPAWN(default_mode, Super("r"), launcher); + QUIT(default_mode, Super("Shift+q"), false); + QUIT(default_mode, Super("Control+r"), true); + + SPAWN(default_mode, Super("Return"), terminal.command); + RAISE_OR_RUN(default_mode, Alt("Control+r"), terminal); + RAISE_OR_RUN(default_mode, Super("e"), editor); + RAISE_OR_RUN(default_mode, Super("q"), browser); + RAISE_OR_RUN(default_mode, Super("a"), chrome); + BIND_DEFAULT(Super("f"), {.type = ZDWM_ACTION_WINDOW_TOGGLE_FLOATING}); + BIND_DEFAULT(Super("m"), {.type = ZDWM_ACTION_WINDOW_TOGGLE_MAXIMIZE}); + BIND_DEFAULT( + Super("Control+space"), + {.type = ZDWM_ACTION_WINDOW_TOGGLE_FLOATING} + ); + BIND_DEFAULT( + Alt("j"), + {.type = ZDWM_ACTION_WINDOW_FOCUS_CYCLE, .as.window_focus_cycle.delta = 1} + ); + BIND_DEFAULT( + Alt("k"), + {.type = ZDWM_ACTION_WINDOW_FOCUS_CYCLE, .as.window_focus_cycle.delta = -1} + ); char buffer[64] = {0}; for (uint32_t i = 0; i < 9; ++i) { - snprintf(buffer, sizeof(buffer), "%s+%d", Super, i + 1); - BIND(default_mode, buffer, switch_workspace, {.ui = i}); + snprintf(buffer, sizeof(buffer), "%s+%d", Super_key, i + 1); + zdwm_action_t action = { + .type = ZDWM_ACTION_WINDOW_SEND_TO_WORKSPACE_SAME_OUTPUT_BY_INDEX, + .as.workspace_switch_same_output_by_index.index = i, + }; + BIND_DEFAULT(buffer, action); } +#undef BIND_DEFAULT #undef BIND api->set_default_mode(builder, default_mode); diff --git a/src/config/runtime_config.c b/src/config/runtime_config.c index 0b6c391..c89fe75 100644 --- a/src/config/runtime_config.c +++ b/src/config/runtime_config.c @@ -167,10 +167,9 @@ 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 + zdwm_action_t action ) { - return binding_table_add_bind(builder->binding_table, mode, key, fn, arg); + return binding_table_add_bind(builder->binding_table, mode, key, action); } static bool runtime_config_set_default_mode( diff --git a/src/core/action.h b/src/core/action.h index c80fef0..ffda191 100644 --- a/src/core/action.h +++ b/src/core/action.h @@ -3,30 +3,29 @@ #include #include +typedef struct runtime_t runtime_t; + void spawn(const char *command); -void quit(zdwm_runtime_t *runtime, bool restart); +void quit(runtime_t *runtime, bool restart); void raise_or_run( - zdwm_runtime_t *runtime, + runtime_t *runtime, const char *class_name, const char *command ); -void toggle_fullscreen(zdwm_runtime_t *runtime); -void toggle_maximize(zdwm_runtime_t *runtime); -void toggle_floating(zdwm_runtime_t *runtime); -void toggle_sticky(zdwm_runtime_t *runtime); -void switch_workspace( - zdwm_runtime_t *runtime, - zdwm_workspace_id_t workspace_id -); +void toggle_fullscreen(runtime_t *runtime); +void toggle_maximize(runtime_t *runtime); +void toggle_floating(runtime_t *runtime); +void toggle_sticky(runtime_t *runtime); +void switch_workspace(runtime_t *runtime, zdwm_workspace_id_t workspace_id); void switch_workspace_in_current_output( - zdwm_runtime_t *runtime, + runtime_t *runtime, zdwm_workspace_id_t workspace_id ); void switch_workspace_by_index_in_current_output( - zdwm_runtime_t *runtime, + runtime_t *runtime, uint32_t index ); -void cycle_layout(zdwm_runtime_t *runtime, int32_t delta); -void cycle_current_output(zdwm_runtime_t *runtime, int32_t delta); -void focus_window(zdwm_runtime_t *runtime, int32_t delta); +void cycle_layout(runtime_t *runtime, int32_t delta); +void cycle_current_output(runtime_t *runtime, int32_t delta); +void focus_window(runtime_t *runtime, int32_t delta); diff --git a/src/core/binding.c b/src/core/binding.c index 96b4c6c..d5a5b58 100644 --- a/src/core/binding.c +++ b/src/core/binding.c @@ -43,8 +43,7 @@ binding_table_add_mode(binding_table_t *table, const char *mode_name) { } 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); + auto new_mode = array_push(table->modes, table->count, table->capacity); new_mode->name = mode_name; new_mode->id = id; @@ -166,8 +165,7 @@ 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 + zdwm_action_t action ) { binding_mode_t *mode = binding_table_get_mode(table, mode_id); if (!mode) return false; @@ -176,12 +174,11 @@ bool binding_table_add_bind( 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; + auto item = array_push(mode->items, mode->count, mode->capacity); + item->key_str = key_sequence; + item->modifiers = modifiers; + item->keysym = keysym; + item->action = action; return true; } diff --git a/src/core/binding.h b/src/core/binding.h index dfa4271..1c8272f 100644 --- a/src/core/binding.h +++ b/src/core/binding.h @@ -12,8 +12,7 @@ typedef struct key_binding_t { const char *key_str; modifier_mask_t modifiers; keysym_t keysym; - zdwm_action_fn *fn; - zdwm_action_arg_t arg; + zdwm_action_t action; } key_binding_t; /** @@ -37,8 +36,7 @@ binding_table_add_mode(binding_table_t *table, const char *mode_name); * @param table 按键绑定表 * @param mode_id 模式 ID * @param key_sequence 按键序列的字符串表达 - * @param fn 用户行为函数 - * @param arg 用户行为函数所需的参数 + * @param action 用户行为描述 * * @return 添加成功返回 true 否则返回 false */ @@ -46,8 +44,7 @@ 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 + zdwm_action_t action ); /** diff --git a/src/core/policy.c b/src/core/policy.c index 336e43c..b05476a 100644 --- a/src/core/policy.c +++ b/src/core/policy.c @@ -18,8 +18,17 @@ #include "core/window.h" #include "core/wm_desc.h" -static void -route_key_press(const policy_context_t *ctx, const key_press_event_t *e) { +static void policy_resolve_action( + const state_t *state, + const zdwm_action_t *action, + command_buffer_t *out +) {} + +static void route_key_press( + const policy_context_t *ctx, + const key_press_event_t *e, + command_buffer_t *out +) { auto binding_table = ctx->bind_table; size_t count = 0; @@ -29,7 +38,8 @@ route_key_press(const policy_context_t *ctx, const key_press_event_t *e) { for (size_t i = 0; i < count; ++i) { auto binding = &bindings[i]; if (binding->modifiers == e->modifiers && binding->keysym == e->keysym) { - binding->fn(ctx->runtime, &ctx->action_api, &binding->arg); + policy_resolve_action(ctx->state, &binding->action, out); + /* binding->fn(ctx->runtime, &ctx->action_api, &binding->arg); */ } } } @@ -264,7 +274,7 @@ void policy_route_event( auto state = ctx->state; switch (event->type) { case ZDWM_EVENT_KEY_PRESS: - route_key_press(ctx, &event->as.key_press); + route_key_press(ctx, &event->as.key_press, out); break; case ZDWM_EVENT_POINTER_ENTER: route_pointer_enter(state, event->as.pointer_enter.window, out); diff --git a/src/core/policy.h b/src/core/policy.h index bd32948..c6262c3 100644 --- a/src/core/policy.h +++ b/src/core/policy.h @@ -17,8 +17,6 @@ typedef struct policy_context_t { const rules_t *rules; const border_config_t *border; const layout_registry_t *layouts; - const zdwm_action_api_t action_api; - zdwm_runtime_t *runtime; } policy_context_t; /** diff --git a/src/core/runtime.c b/src/core/runtime.c index f2f7aac..8810696 100644 --- a/src/core/runtime.c +++ b/src/core/runtime.c @@ -266,25 +266,6 @@ static policy_context_t policy_context_init(runtime_t *runtime) { .rules = &(runtime)->rules, .border = &(runtime)->border, .layouts = &(runtime)->layouts, - .runtime = (runtime), - .action_api = { - .spawn = spawn, - .quit = quit, - .raise_or_run = raise_or_run, - .toggle_fullscreen = toggle_fullscreen, - .toggle_maximize = toggle_maximize, - .toggle_floating = toggle_floating, - .toggle_sticky = toggle_sticky, - - .switch_workspace = switch_workspace, - .switch_workspace_in_current_output = switch_workspace_in_current_output, - .switch_workspace_by_index_in_current_output = - switch_workspace_by_index_in_current_output, - - .cycle_layout = cycle_layout, - .cycle_current_output = cycle_current_output, - .focus_window = focus_window, - }, }; return ctx; } diff --git a/src/core/runtime.h b/src/core/runtime.h index b923685..c4d09e8 100644 --- a/src/core/runtime.h +++ b/src/core/runtime.h @@ -28,7 +28,7 @@ typedef struct runtime_init_desc_t { listeners_t listeners; } runtime_init_desc_t; -typedef struct zdwm_runtime_t { +typedef struct runtime_t { bool running; bool will_restart;