diff --git a/include/zdwm/config.h b/include/zdwm/config.h index 349380c..7592b8a 100644 --- a/include/zdwm/config.h +++ b/include/zdwm/config.h @@ -157,6 +157,14 @@ typedef struct zdwm_api_t { const char *focused ); + /** + * @brief 设置窗口移动和调整大小时的刷新率 + * + * @param builder 配置构建上下文 + * @param fps 刷新帧率,最小 10 帧,若设置小于 10 帧会设置为 10 帧 + */ + void (*set_refresh_fps)(zdwm_config_builder_t *builder, uint32_t fps); + /** @name Listener 注册 * @{ */ diff --git a/src/config/defaults.c b/src/config/defaults.c index 8d8b3f2..d55c7cf 100644 --- a/src/config/defaults.c +++ b/src/config/defaults.c @@ -167,6 +167,7 @@ bool config_defaults_build( api->set_default_mode(builder, default_mode); api->set_initial_mode(builder, default_mode); api->set_border_config(builder, 2, "#1c2022", "#606060"); + api->set_refresh_fps(builder, 30); zdwm_bar_config_t bar_config = { .height = 28, diff --git a/src/config/runtime_config.c b/src/config/runtime_config.c index ea08e0a..1563656 100644 --- a/src/config/runtime_config.c +++ b/src/config/runtime_config.c @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -28,6 +29,7 @@ struct zdwm_config_builder_t { size_t workspace_capacity; size_t output_count; border_config_t border; + uint32_t fps; binding_table_t *binding_table; listeners_t listeners; zdwm_bar_config_t bar; @@ -200,6 +202,11 @@ static void runtime_config_set_border_config( color_parse(focused, &builder->border.focused_color); } +static void +runtime_config_set_refresh_fps(zdwm_config_builder_t *builder, uint32_t fps) { + builder->fps = fps; +} + static void runtime_config_subscribe_current_output( zdwm_config_builder_t *builder, zdwm_current_output_id_listener *fn, @@ -300,6 +307,7 @@ static bool config_builder_finish( if (!layout_registry_move(&builder->layouts, &out->layouts)) return false; if (!rules_move(&builder->rules, &out->rules)) return false; out->border = builder->border; + out->fps = builder->fps; out->binding_table = builder->binding_table; out->workspaces = builder->workspaces; out->workspace_count = builder->workspace_count; @@ -342,6 +350,7 @@ static bool runtime_config_build( .set_default_mode = runtime_config_set_default_mode, .set_initial_mode = runtime_config_set_initial_mode, .set_border_config = runtime_config_set_border_config, + .set_refresh_fps = runtime_config_set_refresh_fps, .subscribe_current_output = runtime_config_subscribe_current_output, .subscribe_initial_workspace_list = diff --git a/src/config/runtime_config.h b/src/config/runtime_config.h index 69a1612..d360783 100644 --- a/src/config/runtime_config.h +++ b/src/config/runtime_config.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -20,6 +21,7 @@ typedef struct runtime_init_desc_t { layout_registry_t layouts; rules_t rules; border_config_t border; + uint32_t fps; workspace_desc_t *workspaces; size_t workspace_count; void *config_module_handle; diff --git a/src/core/policy.c b/src/core/policy.c index 6bbda75..c8be173 100644 --- a/src/core/policy.c +++ b/src/core/policy.c @@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/memory.h" #include "base/process.h" +#include "base/time.h" #include "base/window_list.h" #include "core/binding.h" #include "core/command.h" @@ -523,6 +524,10 @@ static void route_pointer_motion( case ZDWM_WINDOW_INTERACTION_NONE: break; case ZDWM_WINDOW_INTERACTION_MOVE: { + auto time = interaction->last_change_time; + auto now = time_monotonic_ms(); + if (now - time < 1000 / ctx->fps) break; + auto rect = interaction->origin_rect; auto start = interaction->start_coordinate; auto end = data->root; @@ -537,8 +542,14 @@ static void route_pointer_motion( }, }; command_buffer_push(out, &configure); + + interaction->last_change_time = now; } break; case ZDWM_WINDOW_INTERACTION_RESIZE: { + auto time = interaction->last_change_time; + auto now = time_monotonic_ms(); + if (now - time < 1000 / ctx->fps) break; + auto window = state_window_get(ctx->state, window_id); if (!window_can_resize(window)) break; @@ -569,6 +580,7 @@ static void route_pointer_motion( } }; command_buffer_push(out, &configure_cmd); + interaction->last_change_time = now; } break; } } diff --git a/src/core/policy.h b/src/core/policy.h index c5f7791..636e045 100644 --- a/src/core/policy.h +++ b/src/core/policy.h @@ -22,6 +22,7 @@ typedef struct policy_bar_t { } policy_bar_t; typedef struct policy_context_t { + uint32_t fps; window_interaction_state_t *interaction; binding_table_t *bind_table; state_t *state; diff --git a/src/core/types.h b/src/core/types.h index 261de4e..5418261 100644 --- a/src/core/types.h +++ b/src/core/types.h @@ -141,6 +141,7 @@ typedef struct window_interaction_state_t { window_id_t window; point_t start_coordinate; rect_t origin_rect; + uint64_t last_change_time; } window_interaction_state_t; static inline bool window_id_invalid(window_id_t window_id) { diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index e237b8e..c04b38b 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -44,6 +44,7 @@ typedef struct runtime_t { layout_registry_t layouts; rules_t rules; border_config_t border; + uint32_t fps; backend_t *backend; void *config_module_handle; binding_table_t *binding_table; @@ -138,6 +139,7 @@ static bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc) { rules_move(&desc->rules, &runtime->rules); runtime->signal_fd = -1; runtime->border = desc->border; + runtime->fps = MAX(desc->fps, 10); runtime->config_module_handle = desc->config_module_handle; runtime->binding_table = desc->binding_table; runtime->listeners = desc->listeners; @@ -402,6 +404,7 @@ static void runtime_arrange(runtime_t *runtime) { static policy_context_t policy_context_init(runtime_t *runtime) { policy_context_t ctx = { + .fps = runtime->fps, .interaction = &runtime->interaction, .bind_table = runtime->binding_table,