Skip to content

Conversation

@add-uos
Copy link
Contributor

@add-uos add-uos commented Nov 28, 2025

pick develop/eagle to master

Summary by Sourcery

Sort monitor entries from xrandr verbose output by port name, adjust power device filtering for invalid or non-battery states, improve temperature display formatting, and simplify TOML-driven device creation logic.

New Features:

  • Store monitor port identifiers when parsing xrandr verbose output to support stable ordering.

Bug Fixes:

  • Exclude devices with empty or unknown power state in upower data from being treated as valid power devices.

Enhancements:

  • Sort monitor information deterministically by port name instead of conditionally reversing the list.
  • Normalize temperature strings by replacing "degrees C" with the ℃ symbol for clearer display.
  • Remove redundant fallback device creation path when applying TOML configuration in the device manager.

@github-actions
Copy link

github-actions bot commented Nov 28, 2025

CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅

@sourcery-ai
Copy link

sourcery-ai bot commented Nov 28, 2025

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Refines monitor enumeration and ordering based on xrandr output, tightens filtering of non-battery power devices, normalizes temperature display units, and simplifies TOML-driven device creation by removing a fallback duplication path.

Sequence diagram for updated monitor enumeration via xrandr

sequenceDiagram
    participant DeviceManager
    participant ThreadExecXrandr
    participant XrandrCLI as Xrandr_CLI

    DeviceManager->>ThreadExecXrandr: getMonitorInfoFromXrandrVerbose()
    activate ThreadExecXrandr

    ThreadExecXrandr->>ThreadExecXrandr: loadXrandrVerboseInfo(lstMap, xrandr_verbose_cmd)
    ThreadExecXrandr->>XrandrCLI: execute xrandr --verbose
    XrandrCLI-->>ThreadExecXrandr: verbose_output

    loop For_each_output_block
        ThreadExecXrandr->>ThreadExecXrandr: parse mainInfo
        ThreadExecXrandr->>ThreadExecXrandr: mainInfoList = mainInfo.split(" ")
        alt has_port_token
            ThreadExecXrandr->>ThreadExecXrandr: newMap[mainInfo] = mainInfo
            ThreadExecXrandr->>ThreadExecXrandr: newMap[port] = mainInfoList[0]
        else
            ThreadExecXrandr->>ThreadExecXrandr: newMap[mainInfo] = mainInfo
        end
        ThreadExecXrandr->>ThreadExecXrandr: lstMap.append(newMap)
    end

    ThreadExecXrandr->>ThreadExecXrandr: sort lstMap by port ascending

    ThreadExecXrandr-->>DeviceManager: ordered monitor list
    deactivate ThreadExecXrandr
Loading

Class diagram for updated device manager and power handling

classDiagram
    class ThreadExecXrandr {
        +void loadXrandrVerboseInfo(QList_QMap_string_string_ref lstMap, QString cmd)
        +void getMonitorInfoFromXrandrVerbose()
    }

    class DevicePower {
        +bool setInfoFromUpower(QMap_string_string_const_ref mapInfo)
        +void loadBaseDeviceInfo()
        -QString m_Temp
    }

    class DeviceManager {
        +void tomlDeviceSet(DeviceType deviceType)
    }

    DevicePower ..> DeviceManager : reported_in_device_lists
    DeviceManager ..> ThreadExecXrandr : uses_for_display_info

    note for ThreadExecXrandr "loadXrandrVerboseInfo now extracts port from mainInfo and getMonitorInfoFromXrandrVerbose sorts monitors by port"
    note for DevicePower "setInfoFromUpower now ignores line_power, empty, and unknown states; loadBaseDeviceInfo normalizes temperature to use ℃"
    note for DeviceManager "tomlDeviceSet no longer creates fallback duplicate devices when not matched"
Loading

File-Level Changes

Change Details Files
Derive and store monitor port identifiers from xrandr verbose output and sort monitors by port instead of reversing the list for normal computers.
  • Parse the main xrandr verbose line into tokens and store the first token as a new 'port' field in the monitor info map when creating a new display entry.
  • Replace the conditional reverse of the monitor list (based on SpecialComputerType::NormalCom) with a std::sort lambda that orders entries lexicographically by the optional 'port' field, leaving ordering unchanged when one of the entries lacks 'port'.
deepin-devicemanager/src/Tool/ThreadExecXrandr.cpp
Broaden the conditions under which upower devices are treated as non-battery and adjust temperature unit formatting for display.
  • Extend the early-return filter in setInfoFromUpower to also skip devices whose state is reported as 'empty' or 'unknown', in addition to those whose Device string contains 'line_power'.
  • Transform the temperature string by replacing the substring 'degrees C' with the Celsius symbol '℃' (case-insensitive) before adding it as base device info.
deepin-devicemanager/src/DeviceManager/DevicePower.cpp
Remove the secondary device-creation path in TOML-based device setup to avoid creating additional devices when a matching serial is not found.
  • Delete the branch that, for most device types, created and added a new device instance when no existing device with the same serial was found and the fixSameOne flag was still false, thereby simplifying toml-driven device population to only add devices when a matching one is explicitly identified.
deepin-devicemanager/src/DeviceManager/DeviceManager.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 there - I've reviewed your changes - here's some feedback:

  • In ThreadExecXrandr::loadXrandrVerboseInfo, splitting (*it).trimmed() using split(" ") can yield empty items when there are multiple spaces; consider using split(QRegularExpression("\\s+"), Qt::SkipEmptyParts) (or the SkipEmptyParts flag) to ensure the port value is parsed robustly.
  • The custom comparator in the std::sort on lstMap returns false whenever one of the maps lacks "port", which can violate strict weak ordering and lead to undefined behavior; make the comparator total (e.g., explicitly order entries with and without "port") instead of using a plain else return false.
  • In DevicePower::loadBaseDeviceInfo, calling m_Temp.replace(...) inside the addBaseDeviceInfo argument both mutates the member and relies on a side effect for formatting; it would be clearer and safer to compute a local formatted temperature string and pass that into addBaseDeviceInfo without modifying m_Temp.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `ThreadExecXrandr::loadXrandrVerboseInfo`, splitting `(*it).trimmed()` using `split(" ")` can yield empty items when there are multiple spaces; consider using `split(QRegularExpression("\\s+"), Qt::SkipEmptyParts)` (or the `SkipEmptyParts` flag) to ensure the `port` value is parsed robustly.
- The custom comparator in the `std::sort` on `lstMap` returns `false` whenever one of the maps lacks `"port"`, which can violate strict weak ordering and lead to undefined behavior; make the comparator total (e.g., explicitly order entries with and without `"port"`) instead of using a plain `else return false`.
- In `DevicePower::loadBaseDeviceInfo`, calling `m_Temp.replace(...)` inside the `addBaseDeviceInfo` argument both mutates the member and relies on a side effect for formatting; it would be clearer and safer to compute a local formatted temperature string and pass that into `addBaseDeviceInfo` without modifying `m_Temp`.

## Individual Comments

### Comment 1
<location> `deepin-devicemanager/src/DeviceManager/DevicePower.cpp:210-212` </location>
<code_context>
     addBaseDeviceInfo("SBDS Serial Number", m_SBDSSerialNumber);
     addBaseDeviceInfo("SBDS Manufacture Date", m_SBDSManufactureDate);
     addBaseDeviceInfo("SBDS Chemistry", m_SBDSChemistry);
-    addBaseDeviceInfo("Temperature", m_Temp);
+    addBaseDeviceInfo(("Temperature"), m_Temp.replace("degrees C", "℃", Qt::CaseInsensitive));
 }

</code_context>

<issue_to_address>
**issue (bug_risk):** Avoid mutating `m_Temp` as a side effect of formatting and remove redundant parentheses.

`m_Temp.replace(...)` mutates the member each time `loadBaseDeviceInfo()` runs, which can break callers that expect the original value. Instead, copy then format:

```cpp
QString temp = m_Temp;
temp.replace("degrees C", "", Qt::CaseInsensitive);
addBaseDeviceInfo("Temperature", temp);
```

You can also drop the extra parentheses around `"Temperature"` for readability.
</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.

add-uos and others added 4 commits November 28, 2025 16:42
filter the invalid power device

pick from: linuxdeepin@da94bed

Log: filter the invalid power device
Task: https://pms.uniontech.com/task-view-376787.html
fix the invalded device show incorrect

Log: fix the invalded device show incorrect
Bug: https://pms.uniontech.com/bug-view-256787.html
Change-Id: I57c51ef8462b11a369a9f0276f039552a9ea2825
fix the temperature of battery.

