Bug 349123 - Maximized window limited to half screen height after disconnecting the second monitor
Summary: Maximized window limited to half screen height after disconnecting the second...
Status: RESOLVED FIXED
Alias: None
Product: kwin
Classification: Plasma
Component: xrandr (show other bugs)
Version: 5.3.1
Platform: Arch Linux Linux
: NOR normal
Target Milestone: ---
Assignee: KWin default assignee
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-06-13 23:57 UTC by Andrew Chen
Modified: 2016-04-30 22:16 UTC (History)
4 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
output of qdbus org.kde.KWin /KWin supportInformation (5.49 KB, text/plain)
2015-06-13 23:58 UTC, Andrew Chen
Details
Screenshot before disconnect (1.71 MB, image/png)
2015-06-14 00:00 UTC, Andrew Chen
Details
Screenshot after disconnect (506.23 KB, image/png)
2015-06-14 00:01 UTC, Andrew Chen
Details
output of xrandr -q (1.63 KB, patch)
2015-06-14 10:30 UTC, Andrew Chen
Details
outputs of xrandr, xwininfo and xprop (2.62 KB, text/plain)
2015-06-15 06:33 UTC, Andrew Chen
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Chen 2015-06-13 23:57:11 UTC
Both VGA and HDMI/DVI monitor connections will cause this bug.

Reproducible: Always

Steps to Reproduce:
1. Connect a second monitor
2. Open a window on the first display and maximize it.
3. Disconnect the second monitor

Actual Results:  
The maximized window's height becomes half the screen's height.
Opening another window (after the disconnect) and maximizing it produces the same result.

Expected Results:  
The maximized window's height remain the screen's full height.

Hardware: HP Probook 430 G1
Comment 1 Andrew Chen 2015-06-13 23:58:07 UTC
Created attachment 93158 [details]
output of qdbus org.kde.KWin /KWin supportInformation
Comment 2 Andrew Chen 2015-06-14 00:00:50 UTC
Created attachment 93159 [details]
Screenshot before disconnect
Comment 3 Andrew Chen 2015-06-14 00:01:16 UTC
Created attachment 93160 [details]
Screenshot after disconnect
Comment 4 Andrew Chen 2015-06-14 00:15:37 UTC
Sorry, the steps to reproduce is incorrect: the first step should be:
1. boot up with a second monitor connected
Comment 5 Andrew Chen 2015-06-14 00:17:12 UTC
Restarting plasmashell after disconnecting the monitor is a workaround.
Comment 6 Thomas Lübking 2015-06-14 08:05:14 UTC
(In reply to Andrew Chen from comment #5)
> Restarting plasmashell after disconnecting the monitor is a workaround.

There's something severely screwed, but it's not KWin.

a) the 2nd screenshot indicates that the screen was not actually (logically) removed - the root window apparently has the pre-change size. => check the output of "xrandr -q" before and after the disconnect
b) I bet your right arm that "xprop -root _NET_WORKAREA" will reflect that constrained area.
Also compare the output of "xprop | grep _NET_WM_STRUT" for your panel(s)
Do you also have an autohiding panel?
Comment 7 Andrew Chen 2015-06-14 10:30:14 UTC
Created attachment 93165 [details]
output of xrandr -q
Comment 8 Andrew Chen 2015-06-14 10:36:35 UTC
Hi,
I only have one panel (the bottom task bar), and it is not auto hiding.
Just for your information, the screenshot is taken using KSnapshot (activated through print screen)

(for the bottom panel) (output is same both before and after disconnect)
[andrew@ANDREW-LAPTOP-ARCH ~]$ xprop | grep _NET_WM_STRUT
_NET_WM_STRUT(CARDINAL) = 0, 0, 0, 344
_NET_WM_STRUT_PARTIAL(CARDINAL) = 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 1365

--- BEFORE DISCONNECT ---
[andrew@ANDREW-LAPTOP-ARCH ~]$ xprop -root _NET_WORKAREA
_NET_WORKAREA(CARDINAL) = 0, 0, 3286, 1080, 0, 0, 3286, 1080, 0, 0, 3286, 1080, 0, 0, 3286, 1080, 0, 0, 3286, 1080, 0, 0, 3286, 1080, 0, 0, 3286, 1080, 0, 0, 3286, 1080

--- AFTER DISCONNECT ---
[andrew@ANDREW-LAPTOP-ARCH ~]$ xprop -root _NET_WORKAREA
_NET_WORKAREA(CARDINAL) = 0, 0, 1366, 768, 0, 0, 1366, 768, 0, 0, 1366, 768, 0, 0, 1366, 768, 0, 0, 1366, 768, 0, 0, 1366, 768, 0, 0, 1366, 768, 0, 0, 1366, 768
Comment 9 Thomas Lübking 2015-06-14 12:16:09 UTC
Ok, that's "interesting" - kindly spoken.

I assume you change screens via "kcmshell5 kscreen"? (that's direct access to some systemsettings module)

root of evil is (very likely)
> Screen 0: minimum 8 x 8, current 3286 x 1080, maximum 32767 x 32767

The size of the root window seems to be (still) 3286x1080

==> please also attach the ouput of "xwininfo -root" from before and after the screen layout change.


plasmashell/kwindowsystem seems to set the struts correctly in root coordinates:
> _NET_WM_STRUT_PARTIAL(CARDINAL) = 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 1365
(the panel is 1366px wide and (344 + 768) - 1080 == 32, I guess that's the panels actual height)

Just that apparently that strut doesn't end up in KWin ever - or is at least not exported to the world (what would point *some* bug)
> _NET_WORKAREA(CARDINAL) = 0, 0, 3286, 1080

This is expectable, the panel is on the smaller screen and would restrict the bigger one (_NET_WORKAREA only supports one combined area)

> _NET_WORKAREA(CARDINAL) = 0, 0, 1366, 768
But this is not.

Yet kwin (at least internally) restricts the maximize area.
The glitch in KWin here is that it assumes "root window size == bounding rect of all screens", what's "reasonable", but technically wrong.

The final twist is that restarting plasmashell (*only* plasmashell, or do you log out/in?) fixes it.
==> Can you please also check "xrandr -q", "xwininfo -root" and "xprop | grep _NET_WM_STRUT" on the panel after a palsmashell restart? (in case you do NOT need to log out and in)
Comment 10 Martin Flöser 2015-06-14 15:49:09 UTC
the panel has an incurrect strut - try resizing the panel which should fix it.
Comment 11 Thomas Lübking 2015-06-14 16:13:41 UTC
it's not that simple.
iff the rootwindow is still 1080px high w/ the lower 312px out of the screen boundaries (see randr dump), the strut is actually correct to occupy the bottom 32px of the 768px hight output.
Comment 12 Martin Flöser 2015-06-14 18:14:31 UTC
oh right, true. So an xrandr --auto followed by a resize of panel might fix it. At least it did on one system I tried that on the other day.
Comment 13 Andrew Chen 2015-06-15 06:33:21 UTC
Created attachment 93181 [details]
outputs of xrandr, xwininfo and xprop
Comment 14 Andrew Chen 2015-06-15 06:34:23 UTC
Hi,
I change screens through hot (un)plugging the external display, and everything is automatically configured. I have not used the system settings display configuration module before.
Yes, I just restart the plasma shell, by executing the following commands:
$ killall plasmashell
$ nohup plasmashell 2>&1 >/dev/null &
Also, resizing the panel after the disconnect does fix the problem.
Also, `xwininfo -root` is the same both before, after disconnect and after restarting plasma shell.
Comment 15 Thomas Lübking 2015-06-15 14:43:07 UTC
(In reply to Andrew Chen from comment #14)
> Hi,
> I change screens through hot (un)plugging the external display, and
> everything is automatically configured.

That's the kscreen daemon, basically the same as the kscreen kcm (common library) - which I had the "pleasure" to try yesterday (picked me an XGA screen =)


It "somehow" manages to remove the screen
- without impacting the size of the root window
- without even flagging the remaining screen as panning (yet it does)

As result the screenlayout changes, but the X11 screen size does not what (likely and reasonably) makes plasmashell look the other side ("the user replaces two screens w/ one of the same size - why bother...") but KWin will no longer ignore the "inner" strut, causing (along the incorrect assumption that the bounding rect of all screens would match the root window) the stronger constrainment.

When you restart plasmashell, it replicates the same wrong assumption (it now *has* to look at the screens again) and sets the *wrong* 32px strutting (which however happens to match KWins *wrong* strut handling)

So we've 3 bugs in here:
---------------------------------
1. KScreen is *severely* broken when adjusting RandR (getting out of this mess of a config isn't too simple)
2. plasmashell sets struts aligned to the bounding rect of all screens (instead of the root window)
3. KWin reads struts aligned to the bounding rect of all screens (instead of the root window)

I filed (2) as https://bugs.kde.org/show_bug.cgi?id=349191 and (3) as https://bugs.kde.org/show_bug.cgi?id=349190
The kscreen bug seems already reported about a dozen times (and explains the complaints in forum.kde.org)

My best suggestion is to avoid kscreen for the moment (deactivate the module in "kcmshell5 kded" and don't  use the kcm to setup your screens.
Comment 16 Andrew Chen 2015-06-16 10:35:28 UTC
I've been looking through the logs to see why kscreen does not set the correct screen size.
Looks like kscreen thought it was going to apply the right screen size, but it then applied the wrong size.

kscreen.xrandr: XRandR::setConfig
kscreen.xrandr: Requested screen size is QSize(1366, 768)
kscreen.xrandr: Needed CRTCs:  1
kscreen.xrandr: Actions to perform:
kscreen.xrandr:         Primary Output: false
kscreen.xrandr:         Change Screen Size: true
kscreen.xrandr:                 Old: QSize(3286, 1080)
kscreen.xrandr:                 Intermediate: QSize(3286, 1080)
kscreen.xrandr:                 New: QSize(1366, 768)    <== This is right
kscreen.xrandr:         Disable outputs: true
kscreen.xrandr:                  (69)
kscreen.xrandr:         Change outputs: false
kscreen.xrandr:         Enable outputs: false
...
kscreen.xrandr: RRSetScreenSize
kscreen.xrandr:         DPI: 96.2526
kscreen.xrandr:         Size: QSize(3286, 1080)    <== This is wrong
kscreen.xrandr:         SizeMM: QSize(867, 285)
kscreen.xrandr: XRandR::setConfig done!
Comment 17 Andrew Chen 2015-06-16 10:42:29 UTC
I think the bug is in this line (libkscreen/backends/xrandr/xrandrconfig.cpp, L305):
newSize = intermediateScreenSize;
I think it is meant to be:
newSize = newScreenSize;
since the intermediateScreenSize has already been applied in L271, and newScreenSize should be applied now.
Comment 18 Thomas Lübking 2015-06-16 14:07:46 UTC
Unlikely because that particular assignment was only introduced on 2015-05-18 by http://quickgit.kde.org/?p=libkscreen.git&a=blobdiff&h=87f6df2a4b434b49e35efc2ef1f5abdf13f4465c&hp=6b9f7734ace11236bdb391e2273183cc4de42f88&f=backends%2Fxrandr%2Fxrandrconfig.cpp&hb=d6233b63da667e0c9296e0738da74930288c8dc5

I'll have a look what's wrong there tonight. (and why there's an intermediate screen size itfp.)
Comment 19 Thomas Lübking 2015-06-16 23:29:09 UTC
Nevertheless, that patch only seems to have resolved have of the problem and I can confirm that


diff --git a/backends/xrandr/xrandrconfig.cpp b/backends/xrandr/xrandrconfig.cpp
index 87f6df2..0797232 100644
--- a/backends/xrandr/xrandrconfig.cpp
+++ b/backends/xrandr/xrandrconfig.cpp
@@ -297,12 +297,10 @@ void XRandRConfig::applyKScreenConfig(const KScreen::ConfigPtr &config)
     }
 
     if (forceScreenSizeUpdate || intermediateScreenSize != newScreenSize) {
-        QSize newSize;
+        QSize newSize = newScreenSize;
         if (forceScreenSizeUpdate) {
             newSize = screenSize(config);
             qCDebug(KSCREEN_XRANDR) << "Forced to change screen size: " << newSize;
-        } else {
-            newSize = intermediateScreenSize;
         }
         setScreenSize(newSize);
     }


fixes it.
Attached Dan to the bug.
Comment 20 Daniel Vrátil 2015-06-16 23:54:26 UTC
Yep, that's correct. Thanks for the patch Thomas, feel free to ship it.
Comment 21 Andrew Chen 2015-06-17 06:02:08 UTC
Yes, I also confirm the patch fixes the KScreen issue.
Comment 22 Andrew Chen 2015-06-17 09:41:04 UTC
Now, with the root window size fixed and out of the way, let's fix the actual problem that's causing this bug.

My thoughts:

>> _NET_WM_STRUT_PARTIAL(CARDINAL) = 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 1365
> (the panel is 1366px wide and (344 + 768) - 1080 == 32, I guess that's the panels actual height)
Since the main monitor is smaller, the panel strut is set relative to the combined screen size (which has a height of 1080), so it needs to have a height of 344 to be at the bottom of the smaller monitor.
However, when the second (larger) monitor is disconnected, the panel strut is not updated, and still has a height of 344, but now relative to the new screen size (the main monitor size, which only has a height of 768). Therefore, the panel now has a (incorrect) height of 344. So, it restricts a maximized window's height 424 (about 384, half of 768), causing the symptoms described in the bug report. This also explains why resizing the panel (or restarting plasmashell) fixes it, since when the panel size is recalculated, the strut is fixed.
I think the problem is that plasma shell is not notified when the screen size changes, thus does not know when it needs to change the panel strut to compensate for the change in screen size.

Just as a side note: I am also experiencing a bug (which I haven't reported) that causes a maximized window to go under the panel when an external screen is connected. I think that is also caused by the same cause (strut not updating).
Comment 23 Thomas Lübking 2015-06-17 15:26:49 UTC
Git commit a018fef80b51be156230c0f51008e4471a75cb39 by Thomas Lübking.
Committed on 17/06/2015 at 15:15.
Pushed by luebking into branch 'Plasma/5.3'.

really set the new size after the intermediate

supplemental to d6233b63da667e0c9296e0738da74930288c8dc5
Credits go to Andrew Chen, who spotted the bug in the
fix to a long standing bug ;-)

Signed off by Dan.

M  +1    -3    backends/xrandr/xrandrconfig.cpp

http://commits.kde.org/libkscreen/a018fef80b51be156230c0f51008e4471a75cb39
Comment 24 Thomas Lübking 2015-06-17 16:05:29 UTC
Plasmashell is notified (everything on the system gets notified) - have you tried the behavior with the patched libkscreen? (For what happens here is that plasmashell runs into the zero count QScreen bug in Qt5 and simply segfaults + restarts, ie. it does react to the screen size update)
Comment 25 Andrew Chen 2015-06-18 08:04:31 UTC
Yes, I am using the patched kscreen (5.3.1 with the patch). The root window size is set properly. However, I do not experience plasmashell crashing before or after the disconnect of a monitor.

The only sign I can see of plasmashell being notified of the change (monitor disconnect) is:
Jun 18 20:00:35 ANDREW-LAPTOP-ARCH kglobalaccel5[524]: kglobalaccel-runtime: Unregistering key "Meta+Tab" for "plasmashell" : "next activity"
Jun 18 20:00:35 ANDREW-LAPTOP-ARCH kglobalaccel5[524]: kglobalaccel-runtime: Unregistering key "Meta+Shift+Tab" for "plasmashell" : "previous activity"
(or registering for monitor connect)

(BTW, I don't even know why the hotkey for switching between activities is disabled on monitor disconnect. I checked the hotkeys actually doesn't work anymore after it has been unregistered)
Comment 26 Thomas Lübking 2015-06-18 11:44:25 UTC
If plasmashell notices the screen count change and the desktop is resized but doesn't update struts, that's a plasmashell bug.

I could assume the fast updates (2 screens -> 1 screen on oversized root -> 1 screen) could make it miss the 2nd step because it's still occupied by reacting to the 1st step, but neither know, nor can't even test (until Qt 5.5 will hopefully stop those nasty no-screen segfaults)
=> please file a bug against plasmashell, panel component (reg. above thoughts, this could be timing related)
Comment 27 Andrew Chen 2015-06-19 22:55:37 UTC
Filed the bug as: https://bugs.kde.org/show_bug.cgi?id=349400
Comment 28 Ravi Arora 2016-04-30 22:16:33 UTC
I have a similar issue.

1. Connect a second monitor.
2. Not maximize on both first and second monitor occupy half of screen.