feat(bar): 实现 bar 可见性切换 action
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user