Skip to content

fix: Main interface does not gray out when losing focus#570

Open
JWWTSL wants to merge 1 commit intolinuxdeepin:masterfrom
JWWTSL:master
Open

fix: Main interface does not gray out when losing focus#570
JWWTSL wants to merge 1 commit intolinuxdeepin:masterfrom
JWWTSL:master

Conversation

@JWWTSL
Copy link
Contributor

@JWWTSL JWWTSL commented Feb 7, 2026

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:

  • Automatically associate window-modal dialogs with the current active window as their transient parent to restore expected grayed-out background behavior when dialogs appear.

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
@sourcery-ai
Copy link

sourcery-ai bot commented Feb 7, 2026

Reviewer's Guide

Ensures 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 graying

sequenceDiagram
    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
Loading

Updated class diagram for DialogWindow QML component

classDiagram
    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
Loading

File-Level Changes

Change Details Files
Wire DialogWindow.transientParent through a dedicated property to allow dynamic assignment while keeping QML bindings clean.
  • Introduce a transientParentWindow var property initialized to null.
  • Bind the Window.transientParent to transientParentWindow so it can be updated programmatically.
qt6/src/qml/DialogWindow.qml
Automatically select an appropriate transient parent for WindowModal dialogs when they are created.
  • On Component.onCompleted, if the dialog is WindowModal and no transient parent has been set, assign Qt.application.activeWindow as the transient parent window.
qt6/src/qml/DialogWindow.qml
Ensure WindowModal dialogs properly gray out and block their parent window when they become visible.
  • Handle onVisibleChanged to early-return for non-visible or non-WindowModal dialogs.
  • Re-evaluate and, if needed, reset transientParentWindow to the current active window when the dialog is shown, avoiding self-parenting.
  • Use Qt.callLater to asynchronously call raise() and requestActivate() on the dialog so that modality and z-order are correctly applied after it becomes visible.
qt6/src/qml/DialogWindow.qml

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 - I've left some high level feedback:

  • 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.
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.

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.

Copy link

Copilot AI left a 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 transientParentWindow property and bind transientParent to it.
  • Auto-assign transientParentWindow to Qt.application.activeWindow for Qt.WindowModal dialogs.
  • 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.

Comment on lines +66 to +81
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()
})
Copy link

Copilot AI Feb 7, 2026

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.

Copilot uses AI. Check for mistakes.
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.

1 participant