<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[[Feature Request] Allow WindowModal to exclude transient top-level windows from modal blocking]]></title><description><![CDATA[<h2>Title</h2>
<p dir="auto"><strong>[Feature Request] Allow WindowModal to exclude transient top-level windows from modal blocking</strong></p>
<h2>Description</h2>
<p dir="auto"><code>Qt::WindowModal</code> currently treats transient parents as part of the modal window hierarchy.</p>
<p dir="auto">This can be problematic when a transient/owned top-level window is used for Z-order and lifetime management, but is intended to remain interactive while a modal dialog is open for another top-level window.</p>
<h3>Example</h3>
<p dir="auto">Consider two independent top-level windows:</p>
<pre><code class="language-text">A = main/document window
B = independent tool window
</code></pre>
<p dir="auto">B is a top-level window and has a transient relationship with A.</p>
<p dir="auto">The transient relationship is used for:</p>
<ul>
<li>keeping B above A;</li>
<li>following A's minimize/restore behavior;</li>
<li>following A's visibility/lifetime;</li>
<li>maintaining the desired relationship between the two windows.</li>
</ul>
<p dir="auto">Now A opens a <code>Qt::WindowModal</code> dialog C:</p>
<pre><code class="language-text">        C
        │
        ▼
        A
        │
        B
</code></pre>
<p dir="auto">The desired behavior is:</p>
<pre><code class="language-text">C blocks A
C does not block B
</code></pre>
<p dir="auto">However, B is currently considered part of A's modal hierarchy because Qt's <code>WindowModal</code> implementation follows transient parents.</p>
<p dir="auto">As a result:</p>
<pre><code class="language-text">C blocks A
C also blocks B
</code></pre>
<h3>Relevant Qt API</h3>
<p dir="auto">Qt already has an explicit distinction between normal parent relationships and transient-parent relationships:</p>
<pre><code class="language-cpp">enum AncestorMode {
    ExcludeTransients,
    IncludeTransients
};
</code></pre>
<p dir="auto">The documentation for <code>QWindow::AncestorMode</code> states that <code>ExcludeTransients</code> means that transient parents are not considered ancestors. <code>QWindow::isAncestorOf()</code> and <code>QWindow::parent()</code> support this distinction.</p>
<p dir="auto">However, <code>QGuiApplicationPrivate::isWindowBlocked()</code> currently uses the transient relationship when calculating <code>Qt::WindowModal</code> blocking.</p>
<p dir="auto">In Qt 5, see:</p>
<pre><code class="language-text">qtbase/src/gui/kernel/qguiapplication.cpp

QGuiApplicationPrivate::isWindowBlocked()
</code></pre>
<p dir="auto">The <code>Qt::WindowModal</code> implementation walks both <code>parent()</code> and <code>transientParent()</code>.</p>
<p dir="auto">In Qt 6, the implementation explicitly uses:</p>
<pre><code class="language-cpp">QWindow::IncludeTransients
</code></pre>
<p dir="auto">for the <code>WindowModal</code> ancestor checks:</p>
<pre><code class="language-cpp">if (current-&gt;isAncestorOf(modalWindow,
                          QWindow::IncludeTransients)) {
    ...
}

current = current-&gt;parent(QWindow::IncludeTransients);
</code></pre>
<p dir="auto">Therefore, the current implementation effectively couples:</p>
<pre><code class="language-text">transient-parent relationship
        +
WindowModal blocking hierarchy
</code></pre>
<p dir="auto">These relationships are not necessarily equivalent.</p>
<h3>Why this matters</h3>
<p dir="auto">A transient relationship can be needed purely for window-management purposes:</p>
<pre><code class="language-text">A &lt;---- transient ----&gt; B

Purpose:
    Z-order
    minimize/restore
    lifetime
</code></pre>
<p dir="auto">while the desired modal relationship may be:</p>
<pre><code class="language-text">C ---- modal ----&gt; A

C blocks:
    A

C does not block:
    B
</code></pre>
<p dir="auto">In other words:</p>
<pre><code class="language-text">Z-order/lifetime hierarchy
        !=
modal input-blocking hierarchy
</code></pre>
<h3>Proposed behavior</h3>
<p dir="auto">I suggest providing a way for applications to opt out of transient windows participating in <code>WindowModal</code> blocking.</p>
<p dir="auto">For example, conceptually:</p>
<pre><code class="language-cpp">dialog-&gt;setWindowModality(Qt::WindowModal);
dialog-&gt;setModalAncestorMode(QWindow::ExcludeTransients);
</code></pre>
<p dir="auto">or another API with equivalent semantics.</p>
<p dir="auto">The important point is that this should be <strong>opt-in</strong>, so existing applications retain the current behavior.</p>
<h3>Minimal implementation experiment</h3>
<p dir="auto">The existing implementation can be demonstrated with a very small change.</p>
<p dir="auto">In the Qt 6 implementation, the relevant code currently uses:</p>
<pre><code class="language-cpp">QWindow::IncludeTransients
</code></pre>
<p dir="auto">for <code>WindowModal</code>.</p>
<p dir="auto">As an experiment, replacing the relevant <code>WindowModal</code> ancestor traversal with:</p>
<pre><code class="language-cpp">QWindow::ExcludeTransients
</code></pre>
<p dir="auto">makes transient top-level windows no longer participate in the modal hierarchy.</p>
<p dir="auto">This is not necessarily proposed as the final API/patch, but it demonstrates that Qt already has the necessary ancestor semantics internally.</p>
<p dir="auto">For Qt 5, the equivalent minimal experiment is to make the <code>WindowModal</code> traversal follow only:</p>
<pre><code class="language-cpp">QWindow::parent()
</code></pre>
<p dir="auto">and not:</p>
<pre><code class="language-cpp">QWindow::transientParent()
</code></pre>
<h3>Possible patch direction</h3>
<p dir="auto">A minimal API could be an opt-in property controlling the ancestor mode used by <code>WindowModal</code>.</p>
<p dir="auto">For example:</p>
<pre><code class="language-cpp">class QWindow
{
public:
    enum ModalAncestorMode {
        IncludeTransientParents,
        ExcludeTransientParents
    };

    void setModalAncestorMode(ModalAncestorMode mode);
    ModalAncestorMode modalAncestorMode() const;
};
</code></pre>
<p dir="auto">Then <code>QGuiApplicationPrivate::isWindowBlocked()</code> could use that mode when processing <code>Qt::WindowModal</code>.</p>
<p dir="auto">Alternatively, an API at the application/dialog level could expose the same choice.</p>
<h3>Compatibility consideration</h3>
<p dir="auto">I do <strong>not</strong> suggest changing the existing default behavior unconditionally.</p>
<p dir="auto">There may be applications that intentionally rely on transient windows being blocked together with their parent.</p>
<p dir="auto">The feature could therefore default to the current behavior:</p>
<pre><code class="language-text">WindowModal
    -&gt; IncludeTransients
</code></pre>
<p dir="auto">while allowing applications with independent top-level tool windows to request:</p>
<pre><code class="language-text">WindowModal
    -&gt; ExcludeTransients
</code></pre>
<h3>Minimal reproduction</h3>
<p dir="auto">A minimal reproduction would consist of:</p>
<pre><code class="language-text">A: top-level window
B: independent top-level window with transientParent(A)
C: WindowModal dialog for A
</code></pre>
<p dir="auto">Expected:</p>
<pre><code class="language-text">C blocks A
B remains interactive
</code></pre>
<p dir="auto">Actual:</p>
<pre><code class="language-text">C blocks A
B is also blocked
</code></pre>
<p dir="auto">This issue is not about <code>WindowStaysOnTopHint</code> or global always-on-top behavior.</p>
<p dir="auto">The requirement is specifically to use the transient relationship for window-management/Z-order purposes while keeping the modal input-blocking hierarchy independent from that relationship.</p>
<p dir="auto">Would an API allowing <code>WindowModal</code> to use <code>ExcludeTransients</code> be considered reasonable?</p>
]]></description><link>https://forum.qt.io/topic/165081/feature-request-allow-windowmodal-to-exclude-transient-top-level-windows-from-modal-blocking</link><generator>RSS for Node</generator><lastBuildDate>Sat, 26 Sep 2026 01:16:24 GMT</lastBuildDate><atom:link href="https://forum.qt.io/topic/165081.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 11 Sep 2026 02:01:26 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [Feature Request] Allow WindowModal to exclude transient top-level windows from modal blocking on Fri, 11 Sep 2026 15:01:12 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/aidener">@<bdi>Aidener</bdi></a> I merged your answer with the original thread. Please keep things together.</p>
]]></description><link>https://forum.qt.io/post/840099</link><guid isPermaLink="true">https://forum.qt.io/post/840099</guid><dc:creator><![CDATA[SGaist]]></dc:creator><pubDate>Fri, 11 Sep 2026 15:01:12 GMT</pubDate></item><item><title><![CDATA[Reply to [Feature Request] Allow WindowModal to exclude transient top-level windows from modal blocking on Fri, 11 Sep 2026 11:47:23 GMT]]></title><description><![CDATA[<p dir="auto">Re: <a href="/topic/165081/feature-request-allow-windowmodal-to-exclude-transient-top-level-windows-from-modal-blocking">[Feature Request] Allow WindowModal to exclude transient top-level windows from modal blocking</a></p>
<p dir="auto">I am So sory for reply lately.  Using Ai just for saving the time and hope to statement clearly but seem as not well.  This is Minimal code to show my question.  Somebody try and comment will be appreciateed!</p>
<pre><code>#include &lt;QApplication&gt;
#include &lt;QMainWindow&gt;
#include &lt;QDialog&gt;
#include &lt;QPushButton&gt;
#include &lt;QVBoxLayout&gt;
#include &lt;QWindow&gt;

