Bug 494001

Summary: windows frequently stuck offscreen when turning on/off monitors, can't use "move" or kwin script to get back on-screen
Product: [Plasma] kwin Reporter: andy <andy>
Component: wayland-genericAssignee: KWin default assignee <kwin-bugs-null>
Status: RESOLVED FIXED    
Severity: normal CC: kdedev, nate, xaver.hugl
Priority: NOR Keywords: multiscreen
Version: 6.1.5   
Target Milestone: ---   
Platform: Other   
OS: Linux   
See Also: https://bugs.kde.org/show_bug.cgi?id=496824
Latest Commit: Version Fixed In: 6.3.0
Sentry Crash Report:
Attachments: Firefox partially on right side of display

Description andy 2024-10-02 22:10:58 UTC
SUMMARY
I have three monitors connected. At night I turn them off. In the morning I turn them on. Often there are windows which are stuck offscreen and the usual tricks for moving them don't work (e.g. right click item on task manager > more > move; also kwin scripts fail to move windows). But when I repeatedly click the item in the task manager which would minimize/un-minimze the window, I can see the "Magic Lamp" effect swooping the window into the taskbar and out of the taskbar to somewhere offscreen to the upper right of my monitors.

I can't say whether this happens more to some windows or application types more than others. Some recent ones I can think of are windows in an electron app (obsidian, native wayland mode), and a jupyter qtconsole window (native wayland window).

One solution that would be nice is a way to turn off display port monitors without kwin actually disconnecting them. I never need kwin to automatically shuffle all my windows and panels and widgets all over the place just cause I want to turn off my screens. The display configuration could have a checkbox next to "Enabled" for "Frozen" or "Locked" to tell kwin to keep that monitor frozen in the current layout. For my permanent desktop setup, I would check off every one of those. I could previously achieve this effect by stopping the KScreen background service, but that stopped working (possibly with wayland), not to mention background services aren't shown in settings anymore.


STEPS TO REPRODUCE
0. Have a bunch of windows open
1. Turn off three monitors one at a time
2. Turn on three monitors one at a time
3. See if you can access each window
4. See if you can use "Move" function from task manager right click menu to move the window on-screen
5. See if you can use a kwin script to change the position of the window

OBSERVED RESULT
- Some windows cannot be accessed and are stuck offscreen.
- Can't use "move" function. 
- Kwin script cannot change stuck window position or geometry. See more details in bottom section.

EXPECTED RESULT
- Windows should always be in valid desktop area.
- "Move" function should always let you move a window from an invalid area to valid desktop area
- kwin script should always let you change window geometry, regardless if it is currently in an invalid area

SOFTWARE/OS VERSIONS
Operating System: Arch Linux
KDE Plasma Version: 6.1.5
KDE Frameworks Version: 6.6.0
Qt Version: 6.7.2
Kernel Version: 6.6.52-1-lts (64-bit)
Graphics Platform: Wayland
Processors: 16 × Intel® Core™ i9-9900K CPU @ 3.60GHz
Memory: 62.6 GiB of RAM
Graphics Processor: AMD Radeon RX 6600

ADDITIONAL INFORMATION
https://bugs.kde.org/show_bug.cgi?id=452118 is related/closed and was suggested to open new bug reports


LIVE EXAMPLE

I have a window stuck offscreen right now.

My screens look like this:

    DP-6        2560,360,3840x2160
    DP-7        0,1440,2560x1440
    DP-5        0,0,2560x1440
> +-------------------+
> |                   |-----------------------------+
> |       DP-5        |                             |
> |                   |                             |
> |                   |                             |
> +-------------------+            DP-6             |
> |                   |                             |
> |       DP-7        |                             |
> |                   |                             |
> |                   |-----------------------------+
> +-------------------+

The window stuck offscreen is a Jupyter QtConsole (native wayland window). In the kwin debug console it says: bufferGeometry: 7362,28 958x1052
Since I can't screenshot that or copy the rest of the values, in `plasma-interactiveconsole --kwin` I'll dump the client info matching to it's pid

const clients = workspace.windowList();
for (var i = 0; i < clients.length; i++) {
    var client = clients[i]
    if (client.pid === 3082266) {
        // JSON.stringify(client)) // cant print circular references
        Object.keys(client).forEach(function(key) {
            var value = client[key];
            print(key, "=", value)
        })
    }
}


> objectName =
> bufferGeometry = QRectF(7362, 28, 958, 1052)
> clientGeometry = QRectF(7362, 28, 958, 1052)
> pos = QPointF(7360, 0)
> size = QSizeF(960, 1080)
> x = 7360
> y = 0
> width = 960
> height = 1080
> opacity = 1
> output = KWin::DrmOutput(0x5f7cf78a20b0)
> rect = QRectF(0, 0, 960, 1080)
> resourceName = python3.12
> resourceClass = python3
> windowRole =
> desktopWindow = false
> dock = false
> toolbar = false
> menu = false
> normalWindow = true
> dialog = false
> splash = false
> utility = false
> dropdownMenu = false
> popupMenu = false
> tooltip = false
> notification = false
> criticalNotification = false
> appletPopup = false
> onScreenDisplay = false
> comboBox = false
> dndIcon = false
> windowType = 0
> managed = true
> deleted = false
> skipsCloseAnimation = false
> popupWindow = false
> outline = false
> internalId = {5d33508e-1159-4eff-9b0b-752b71e517a9}
> pid = 3082266
> stackingOrder = 28
> fullScreen = false
> fullScreenable = true
> active = false
> desktops = [KWin::VirtualDesktop(0x5f7cf67061f0)]
> onAllDesktops = false
> activities = [b27b5dce-4d17-4310-91d7-31844c1b40d5]
> skipTaskbar = false
> skipPager = false
> skipSwitcher = false
> closeable = true
> icon = QVariant(QIcon, QIcon("wayland",availableSizes[normal,Off]=QList(QSize(16, 16), QSize(22, 22), QSize(32, 32), QSize(48, 48), QSize(64, 64), QSize(128, 128), QSize(256, 256)),cacheKey=0x400000000))
> keepAbove = false
> keepBelow = false
> shadeable = false
> shade = false
> minimizable = true
> minimized = false
> iconGeometry = QRectF(2292, 2033, 268, 36)
> specialWindow = false
> demandsAttention = false
> caption = Jupyter QtConsole
> minSize = QSizeF(150, 150)
> maxSize = QSizeF(2.14748e+09, 2.14748e+09)
> wantsInput = true
> transient = false
> transientFor = null
> modal = false
> frameGeometry = QRectF(7360, 0, 960, 1080)
> move = false
> resize = false
> decorationHasAlpha = true
> noBorder = false
> providesContextHelp = false
> maximizable = true
> moveable = true
> moveableAcrossScreens = true
> resizeable = true
> desktopFileName = python3
> hasApplicationMenu = false
> applicationMenuActive = false
> unresponsive = false
> colorScheme = kdeglobals
> layer = 2
> hidden = false
> tile = KWin::Tile(0x5f7d1c9e0250)
> inputMethod = false

Obviously x=7362 is way way way off screen. If I try to set geometry in a similar script, neither method works:

const clients = workspace.windowList();
for (var i = 0; i < clients.length; i++) {
    var client = clients[i]
    if (client.pid === 3082266) {
        //client.frameGeometry = {"x":1000,"y":1000} // doesn't work
        client.frameGeometry = {"x":1000,"y":1000, "width": 1000, "height": 1000, "left":1000, "right":2000, "top":1000, "bottom":2000} // also doesn't work
    }
}

Also occasionally I can get it back on screen by temporarily enabling/disabling a monitor, but that also isn't working in this case.
Comment 1 Nate Graham 2024-10-03 19:40:18 UTC
I've been experiencing this with current git master too. I found a bulletproof way to reproduce it today:

1. Have a laptop and plug in an external monitor to the right of the laptop
2. Custom tile (not quick tile) a window to the far right side of the external monitor
3. Unplug the external monitor

At this point, the window sometimes fails to move to the laptop screen, but usually it does move. HOWEVER! When it does move, if I try to right-tile it by pressing Meta+Right Arrow (may need to do it 1-3 times), the window will move off the screen and get permanently stuck there — no tricks can bring it back.
Comment 2 TraceyC 2024-11-08 17:03:00 UTC
I was not able to reproduce the exact same thing with git master, but I am observing something similar and probably related

**Setup**
Laptop has a monitor plugged in via HDMI cable. The external display is to the right of the laptop's display

The simplest way I can reproduce:

It has to be with a fresh plasma session (I restart plasmashell first, otherwise other window repositioning makes this not happen)
With the monitor connected, tile Firefox on the upper left of the external display
Unplug the HDMI cable
Observe: Firefox is only partly on the visible screen (screenshot)  
If I plug the monitor back in, Firefox is *not* returned to its previous position

I can then also reproduce with FF custom tiled to the middle on the external monitor


I've also reproduced windows partially moving to the laptop display with other arrangements

Laptop screen:
Konsole quick tiled on the right (Meta+R-Arrow)

External monitor:
System settings custom tiled lower left
Firefox custom tiled top left
Dolphin custom tiled middle third

When I unplug the monitor cable, all windows are moved to the laptop screen
Notably, the Quick Settings window is only partially on the screen

When I plug the monitor back in, other windows go back to the positions on that display *except* Quick Settings
Comment 3 TraceyC 2024-11-08 17:03:56 UTC
Created attachment 175656 [details]
Firefox partially on right side of display
Comment 4 TraceyC 2024-11-08 17:07:40 UTC
The main System Settings window seems prone to this
Custom tiled it to the right on the external display
Disconnected display
System settings was off screen, but could be moved on screen
Comment 5 andy 2024-11-09 21:05:53 UTC
a workaround that seems to be working for me is to have an extra desktop with no windows on it, switch to that before I start turning off monitors, and after coming back with all the monitors on switch back to the original desktop

I still believe a great solution would be the ability to lock the monitor layout and prevent dynamic moving of windows, panels, and widgets when one monitor disconnects. On my desktop 99% of the time I am never actually adding/removing a physical screen, but the current behavior acts that way (more oriented towards laptops with a single external monitor). It would save a lot of frustration from things moving around. Is there a way to do this, like disable kscreen somehow?
Comment 6 Nate Graham 2024-12-11 14:33:52 UTC
This should be fixed in the upcoming Plasma 6.3.0 with some recent changes to KWin.

Windows may now appear *partially* offscreen which is a remaining known issue, but that'll have to be fixed separately.