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:
48
src/client.c
48
src/client.c
@@ -10,6 +10,7 @@
|
||||
#include "atoms-extern.h"
|
||||
#include "base.h"
|
||||
#include "monitor.h"
|
||||
#include "rect.h"
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
#include "wm.h"
|
||||
@@ -646,3 +647,50 @@ void client_stack_raise(client_t *client) {
|
||||
bool client_is_visible(client_t *client) {
|
||||
return client->tags & client->monitor->selected_tag->mask;
|
||||
}
|
||||
|
||||
static inline rect_t client_to_rect(client_t *client) {
|
||||
return (rect_t){
|
||||
.x1 = client->geometry.x,
|
||||
.y1 = client->geometry.y,
|
||||
.x2 = client->geometry.x + (int32_t)client_width(client),
|
||||
.y2 = client->geometry.y + (int32_t)client_height(client),
|
||||
};
|
||||
}
|
||||
|
||||
obscured_t client_get_obscured_state(client_t *client, client_t *client_stack) {
|
||||
if (!client || !client_stack) return obscured_none;
|
||||
|
||||
rect_t source = client_to_rect(client);
|
||||
size_t clip_count = 0;
|
||||
size_t clip_capacity = 0;
|
||||
rect_t *clips = nullptr;
|
||||
|
||||
bool has_overlap = false;
|
||||
for (client_t *c = client_stack; c; c = c->stack_next) {
|
||||
if (c == client) break;
|
||||
if (c->minimize || !client_is_visible(c)) continue;
|
||||
|
||||
rect_t clip = client_to_rect(c);
|
||||
if (!rect_intersection(source, clip, nullptr)) continue;
|
||||
|
||||
has_overlap = true;
|
||||
if (clip_count == clip_capacity) {
|
||||
clip_capacity = clip_capacity ? clip_capacity * 2 : 4;
|
||||
p_realloc(&clips, clip_capacity);
|
||||
}
|
||||
clips[clip_count++] = clip;
|
||||
}
|
||||
|
||||
if (!has_overlap) {
|
||||
p_delete(&clips);
|
||||
return obscured_none;
|
||||
}
|
||||
|
||||
rect_t *remaining = nullptr;
|
||||
size_t remaining_count =
|
||||
rect_subtract_many(source, clips, clip_count, &remaining);
|
||||
|
||||
p_delete(&clips);
|
||||
p_delete(&remaining);
|
||||
return remaining_count == 0 ? obscured_fully : obscured_partially;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user