summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/kernel/qscreen.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp25
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h2
-rw-r--r--src/widgets/kernel/qdesktopwidget.qdoc2
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()
*/
/*!