diff --git a/autotests/integration/stacking_order_test.cpp b/autotests/integration/stacking_order_test.cpp --- a/autotests/integration/stacking_order_test.cpp +++ b/autotests/integration/stacking_order_test.cpp @@ -54,7 +54,6 @@ void testGroupTransientIsAboveWindowGroup(); void testRaiseGroupTransient(); - void testDontKeepAboveNonModalDialogGroupTransients(); }; @@ -316,27 +315,6 @@ windowCreatedSpy.clear(); xcb_window_t transientWid = createGroupWindow(conn.data(), geometry, leaderWid); xcb_icccm_set_wm_transient_for(conn.data(), transientWid, rootWindow()); - - // Currently, we have some weird bug workaround: if a group transient - // is a non-modal dialog, then it won't be kept above its window group. - // We need to explicitly specify window type, otherwise the window type - // will be deduced to _NET_WM_WINDOW_TYPE_DIALOG because we set transient - // for before (the EWMH spec says to do that). - xcb_atom_t net_wm_window_type = Xcb::Atom( - QByteArrayLiteral("_NET_WM_WINDOW_TYPE"), false, conn.data()); - xcb_atom_t net_wm_window_type_normal = Xcb::Atom( - QByteArrayLiteral("_NET_WM_WINDOW_TYPE_NORMAL"), false, conn.data()); - xcb_change_property( - conn.data(), // c - XCB_PROP_MODE_REPLACE, // mode - transientWid, // window - net_wm_window_type, // property - XCB_ATOM_ATOM, // type - 32, // format - 1, // data_len - &net_wm_window_type_normal // data - ); - xcb_map_window(conn.data(), transientWid); xcb_flush(conn.data()); @@ -348,7 +326,6 @@ QCOMPARE(transient->group(), leader->group()); QVERIFY(transient->isTransient()); QVERIFY(transient->groupTransient()); - QVERIFY(!transient->isDialog()); // See above why QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2, transient})); @@ -430,27 +407,6 @@ windowCreatedSpy.clear(); xcb_window_t transientWid = createGroupWindow(conn.data(), geometry, leaderWid); xcb_icccm_set_wm_transient_for(conn.data(), transientWid, rootWindow()); - - // Currently, we have some weird bug workaround: if a group transient - // is a non-modal dialog, then it won't be kept above its window group. - // We need to explicitly specify window type, otherwise the window type - // will be deduced to _NET_WM_WINDOW_TYPE_DIALOG because we set transient - // for before (the EWMH spec says to do that). - xcb_atom_t net_wm_window_type = Xcb::Atom( - QByteArrayLiteral("_NET_WM_WINDOW_TYPE"), false, conn.data()); - xcb_atom_t net_wm_window_type_normal = Xcb::Atom( - QByteArrayLiteral("_NET_WM_WINDOW_TYPE_NORMAL"), false, conn.data()); - xcb_change_property( - conn.data(), // c - XCB_PROP_MODE_REPLACE, // mode - transientWid, // window - net_wm_window_type, // property - XCB_ATOM_ATOM, // type - 32, // format - 1, // data_len - &net_wm_window_type_normal // data - ); - xcb_map_window(conn.data(), transientWid); xcb_flush(conn.data()); @@ -462,7 +418,6 @@ QCOMPARE(transient->group(), leader->group()); QVERIFY(transient->isTransient()); QVERIFY(transient->groupTransient()); - QVERIFY(!transient->isDialog()); // See above why QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2, transient})); @@ -501,100 +456,5 @@ QCOMPARE(workspace()->stackingOrder(), (ToplevelList{member1, leader, member2, anotherClient, transient})); } -void StackingOrderTest::testDontKeepAboveNonModalDialogGroupTransients() -{ - // Bug 76026 - - const QRect geometry = QRect(0, 0, 128, 128); - - QScopedPointer conn( - xcb_connect(nullptr, nullptr)); - - QSignalSpy windowCreatedSpy(workspace(), &Workspace::clientAdded); - QVERIFY(windowCreatedSpy.isValid()); - - // Create the group leader. - xcb_window_t leaderWid = createGroupWindow(conn.data(), geometry); - xcb_map_window(conn.data(), leaderWid); - xcb_flush(conn.data()); - - QVERIFY(windowCreatedSpy.wait()); - Client *leader = windowCreatedSpy.first().first().value(); - QVERIFY(leader); - QVERIFY(leader->isActive()); - QCOMPARE(leader->windowId(), leaderWid); - QVERIFY(!leader->isTransient()); - - QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader})); - - // Create another group member. - windowCreatedSpy.clear(); - xcb_window_t member1Wid = createGroupWindow(conn.data(), geometry, leaderWid); - xcb_map_window(conn.data(), member1Wid); - xcb_flush(conn.data()); - - QVERIFY(windowCreatedSpy.wait()); - Client *member1 = windowCreatedSpy.first().first().value(); - QVERIFY(member1); - QVERIFY(member1->isActive()); - QCOMPARE(member1->windowId(), member1Wid); - QCOMPARE(member1->group(), leader->group()); - QVERIFY(!member1->isTransient()); - - QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1})); - - // Create yet another group member. - windowCreatedSpy.clear(); - xcb_window_t member2Wid = createGroupWindow(conn.data(), geometry, leaderWid); - xcb_map_window(conn.data(), member2Wid); - xcb_flush(conn.data()); - - QVERIFY(windowCreatedSpy.wait()); - Client *member2 = windowCreatedSpy.first().first().value(); - QVERIFY(member2); - QVERIFY(member2->isActive()); - QCOMPARE(member2->windowId(), member2Wid); - QCOMPARE(member2->group(), leader->group()); - QVERIFY(!member2->isTransient()); - - QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2})); - - // Create a group transient. - windowCreatedSpy.clear(); - xcb_window_t transientWid = createGroupWindow(conn.data(), geometry, leaderWid); - xcb_icccm_set_wm_transient_for(conn.data(), transientWid, rootWindow()); - xcb_map_window(conn.data(), transientWid); - xcb_flush(conn.data()); - - QVERIFY(windowCreatedSpy.wait()); - Client *transient = windowCreatedSpy.first().first().value(); - QVERIFY(transient); - QVERIFY(transient->isActive()); - QCOMPARE(transient->windowId(), transientWid); - QCOMPARE(transient->group(), leader->group()); - QVERIFY(transient->isTransient()); - QVERIFY(transient->groupTransient()); - QVERIFY(transient->isDialog()); - QVERIFY(!transient->isModal()); - - QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2, transient})); - - workspace()->activateClient(leader); - QTRY_VERIFY(leader->isActive()); - QCOMPARE(workspace()->stackingOrder(), (ToplevelList{member1, member2, transient, leader})); - - workspace()->activateClient(member1); - QTRY_VERIFY(member1->isActive()); - QCOMPARE(workspace()->stackingOrder(), (ToplevelList{member2, transient, leader, member1})); - - workspace()->activateClient(member2); - QTRY_VERIFY(member2->isActive()); - QCOMPARE(workspace()->stackingOrder(), (ToplevelList{transient, leader, member1, member2})); - - workspace()->activateClient(transient); - QTRY_VERIFY(transient->isActive()); - QCOMPARE(workspace()->stackingOrder(), (ToplevelList{leader, member1, member2, transient})); -} - WAYLANDTEST_MAIN(StackingOrderTest) #include "stacking_order_test.moc" diff --git a/layers.cpp b/layers.cpp --- a/layers.cpp +++ b/layers.cpp @@ -621,14 +621,6 @@ // #93832 - don't keep splashscreens above dialogs if (transient->isSplash() && mainwindow->isDialog()) return false; - // This is rather a hack for #76026. Don't keep non-modal dialogs above - // the mainwindow, but only if they're group transient (since only such dialogs - // have taskbar entry in Kicker). A proper way of doing this (both kwin and kicker) - // needs to be found. - if (const Client *ct = dynamic_cast(transient)) { - if (ct->isDialog() && !ct->isModal() && ct->groupTransient()) - return false; - } // #63223 - don't keep transients above docks, because the dock is kept high, // and e.g. dialogs for them would be too high too // ignore this if the transient has a placement hint which indicates it should go above it's parent