Skip to content

fix: auto-restart fcitx5 in ProcessMonitor constructor#125

Merged
wyu71 merged 1 commit intolinuxdeepin:masterfrom
wyu71:master
Jan 4, 2026
Merged

fix: auto-restart fcitx5 in ProcessMonitor constructor#125
wyu71 merged 1 commit intolinuxdeepin:masterfrom
wyu71:master

Conversation

@wyu71
Copy link
Copy Markdown
Contributor

@wyu71 wyu71 commented Jan 4, 2026

  • Kill existing fcitx5 processes for current user before starting
  • Start fcitx5 in detached mode during constructor

Log: auto-restart fcitx5 in ProcessMonitor constructor
pms: BUG-339241

Summary by Sourcery

Ensure the ProcessMonitor proactively restarts the fcitx5 process when constructed.

Bug Fixes:

  • Terminate any existing fcitx5 processes for the current user before starting a new instance to avoid multiple conflicting input method daemons.
  • Automatically start fcitx5 in detached mode from the ProcessMonitor constructor so it is running even if it was not previously active.

- Kill existing fcitx5 processes for current user before starting
- Start fcitx5 in detached mode during constructor

Log: auto-restart fcitx5 in ProcessMonitor constructor
pms: BUG-339241
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jan 4, 2026

TAG Bot

TAG: 6.0.23
EXISTED: no
DISTRIBUTION: unstable

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Jan 4, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

The ProcessMonitor constructor now proactively restarts fcitx5 by killing any existing fcitx5 processes for the current user and launching a new detached fcitx5 instance, with logging around these actions.

Sequence diagram for ProcessMonitor constructor auto-restart of fcitx5

sequenceDiagram
    participant Caller
    participant ProcessMonitor
    participant QTimer
    participant exeCommand
    participant QProcess

    Caller->>ProcessMonitor: constructor(parent)
    activate ProcessMonitor
    ProcessMonitor->>QTimer: connect(m_timer.timeout, checkFcitx5Process)

    ProcessMonitor->>exeCommand: exeCommand(pgrep, [-u, getCurrentUserName(), -x, fcitx5], output, error)
    exeCommand-->>ProcessMonitor: output, error

    alt fcitx5 processes found
        ProcessMonitor->>ProcessMonitor: pids = output.trimmed().split('\n')
        loop for each pid in pids
            ProcessMonitor->>exeCommand: exeCommand(kill, [pid.trimmed()], killOutput, killError)
            exeCommand-->>ProcessMonitor: killOutput, killError
        end
    end

    ProcessMonitor->>QProcess: startDetached(PROCESS_NAME, [-d])
    QProcess-->>ProcessMonitor: started

    alt started is true
        ProcessMonitor->>ProcessMonitor: log success
    else started is false
        ProcessMonitor->>ProcessMonitor: log failure
    end

    deactivate ProcessMonitor
Loading

Class diagram for updated ProcessMonitor constructor behavior

classDiagram
    class ProcessMonitor {
        - QTimer m_timer
        + ProcessMonitor(parent: QObject*)
        + startMonitoring() void
        + checkFcitx5Process() void
    }

    class QTimer {
        + timeout() void
    }

    class QProcess {
        + startDetached(program: QString, arguments: QStringList) bool
    }

    class HelperFunctions {
        + exeCommand(command: QString, arguments: QStringList, output: QString, error: QString) void
        + getCurrentUserName() QString
    }

    ProcessMonitor --> QTimer : uses
    ProcessMonitor --> QProcess : uses
    ProcessMonitor --> HelperFunctions : uses
Loading

File-Level Changes

Change Details Files
Ensure fcitx5 is auto-restarted when ProcessMonitor is constructed.
  • Invoke pgrep scoped to the current user to discover existing fcitx5 PIDs and parse the result into a list
  • Iterate over discovered PIDs and issue kill commands for each, logging each termination attempt
  • Start a new detached fcitx5 process with the -d flag from within the constructor using QProcess::startDetached
  • Add debug and warning logging around successful or failed fcitx5 startup in the constructor
src/fcitx5helper/processmonitor.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
Copy Markdown

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

  • The constructor now performs synchronous pgrep/kill calls and starts a new process, which may block the main thread during object construction; consider moving this logic to an explicit initialization/start method or a background task instead of doing it in the constructor.
  • The return values and stderr (error, killError) from exeCommand are currently ignored; consider checking and logging failures so that issues with pgrep or kill are visible and can be diagnosed.
  • You can simplify the detached start by using QProcess::startDetached(PROCESS_NAME, {"-d"}) directly instead of creating a local QProcess process instance that is otherwise unused.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The constructor now performs synchronous `pgrep`/`kill` calls and starts a new process, which may block the main thread during object construction; consider moving this logic to an explicit initialization/start method or a background task instead of doing it in the constructor.
- The return values and stderr (`error`, `killError`) from `exeCommand` are currently ignored; consider checking and logging failures so that issues with `pgrep` or `kill` are visible and can be diagnosed.
- You can simplify the detached start by using `QProcess::startDetached(PROCESS_NAME, {"-d"})` directly instead of creating a local `QProcess process` instance that is otherwise unused.

## Individual Comments

### Comment 1
<location> `src/fcitx5helper/processmonitor.cpp:92-99` </location>
<code_context>
+        for (const QString &pid : pids) {
+            qCDebug(procMon) << "Killing existing fcitx5 process with PID:" << pid;
+            QString killOutput, killError;
+            exeCommand("kill", QStringList() << pid.trimmed(), killOutput, killError);
+        }
+    }
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Kill failures and errors are ignored, which may hide problems in process cleanup.

`exeCommand`’s return value and `killOutput` / `killError` are ignored, so a failed `kill` (permissions, process already gone, invalid PID, etc.) is silently treated as success. Please check the result and/or `killError` and log or otherwise handle failures, especially since this is terminating user processes.

```suggestion
    if (!output.isEmpty()) {
        QStringList pids = output.trimmed().split('\n', Qt::SkipEmptyParts);
        for (const QString &pid : pids) {
            const QString trimmedPid = pid.trimmed();
            qCDebug(procMon) << "Killing existing fcitx5 process with PID:" << trimmedPid;
            QString killOutput, killError;
            const bool killSucceeded =
                exeCommand("kill", QStringList() << trimmedPid, killOutput, killError);

            if (!killSucceeded || !killError.trimmed().isEmpty()) {
                qCWarning(procMon)
                    << "Failed to kill existing fcitx5 process"
                    << "PID:" << trimmedPid
                    << "success:" << killSucceeded
                    << "stderr:" << killError.trimmed()
                    << "stdout:" << killOutput.trimmed();
            }
        }
    }
```
</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.

@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

我来对这个diff进行详细的代码审查:

  1. 版本更新(debian/changelog):
  • 更新了版本号从6.0.22到6.0.23
  • 标记为Non-maintainer upload(非维护者上传)
  • 更新日期为2026年1月4日(这个日期似乎有误,应该是未来日期)
    建议:修正日期为当前日期
  1. ProcessMonitor构造函数的修改:

安全性问题:

  1. 在构造函数中直接执行kill命令存在安全风险,因为:
    • 没有验证PID的有效性
    • 没有检查进程是否真的是fcitx5
    • 可能误杀其他进程

建议改进:

// 在kill之前验证进程
exeCommand("ps", QStringList() << "-p" << pid.trimmed() << "-o" << "comm=", output, error);
if (output.trimmed() == "fcitx5") {
    exeCommand("kill", QStringList() << pid.trimmed(), killOutput, killError);
}

代码质量问题:

  1. 构造函数承担了太多职责:
    • 检查进程
    • 终止进程
    • 启动新进程

建议将这些操作分离到单独的方法中:

ProcessMonitor::ProcessMonitor(QObject *parent) : QObject(parent)
{
    connect(&m_timer, &QTimer::timeout, this, &ProcessMonitor::checkFcitx5Process);
    initializeFcitx5();
}

void ProcessMonitor::initializeFcitx5()
{
    terminateExistingFcitx5();
    startNewFcitx5();
}

性能问题:

  1. 使用多个同步命令执行可能造成阻塞
  2. 没有设置超时机制

建议改进:

QProcess process;
process.setProgram("pgrep");
process.setArguments(QStringList() << "-u" << getCurrentUserName() << "-x" << "fcitx5");
process.start();
if (!process.waitForFinished(5000)) { // 设置5秒超时
    qCWarning(procMon) << "pgrep command timeout";
    process.kill();
    return;
}

错误处理问题:

  1. 没有处理exeCommand可能的失败情况
  2. kill命令的输出和错误没有检查

建议改进:

if (!killError.isEmpty()) {
    qCWarning(procMon) << "Failed to kill process" << pid << ":" << killError;
}

其他建议:

  1. 添加日志记录,便于调试和问题追踪
  2. 考虑使用信号量或其他同步机制,避免多个实例同时操作
  3. 添加权限检查,确保有足够权限执行这些操作

总的来说,这个修改虽然实现了功能,但在安全性、可靠性和代码结构方面还有改进空间。建议重构代码,提高其健壮性和可维护性。

@wyu71 wyu71 merged commit 79f1ff4 into linuxdeepin:master Jan 4, 2026
8 checks passed
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: lzwind, wyu71

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

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