diff options
-rw-r--r-- | src/gui/kernel/qscreen.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.cpp | 25 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.h | 2 | ||||
-rw-r--r-- | 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 96f75f37eb..479e228e27 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 d097ad79a8..189d46dd67 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -188,6 +188,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; @@ -556,6 +573,14 @@ void QXcbScreen::sendStartupMessage(const QByteArray &message) const } while (sent < length); } +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 b9364758c4..22ae0bc61b 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -154,7 +154,7 @@ public: QString serialNumber() 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 27d05ece8c..fdf6a27597 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() */ /*! |