Skip to content

Conversation

@BLumia
Copy link
Member

@BLumia BLumia commented Feb 3, 2026

针对一些不规范的 desktop 文件,例如没有提供当前地区的显示名称,也没有
提供默认(无地区)显示名称的情况下,fallback到使用原始 desktop id 作为
对用户呈现的名称.

PMS: BUG-349847

Summary by Sourcery

Bug Fixes:

  • Handle ill-formed desktop files by using the desktop ID as the user-visible name when no localized or default name is available.

针对一些不规范的 desktop 文件,例如没有提供当前地区的显示名称,也没有
提供默认(无地区)显示名称的情况下,fallback到使用原始 desktop id 作为
对用户呈现的名称.

PMS: BUG-349847
Log:
@BLumia BLumia requested a review from 18202781743 February 3, 2026 08:17
@sourcery-ai
Copy link

sourcery-ai bot commented Feb 3, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adds a fallback so that for ill-formed desktop entries without a valid display name, the application uses the desktop-id as the display name instead.

Flow diagram for AppItem displayName fallback to desktop id

flowchart TD
  A[Receive DBus appInfo for application] --> B[Create AppItem with
id from DesktopId
initial displayName from Name
initial genericName from GenericName]
  B --> C{Is initial displayName empty?}
  C -- Yes --> D[Set displayName to id]
  C -- No --> E[Keep existing displayName]
  D --> F{Is a localized Name field available?}
  E --> F
  F -- Yes --> G[Parse localized Name and assign to item name]
  F -- No --> H[Skip name localization]
  G --> I[Return AppItem to caller]
  H --> I[Return AppItem to caller]
Loading

File-Level Changes

Change Details Files
Add a fallback to use the desktop-id as the user-visible name when a desktop entry lacks a valid display name.
  • After constructing the AppItem in parseDBus2AppItem, check if displayName is empty.
  • If displayName is empty, assign the AppItem id to displayName as a fallback value.
src/ddeintegration/appmgr.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location> `src/ddeintegration/appmgr.cpp:97-100` </location>
<code_context>
                                        parseDBusField<QStringMap>(appInfo, u8"Name").value(),
                                        parseDBusField<QStringMap>(appInfo, u8"GenericName").value());

+    // just in case the entry is ill-formed, doesn't have a valid display name, fallback to use its desktop-id instead.
+    if (item->displayName.isEmpty()) {
+        item->displayName = item->id;
+    }
+
</code_context>

<issue_to_address>
**suggestion:** Treat whitespace-only display names as empty before applying the desktop-id fallback.

Because this uses `isEmpty()`, a display name containing only spaces or other whitespace will not fall back and will likely render poorly. Please use `item->displayName.trimmed().isEmpty()` so whitespace-only values also trigger the desktop-id fallback.

