feat(bar): 实现 bar 可见性切换 action
This commit is contained in:
@@ -31,6 +31,8 @@ typedef enum zdwm_action_type_t {
|
||||
|
||||
ZDWM_ACTION_WINDOW_SEND_TO_WORKSPACE_SAME_OUTPUT_BY_INDEX,
|
||||
ZDWM_ACTION_WINDOW_CYCLE_OUTPUT,
|
||||
|
||||
ZDWM_ACTION_BAR_TOGGLE_VISIBILITY,
|
||||
} zdwm_action_type_t;
|
||||
|
||||
typedef struct zdwm_action_data_spawn_t {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <zdwm/action.h>
|
||||
#include <zdwm/bar.h>
|
||||
#include <zdwm/layout.h>
|
||||
#include <zdwm/listeners.h>
|
||||
#include <zdwm/rules.h>
|
||||
@@ -206,6 +207,14 @@ typedef struct zdwm_api_t {
|
||||
);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name bar 配置
|
||||
* @{ */
|
||||
void (*set_bar_config)(
|
||||
zdwm_config_builder_t *builder,
|
||||
zdwm_bar_config_t config
|
||||
);
|
||||
/** @} */
|
||||
} zdwm_api_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <cairo.h>
|
||||
#include <stddef.h>
|
||||
#include <zdwm/bar.h>
|
||||
#include <zdwm/types.h>
|
||||
@@ -7,6 +8,7 @@
|
||||
#include "bar/types.h"
|
||||
|
||||
typedef struct bar_output_t {
|
||||
cairo_t *cr;
|
||||
zdwm_window_id_t window_id;
|
||||
zdwm_output_id_t output_id;
|
||||
bar_side_t sides[ZDWM_BAR_SIDE_COUNT];
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stddef.h>
|
||||
#include <zdwm/bar.h>
|
||||
#include <zdwm/config.h>
|
||||
|
||||
#include "base/array.h"
|
||||
@@ -29,6 +30,7 @@ struct zdwm_config_builder_t {
|
||||
border_config_t border;
|
||||
binding_table_t *binding_table;
|
||||
listeners_t listeners;
|
||||
zdwm_bar_config_t bar;
|
||||
};
|
||||
|
||||
void runtime_config_cleanup(runtime_init_desc_t *desc) {
|
||||
@@ -279,6 +281,14 @@ static void runtime_config_subscribe_window_removed(
|
||||
listeners_add_window_removed_listener(&builder->listeners, fn, user_data);
|
||||
}
|
||||
|
||||
static void runtime_config_set_bar_config(
|
||||
zdwm_config_builder_t *builder,
|
||||
zdwm_bar_config_t config
|
||||
) {
|
||||
if (!builder) return;
|
||||
builder->bar = config;
|
||||
}
|
||||
|
||||
static bool config_builder_finish(
|
||||
zdwm_config_builder_t *builder,
|
||||
runtime_init_desc_t *out
|
||||
@@ -294,12 +304,14 @@ static bool config_builder_finish(
|
||||
out->workspaces = builder->workspaces;
|
||||
out->workspace_count = builder->workspace_count;
|
||||
out->listeners = builder->listeners;
|
||||
out->bar = builder->bar;
|
||||
builder->binding_table = nullptr;
|
||||
builder->workspaces = nullptr;
|
||||
builder->workspace_count = 0;
|
||||
builder->workspace_capacity = 0;
|
||||
builder->output_count = 0;
|
||||
p_clear(&builder->listeners, 1);
|
||||
p_clear(&builder->bar, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -342,6 +354,8 @@ static bool runtime_config_build(
|
||||
.subscribe_window_added = runtime_config_subscribe_window_added,
|
||||
.subscribe_window_updated = runtime_config_subscribe_window_updated,
|
||||
.subscribe_window_removed = runtime_config_subscribe_window_removed,
|
||||
|
||||
.set_bar_config = runtime_config_set_bar_config,
|
||||
};
|
||||
bool ok = setup(&api, &builder, outputs, output_count) &&
|
||||
config_builder_finish(&builder, out);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <zdwm/bar.h>
|
||||
#include <zdwm/types.h>
|
||||
|
||||
#include "core/backend.h"
|
||||
@@ -24,6 +25,7 @@ typedef struct runtime_init_desc_t {
|
||||
void *config_module_handle;
|
||||
binding_table_t *binding_table;
|
||||
listeners_t listeners;
|
||||
zdwm_bar_config_t bar;
|
||||
} runtime_init_desc_t;
|
||||
|
||||
bool runtime_config_load(const char *override_path, runtime_init_desc_t *out);
|
||||
|
||||
@@ -22,6 +22,7 @@ typedef enum command_type_t {
|
||||
ZDWM_COMMAND_SET_CURRENT_OUTPUT,
|
||||
ZDWM_COMMAND_SET_LAYOUT,
|
||||
ZDWM_COMMAND_SET_BINDING_MODE,
|
||||
ZDWM_COMMAND_SET_BAR_VISIBILITY,
|
||||
ZDWM_COMMAND_QUIT,
|
||||
} command_type_t;
|
||||
|
||||
@@ -64,6 +65,10 @@ typedef struct set_binding_mode_command_t {
|
||||
zdwm_binding_mode_id_t mode;
|
||||
} set_binding_mode_command_t;
|
||||
|
||||
typedef struct visibility_command_t {
|
||||
bool visible;
|
||||
} visibility_command_t;
|
||||
|
||||
typedef struct quit_command_t {
|
||||
bool will_restart;
|
||||
} quit_command_t;
|
||||
@@ -98,6 +103,7 @@ typedef struct command_t {
|
||||
set_current_output_command_t current_output;
|
||||
set_layout_command_t layout;
|
||||
set_binding_mode_command_t binding_mode;
|
||||
visibility_command_t bar_visibility;
|
||||
quit_command_t quit;
|
||||
} as;
|
||||
} command_t;
|
||||
|
||||
@@ -355,6 +355,19 @@ static void send_window_to_workspace_same_output_by_index(
|
||||
command_buffer_push(command_buffer, &send_window_to_workspace_command);
|
||||
}
|
||||
|
||||
static void toggle_bar_visibility(
|
||||
const policy_bar_t *bar,
|
||||
command_buffer_t *command_buffer
|
||||
) {
|
||||
command_t set_bar_visibility_command = {
|
||||
.type = ZDWM_COMMAND_SET_BAR_VISIBILITY,
|
||||
.as.bar_visibility = {
|
||||
.visible = !*bar->visible,
|
||||
},
|
||||
};
|
||||
command_buffer_push(command_buffer, &set_bar_visibility_command);
|
||||
}
|
||||
|
||||
static void policy_resolve_action(
|
||||
const policy_context_t *ctx,
|
||||
const zdwm_action_t *action,
|
||||
@@ -420,6 +433,9 @@ static void policy_resolve_action(
|
||||
case ZDWM_ACTION_WINDOW_CYCLE_OUTPUT:
|
||||
cycle_window_output(ctx->state, &action->as.window_cycle_output, out);
|
||||
break;
|
||||
case ZDWM_ACTION_BAR_TOGGLE_VISIBILITY:
|
||||
toggle_bar_visibility(&ctx->bar, out);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1365,6 +1381,34 @@ static void set_binding_mode(
|
||||
listeners_notify_binding_mode(ctx->listeners, ctx->bind_table);
|
||||
}
|
||||
|
||||
static void
|
||||
set_bar_visibility(const policy_context_t *ctx, bool visible, plan_t *plan) {
|
||||
auto bar = &ctx->bar;
|
||||
if (*bar->visible == visible) return;
|
||||
|
||||
*bar->visible = visible;
|
||||
|
||||
inset_t inset = {0};
|
||||
if (visible) {
|
||||
if (bar->show_top) inset.top = bar->height;
|
||||
else inset.bottom = bar->height;
|
||||
}
|
||||
|
||||
auto state = ctx->state;
|
||||
for (size_t i = 0; i < state->output_count; ++i) {
|
||||
auto output = state_output_at(state, i);
|
||||
state_output_inset_workarea(state, output->id, inset);
|
||||
}
|
||||
|
||||
auto push_effect = visible ? plan_push_map_effect : plan_push_unmap_effect;
|
||||
for (size_t i = 0; i < bar->windows->count; ++i) {
|
||||
auto window_id = bar->windows->windows[i];
|
||||
push_effect(plan, window_id);
|
||||
}
|
||||
|
||||
plan->need_relayout = true;
|
||||
}
|
||||
|
||||
void policy_apply_command(
|
||||
const policy_context_t *ctx,
|
||||
const command_buffer_t *command_buffer,
|
||||
@@ -1428,6 +1472,9 @@ void policy_apply_command(
|
||||
case ZDWM_COMMAND_SET_BINDING_MODE:
|
||||
set_binding_mode(ctx, cmd->as.binding_mode.mode, plan);
|
||||
break;
|
||||
case ZDWM_COMMAND_SET_BAR_VISIBILITY:
|
||||
set_bar_visibility(ctx, cmd->as.bar_visibility.visible, plan);
|
||||
break;
|
||||
case ZDWM_COMMAND_QUIT:
|
||||
plan->quit = true;
|
||||
plan->will_restart = cmd->as.quit.will_restart;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <zdwm/action.h>
|
||||
|
||||
#include "base/window_list.h"
|
||||
#include "core/binding.h"
|
||||
#include "core/command_buffer.h"
|
||||
#include "core/event.h"
|
||||
@@ -12,6 +14,13 @@
|
||||
#include "core/state.h"
|
||||
#include "core/types.h"
|
||||
|
||||
typedef struct policy_bar_t {
|
||||
bool *visible;
|
||||
window_list_t *windows;
|
||||
int32_t height;
|
||||
bool show_top;
|
||||
} policy_bar_t;
|
||||
|
||||
typedef struct policy_context_t {
|
||||
binding_table_t *bind_table;
|
||||
state_t *state;
|
||||
@@ -19,6 +28,7 @@ typedef struct policy_context_t {
|
||||
const listeners_t *listeners;
|
||||
const border_config_t *border;
|
||||
const layout_registry_t *layouts;
|
||||
const policy_bar_t bar;
|
||||
} policy_context_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -232,6 +232,22 @@ const output_t *state_output_at(const state_t *state, size_t index) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void state_output_inset_workarea(
|
||||
state_t *state,
|
||||
output_id_t output_id,
|
||||
inset_t inset
|
||||
) {
|
||||
auto output = (output_t *)state_output_get(state, output_id);
|
||||
if (!output) return;
|
||||
|
||||
auto workarea = output->geometry;
|
||||
workarea.y += inset.top;
|
||||
workarea.x += inset.left;
|
||||
workarea.width -= inset.left + inset.right;
|
||||
workarea.height -= inset.top + inset.bottom;
|
||||
output->workarea = workarea;
|
||||
}
|
||||
|
||||
void state_output_set_workarea(
|
||||
state_t *state,
|
||||
output_id_t output_id,
|
||||
|
||||
@@ -115,6 +115,30 @@ bool state_workspace_show(const state_t *state, workspace_id_t workspace_id);
|
||||
*/
|
||||
const output_t *state_output_get(const state_t *state, output_id_t id);
|
||||
const output_t *state_output_at(const state_t *state, size_t index);
|
||||
|
||||
typedef struct inset_t {
|
||||
int32_t top;
|
||||
int32_t right;
|
||||
int32_t bottom;
|
||||
int32_t left;
|
||||
} inset_t;
|
||||
|
||||
/**
|
||||
* @brief 按四边内缩量重新计算 output 的可用区域
|
||||
*
|
||||
* @details 以 output->geometry 为基准,各边向内收缩对应像素数,将结果写入
|
||||
* output->workarea。未设置的边默认为 0,表示该边不收缩。
|
||||
*
|
||||
* @param state 状态实例指针
|
||||
* @param output_id 目标 output 的 id
|
||||
* @param inset 四边内缩量(像素),值为 0 表示该边不收缩
|
||||
*/
|
||||
void state_output_inset_workarea(
|
||||
state_t *state,
|
||||
output_id_t output_id,
|
||||
inset_t inset
|
||||
);
|
||||
|
||||
void state_output_set_workarea(
|
||||
state_t *state,
|
||||
output_id_t output_id,
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
#include <stdint.h>
|
||||
#include <zdwm/layout.h>
|
||||
|
||||
#include "bar/bar.h"
|
||||
#include "base/array.h"
|
||||
#include "base/log.h"
|
||||
#include "base/memory.h"
|
||||
#include "base/window_list.h"
|
||||
#include "config/runtime_config.h"
|
||||
#include "core/backend.h"
|
||||
#include "core/binding.h"
|
||||
@@ -38,6 +40,9 @@ typedef struct runtime_t {
|
||||
void *config_module_handle;
|
||||
binding_table_t *binding_table;
|
||||
listeners_t listeners;
|
||||
|
||||
bar_t bar;
|
||||
window_list_t bar_windows;
|
||||
} runtime_t;
|
||||
|
||||
static bool runtime_workspace_desc_has_valid_layouts(
|
||||
@@ -82,10 +87,12 @@ static bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc) {
|
||||
runtime->config_module_handle = desc->config_module_handle;
|
||||
runtime->binding_table = desc->binding_table;
|
||||
runtime->listeners = desc->listeners;
|
||||
runtime->bar.config = desc->bar;
|
||||
desc->backend = nullptr;
|
||||
desc->config_module_handle = nullptr;
|
||||
desc->binding_table = nullptr;
|
||||
p_clear(&desc->listeners, 1);
|
||||
p_clear(&desc->bar, 1);
|
||||
|
||||
state_init(
|
||||
&runtime->state,
|
||||
@@ -137,6 +144,7 @@ static void runtime_shutdown(runtime_t *runtime) {
|
||||
binding_table_destroy(runtime->binding_table);
|
||||
runtime->binding_table = nullptr;
|
||||
listeners_cleanup(&runtime->listeners);
|
||||
window_list_cleanup(&runtime->bar_windows);
|
||||
backend_destroy(runtime->backend);
|
||||
runtime->backend = nullptr;
|
||||
if (runtime->config_module_handle) dlclose(runtime->config_module_handle);
|
||||
@@ -318,13 +326,20 @@ static void runtime_arrange(runtime_t *runtime) {
|
||||
|
||||
static policy_context_t policy_context_init(runtime_t *runtime) {
|
||||
policy_context_t ctx = {
|
||||
.bind_table = (runtime)->binding_table,
|
||||
.state = &(runtime)->state,
|
||||
.rules = &(runtime)->rules,
|
||||
.bind_table = runtime->binding_table,
|
||||
.state = &runtime->state,
|
||||
.rules = &runtime->rules,
|
||||
.listeners = &runtime->listeners,
|
||||
.border = &(runtime)->border,
|
||||
.layouts = &(runtime)->layouts,
|
||||
.border = &runtime->border,
|
||||
.layouts = &runtime->layouts,
|
||||
.bar = {
|
||||
.visible = &runtime->bar.visible,
|
||||
.windows = &runtime->bar_windows,
|
||||
.height = runtime->bar.config.height,
|
||||
.show_top = runtime->bar.config.show_top,
|
||||
},
|
||||
};
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user