Bug 322480 - maximized windows get behind top panel when displays have different height
Summary: maximized windows get behind top panel when displays have different height
Status: RESOLVED UNMAINTAINED
Alias: None
Product: plasma4
Classification: Plasma
Component: containment-panel (show other bugs)
Version: unspecified
Platform: Debian stable Linux
: NOR minor
Target Milestone: ---
Assignee: Plasma Bugs List
URL:
Keywords:
: 323315 336014 (view as bug list)
Depends on:
Blocks:
 
Reported: 2013-07-17 10:48 UTC by Bogdan
Modified: 2018-06-08 18:57 UTC (History)
5 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Example for the bug (247.13 KB, image/jpeg)
2013-07-17 10:52 UTC, Bogdan
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Bogdan 2013-07-17 10:48:25 UTC
KDE version:  4.8.4.



Reproducible: Always

Steps to Reproduce:
1. Get a computer with a virtual screen that spans two displays with different height, and make sure the short display is not aligned with the top of the taller one;
2. Make sure you have panels on the top and bottom border of each display, each set to expand horizontally on the entire display, and each set to be always visible;
3. Open a window on the shorter display;
4. Maximize the window vertically.
Actual Results:  
The window stretches behind the top panel.

Expected Results:  
The window should stretch only up to the bottom border of the top panel.

OK, so I have a bit of an unusual configuration, but please bear with me, I’m pretty sure it can happen in other cases, too.

I have two 1920x1200 displays, one of which is rotated to portrait mode and the other in landscape mode. The virtual screen is set up such that one is right on the side of the other, but the landscape display is not aligned to the top of the portrait display, but more towards the middle. (This approximates the physical positions of the two monitors on my desk.) I’ve pasted xrandr’s output below.

There’s a panel on the top and bottom of each display, set up to be always visible. So a window maximized on either monitor should fit exactly in the space between the two panels on that monitor. This works on the tall (portrait) one, but on the landscape one the window is pulled below the top panel (i.e., it’s maximized to the top of the monitor). This doesn’t happen on the bottom, i.e., the bottom of the window correctly reaches only to the top of the bottom panel. I’ll attach a screenshot with examples.

I’ve tested with other positions, it always happens on the display that is not top-aligned with the virtual screen, regardless of size and rotation. (So you can probably test with any two monitor configuration, as long as you use a different vertical resolution for the two monitors. There’s a bug/feature in the display config applet that forces the two displays to be aligned if they have the same height, but you can use xrandr directly to build this kind of configuration even in that case.)

I don’t use vertical panels so I don’t know if an analogous problem exists with horizontal maximization. Also, I didn’t test what happens if the screens are one above the other, or overlapping, but it’d probably be worth it to also add a test case for those situations.

$ xrandr 
Screen 0: minimum 8 x 8, current 3120 x 1920, maximum 8192 x 8192
DVI-I-0 disconnected (normal left inverted right x axis y axis)
VGA-0 disconnected (normal left inverted right x axis y axis)
DVI-I-1 connected 1200x1920+1920+0 left (normal left inverted right x axis y axis) 546mm x 352mm
   1920x1200      60.0*+   59.9  
[snip other modes]
HDMI-0 connected 1920x1200+0+240 (normal left inverted right x axis y axis) 546mm x 352mm
   1920x1200      60.0*+
[snip other modes]
Comment 1 Bogdan 2013-07-17 10:52:44 UTC
Created attachment 81155 [details]
Example for the bug

Here’s an example of the two cases. There’s a Geany window on each monitor, vertically maximized. Note how the title bar of the one on the left screen is not visible, while the right one is. The same happens if you use full maximization (i.e., in both directions).

The obvious work-around is to use resize the window by hand, possibly using a shortcut for horizontal maximization.
Comment 2 Thomas Lübking 2013-07-17 12:35:01 UTC
I think this is bug #308853 (the explanation of the problem there might be wrong / unsharp)

Please post the output of 
   xprop | grep -iC1 STRUT
(the cursor turns into a cross, then just click somewhere on the problematic panel)
and
   xrandr -q
Comment 3 Bogdan 2013-07-17 13:06:21 UTC
(In reply to comment #2)

Here you go:

$ xprop | grep -iC1 STRUT
_KDE_NET_WM_BLUR_BEHIND_REGION(CARDINAL) = 0, 0, 1920, 25
_NET_WM_STRUT(CARDINAL) = 0, 0, 4294966891, 0
_NET_WM_STRUT_PARTIAL(CARDINAL) = 0, 0, 4294966891, 0, 0, 0, 0, 0, 0, 1919, 0, 0
WM_STATE(WM_STATE):
--
_NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_CHANGE_DESKTOP
_KDE_NET_WM_FRAME_STRUT(CARDINAL) = 0, 0, 0, 0
_NET_FRAME_EXTENTS(CARDINAL) = 0, 0, 0, 0

$ xrandr -q
Screen 0: minimum 8 x 8, current 3120 x 1920, maximum 8192 x 8192
DVI-I-0 disconnected (normal left inverted right x axis y axis)
VGA-0 disconnected (normal left inverted right x axis y axis)
DVI-I-1 connected 1200x1920+1920+0 left (normal left inverted right x axis y axis) 546mm x 352mm
   1920x1200      60.0*+   59.9  
   1680x1050      60.0  
   1600x1200      60.0  
   1600x1000      60.0  
   1280x1024      75.0     60.0  
   1280x960       60.0  
   1024x768       75.0     60.0  
   800x600        75.0     60.3  
   640x480        75.0     59.9  
HDMI-0 connected 1920x1200+0+430 (normal left inverted right x axis y axis) 546mm x 352mm
   1920x1200      60.0*+
   1920x1080      59.9     50.0     30.0     30.0     25.0  
   1680x1050      60.0  
   1600x1200      60.0  
   1600x1000      60.0  
   1280x1024      75.0  
   1280x960       60.0  
   1280x720       60.0     59.9     50.0  
   1024x768       75.0     60.0  
   800x600        75.0     60.3  
   720x576        50.0     25.0  
   720x480        59.9     30.0  
   640x480        75.0     59.9     59.9
Comment 4 Bogdan 2013-07-17 13:10:15 UTC
(In reply to comment #2)
> I think this is bug #308853 (the explanation of the problem there might be
> wrong / unsharp)

Can’t tell, but there’s at least one difference from the report there: I my case the mouse is not allowed to exit the bounds of the monitor, but that report says “The mouse also is not restricted traveling out of bounds.” (The grammar sounds iffy, so depending on the missing word it might not mean what I think it means.)
Comment 5 Thomas Lübking 2013-07-17 13:26:33 UTC
_NET_WM_STRUT(CARDINAL) = 0, 0, 4294966891, 0
                                                    ^^^^^^^^^^^^^

We've a winner.
It seems the strut is seems set by a weird "screen / root pos" mapping.
The value is apparently a strut of "-405"

1. negative struts don't exist in the first place.
2. struts have to be in root coordinates (the netwm spec is initially quite confusing about this but at some point clearly states this: "Struts MUST be specified in root window coordinates, that is, they are not relative to the edges of any view port or Xinerama monitor.")

Since your horizontal screen is at y=430 and the panel 25px high, this means the strut seems calculated as
   "panel bottom in screen coordinates" - "screen top" | 25 - 430 = -405
while it should be 
   "panel bottom in screen coordinates" + "screen top"  | 25 + 430 = 455

what's obviously equal if "screen top" is "0" only.

Seems to be a bug in the plasma panel containment strut calculation, eventually some sublying library.
Comment 6 Thomas Lübking 2013-07-17 13:34:31 UTC
(In reply to comment #4)

> report says “The mouse also is not restricted traveling out of bounds.” (The
> grammar sounds iffy, so depending on the missing word it might not mean what I think it means.)

Either this means the setup is broken (and the screen continues outside the viewport) or he's referring to the fact that mouse movement is not restricted at common screen edges - resp. for older Xorg version was not restricted to the viewport at all (ie. could be moved outside all over the root window) - we'll need a reply over there to finally say.
Comment 7 Bogdan 2013-07-18 16:28:53 UTC
(In reply to comment #5)
> It seems the strut is seems set by a weird "screen / root pos" mapping.
> Seems to be a bug in the plasma panel containment strut calculation,
> eventually some sublying library.

I’m not a KDE hacker, but I’m a programmer, so if there’s anything I can do to help that doesn’t require a week of learning how KDE/Plasma works let me know.

Out of curiosity, I looked through plasma/desktop/shell/panelview.cpp, and I don’t think I get it. PanelView::updateStruts has this (edited slightly to fit better):

>       //Extended struts against a screen edge near to another screen are really harmful, 
>       //so windows maximized under the panel is a lesser pain
>        //TODO: force "windows can cover" in those cases?
>        const int numScreens = PlasmaApp::self()->corona()->numScreens();
>        for (int i = 0; i < numScreens; ++i) {
>            if (i == containment()->screen()) continue;
>            const QRect otherScreen = PlasmaApp::self()->corona()->screenGeometry(i);
>            switch (location()){
>            case Plasma::TopEdge:
>                if (otherScreen.bottom() <= thisScreen.top()) { /* BAD TEST HERE, I think */
>                    KWindowSystem::setExtendedStrut(winId(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
>                    return;
>                }

If I understand what it does, then for that panel in particular that last “if” is true and the function returns here. But in that case it sets all-zero struts, so I don’t understand where the negative value is coming from.

That said, I think the condition as written I think is wrong. I think the code is trying to avoid setting struts on panels that lie on a border shared with another adjacent screen. But it doesn’t in fact test if the other screen shares the tested border. Whoever wrote the code probably assumed same-sized and corner-aligned screens. (Though even then it wouldn’t work right, the test would say “true” even if the other screen were below this one, or (my case) if it is on the side.

Assuming I understood the code, the correct test is probably something like:

> if (otherScreen.top() > thisScreen.top()      // the other screen is really above us
>  && otherScreen.left() < thisScreen.right()   // and it’s not too far to the right
>  && otherScreen.right() > thisScreen.left()   // nor too far to the left
>  && otherScreen.bottom() <= thisScreen.top()) // and it actually touches this screen

Though there is a test like this for each case (border), so there might be a way to organize the tests better.
Comment 8 Bogdan 2013-07-18 16:31:26 UTC
That said, the test for the bottom panel would have the same bug, but it doesn’t manifest in my case, and I checked with xprop and the values seem sane.
Comment 9 Thomas Lübking 2013-08-09 18:47:15 UTC
*** Bug 323315 has been marked as a duplicate of this bug. ***
Comment 10 Jakub Zakrzewski 2013-11-02 17:03:27 UTC
I can confirm I have the same problem too.
I use a small laptop with the screen dimensions
1280x800
and the other monitor with the screen dimensions
1920x1080

The bigger one is configured to be above the smaller one and the smaller one
has a panel at the top of the screen.
I have the same problem as described here.
Comment 11 Elias Probst 2014-05-04 10:04:38 UTC
I experience the same behaviour on KF5/Plasma Workspaces (all components from git master as of 2014-05-04).

Primary screen is 1920x1080 (under secondary)
Secondary screen is 2560x1440 (above primary)

Both have a panel at the bottom.
The problem only exists for the panel on the secondary screen, where the panel shares a border with the primary screen.

The strut values for the primary panel are:
_NET_WM_STRUT(CARDINAL) = 0, 0, 0, 30
_NET_WM_STRUT_PARTIAL(CARDINAL) = 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 496, 2415
_KDE_NET_WM_ACTIVITIES(STRING) = "00000000-0000-0000-0000-000000000000"

The struct values for the secondary panel are:
_NET_WM_STRUT(CARDINAL) = 0, 0, 0, 0
_NET_WM_STRUT_PARTIAL(CARDINAL) = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
_KDE_NET_WM_ACTIVITIES(STRING) = "00000000-0000-0000-0000-000000000000"

Display layout:
eDP1 connected 1920x1080+496+1440 (normal left inverted right x axis y axis) 294mm x 165mm
DP1 connected 2560x1440+0+0 (normal left inverted right x axis y axis) 597mm x 336mm

Moving the secondary panel to the top where it doesn't share a border with the primary screen makes the problem disappear, so it seems to be related to the panel's position in the middle of both screens.

The same goes vice versa for the primary panel (moving it to the top makes the problem appear on the primary screen).
Comment 12 Martin Klapetek 2014-05-06 12:44:58 UTC
Jakub and Elias - your bug is different, having panels on the shared screen edge is deliberately ignored, see bug 167852
Comment 13 Thomas Lübking 2014-06-12 19:58:23 UTC
*** Bug 336014 has been marked as a duplicate of this bug. ***
Comment 14 Nate Graham 2018-06-08 18:57:05 UTC
Hello!

This bug report was filed for KDE Plasma 4, which reached end-of-support status in August 2015. KDE Plasma 5's desktop shell has been almost completely rewritten for better performance and usability, so it is likely that this bug is already resolved in Plasma 5.

Accordingly, we hope you understand why we must close this bug report. If the issue described  here is still present in KDE Plasma 5.12 or later, please feel free to open a new ticket in the "plasmashell" product after reading https://community.kde.org/Get_Involved/Bug_Reporting

If you would like to get involved in KDE's bug triaging effort so that future mass bug closes like this are less likely, please read https://community.kde.org/Get_Involved#Bug_Triaging

Thanks for your understanding!

Nate Graham