#define SECTION_USE_setTransientParent

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);

    QMainWindow* mainWindow = new QMainWindow;
    mainWindow-&gt;setWindowTitle("A - MainWindow");
    mainWindow-&gt;resize(400, 300);

    auto* openButton = new QPushButton(
        "Open WindowModal Dialog",
        mainWindow
    );
    mainWindow-&gt;setCentralWidget(openButton);

    // B: A top level Dialog for message. example for license, global tip for document
    // Sometimes we need to show some unimportant message and just affirm when user is free
    QDialog* TipDialog = new QDialog(); //parent NULL for C with Qt::WindowModal can not block it.
    TipDialog-&gt;setWindowTitle("B - Non-modal Dialog");
    TipDialog-&gt;setModal(false);
    TipDialog-&gt;setWindowModality(Qt::NonModal);
    TipDialog-&gt;resize(250, 150);

    auto* toolButton = new QPushButton("Click B");
    auto* toolLayout = new QVBoxLayout(TipDialog);
    toolLayout-&gt;addWidget(toolButton);

#ifdef SECTION_USE_setTransientParent
    // set B -&gt; A transient relationship
    TipDialog-&gt;winId(); //Just for get windwow hwd. Another way By Using show() instead.
    mainWindow-&gt;winId();
    //keep TipDialog always over mainWindow and 
    //Z-order : lower with mainWindow when other process activate
    //minimize / restore
    //attention that setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint) can not get the same result
    TipDialog-&gt;windowHandle()-&gt;setTransientParent(
        mainWindow-&gt;windowHandle()
    );
#else
    //nothing
    //TipDialog is independent but as a message dialog, it is unaccepted
    // when other process activate and show inside of TipDialog and mainWindow.
    TipDialog-&gt;setWindowFlags(TipDialog-&gt;windowFlags() | Qt::WindowStaysOnTopHint);
#endif 

    // C:  WindowModal Dialog of MainWindow
    QObject::connect(openButton, &amp;QPushButton::clicked, [&amp;] {
        //as child of MainWindow. Sometimes like the QMessageBox::Information but excec() was Qt::ApplicationModal
        auto* dialog = new QDialog(mainWindow);
        dialog-&gt;setWindowTitle("C - WindowModal");
        auto* closeButton = new QPushButton("Close", dialog);
        auto* layout = new QVBoxLayout(dialog);
        layout-&gt;addWidget(closeButton);

        QObject::connect(
            closeButton,
            &amp;QPushButton::clicked,
            dialog,
            &amp;QDialog::accept
        );

        dialog-&gt;setWindowModality(Qt::WindowModal); //only block itself and parent window
        dialog-&gt;open(); //this calls will block B out of expectation
        });

    mainWindow-&gt;show();

    TipDialog-&gt;move(
        mainWindow-&gt;x() + mainWindow-&gt;width() + 20,
        mainWindow-&gt;y()
    );
    TipDialog-&gt;show();

    return app.exec();
}
</code></pre>
<p dir="auto">After compiling it will show like that.<br />
<img src="https://ddgobkiprc33d.cloudfront.net/aa8f7a28-f6a4-4ff5-9641-741dd73e21eb.gif" alt="PixPin_2026-09-11_19-06-36.gif" class=" img-fluid img-markdown" /></p>
<p dir="auto"><img src="https://ddgobkiprc33d.cloudfront.net/7f2267db-1b40-4dcf-9ba4-468ce589b778.png" alt="c3ceb919-a127-4abe-a022-66adb64e37d4-image.png" class=" img-fluid img-markdown" /></p>
]]></description><link>https://forum.qt.io/post/840098</link><guid isPermaLink="true">https://forum.qt.io/post/840098</guid><dc:creator><![CDATA[Aidener]]></dc:creator><pubDate>Fri, 11 Sep 2026 11:47:23 GMT</pubDate></item><item><title><![CDATA[Reply to [Feature Request] Allow WindowModal to exclude transient top-level windows from modal blocking on Fri, 11 Sep 2026 06:54:53 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/simonschroeder">@<bdi>SimonSchroeder</bdi></a> said in <a href="/post/840092">[Feature Request] Allow WindowModal to exclude transient top-level windows from modal blocking</a>:</p>
<blockquote>
<p dir="auto">BTW, I don't think that AI made your feature request any better.</p>
</blockquote>
<p dir="auto">tbh - I don't read such stuff at all anymore, it's to much with no real information. Just bloated AI slop.</p>
]]></description><link>https://forum.qt.io/post/840093</link><guid isPermaLink="true">https://forum.qt.io/post/840093</guid><dc:creator><![CDATA[Christian Ehrlicher]]></dc:creator><pubDate>Fri, 11 Sep 2026 06:54:53 GMT</pubDate></item><item><title><![CDATA[Reply to [Feature Request] Allow WindowModal to exclude transient top-level windows from modal blocking on Fri, 11 Sep 2026 06:50:43 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/aidener">@<bdi>Aidener</bdi></a> said in <a href="/post/840091">[Feature Request] Allow WindowModal to exclude transient top-level windows from modal blocking</a>:</p>
<blockquote>
<p dir="auto">B = independent tool window</p>
</blockquote>
<p dir="auto">Don't make A the parent of B if you really mean "independent" tool window. Just pass <code>nullptr</code> as parent to B. If you using <code>WindowModal</code> instead of <code>AppModal</code> this should work. But I see your point about visibility and lifetime.</p>
<p dir="auto">BTW, I don't think that AI made your feature request any better. Longer text does not necessarily better provides the point of your feature request. The way you told AI what feature you expect would have been a lot more helpful for us (I guess). The AI just gave the general structure for a proposal. The "minimal implementation experiment" is not an experiment because it does not contain any real source code (you'd have to fill that section yourself). The "possible patch direction" is still incomplete (it is only half the patch). And the "minimal reproduction" is no reproduction at all because it does not contain any source code that could be tested. Again, you'd have to fill out that section yourself. I am quite annoyed by people just posting AI slop. At least turn on your brain and check the output of AI (and modify it to make it suitable for the target audience). (I just tried it: Even AI cannot summerize your post and get to the key points.)</p>
]]></description><link>https://forum.qt.io/post/840092</link><guid isPermaLink="true">https://forum.qt.io/post/840092</guid><dc:creator><![CDATA[SimonSchroeder]]></dc:creator><pubDate>Fri, 11 Sep 2026 06:50:43 GMT</pubDate></item></channel></rss>