-
Notifications
You must be signed in to change notification settings - Fork 45
fix: Main interface does not gray out when losing focus #570
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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() | ||
| }) |
Copilot
AI
Feb 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
deepin pr auto review这段代码主要对 以下是对该代码的详细审查意见,分为语法逻辑、代码质量、代码性能和代码安全四个方面: 1. 语法逻辑
2. 代码质量
3. 代码性能
4. 代码安全
改进后的代码示例基于以上意见,建议修改如下: Window {
id: control
// ... 其他属性 ...
// 明确类型,建议使用 QWindow 或者具体的窗口类型
property Item transientParentWindow: null
// 仅在初始化时绑定一次,避免动态修改带来的副作用
// 如果确实需要动态修改,请确保平台支持
transientParent: transientParentWindow
Item {
id: content
// ...
}
// 提取公共逻辑
function updateTransientParent() {
if (control.modality !== Qt.WindowModal) {
return;
}
// 如果已有父窗口且不是自身,通常不需要更改,除非业务逻辑要求总是跟随活动窗口
// 这里假设逻辑是:如果没有父窗口,则尝试获取活动窗口
if (!transientParentWindow || transientParentWindow === control) {
var candidate = Qt.application.activeWindow;
// 增加更严格的检查,确保 candidate 有效且不是自身
if (candidate && candidate !== control && candidate.visible) {
transientParentWindow = candidate;
}
}
}
Component.onCompleted: {
updateTransientParent();
}
onVisibleChanged: {
if (!control.visible) {
return;
}
// 每次显示时更新父窗口逻辑(根据实际需求决定是否总是更新)
updateTransientParent();
Qt.callLater(function () {
control.raise();
control.requestActivate();
});
}
onClosing: function(close) {
// ...
}
}总结原代码主要解决了模态对话框找不到父窗口时的回退逻辑,并优化了显示时的激活行为。主要改进点在于:明确属性类型、消除重复逻辑、优化类型检查,以及根据实际业务需求确认 |
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: