From f5d966ee77f43b758f23eda02d879dd21442e5a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 14 Jul 2016 13:07:36 +0200 Subject: [PATCH] Allow struts on panels between screen edges if WM is KWin Summary: KWin starting with 5.7 supports struts on panels between screen edges. Thus we can start setting struts on such panels, it won't exclude a complete screen. But we don't know how other window managers handle it and it's in general a rather "dangerous" change. Thus to not affect other window managers, we check whether KWin is running and only allow struts on thus panels if KWin is running. Unfortunately we need to test this every time we go into the code path as the WM might have changed. In case the user replaces the window manager at runtime this still can result in a bad situation. BUG: 94470 FIXED-IN: 5.8.0 Test Plan: Tested whether it works in general in X11. Further testing needed by X11, multi-screen users. Reviewers: #plasma Subscribers: plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D2164 --- shell/panelview.cpp | 109 +++++++++++++++++++++++++++----------------- shell/panelview.h | 1 + 2 files changed, 69 insertions(+), 41 deletions(-) diff --git a/shell/panelview.cpp b/shell/panelview.cpp index 682db4864..0ab50ec4f 100644 --- a/shell/panelview.cpp +++ b/shell/panelview.cpp @@ -44,6 +44,7 @@ #if HAVE_X11 #include +#include #include #endif @@ -871,6 +872,70 @@ void PanelView::updateMask() } } +bool PanelView::canSetStrut() const +{ +#if HAVE_X11 + if (!QX11Info::isPlatformX11()) { + return true; + } + // read the wm name, need to do this every time which means a roundtrip unfortunately + // but WM might have changed + NETRootInfo rootInfo(QX11Info::connection(), NET::Supported | NET::SupportingWMCheck); + if (qstricmp(rootInfo.wmName(), "KWin") == 0) { + // KWin since 5.7 can handle this fine, so only exclude for other window managers + return true; + } + + const QRect thisScreen = screen()->geometry(); + const int numScreens = corona()->numScreens(); + if (numScreens < 2) { + return true; + } + + //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? + foreach (int id, m_corona->screenIds()) { + if (id == containment()->screen()) { + continue; + } + + const QRect otherScreen = corona()->screenGeometry(id); + if (!otherScreen.isValid()) { + continue; + } + + switch (location()) + { + case Plasma::Types::TopEdge: + if (otherScreen.bottom() <= thisScreen.top()) { + return false; + } + break; + case Plasma::Types::BottomEdge: + if (otherScreen.top() >= thisScreen.bottom()) { + return false; + } + break; + case Plasma::Types::RightEdge: + if (otherScreen.left() >= thisScreen.right()) { + return false; + } + break; + case Plasma::Types::LeftEdge: + if (otherScreen.right() <= thisScreen.left()) { + return false; + } + break; + default: + return false; + } + } + return true; +#else + return true; +#endif +} + void PanelView::updateStruts() { if (!containment() || !m_screenToFollow) { @@ -885,47 +950,9 @@ void PanelView::updateStruts() // QScreen::virtualGeometry() is very unreliable (Qt 5.5) const QRect wholeScreen = QRect(QPoint(0, 0), m_screenToFollow->virtualSize()); - //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? - foreach (int id, m_corona->screenIds()) { - if (id == containment()->screen()) { - continue; - } - - const QRect otherScreen = corona()->screenGeometry(id); - if (!otherScreen.isValid()) { - continue; - } - - switch (location()) - { - case Plasma::Types::TopEdge: - if (otherScreen.bottom() <= thisScreen.top()) { - KWindowSystem::setExtendedStrut(winId(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - return; - } - break; - case Plasma::Types::BottomEdge: - if (otherScreen.top() >= thisScreen.bottom()) { - KWindowSystem::setExtendedStrut(winId(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - return; - } - break; - case Plasma::Types::RightEdge: - if (otherScreen.left() >= thisScreen.right()) { - KWindowSystem::setExtendedStrut(winId(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - return; - } - break; - case Plasma::Types::LeftEdge: - if (otherScreen.right() <= thisScreen.left()) { - KWindowSystem::setExtendedStrut(winId(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - return; - } - break; - default: - return; - } + if (!canSetStrut()) { + KWindowSystem::setExtendedStrut(winId(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + return; } // extended struts are to the combined screen geoms, not the single screen int leftOffset = thisScreen.x(); diff --git a/shell/panelview.h b/shell/panelview.h index 2aeef3040..11f50ff0c 100644 --- a/shell/panelview.h +++ b/shell/panelview.h @@ -200,6 +200,7 @@ private: void setupWaylandIntegration(); bool edgeActivated() const; void updateEnabledBorders(); + bool canSetStrut() const; int m_offset; int m_maxLength;