Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:dirkmueller:acdc:as_python3_module
libqt5-qtbase.16533
xcb-dont-rely-on-_NET_WORKAREA_for_available_ge...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xcb-dont-rely-on-_NET_WORKAREA_for_available_geometry.patch of Package libqt5-qtbase.16533
From b021ce5cb3c135dc60a4155b8840d1d01e7f54fb Mon Sep 17 00:00:00 2001 From: Gatis Paeglis <gatis.paeglis@qt.io> Date: Fri, 21 Jul 2017 14:01:56 +0200 Subject: [PATCH] xcb: don't rely on _NET_WORKAREA for available geometry on multi-head systems On X11, QScreen::availableGeometry() is broken with multi-head systems, and there doesn't seem to be a real fix for this due to limitation in the protocol and therefore support in WMs (more details in the patch). In Gnome this issue is more visible because on this DE the _NET_WORKAREA rectangle represents the intersection of the available geometries on all monitors. This results in a big area of "dead space" on the secondary screen, when primary screen is positioned lower in the virtual space. If menu is opened by clicking in this dead space, the menu is awfully misplaced (qmenu uses availableGeometry() to calculate the position of menu). On Ubuntu with Unity (same is true for KDE Neon+Kwin and LUbuntu+Openbox), _NET_WORKAREA returns a bounding rectangle containing all monitors. Which does not cause the menu misplacement as "dead space" is outside clickable area. But this does not mean that the QScreen::availableGeometry() reported values are correct. With the same setup as described above, QScreen::availableGeometry() thinks that we have a tool panel on the right screen, when in reality it is on the left screen. AwesomeWM for example does not set _NET_WORKAREA at all, which means QScreen::availableGeometry() == QScreen::geometry(). I am not aware that it would cause any issues for popup/menu window positioning in Qt (Qt positions these windows manually by bypassing WM (via Qt::BypassWindowManagerHint) and using availableGeometry for calculations. With this patch, we would take the same code path as if _NET_WORKAREA was not set (where we know that_NET_WORKAREA is cleary wrong). The solution here is to recognize _NET_WORKAREA as true available geometry only in specific cases (cases where the meaning is cleary defined by the specification) and adjust the documentation accordingly. Not knowing the true available geometry on X11 is mitigated by WMs. Window manager can position windows as it wants. WMs are smart enough not to place windows on top of reserved areas at edges (even if user has explicitly requested this via setGeometry based on inaccurate information from availableGeometry()). [ChangeLog][Platform Specific Changes][Linux] The _NET_WORKAREA atom is used for calculating QScreen::availableGeometry() only on systems with one monitor. In all other cases QScreen::availableGeometry() is equal to QScreen::geometry(). To restore the legacy behavior with untrustworthy values in QScreen::availableGeometry() set QT_RELY_ON_NET_WORKAREA_ATOM=1 environment variable. Task-number: QTBUG-60513 Task-number: QTBUG-29278 Task-number: QTBUG-43768 Task-number: QTBUG-18380 Change-Id: I7e0f62f81d1444991b8a6c007c2527d8f96088c2 Reviewed-by: Uli Schlachter <psychon@znc.in> Reviewed-by: Lars Knoll <lars.knoll@qt.io> --- src/gui/kernel/qscreen.cpp | 4 ++++ src/plugins/platforms/xcb/qxcbscreen.cpp | 25 ++++++++++++++++++++++++ src/plugins/platforms/xcb/qxcbscreen.h | 2 +- src/widgets/kernel/qdesktopwidget.qdoc | 2 +- 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp index 96f75f3..479e228 100644 --- a/src/gui/kernel/qscreen.cpp +++ b/src/gui/kernel/qscreen.cpp @@ -384,6 +384,10 @@ QRect QScreen::geometry() const The available geometry is the geometry excluding window manager reserved areas such as task bars and system menus. + + Note, on X11 this will return the true available geometry only on systems with one monitor and + if window manager has set _NET_WORKAREA atom. In all other cases this is equal to geometry(). + This is a limitation in X11 window manager specification. */ QRect QScreen::availableGeometry() const { diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index ce1d541..d59f8ec 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -127,6 +127,23 @@ void QXcbVirtualDesktop::subscribeToXFixesSelectionNotify() } } +/*! \internal + + Using _NET_WORKAREA to calculate the available desktop geometry on multi-head systems (systems + with more than one monitor) is unreliable. Different WMs have different interpretations of what + _NET_WORKAREA means with multiple attached monitors. This gets worse when monitors have + different dimensions and/or screens are not virtually aligned. In Qt we want the available + geometry per monitor (QScreen), not desktop (represented by _NET_WORKAREA). WM specification + does not have an atom for this. Thus, QScreen is limted by the lack of support from the + underlying system. + + One option could be that Qt does WM's job of calculating this by subtracting geometries of + _NET_WM_STRUT_PARTIAL and windows where _NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_DOCK. + But this won't work on Gnome 3 shell as it seems that on this desktop environment the tool panel + is painted directly on the root window. Maybe there is some Gnome/GTK API that could be used + to get height of the panel, but I did not find one. Maybe other WMs have their own tricks, so + the reliability of this approach is questionable. + */ QRect QXcbVirtualDesktop::getWorkArea() const { QRect r; @@ -450,6 +467,14 @@ quint8 QXcbScreen::depthOfVisual(xcb_visualid_t visualid) const return *it; } +QRect QXcbScreen::availableGeometry() const +{ + static bool enforceNetWorkarea = !qEnvironmentVariableIsEmpty("QT_RELY_ON_NET_WORKAREA_ATOM"); + bool isMultiHeadSystem = virtualSiblings().length() > 1; + bool useScreenGeometry = isMultiHeadSystem && !enforceNetWorkarea; + return useScreenGeometry ? m_geometry : m_availableGeometry; +} + QImage::Format QXcbScreen::format() const { return qt_xcb_imageFormatForVisual(connection(), screen()->root_depth, visualForId(screen()->root_visual)); diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index 4163be2..95fbb79 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -120,7 +120,7 @@ public: QWindow *topLevelAt(const QPoint &point) const override; QRect geometry() const override { return m_geometry; } - QRect availableGeometry() const override {return m_availableGeometry;} + QRect availableGeometry() const override; int depth() const override { return screen()->root_depth; } QImage::Format format() const override; QSizeF physicalSize() const override { return m_sizeMillimeters; } diff --git a/src/widgets/kernel/qdesktopwidget.qdoc b/src/widgets/kernel/qdesktopwidget.qdoc index 27d05ec..fdf6a27 100644 --- a/src/widgets/kernel/qdesktopwidget.qdoc +++ b/src/widgets/kernel/qdesktopwidget.qdoc @@ -152,7 +152,7 @@ on \macos, or the task bar on Windows). The default screen is used if \a screen is -1. - \sa screenNumber(), screenGeometry() + \sa screenNumber(), screenGeometry(), QScreen::availableGeometry() */ /*! -- 2.24.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor