Skip to content

fix: prevent IME from activating when echo mode is Normal#746

Open
MyLeeJiEun wants to merge 1 commit into
linuxdeepin:masterfrom
MyLeeJiEun:fork-from-master-0526-fix-issue-361783
Open

fix: prevent IME from activating when echo mode is Normal#746
MyLeeJiEun wants to merge 1 commit into
linuxdeepin:masterfrom
MyLeeJiEun:fork-from-master-0526-fix-issue-361783

Conversation

@MyLeeJiEun
Copy link
Copy Markdown

  1. Add event filter to intercept InputMethod and InputMethodQuery events on the line edit widget in Qt6
  2. This works around a Qt6 bug where switching EchoMode to Normal invalidates WA_InputMethodEnabled and causes IME to reactivate
  3. The filter is conditionally compiled only for Qt6 builds

Log: Fix IME reactivation issue in DPasswordEdit on Qt6 when password is visible

fix: 修复密码可见时输入法被意外激活的问题

  1. 在 Qt6 构建中为 line edit 添加事件过滤器,拦截输入法相关事件
  2. 解决 Qt6 切换 EchoMode 为 Normal 时 WA_InputMethodEnabled 失效 导致输入法被重新激活的问题
  3. 该过滤仅在 Qt6 编译条件下生效

Log: 修复 Qt6 下 DPasswordEdit 密码可见时输入法被意外重新激活的问题
PMS: BUG-361783

@deepin-ci-robot
Copy link
Copy Markdown
Contributor

Hi @MyLeeJiEun. Thanks for your PR. 😃

@deepin-ci-robot
Copy link
Copy Markdown
Contributor

Hi @MyLeeJiEun. Thanks for your PR.

I'm waiting for a linuxdeepin member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

1. Add event filter to intercept InputMethod and InputMethodQuery events
   on the line edit widget in Qt6
2. This works around a Qt6 bug where switching EchoMode to Normal
   invalidates WA_InputMethodEnabled and causes IME to reactivate
3. The filter is conditionally compiled only for Qt6 builds

Log: Fix IME reactivation issue in DPasswordEdit on Qt6 when password is visible

fix: 修复密码可见时输入法被意外激活的问题

1. 在 Qt6 构建中为 line edit 添加事件过滤器,拦截输入法相关事件
2. 解决 Qt6 切换 EchoMode 为 Normal 时 WA_InputMethodEnabled 失效
   导致输入法被重新激活的问题
3. 该过滤仅在 Qt6 编译条件下生效

Log: 修复 Qt6 下 DPasswordEdit 密码可见时输入法被意外重新激活的问题
PMS: BUG-361783
@MyLeeJiEun MyLeeJiEun force-pushed the fork-from-master-0526-fix-issue-361783 branch from c4c47d5 to d073b05 Compare May 26, 2026 08:58
@mhduiy
Copy link
Copy Markdown
Contributor

mhduiy commented May 28, 2026

/ok-to-test

@deepin-ci-robot
Copy link
Copy Markdown
Contributor

deepin pr auto review

你好!我是CodeGeeX。我已仔细审查了你提供的Git Diff代码。这段代码的主要目的是修复在Qt6环境下,DPasswordEdit切换显示模式时输入法异常激活的问题。

以下是我对这段代码在语法逻辑、代码质量、代码性能和代码安全方面的审查意见及改进建议:

1. 语法与逻辑

  • 逻辑有效性:通过拦截 QEvent::InputMethodQEvent::InputMethodQuery 事件并返回 true,确实可以有效阻止输入法向密码框发送候选词和查询请求,这是一种常见且有效的“兜底”策略。
  • 潜在逻辑缺陷(状态耦合):当前代码无条件拦截了密码框的输入法事件。如果用户在明文模式(EchoMode::Normal)下希望使用输入法输入密码,这段代码会导致输入法完全不可用。通常,我们只在密文模式EchoMode::PasswordEchoMode::NoEcho)下拦截输入法事件。
  • 年份修改逻辑:将版权年份从 2023 改为 2026,如果是预置未来年份的模板修改,逻辑上没有问题;但如果是笔误,请注意修改。

