summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2015-11-18 09:01:51 +0100
committerLiang Qi <liang.qi@theqtcompany.com>2015-11-18 09:01:51 +0100
commitc7934f2489e2eb9a539206bab35f335b1943c5bd (patch)
treea27d0ed6c001fe9432e2a0f28fb935acf9e4c65f /src/plugins/platforms/xcb
parentf40593b11199fbef886bfcb6b210a214d8c3adf3 (diff)
parent08f9a1bd6ab9b1777ee5ba163d75e5c848c39eb4 (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts: src/corelib/io/qprocess.cpp src/corelib/io/qprocess_unix.cpp src/network/kernel/qnetworkinterface_winrt.cpp tools/configure/configureapp.cpp Change-Id: I47df00a01597d2e63b334b492b3b4221b29f58ea
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro2
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp26
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp73
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h20
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp2
-rw-r--r--src/plugins/platforms/xcb/xcb_qpa_lib.pro9
6 files changed, 83 insertions, 49 deletions
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro
index 57cd81ec3b..1c577e5dc9 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro
@@ -17,6 +17,8 @@ contains(QT_CONFIG, xcb-glx) {
LIBS += -lxcb-glx
}
+LIBS += $$QMAKE_LIBS_DYNLOAD
+
HEADERS += \
qxcbglxintegration.h \
qxcbglxwindow.h \
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index a20d957138..901764bbf8 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -263,8 +263,7 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
// Known screen removed -> delete it
m_screens.removeOne(screen);
- foreach (QXcbScreen *otherScreen, m_screens)
- otherScreen->removeVirtualSibling((QPlatformScreen *) screen);
+ virtualDesktop->removeScreen(screen);
QXcbIntegration::instance()->destroyScreen(screen);
@@ -283,9 +282,7 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled";
screen->setPrimary(checkOutputIsPrimary(output.window, output.output));
- foreach (QXcbScreen *otherScreen, m_screens)
- if (otherScreen->root() == output.window)
- otherScreen->addVirtualSibling(screen);
+ virtualDesktop->addScreen(screen);
m_screens << screen;
QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary());
@@ -308,8 +305,7 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
if (outputInfo->crtc == XCB_NONE) {
qCDebug(lcQpaScreen) << "output" << screen->name() << "has been disabled";
m_screens.removeOne(screen);
- foreach (QXcbScreen *otherScreen, m_screens)
- otherScreen->removeVirtualSibling((QPlatformScreen *) screen);
+ virtualDesktop->removeScreen(screen);
QXcbIntegration::instance()->destroyScreen(screen);
} else {
qCDebug(lcQpaScreen) << "output" << screen->name() << "has been temporarily disabled for the mode switch";
@@ -443,8 +439,7 @@ void QXcbConnection::initializeScreens()
}
}
}
- foreach (QPlatformScreen* s, siblings)
- ((QXcbScreen*)s)->setVirtualSiblings(siblings);
+ virtualDesktop->setScreens(siblings);
xcb_screen_next(&it);
++xcbScreenNumber;
} // for each xcb screen
@@ -460,7 +455,7 @@ void QXcbConnection::initializeScreens()
QXcbVirtualDesktop *virtualDesktop = m_virtualDesktops.value(0);
if (virtualDesktop && !hasOutputs && !virtualDesktop->size().isEmpty() && m_screens.isEmpty()) {
QXcbScreen *screen = createScreen(virtualDesktop, 0, Q_NULLPTR);
- screen->setVirtualSiblings(QList<QPlatformScreen *>() << screen);
+ virtualDesktop->setScreens(QList<QPlatformScreen *>() << screen);
m_screens << screen;
primaryScreen = screen;
primaryScreen->setPrimary(true);
@@ -1126,8 +1121,17 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
handled = false;
break;
case XCB_PROPERTY_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
+ {
+ xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;
+ if (pn->atom == atom(QXcbAtom::_NET_WORKAREA)) {
+ QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(pn->window);
+ if (virtualDesktop)
+ virtualDesktop->updateWorkArea();
+ } else {
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
+ }
break;
+ }
#if defined(XCB_USE_XINPUT2)
case XCB_GE_GENERIC:
// Here the windowEventListener is invoked from xi2HandleEvent()
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 4f71ac8693..55bae05523 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -58,6 +58,8 @@ QXcbVirtualDesktop::QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t
cmAtomName += QByteArray::number(m_number);
m_net_wm_cm_atom = connection->internAtom(cmAtomName.constData());
m_compositingActive = connection->getSelectionOwner(m_net_wm_cm_atom);
+
+ m_workArea = getWorkArea();
}
QXcbVirtualDesktop::~QXcbVirtualDesktop()
@@ -74,6 +76,11 @@ QXcbScreen *QXcbVirtualDesktop::screenAt(const QPoint &pos) const
return Q_NULLPTR;
}
+void QXcbVirtualDesktop::addScreen(QPlatformScreen *s)
+{
+ ((QXcbScreen *) s)->isPrimary() ? m_screens.prepend(s) : m_screens.append(s);
+}
+
QXcbXSettings *QXcbVirtualDesktop::xSettings() const
{
if (!m_xSettings) {
@@ -107,6 +114,40 @@ void QXcbVirtualDesktop::subscribeToXFixesSelectionNotify()
}
}
+QRect QXcbVirtualDesktop::getWorkArea() const
+{
+ QRect r;
+ xcb_get_property_reply_t * workArea =
+ xcb_get_property_reply(xcb_connection(),
+ xcb_get_property_unchecked(xcb_connection(), false, screen()->root,
+ atom(QXcbAtom::_NET_WORKAREA),
+ XCB_ATOM_CARDINAL, 0, 1024), NULL);
+ if (workArea && workArea->type == XCB_ATOM_CARDINAL && workArea->format == 32 && workArea->value_len >= 4) {
+ // If workArea->value_len > 4, the remaining ones seem to be for WM's virtual desktops
+ // (don't mess with QXcbVirtualDesktop which represents an X screen).
+ // But QScreen doesn't know about that concept. In reality there could be a
+ // "docked" panel (with _NET_WM_STRUT_PARTIAL atom set) on just one desktop.
+ // But for now just assume the first 4 values give us the geometry of the
+ // "work area", AKA "available geometry"
+ uint32_t *geom = (uint32_t*)xcb_get_property_value(workArea);
+ r = QRect(geom[0], geom[1], geom[2], geom[3]);
+ } else {
+ r = QRect(QPoint(), size());
+ }
+ free(workArea);
+ return r;
+}
+
+void QXcbVirtualDesktop::updateWorkArea()
+{
+ QRect workArea = getWorkArea();
+ if (m_workArea != workArea) {
+ m_workArea = workArea;
+ foreach (QPlatformScreen *screen, m_screens)
+ ((QXcbScreen *)screen)->updateAvailableGeometry();
+ }
+}
+
QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDesktop,
xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output,
QString outputName)
@@ -450,7 +491,6 @@ void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation)
{
QRect xGeometry = geom;
- QRect xAvailableGeometry = xGeometry;
switch (rotation) {
case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal
m_orientation = Qt::LandscapeOrientation;
@@ -479,34 +519,23 @@ void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation)
Q_MM_PER_INCH * xGeometry.width() / dpi.second);
}
- xcb_get_property_reply_t * workArea =
- xcb_get_property_reply(xcb_connection(),
- xcb_get_property_unchecked(xcb_connection(), false, screen()->root,
- atom(QXcbAtom::_NET_WORKAREA),
- XCB_ATOM_CARDINAL, 0, 1024), NULL);
-
- if (workArea && workArea->type == XCB_ATOM_CARDINAL && workArea->format == 32 && workArea->value_len >= 4) {
- // If workArea->value_len > 4, the remaining ones seem to be for virtual desktops.
- // But QScreen doesn't know about that concept. In reality there could be a
- // "docked" panel (with _NET_WM_STRUT_PARTIAL atom set) on just one desktop.
- // But for now just assume the first 4 values give us the geometry of the
- // "work area", AKA "available geometry"
- uint32_t *geom = (uint32_t*)xcb_get_property_value(workArea);
- QRect virtualAvailableGeometry(geom[0], geom[1], geom[2], geom[3]);
- // Take the intersection of the desktop's available geometry with this screen's geometry
- // to get the part of the available geometry which belongs to this screen.
- xAvailableGeometry = xGeometry & virtualAvailableGeometry;
- }
- free(workArea);
-
qreal dpi = xGeometry.width() / physicalSize().width() * qreal(25.4);
m_pixelDensity = qRound(dpi/96);
m_geometry = QRect(xGeometry.topLeft(), xGeometry.size());
m_nativeGeometry = QRect(xGeometry.topLeft(), xGeometry.size());
- m_availableGeometry = QRect(xAvailableGeometry.topLeft(), xAvailableGeometry.size());
+ m_availableGeometry = xGeometry & m_virtualDesktop->workArea();
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry);
}
+void QXcbScreen::updateAvailableGeometry()
+{
+ QRect availableGeometry = m_geometry & m_virtualDesktop->workArea();
+ if (m_availableGeometry != availableGeometry) {
+ m_availableGeometry = availableGeometry;
+ QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry);
+ }
+}
+
void QXcbScreen::updateRefreshRate(xcb_randr_mode_t mode)
{
if (!connection()->hasXRandr())
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index 51c92a40ae..c68c290791 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -68,20 +68,33 @@ public:
xcb_window_t root() const { return m_screen->root; }
QXcbScreen *screenAt(const QPoint &pos) const;
+ QList<QPlatformScreen *> screens() const { return m_screens; }
+ void setScreens(QList<QPlatformScreen *> sl) { m_screens = sl; }
+ void removeScreen(QPlatformScreen *s) { m_screens.removeOne(s); }
+ void addScreen(QPlatformScreen *s);
+
QXcbXSettings *xSettings() const;
bool compositingActive() const;
+ QRect workArea() const { return m_workArea; }
+ void updateWorkArea();
+
void handleXFixesSelectionNotify(xcb_xfixes_selection_notify_event_t *notify_event);
void subscribeToXFixesSelectionNotify();
private:
+ QRect getWorkArea() const;
+
xcb_screen_t *m_screen;
int m_number;
+ QList<QPlatformScreen *> m_screens;
QXcbXSettings *m_xSettings;
xcb_atom_t m_net_wm_cm_atom;
bool m_compositingActive;
+
+ QRect m_workArea;
};
class Q_XCB_EXPORT QXcbScreen : public QXcbObject, public QPlatformScreen
@@ -110,10 +123,7 @@ public:
QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
qreal refreshRate() const Q_DECL_OVERRIDE { return m_refreshRate; }
Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE { return m_orientation; }
- QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; }
- void setVirtualSiblings(QList<QPlatformScreen *> sl) { m_siblings = sl; }
- void removeVirtualSibling(QPlatformScreen *s) { m_siblings.removeOne(s); }
- void addVirtualSibling(QPlatformScreen *s) { ((QXcbScreen *) s)->isPrimary() ? m_siblings.prepend(s) : m_siblings.append(s); }
+ QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE { return m_virtualDesktop->screens(); }
QXcbVirtualDesktop *virtualDesktop() const { return m_virtualDesktop; }
void setPrimary(bool primary) { m_primary = primary; }
@@ -139,6 +149,7 @@ public:
void handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event);
void updateGeometry(const QRect &geom, uint8_t rotation);
void updateGeometry(xcb_timestamp_t timestamp = XCB_TIME_CURRENT_TIME);
+ void updateAvailableGeometry();
void updateRefreshRate(xcb_randr_mode_t mode);
void readXResources();
@@ -171,7 +182,6 @@ private:
QRect m_availableGeometry;
QSize m_virtualSize;
QSizeF m_virtualSizeMillimeters;
- QList<QPlatformScreen *> m_siblings;
Qt::ScreenOrientation m_orientation;
QString m_windowManagerName;
bool m_syncRequestSupported;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index b691c7550f..bcc571c3c8 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -2378,8 +2378,6 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
return;
} else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) {
m_dirtyFrameMargins = true;
- } else if (event->atom == atom(QXcbAtom::_NET_WORKAREA) && xcbScreen() && event->window == xcbScreen()->root()) {
- xcbScreen()->updateGeometry(event->time);
}
}
diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
index 12987567ff..60eb8a02e3 100644
--- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro
+++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
@@ -1,13 +1,6 @@
TARGET = QtXcbQpa
CONFIG += no_module_headers internal_module
-MODULE_INCLUDES = \
- \$\$QT_MODULE_INCLUDE_BASE \
- \$\$QT_MODULE_INCLUDE_BASE/QtQGui
-MODULE_PRIVATE_INCLUDES = \
- \$\$QT_MODULE_INCLUDE_BASE/QtGui/$$QT.gui.VERSION \
- \$\$QT_MODULE_INCLUDE_BASE/QtGui/$$QT.gui.VERSION/QtGui
-
load(qt_module)
QT += core-private gui-private platformsupport-private
@@ -47,8 +40,6 @@ HEADERS = \
qxcbxsettings.h \
qxcbsystemtraytracker.h
-LIBS += $$QMAKE_LIBS_DYNLOAD
-
DEFINES += QT_BUILD_XCB_PLUGIN
# needed by Xcursor ...
contains(QT_CONFIG, xcb-xlib) {