Skip to content

fix: Resolve the issue where the shortcut key for selected desktop fi…#3008

Open
Fire-dtx wants to merge 1 commit intolinuxdeepin:masterfrom
Fire-dtx:master
Open

fix: Resolve the issue where the shortcut key for selected desktop fi…#3008
Fire-dtx wants to merge 1 commit intolinuxdeepin:masterfrom
Fire-dtx:master

Conversation

@Fire-dtx
Copy link

@Fire-dtx Fire-dtx commented Feb 5, 2026

Optimizing: Missing the dde-am parameter

Log: When detecting a desktop file during command execution, automatically prepend the dde-am parameter to the command

pms: BUG-337781

Summary by Sourcery

Bug Fixes:

  • Automatically prepend the dde-am launcher to commands that reference existing .desktop files or desktop file paths when creating or modifying custom shortcuts.

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Fire-dtx

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

@sourcery-ai
Copy link

sourcery-ai bot commented Feb 5, 2026

Reviewer's Guide

Adds a helper in KeyboardController to detect when a custom shortcut command targets a .desktop file and, if the file exists, automatically prefixes the command with dde-am when adding or modifying custom shortcuts, resolving missing dde-am parameter issues.

Sequence diagram for adding a custom shortcut with desktop command detection

sequenceDiagram
    actor User
    participant KeyboardController
    participant KeyboardWorker
    participant QFileInfo

    User->>KeyboardController: addCustomShortcut(name, cmd, accels)
    KeyboardController->>KeyboardWorker: onDisableShortcut(conflict) (for each conflict)
    KeyboardController->>KeyboardController: checkDesktopCmd(cmd)
    KeyboardController->>QFileInfo: QFileInfo(cmd)
    QFileInfo-->>KeyboardController: exists()
    alt desktop file exists and path or .desktop detected
        KeyboardController-->>KeyboardController: newCmd = dde-am + cmd
    else
        KeyboardController-->>KeyboardController: newCmd = cmd
    end
    KeyboardController->>KeyboardWorker: addCustomShortcut(name, newCmd, accels)
Loading

Class diagram for updated KeyboardController desktop command handling

classDiagram
    class KeyboardController {
        +formatKeys(shortcuts QString) QStringList
        +addCustomShortcut(name QString, cmd QString, accels QString) void
        +modifyCustomShortcut(id QString, name QString, cmd QString, accels QString) void
        +keyboardEnabledChanged() void
        -checkDesktopCmd(cmd QString) QString
        -m_repeatInterval uint
        -m_repeatDelay uint
        -m_numLock bool
    }

    class KeyboardWorker {
        +onDisableShortcut(conflict QString) void
        +addCustomShortcut(name QString, cmd QString, accels QString) void
        +modifyCustomShortcut(shortcut ShortcutPtr) void
    }

    class Shortcut {
        +id QString
        +name QString
        +command QString
        +accels QString
    }

    KeyboardController --> KeyboardWorker : uses
    KeyboardController --> Shortcut : modifies
Loading

File-Level Changes

Change Details Files
Introduce command-normalization helper to prefix existing desktop file commands with dde-am.
  • Add a private method that checks if a command is non-empty and either absolute-path-like or contains .desktop, verifies the target exists via QFileInfo, and conditionally returns the command prefixed with dde-am.
  • Include QFileInfo in the implementation file to support filesystem checks.
src/plugin-keyboard/operation/keyboardcontroller.cpp
src/plugin-keyboard/operation/keyboardcontroller.h
Apply desktop command normalization when creating and updating custom keyboard shortcuts.
  • Wrap the cmd parameter with the new helper before passing it into addCustomShortcut so saved custom shortcuts reference dde-am when invoking an existing desktop file.
  • Use the helper when updating an existing shortcut’s command field in modifyCustomShortcut so edits to commands that are desktop files also gain the dde-am prefix if appropriate.
  • Declare the helper in the KeyboardController class as a private method for reuse across add/modify flows.
src/plugin-keyboard/operation/keyboardcontroller.cpp
src/plugin-keyboard/operation/keyboardcontroller.h

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 2 issues, and left some high level feedback:

  • The checkDesktopCmd logic uses QFileInfo on the full cmd string, which will fail if arguments are appended to the desktop file path (e.g. /usr/share/applications/foo.desktop --option); consider parsing out the actual path before checking exists().
  • Relying on QFileInfo::exists() for commands that only contain a .desktop filename (without a full or relative path) likely won't detect desktop files in standard application directories; you may want to resolve such names against known desktop file locations before deciding whether to prepend dde-am.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `checkDesktopCmd` logic uses `QFileInfo` on the full `cmd` string, which will fail if arguments are appended to the desktop file path (e.g. `/usr/share/applications/foo.desktop --option`); consider parsing out the actual path before checking `exists()`.
- Relying on `QFileInfo::exists()` for commands that only contain a `.desktop` filename (without a full or relative path) likely won't detect desktop files in standard application directories; you may want to resolve such names against known desktop file locations before deciding whether to prepend `dde-am`.

## Individual Comments

### Comment 1
<location> `src/plugin-keyboard/operation/keyboardcontroller.cpp:232-242` </location>
<code_context>
+QString KeyboardController::checkDesktopCmd(const QString &cmd)
+{
+    // 检查并处理desktop命令,如果desktop文件存在则添加dde-am前缀
+    if (!cmd.isEmpty() && (cmd.startsWith("/") || cmd.contains(".desktop"))) {
+        QFileInfo fileInfo(cmd);
+        if (fileInfo.exists()) {
</code_context>

<issue_to_address>
**suggestion:** Trim the command string before checks to avoid whitespace-related misdetection

Leading/trailing spaces in `cmd` (e.g. from copy-paste) will cause `startsWith("/")` to fail and `QFileInfo` to look up a path with whitespace, so an existing desktop file may not be detected. Consider `auto trimmed = cmd.trimmed();` and performing the checks on `trimmed` (and returning `trimmed` or the original as appropriate) to handle this case reliably.

```suggestion
QString KeyboardController::checkDesktopCmd(const QString &cmd)
{
    // 检查并处理desktop命令,如果desktop文件存在则添加dde-am前缀
    const auto trimmed = cmd.trimmed();
    if (!trimmed.isEmpty() && (trimmed.startsWith("/") || trimmed.contains(".desktop"))) {
        QFileInfo fileInfo(trimmed);
        if (fileInfo.exists()) {
            return "dde-am " + trimmed;
        }
    }
    return cmd;
}
```
</issue_to_address>

### Comment 2
<location> `src/plugin-keyboard/operation/keyboardcontroller.cpp:236-237` </location>
<code_context>
+{
+    // 检查并处理desktop命令,如果desktop文件存在则添加dde-am前缀
+    if (!cmd.isEmpty() && (cmd.startsWith("/") || cmd.contains(".desktop"))) {
+        QFileInfo fileInfo(cmd);
+        if (fileInfo.exists()) {
+            return "dde-am " + cmd;
+        }
</code_context>

<issue_to_address>
**suggestion:** Limit `.desktop` existence checks to the command token rather than the full string

Because `QFileInfo` is constructed with the full `cmd` string, any arguments or shell wrappers (e.g. `"/usr/share/applications/foo.desktop --flag"`, `"env FOO=1 foo.desktop"`) will cause `exists()` to fail even when the underlying `.desktop` file is present. Extract the executable/desktop-file token (up to the first whitespace) and pass only that to `QFileInfo` so the existence check reflects the actual desktop file.
</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.

@Fire-dtx Fire-dtx force-pushed the master branch 3 times, most recently from de2a6e8 to 784defc Compare February 5, 2026 08:22
…les does not work

Optimizing: Missing the dde-am parameter

Log: When detecting a desktop file during command execution, automatically prepend the dde-am parameter to the command

pms: BUG-337781
@deepin-ci-robot
Copy link

deepin pr auto review

这段代码主要实现了在添加或修改自定义快捷键时,自动检测 .desktop 文件路径,并在文件存在时为其添加 dde-am 前缀的功能。以下是对这段代码的详细审查和改进建议:

1. 语法逻辑审查

  • 逻辑正确性
    • checkDesktopCmd 函数逻辑基本正确,能够判断字符串是否以 / 开头且以 .desktop 结尾,并使用 QFileInfo 检查文件是否存在。
    • addCustomShortcutmodifyCustomShortcut 中正确调用了该函数,确保了逻辑的闭环。
  • 潜在逻辑缺陷
    • 符号链接问题QFileInfo::exists() 对于符号链接会检查链接目标是否存在,而 QFileInfo::isFile() 在某些情况下(取决于是否调用了缓存刷新)可能只检查链接本身。如果用户传入一个指向不存在目标的符号链接 .desktop 文件,行为可能不符合预期。建议统一使用 fileInfo.exists()
    • 路径格式cmd.startsWith("/") 仅检查绝对路径。如果系统环境变量或用户意图允许相对路径(例如通过 ~ 或环境变量),此逻辑会失效。不过考虑到快捷键命令通常需要绝对路径,这一点尚可接受,但需明确需求。

2. 代码质量审查

  • 命名与注释
    • 函数名 checkDesktopCmd 略显歧义。它不仅是检查,还在"转换/包装"命令。建议改名为 processDesktopCmdwrapDesktopCmd
    • 头文件中的注释 // 检查并处理desktop命令... 很好,建议将其补充到 .cpp 文件的函数实现上方,保持一致性。
  • 代码重复
    • addCustomShortcutmodifyCustomShortcut 中都有处理冲突快捷键的逻辑(m_worker->onDisableShortcut)。虽然目前代码量不大,但如果未来冲突处理逻辑变得复杂(例如需要弹窗确认),建议提取为私有函数 disableConflictShortcut(const QString &accels)
  • 硬编码字符串
    • "dde-am " 是一个硬编码的字符串。如果前缀可能变化或需要配置,建议定义为类常量或静态变量,例如 static const QString DESKTOP_CMD_PREFIX = "dde-am ";

3. 代码性能审查

  • I/O 操作
    • QFileInfo 的构造和 exists()/isFile() 调用涉及磁盘 I/O 操作。虽然快捷键设置不是高频操作,但为了代码健壮性,应确保此操作不在高频循环中调用。当前代码仅在用户点击保存时触发,性能影响可忽略。
  • 字符串操作
    • cmd.startsWithcmd.endsWith 效率较高,无性能问题。

4. 代码安全审查

  • 命令注入风险
    • 代码直接将 cmd 拼接到 dde-am 后面("dde-am " + cmd)。如果 cmd 包含 shell 元字符(如 ;, &, |, $() 等),且 m_worker 最终通过 system() 或未加引号的 sh -c 执行,可能存在命令注入风险。
    • 改进建议:确认 m_worker 的执行方式。如果是通过 QProcess 启动并参数分离,则是安全的。如果是通过 shell 执行,必须确保 cmd 被正确转义。考虑到 cmd.desktop 文件路径,通常只包含安全字符,但防御性编程要求我们不能假设输入总是安全的。
  • 路径遍历
    • 虽然使用了绝对路径检查,但仍需确保后续处理逻辑(dde-am)能够正确处理包含空格或特殊字符的路径。

5. 改进后的代码建议

以下是综合了上述建议的改进代码片段:

// keyboardcontroller.h
private:
    // 处理desktop命令,如果desktop文件存在则添加dde-am前缀
    QString processDesktopCmd(const QString &cmd);
    void disableConflictShortcut(const QString &accels); // 提取公共逻辑

    static const QString DESKTOP_CMD_PREFIX;
    
    uint m_repeatInterval;
    // ... 其他成员
// keyboardcontroller.cpp
const QString KeyboardController::DESKTOP_CMD_PREFIX = "dde-am ";

QString KeyboardController::processDesktopCmd(const QString &cmd)
{
    // 检查是否为绝对路径且以.desktop结尾
    if (!cmd.isEmpty() && cmd.startsWith("/") && cmd.endsWith(".desktop")) {
        QFileInfo fileInfo(cmd);
        // exists() 会自动处理符号链接的目标检查
        if (fileInfo.exists()) {
            // 注意:这里假设 m_worker 能安全处理包含空格的路径。
            // 如果是通过 shell 执行,建议对 cmd 进行转义或使用引号包裹。
            return DESKTOP_CMD_PREFIX + cmd;
        }
    }
    return cmd;
}

void KeyboardController::disableConflictShortcut(const QString &accels)
{
    if (auto conflict = m_shortcutModel->getInfo(accels)) {
        m_worker->onDisableShortcut(conflict);
    }
}

void KeyboardController::addCustomShortcut(const QString &name, const QString &cmd, const QString &accels)
{
    // 清理冲突快捷键
    disableConflictShortcut(accels);

    // 处理命令前缀
    QString newCmd = processDesktopCmd(cmd);
    m_worker->addCustomShortcut(name, newCmd, accels);
}

void KeyboardController::modifyCustomShortcut(const QString &id, const QString &name, const QString &cmd, const QString &accels)
{
    auto shortcut = m_shortcutModel->getCustomInfo(id);
    if (!shortcut) {
        return;
    }

    // 清理冲突快捷键
    disableConflictShortcut(accels);

    shortcut->name = name;
    shortcut->command = processDesktopCmd(cmd);
    shortcut->accels = accels;

    m_worker->modifyCustomShortcut(shortcut);
    // ... 
}

总结

这段代码实现了预期的功能,逻辑清晰。主要改进点在于:

  1. 提高代码的健壮性(处理符号链接、提取公共逻辑)。
  2. 增强可维护性(去除硬编码、优化命名)。
  3. 加强安全性意识(注意潜在的命令注入风险,尽管在此场景下风险较低)。

@deepin-bot
Copy link

deepin-bot bot commented Feb 5, 2026

TAG Bot

New tag: 6.1.72
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #3009

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.

2 participants