feat: 添加核心状态变更通知系统

This commit is contained in:
2026-05-17 03:20:38 +08:00
parent 74be362b1f
commit 74319e97f1
10 changed files with 392 additions and 1 deletions

View File

@@ -45,6 +45,7 @@ add_executable(${APP_NAME}
${SOURCE_DIR}/core/event.c ${SOURCE_DIR}/core/event.c
${SOURCE_DIR}/core/layer.c ${SOURCE_DIR}/core/layer.c
${SOURCE_DIR}/core/layout.c ${SOURCE_DIR}/core/layout.c
${SOURCE_DIR}/core/listeners.c
${SOURCE_DIR}/core/plan.c ${SOURCE_DIR}/core/plan.c
${SOURCE_DIR}/core/policy.c ${SOURCE_DIR}/core/policy.c
${SOURCE_DIR}/core/rules.c ${SOURCE_DIR}/core/rules.c

View File

@@ -6,6 +6,7 @@
#include <stdint.h> #include <stdint.h>
#include <zdwm/action.h> #include <zdwm/action.h>
#include <zdwm/layout.h> #include <zdwm/layout.h>
#include <zdwm/listeners.h>
#include <zdwm/rules.h> #include <zdwm/rules.h>
#include <zdwm/types.h> #include <zdwm/types.h>
@@ -155,6 +156,57 @@ typedef struct zdwm_api_t {
const char *normal, const char *normal,
const char *focused const char *focused
); );
/** @name Listener 注册
* @{ */
void (*subscribe_current_output)(
zdwm_config_builder_t *builder,
zdwm_current_output_id_listener *fn,
void *user_data
);
void (*subscribe_initial_workspace_list)(
zdwm_config_builder_t *builder,
zdwm_initial_workspace_list *fn,
void *user_data
);
void (*subscribe_workspace_active)(
zdwm_config_builder_t *builder,
zdwm_workspace_active_updated *fn,
void *user_data
);
void (*subscribe_layout)(
zdwm_config_builder_t *builder,
zdwm_layout_notify *fn,
void *user_data
);
void (*subscribe_binding_mode)(
zdwm_config_builder_t *builder,
zdwm_binding_mode_notify *fn,
void *user_data
);
void (*subscribe_initial_window_list)(
zdwm_config_builder_t *builder,
zdwm_initial_window_list *fn,
void *user_data
);
void (*subscribe_window_added)(
zdwm_config_builder_t *builder,
zdwm_window_added *fn,
void *user_data
);
void (*subscribe_window_updated)(
zdwm_config_builder_t *builder,
zdwm_window_updated *fn,
void *user_data
);
void (*subscribe_window_removed)(
zdwm_config_builder_t *builder,
zdwm_window_removed *fn,
void *user_data
);
/** @} */
} zdwm_api_t; } zdwm_api_t;
/** /**

63
include/zdwm/listeners.h Normal file
View File

@@ -0,0 +1,63 @@
#ifndef ZDWM_LISTENERS_H
#define ZDWM_LISTENERS_H
#include <stddef.h>
#include <zdwm/types.h>
typedef void
zdwm_current_output_id_listener(zdwm_output_id_t output_id, void *user_data);
typedef struct zdwm_workspace_t {
zdwm_output_id_t output_id;
zdwm_workspace_id_t id;
const char *name; /* 不持有内存 */
} zdwm_workspace_t;
typedef void zdwm_initial_workspace_list(
const zdwm_workspace_t *list,
size_t count,
void *user_data
);
typedef void zdwm_workspace_active_updated(
zdwm_output_id_t output_id,
zdwm_workspace_id_t workspace_id,
void *user_data
);
typedef struct zdwm_layout_notify_t {
zdwm_workspace_id_t workspace;
zdwm_layout_id_t id;
const char *symbol; /* 不持有内存 */
} zdwm_layout_notify_t;
typedef void zdwm_layout_notify(zdwm_layout_notify_t layout, void *user_data);
typedef struct zdwm_binding_mode_notify_t {
bool is_default_mode;
bool is_current_mode;
zdwm_binding_mode_id_t id;
const char *name; /* 不持有内存 */
} zdwm_binding_mode_notify_t;
typedef void zdwm_binding_mode_notify(
zdwm_binding_mode_notify_t binding_mode,
void *user_data
);
typedef struct zdwm_window_t {
zdwm_workspace_id_t workspace;
zdwm_window_id_t id;
const char *title; /* 不持有内存 */
bool focused;
bool urgent;
bool skip_taskbar;
} zdwm_window_t;
typedef void zdwm_initial_window_list(
const zdwm_window_t *list,
size_t count,
void *user_data
);
typedef void zdwm_window_added(const zdwm_window_t *window, void *user_data);
typedef void zdwm_window_updated(const zdwm_window_t *window, void *user_data);
typedef void zdwm_window_removed(zdwm_window_id_t window_id, void *user_data);
typedef struct zdwm_listeners_t zdwm_listeners_t;
#endif /* ZDWM_LISTENERS_H */

View File

@@ -7,6 +7,7 @@
extern "C" { extern "C" {
#endif #endif
typedef uint32_t zdwm_output_id_t;
typedef uint32_t zdwm_layout_id_t; typedef uint32_t zdwm_layout_id_t;
typedef uint32_t zdwm_window_id_t; typedef uint32_t zdwm_window_id_t;
typedef uint32_t zdwm_workspace_id_t; typedef uint32_t zdwm_workspace_id_t;

View File

@@ -11,6 +11,7 @@
#include "config/loader.h" #include "config/loader.h"
#include "core/binding.h" #include "core/binding.h"
#include "core/layout.h" #include "core/layout.h"
#include "core/listeners.h"
#include "core/rules.h" #include "core/rules.h"
#include "core/runtime.h" #include "core/runtime.h"
#include "core/types.h" #include "core/types.h"
@@ -28,6 +29,7 @@ struct zdwm_config_builder_t {
size_t output_count; size_t output_count;
border_config_t border; border_config_t border;
binding_table_t *binding_table; binding_table_t *binding_table;
listeners_t listeners;
}; };
void runtime_config_cleanup(runtime_init_desc_t *desc) { void runtime_config_cleanup(runtime_init_desc_t *desc) {
@@ -196,6 +198,87 @@ static void runtime_config_set_border_config(
color_parse(focused, &builder->border.focused_color); color_parse(focused, &builder->border.focused_color);
} }
static void runtime_config_subscribe_current_output(
zdwm_config_builder_t *builder,
zdwm_current_output_id_listener *fn,
void *user_data
) {
if (!builder || !fn) return;
listeners_add_output_listener(&builder->listeners, fn, user_data);
}
static void runtime_config_subscribe_initial_workspace_list(
zdwm_config_builder_t *builder,
zdwm_initial_workspace_list *fn,
void *user_data
) {
if (!builder || !fn) return;
listeners_add_initial_workspace_listener(&builder->listeners, fn, user_data);
}
static void runtime_config_subscribe_workspace_active(
zdwm_config_builder_t *builder,
zdwm_workspace_active_updated *fn,
void *user_data
) {
if (!builder || !fn) return;
listeners_add_active_workspace_listener(&builder->listeners, fn, user_data);
}
static void runtime_config_subscribe_layout(
zdwm_config_builder_t *builder,
zdwm_layout_notify *fn,
void *user_data
) {
if (!builder || !fn) return;
listeners_add_layout_notify(&builder->listeners, fn, user_data);
}
static void runtime_config_subscribe_binding_mode(
zdwm_config_builder_t *builder,
zdwm_binding_mode_notify *fn,
void *user_data
) {
if (!builder || !fn) return;
listeners_add_binding_mode_notify(&builder->listeners, fn, user_data);
}
static void runtime_config_subscribe_initial_window_list(
zdwm_config_builder_t *builder,
zdwm_initial_window_list *fn,
void *user_data
) {
if (!builder || !fn) return;
listeners_add_initial_window_listener(&builder->listeners, fn, user_data);
}
static void runtime_config_subscribe_window_added(
zdwm_config_builder_t *builder,
zdwm_window_added *fn,
void *user_data
) {
if (!builder || !fn) return;
listeners_add_window_added_listener(&builder->listeners, fn, user_data);
}
static void runtime_config_subscribe_window_updated(
zdwm_config_builder_t *builder,
zdwm_window_updated *fn,
void *user_data
) {
if (!builder || !fn) return;
listeners_add_window_updated_listener(&builder->listeners, fn, user_data);
}
static void runtime_config_subscribe_window_removed(
zdwm_config_builder_t *builder,
zdwm_window_removed *fn,
void *user_data
) {
if (!builder || !fn) return;
listeners_add_window_removed_listener(&builder->listeners, fn, user_data);
}
static bool config_builder_finish( static bool config_builder_finish(
zdwm_config_builder_t *builder, zdwm_config_builder_t *builder,
runtime_init_desc_t *out runtime_init_desc_t *out
@@ -210,11 +293,13 @@ static bool config_builder_finish(
out->binding_table = builder->binding_table; out->binding_table = builder->binding_table;
out->workspaces = builder->workspaces; out->workspaces = builder->workspaces;
out->workspace_count = builder->workspace_count; out->workspace_count = builder->workspace_count;
out->listeners = builder->listeners;
builder->binding_table = nullptr; builder->binding_table = nullptr;
builder->workspaces = nullptr; builder->workspaces = nullptr;
builder->workspace_count = 0; builder->workspace_count = 0;
builder->workspace_capacity = 0; builder->workspace_capacity = 0;
builder->output_count = 0; builder->output_count = 0;
p_clear(&builder->listeners, 1);
return true; return true;
} }
@@ -245,6 +330,18 @@ static bool runtime_config_build(
.set_default_mode = runtime_config_set_default_mode, .set_default_mode = runtime_config_set_default_mode,
.set_initial_mode = runtime_config_set_initial_mode, .set_initial_mode = runtime_config_set_initial_mode,
.set_border_config = runtime_config_set_border_config, .set_border_config = runtime_config_set_border_config,
.subscribe_current_output = runtime_config_subscribe_current_output,
.subscribe_initial_workspace_list =
runtime_config_subscribe_initial_workspace_list,
.subscribe_workspace_active = runtime_config_subscribe_workspace_active,
.subscribe_layout = runtime_config_subscribe_layout,
.subscribe_binding_mode = runtime_config_subscribe_binding_mode,
.subscribe_initial_window_list =
runtime_config_subscribe_initial_window_list,
.subscribe_window_added = runtime_config_subscribe_window_added,
.subscribe_window_updated = runtime_config_subscribe_window_updated,
.subscribe_window_removed = runtime_config_subscribe_window_removed,
}; };
bool ok = setup(&api, &builder, outputs, output_count) && bool ok = setup(&api, &builder, outputs, output_count) &&
config_builder_finish(&builder, out); config_builder_finish(&builder, out);

83
src/core/listeners.c Normal file
View File

@@ -0,0 +1,83 @@
#include "core/listeners.h"
#include "base/array.h"
#define ADD_LISTENER(FIELD) \
auto list = &listeners->FIELD; \
auto item = array_push(list->items, list->count, list->capacity); \
item->fn = fn; \
item->user_data = user_data
void listeners_add_output_listener(
listeners_t *listeners,
zdwm_current_output_id_listener fn,
void *user_data
) {
ADD_LISTENER(output_listeners);
}
void listeners_add_initial_workspace_listener(
listeners_t *listeners,
zdwm_initial_workspace_list fn,
void *user_data
) {
ADD_LISTENER(initial_workspace_listeners);
}
void listeners_add_active_workspace_listener(
listeners_t *listeners,
zdwm_workspace_active_updated fn,
void *user_data
) {
ADD_LISTENER(active_workspace_listeners);
}
void listeners_add_layout_notify(
listeners_t *listeners,
zdwm_layout_notify fn,
void *user_data
) {
ADD_LISTENER(layout_listeners);
}
void listeners_add_binding_mode_notify(
listeners_t *listeners,
zdwm_binding_mode_notify fn,
void *user_data
) {
ADD_LISTENER(binding_mode_listeners);
}
void listeners_add_initial_window_listener(
listeners_t *listeners,
zdwm_initial_window_list fn,
void *user_data
) {
ADD_LISTENER(initial_window_listeners);
}
void listeners_add_window_added_listener(
listeners_t *listeners,
zdwm_window_added fn,
void *user_data
) {
ADD_LISTENER(window_added_listeners);
}
void listeners_add_window_updated_listener(
listeners_t *listeners,
zdwm_window_updated fn,
void *user_data
) {
ADD_LISTENER(window_updated_listeners);
}
void listeners_add_window_removed_listener(
listeners_t *listeners,
zdwm_window_removed fn,
void *user_data
) {
ADD_LISTENER(window_removed_listeners);
}
#undef ADD_LISTENER

89
src/core/listeners.h Normal file
View File

@@ -0,0 +1,89 @@
#pragma once
#include <stddef.h>
#include <zdwm/listeners.h>
#define ITEM(NAME, FN_TYPE) \
typedef struct NAME##_listener_item_t { \
FN_TYPE *fn; \
void *user_data; \
} NAME##_listener_item_t
#define LISTENERS(NAME, FN_TYPE) \
ITEM(NAME, FN_TYPE); \
typedef struct NAME##_listeners_t { \
NAME##_listener_item_t *items; \
size_t count; \
size_t capacity; \
} NAME##_listeners_t
LISTENERS(output, zdwm_current_output_id_listener);
LISTENERS(initial_workspace_list, zdwm_initial_workspace_list);
LISTENERS(workspace_active, zdwm_workspace_active_updated);
LISTENERS(layout, zdwm_layout_notify);
LISTENERS(binding_mode, zdwm_binding_mode_notify);
LISTENERS(initial_window_list, zdwm_initial_window_list);
LISTENERS(window_added, zdwm_window_added);
LISTENERS(window_updated, zdwm_window_updated);
LISTENERS(window_removed, zdwm_window_removed);
#undef ITEM
#undef LISTENERS
typedef struct zdwm_listeners_t {
output_listeners_t output_listeners;
initial_workspace_list_listeners_t initial_workspace_listeners;
workspace_active_listeners_t active_workspace_listeners;
layout_listeners_t layout_listeners;
binding_mode_listeners_t binding_mode_listeners;
initial_window_list_listeners_t initial_window_listeners;
window_added_listeners_t window_added_listeners;
window_updated_listeners_t window_updated_listeners;
window_removed_listeners_t window_removed_listeners;
} listeners_t;
void listeners_add_output_listener(
listeners_t *listeners,
zdwm_current_output_id_listener fn,
void *user_data
);
void listeners_add_initial_workspace_listener(
listeners_t *listeners,
zdwm_initial_workspace_list fn,
void *user_data
);
void listeners_add_active_workspace_listener(
listeners_t *listeners,
zdwm_workspace_active_updated fn,
void *user_data
);
void listeners_add_layout_notify(
listeners_t *listeners,
zdwm_layout_notify fn,
void *user_data
);
void listeners_add_binding_mode_notify(
listeners_t *listeners,
zdwm_binding_mode_notify fn,
void *user_data
);
void listeners_add_initial_window_listener(
listeners_t *listeners,
zdwm_initial_window_list fn,
void *user_data
);
void listeners_add_window_added_listener(
listeners_t *listeners,
zdwm_window_added fn,
void *user_data
);
void listeners_add_window_updated_listener(
listeners_t *listeners,
zdwm_window_updated fn,
void *user_data
);
void listeners_add_window_removed_listener(
listeners_t *listeners,
zdwm_window_removed fn,
void *user_data
);

View File

@@ -62,9 +62,11 @@ bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc) {
runtime->border = desc->border; runtime->border = desc->border;
runtime->config_module_handle = desc->config_module_handle; runtime->config_module_handle = desc->config_module_handle;
runtime->binding_table = desc->binding_table; runtime->binding_table = desc->binding_table;
runtime->listeners = desc->listeners;
desc->backend = nullptr; desc->backend = nullptr;
desc->config_module_handle = nullptr; desc->config_module_handle = nullptr;
desc->binding_table = nullptr; desc->binding_table = nullptr;
p_clear(&desc->listeners, 1);
state_init( state_init(
&runtime->state, &runtime->state,

View File

@@ -7,6 +7,7 @@
#include "core/binding.h" #include "core/binding.h"
#include "core/command_buffer.h" #include "core/command_buffer.h"
#include "core/layout.h" #include "core/layout.h"
#include "core/listeners.h"
#include "core/plan.h" #include "core/plan.h"
#include "core/rules.h" #include "core/rules.h"
#include "core/state.h" #include "core/state.h"
@@ -24,6 +25,7 @@ typedef struct runtime_init_desc_t {
size_t workspace_count; size_t workspace_count;
void *config_module_handle; void *config_module_handle;
binding_table_t *binding_table; binding_table_t *binding_table;
listeners_t listeners;
} runtime_init_desc_t; } runtime_init_desc_t;
typedef struct zdwm_runtime_t { typedef struct zdwm_runtime_t {
@@ -40,6 +42,7 @@ typedef struct zdwm_runtime_t {
backend_t *backend; backend_t *backend;
void *config_module_handle; void *config_module_handle;
binding_table_t *binding_table; binding_table_t *binding_table;
listeners_t listeners;
} runtime_t; } runtime_t;
bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc); bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc);

View File

@@ -10,7 +10,7 @@
typedef zdwm_layout_id_t layout_id_t; typedef zdwm_layout_id_t layout_id_t;
typedef zdwm_window_id_t window_id_t; typedef zdwm_window_id_t window_id_t;
typedef zdwm_workspace_id_t workspace_id_t; typedef zdwm_workspace_id_t workspace_id_t;
typedef uint32_t output_id_t; typedef zdwm_output_id_t output_id_t;
typedef zdwm_rect_t rect_t; typedef zdwm_rect_t rect_t;
typedef zdwm_output_info_t output_info_t; typedef zdwm_output_info_t output_info_t;