Skip to content

feat(映射整理): 从映射格子拖到桌面 = 放回桌面 - #7

Draft
GOXF wants to merge 8 commits into
feat/organize-mode-settingfrom
feat/mapped-drag-to-desktop
Draft

GOXF wants to merge 8 commits into
feat/organize-mode-settingfrom
feat/mapped-drag-to-desktop

Conversation

@GOXF

@GOXF GOXF commented Nov 8, 2026

Copy link
Copy Markdown
Owner

问题

在映射格子里把项拖出到桌面没有任何效果:映射项本身就在桌面文件夹里,拖到桌面对资源管理器是同文件夹移动(无操作),项仍被隐藏、仍留在格子里。

改动

  • 拖放完成(CompleteDragItemsSession)时用光标位置判断目标。落在系统桌面空白处(Progman/WorkerW 下的 SHELLDLL_DefView/SysListView32,多显示器均可;须属于资源管理器进程,DeskBox 自己的窗口——包括嵌入 WorkerW 的格子——不算)时,对拖动的项(支持多选)执行「放回桌面」:取消映射、去掉 DeskBox 加的隐藏属性、标记留在桌面(与右键「放回桌面」同一 KeepOnDesktop),并显示同样的提示。
  • 图标放到松手位置:通过桌面 IFolderView.SelectAndPositionItems(IShellWindows → SID_STopLevelBrowser → QueryActiveShellView),第一个居中于光标,其余向下排成一列、到工作区底部换列;开启「自动排列图标」时跳过(「将图标与网格对齐」仍会吸附)。函数指针调 vtable,无 RCW,AOT 安全。
  • 保持原行为:落在桌面图标上(文件夹/回收站 = 真实移动)、其他文件夹、其他格子、移动模式格子;按 Esc 取消或完成时仍按住鼠标键(叠放弹层中途关闭)不触发。

文件

新增:FileSurfaceContent.MappedDragToDesktop.cs、Services/MappedDragToDesktopPolicy.cs(纯逻辑)、Services/MappedDragToDesktopTarget.cs(窗口探测)、Services/MappedDragToDesktopPlacement.cs(STA 轮询摆放)、Platform/DesktopIconPlacementNativeMethods.cs、tests/.../MappedDragToDesktopTests.cs。
上游文件只改 FileSurfaceContent.xaml.cs 一处调用(+6 行);未改 Strings/*.json(复用 fork 内联文案)。

测试

单元测试:目标窗口类名判定(桌面/资源管理器文件夹窗口/任务栏/DeskBox 自身/非 shell 进程)、是否放回、放回路径集合(去重、规范化、过滤不存在与非桌面路径)、图标位置计算。

已知限制

  • 未在真机桌面上运行验证(CI 只做构建和单元测试)。
  • 拖到已有桌面图标上不算放回;Esc 判定靠完成时按键状态,极快松开 Esc 可能漏判。
  • 若资源管理器对同文件夹的“复制”落点生成了副本(Win10 默认拖出为复制),副本由资源管理器产生,本改动不处理。
  • 已有缺口(非本 PR 引入):映射项拖到别的文件夹(移动/复制)后,映射关系和隐藏记录会被桌面监视器清理,但文件身上的隐藏属性会随文件带走,目标处看不见。

Base 说明

分支基于 dev(含 #5、#6),为避免指向 custom 时 diff 混入 #5(35 个文件),base 设为 feat/organize-mode-setting;diff 中仍会含 #6 与 dev 脚本的改动,本 PR 自身改动见最后一个提交。

GOXF added 8 commits November 8, 2026 05:38
仅当 DeskBox.exe 位于本地 git 克隆内(向上找到同时含 .git 与
scripts/fork-dev-update.ps1 的仓库根)时启用,正式安装版完全不受影响。

- Directory.Build.targets:Debug 构建时 git rev-parse,把提交 sha/分支写入
  AssemblyMetadata(ForkGitSha/ForkGitBranch);取不到时运行时读 .git。
- 启动后及每 30 分钟匿名请求 GitHub commits/dev,比较远端最新 sha,
  有新提交时发更新通知(沿用现有更新提示样式,点击打开 关于)。
- 设置「关于→更新详情」显示「本地测试版:当前 <短sha>,有新提交 …」与
  「更新并重启」按钮;点「检查更新」时同时检查该通道。
- 「更新并重启」以独立可见窗口运行 fork-dev-update.ps1 后退出 DeskBox;
  脚本新增 -GraceSeconds(先等 DeskBox 自行退出),失败时 Read-Host 暂停。
- 新增 ForkDevUpdateTests:仓库根探测、sha 比较、正式安装版不启用等。
映射项本身就在桌面文件夹里,拖到桌面对资源管理器是同文件夹移动(无操作),
项仍被隐藏、仍留在格子里。现在拖放完成时用光标位置判断目标:
- 落在系统桌面空白处(Progman/WorkerW 下的 SHELLDLL_DefView/SysListView32,
  多显示器均可;必须属于资源管理器进程、不是 DeskBox 自己的窗口)时,
  对拖动的项(支持多选)执行「放回桌面」:取消映射、去掉 DeskBox 加的隐藏属性、
  标记留在桌面。
- 通过桌面 IFolderView.SelectAndPositionItems 把图标放到松手位置
  (第一个居中于光标,其余向下排成一列);开启「自动排列图标」时跳过。
- 落在桌面图标上(文件夹/回收站)、其他文件夹、其他格子,以及移动模式格子,
  保持上游原行为;按 Esc 取消或仍按住鼠标键时不触发。

只新增文件,上游文件仅在 CompleteDragItemsSession 加一处调用。
附纯逻辑单元测试(目标窗口类名判定、放回路径集合、图标位置)。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant