-
Notifications
You must be signed in to change notification settings - Fork 55
chore: Re-implement the calculation method of exclusion zone #1227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
yixinshark
merged 1 commit into
linuxdeepin:master
from
yixinshark:fix-allExclusionZoneErrors
Aug 21, 2025
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,186 @@ | ||
| # 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混合坐标系统,确保在所有屏幕配置和缩放比例下都能准确计算独占区域。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (bug_risk): Potential for overflow or precision loss when casting to uint32_t.
Use a safe rounding method and validate for overflow before casting to uint32_t to prevent data loss.