---
# SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd.
#
# SPDX-License-Identifier: CC-BY-4.0
---
# DDE-Shell 独占区域计算规则

## 概述

独占区域（Exclusion Zone）用于向窗口管理器声明面板/任务栏需要保留的屏幕空间，确保其他窗口不会覆盖在任务栏上。

## 关键概念

### Qt混合坐标系统
- **X/Y坐标**: 物理像素坐标（不需要缩放转换）
- **宽度/高度**: 逻辑像素尺寸（需要乘以缩放系数转换为物理像素）

### 计算公式
```
独占区域 = 屏幕边界距离（物理像素) + 任务栏尺寸（物理像素）
物理像素 = 逻辑像素 × 缩放系数
```

## 布局示意图

### 垂直布局（1K屏上方 + 2K屏下方，2倍缩放）
```
实际拼接布局（控制中心的示意图）:

       ┌──────────┐
       │   1K屏   │
      ┌┴──────────┤──────────
      │        2K屏          │
      │                      │
      └──────────────────────┘

屏幕坐标信息：
• 1K屏幕: (265, 0, 960, 540)    - 物理区域: (265,0) 到 (2185,540)
• 2K屏幕: (0, 1080, 1280, 720)  - 物理区域: (0,1080) 到 (2560,1800)

假设：任务栏停靠屏幕下边缘的时候，1倍缩放高度为40

任务栏在1K屏右侧计算：
- 1K屏物理右边界: 265 + (960×2) = 2185
- 桌面物理右边界: 为2k最大宽度 = 2560  
- 距离: 2560 - 2185 = 375
- 独占区域: 375 + 80 = 455
```

### 水平布局（2K屏左侧 + 1K屏右侧，下边缘对齐，2倍缩放）
```
实际拼接布局（控制中心的示意图）:

   ┌───────────┬
   │           │              
   │   2K屏    │                 
   │           │                
   │           ┌─────────────────┤
   │           │     1K屏        │
   │           │                 │
   └───────────┴─────────────────┘

屏幕坐标信息：
• 2K屏幕: (0, 0, 1280, 720)      - 物理区域: (0,0) 到 (2560,1440)
• 1K屏幕: (2560, 360, 960, 540)  - 物理区域: (2560,360) 到 (4480,1440)

假设：任务栏停靠屏幕下边缘的时候，1倍缩放高度为40

任务栏在2K屏下边计算：
- 2K屏物理底边: 0 + (720×2) = 1440
- 1K屏物理底边: 360 + (540×2) = 1440
- 桌面物理底边: max(1440, 1440) = 1440
- 距离: 1440 - 1440 = 0（下边缘对齐）
- 独占区域: 0 + 80 = 80
```

## 各锚定类型计算规则

### AnchorLeft（左侧）
```cpp
strut_partial.left = screenX + exclusionZone × scaleFactor
```
- **screenX**: 屏幕X坐标（物理像素）
- **示例**: 1K屏(265,0) 左侧任务栏 = 265 + (40×2) = 345

### AnchorRight（右侧）  
```cpp
desktopRightBoundary = max(所有屏幕的物理右边界)
currentScreenRight = screenX + screenWidth × scaleFactor  
distance = desktopRightBoundary - currentScreenRight
strut_partial.right = distance + exclusionZone × scaleFactor
```
- **复杂度**: 需计算到整个桌面右边界的距离
- **示例**: 1K屏(265,0) 右侧任务栏 = (2560-2185) + 80 = 455

### AnchorTop（上边）
```cpp
strut_partial.top = screenY + exclusionZone × scaleFactor
```
- **screenY**: 屏幕Y坐标（物理像素）
- **示例**: 1K屏(265,0) 上边任务栏 = 0 + (40×2) = 80

### AnchorBottom（下边）
```cpp
// 优先查找下方重叠屏幕
if (找到下方屏幕) {
    strut_partial.bottom = belowScreensHeight × scaleFactor + exclusionZone × scaleFactor
} else {
    // 回退算法：计算到桌面底边的距离
    desktopBottomBoundary = max(所有屏幕的物理底边界)
    distance = desktopBottomBoundary - currentScreenBottom
    strut_partial.bottom = distance + exclusionZone × scaleFactor
}
```
- **垂直布局示例**: 1K屏(265,0) 下边任务栏 = (720×2) + 80 = 1520
- **水平布局示例**: 2K屏(0,0) 下边任务栏 = 0 + 80 = 80

## 关键特性

### 布局兼容性
- ✅ **垂直布局**: 屏幕上下排列
- ✅ **水平布局**: 屏幕左右排列  
- ✅ **混合布局**: 复杂屏幕排列
- ✅ **单屏配置**: 独占区域仅为任务栏尺寸

### 缩放支持
- ✅ **1.0x**: 无缩放
- ✅ **1.5x**: 高DPI显示器
- ✅ **2.0x**: 超高DPI显示器
- ✅ **任意比例**: 自动适应

### 边界处理
- **智能检测**: 自动识别屏幕位置关系
- **重叠判断**: 准确计算屏幕间的重叠区域
- **回退机制**: 处理特殊配置和边界情况

## 坐标系统示例

### 实际系统配置
```
QScreen::geometry() 返回值（垂直布局示例）:
- 1K屏幕: (265, 0, 960, 540)     // X/Y物理坐标，宽度/高度逻辑像素
- 2K屏幕: (0, 1080, 1280, 720)   // X/Y物理坐标，宽度/高度逻辑像素

转换为完整物理坐标区域:
- 1K屏幕: 物理区域 (265, 0) 到 (2185, 540)
- 2K屏幕: 物理区域 (0, 1080) 到 (2560, 1800)

QScreen::geometry() 返回值（水平布局示例）:
- 2K屏幕: (0, 0, 1280, 720)      // X/Y物理坐标，宽度/高度逻辑像素  
- 1K屏幕: (2560, 360, 960, 540)  // X/Y物理坐标，宽度/高度逻辑像素

转换为完整物理坐标区域:
- 2K屏幕: 物理区域 (0, 0) 到 (2560, 1440)
- 1K屏幕: 物理区域 (2560, 360) 到 (4480, 1440)
```

### 关键公式验证
```
用户验证公式（1K屏(265,0)右侧任务栏，任务栏宽度40逻辑像素）:
2560 - 265 - 1920 + 80 = 455 ✓

算法计算过程:
- 1K屏左上角坐标: (265, 0)
- 桌面右边界: 2560
- 1K屏右边界: 265 + (960×2) = 2185  
- 距离: 2560 - 2185 = 375
- 独占区域: 375 + (40×2) = 455 ✓
```

## 调试信息

### 简化日志格式
```
假设任务栏尺寸：40逻辑像素

AnchorLeft: screen.x=265 exclusionZone=40 result=345
AnchorRight: desktopRightBoundary=2560 currentScreenRight=2185 distance=375 result=455
AnchorTop: screen.y=0 exclusionZone=40 result=80  
AnchorBottom: belowScreensHeight=720 exclusionZone=40 result=1520
```

### 最终汇总
```
示例输出（基于任务栏40逻辑像素）:
update exclusion zone, winId:123456, (left, right, top, bottom) 345 455 80 1520
```

---

**注意**: 本算法完全支持Qt混合坐标系统，确保在所有屏幕配置和缩放比例下都能准确计算独占区域。