```suggestion
    // just in case the entry is ill-formed, doesn't have a valid display name (or only whitespace),
    // fallback to use its desktop-id instead.
    if (item->displayName.trimmed().isEmpty()) {
        item->displayName = item->id;
    }
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +97 to +100
// just in case the entry is ill-formed, doesn't have a valid display name, fallback to use its desktop-id instead.
if (item->displayName.isEmpty()) {
item->displayName = item->id;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Treat whitespace-only display names as empty before applying the desktop-id fallback.

Because this uses isEmpty(), a display name containing only spaces or other whitespace will not fall back and will likely render poorly. Please use item->displayName.trimmed().isEmpty() so whitespace-only values also trigger the desktop-id fallback.

Suggested change
// just in case the entry is ill-formed, doesn't have a valid display name, fallback to use its desktop-id instead.
if (item->displayName.isEmpty()) {
item->displayName = item->id;
}
// just in case the entry is ill-formed, doesn't have a valid display name (or only whitespace),
// fallback to use its desktop-id instead.
if (item->displayName.trimmed().isEmpty()) {
item->displayName = item->id;
}

@deepin-ci-robot
Copy link

deepin pr auto review

这段代码主要是在解析 DBus 返回的应用信息时,增加了一个容错处理逻辑:当应用没有有效的显示名称(displayName)时,回退使用应用的 ID(id)作为显示名称。

以下是从语法逻辑、代码质量、代码性能和代码安全四个方面的详细审查意见:

1. 语法逻辑

  • 逻辑顺序问题
    • 代码中先使用 parseDBusField<QStringMap>(appInfo, u8"Name").value() 初始化了 displayName
    • 紧接着检查 if (item->displayName.isEmpty()) 并进行赋值。
    • 随后,代码又执行了 if (auto value = parseDBusField<QStringMap>(appInfo, u8"Name"))
    • 问题:这里对 u8"Name" 字段进行了两次解析和获取。虽然逻辑上能跑通,但显得冗余。如果后面那个 if 块里的逻辑(parseName)旨在处理 name 字段而非 displayName,那么注释和逻辑是清晰的;但如果 parseName 的结果本应影响 displayName,那么当前的回退逻辑可能会在 parseName 之前就生效,导致逻辑错误。
    • 建议:确认 namedisplayName 的关系。如果它们是独立的,建议合并 DBus 字段的获取,避免重复调用。

2. 代码质量

  • 重复代码
    • parseDBusField<QStringMap>(appInfo, u8"Name") 在构造函数和后续的 if 判断中出现了两次。这不仅增加了代码量,也增加了维护成本。如果未来字段名从 "Name" 变更,需要修改多处。
    • 建议:将解析结果提取到一个局部变量中,复用该变量。
  • 注释语言
    • 注释使用的是英文 // just in case...。如果项目主要使用中文注释,建议统一为中文,以提高团队内部的可读性。

3. 代码性能

  • 冗余解析
    • 如前所述,重复调用 parseDBusField 会带来不必要的性能开销(尽管在 DBus 调用场景下可能不是瓶颈,但属于不良实践)。
    • 建议:只解析一次 "Name" 字段,根据结果同时初始化 displayNamename

4. 代码安全

  • 空指针风险
    • item 是通过 new 创建的指针。如果 new 失败(虽然在现代系统中很少见,但在极端内存不足情况下可能发生),或者 item 在后续逻辑中被意外释放,访问 item->displayName 会导致崩溃。
    • 建议:虽然在此处通常假设内存分配成功,但更严谨的做法是检查指针有效性(尽管在 C++ 这种高频路径下通常省略)。
  • u8"Name" 的使用
    • 使用 u8 前缀表示 UTF-8 字符串字面量是好的习惯,确保了跨平台字符编码的一致性。

改进后的代码建议

假设 namedisplayName 需要基于同一个 "Name" 字段源,但处理方式不同(displayName 直接取值,name 经过 parseName 处理),建议修改如下:

static AppMgr::AppItem *parseDBus2AppItem(const ObjectInterfaceMap &source)
{
    // ... (前置代码)

    // 提前解析 "Name" 字段,避免重复调用
    auto nameValueOpt = parseDBusField<QStringMap>(appInfo, u8"Name");
    
    // 初始化 displayName
    QString displayNameStr = nameValueOpt.value_or(QStringMap{}).value(); // 或者根据实际返回类型调整
    // 如果 parseDBusField 返回的是 Optional<QStringMap>,这里需要解包

    // 初始化 item
    auto *item = new AppMgr::AppItem(
                                        parseDBusField<QString>(appInfo, u8"Id").value(),
                                        displayNameStr, // 使用解析出的值
                                        parseDBusField<QStringMap>(appInfo, u8"GenericName").value());

    // 容错处理:如果 display name 为空,回退到 ID
    if (item->displayName.isEmpty()) {
        item->displayName = item->id;
    }

    // 处理 name 字段
    if (nameValueOpt) {
        item->name = parseName(nameValueOpt.value());
    }

    // ... (后续代码)
}

注意:由于 parseDBusField 的具体返回类型未在 diff 中完全展示(看起来像是返回一个 Optional 类型的容器),上述代码中的 nameValueOpt.value_or(...) 部分可能需要根据实际返回的 QStringMap 结构进行调整。核心思想是复用解析结果

如果 namedisplayName 的来源完全不同,或者必须分开处理,那么至少应确保没有重复的 DBus 字符串字面量和解析调用。

总结

原代码在功能上是可以工作的,但存在重复解析和逻辑不够紧凑的问题。通过提取公共变量和优化逻辑顺序,可以提高代码的可读性和维护性。

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, BLumia

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

@BLumia BLumia merged commit c311f7a into linuxdeepin:master Feb 3, 2026
10 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