Bug 477262 - Incorrect window stacking order of transient windows
Summary: Incorrect window stacking order of transient windows
Status: RESOLVED FIXED
Alias: None
Product: kwin
Classification: Plasma
Component: core (show other bugs)
Version: git master
Platform: Neon Linux
: NOR normal
Target Milestone: ---
Assignee: KWin default assignee
URL:
Keywords: qt6, regression
Depends on:
Blocks:
 
Reported: 2023-11-20 02:36 UTC by Jarek Janik
Modified: 2023-11-22 17:05 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jarek Janik 2023-11-20 02:36:59 UTC
SUMMARY
When stacking windows kwin correctly obeys the "constraints" between windows (by means of struct Constraint in workspace.h, i.e. transients go above parents), but ignores the order in which user has stacked the windows - windows are stacked in order they were created (oldest window goes on top) in many circumstances.
This has regressed somewhere between 4.20.5 (debian 11) and 4.27 (debian 12)
***
STEPS TO REPRODUCE
1. Run KCalc (KCalc is just an example here)
2. Open transient windows (in this order): Help/About Calc, Help/About KDE, Settings/Configure KCalc, place them so that they all overlap each other but some part of each window is always visible.
3. Click on them for a while - observe that the only constrain is that each transient window must be above main window - there are no constraints between transients - each one can be stacked above any other.

OBSERVED RESULT
4. Despite the lack of constraints between transients you cannot stack them freely - when you click on a transient it is raised as expected, but the other 2 are restacked in order they were created (unless already in that order).
5. When you click on main window - all transients are restacked in order of their creation (unless already in that order).
6. When you make main window "KeepAbove" all transients are restacked in order of creation and you cannot change that order anymore.

EXPECTED RESULT
4. Clicked transient is raised, but the other transients are not restacked, they are kept in order they were stacked by the user. 
5. Transients are not restacked, they are kept in order they were stacked by the user. 
6. Transients are not restacked, they are kept in order they were stacked by the user, user can still restack them freely.

SOFTWARE/OS VERSIONS
Linux: KDE Neon Unstable
KDE Plasma Version: 5.27.80
KDE Frameworks Version: 5.240.0
Qt Version: 6.6.0
Comment 1 Jarek Janik 2023-11-20 03:27:37 UTC
MR with fix is here:
https://invent.kde.org/plasma/kwin/-/merge_requests/4666
Comment 2 Bug Janitor Service 2023-11-21 09:46:19 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/kwin/-/merge_requests/4678
Comment 3 Vlad Zahorodnii 2023-11-21 19:34:55 UTC
Git commit 15b8fbe6044a0fd3cb66af78d7e4e44338be5b58 by Vlad Zahorodnii.
Committed on 21/11/2023 at 20:26.
Pushed by vladz into branch 'master'.

Preserve relative order of transient siblings

If a constraint indicates that window A must be below window B but it's
not the case at the moment, the workspace will move window A right after
window B.

This can invert the relative order of transient siblings, for example
let's say that there are three constraints

- A <- B (window A must be below window B)
- A <- C
- A <- D

and the unconstrained stacking order looks as follows: [B, C, D, A]. The
final constrained stacking order is expected to look as [A, B, C, D],
but currently it's [A, D, C, B] instead:

- starting stacking order: [B, C, D, A]
- apply A <- B constraint: [C, D, A, B]
- apply A <- C constraint: [D, A, C, B]
- apply A <- D constraint: [A, D, C, B]

In order to fix this issue, this patch makes the workspace traverse the
constraint graph in the reverse order. In addition to that, it ensures
that the relative order of transient siblings in unconstrained stacking
order is preserved in the constrained one.

M  +16   -7    src/layers.cpp

https://invent.kde.org/plasma/kwin/-/commit/15b8fbe6044a0fd3cb66af78d7e4e44338be5b58
Comment 4 Vlad Zahorodnii 2023-11-22 17:05:52 UTC
Git commit 43b2dfa3a2c97dc47a1f7edce488ff172a8a2430 by Vlad Zahorodnii.
Committed on 22/11/2023 at 08:01.
Pushed by vladz into branch 'Plasma/5.27'.

Preserve relative order of transient siblings

If a constraint indicates that window A must be below window B but it's
not the case at the moment, the workspace will move window A right after
window B.

This can invert the relative order of transient siblings, for example
let's say that there are three constraints

- A <- B (window A must be below window B)
- A <- C
- A <- D

and the unconstrained stacking order looks as follows: [B, C, D, A]. The
final constrained stacking order is expected to look as [A, B, C, D],
but currently it's [A, D, C, B] instead:

- starting stacking order: [B, C, D, A]
- apply A <- B constraint: [C, D, A, B]
- apply A <- C constraint: [D, A, C, B]
- apply A <- D constraint: [A, D, C, B]

In order to fix this issue, this patch makes the workspace traverse the
constraint graph in the reverse order. In addition to that, it ensures
that the relative order of transient siblings in unconstrained stacking
order is preserved in the constrained one.


(cherry picked from commit 15b8fbe6044a0fd3cb66af78d7e4e44338be5b58)

M  +16   -7    src/layers.cpp

https://invent.kde.org/plasma/kwin/-/commit/43b2dfa3a2c97dc47a1f7edce488ff172a8a2430