feat: client 的任务栏标题点击行为根据 client 窗口的遮挡状态进行

- 当点击 client 在任务中的标题时,如果 client 被其他窗口遮挡,则将其显
示出来,否则切换其 minimize 属性
- 新增 rect 模块用于辅助判断 client 的遮挡状态,添加
rect_intersection/rect_subtract/rect_subtract_many 函数
- client 模块新增 client_get_obscured_state 计算 client 窗口被遮挡状态
- action 模块新增 change_client_state_dwim,实现上述的 client 状态切换
This commit is contained in:
2026-03-03 00:35:11 +08:00
parent 9b7c3a67ef
commit 41a2289c96
8 changed files with 280 additions and 1 deletions

41
src/rect.h Normal file
View File

@@ -0,0 +1,41 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
typedef struct rect_t {
int32_t x1;
int32_t y1;
int32_t x2;
int32_t y2;
} rect_t;
bool rect_intersection(rect_t a, rect_t b, rect_t *intersection);
size_t rect_subtract(rect_t source, rect_t clip, rect_t remaining[4]);
/**
* @brief 从 source 中按顺序减去 clips 中的多个矩形
* @param source 源矩形
* @param clips 要减去的矩形数组,可为 nullptr
* @param clip_count clips 的长度
* @param remaining 输出剩余矩形数组;若不为 nullptr则由函数分配内存并由调用方释放
* @return 剩余矩形数量
*
* @code{.c}
* rect_t source = {.x1 = 0, .y1 = 0, .x2 = 100, .y2 = 80};
* rect_t clips[] = {
* {.x1 = 10, .y1 = 10, .x2 = 40, .y2 = 40},
* {.x1 = 30, .y1 = 20, .x2 = 70, .y2 = 60},
* };
*
* rect_t *remaining = nullptr;
* size_t count = rect_subtract_many(source, clips, 2, &remaining);
*
* for (size_t i = 0; i < count; i++) {
* // use remaining[i]
* }
*
* free(remaining);
* @endcode
*/
size_t rect_subtract_many(rect_t source, const rect_t clips[],
size_t clip_count, rect_t **remaining);