fix: Main interface does not gray out when losing focus#570
fix: Main interface does not gray out when losing focus#570JWWTSL wants to merge 2 commits intolinuxdeepin:masterfrom
Conversation
Reviewer's GuideEnsures WindowModal DialogWindow instances correctly set and maintain their transient parent and, when shown, raise and activate themselves so the main window enters the expected grayed-out (modal) state. Sequence diagram for WindowModal DialogWindow activation and main window grayingsequenceDiagram
actor User
participant MainWindow
participant DialogWindow
participant QtApplication
User->>MainWindow: openDialog()
MainWindow->>DialogWindow: create DialogWindow (modality = Qt.WindowModal)
DialogWindow->>DialogWindow: Component.onCompleted
alt modality is WindowModal and transientParentWindow is null
DialogWindow->>QtApplication: get activeWindow
QtApplication-->>DialogWindow: activeWindow
DialogWindow->>DialogWindow: set transientParentWindow
DialogWindow->>DialogWindow: bind transientParent to transientParentWindow
end
User->>DialogWindow: set visible = true
DialogWindow->>DialogWindow: onVisibleChanged (visible = true)
alt modality is WindowModal
alt transientParentWindow is null or equals control
DialogWindow->>QtApplication: get activeWindow
QtApplication-->>DialogWindow: activeWindow
DialogWindow->>DialogWindow: set transientParentWindow
end
DialogWindow->>DialogWindow: Qt.callLater
DialogWindow->>DialogWindow: raise()
DialogWindow->>DialogWindow: requestActivate()
DialogWindow->>MainWindow: enforce modal relationship (main window grayed)
end
Updated class diagram for DialogWindow QML componentclassDiagram
class DialogWindow {
<<Window>>
+real leftPadding
+real rightPadding
+var transientParentWindow
+Window transientParent
+onCompleted()
+onVisibleChanged(visible)
+onClosing(close)
}
class QtApplication {
+Window activeWindow
+callLater(callback)
}
class Window {
+bool visible
+int modality
+void raise()
+void requestActivate()
}
DialogWindow --|> Window
DialogWindow --> QtApplication : uses
QtApplication --> Window : returns activeWindow
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 left some high level feedback:
- When the dialog becomes visible,
Qt.application.activeWindowmay already be the dialog itself, so thetransientParentWindow === controlguard and re-read ofactiveWindowwill still not yield the main window; consider capturing the previously active window before showing or using a more reliable source for the parent. - Overwriting
transientParentWindowinonVisibleChangedcan break any external binding or explicit assignment to this property; if it is meant to be user-configurable, consider only setting a default once (e.g., via a binding or when the property is stillnull) rather than reassigning on every visibility change.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- When the dialog becomes visible, `Qt.application.activeWindow` may already be the dialog itself, so the `transientParentWindow === control` guard and re-read of `activeWindow` will still not yield the main window; consider capturing the previously active window before showing or using a more reliable source for the parent.
- Overwriting `transientParentWindow` in `onVisibleChanged` can break any external binding or explicit assignment to this property; if it is meant to be user-configurable, consider only setting a default once (e.g., via a binding or when the property is still `null`) rather than reassigning on every visibility change.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Pull request overview
This PR fixes a focus/modality behavior issue where DialogWindow instances shown as Qt.WindowModal don’t correctly gray out the main window by ensuring a transient parent is set and activating the dialog when it becomes visible.
Changes:
- Introduce a
transientParentWindowproperty and bindtransientParentto it. - Auto-assign
transientParentWindowtoQt.application.activeWindowforQt.WindowModaldialogs. - On show, raise and request activation for window-modal dialogs to trigger expected grayed-out behavior.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Component.onCompleted: { | ||
| if (control.modality === Qt.WindowModal && !transientParentWindow) | ||
| transientParentWindow = Qt.application.activeWindow | ||
| } | ||
|
|
||
| onVisibleChanged: { | ||
| if (!control.visible) | ||
| return | ||
| if (control.modality !== Qt.WindowModal) | ||
| return | ||
| if (!transientParentWindow || transientParentWindow === control) | ||
| transientParentWindow = Qt.application.activeWindow | ||
| Qt.callLater(function () { | ||
| control.raise() | ||
| control.requestActivate() | ||
| }) |
There was a problem hiding this comment.
transientParentWindow is only set when it is null (or equals control). Once it has been auto-assigned the first time, it will not update on subsequent shows. If a DialogWindow instance is reused across multiple top-level windows, the dialog can remain transient for the original window, causing the wrong window to gray out (or none) when shown from another active window. Consider recalculating the transient parent each time the dialog becomes visible (or clearing the auto-assigned parent when the dialog is hidden), while still respecting an explicitly provided transient parent when callers set one.
log: In the DialogWindow, when set to WindowModal, the transientParent is automatically set to Qt.application.activeWindow. Upon display, raise() and requestActivate() are called to ensure the main window correctly enters a grayed-out state. pms: bug-336201
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: JWWTSL 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 |
| } | ||
|
|
||
| onVisibleChanged: { | ||
| if (!control.visible) |
There was a problem hiding this comment.
更新transientParentWindow的代码封装一下,逻辑在omCompleted和visibleChanged的时候应该是一样的,
|
TAG Bot New tag: 6.7.34 |
deepin pr auto review这是一个关于Qt/QML代码的审查,针对你提供的 1. 语法与逻辑审查
2. 代码质量建议
3. 代码性能
4. 代码安全
5. 改进后的代码建议基于以上分析,建议对代码进行如下重构,以提高可读性和健壮性: Window {
// ... 原有属性 ...
// 建议明确类型,如果环境允许
property var transientParentWindow: null
// 绑定 transientParent
transientParent: transientParentWindow
// 提取公共逻辑函数
function updateTransientParent() {
// 如果不是模态窗口,或者已经明确设置了父窗口,则不处理
// 注意:这里假设显式设置的不为 null 且不为自身
if (control.modality !== Qt.WindowModal) {
return;
}
// 如果当前没有父窗口,或者父窗口设置错误(指向了自己),则尝试自动寻找
if (!transientParentWindow || transientParentWindow === control) {
var candidate = Qt.application.activeWindow;
// 确保候选窗口存在,且不是自己
if (candidate && candidate !== control) {
transientParentWindow = candidate;
}
}
}
Component.onCompleted: {
updateTransientParent();
}
onVisibleChanged: {
if (!control.visible) {
return;
}
// 更新父窗口逻辑
updateTransientParent();
// 延迟激活窗口,确保置顶
Qt.callLater(function () {
control.raise();
control.requestActivate();
});
}
// ... 其他代码 ...
}总结原代码逻辑基本正确,能够解决模态对话框父窗口未指定时的默认行为问题。
|
log: In the DialogWindow, when set to WindowModal, the transientParent is automatically set to Qt.application.activeWindow. Upon display, raise() and requestActivate() are called to ensure the main window correctly enters a grayed-out state.
pms: bug-336201
Summary by Sourcery
Bug Fixes: