Skip to content

Bug fix 5 21#844

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
dengzhongyuan365-dev:bug-fix-5-21
May 25, 2026
Merged

Bug fix 5 21#844
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
dengzhongyuan365-dev:bug-fix-5-21

Conversation

@dengzhongyuan365-dev

Copy link
Copy Markdown
Member

fix(pin_screenshot): adapt toolbar and window management for Treeland compositor

- Add isTreelandMode flag with case-insensitive DDE_CURRENT_COMPOSITOR check
- Use QSurfaceFormat alpha buffer for Treeland before QApplication creation
- Move DGuiApplicationHelper palette setup after QApplication to fix Treeland crash
- Make toolbar a subsurface of the main pin window via QWindow::setParent
- Replace DBlurEffectWidget blur with custom QPainter rounded-rect background
  (DBlur is non-functional under Treeland subsurface)
- Use startSystemMove() / windowHandle()->setPosition() for drag & key move
- Fix geometry() vs mapFromGlobal() coordinate mismatch for toolbar hit-test

TASK: https://pms.uniontech.com/task-view-389563.html

@dengzhongyuan365-dev dengzhongyuan365-dev force-pushed the bug-fix-5-21 branch 3 times, most recently from b00265f to bb39392 Compare May 22, 2026 07:16
… compositor

- Add isTreelandMode flag with case-insensitive DDE_CURRENT_COMPOSITOR check
- Use QSurfaceFormat alpha buffer for Treeland before QApplication creation
- Move DGuiApplicationHelper palette setup after QApplication to fix Treeland crash
- Make toolbar a subsurface of the main pin window via QWindow::setParent
- Replace DBlurEffectWidget blur with custom QPainter rounded-rect background
  (DBlur is non-functional under Treeland subsurface)
- Use startSystemMove() / windowHandle()->setPosition() for drag & key move
- Fix geometry() vs mapFromGlobal() coordinate mismatch for toolbar hit-test

新增 isTreelandMode 标志,通过 DDE_CURRENT_COMPOSITOR 环境变量判断合成器类型。
Treeland 模式下:设置 QSurfaceFormat alpha 缓冲、调整 DGuiApplicationHelper
调色板初始化顺序避免崩溃、将工具栏设为主窗口子表面替代独立窗口、用 QPainter
自定义圆角背景替代 DBlurEffectWidget、使用 startSystemMove() 实现拖拽移动、
修复工具栏命中测试的坐标计算偏差。

Log: 修复截图钉图功能在Treeland合成器下工具栏显示异常和窗口管理问题

PMS: TASK-389563

Influence: 修复后截图钉图功能可在Treeland合成器下正常使用,工具栏正确显示并支持拖拽移动
lzwind
lzwind previously approved these changes May 22, 2026
@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: dengzhongyuan365-dev

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

1 similar comment
@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: dengzhongyuan365-dev

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

这份 Git Diff 包含了对深度截图录屏工具的诸多重要更新,主要集中在 Treeland(Wayland合成器)适配、X11 下 Dock Grab 导致事件丢失的修复、截图窗口列表获取时机的优化,以及贴图功能的 D-Bus 异步化改造

整体来看,代码逻辑清晰,注释详尽,解决了实际场景中的复杂问题。但在语法逻辑、代码质量和安全性方面,仍有进一步优化的空间。以下是详细的审查意见:

一、 语法与逻辑

  1. Qt 鼠标事件构造参数不准确(高风险)

    • 位置src/main_window.cpp 中的 onMouseDragonMousePressonMouseReleaseonMouseMove
    • 问题:在 Qt5/6 中,QMouseEvent 的构造函数区分了 pos(相对组件的坐标)和 globalPos(全局屏幕坐标)。当前代码仅传入了 QPoint(x, y) 作为 localPos,而 globalPos 默认会被设置为与 localPos 相同的值,这在窗口不在屏幕 (0,0) 位置时会导致坐标体系混乱。此外,鼠标移动事件的 Button 状态设置不一致(有的设为 Qt::LeftButton,有的设为 Qt::NoButton)。
    • 建议:明确传入全局坐标,并根据事件类型正确设置按键状态。
    // 以 onMousePress 为例
    QPoint globalPos(x, y);
    // 建议使用 this->mapFromGlobal(globalPos) 获取局部坐标,若此逻辑在主窗口,且 x/y 本身就是全局坐标,可直接用
    QMouseEvent *mousePress = new QMouseEvent(QEvent::MouseButtonPress, globalPos, globalPos, 
                                              Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
  2. isFirstMove 逻辑可能被永久跳过

    • 位置src/main_window.cpponMouseMove 中。
    • 问题:原逻辑中 !isFirstMove 用于保证“第一次移动”的特殊处理只执行一次。现在条件改为了 !isFirstMove || inShotHoverPhase。如果 inShotHoverPhase 持续为真,即使 isFirstMove 已经变为 true,该代码块依然会不断进入。如果内部逻辑对“第一次”有依赖,可能会引发异常。
    • 建议:确认内部逻辑是否需要严格区分“首次”和“悬停”。如果只是需要发送 MouseMove,当前逻辑可以接受;但如果内部有依赖 isFirstMove 状态变更的副作用,建议将首次逻辑单独前置:
    if (!isFirstMove) {
        // 单独处理首次移动的特殊逻辑
    }
    if (!isFirstMove || inShotHoverPhase) {
        // 处理鼠标事件转发
    }
  3. QWindow::setPosition 在 Wayland 下无效

    • 位置src/pin_screenshots/mainwindow.cppapplyWindowMove lambda。
    • 问题:Wayland 协议出于安全考虑,不允许客户端主动设置窗口的绝对位置。windowHandle()->setPosition(nx, ny) 在 Wayland/Treeland 下大概率会被合成器忽略,或者产生警告。
    • 建议:对于 Treeland 模式,既然前面已经使用了 startSystemMove(),键盘移动也应该通过合成器的移动协议进行,或者确保 Treeland 确实扩展了 Qt 的 XdgShell 移动能力。否则键盘方向键移动贴图的功能在 Treeland 下将失效。

二、 代码质量

  1. 内存泄漏风险(QMouseEvent)

    • 位置:所有 new QMouseEvent(...) 的地方。
    • 问题:使用 new 创建事件后,通过 sendEvent 发送,然后手动 delete。如果 sendEvent 内部抛出异常或提前返回,可能导致内存泄漏。
    • 建议:使用 QScopedPointerstd::unique_ptr 管理事件生命周期。
    QScopedPointer<QMouseEvent> mousePress(new QMouseEvent(...));
    QApplication::sendEvent(this, mousePress.data());
    // 自动析构,无需 delete
  2. 魔法数字

    • 位置src/pin_screenshots/ui/toolbarwidget.cpppaintEvent 中。
    • 问题QColor(237, 237, 237, 255)QColor(48, 48, 48, 255) 以及 radius = 16.0 是硬编码的魔法数字,不利于主题统一管理和后期维护。
    • 建议:提取为类的常量成员或配置变量,并与 DTK 的调色板系统(如 DGuiApplicationHelper 的颜色接口)对齐。
  3. D-Bus 成功日志级别不当

    • 位置src/main_window.cppchangeShotToolEvent 中。
    • 问题qCWarning(dsrApp) << "[PIN_DIAG] D-Bus openImageAndName succeeded"; 成功的日志使用了 qCWarning(警告级别),这会污染生产环境的警告日志。
    • 建议:将成功的日志降级为 qCInfoqCDebug
    qCInfo(dsrApp) << "[PIN_DIAG] D-Bus openImageAndName succeeded";
  4. isFirstPressButton 状态竞争

    • 位置onMousePress 中的 !isFirstPressButton 判断。
    • 问题:注释中提到“利用 QueuedConnection 的时序”,但 XRecord 的事件回调与 Qt 的事件循环在多线程/多处理层级下,时序并不绝对稳定。如果 XRecord 抢先于 Qt 原生事件到达,isFirstPressButton 仍为 false,会导致补发事件,随后 Qt 原生事件再到达时,可能导致双重触发。
    • 建议:增加防抖逻辑或更严谨的标志位(如增加一个 x11EventProcessed 标志),确保不会因为底层时序抖动导致双击。

三、 代码性能

  1. 频繁的 toImage() 转换

    • 位置src/main_window.cppchangeShotToolEvent 中。
    • 问题m_resultPixmap.toImage() 会触发底层数据从 GPU 显存到 CPU 内存的同步回读,这是一个非常耗时的操作。在 D-Bus 调用前进行此转换,如果图片较大,会导致 UI 短暂卡顿。
    • 建议
      1. 如果 openImageAndName 接口支持直接传递 QPixmap,优先传递 QPixmap(D-Bus 会自动处理序列化,内部可能有更优化的共享内存传输机制)。
      2. 如果必须传 QImage,考虑将其放入后台线程执行,避免阻塞主事件循环。
  2. onMouseMove 中的去重判断性能

    • 位置src/main_window.cpponMouseMove 中。
    • 问题m_currentCursor != pos 是一个很好的去重优化,避免了同一坐标的重复事件派发。但 QApplication::sendEvent 是同步的,在高频鼠标移动时,频繁 new/delete 事件对象会产生内存碎片(见质量第1点,建议使用智能指针或栈对象优化)。

四、 代码安全

  1. D-Bus 参数传递的安全隐患

    • 位置src/main_window.cppchangeShotToolEvent 中。
    • 问题m_pinInterface->openImageAndName(pinImage, m_saveFileName, QPoint(recordX, recordY))。将完整的 QImage 通过 D-Bus 传递,意味着整张图片的像素数据将被序列化并穿越进程边界。这不仅带来巨大的性能开销(可能触发 D-Bus 的数据大小限制,默认通常是几MB到几十MB),还存在内存安全隐患(如果截图包含敏感信息,在 D-Bus 上传输可能被同 session 的其他进程嗅探)。
    • 建议
      1. 最佳实践:不要通过 D-Bus 传输图片数据本身。改为将图片保存到本地临时文件(确保权限为 0600),然后仅通过 D-Bus 传递文件路径。贴图程序通过文件路径读取,读取后立即销毁临时文件。
      2. 如果必须传图片,需确认系统 D-Bus 配置是否支持如此巨大的 Payload,并考虑使用 QDBusArgument 进行流式优化。
  2. 环境变量大小写绕过的潜在风险

    • 位置src/pin_screenshots/main.cpp 中。
    • 问题compositor.compare(QStringLiteral("treeland"), Qt::CaseInsensitive) == 0。将原本的精确匹配改为了大小写不敏感匹配。虽然注释解释了原因,但环境变量通常是由桌面环境(root权限下的服务)注入的,应当具有确定性。放宽匹配条件可能被恶意用户利用(例如用户手动 export DDE_CURRENT_COMPOSITOR=treeland 来欺骗程序进入特定分支,绕过某些 Wayland 安全限制)。
    • 建议:如果确实存在历史版本大小写不一致的问题,建议增加对两种确定格式的判断(如 "TreeLand""treeland"),而不是完全的 CaseInsensitive,并在注释中明确说明是哪个历史版本需要兼容。

总结

此次提交的核心逻辑(延迟获取窗口列表、XRecord补发事件、Treeland适配)是正确且必要的,解决了复杂的系统级交互问题。主要的改进点在于:

  1. 统一并修正 Qt 鼠标事件的构造方式,避免坐标和按键状态混乱。
  2. 消除通过 D-Bus 传输大体积 QImage 的性能与安全隐患,改传文件路径。
  3. 规范资源管理(使用智能指针)和日志级别

@dengzhongyuan365-dev

Copy link
Copy Markdown
Member Author

/forcemerge

@deepin-bot

deepin-bot Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

This pr force merged! (status: blocked)

@deepin-bot deepin-bot Bot merged commit 08a38b0 into linuxdeepin:master May 25, 2026
14 of 16 checks passed
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.

3 participants