Skip to content

Conversation

@wjyrich
Copy link
Contributor

@wjyrich wjyrich commented Oct 21, 2025

  1. Changed timer connection from hideOsd to doneSetting to handle modifier key detection
  2. Added doneSetting method that checks for MetaModifier key state
  3. When Meta key is pressed, restarts timer instead of hiding OSD immediately
  4. Creates additional hide timer when Meta key is not pressed to ensure proper timeout after key release
  5. This prevents OSD from disappearing while user is holding modifier keys for shortcuts

fix: 改进 OSD 面板超时行为以支持修饰键

  1. 将定时器连接从 hideOsd 改为 doneSetting 以处理修饰键检测
  2. 添加 doneSetting 方法检查 MetaModifier 键状态
  3. 当 Meta 键按下时,重新启动定时器而不是立即隐藏 OSD
  4. 当 Meta 键未按下时,创建额外的隐藏定时器确保按键释放后正确超时
  5. 防止用户在按住修饰键进行快捷操作时 OSD 意外消失

PMS: BUG-294169 BUG-294165

Summary by Sourcery

Improve OSD panel timeout behavior by detecting the Meta modifier key and postponing the hide action until the key is released

Bug Fixes:

  • Prevent OSD from disappearing while holding modifier keys by delaying or restarting the hide timer until the Meta key is released

Enhancements:

  • Introduce doneSetting method to check the Meta modifier state and adjust the hide timer accordingly

@sourcery-ai
Copy link

sourcery-ai bot commented Oct 21, 2025

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

This PR refactors the OSD panel’s timeout handling by introducing a doneSetting slot that checks for the Meta modifier key before hiding the OSD, restarting or deferring the hide timer as appropriate to prevent premature disappearance during key holds.

Sequence diagram for OSD panel timeout with modifier key

sequenceDiagram
    participant User as actor User
    participant OsdPanel
    participant QTimer
    participant qApp
    User->>OsdPanel: Triggers OSD display
    OsdPanel->>QTimer: Start m_osdTimer
    QTimer-->>OsdPanel: timeout
    OsdPanel->>qApp: queryKeyboardModifiers()
    alt MetaModifier is pressed
        OsdPanel->>QTimer: Restart m_osdTimer
    else MetaModifier not pressed
        OsdPanel->>QTimer: Create hideTimer
        QTimer-->>OsdPanel: hideTimer timeout
        OsdPanel->>OsdPanel: hideOsd()
    end
Loading

Updated class diagram for OsdPanel timeout logic

classDiagram
    class OsdPanel {
        +void ShowOSD(QString text)
        +void hideOsd()
        +void doneSetting()
        -QTimer* m_osdTimer
        -int m_interval
        +void showOsd()
        +void setVisible(bool visible)
    }
    OsdPanel --> QTimer : uses
    OsdPanel --> qApp : queries keyboard modifiers
Loading

File-Level Changes

Change Details Files
Redirected OSD timer to new doneSetting slot
  • Connected m_osdTimer timeout to doneSetting instead of hideOsd
panels/notification/osd/osdpanel.cpp
Added doneSetting method to handle modifier key logic
  • Check for MetaModifier and restart m_osdTimer when pressed
  • Create a separate hideTimer to defer hideOsd after key release
panels/notification/osd/osdpanel.cpp
Exposed doneSetting as a private slot
  • Added doneSetting declaration in OsdPanel header
panels/notification/osd/osdpanel.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 there - I've reviewed your changes and they look great!

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

## Individual Comments

### Comment 1
<location> `panels/notification/osd/osdpanel.cpp:79-81` </location>
<code_context>

+void OsdPanel::doneSetting()
+{
+    if (qApp->queryKeyboardModifiers().testFlag(Qt::MetaModifier)) {
+        return m_osdTimer->start();
+    }
+    
</code_context>

<issue_to_address>
**suggestion:** Returning m_osdTimer->start() may be misleading since QTimer::start() returns void.

Use 'm_osdTimer->start(); return;' instead to avoid confusion, since QTimer::start() does not return a value.

```suggestion
    if (qApp->queryKeyboardModifiers().testFlag(Qt::MetaModifier)) {
        m_osdTimer->start();
        return;
    }
```
</issue_to_address>

### Comment 2
<location> `panels/notification/osd/osdpanel.cpp:84-86` </location>
<code_context>
+    }
+    
+    //松下快捷键后,能够延时消失
+    QTimer *hideTimer = new QTimer(this); 
+    hideTimer->setInterval(m_osdTimer->interval() - m_osdTimer->remainingTime());
+    hideTimer->setSingleShot(true);
+    QObject::connect(hideTimer, &QTimer::timeout, this, &OsdPanel::hideOsd);
+    hideTimer->start(); 
</code_context>

<issue_to_address>
**issue (bug_risk):** Creating a new QTimer on each call may lead to resource leaks if not properly managed.

Repeatedly creating QTimer instances without deletion can increase memory usage. Consider reusing a member QTimer or deleting each timer after it finishes.
</issue_to_address>

### Comment 3
<location> `panels/notification/osd/osdpanel.cpp:85` </location>
<code_context>
+    
+    //松下快捷键后,能够延时消失
+    QTimer *hideTimer = new QTimer(this); 
+    hideTimer->setInterval(m_osdTimer->interval() - m_osdTimer->remainingTime());
+    hideTimer->setSingleShot(true);
+    QObject::connect(hideTimer, &QTimer::timeout, this, &OsdPanel::hideOsd);
</code_context>

<issue_to_address>
**issue (bug_risk):** Subtracting remainingTime from interval may result in a negative value.

If remainingTime() is greater than interval(), hideTimer will have a negative interval, which may cause undefined behavior. Please ensure the interval is always non-negative.
</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.

1. Changed timer connection from hideOsd to doneSetting to handle
modifier key detection
2. Added doneSetting method that checks for MetaModifier key state
3. When Meta key is pressed, restarts timer instead of hiding OSD
immediately
4. Creates additional hide timer when Meta key is not pressed to ensure
proper timeout after key release
5. This prevents OSD from disappearing while user is holding modifier
keys for shortcuts

fix: 改进 OSD 面板超时行为以支持修饰键

1. 将定时器连接从 hideOsd 改为 doneSetting 以处理修饰键检测
2. 添加 doneSetting 方法检查 MetaModifier 键状态
3. 当 Meta 键按下时,重新启动定时器而不是立即隐藏 OSD
4. 当 Meta 键未按下时,创建额外的隐藏定时器确保按键释放后正确超时
5. 防止用户在按住修饰键进行快捷操作时 OSD 意外消失

PMS: BUG-294169 BUG-294165
@deepin-ci-robot
Copy link

deepin pr auto review

我来帮你审查这段代码的改动:

  1. 代码逻辑分析:
  • 原代码中,定时器超时直接调用 hideOsd() 隐藏 OSD
  • 新代码中,定时器超时改为调用 doneSetting(),增加了对 Meta 键(Windows/Super 键)的检测
  • 如果按住 Meta 键,会重新启动定时器;否则会计算延迟后隐藏 OSD
  1. 存在的问题和改进建议:

a) 逻辑问题:

int delay = m_osdTimer->interval() - m_osdTimer->remainingTime();
if (delay < 0) delay = 0;

这里的逻辑可能有问题。当定时器已经超时(remainingTime() 返回 0)时,delay 会等于 interval,这可能不是预期行为。建议改为:

int remaining = m_osdTimer->remainingTime();
if (remaining <= 0) {
    hideOsd();
    return;
}
QTimer::singleShot(remaining, this, [this](){ hideOsd(); });

b) 命名建议:

  • doneSetting 这个命名不够直观,建议改为 handleTimeout 或 onTimeout 更符合 Qt 的命名规范

c) 代码健壮性:

  • 建议在 doneSetting 开始处添加定时器状态检查:
void OsdPanel::handleTimeout()
{
    if (!m_osdTimer || !m_osdTimer->isActive()) {
        return;
    }
    // ... 其余代码
}

d) 性能考虑:

  • 使用 QTimer::singleShot 创建新的定时器可能带来轻微性能开销,建议考虑直接使用现有定时器
  • 可以考虑将 Meta 键的检测移到键盘事件处理中,而不是在定时器回调中

e) 安全性:

  • current 代码没有明显的安全性问题

f) 代码结构:

  • 建议在头文件中添加函数注释,说明新函数的作用:
/**
 * @brief 处理 OSD 显示定时器超时事件
 * 
 * 当用户按住 Meta 键时,重新启动定时器
 * 否则在适当延迟后隐藏 OSD
 */
void handleTimeout();
  1. 总结:
    这个改动主要增加了对 Meta 键的特殊处理,但实现方式可以优化。建议:
  2. 修改定时器处理逻辑
  3. 改进函数命名
  4. 添加必要的参数检查
  5. 考虑将 Meta 键检测移到键盘事件处理中
  6. 添加适当的代码注释

这些改进可以让代码更加健壮、可维护,并且更符合 Qt 的编程规范。

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

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

@wjyrich wjyrich merged commit 4c11f38 into linuxdeepin:master Oct 21, 2025
10 of 11 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