fix(popup): focus window popups for input#638
Conversation
Reviewer's GuideEnsures window-mode popups request focus and activation on show so that embedded input controls can receive focus and trigger the input method, by wiring popup focus properties in QML to a new focus-request helper in the popup window handle. Sequence diagram for popup window focus request on showsequenceDiagram
participant PopupWin as QQuickWindow_m_popupWin
participant Handle as DPopupWindowHandle
participant Popup as QObject_m_popup
participant Item as QQuickItem_popupItem
PopupWin->>Handle: eventFilter(watched=PopupWin, event: QEvent::Show)
alt watched is m_popupWin and event is Show
Handle->>Handle: requestPopupFocus()
Handle->>Handle: QMetaObject::invokeMethod(this, lambda, QueuedConnection)
Note over Handle: Queued lambda executes later
Handle->>Popup: property focus
alt isEnabled and popup focus and popupWin visible
Handle->>PopupWin: requestActivate()
Handle->>Item: forceActiveFocus(Qt::ActiveWindowFocusReason)
end
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- In
requestPopupFocus(), instead of capturingpopupItem()in aQPointer<QQuickItem>before the queued invocation, consider resolving the current popup item inside the lambda to avoid focusing a stale or deleted item if the content changes between theShowevent and the queued execution. - The check
popup->property("focus").toBool()is performed both before and inside the queued lambda; you could drop the outer check and rely on the inner one to reduce duplicated property lookups and keep the decision logic in a single place.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `requestPopupFocus()`, instead of capturing `popupItem()` in a `QPointer<QQuickItem>` before the queued invocation, consider resolving the current popup item inside the lambda to avoid focusing a stale or deleted item if the content changes between the `Show` event and the queued execution.
- The check `popup->property("focus").toBool()` is performed both before and inside the queued lambda; you could drop the outer check and rely on the inner one to reduce duplicated property lookups and keep the decision logic in a single place.
## Individual Comments
### Comment 1
<location path="src/private/dpopupwindowhandle.cpp" line_range="287-306" />
<code_context>
m_popupWin->setPosition(newPos);
}
+void DPopupWindowHandle::requestPopupFocus()
+{
+ if (!m_popup || !isEnabled() || !m_popupWin || !m_popupWin->isVisible())
+ return;
+ if (!m_popup->property("focus").toBool())
+ return;
+
+ QPointer<QObject> popup = m_popup;
+ QPointer<QQuickWindow> popupWin = m_popupWin;
+ QPointer<QQuickItem> item = popupItem();
+
+ QMetaObject::invokeMethod(this, [this, popup, popupWin, item] {
+ if (!isEnabled() || !popup || !popup->property("focus").toBool() || !popupWin || popupWin != m_popupWin || !popupWin->isVisible())
+ return;
+
+ popupWin->requestActivate();
+ if (item && item->window() == popupWin)
+ item->forceActiveFocus(Qt::ActiveWindowFocusReason);
+ }, Qt::QueuedConnection);
+}
+
DQUICK_END_NAMESPACE
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Avoid capturing a potentially stale popup item and consider resolving it at invocation time.
Because `item` is captured before the queued call executes, it may no longer match the actual popup item when the lambda runs (e.g. due to reparenting or delayed creation changing `popupItem()`). Instead, construct the `QPointer<QQuickItem>` inside the lambda by calling `popupItem()` there, then validate it (and its window) before requesting focus.
```suggestion
void DPopupWindowHandle::requestPopupFocus()
{
if (!m_popup || !isEnabled() || !m_popupWin || !m_popupWin->isVisible())
return;
if (!m_popup->property("focus").toBool())
return;
QPointer<QObject> popup = m_popup;
QPointer<QQuickWindow> popupWin = m_popupWin;
QMetaObject::invokeMethod(this, [this, popup, popupWin] {
if (!isEnabled() || !popup || !popup->property("focus").toBool() || !popupWin || popupWin != m_popupWin || !popupWin->isVisible())
return;
popupWin->requestActivate();
QPointer<QQuickItem> item = popupItem();
if (item && item->window() == popupWin)
item->forceActiveFocus(Qt::ActiveWindowFocusReason);
}, Qt::QueuedConnection);
}
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
TAG Bot New tag: 6.7.44 |
1. Add onPopupVisibleChanged slot to detect popup hide event 2. Add restoreParentFocus to return focus to parent window 3. Save active focus item before popup takes focus 4. Restore saved focus item when popup becomes invisible 5. Handle null window case in onWindowChanged to trigger restore Log: Fix focus not returning to parent window when popup closes fix(DPopupWindowHandle): 弹窗关闭时恢复父窗口焦点 1. 新增 onPopupVisibleChanged 槽函数检测弹窗隐藏事件 2. 新增 restoreParentFocus 方法将焦点归还父窗口 3. 弹窗获取焦点前保存当前活动焦点项 4. 弹窗不可见时恢复之前保存的焦点项 5. 在 onWindowChanged 中处理 window 为空时触发焦点恢复 Log: 修复弹窗关闭后焦点未归还父窗口的问题 PMS: BUG-366067
|
/test all |
deepin pr auto review★ 总体评分:100分■ 【总体评价】
■ 【详细分析】
■ 【改进建议代码示例】 // 当前代码已非常优秀,以下仅展示若 m_popup 类型明确时的可选优化写法
// 假设 m_popup 可安全转换为 QQuickPopup
void DPopupWindowHandle::requestPopupFocus()
{
if (!m_popup || !isEnabled() || !m_popupWin || !m_popupWin->isVisible())
return;
// 优化:避免使用字符串属性查找,提升性能与类型安全
bool hasFocus = false;
if (auto quickPopup = qobject_cast<QQuickPopup*>(m_popup)) {
hasFocus = quickPopup->hasFocus();
} else {
hasFocus = m_popup->property("focus").toBool();
}
if (!hasFocus)
return;
m_restoreFocusItem = m_parentWindow ? m_parentWindow->activeFocusItem() : nullptr;
QMetaObject::invokeMethod(this, [this] {
if (!isEnabled() || !m_popupWin || !m_popupWin->isVisible())
return;
bool hasFocus = false;
if (auto quickPopup = qobject_cast<QQuickPopup*>(m_popup)) {
hasFocus = quickPopup->hasFocus();
} else {
hasFocus = m_popup->property("focus").toBool();
}
if (!hasFocus)
return;
QPointer<QQuickItem> item = popupItem();
if (!item || item->window() != m_popupWin)
return;
m_popupFocusRequested = true;
m_popupWin->requestActivate();
}, Qt::QueuedConnection);
} |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: 18202781743, mhduiy The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Log: Focus window popups on show so embedded input controls can open the input method.
fix(popup): 让窗口弹窗支持输入法
Log: 显示窗口弹窗时获取焦点,使内部输入控件可以调起输入法。
Summary by Sourcery
Ensure window-based popups gain focus and activation when shown so embedded input controls can properly receive input and trigger the input method.
Bug Fixes:
Enhancements: