feat(bar): 实现 bar 可见性切换 action

This commit is contained in:
2026-06-06 04:44:56 +08:00
parent be37b17c2e
commit adf839bf21
11 changed files with 152 additions and 5 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
/**

View File

@@ -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,

View File

@@ -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,