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_layout)(zdwm_runtime_t *runtime, int32_t delta);
|
||||||
void (*cycle_current_output)(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_api_t;
|
||||||
|
|
||||||
typedef void zdwm_action_fn(
|
typedef void zdwm_action_fn(
|
||||||
|
|||||||
@@ -67,6 +67,14 @@ static void toggle_floating(
|
|||||||
api->toggle_floating(runtime);
|
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(
|
bool config_defaults_build(
|
||||||
const zdwm_api_t *api,
|
const zdwm_api_t *api,
|
||||||
zdwm_config_builder_t *builder,
|
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 "+f", toggle_fullscreen, {0});
|
||||||
BIND(default_mode, Super "+m", toggle_maximize, {0});
|
BIND(default_mode, Super "+m", toggle_maximize, {0});
|
||||||
BIND(default_mode, Super "+Control+space", toggle_floating, {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
|
#undef BIND
|
||||||
|
|
||||||
|
|||||||
@@ -177,3 +177,50 @@ void cycle_current_output(runtime_t *runtime, int32_t delta) {
|
|||||||
auto state = &runtime->state;
|
auto state = &runtime->state;
|
||||||
state_cycle_current_output(state, delta);
|
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_layout(zdwm_runtime_t *runtime, int32_t delta);
|
||||||
void cycle_current_output(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_UNMANAGE_WINDOW,
|
||||||
ZDWM_COMMAND_FOCUS_WINDOW,
|
ZDWM_COMMAND_FOCUS_WINDOW,
|
||||||
ZDWM_COMMAND_KILL_WINDOW,
|
ZDWM_COMMAND_KILL_WINDOW,
|
||||||
|
ZDWM_COMMAND_RAISE_WINDOW,
|
||||||
ZDWM_COMMAND_WITHDRAW_WINDOW,
|
ZDWM_COMMAND_WITHDRAW_WINDOW,
|
||||||
ZDWM_COMMAND_CONFIGURE_WINDOW,
|
ZDWM_COMMAND_CONFIGURE_WINDOW,
|
||||||
ZDWM_COMMAND_CHANGE_WINDOW_STATE,
|
ZDWM_COMMAND_CHANGE_WINDOW_STATE,
|
||||||
@@ -56,6 +57,7 @@ typedef struct command_t {
|
|||||||
only_window_data_t unmanage;
|
only_window_data_t unmanage;
|
||||||
only_window_data_t focus;
|
only_window_data_t focus;
|
||||||
only_window_data_t kill;
|
only_window_data_t kill;
|
||||||
|
only_window_data_t raise;
|
||||||
only_window_data_t withdraw;
|
only_window_data_t withdraw;
|
||||||
configure_data_t configure;
|
configure_data_t configure;
|
||||||
window_state_change_command_t state_change;
|
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);
|
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) {
|
static void withdraw_window(state_t *state, window_id_t window, plan_t *plan) {
|
||||||
auto win = state_window_get(state, window);
|
auto win = state_window_get(state, window);
|
||||||
if (!win) return;
|
if (!win) return;
|
||||||
@@ -846,6 +866,9 @@ void policy_apply_command(
|
|||||||
case ZDWM_COMMAND_KILL_WINDOW:
|
case ZDWM_COMMAND_KILL_WINDOW:
|
||||||
kill_window(state, cmd->as.kill.window, plan);
|
kill_window(state, cmd->as.kill.window, plan);
|
||||||
break;
|
break;
|
||||||
|
case ZDWM_COMMAND_RAISE_WINDOW:
|
||||||
|
raise_window(state, cmd->as.raise.window, plan);
|
||||||
|
break;
|
||||||
case ZDWM_COMMAND_WITHDRAW_WINDOW:
|
case ZDWM_COMMAND_WITHDRAW_WINDOW:
|
||||||
withdraw_window(state, cmd->as.withdraw.window, plan);
|
withdraw_window(state, cmd->as.withdraw.window, plan);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -276,6 +276,7 @@ policy_context_t policy_context_init(runtime_t *runtime) {
|
|||||||
.switch_workspace = switch_workspace,
|
.switch_workspace = switch_workspace,
|
||||||
.cycle_layout = cycle_layout,
|
.cycle_layout = cycle_layout,
|
||||||
.cycle_current_output = cycle_current_output,
|
.cycle_current_output = cycle_current_output,
|
||||||
|
.focus_window = focus_window,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return ctx;
|
return ctx;
|
||||||
|
|||||||
Reference in New Issue
Block a user