2. 代码质量

  • 魔法值与硬编码QT_VERSION_CHECK(6, 0, 0) 是Qt提供的宏,使用规范,这一点很好。
  • 注释质量:注释清晰地解释了“为什么”要加这段代码(Qt6的子系统缺陷),这对于后续维护非常友好。
  • 代码可读性:使用 switch-case 处理事件类型是Qt事件过滤中的标准写法,可读性良好。

3. 代码性能

  • 事件过滤开销eventFilter 是高频调用函数。虽然 switch-case 的执行效率很高,但每次事件触发都要进行 watcher == lineEdit() 的指针比较以及版本宏判断。在这里影响微乎其微,但属于合理的性能考量点。

4. 代码安全

  • 输入安全:密码框的核心安全要求是防止密码明文被窃取。拦截输入法事件实际上增强了安全性,因为它防止了输入法软件记录用户的键盘输入和候选词。但在某些安全合规场景中,如果完全禁用输入法导致用户只能通过物理键盘输入,可能会降低可用性。需要根据实际产品需求权衡。

💡 改进建议与重构代码

核心改进:应该仅在密码处于隐藏状态时拦截输入法事件,在明文状态下应放行,以保证用户体验。

改进后的代码如下:

diff --git a/src/widgets/dpasswordedit.cpp b/src/widgets/dpasswordedit.cpp
index 8f08360a3..90c9e90ee 100644
--- a/src/widgets/dpasswordedit.cpp
+++ b/src/widgets/dpasswordedit.cpp
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: 2015 - 2023 UnionTech Software Technology Co., Ltd.
+// SPDX-FileCopyrightText: 2015 - 2026 UnionTech Software Technology Co., Ltd.
 //
 // SPDX-License-Identifier: LGPL-3.0-or-later
 
@@ -120,6 +120,24 @@ void DPasswordEdit::changeEvent(QEvent *event)
 
 bool DPasswordEdit::eventFilter(QObject* watcher, QEvent* event)
 {
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+    // Qt6 的输入法子系统会在切换 EchoMode 为 Normal 时会导致设置 WA_InputMethodEnabled失效,
+    // 导致输入法重新激活,因此通过事件过滤器拦截输入法事件来兜底。
+    // 修复:仅在密码隐藏状态下拦截输入法,明文状态下应允许使用输入法
+    if (watcher == lineEdit() && echoMode() != QLineEdit::Normal) {
+        switch (event->type()) {
+        case QEvent::InputMethod:
+        case QEvent::InputMethodQuery:
+            return true;
+        default:
+            break;
+        }
+    }
+#endif
     return DLineEdit::eventFilter(watcher, event);
 }

详细解释:

  1. 增加 echoMode() != QLineEdit::Normal 判断:这是最关键的改进。当 DPasswordEdit 处于密码隐藏模式时,输入法本就不该工作(否则会有安全风险和显示错乱);当用户点击“显示密码”图标切换到明文模式时,echoMode() 变为 Normal,此时不再拦截事件,用户可以正常使用输入法输入复杂密码。
  2. 合并判断条件:将 watcher == lineEdit()echoMode() != QLineEdit::Normal 合并到一个 if 语句中,减少了嵌套层级,代码更紧凑。

如果你有关于这段代码的更多上下文(例如为什么要在明文模式下也禁用输入法),欢迎提供,我可以做进一步的针对性分析!

@mhduiy mhduiy requested a review from 18202781743 May 28, 2026 02:52
@deepin-ci-robot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: mhduiy, MyLeeJiEun

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

bool DPasswordEdit::eventFilter(QObject* watcher, QEvent* event)
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
// Qt6 的输入法子系统会在切换 EchoMode 为 Normal 时会导致设置 WA_InputMethodEnabled失效,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

知道根因吗?到底是Qt的问题还是?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

qt6增加了对Qt::ImEnabled 的特殊处理。这个查询项是在 Qt 5.3后逐步加入的
只有在Qt::ImEnabled查询项无效时,再去查询WA_InputMethodEnabled
而QLineEdit的Qt::ImEnabled查询查询返回是

case Qt::ImEnabled:
   return isEnabled() && !isReadOnly();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants