feat(action): 实现 focus_window 窗口焦点切换及 raise 命令
This commit is contained in:
@@ -36,6 +36,7 @@ typedef struct zdwm_action_api_t {
|
||||
);
|
||||
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;
|
||||
|
||||
typedef void zdwm_action_fn(
|
||||
|
||||
@@ -67,6 +67,14 @@ static void toggle_floating(
|
||||
api->toggle_floating(runtime);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
bool config_defaults_build(
|
||||
const zdwm_api_t *api,
|
||||
zdwm_config_builder_t *builder,
|
||||
@@ -143,6 +151,8 @@ bool config_defaults_build(
|
||||
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});
|
||||
|
||||
#undef BIND
|
||||
|
||||
|
||||
@@ -177,3 +177,50 @@ void cycle_current_output(runtime_t *runtime, int32_t delta) {
|
||||
auto state = &runtime->state;
|
||||
state_cycle_current_output(state, delta);
|
||||
}
|
||||
|
||||
void focus_window(runtime_t *runtime, int32_t delta) {
|
||||
auto state = &runtime->state;
|
||||
auto output = state_output_at(state, state->current_output_index);
|
||||
auto workspace = state_workspace_get(state, output->current_workspace_id);
|
||||
|
||||
size_t count = state_window_count(state);
|
||||
if (!count) return;
|
||||
|
||||
size_t indices[count];
|
||||
size_t num = 0;
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
auto window = state_window_at(state, i);
|
||||
if (window->workspace_id == workspace->id) {
|
||||
indices[num++] = i;
|
||||
}
|
||||
}
|
||||
if (!num) return;
|
||||
|
||||
size_t current = 0;
|
||||
if (!window_id_invalid(workspace->focused_window_id)) {
|
||||
for (size_t i = 0; i < num; ++i) {
|
||||
auto window = state_window_at(state, indices[i]);
|
||||
if (window->id == workspace->focused_window_id) {
|
||||
current = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int64_t next = ((int64_t)current + (int64_t)delta) % (int64_t)num;
|
||||
if (next < 0) next += (int64_t)num;
|
||||
|
||||
auto target = state_window_at(state, indices[next]);
|
||||
|
||||
command_t focus_cmd = {
|
||||
.type = ZDWM_COMMAND_FOCUS_WINDOW,
|
||||
.as.focus.window = target->id,
|
||||
};
|
||||
command_buffer_push(&runtime->command_buffer, &focus_cmd);
|
||||
|
||||
command_t raise_cmd = {
|
||||
.type = ZDWM_COMMAND_RAISE_WINDOW,
|
||||
.as.raise.window = target->id,
|
||||
};
|
||||
command_buffer_push(&runtime->command_buffer, &raise_cmd);
|
||||
}
|
||||
|
||||
@@ -21,3 +21,4 @@ void switch_workspace(
|
||||
);
|
||||
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);
|
||||
|
||||
@@ -8,6 +8,7 @@ typedef enum command_type_t {
|
||||
ZDWM_COMMAND_UNMANAGE_WINDOW,
|
||||
ZDWM_COMMAND_FOCUS_WINDOW,
|
||||
ZDWM_COMMAND_KILL_WINDOW,
|
||||
ZDWM_COMMAND_RAISE_WINDOW,
|
||||
ZDWM_COMMAND_WITHDRAW_WINDOW,
|
||||
ZDWM_COMMAND_CONFIGURE_WINDOW,
|
||||
ZDWM_COMMAND_CHANGE_WINDOW_STATE,
|
||||
@@ -56,6 +57,7 @@ typedef struct command_t {
|
||||
only_window_data_t unmanage;
|
||||
only_window_data_t focus;
|
||||
only_window_data_t kill;
|
||||
only_window_data_t raise;
|
||||
only_window_data_t withdraw;
|
||||
configure_data_t configure;
|
||||
window_state_change_command_t state_change;
|
||||
|
||||
@@ -476,6 +476,26 @@ static void kill_window(state_t *state, window_id_t window, plan_t *plan) {
|
||||
plan_push_kill_effect(plan, window);
|
||||
}
|
||||
|
||||
static void raise_window(state_t *state, window_id_t window, plan_t *plan) {
|
||||
if (!state_stack_raise(state, window)) return;
|
||||
|
||||
window_list_t list = {0};
|
||||
for (size_t i = 0; i < countof(state->stacks); ++i) {
|
||||
for (size_t j = 0; j < state->stacks[i].count; ++j) {
|
||||
auto window_id = state->stacks[i].order[j];
|
||||
window_list_push(&list, window_id);
|
||||
}
|
||||
}
|
||||
effect_t restack_windows_effect = {
|
||||
.type = ZDWM_EFFECT_RESTACK_WINDOWS,
|
||||
.as.restack_windows = {
|
||||
.windows = list.windows,
|
||||
.count = list.count,
|
||||
},
|
||||
};
|
||||
plan_push_effect(plan, &restack_windows_effect);
|
||||
}
|
||||
|
||||
static void withdraw_window(state_t *state, window_id_t window, plan_t *plan) {
|
||||
auto win = state_window_get(state, window);
|
||||
if (!win) return;
|
||||
@@ -846,6 +866,9 @@ void policy_apply_command(
|
||||
case ZDWM_COMMAND_KILL_WINDOW:
|
||||
kill_window(state, cmd->as.kill.window, plan);
|
||||
break;
|
||||
case ZDWM_COMMAND_RAISE_WINDOW:
|
||||
raise_window(state, cmd->as.raise.window, plan);
|
||||
break;
|
||||
case ZDWM_COMMAND_WITHDRAW_WINDOW:
|
||||
withdraw_window(state, cmd->as.withdraw.window, plan);
|
||||
break;
|
||||
|
||||
@@ -276,6 +276,7 @@ policy_context_t policy_context_init(runtime_t *runtime) {
|
||||
.switch_workspace = switch_workspace,
|
||||
.cycle_layout = cycle_layout,
|
||||
.cycle_current_output = cycle_current_output,
|
||||
.focus_window = focus_window,
|
||||
},
|
||||
};
|
||||
return ctx;
|
||||
|
||||
Reference in New Issue
Block a user