feat: 让 bar 支持点击触发动作
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <zdwm/action.h>
|
||||
#include <zdwm/bar.h>
|
||||
#include <zdwm/types.h>
|
||||
|
||||
@@ -394,3 +395,49 @@ bool bar_draw(bar_t *bar) {
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
bar_item_click(zdwm_bar_item_t *item, int32_t x, zdwm_action_t *action) {
|
||||
if (!(item->region.start <= x && item->region.end >= x)) return false;
|
||||
|
||||
if (!item->api.on_click) return true;
|
||||
|
||||
for (size_t i = 0; i < item->count; ++i) {
|
||||
auto cell = &item->cells[i];
|
||||
if (cell->region.start <= x && cell->region.end >= x) {
|
||||
*action = item->api.on_click(item, i, x, item->state);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
bar_side_click(bar_side_t *side, int32_t x, zdwm_action_t *action) {
|
||||
if (side->region.start > x || side->region.end < x) return false;
|
||||
|
||||
for (size_t i = 0; i < side->count; ++i) {
|
||||
if (bar_item_click(&side->items[i], x, action)) return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bar_click(
|
||||
bar_t *bar,
|
||||
zdwm_window_id_t window,
|
||||
int32_t x,
|
||||
zdwm_action_t *action
|
||||
) {
|
||||
for (size_t i = 0; i < bar->count; ++i) {
|
||||
auto bar_output = &bar->bars[i];
|
||||
if (bar_output->window_id != window) continue;
|
||||
|
||||
if (bar_side_click(&bar_output->left, x, action)) return true;
|
||||
if (bar_item_click(&bar_output->center, x, action)) return true;
|
||||
if (bar_side_click(&bar_output->right, x, action)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <cairo.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <zdwm/action.h>
|
||||
#include <zdwm/bar.h>
|
||||
#include <zdwm/types.h>
|
||||
|
||||
@@ -42,3 +43,9 @@ void bar_init(bar_t *bar, listeners_t *listeners);
|
||||
void bar_cleanup(bar_t *bar);
|
||||
void bar_update(bar_t *bar);
|
||||
bool bar_draw(bar_t *bar);
|
||||
bool bar_click(
|
||||
bar_t *bar,
|
||||
zdwm_window_id_t window,
|
||||
int32_t x,
|
||||
zdwm_action_t *action
|
||||
);
|
||||
|
||||
@@ -371,7 +371,7 @@ static void toggle_bar_visibility(
|
||||
command_buffer_push(command_buffer, &set_bar_visibility_command);
|
||||
}
|
||||
|
||||
static void policy_resolve_action(
|
||||
void policy_resolve_action(
|
||||
const policy_context_t *ctx,
|
||||
const zdwm_action_t *action,
|
||||
command_buffer_t *out
|
||||
|
||||
@@ -33,6 +33,12 @@ typedef struct policy_context_t {
|
||||
const policy_bar_t bar;
|
||||
} policy_context_t;
|
||||
|
||||
void policy_resolve_action(
|
||||
const policy_context_t *ctx,
|
||||
const zdwm_action_t *action,
|
||||
command_buffer_t *out
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief 事件路由:将运行时事件翻译为语义命令
|
||||
*
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <sys/poll.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <unistd.h>
|
||||
#include <zdwm/action.h>
|
||||
#include <zdwm/layout.h>
|
||||
|
||||
#include "bar/bar.h"
|
||||
@@ -456,10 +457,30 @@ static void runtime_scan(runtime_t *runtime) {
|
||||
listeners_notify_initial_windows(&runtime->listeners, &runtime->state);
|
||||
}
|
||||
|
||||
static bool runtime_handle_bar_click(
|
||||
const policy_context_t *ctx,
|
||||
const event_t *event,
|
||||
bar_t *bar,
|
||||
command_buffer_t *command_buffer
|
||||
) {
|
||||
if (event->type != ZDWM_EVENT_POINTER_BUTTON_PRESS) return false;
|
||||
|
||||
auto data = &event->as.pointer_button_press;
|
||||
|
||||
zdwm_action_t action = {.type = ZDWM_ACTION_NONE};
|
||||
if (bar_click(bar, data->window, data->local.x, &action)) {
|
||||
policy_resolve_action(ctx, &action, command_buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void runtime_handle_event(runtime_t *runtime, short int revents) {
|
||||
auto backend = runtime->backend;
|
||||
auto command_buffer = &runtime->command_buffer;
|
||||
auto plan = &runtime->plan;
|
||||
auto bar = &runtime->bar;
|
||||
auto ctx = policy_context_init(runtime);
|
||||
|
||||
if (revents & POLLHUP) {
|
||||
@@ -473,7 +494,10 @@ static void runtime_handle_event(runtime_t *runtime, short int revents) {
|
||||
command_buffer_reset(command_buffer);
|
||||
plan_reset(plan);
|
||||
|
||||
if (!runtime_handle_bar_click(&ctx, &event, bar, command_buffer)) {
|
||||
policy_route_event(&ctx, &event, command_buffer);
|
||||
}
|
||||
|
||||
policy_apply_command(&ctx, command_buffer, plan);
|
||||
if (plan->need_relayout) runtime_arrange(runtime);
|
||||
if (plan->count) backend_apply_effect(backend, plan->effects, plan->count);
|
||||
|
||||
Reference in New Issue
Block a user