pick from: linuxdeepin@07bb6c9

Log: fix the temperature of battery.
Bug: https://pms.uniontech.com/task-view-377193.html
@deepin-ci-robot
Copy link

deepin pr auto review

我来逐个分析这些代码变更:

  1. DeviceManager.cpp 的变更:
-        } else if ((deviceType != DT_Bios) && (deviceType != DT_Computer) && !fixSameOne) {
-            fixSameOne = true;  //标记为该项信息有用过 ,则不再增加了
-            DeviceBaseInfo *device = createDevice(deviceType);
-            tomlDeviceMapSet(deviceType, device, tomlMapLst[j]);
-            tomlDeviceAdd(deviceType, device); //不存在 就加

这段代码被删除了,看起来是为了简化逻辑。但这个改动可能会带来一些问题:

  • 安全性:删除了设备类型检查,可能会导致某些设备类型的重复添加
  • 建议:如果确实要删除这段代码,应该确保其他地方有相应的重复检查机制
  1. DevicePower.cpp 的变更:
-    if (mapInfo["Device"].contains("line_power", Qt::CaseInsensitive)) {
+    if (mapInfo["Device"].contains("line_power", Qt::CaseInsensitive) ||
+        mapInfo["state"].contains("empty", Qt::CaseInsensitive) ||
+        mapInfo["state"].contains("unknown", Qt::CaseInsensitive)) {

这个改动增加了对电池状态的检查:

  • 逻辑性:改进了电源设备的判断逻辑,更全面地处理了特殊情况
  • 性能:增加了字符串匹配,但影响很小
  • 安全性:提高了代码的健壮性,避免了无效设备信息的处理
-    addBaseDeviceInfo("Temperature", m_Temp);
+    addBaseDeviceInfo(("Temperature"), m_Temp.replace("degrees C", "", Qt::CaseInsensitive));

这个改动改进了温度显示:

  • 可读性:使用更标准的温度单位显示
  • 性能:字符串替换操作,但影响很小
  • 建议:可以考虑将替换操作放在数据获取时而不是显示时
  1. ThreadExecXrandr.cpp 的变更:
+            auto mainInfoList = (*it).trimmed().split(" ");
+            if (mainInfoList.size() > 0) {
+                newMap.insert("port", mainInfoList.at(0));
+            }

新增了端口信息提取:

  • 逻辑性:增加了显示器端口信息的获取
  • 安全性:添加了数组边界检查
-    if (Common::specialComType == Common::SpecialComputerType::NormalCom) {
-        std::reverse(lstMap.begin(), lstMap.end());
-    }
+    std::sort(lstMap.begin(), lstMap.end(), [](const QMap<QString, QString> &monintor1, const QMap<QString, QString> &monintor2) {
+        if (monintor1.contains("port") && monintor2.contains("port"))
+            return monintor1.value("port") < monintor2.value("port");
+        else
+            return false;
+    });

显示器排序逻辑的改进:

  • 逻辑性:使用端口名称排序比简单的反转更有意义
  • 性能:排序操作比反转稍慢,但提供了更好的可预测性
  • 建议:可以考虑将排序函数提取为单独的方法,提高代码可读性

总体建议:

  1. 对于 DeviceManager.cpp 的改动,建议添加注释说明为什么删除这段代码
  2. 对于字符串操作,建议考虑性能影响,特别是在频繁调用的场景
  3. 对于排序逻辑,建议添加单元测试确保排序的正确性
  4. 建议添加更多的错误处理和边界检查
  5. 考虑将一些常量字符串提取为类常量,便于维护

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: add-uos, lzwind

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

@add-uos
Copy link
Contributor Author

add-uos commented Nov 28, 2025

/merge

@add-uos
Copy link
Contributor Author

add-uos commented Nov 28, 2025

/forcemerge

@deepin-bot
Copy link
Contributor

deepin-bot bot commented Nov 28, 2025

This pr cannot be merged! (status: unstable)

@deepin-bot
Copy link
Contributor

deepin-bot bot commented Nov 28, 2025

This pr force merged! (status: unstable)

@deepin-bot deepin-bot bot merged commit b063c01 into linuxdeepin:master Nov 28, 2025
15 of 17 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.

4 participants