Bug 493778

Summary: kwin deadlock on disconnect/reconnect external monitor
Product: [Plasma] kwin Reporter: Ike Devolder <ike.devolder>
Component: multi-screenAssignee: KWin default assignee <kwin-bugs-null>
Status: RESOLVED FIXED    
Severity: major CC: nate, xaver.hugl
Priority: NOR Keywords: multiscreen
Version: 6.1.90   
Target Milestone: ---   
Platform: Arch Linux   
OS: Linux   
Latest Commit: Version Fixed In: 6.2.0
Sentry Crash Report:
Attachments: konsole window rule

Description Ike Devolder 2024-09-28 11:50:45 UTC
SUMMARY

It is not 100% on reconnect, but usually disconnecting an external diplay works fine and reconnecting sends kwin_wayland to ~100% cpu on a laptop with intel/nvidia (iris/nouveau). This is visible in a way that you can see the interface, but no mouse input works, no keyboard input works, you can't even seem to switch to VT as well.

STEPS TO REPRODUCE

1. log in, have laptop internal monitor as secondary and external display as primary, all open windows are on external display
2. disconnect external display (usually in my case this works) (what I have noticed is that evolution is not showing up on my laptop display and that that window if you click in the task manager looks like it is still on another display, while that is not there)
3. reconnect external display -> nothing shows up there, get a "no signal" and if I ssh into the machine kwin_wayland is doing ~100% cpu

OBSERVED RESULT

You think the system hangs, no input is possible, no mouse, nothing

I have observed this with kwin 6.1.5-1, so I installed KDE-Unstable to see if it was also the case there

With kwin 6.1.90 I have installed what I think the relevant -debug packages and attached gdb which resulted in these stacks: https://pastebin.com/5YiaBj6Y

EXPECTED RESULT

keep working and move all my open windows to the correct display

SOFTWARE/OS VERSIONS
Windows: 
macOS: 
(available in the Info Center app, or by running `kinfo` in a terminal window)
Linux/KDE Plasma: 
KDE Plasma Version: 6.1.90
KDE Frameworks Version: 6.6.0
Qt Version: 6.8.0rc1

ADDITIONAL INFORMATION
Comment 1 Zamundaaa 2024-09-30 16:38:34 UTC
If you can debug the process, could you check if KWin ever steps out of PlacementTracker::restore?
Comment 2 Ike Devolder 2024-09-30 19:38:13 UTC
I did an attempt to debug and have pasted the info here: https://pastebin.com/cFWUBPCE
Comment 3 Ike Devolder 2024-09-30 20:40:40 UTC
Maybe this was a better try:

```
(gdb) attach 1984
Attaching to process 1984
[New LWP 33811]
[New LWP 33810]
[New LWP 2078]
[New LWP 2077]
[New LWP 2076]
[New LWP 2074]
[New LWP 2068]
[New LWP 2067]
[New LWP 2060]
[New LWP 2059]
[New LWP 2046]
[New LWP 2038]
[New LWP 2036]
[New LWP 2035]
[New LWP 2027]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
KWin::Window::desktops (this=this@entry=0x55f67e8d3460) at /usr/include/qt6/QtCore/qarraydata.h:60
warning: Source file is more recent than executable.
60              return true;
(gdb) finish
Run till exit from #0  KWin::Window::desktops (this=this@entry=0x55f67e8d3460) at /usr/include/qt6/QtCore/qarraydata.h:60
KWin::Window::isOnAllDesktops (this=0x55f67e8d3460) at /usr/src/debug/kwin/kwin-6.1.90/src/window.h:2047
2047        return desktops().isEmpty();
Value returned is $1 = {<QListSpecialMethods<KWin::VirtualDesktop*>> = {<QListSpecialMethodsBase<KWin::VirtualDesktop*>> = {<No data fields>}, <No data fields>}, d = {d = 0x55f67cd30df0, ptr = 0x55f67cd30e00, size = 1}}
(gdb) finish
Run till exit from #0  KWin::Window::isOnAllDesktops (this=0x55f67e8d3460) at /usr/src/debug/kwin/kwin-6.1.90/src/window.h:2047
KWin::Workspace::clientArea (this=0x55f67cf2b9e0, opt=KWin::MaximizeArea, window=0x55f67e8d3460, output=0x55f67de6a620) at /usr/src/debug/kwin/kwin-6.1.90/src/workspace.cpp:2444
2444            desktop = VirtualDesktopManager::self()->currentDesktop();
(gdb) finish
Run till exit from #0  KWin::Workspace::clientArea (this=0x55f67cf2b9e0, opt=KWin::MaximizeArea, window=0x55f67e8d3460, output=0x55f67de6a620)
    at /usr/src/debug/kwin/kwin-6.1.90/src/workspace.cpp:2444
0x00007f617d1aa089 in KWin::XdgToplevelWindow::maximize (this=0x55f67e8d3460, mode=KWin::MaximizeRestore) at /usr/src/debug/kwin/kwin-6.1.90/src/xdgshellwindow.cpp:1563
1563        const QRectF clientArea = isElectricBorderMaximizing() ? workspace()->clientArea(MaximizeArea, this, interactiveMoveResizeAnchor()) : workspace()->clientArea(MaximizeArea, this, moveResizeOutput());
Value returned is $2 = {xp = 0, yp = 36, w = 1920, h = 1164}
(gdb) finish
Run till exit from #0  0x00007f617d1aa089 in KWin::XdgToplevelWindow::maximize (this=0x55f67e8d3460, mode=KWin::MaximizeRestore)
    at /usr/src/debug/kwin/kwin-6.1.90/src/xdgshellwindow.cpp:1563
KWin::Window::setQuickTileMode (this=0x55f67e8d3460, mode=..., tileAtPoint=...) at /usr/src/debug/kwin/kwin-6.1.90/src/window.cpp:3516
3516        if (!isResizable() || isAppletPopup()) {
(gdb) finish
Run till exit from #0  KWin::Window::setQuickTileMode (this=0x55f67e8d3460, mode=..., tileAtPoint=...) at /usr/src/debug/kwin/kwin-6.1.90/src/window.cpp:3516
```
There it gets stuck it seems
Comment 4 Ike Devolder 2024-10-01 05:24:15 UTC
Maybe additional info that could be interesting:

laptop screen resolution: 1920x1200 (16:10)
external screen resolution: 1920x1080 (16:9)

on an older laptop (with only intel gpu) I don't have this issue but there the internal screen and external screen are 1920x1080 (16:9)
Comment 5 Zamundaaa 2024-10-01 14:41:25 UTC
hmm, I couldn't reproduce this issue, even with two screens that have different resolutions. I found something else (https://invent.kde.org/plasma/kwin/-/merge_requests/6545), which could influence this, but it seems unlikely.

Looking at the code, I don't understand how KWin can get stuck in Window::setQuickTileMode. Could you step through the function a bit and see if there's some more specific spot it gets stuck in?
Comment 6 Ike Devolder 2024-10-01 14:57:36 UTC
(In reply to Zamundaaa from comment #5)
> hmm, I couldn't reproduce this issue, even with two screens that have
> different resolutions. I found something else
> (https://invent.kde.org/plasma/kwin/-/merge_requests/6545), which could
> influence this, but it seems unlikely.
> 
> Looking at the code, I don't understand how KWin can get stuck in
> Window::setQuickTileMode. Could you step through the function a bit and see
> if there's some more specific spot it gets stuck in?

The pastebin from https://bugs.kde.org/show_bug.cgi?id=493778#c2 is not good for this?
Comment 7 Zamundaaa 2024-10-01 15:32:06 UTC
It is useful, but it suggests an infinite recursion between setMaximize(false, false) and setQuickTileMode, which should crash and not hang.

Something else I see in there though... do you have a window rule that forces a window to be (not) maximized?
Comment 8 Bug Janitor Service 2024-10-01 15:38:01 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/kwin/-/merge_requests/6547
Comment 9 Zamundaaa 2024-10-01 15:38:18 UTC
If you do have a window rule like that, this MR should fix the hang
Comment 10 Ike Devolder 2024-10-01 15:39:52 UTC
Created attachment 174287 [details]
konsole window rule

I have a windowrule for konsole to have no titlebar and frame and be maximized both horizontally and vertically
Comment 11 Ike Devolder 2024-10-01 15:47:28 UTC
On first glance: removing the window rule indeed fixes the issue, thank you very much
Comment 12 Zamundaaa 2024-10-01 16:50:05 UTC
Git commit 68015321e924e1dd54770df748cd42440aaf204f by Xaver Hugl.
Committed on 01/10/2024 at 16:42.
Pushed by zamundaaa into branch 'master'.

window: prevent infinite recursion in setQuickTileMode

If there's a window rule, setMaximize may not actually change the maximize mode, so this
needs to be accounted for

M  +4    -0    src/window.cpp

https://invent.kde.org/plasma/kwin/-/commit/68015321e924e1dd54770df748cd42440aaf204f
Comment 13 Zamundaaa 2024-10-01 17:09:50 UTC
Git commit 35e50d6f87ec632c939b059011a3b39389e2092b by Xaver Hugl.
Committed on 01/10/2024 at 16:50.
Pushed by zamundaaa into branch 'Plasma/6.2'.

window: prevent infinite recursion in setQuickTileMode

If there's a window rule, setMaximize may not actually change the maximize mode, so this
needs to be accounted for


(cherry picked from commit 68015321e924e1dd54770df748cd42440aaf204f)

Co-authored-by: Xaver Hugl <xaver.hugl@gmail.com>

M  +4    -0    src/window.cpp

https://invent.kde.org/plasma/kwin/-/commit/35e50d6f87ec632c939b059011a3b39389e2092b
Comment 14 Zamundaaa 2024-10-01 17:32:05 UTC
Great! Thank you for the extensive debugging info btw, this would've been impossible to track down otherwise
Comment 15 Ike Devolder 2024-10-01 18:11:01 UTC
Thank you for fixing it, I have re-build kwin with the patch + re-added the konsole window rules and it works properly now